diff --git a/apps/web/src/components/allocations/AllocationsClient.tsx b/apps/web/src/components/allocations/AllocationsClient.tsx index 8a8dbb4..5242cab 100644 --- a/apps/web/src/components/allocations/AllocationsClient.tsx +++ b/apps/web/src/components/allocations/AllocationsClient.tsx @@ -25,6 +25,7 @@ import { ALLOCATION_STATUS_BADGE as STATUS_BADGE } from "~/lib/status-styles.js" import { SuccessToast } from "~/components/ui/SuccessToast.js"; import { EmptyState } from "~/components/ui/EmptyState.js"; import { BatchDateShiftModal } from "./BatchDateShiftModal.js"; +import { downloadWorkbookSheets } from "~/lib/workbook-export.js"; import { collapseAllAllocationGroups, createInitialCollapsedAllocationGroups, @@ -191,6 +192,22 @@ export function AllocationsClient() { // eslint-disable-next-line react-hooks/exhaustive-deps }, [filterProjectId, filterResourceId, filterStatus, hidePastProjects, hideCompletedProjects, hideDraftProjects]); + function handleExportExcel() { + const rows: (string | number | null)[][] = [ + ["Resource", "Project", "Role", "Start Date", "End Date", "Hours/Day", "Status"], + ...sorted.map((a) => [ + (a.resource as { displayName?: string } | null | undefined)?.displayName ?? "Unassigned", + (a.project as { shortCode?: string; name?: string } | null | undefined) ? `${(a.project as { shortCode: string }).shortCode} — ${(a.project as { name: string }).name}` : "", + a.role ?? "", + typeof a.startDate === "string" ? a.startDate : (a.startDate as Date).toISOString().slice(0, 10), + typeof a.endDate === "string" ? a.endDate : (a.endDate as Date).toISOString().slice(0, 10), + a.hoursPerDay, + a.status, + ]), + ]; + void downloadWorkbookSheets("allocations.xlsx", [{ name: "Allocations", rows }]); + } + function openCreate() { setEditingAllocation(null); setModalOpen(true); @@ -665,6 +682,20 @@ export function AllocationsClient() { + {sorted.length > 0 && ( + + )} + {viewMode === "grouped" && groups.length > 1 && (