From 73610dc273192c8581f71b5659e2eaacf33aaff3 Mon Sep 17 00:00:00 2001 From: Joao Correia Date: Sat, 25 Jan 2025 19:45:39 +0000 Subject: [PATCH] implement edit workflow --- src/demo/approval_workflows.json | 2 + src/pages/approval-workflows/[id]/edit.tsx | 153 ++++++++++++++++++ .../{[id].tsx => [id]/index.tsx} | 2 +- src/pages/approval-workflows/create.tsx | 4 +- src/pages/approval-workflows/index.tsx | 23 ++- 5 files changed, 175 insertions(+), 9 deletions(-) create mode 100644 src/pages/approval-workflows/[id]/edit.tsx rename src/pages/approval-workflows/{[id].tsx => [id]/index.tsx} (99%) diff --git a/src/demo/approval_workflows.json b/src/demo/approval_workflows.json index a27cf88d..7a804c8d 100644 --- a/src/demo/approval_workflows.json +++ b/src/demo/approval_workflows.json @@ -63,6 +63,7 @@ "stepType": "approval-by", "stepNumber": 5, "completed": false, + "finalStep": true, "assignees": [ "fd5fce42-4bcc-4150-a143-b484e750b265", "231c84b2-a65a-49a9-803c-c664d84b13e0", @@ -145,6 +146,7 @@ "completed": true, "completedBy": "c5fc1514-1a94-4f8c-a046-a62099097a50", "completedDate": 1737712243906, + "finalStep": true, "assignees": [ "fd5fce42-4bcc-4150-a143-b484e750b265", "231c84b2-a65a-49a9-803c-c664d84b13e0", diff --git a/src/pages/approval-workflows/[id]/edit.tsx b/src/pages/approval-workflows/[id]/edit.tsx new file mode 100644 index 00000000..bae9fb09 --- /dev/null +++ b/src/pages/approval-workflows/[id]/edit.tsx @@ -0,0 +1,153 @@ +import RequestedBy from "@/components/ApprovalWorkflows/RequestedBy"; +import StartedOn from "@/components/ApprovalWorkflows/StartedOn"; +import Status from "@/components/ApprovalWorkflows/Status"; +import WorkflowForm from "@/components/ApprovalWorkflows/WorkflowForm"; +import Layout from "@/components/High/Layout"; +import { ApprovalWorkflow, EditableApprovalWorkflow, EditableWorkflowStep, getUserTypeLabelShort } from "@/interfaces/approval.workflow"; +import { CorporateUser, TeacherUser, User } from "@/interfaces/user"; +import { sessionOptions } from "@/lib/session"; +import { redirect, serialize } from "@/utils"; +import { requestUser } from "@/utils/api"; +import { shouldRedirectHome } from "@/utils/navigation.disabled"; +import { getEntityUsers } from "@/utils/users.be"; +import { motion } from "framer-motion"; +import { withIronSessionSsr } from "iron-session/next"; +import Head from "next/head"; +import Link from "next/link"; +import { useEffect, useState } from "react"; +import { BsChevronLeft } from "react-icons/bs"; +import { ToastContainer } from "react-toastify"; +import approvalWorkflowsData from '../../../demo/approval_workflows.json'; // to test locally + +export const getServerSideProps = withIronSessionSsr(async ({ req, res, params }) => { + const user = await requestUser(req, res); + if (!user) return redirect("/login") + + if (shouldRedirectHome(user) || !["admin", "developer", "teacher", "corporate", "mastercorporate"].includes(user.type)) + return redirect("/") + + const { id } = params as { id: string }; + + // replace later with await getApprovalWorkflow(id). + const approvalWorkflowsDataAsWorkflows = approvalWorkflowsData as ApprovalWorkflow[]; + const workflow: ApprovalWorkflow | undefined = approvalWorkflowsDataAsWorkflows.find(workflow => workflow.id === id); + + if (!workflow) + return redirect("/approval-workflows") + + return { + props: serialize({ + user, + workflow, + workflowEntityTeachers: await getEntityUsers(workflow.entityId, undefined, { type: "teacher" }), + workflowEntityCorporates: await getEntityUsers(workflow.entityId, undefined, { type: "corporate" }), + }), + }; +}, sessionOptions); + +interface Props { + user: User, + workflow: ApprovalWorkflow, + workflowEntityTeachers: TeacherUser[], + workflowEntityCorporates: CorporateUser[], +} + +export default function Home({ user, workflow, workflowEntityTeachers, workflowEntityCorporates }: Props) { + const [updatedWorkflow, setUpdatedWorkflow] = useState(null); + + useEffect(() => { + const editableSteps: EditableWorkflowStep[] = workflow.steps.map(step => ({ + key: step.stepNumber + 999, // just making sure they are unique because new steps that users add will have key=3 key=4 etc + stepType: step.stepType, + stepNumber: step.stepNumber, + assignees: step.assignees.map(id => id), + firstStep: step.firstStep || false, + finalStep: step.finalStep || false, + onDelete: undefined, + })); + + const editableWorkflow: EditableApprovalWorkflow = { + id: workflow.id, + name: workflow.name, + entityId: workflow.entityId, + requester: user.id, // should it change to the editor? + startDate: workflow.startDate, + modules: workflow.modules, + status: workflow.status, + steps: editableSteps, + }; + + setUpdatedWorkflow(editableWorkflow); + }, []); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + console.log("Form submitted! Values:", updatedWorkflow); + }; + + const onWorkflowChange = (wf: EditableApprovalWorkflow) => { + setUpdatedWorkflow(wf); + } + + return ( + <> + + Edit Workflow | EnCoach + + + + + + {user && ( + +
+ + + +

{workflow.name}

+
+ +
+
+ + + +
+
+ +
+ + {updatedWorkflow && + + } + +
+
+ )} + + ); +} diff --git a/src/pages/approval-workflows/[id].tsx b/src/pages/approval-workflows/[id]/index.tsx similarity index 99% rename from src/pages/approval-workflows/[id].tsx rename to src/pages/approval-workflows/[id]/index.tsx index b9c39671..86ea893d 100644 --- a/src/pages/approval-workflows/[id].tsx +++ b/src/pages/approval-workflows/[id]/index.tsx @@ -21,7 +21,7 @@ import { MdOutlineDoubleArrow } from "react-icons/md"; import { RiThumbUpLine } from "react-icons/ri"; import { ToastContainer } from "react-toastify"; -import approvalWorkflowsData from '../../demo/approval_workflows.json'; // to test locally +import approvalWorkflowsData from '../../../demo/approval_workflows.json'; // to test locally import Tip from "@/components/ApprovalWorkflows/Tip"; import { AnimatePresence, LayoutGroup, motion } from "framer-motion"; diff --git a/src/pages/approval-workflows/create.tsx b/src/pages/approval-workflows/create.tsx index b7688157..2047ab8e 100644 --- a/src/pages/approval-workflows/create.tsx +++ b/src/pages/approval-workflows/create.tsx @@ -102,8 +102,8 @@ export default function Home({ user, userEntitiesWithLabel, userEntitiesTeachers startDate: Date.now(), status: "pending", steps: [ - { key: Date.now(), stepType: "form-intake", stepNumber: 1, firstStep: true, finalStep: false, assignees: [null] }, - { key: Date.now() + 1, stepType: "approval-by", stepNumber: 2, firstStep: false, finalStep: true, assignees: [null] }, + { key: 9998, stepType: "form-intake", stepNumber: 1, firstStep: true, finalStep: false, assignees: [null] }, + { key: 9999, stepType: "approval-by", stepNumber: 2, firstStep: false, finalStep: true, assignees: [null] }, ], }; setWorkflows((prev) => [...prev, newWorkflow]); diff --git a/src/pages/approval-workflows/index.tsx b/src/pages/approval-workflows/index.tsx index d909c3b8..0c4ae873 100644 --- a/src/pages/approval-workflows/index.tsx +++ b/src/pages/approval-workflows/index.tsx @@ -242,15 +242,15 @@ export default function ApprovalWorkflows({ user, workflows, workflowsAssignees, ); }, }), - { + columnHelper.accessor("steps", { header: "ACTIONS", id: "actions", - cell: ({ row }: { row: { original: ApprovalWorkflow } }) => { + cell: ({ row }) => { + const steps = row.original.steps; + const currentStep = steps.find((step) => !step.completed); + return (
- e.stopPropagation()} data-tip="Edit" href={`/approval-workflows/${row.original.id}/edit`} className="cursor-pointer tooltip"> - - + + {currentStep && ( + e.stopPropagation()} + data-tip="Edit" + href={`/approval-workflows/${row.original.id}/edit`} + className="cursor-pointer tooltip" + > + + + )}
); }, - }, + }) ]; const table = useReactTable({