- fix assignees bug after editing active workflow

- only allow corporate+ to configure workflows
- give admins and devs permissions to approve and reject steps even when they are not assigned to them.
- small fixes
This commit is contained in:
Joao Correia
2025-02-05 16:50:09 +00:00
parent 845a5aa9dc
commit f0849b9b42
6 changed files with 25 additions and 19 deletions

View File

@@ -215,12 +215,12 @@ const LevelSettings: React.FC = () => {
}); });
const requestBody = await (async () => { const requestBody = await (async () => {
const handledExam = await getExamById("writing", result.data.id); const handledExam = await getExamById("level", result.data.id);
return { return {
examAuthor: handledExam?.createdBy ?? "Unknown Author", examAuthor: handledExam?.createdBy ?? "Unknown Author",
examEntities: handledExam?.entities ?? [], examEntities: handledExam?.entities ?? [],
examId: handledExam?.id ?? "Unknown ID", examId: handledExam?.id ?? "Unknown ID",
examModule: "writing" examModule: "level"
}; };
})(); })();
await axios await axios

View File

@@ -153,12 +153,12 @@ const ListeningSettings: React.FC = () => {
toast.success(`Submitted Exam ID: ${result.data.id}`); toast.success(`Submitted Exam ID: ${result.data.id}`);
const requestBody = await (async () => { const requestBody = await (async () => {
const handledExam = await getExamById("writing", result.data.id); const handledExam = await getExamById("listening", result.data.id);
return { return {
examAuthor: handledExam?.createdBy ?? "Unknown Author", examAuthor: handledExam?.createdBy ?? "Unknown Author",
examEntities: handledExam?.entities ?? [], examEntities: handledExam?.entities ?? [],
examId: handledExam?.id ?? "Unknown ID", examId: handledExam?.id ?? "Unknown ID",
examModule: "writing" examModule: "listening"
}; };
})(); })();
await axios await axios

View File

@@ -197,12 +197,12 @@ const SpeakingSettings: React.FC = () => {
}); });
const requestBody = await (async () => { const requestBody = await (async () => {
const handledExam = await getExamById("writing", result.data.id); const handledExam = await getExamById("speaking", result.data.id);
return { return {
examAuthor: handledExam?.createdBy ?? "Unknown Author", examAuthor: handledExam?.createdBy ?? "Unknown Author",
examEntities: handledExam?.entities ?? [], examEntities: handledExam?.entities ?? [],
examId: handledExam?.id ?? "Unknown ID", examId: handledExam?.id ?? "Unknown ID",
examModule: "writing" examModule: "speaking"
}; };
})(); })();
await axios await axios

View File

