- edit workflow back-end implementation
- clone workflow back-end implementation - added loading and redirecting to form submissions - fixed form intake in progress bug - fixed rendering bug
This commit is contained in:
@@ -21,8 +21,11 @@ import Link from "next/link";
|
||||
import { useEffect, useState } from "react";
|
||||
import { BsChevronLeft } from "react-icons/bs";
|
||||
import { GrClearOption } from "react-icons/gr";
|
||||
import { ToastContainer } from "react-toastify";
|
||||
import { toast, ToastContainer } from "react-toastify";
|
||||
import approvalWorkflowsData from '../../../demo/approval_workflows.json'; // to test locally
|
||||
import { getApprovalWorkflow } from "@/utils/approval.workflows.be";
|
||||
import { useRouter } from "next/router";
|
||||
import axios from "axios";
|
||||
|
||||
export const getServerSideProps = withIronSessionSsr(async ({ req, res, params }) => {
|
||||
const user = await requestUser(req, res);
|
||||
@@ -33,9 +36,7 @@ export const getServerSideProps = withIronSessionSsr(async ({ req, res, params }
|
||||
|
||||
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);
|
||||
const workflow: ApprovalWorkflow | null = await getApprovalWorkflow(id);
|
||||
|
||||
if (!workflow)
|
||||
return redirect("/approval-workflows")
|
||||
@@ -66,6 +67,10 @@ export default function Home({ user, workflow, userEntitiesWithLabel, userEntiti
|
||||
const [entityId, setEntityId] = useState<string | null | undefined>(workflow.entityId);
|
||||
const [entityTeachers, setEntityTeachers] = useState<TeacherUser[]>([]);
|
||||
const [entityCorporates, setEntityCorporates] = useState<CorporateUser[]>([]);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const [isRedirecting, setIsRedirecting] = useState<boolean>(false);
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
if (entityId) {
|
||||
@@ -118,18 +123,47 @@ export default function Home({ user, workflow, userEntitiesWithLabel, userEntiti
|
||||
|
||||
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!cloneWorkflow) return;
|
||||
|
||||
const filteredWorkflow = {
|
||||
setIsLoading(true);
|
||||
|
||||
if (!cloneWorkflow) {
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const filteredWorkflow: ApprovalWorkflow = {
|
||||
...cloneWorkflow,
|
||||
steps: cloneWorkflow.steps.map(step => ({
|
||||
...step,
|
||||
assignees: step.assignees.filter(assignee => assignee !== null && assignee !== undefined)
|
||||
currentStep: step.stepNumber === 1 ? true : false,
|
||||
completed: false,
|
||||
assignees: step.assignees.filter((assignee): assignee is string => assignee !== null && assignee !== undefined)
|
||||
}))
|
||||
};
|
||||
|
||||
console.log("Form submitted! Filtered Workflow:", filteredWorkflow);
|
||||
|
||||
axios
|
||||
.post(`/api/approval-workflows/${workflow.id}/clone`, filteredWorkflow)
|
||||
.then(() => {
|
||||
toast.success("Approval Workflow cloned successfully.");
|
||||
setIsRedirecting(true);
|
||||
setTimeout(() => {
|
||||
router.push("/approval-workflows");
|
||||
}, 2000);
|
||||
})
|
||||
.catch((reason) => {
|
||||
if (reason.response.status === 401) {
|
||||
toast.error("Not logged in!");
|
||||
return router.push("/login");
|
||||
}
|
||||
if (reason.response.status === 403) {
|
||||
toast.error("You do not have permission to clone Approval Workflows!");
|
||||
return router.push("/approval-workflows");
|
||||
}
|
||||
toast.error("Something went wrong, please try again later.");
|
||||
setIsLoading(false);
|
||||
return;
|
||||
})
|
||||
|
||||
console.log("Form submitted! Filtered Values:", filteredWorkflow);
|
||||
};
|
||||
|
||||
const onWorkflowChange = (wf: EditableApprovalWorkflow) => {
|
||||
@@ -257,6 +291,8 @@ export default function Home({ user, workflow, userEntitiesWithLabel, userEntiti
|
||||
onWorkflowChange={onWorkflowChange}
|
||||
entityTeachers={entityTeachers}
|
||||
entityCorporates={entityCorporates}
|
||||
isLoading={isLoading}
|
||||
isRedirecting={isRedirecting}
|
||||
/>
|
||||
</motion.div>
|
||||
</LayoutGroup>
|
||||
|
||||
@@ -16,8 +16,10 @@ 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
|
||||
import { toast, ToastContainer } from "react-toastify";
|
||||
import axios from "axios";
|
||||
import { getApprovalWorkflow } from "@/utils/approval.workflows.be";
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
export const getServerSideProps = withIronSessionSsr(async ({ req, res, params }) => {
|
||||
const user = await requestUser(req, res);
|
||||
@@ -28,9 +30,7 @@ export const getServerSideProps = withIronSessionSsr(async ({ req, res, params }
|
||||
|
||||
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);
|
||||
const workflow: ApprovalWorkflow | null = await getApprovalWorkflow(id);
|
||||
|
||||
if (!workflow)
|
||||
return redirect("/approval-workflows")
|
||||
@@ -54,6 +54,10 @@ interface Props {
|
||||
|
||||
export default function Home({ user, workflow, workflowEntityTeachers, workflowEntityCorporates }: Props) {
|
||||
const [updatedWorkflow, setUpdatedWorkflow] = useState<EditableApprovalWorkflow | null>(null);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const [isRedirecting, setIsRedirecting] = useState<boolean>(false);
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
const editableSteps: EditableWorkflowStep[] = workflow.steps.map(step => ({
|
||||
@@ -82,23 +86,52 @@ export default function Home({ user, workflow, workflowEntityTeachers, workflowE
|
||||
|
||||
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!updatedWorkflow) return;
|
||||
|
||||
const filteredWorkflow = {
|
||||
setIsLoading(true);
|
||||
|
||||
if (!updatedWorkflow){
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const filteredWorkflow: ApprovalWorkflow = {
|
||||
...updatedWorkflow,
|
||||
steps: updatedWorkflow.steps.map(step => ({
|
||||
...step,
|
||||
assignees: step.assignees.filter(assignee => assignee !== null && assignee !== undefined)
|
||||
currentStep: step.stepNumber === 1 ? true : false,
|
||||
completed: false,
|
||||
assignees: step.assignees.filter((assignee): assignee is string => assignee !== null && assignee !== undefined)
|
||||
}))
|
||||
};
|
||||
|
||||
console.log("Form submitted! Filtered Workflow:", filteredWorkflow);
|
||||
|
||||
axios
|
||||
.put(`/api/approval-workflows/${workflow.id}/edit`, filteredWorkflow)
|
||||
.then(() => {
|
||||
toast.success("Approval Workflow edited successfully.");
|
||||
setIsRedirecting(true);
|
||||
setTimeout(() => {
|
||||
router.push("/approval-workflows");
|
||||
}, 2000);
|
||||
})
|
||||
.catch((reason) => {
|
||||
if (reason.response.status === 401) {
|
||||
toast.error("Not logged in!");
|
||||
return router.push("/login");
|
||||
}
|
||||
if (reason.response.status === 403) {
|
||||
toast.error("You do not have permission to edit Approval Workflows!");
|
||||
return router.push("/approval-workflows");
|
||||
}
|
||||
toast.error("Something went wrong, please try again later.");
|
||||
setIsLoading(false);
|
||||
return;
|
||||
})
|
||||
|
||||
console.log("Form submitted! Filtered Values:", filteredWorkflow);
|
||||
};
|
||||
|
||||
const onWorkflowChange = (wf: EditableApprovalWorkflow) => {
|
||||
setUpdatedWorkflow(wf);
|
||||
}
|
||||
const onWorkflowChange = (updatedWorkflow: EditableApprovalWorkflow) => {
|
||||
setUpdatedWorkflow(updatedWorkflow);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -153,6 +186,8 @@ export default function Home({ user, workflow, workflowEntityTeachers, workflowE
|
||||
onWorkflowChange={onWorkflowChange}
|
||||
entityTeachers={workflowEntityTeachers}
|
||||
entityCorporates={workflowEntityCorporates}
|
||||
isLoading={isLoading}
|
||||
isRedirecting={isRedirecting}
|
||||
/>
|
||||
}
|
||||
</motion.div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import RequestedBy from "@/components/ApprovalWorkflows/RequestedBy";
|
||||
import StartedOn from "@/components/ApprovalWorkflows/StartedOn";
|
||||
import Status from "@/components/ApprovalWorkflows/Status";
|
||||
import Tip from "@/components/ApprovalWorkflows/Tip";
|
||||
import UserWithProfilePic from "@/components/ApprovalWorkflows/UserWithProfilePic";
|
||||
import WorkflowStepComponent from "@/components/ApprovalWorkflows/WorkflowStepComponent";
|
||||
import Layout from "@/components/High/Layout";
|
||||
@@ -9,8 +10,10 @@ import { User } from "@/interfaces/user";
|
||||
import { sessionOptions } from "@/lib/session";
|
||||
import { redirect, serialize } from "@/utils";
|
||||
import { requestUser } from "@/utils/api";
|
||||
import { getApprovalWorkflow } from "@/utils/approval.workflows.be";
|
||||
import { shouldRedirectHome } from "@/utils/navigation.disabled";
|
||||
import { getSpecificUsers, getUser } from "@/utils/users.be";
|
||||
import { AnimatePresence, LayoutGroup, motion } from "framer-motion";
|
||||
import { withIronSessionSsr } from "iron-session/next";
|
||||
import Head from "next/head";
|
||||
import Link from "next/link";
|
||||
@@ -21,10 +24,6 @@ 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 Tip from "@/components/ApprovalWorkflows/Tip";
|
||||
import { AnimatePresence, LayoutGroup, motion } from "framer-motion";
|
||||
|
||||
export const getServerSideProps = withIronSessionSsr(async ({ req, res, params }) => {
|
||||
const user = await requestUser(req, res);
|
||||
if (!user) return redirect("/login")
|
||||
@@ -34,9 +33,7 @@ export const getServerSideProps = withIronSessionSsr(async ({ req, res, params }
|
||||
|
||||
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);
|
||||
const workflow: ApprovalWorkflow | null = await getApprovalWorkflow(id);
|
||||
|
||||
if (!workflow)
|
||||
return redirect("/approval-workflows")
|
||||
|
||||
@@ -18,6 +18,7 @@ import { AnimatePresence, LayoutGroup, motion } from "framer-motion";
|
||||
import { withIronSessionSsr } from "iron-session/next";
|
||||
import Head from "next/head";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
import { useEffect, useState } from "react";
|
||||
import { BsChevronLeft, BsTrash } from "react-icons/bs";
|
||||
import { MdFormatListBulletedAdd } from "react-icons/md";
|
||||
@@ -56,7 +57,11 @@ export default function Home({ user, userEntitiesWithLabel, userEntitiesTeachers
|
||||
const [entityId, setEntityId] = useState<string | null | undefined>(null);
|
||||
const [entityTeachers, setEntityTeachers] = useState<TeacherUser[]>([]);
|
||||
const [entityCorporates, setEntityCorporates] = useState<CorporateUser[]>([]);
|
||||
const [isAdding, setIsAdding] = useState(false); // used to temporary timeout new workflow button. With animations, clicking too fast might cause state inconsistencies between renders.
|
||||
const [isAdding, setIsAdding] = useState<boolean>(false); // used to temporary timeout new workflow button. With animations, clicking too fast might cause state inconsistencies between renders.
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const [isRedirecting, setIsRedirecting] = useState<boolean>(false);
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
if (entityId) {
|
||||
@@ -86,6 +91,11 @@ export default function Home({ user, userEntitiesWithLabel, userEntitiesTeachers
|
||||
|
||||
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
setIsLoading(true);
|
||||
|
||||
if (workflows.length === 0) {
|
||||
setIsLoading(false);
|
||||
}
|
||||
|
||||
const filteredWorkflows: ApprovalWorkflow[] = workflows.map(workflow => ({
|
||||
...workflow,
|
||||
@@ -99,24 +109,28 @@ export default function Home({ user, userEntitiesWithLabel, userEntitiesTeachers
|
||||
|
||||
axios
|
||||
.post(`/api/approval-workflows/create`, filteredWorkflows)
|
||||
.then(() => toast.success(`Approval Workflows created successfully.`))
|
||||
.then(() => {
|
||||
toast.success("Approval Workflows created successfully.");
|
||||
setIsRedirecting(true);
|
||||
setTimeout(() => {
|
||||
router.push("/approval-workflows");
|
||||
}, 2000);
|
||||
})
|
||||
.catch((reason) => {
|
||||
if (reason.response.status === 401) {
|
||||
toast.error("Not logged in!");
|
||||
return redirect("/login");
|
||||
return router.push("/login");
|
||||
}
|
||||
if (reason.response.status === 403) {
|
||||
toast.error("You do not have permission to create Approval Workflows!");
|
||||
return;
|
||||
return router.push("/approval-workflows");
|
||||
}
|
||||
|
||||
toast.error("Something went wrong, please try again later.");
|
||||
setIsLoading(false);
|
||||
return;
|
||||
})
|
||||
|
||||
|
||||
console.log("Form submitted! Filtered Values:", filteredWorkflows);
|
||||
|
||||
return redirect("/approval-workflows");
|
||||
};
|
||||
|
||||
const handleAddNewWorkflow = () => {
|
||||
@@ -309,6 +323,8 @@ export default function Home({ user, userEntitiesWithLabel, userEntitiesTeachers
|
||||
onWorkflowChange={onWorkflowChange}
|
||||
entityTeachers={entityTeachers}
|
||||
entityCorporates={entityCorporates}
|
||||
isLoading={isLoading}
|
||||
isRedirecting={isRedirecting}
|
||||
/>
|
||||
</motion.div>
|
||||
</LayoutGroup>
|
||||
|
||||
Reference in New Issue
Block a user