implement logging of exam edits on workflow's current step
This commit is contained in:
@@ -6,6 +6,8 @@ import client from "@/lib/mongodb";
|
||||
import { sessionOptions } from "@/lib/session";
|
||||
import { mapBy } from "@/utils";
|
||||
import { requestUser } from "@/utils/api";
|
||||
import { getApprovalWorkflowsByExamId, updateApprovalWorkflows } from "@/utils/approval.workflows.be";
|
||||
import { generateExamDifferences } from "@/utils/exam.differences";
|
||||
import { getExams } from "@/utils/exams.be";
|
||||
import { isAdmin } from "@/utils/users";
|
||||
import { withIronSessionApiRoute } from "iron-session/next";
|
||||
@@ -108,8 +110,26 @@ async function POST(req: NextApiRequest, res: NextApiResponse) {
|
||||
responseStatus = 207;
|
||||
responseMessage = `Successfully created exam with ID: "${exam.id}" but something went wrong while creating the Approval Workflow(s).`;
|
||||
}
|
||||
} else { // if exam was updated, log the updates
|
||||
const approvalWorkflows = await getApprovalWorkflowsByExamId(exam.id);
|
||||
|
||||
if (approvalWorkflows) {
|
||||
const differences = generateExamDifferences(docSnap as Exam, exam as Exam);
|
||||
if (differences) {
|
||||
approvalWorkflows.forEach((workflow) => {
|
||||
const currentStepIndex = workflow.steps.findIndex(step => !step.completed || step.rejected);
|
||||
|
||||
if (workflow.steps[currentStepIndex].examChanges === undefined) {
|
||||
workflow.steps[currentStepIndex].examChanges = [...differences];
|
||||
} else {
|
||||
workflow.steps[currentStepIndex].examChanges!.push(...differences);
|
||||
}
|
||||
});
|
||||
await updateApprovalWorkflows("active-workflows", approvalWorkflows);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
res.status(responseStatus).json({
|
||||
message: responseMessage,
|
||||
});
|
||||
|
||||
@@ -29,7 +29,7 @@ import { FaSpinner, FaWpforms } from "react-icons/fa6";
|
||||
import { FiSave } from "react-icons/fi";
|
||||
import { IoMdCheckmarkCircleOutline } from "react-icons/io";
|
||||
import { IoDocumentTextOutline } from "react-icons/io5";
|
||||
import { MdOutlineDoubleArrow } from "react-icons/md";
|
||||
import { MdKeyboardArrowDown, MdKeyboardArrowUp, MdOutlineDoubleArrow } from "react-icons/md";
|
||||
import { RiThumbUpLine } from "react-icons/ri";
|
||||
import { RxCrossCircled } from "react-icons/rx";
|
||||
import { TiEdit } from "react-icons/ti";
|
||||
@@ -89,6 +89,7 @@ export default function Home({ user, initialWorkflow, id, workflowAssignees, wor
|
||||
const [selectedStepIndex, setSelectedStepIndex] = useState<number>(currentStepIndex);
|
||||
const [selectedStep, setSelectedStep] = useState<WorkflowStep>(currentWorkflow.steps[selectedStepIndex]);
|
||||
const [isPanelOpen, setIsPanelOpen] = useState(true);
|
||||
const [isAccordionOpen, setIsAccordionOpen] = useState(false);
|
||||
const [comments, setComments] = useState<string>(selectedStep.comments || "");
|
||||
const [viewExamIsLoading, setViewExamIsLoading] = useState<boolean>(false);
|
||||
const [editExamIsLoading, setEditExamIsLoading] = useState<boolean>(false);
|
||||
@@ -517,11 +518,53 @@ export default function Home({ user, initialWorkflow, id, workflowAssignees, wor
|
||||
|
||||
<hr className="my-4 h-[4px] bg-mti-purple-ultralight rounded-full w-full" />
|
||||
|
||||
{/* Accordion for Exam Changes */}
|
||||
<div className="mb-4">
|
||||
<div
|
||||
className="flex items-center justify-between cursor-pointer p-2 rounded-lg"
|
||||
onClick={() => setIsAccordionOpen((prev) => !prev)}
|
||||
>
|
||||
<h2 className="font-medium text-gray-500">
|
||||
Changes ({currentWorkflow.steps[selectedStepIndex].examChanges?.length || "0"})
|
||||
</h2>
|
||||
{isAccordionOpen ? (
|
||||
<MdKeyboardArrowUp size={24} />
|
||||
) : (
|
||||
<MdKeyboardArrowDown size={24} />
|
||||
)}
|
||||
</div>
|
||||
<AnimatePresence>
|
||||
{isAccordionOpen && (
|
||||
<motion.div
|
||||
initial={{ height: 0, opacity: 0 }}
|
||||
animate={{ height: "auto", opacity: 1 }}
|
||||
exit={{ height: 0, opacity: 0 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
className="overflow-hidden mt-2"
|
||||
>
|
||||
<div className="p-3 border border-gray-300 rounded-xl bg-white bg-opacity-80 overflow-y-auto max-h-40">
|
||||
{currentWorkflow.steps[selectedStepIndex].examChanges?.length ? (
|
||||
currentWorkflow.steps[selectedStepIndex].examChanges!.map((change, index) => (
|
||||
<p key={index} className="text-sm text-gray-500 mb-2">
|
||||
{change}
|
||||
</p>
|
||||
))
|
||||
) : (
|
||||
<p className="text-normal text-opacity-70 text-gray-500">No changes made so far.</p>
|
||||
)}
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
|
||||
<hr className="my-4 h-[4px] bg-mti-purple-ultralight rounded-full w-full" />
|
||||
|
||||
<textarea
|
||||
value={comments}
|
||||
onChange={(e) => setComments(e.target.value)}
|
||||
placeholder="Input comments here"
|
||||
className="w-full h-64 p-2 border-2 rounded-xl shadow-lg focus:border-mti-purple focus:outline-none mt-3 resize-none"
|
||||
className="w-full h-40 p-2 border-2 rounded-xl shadow-lg focus:border-mti-purple focus:outline-none mt-3 resize-none"
|
||||
/>
|
||||
|
||||
<Button
|
||||
|
||||
Reference in New Issue
Block a user