@@ -334,7 +334,7 @@ export default function Home({ user, initialWorkflow, id, workflowAssignees, wor
variant="solid" variant="solid"
onClick={handleEditExam} onClick={handleEditExam}
padding="px-6 py-2" padding="px-6 py-2"
disabled={!currentWorkflow.steps[currentStepIndex].assignees.includes(user.id) || editExamIsLoading} disabled={(!currentWorkflow.steps[currentStepIndex].assignees.includes(user.id) && user.type !== "admin" && user.type !== "developer") || editExamIsLoading}
className="w-[240px] text-lg flex items-center justify-center gap-2 text-left" className="w-[240px] text-lg flex items-center justify-center gap-2 text-left"
> >
{editExamIsLoading ? ( {editExamIsLoading ? (
@@ -475,7 +475,7 @@ export default function Home({ user, initialWorkflow, id, workflowAssignees, wor
type="submit" type="submit"
color="purple" color="purple"
variant="solid" variant="solid"
disabled={!selectedStep.assignees.includes(user.id) || isLoading} disabled={(!selectedStep.assignees.includes(user.id) && user.type !== "admin" && user.type !== "developer") || isLoading}
onClick={handleApproveStep} onClick={handleApproveStep}
padding="px-6 py-2" padding="px-6 py-2"
className="mb-3 w-full text-lg flex items-center justify-center gap-2 text-left" className="mb-3 w-full text-lg flex items-center justify-center gap-2 text-left"
@@ -496,7 +496,7 @@ export default function Home({ user, initialWorkflow, id, workflowAssignees, wor
type="submit" type="submit"
color="red" color="red"
variant="solid" variant="solid"
disabled={!selectedStep.assignees.includes(user.id) || isLoading} disabled={(!selectedStep.assignees.includes(user.id) && user.type !== "admin" && user.type !== "developer") || isLoading}
onClick={handleRejectStep} onClick={handleRejectStep}
padding="px-6 py-2" padding="px-6 py-2"
className="mb-3 w-1/2 text-lg flex items-center justify-center gap-2 text-left" className="mb-3 w-1/2 text-lg flex items-center justify-center gap-2 text-left"

View File

@@ -31,19 +31,27 @@ export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
const user = await requestUser(req, res) const user = await requestUser(req, res)
if (!user) return redirect("/login") if (!user) return redirect("/login")
if (shouldRedirectHome(user) || !["admin", "developer", "teacher", "corporate", "mastercorporate"].includes(user.type)) if (shouldRedirectHome(user) || !["admin", "developer", "corporate", "mastercorporate"].includes(user.type))
return redirect("/") return redirect("/")
const userEntitiesWithLabel = await getEntities(user.entities.map(entity => entity.id)); const userEntitiesWithLabel = await getEntities(user.entities.map(entity => entity.id));
const allConfiguredWorkflows = await getApprovalWorkflowsByEntities("configured-workflows", userEntitiesWithLabel.map(entity => entity.id)); const allConfiguredWorkflows = await getApprovalWorkflowsByEntities("configured-workflows", userEntitiesWithLabel.map(entity => entity.id));
const approverTypes = ["teacher", "corporate", "mastercorporate"];
if (user.type === "developer") {
approverTypes.push("developer");
}
const userEntitiesApprovers = await getEntitiesUsers(userEntitiesWithLabel.map(entity => entity.id), { type: { $in: approverTypes } }) as (TeacherUser | CorporateUser | MasterCorporateUser | DeveloperUser)[];
return { return {
props: serialize({ props: serialize({
user, user,
allConfiguredWorkflows, allConfiguredWorkflows,
userEntitiesWithLabel, userEntitiesWithLabel,
userEntitiesApprovers: await getEntitiesUsers(userEntitiesWithLabel.map(entity => entity.id), { type: { $in: ["teacher", "corporate", "mastercorporate", "developer"] } }) as (TeacherUser | CorporateUser | MasterCorporateUser | DeveloperUser)[], userEntitiesApprovers,
}), }),
}; };
}, sessionOptions); }, sessionOptions);

View File

@@ -36,7 +36,7 @@ export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
if (shouldRedirectHome(user) || !["admin", "developer", "teacher", "corporate", "mastercorporate"].includes(user.type)) if (shouldRedirectHome(user) || !["admin", "developer", "teacher", "corporate", "mastercorporate"].includes(user.type))
return redirect("/") return redirect("/")
const workflows = await getApprovalWorkflows("configured-workflows"); const workflows = await getApprovalWorkflows("active-workflows");
const allAssigneeIds: string[] = [ const allAssigneeIds: string[] = [
...new Set( ...new Set(
@@ -97,8 +97,6 @@ export default function ApprovalWorkflows({ user, initialWorkflows, workflowsAss
const {workflows, reload} = useApprovalWorkflows(); const {workflows, reload} = useApprovalWorkflows();
const currentWorkflows = workflows || initialWorkflows; const currentWorkflows = workflows || initialWorkflows;
console.log(currentWorkflows);
const [filteredWorkflows, setFilteredWorkflows] = useState<ApprovalWorkflow[]>([]); const [filteredWorkflows, setFilteredWorkflows] = useState<ApprovalWorkflow[]>([]);
const [statusFilter, setStatusFilter] = useState<CustomStatus>(undefined); const [statusFilter, setStatusFilter] = useState<CustomStatus>(undefined);