diff --git a/src/pages/api/approval-workflows/[id]/clone.ts b/src/pages/api/approval-workflows/[id]/clone.ts deleted file mode 100644 index 73fd4153..00000000 --- a/src/pages/api/approval-workflows/[id]/clone.ts +++ /dev/null @@ -1,27 +0,0 @@ -// Next.js API route support: https://nextjs.org/docs/api-routes/introduction -import { ApprovalWorkflow } from "@/interfaces/approval.workflow"; -import { sessionOptions } from "@/lib/session"; -import { requestUser } from "@/utils/api"; -import { createApprovalWorkflow } from "@/utils/approval.workflows.be"; -import { withIronSessionApiRoute } from "iron-session/next"; -import type { NextApiRequest, NextApiResponse } from "next"; - -export default withIronSessionApiRoute(handler, sessionOptions); - -async function handler(req: NextApiRequest, res: NextApiResponse) { - if (req.method === "POST") return await post(req, res); -} - -async function post(req: NextApiRequest, res: NextApiResponse) { - const user = await requestUser(req, res); - if (!user) return res.status(401).json({ ok: false }); - - if (!["admin", "developer", "corporate", "mastercorporate"].includes(user.type)) { - return res.status(403).json({ ok: false }); - } - - const approvalWorkflow: ApprovalWorkflow = req.body; - - if (approvalWorkflow) - return res.status(201).json(await createApprovalWorkflow("configured-workflows", approvalWorkflow)); -} diff --git a/src/pages/approval-workflows/[id]/clone.tsx b/src/pages/approval-workflows/[id]/clone.tsx deleted file mode 100644 index e580d50c..00000000 --- a/src/pages/approval-workflows/[id]/clone.tsx +++ /dev/null @@ -1,303 +0,0 @@ -import Tip from "@/components/ApprovalWorkflows/Tip"; -import WorkflowForm from "@/components/ApprovalWorkflows/WorkflowForm"; -import Layout from "@/components/High/Layout"; -import Button from "@/components/Low/Button"; -import Input from "@/components/Low/Input"; -import Select from "@/components/Low/Select"; -import { ApprovalWorkflow, EditableApprovalWorkflow, EditableWorkflowStep } from "@/interfaces/approval.workflow"; -import { Entity } from "@/interfaces/entity"; -import { CorporateUser, DeveloperUser, MasterCorporateUser, TeacherUser, User } from "@/interfaces/user"; -import { sessionOptions } from "@/lib/session"; -import { redirect, serialize } from "@/utils"; -import { requestUser } from "@/utils/api"; -import { getEntities } from "@/utils/entities.be"; -import { shouldRedirectHome } from "@/utils/navigation.disabled"; -import { getEntitiesUsers } from "@/utils/users.be"; -import { uuidv4 } from "@firebase/util"; -import { AnimatePresence, LayoutGroup, 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 { GrClearOption } from "react-icons/gr"; -import { toast, ToastContainer } from "react-toastify"; -import { useRouter } from "next/router"; -import axios from "axios"; -import { getApprovalWorkflow, getFormIntakersByEntity } from "@/utils/approval.workflows.be"; - -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 }; - - const workflow: ApprovalWorkflow | null = await getApprovalWorkflow("configured-workflows", id); - - if (!workflow) - return redirect("/approval-workflows") - - const userEntitiesWithLabel = await getEntities(user.entities.map(entity => entity.id)); - - return { - props: serialize({ - user, - workflow, - userEntitiesWithLabel, - entityUnavailableFormIntakers: await getFormIntakersByEntity(workflow.entityId), - userEntitiesApprovers: await getEntitiesUsers(userEntitiesWithLabel.map(entity => entity.id), { type: { $in: ["teacher", "corporate", "mastercorporate", "developer"] } }) as (TeacherUser | CorporateUser | MasterCorporateUser | DeveloperUser)[], - }), - }; -}, sessionOptions); - -interface Props { - user: User, - workflow: ApprovalWorkflow, - userEntitiesWithLabel: Entity[], - entityUnavailableFormIntakers: string[], - userEntitiesApprovers: (TeacherUser | CorporateUser | MasterCorporateUser | DeveloperUser)[], -} - -export default function Home({ user, workflow, userEntitiesWithLabel, entityUnavailableFormIntakers, userEntitiesApprovers }: Props) { - const [cloneWorkflow, setCloneWorkflow] = useState(null); - const [entityId, setEntityId] = useState(workflow.entityId); - const [entityApprovers, setEntityApprovers] = useState<(TeacherUser | CorporateUser | MasterCorporateUser | DeveloperUser)[]>([]); - const [isLoading, setIsLoading] = useState(false); - const [isRedirecting, setIsRedirecting] = useState(false); - - const router = useRouter(); - - useEffect(() => { - if (entityId) { - setEntityApprovers( - userEntitiesApprovers.filter(approver => - approver.entities.some(entity => entity.id === entityId) - ) - ); - } else { - setEntityApprovers([]); - } - }, [entityId, userEntitiesApprovers]); - - const ENTITY_OPTIONS = userEntitiesWithLabel.map(entity => ({ - label: entity.label, - value: entity.id, - filter: (x: EditableApprovalWorkflow) => x.entityId === entity.id, - })); - - 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, - completed: false, - assignees: step.assignees.map(id => id), - firstStep: step.firstStep || false, - finalStep: step.finalStep || false, - onDelete: undefined, - })); - - const editableWorkflow: EditableApprovalWorkflow = { - id: uuidv4(), // this id is only used in UI. it is ommited on submission to DB and lets mongo handle unique id. - name: workflow.name, - entityId: workflow.entityId, - requester: user.id, - startDate: Date.now(), - modules: workflow.modules, - status: "pending", - steps: editableSteps, - }; - - setCloneWorkflow(editableWorkflow); - }, []); - - const handleSubmit = (e: React.FormEvent) => { - e.preventDefault(); - setIsLoading(true); - - if (!cloneWorkflow) { - setIsLoading(false); - return; - } - - for (const step of cloneWorkflow.steps) { - if (step.assignees.every(x => !x)) { - toast.warning("There is at least one empty step in the workflow."); - setIsLoading(false); - return; - } - } - - const filteredWorkflow: ApprovalWorkflow = { - ...cloneWorkflow, - steps: cloneWorkflow.steps.map(step => ({ - ...step, - completed: false, - assignees: step.assignees.filter((assignee): assignee is string => assignee !== null && assignee !== undefined) - })) - }; - - axios - .post(`/api/approval-workflows/${workflow._id}/clone`, filteredWorkflow) - .then(() => { - toast.success("Approval Workflow cloned successfully."); - setIsRedirecting(true); - router.push("/approval-workflows"); - }) - .catch((reason) => { - if (reason.response.status === 401) { - toast.error("Not logged in!"); - } else if (reason.response.status === 403) { - toast.error("You do not have permission to clone Approval Workflows!"); - } else { - toast.error("Something went wrong, please try again later."); - } - setIsLoading(false); - console.log("Submitted Values:", filteredWorkflow); - return; - }) - - }; - - const onWorkflowChange = (wf: EditableApprovalWorkflow) => { - setCloneWorkflow(wf); - } - - const handleEntityChange = (wf: EditableApprovalWorkflow, entityId: string) => { - const updatedWorkflow = { - ...wf, - entityId: entityId, - steps: wf.steps.map(step => ({ - ...step, - assignees: step.assignees.map(() => null) - })) - } - onWorkflowChange(updatedWorkflow); - } - - const handleResetWorkflow = () => { - if (!confirm("This action will reset all the fields in this workflow. Are you sure you want to proceed?")) return; - const newId = uuidv4(); - const newWorkflow: EditableApprovalWorkflow = { - id: newId, - name: "", - entityId: "", - modules: [], - requester: user.id, - startDate: Date.now(), - status: "pending", - steps: [ - { key: 9998, stepType: "form-intake", stepNumber: 1, completed: false, firstStep: true, finalStep: false, assignees: [null] }, - { key: 9999, stepType: "approval-by", stepNumber: 2, completed: false, firstStep: false, finalStep: true, assignees: [null] }, - ], - }; - setCloneWorkflow(newWorkflow); - } - - return ( - <> - - Clone Workflow | EnCoach - - - - - - {user && ( - -
- - - -

Clone Workflow

-
- -
- {cloneWorkflow && ( - <> -
- { - const updatedWorkflow = { - ...cloneWorkflow, - name: updatedName, - }; - onWorkflowChange(updatedWorkflow); - }} - /> -