From f80e50d2d84a9f1b379567ae6dd356c2c4143b0c Mon Sep 17 00:00:00 2001 From: Adam Moussa Date: Fri, 25 Sep 2026 17:05:01 -0400 Subject: [PATCH] fix(web): keep pay date editable on the approved grid --- src/dashboard/DashboardGrids.tsx | 8 ++++++-- src/dashboard/approved-columns.ts | 16 ++++++++++++++++ src/dashboard/columns.test.ts | 22 ++++++++++++++++++++++ src/dashboard/columns.tsx | 6 ++++++ 4 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 src/dashboard/approved-columns.ts diff --git a/src/dashboard/DashboardGrids.tsx b/src/dashboard/DashboardGrids.tsx index d75a151..cd8549c 100644 --- a/src/dashboard/DashboardGrids.tsx +++ b/src/dashboard/DashboardGrids.tsx @@ -5,7 +5,7 @@ import { ColumnsDrawer } from "@/dashboard/ColumnsDrawer"; import { InvoiceFilterToolbar } from "@/dashboard/InvoiceFilterToolbar"; import { CreatePayRunButton } from "@/dashboard/CreatePayRunButton"; import { InvoiceDataGrid } from "@/dashboard/InvoiceDataGrid"; -import { columnsFromCatalogKeys } from "@/dashboard/columns"; +import { columnsForApprovedGrid, columnsFromCatalogKeys } from "@/dashboard/columns"; import { loadColumnPrefs, resetColumnPrefs, @@ -85,6 +85,10 @@ export function DashboardGrids() { () => columnsFromCatalogKeys(columnPrefs.visibleOrder), [columnPrefs.visibleOrder], ); + const approvedColumns = useMemo( + () => columnsForApprovedGrid(columnPrefs.visibleOrder), + [columnPrefs.visibleOrder], + ); const openInvoice = (params: GridRowParams) => { navigate("/invoices/:id", { params: { id: params.row.id } }); @@ -281,7 +285,7 @@ export function DashboardGrids() { setSelection(model)} diff --git a/src/dashboard/approved-columns.ts b/src/dashboard/approved-columns.ts new file mode 100644 index 0000000..176dde7 --- /dev/null +++ b/src/dashboard/approved-columns.ts @@ -0,0 +1,16 @@ +import type { GridColDef } from "@mui/x-data-grid"; +import type { MockInvoice } from "@/mocks"; + +/** Keep one editable pay-date column on the approved grid. */ +export function withEditablePayDate( + columns: GridColDef[], + payDateColumn: GridColDef, +): GridColDef[] { + const next = columns.map((column) => + column.field === "payDate" ? { ...column, editable: true } : column, + ); + if (next.some((column) => column.field === "payDate")) { + return next; + } + return [...next, { ...payDateColumn, editable: true }]; +} diff --git a/src/dashboard/columns.test.ts b/src/dashboard/columns.test.ts index a0cdeb1..4d2cc28 100644 --- a/src/dashboard/columns.test.ts +++ b/src/dashboard/columns.test.ts @@ -1,4 +1,7 @@ +import type { GridColDef } from "@mui/x-data-grid"; import { describe, expect, it } from "vitest"; +import { withEditablePayDate } from "@/dashboard/approved-columns"; +import type { MockInvoice } from "@/mocks"; import { formatRelativeFromIsoDate, formatSlashDate } from "@/dashboard/invoice-date-format"; describe("invoice column date helpers (AP-47)", () => { @@ -26,3 +29,22 @@ describe("invoice column date helpers (AP-47)", () => { expect(formatRelativeFromIsoDate("2026-10-11", now)).toBe("in 2 months"); }); }); + +describe("withEditablePayDate", () => { + const hidden: GridColDef = { field: "vendorName", headerName: "Vendor" }; + const payDate: GridColDef = { field: "payDate", headerName: "Payment Date" }; + + it("appends an editable pay date when the catalog hides Payment Date", () => { + const columns = withEditablePayDate([hidden], payDate); + expect(columns.filter((column) => column.field === "payDate")).toEqual([ + { field: "payDate", headerName: "Payment Date", editable: true }, + ]); + }); + + it("keeps a single editable pay date when Payment Date is already visible", () => { + const columns = withEditablePayDate([hidden, { ...payDate, editable: false }], payDate); + const matches = columns.filter((column) => column.field === "payDate"); + expect(matches).toHaveLength(1); + expect(matches[0]?.editable).toBe(true); + }); +}); diff --git a/src/dashboard/columns.tsx b/src/dashboard/columns.tsx index 3b1ded2..c03a486 100644 --- a/src/dashboard/columns.tsx +++ b/src/dashboard/columns.tsx @@ -4,6 +4,7 @@ import NotificationsNoneOutlinedIcon from "@mui/icons-material/NotificationsNone import VisibilityOutlinedIcon from "@mui/icons-material/VisibilityOutlined"; import { Box, Link as MuiLink, Stack, Typography } from "@mui/material"; import type { GridColDef, GridRenderCellParams } from "@mui/x-data-grid"; +import { withEditablePayDate } from "@/dashboard/approved-columns"; import type { InvoiceColumnKey } from "@/dashboard/column-catalog"; import { formatRelativeFromIsoDate, formatSlashDate } from "@/dashboard/invoice-date-format"; import type { MockInvoice } from "@/mocks"; @@ -250,6 +251,11 @@ export function columnsFromCatalogKeys(keys: InvoiceColumnKey[]): GridColDef catalogColumnDefs[key]); } +/** Approved tab keeps an editable pay date even when the catalog hides Payment Date. */ +export function columnsForApprovedGrid(keys: InvoiceColumnKey[]): GridColDef[] { + return withEditablePayDate(columnsFromCatalogKeys(keys), catalogColumnDefs.paymentDate); +} + export const readyToPayColumns: GridColDef[] = [ { field: "invoiceNumber",