- 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:
Joao Correia
2025-02-02 22:40:05 +00:00
parent 16545d2075
commit 835a9bee03
5 changed files with 97 additions and 31 deletions

View File

@@ -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 isnt 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}
/>