- initial selected step
- assignees id to name on table view
This commit is contained in:
@@ -1,17 +1,16 @@
|
||||
import Layout from "@/components/High/Layout";
|
||||
import Button from "@/components/Low/Button";
|
||||
import Select from "@/components/Low/Select";
|
||||
import useApprovalWorkflows from "@/hooks/useApprovalWorkflows";
|
||||
import { Module, ModuleTypeLabels } from "@/interfaces";
|
||||
import { ApprovalWorkflow, ApprovalWorkflowStatus, ApprovalWorkflowStatusLabel, StepTypeLabel } from "@/interfaces/approval.workflow";
|
||||
import { Entity, EntityWithRoles } from "@/interfaces/entity";
|
||||
import { TeacherUser, User } from "@/interfaces/user";
|
||||
import { User } from "@/interfaces/user";
|
||||
import { sessionOptions } from "@/lib/session";
|
||||
import { redirect, serialize } from "@/utils";
|
||||
import { requestUser } from "@/utils/api";
|
||||
import { getEntities } from "@/utils/entities.be";
|
||||
import { shouldRedirectHome } from "@/utils/navigation.disabled";
|
||||
import { getUsers } from "@/utils/users.be";
|
||||
import { getSpecificUsers } from "@/utils/users.be";
|
||||
import { createColumnHelper, flexRender, getCoreRowModel, useReactTable } from "@tanstack/react-table";
|
||||
import axios from "axios";
|
||||
import clsx from "clsx";
|
||||
@@ -24,6 +23,8 @@ import { FaRegEdit } from "react-icons/fa";
|
||||
import { IoIosAddCircleOutline } from "react-icons/io";
|
||||
import { toast, ToastContainer } from "react-toastify";
|
||||
|
||||
import approvalWorkflowsData from '../../demo/approval_workflows.json'; // to test locally
|
||||
|
||||
const columnHelper = createColumnHelper<ApprovalWorkflow>();
|
||||
|
||||
export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
|
||||
@@ -37,9 +38,25 @@ export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
|
||||
const entities = await getEntitiesWithRoles(isAdmin(user) ? undefined : entityIDS);
|
||||
const allowedEntities = findAllowedEntities(user, entities, "view_approval_workflows"); */
|
||||
|
||||
|
||||
// replace later with await getApprovalWorkflow(id). Don't think a hook is needed here;
|
||||
const workflows = approvalWorkflowsData as ApprovalWorkflow[];
|
||||
|
||||
const allAssigneeIds: string[] = [
|
||||
...new Set(
|
||||
workflows
|
||||
.map(workflow => workflow.steps
|
||||
.map(step => step.assignees)
|
||||
.flat() as string[] // we are sure assignees coming from a db workflow are all valid strings.
|
||||
).flat() as string[]
|
||||
)
|
||||
];
|
||||
|
||||
return {
|
||||
props: serialize({
|
||||
user,
|
||||
workflows,
|
||||
workflowsAssignees: await getSpecificUsers(allAssigneeIds),
|
||||
userEntitiesWithLabel: await getEntities(user.entities.map(entity => entity.id)),
|
||||
}),
|
||||
};
|
||||
@@ -79,10 +96,12 @@ const STATUS_OPTIONS = [
|
||||
|
||||
interface Props {
|
||||
user: User,
|
||||
workflows: ApprovalWorkflow[],
|
||||
workflowsAssignees: User[],
|
||||
userEntitiesWithLabel: Entity[],
|
||||
}
|
||||
|
||||
export default function ApprovalWorkflows({ user, userEntitiesWithLabel }: Props) {
|
||||
export default function ApprovalWorkflows({ user, workflows, workflowsAssignees, userEntitiesWithLabel }: Props) {
|
||||
|
||||
const ENTITY_OPTIONS = [
|
||||
{
|
||||
@@ -100,13 +119,11 @@ export default function ApprovalWorkflows({ user, userEntitiesWithLabel }: Props
|
||||
.sort((a, b) => a.label.localeCompare(b.label)),
|
||||
];
|
||||
|
||||
const [filteredApprovalWorkflows, setFilteredApprovalWorkflows] = useState<ApprovalWorkflow[]>([]);
|
||||
const [filteredWorkflows, setFilteredWorkflows] = useState<ApprovalWorkflow[]>([]);
|
||||
|
||||
const [statusFilter, setStatusFilter] = useState<CustomStatus>("all");
|
||||
const [entityFilter, setEntityFilter] = useState<CustomEntity>("all");
|
||||
|
||||
const { approvalWorkflows/* , reload */ } = useApprovalWorkflows();
|
||||
|
||||
useEffect(() => {
|
||||
const filters = [];
|
||||
if (statusFilter) {
|
||||
@@ -118,9 +135,9 @@ export default function ApprovalWorkflows({ user, userEntitiesWithLabel }: Props
|
||||
if (filter) filters.push(filter);
|
||||
}
|
||||
|
||||
setFilteredApprovalWorkflows([...filters.reduce((d, f) => d.filter(f), approvalWorkflows)]);
|
||||
setFilteredWorkflows([...filters.reduce((d, f) => d.filter(f), workflows)]);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [approvalWorkflows, statusFilter, entityFilter]);
|
||||
}, [workflows, statusFilter, entityFilter]);
|
||||
|
||||
const deleteApprovalWorkflow = (id: string, name: string) => {
|
||||
if (!confirm(`Are you sure you want to delete this Approval Workflow?`)) return;
|
||||
@@ -193,21 +210,25 @@ export default function ApprovalWorkflows({ user, userEntitiesWithLabel }: Props
|
||||
),
|
||||
}),
|
||||
columnHelper.accessor("steps", {
|
||||
id: "currentApprovers",
|
||||
header: "CURRENT APPROVERS",
|
||||
id: "currentAssignees",
|
||||
header: "CURRENT ASSIGNEES",
|
||||
cell: (info) => {
|
||||
const steps = info.row.original.steps;
|
||||
const currentStep = steps.find((step) => !step.completed);
|
||||
const approvers = currentStep?.assignees || [];
|
||||
|
||||
const assignees = currentStep?.assignees!.map((assigneeId) => {
|
||||
const assignee = workflowsAssignees.find((user) => user.id === assigneeId);
|
||||
return assignee?.name || "Unknown Assignee";
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{approvers.map((approver: string | null | undefined, index: number) => (
|
||||
{assignees?.map((assigneeName: string, index: number) => (
|
||||
<span
|
||||
key={index}
|
||||
className="inline-block rounded-full px-3 py-1 text-sm font-medium bg-gray-100 border border-gray-300 text-gray-900"
|
||||
>
|
||||
{approver}
|
||||
{assigneeName}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
@@ -236,10 +257,17 @@ export default function ApprovalWorkflows({ user, userEntitiesWithLabel }: Props
|
||||
cell: ({ row }: { row: { original: ApprovalWorkflow } }) => {
|
||||
return (
|
||||
<div className="flex gap-4">
|
||||
<Link data-tip="Edit" href={`/approval-workflows/${row.original.id}`} className="cursor-pointer tooltip">
|
||||
<Link onClick={(e) => e.stopPropagation()} data-tip="Edit" href={`/approval-workflows/${row.original.id}/edit`} className="cursor-pointer tooltip">
|
||||
<FaRegEdit className="hover:text-mti-purple-light transition ease-in-out duration-300" />
|
||||
</Link>
|
||||
<button data-tip="Delete" className="cursor-pointer tooltip" onClick={() => deleteApprovalWorkflow(row.original.id, row.original.name)}>
|
||||
<button
|
||||
data-tip="Delete"
|
||||
className="cursor-pointer tooltip"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
deleteApprovalWorkflow(row.original.id, row.original.name);
|
||||
}}
|
||||
>
|
||||
<BsTrash className="hover:text-mti-purple-light transition ease-in-out duration-300" />
|
||||
</button>
|
||||
</div>
|
||||
@@ -249,7 +277,7 @@ export default function ApprovalWorkflows({ user, userEntitiesWithLabel }: Props
|
||||
];
|
||||
|
||||
const table = useReactTable({
|
||||
data: filteredApprovalWorkflows,
|
||||
data: filteredWorkflows,
|
||||
columns: columns,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
});
|
||||
@@ -315,7 +343,7 @@ export default function ApprovalWorkflows({ user, userEntitiesWithLabel }: Props
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<tr key={headerGroup.id}>
|
||||
{headerGroup.headers.map((header) => (
|
||||
<th key={header.id} className="px-2 py-3 text-left text-purple-900">
|
||||
<th key={header.id} className="px-3 py-2 text-left text-purple-900">
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
@@ -338,7 +366,7 @@ export default function ApprovalWorkflows({ user, userEntitiesWithLabel }: Props
|
||||
{row.getVisibleCells().map((cell, cellIndex) => {
|
||||
const lastCellIndex = row.getVisibleCells().length - 1;
|
||||
|
||||
let cellClasses = "px-4 py-2 bg-purple-50 border-y-2 border-purple-300";
|
||||
let cellClasses = "px-3 py-2 bg-purple-50 border-y-2 border-purple-300";
|
||||
if (cellIndex === 0) {
|
||||
cellClasses += " border-l-2 rounded-l-2xl";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user