From 653728f5e388dde028563c5aa476757490e0a01b Mon Sep 17 00:00:00 2001 From: Greg Haislip <54045190+haislip@users.noreply.github.com> Date: Tue, 17 Dec 2024 09:49:58 -0500 Subject: [PATCH] feat: [sc-63506] Flip -s to 0s in the interest summary export (#1097) Story details: https://app.shortcut.com/homebound-team/story/63506 --- src/components/Table/GridTable.test.tsx | 32 +++++++++++++++++++++---- src/components/Table/GridTableApi.ts | 3 ++- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/components/Table/GridTable.test.tsx b/src/components/Table/GridTable.test.tsx index cd1a5b168..a3c738009 100644 --- a/src/components/Table/GridTable.test.tsx +++ b/src/components/Table/GridTable.test.tsx @@ -13,7 +13,7 @@ import { emptyCell, matchesFilter } from "src/components/Table/utils/utils"; import { Css, Palette } from "src/Css"; import { useComputed } from "src/hooks"; import { SelectField, TextField } from "src/inputs"; -import { noop } from "src/utils"; +import { isDefined, noop } from "src/utils"; import { cell, cellAnd, @@ -27,6 +27,7 @@ import { wait, withRouter, } from "src/utils/rtl"; +import { GridCellContent } from "./components/cell"; // Most of our tests use this simple Row and 2 columns type Data = { name: string; value: number | undefined | null }; @@ -3791,6 +3792,13 @@ describe("GridTable", () => { it("can download csvs", async () => { let api: GridTableApi | undefined; + function amountGridCellContent(amount: number): GridCellContent { + return { + content:
, + value: amount, + }; + } + const columns: GridColumn[] = [ // Given a column returns JSX, but defines a `sortValue` { header: "Name", data: ({ name }) => ({ content:
{name}
, sortValue: name }) }, @@ -3802,23 +3810,37 @@ describe("GridTable", () => { { header: "Value", data: ({ value }) => `${value},${value}` }, // And a column returns a string with a quote in it { header: "Value", data: ({ value }) => `a quoted "${value}" value` }, + // And a column returns when it's a grid cell contect + { header: "GridCellValue", data: ({ value }) => (isDefined(value) ? amountGridCellContent(value) : value) }, // And a column returns undefined { header: "Value", data: () => undefined }, // And a column returns JSX with nothing else { header: "Action", data: () =>
Actions
, isAction: true }, ]; + const csvRows: GridDataRow[] = [ + simpleHeader, + { kind: "data", id: "1", data: { name: "foo", value: 1 } }, + { kind: "data", id: "2", data: { name: "bar", value: 2 } }, + { kind: "data", id: "3", data: { name: "zeroname", value: 0 } }, + { kind: "data", id: "4", data: { name: "nullname", value: null } }, + { kind: "data", id: "5", data: { name: "undefname", value: undefined } }, + ]; + function Test() { api = useGridTableApi(); - return api={api} columns={columns} rows={rows} />; + return api={api} columns={columns} rows={csvRows} />; } await render(); expect((api as GridTableApiImpl).generateCsvContent()).toEqual([ - "Name,Value,Value,Value,Value,Value", - `foo,1,1,"1,1","a quoted ""1"" value",`, - `bar,2,2,"2,2","a quoted ""2"" value",`, + "Name,Value,Value,Value,Value,GridCellValue,Value", + `foo,1,1,"1,1","a quoted ""1"" value",1,`, + `bar,2,2,"2,2","a quoted ""2"" value",2,`, + `zeroname,0,0,"0,0","a quoted ""0"" value",0,`, + `nullname,,null,"null,null","a quoted ""null"" value",,`, + `undefname,,undefined,"undefined,undefined","a quoted ""undefined"" value",,`, ]); }); diff --git a/src/components/Table/GridTableApi.ts b/src/components/Table/GridTableApi.ts index 6ec3151fe..0cda89472 100644 --- a/src/components/Table/GridTableApi.ts +++ b/src/components/Table/GridTableApi.ts @@ -14,6 +14,7 @@ import { import { GridDataRow } from "src/components/Table/components/Row"; import { DiscriminateUnion, Kinded } from "src/components/Table/types"; import { TableState } from "src/components/Table/utils/TableState"; +import { isDefined } from "src/utils"; /** * Creates an `api` handle to drive a `GridTable`. @@ -246,7 +247,7 @@ export class GridTableApiImpl implements GridTableApi { // Anything not isJSX (like a string) we can put into the CSV directly if (!isJSX(content)) return content; // Otherwise use the value/sortValue values - return cell.value ? maybeApply(cell.value) : cell.sortValue ? maybeApply(cell.sortValue) : "-"; + return isDefined(cell.value) ? maybeApply(cell.value) : cell.sortValue ? maybeApply(cell.sortValue) : "-"; // Do we need the "-" handling unclear if we use it ever } else { // ReactNode return isJSX(maybeContent) ? "-" : maybeContent;