code refactoring
This commit is contained in:
@@ -7,6 +7,7 @@ import { BsTrash } from "react-icons/bs";
|
|||||||
import { LuGripHorizontal } from "react-icons/lu";
|
import { LuGripHorizontal } from "react-icons/lu";
|
||||||
import WorkflowStepNumber from "./WorkflowStepNumber";
|
import WorkflowStepNumber from "./WorkflowStepNumber";
|
||||||
import WorkflowStepSelects from "./WorkflowStepSelects";
|
import WorkflowStepSelects from "./WorkflowStepSelects";
|
||||||
|
import Image from "next/image";
|
||||||
|
|
||||||
interface Props extends WorkflowStep {
|
interface Props extends WorkflowStep {
|
||||||
entityTeachers: TeacherUser[];
|
entityTeachers: TeacherUser[];
|
||||||
@@ -31,7 +32,7 @@ export default function WorkflowEditableStepComponent({
|
|||||||
.map((teacher) => ({
|
.map((teacher) => ({
|
||||||
value: teacher.id,
|
value: teacher.id,
|
||||||
label: teacher.name,
|
label: teacher.name,
|
||||||
icon: () => <img src={teacher.profilePicture} alt={teacher.name} />
|
icon: () => <Image src={teacher.profilePicture} alt={teacher.name} />
|
||||||
}))
|
}))
|
||||||
.sort((a, b) => a.label.localeCompare(b.label)),
|
.sort((a, b) => a.label.localeCompare(b.label)),
|
||||||
[entityTeachers]
|
[entityTeachers]
|
||||||
@@ -42,7 +43,7 @@ export default function WorkflowEditableStepComponent({
|
|||||||
.map((corporate) => ({
|
.map((corporate) => ({
|
||||||
value: corporate.id,
|
value: corporate.id,
|
||||||
label: corporate.name,
|
label: corporate.name,
|
||||||
icon: () => <img src={corporate.profilePicture} alt={corporate.name} />
|
icon: () => <Image src={corporate.profilePicture} alt={corporate.name} />
|
||||||
}))
|
}))
|
||||||
.sort((a, b) => a.label.localeCompare(b.label)),
|
.sort((a, b) => a.label.localeCompare(b.label)),
|
||||||
[entityCorporates]
|
[entityCorporates]
|
||||||
@@ -55,9 +56,16 @@ export default function WorkflowEditableStepComponent({
|
|||||||
const initialSelects = assignees.map((assignee) =>
|
const initialSelects = assignees.map((assignee) =>
|
||||||
typeof assignee === 'string' ? allOptions.find(opt => opt.value === assignee) || null : null
|
typeof assignee === 'string' ? allOptions.find(opt => opt.value === assignee) || null : null
|
||||||
);
|
);
|
||||||
if (JSON.stringify(initialSelects) !== JSON.stringify(selects)) {
|
|
||||||
setSelects(initialSelects);
|
setSelects((prevSelects) => {
|
||||||
}
|
// This is needed to avoid unnecessary re-renders which can cause warning of a child component being re-rendered while parent is in the midle of also re-rendering.
|
||||||
|
const areEqual = initialSelects.length === prevSelects.length && initialSelects.every((option, idx) => option?.value === prevSelects[idx]?.value);
|
||||||
|
|
||||||
|
if (!areEqual) {
|
||||||
|
return initialSelects;
|
||||||
|
}
|
||||||
|
return prevSelects;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}, [assignees, allOptions]);
|
}, [assignees, allOptions]);
|
||||||
|
|
||||||
|
|||||||
@@ -23,18 +23,8 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function WorkflowForm({ workflow, onWorkflowChange, entityTeachers, entityCorporates }: Props) {
|
export default function WorkflowForm({ workflow, onWorkflowChange, entityTeachers, entityCorporates }: Props) {
|
||||||
const [steps, setSteps] = useState<WorkflowStep[]>(workflow.steps);
|
|
||||||
const [stepCounter, setStepCounter] = useState<number>(3); // to guarantee unique keys used for animations
|
const [stepCounter, setStepCounter] = useState<number>(3); // to guarantee unique keys used for animations
|
||||||
const lastStep = steps[steps.length - 1];
|
const lastStep = workflow.steps[workflow.steps.length - 1];
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setSteps(workflow.steps);
|
|
||||||
}, [workflow]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const updatedWorkflow = { ...workflow, steps };
|
|
||||||
onWorkflowChange(updatedWorkflow);
|
|
||||||
}, [steps]);
|
|
||||||
|
|
||||||
const renumberSteps = (steps: WorkflowStep[]): WorkflowStep[] => {
|
const renumberSteps = (steps: WorkflowStep[]): WorkflowStep[] => {
|
||||||
return steps.map((step, index) => ({
|
return steps.map((step, index) => ({
|
||||||
@@ -44,49 +34,49 @@ export default function WorkflowForm({ workflow, onWorkflowChange, entityTeacher
|
|||||||
};
|
};
|
||||||
|
|
||||||
const addStep = () => {
|
const addStep = () => {
|
||||||
setSteps((prev) => {
|
const newStep: WorkflowStep = {
|
||||||
const newStep: WorkflowStep = {
|
key: stepCounter,
|
||||||
key: stepCounter,
|
stepType: "approval-by",
|
||||||
stepType: "approval-by",
|
stepNumber: workflow.steps.length,
|
||||||
stepNumber: steps.length,
|
completed: false,
|
||||||
completed: false,
|
assignees: [null],
|
||||||
assignees: [null],
|
};
|
||||||
};
|
setStepCounter((count) => count + 1);
|
||||||
setStepCounter((count) => count + 1);
|
|
||||||
|
|
||||||
const updatedSteps = [...prev.slice(0, -1), newStep, lastStep];
|
const updatedSteps = [
|
||||||
return renumberSteps(updatedSteps);
|
...workflow.steps.slice(0, -1),
|
||||||
});
|
newStep,
|
||||||
|
lastStep
|
||||||
|
];
|
||||||
|
onWorkflowChange({ ...workflow, steps: renumberSteps(updatedSteps) });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = (key: number | undefined) => {
|
const handleDelete = (key: number | undefined) => {
|
||||||
if (key) {
|
if (!key) return;
|
||||||
setSteps((prev) => {
|
|
||||||
const updatedSteps = prev.filter((step) => step.key !== key);
|
const updatedSteps = workflow.steps.filter((step) => step.key !== key);
|
||||||
return renumberSteps(updatedSteps);
|
onWorkflowChange({ ...workflow, steps: renumberSteps(updatedSteps) });
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSelectChange = (key: number | undefined, numberOfSelects: number, index: number, selectedOption: Option | null) => {
|
const handleSelectChange = (key: number | undefined, numberOfSelects: number, index: number, selectedOption: Option | null) => {
|
||||||
if (key === undefined) return;
|
if (!key) return;
|
||||||
|
|
||||||
setSteps((prevSteps) =>
|
const updatedSteps = workflow.steps.map((step) => {
|
||||||
prevSteps.map((step) => {
|
if (step.key !== key) return step;
|
||||||
if (step.key !== key) return step;
|
|
||||||
|
|
||||||
const assignees = step.assignees ?? [];
|
const assignees = step.assignees ?? [];
|
||||||
let newAssignees = [...assignees];
|
let newAssignees = [...assignees];
|
||||||
|
|
||||||
if (numberOfSelects === assignees.length) { // means no new select was added and instead one was changed
|
if (numberOfSelects === assignees.length) { // means no new select was added and instead one was changed
|
||||||
newAssignees[index] = selectedOption?.value;
|
newAssignees[index] = selectedOption?.value;
|
||||||
} else if (numberOfSelects === assignees.length + 1) { // means a new select was added
|
} else if (numberOfSelects === assignees.length + 1) { // means a new select was added
|
||||||
newAssignees.push(selectedOption?.value || null);
|
newAssignees.push(selectedOption?.value || null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return { ...step, assignees: newAssignees };
|
return { ...step, assignees: newAssignees };
|
||||||
})
|
});
|
||||||
);
|
|
||||||
|
onWorkflowChange({ ...workflow, steps: updatedSteps });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleReorder = (newOrder: WorkflowStep[]) => {
|
const handleReorder = (newOrder: WorkflowStep[]) => {
|
||||||
@@ -101,7 +91,8 @@ export default function WorkflowForm({ workflow, onWorkflowChange, entityTeacher
|
|||||||
const [final] = newOrder.splice(finalIndex, 1);
|
const [final] = newOrder.splice(finalIndex, 1);
|
||||||
newOrder.push(final);
|
newOrder.push(final);
|
||||||
}
|
}
|
||||||
setSteps(renumberSteps(newOrder));
|
|
||||||
|
onWorkflowChange({ ...workflow, steps: renumberSteps(newOrder) });
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -119,13 +110,13 @@ export default function WorkflowForm({ workflow, onWorkflowChange, entityTeacher
|
|||||||
|
|
||||||
<Reorder.Group
|
<Reorder.Group
|
||||||
axis="y"
|
axis="y"
|
||||||
values={steps}
|
values={workflow.steps}
|
||||||
onReorder={handleReorder}
|
onReorder={handleReorder}
|
||||||
className="flex flex-col gap-0"
|
className="flex flex-col gap-0"
|
||||||
>
|
>
|
||||||
|
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{steps.map((step, index) => (
|
{workflow.steps.map((step, index) => (
|
||||||
<Reorder.Item
|
<Reorder.Item
|
||||||
key={step.key}
|
key={step.key}
|
||||||
value={step}
|
value={step}
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ export default function Home({ user, userEntitiesWithLabel, userEntitiesTeachers
|
|||||||
|
|
||||||
setWorkflows(prev => prev.filter(wf => wf.id !== id));
|
setWorkflows(prev => prev.filter(wf => wf.id !== id));
|
||||||
if (selectedWorkflowId === id) {
|
if (selectedWorkflowId === id) {
|
||||||
setSelectedWorkflowId(undefined);
|
workflows.length > 0 ? setSelectedWorkflowId(workflows[0].id) : setSelectedWorkflowId(undefined);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -159,6 +159,8 @@ export default function Home({ user, userEntitiesWithLabel, userEntitiesTeachers
|
|||||||
Add New Workflow
|
Add New Workflow
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
{workflows.length !== 0 && <div className="bg-gray-300 w-[1px]"></div>}
|
||||||
|
|
||||||
<div className="flex flex-wrap gap-2">
|
<div className="flex flex-wrap gap-2">
|
||||||
{workflows.map((workflow) => (
|
{workflows.map((workflow) => (
|
||||||
<Button
|
<Button
|
||||||
@@ -172,7 +174,7 @@ export default function Home({ user, userEntitiesWithLabel, userEntitiesTeachers
|
|||||||
onClick={() => handleSelectWorkflow(workflow.id)}
|
onClick={() => handleSelectWorkflow(workflow.id)}
|
||||||
className="min-w-fit text-lg font-medium flex items-center gap-2 text-left"
|
className="min-w-fit text-lg font-medium flex items-center gap-2 text-left"
|
||||||
>
|
>
|
||||||
{workflow.name.trim() === "" ? "New Workflow" : workflow.name}
|
{workflow.name.trim() === "" ? "Workflow" : workflow.name}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
))}
|
))}
|
||||||
@@ -213,7 +215,7 @@ export default function Home({ user, userEntitiesWithLabel, userEntitiesTeachers
|
|||||||
placeholder="Entity..."
|
placeholder="Entity..."
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
color="purple"
|
color="red"
|
||||||
variant="solid"
|
variant="solid"
|
||||||
onClick={() => handleDeleteWorkflow(currentWorkflow.id)}
|
onClick={() => handleDeleteWorkflow(currentWorkflow.id)}
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
Reference in New Issue
Block a user