- Filter available form intakers so that no form intaker can be in two workflows at once.
- add getApprovalWorkflowByIntaker to prepare workflow start after exam creation. - fix builder bug with step keys - ignore edit view for now because it will only be available for active workflows and not configured workflows.
This commit is contained in:
@@ -31,7 +31,7 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
|
||||
const configuredWorkflows: ApprovalWorkflow[] = filteredWorkflows;
|
||||
const entitiesIds: string[] = userEntitiesWithLabel.map((e) => e.id);
|
||||
|
||||
await replaceApprovalWorkflowsByEntities("configured-workflows", configuredWorkflows, entitiesIds);
|
||||
await replaceApprovalWorkflowsByEntities(configuredWorkflows, entitiesIds);
|
||||
|
||||
return res.status(201).json({ ok: true });
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import { GrClearOption } from "react-icons/gr";
|
||||
import { toast, ToastContainer } from "react-toastify";
|
||||
import { useRouter } from "next/router";
|
||||
import axios from "axios";
|
||||
import { getApprovalWorkflow } from "@/utils/approval.workflows.be";
|
||||
import { getApprovalWorkflow, getFormIntakersByEntity } from "@/utils/approval.workflows.be";
|
||||
|
||||
export const getServerSideProps = withIronSessionSsr(async ({ req, res, params }) => {
|
||||
const user = await requestUser(req, res);
|
||||
@@ -47,6 +47,7 @@ export const getServerSideProps = withIronSessionSsr(async ({ req, res, params }
|
||||
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)[],
|
||||
}),
|
||||
};
|
||||
@@ -56,10 +57,11 @@ interface Props {
|
||||
user: User,
|
||||
workflow: ApprovalWorkflow,
|
||||
userEntitiesWithLabel: Entity[],
|
||||
entityUnavailableFormIntakers: string[],
|
||||
userEntitiesApprovers: (TeacherUser | CorporateUser | MasterCorporateUser | DeveloperUser)[],
|
||||
}
|
||||
|
||||
export default function Home({ user, workflow, userEntitiesWithLabel, userEntitiesApprovers }: Props) {
|
||||
export default function Home({ user, workflow, userEntitiesWithLabel, entityUnavailableFormIntakers, userEntitiesApprovers }: Props) {
|
||||
const [cloneWorkflow, setCloneWorkflow] = useState<EditableApprovalWorkflow | null>(null);
|
||||
const [entityId, setEntityId] = useState<string | null | undefined>(workflow.entityId);
|
||||
const [entityApprovers, setEntityApprovers] = useState<(TeacherUser | CorporateUser | MasterCorporateUser | DeveloperUser)[]>([]);
|
||||
@@ -276,6 +278,7 @@ export default function Home({ user, workflow, userEntitiesWithLabel, userEntiti
|
||||
workflow={cloneWorkflow}
|
||||
onWorkflowChange={onWorkflowChange}
|
||||
entityApprovers={entityApprovers}
|
||||
entityAvailableFormIntakers={entityApprovers.filter(approver => !entityUnavailableFormIntakers.includes(approver.id))}
|
||||
isLoading={isLoading}
|
||||
isRedirecting={isRedirecting}
|
||||
/>
|
||||
|
||||
@@ -34,7 +34,7 @@ export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
|
||||
return redirect("/")
|
||||
|
||||
const userEntitiesWithLabel = await getEntities(user.entities.map(entity => entity.id));
|
||||
|
||||
|
||||
const allConfiguredWorkflows = await getApprovalWorkflowsByEntities("configured-workflows", userEntitiesWithLabel.map(entity => entity.id));
|
||||
|
||||
return {
|
||||
@@ -59,6 +59,7 @@ export default function Home({ user, allConfiguredWorkflows, userEntitiesWithLab
|
||||
const [selectedWorkflowId, setSelectedWorkflowId] = useState<string | undefined>(undefined);
|
||||
const [entityId, setEntityId] = useState<string | null | undefined>(null);
|
||||
const [entityApprovers, setEntityApprovers] = useState<(TeacherUser | CorporateUser | MasterCorporateUser | DeveloperUser)[]>([]);
|
||||
const [entityAvailableFormIntakers, setEntityAvailableFormIntakers] = useState<(TeacherUser | CorporateUser | MasterCorporateUser | DeveloperUser)[]>([]);
|
||||
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);
|
||||
@@ -72,11 +73,40 @@ export default function Home({ user, allConfiguredWorkflows, userEntitiesWithLab
|
||||
approver.entities.some(entity => entity.id === entityId)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
setEntityApprovers([]);
|
||||
}
|
||||
}, [entityId, userEntitiesApprovers]);
|
||||
|
||||
useEffect(() => {
|
||||
if (entityId) {
|
||||
// Get all workflows for the selected entity
|
||||
const workflowsForEntity = workflows.filter(wf => wf.entityId === entityId);
|
||||
|
||||
// For all workflows except the current one, collect the first step assignees
|
||||
const assignedFormIntakers = workflowsForEntity.reduce<string[]>((acc, wf) => {
|
||||
if (wf.id === selectedWorkflowId) return acc; // skip current workflow so its selection isn’t removed
|
||||
|
||||
const formIntakeStep = wf.steps.find(step => step.stepType === "form-intake");
|
||||
if (formIntakeStep) {
|
||||
// Only consider non-null assignees
|
||||
const validAssignees = formIntakeStep.assignees.filter(
|
||||
(assignee): assignee is string => !!assignee
|
||||
);
|
||||
return acc.concat(validAssignees);
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
// Now filter out any user from entityApprovers whose id is in the assignedFormIntakers list.
|
||||
// (The selected one in the current workflow is allowed even if it is in the list.)
|
||||
const availableFormIntakers = entityApprovers.filter(assignee =>
|
||||
!assignedFormIntakers.includes(assignee.id)
|
||||
);
|
||||
|
||||
setEntityAvailableFormIntakers(availableFormIntakers);
|
||||
}
|
||||
}, [entityId, entityApprovers, workflows, selectedWorkflowId]);
|
||||
|
||||
|
||||
const currentWorkflow = workflows.find(wf => wf.id === selectedWorkflowId);
|
||||
|
||||
const ENTITY_OPTIONS = userEntitiesWithLabel.map(entity => ({
|
||||
@@ -102,7 +132,7 @@ export default function Home({ user, allConfiguredWorkflows, userEntitiesWithLab
|
||||
}))
|
||||
}));
|
||||
|
||||
const requestData = {filteredWorkflows, userEntitiesWithLabel};
|
||||
const requestData = { filteredWorkflows, userEntitiesWithLabel };
|
||||
|
||||
axios
|
||||
.post(`/api/approval-workflows/create`, requestData)
|
||||
@@ -316,6 +346,7 @@ export default function Home({ user, allConfiguredWorkflows, userEntitiesWithLab
|
||||
workflow={currentWorkflow}
|
||||
onWorkflowChange={onWorkflowChange}
|
||||
entityApprovers={entityApprovers}
|
||||
entityAvailableFormIntakers={entityAvailableFormIntakers}
|
||||
isLoading={isLoading}
|
||||
isRedirecting={isRedirecting}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user