From 44ccfa7fb969c97d73261fc62d8acb18169c2685 Mon Sep 17 00:00:00 2001 From: Romain Lenzotti Date: Fri, 22 Mar 2024 13:43:56 +0100 Subject: [PATCH] feat(react-formio): add possibility to give custom choices function to column property --- packages/config/package.json | 6 +-- packages/react-formio-container/package.json | 3 +- .../components/defaultCells.component.tsx | 15 ++++-- .../selectColumnFilter.component.spec.tsx | 21 ++++++++ .../filters/selectColumnFilter.component.tsx | 50 ++++++++++++++----- .../table/hooks/useCustomTable.hook.tsx | 32 +++++++++++- .../src/components/table/table.component.tsx | 1 + .../table/utils/mapFormToColumns.tsx | 9 ++-- packages/redux-utils/package.json | 3 +- packages/storybook/package.json | 3 +- packages/tailwind-formio/package.json | 6 +-- packages/tailwind/package.json | 4 +- 12 files changed, 116 insertions(+), 37 deletions(-) diff --git a/packages/config/package.json b/packages/config/package.json index e0e29fe6..f07bfd0f 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -17,7 +17,5 @@ "devDependencies": { "@tsed/tailwind": "2.2.3", "@tsed/yarn-workspaces": "1.19.3" - }, - "dependencies": {}, - "peerDependencies": {} -} \ No newline at end of file + } +} diff --git a/packages/react-formio-container/package.json b/packages/react-formio-container/package.json index f51c6979..08f399aa 100644 --- a/packages/react-formio-container/package.json +++ b/packages/react-formio-container/package.json @@ -89,6 +89,5 @@ "tooltip.js": { "optional": false } - }, - "dependencies": {} + } } diff --git a/packages/react-formio/src/components/table/components/defaultCells.component.tsx b/packages/react-formio/src/components/table/components/defaultCells.component.tsx index a505e1e7..5091e2c6 100644 --- a/packages/react-formio/src/components/table/components/defaultCells.component.tsx +++ b/packages/react-formio/src/components/table/components/defaultCells.component.tsx @@ -1,18 +1,27 @@ import React from "react"; import { Row } from "react-table"; +import type { ExtendedCell } from "../hooks/useCustomTable.hook"; + export function DefaultCells({ row }: { row: Row }) { return ( <> - {row.cells.map((cell, i) => { - const { hidden, colspan } = cell.column as any; + {row.cells.map((cell: ExtendedCell, i) => { + const { hidden, colspan } = cell.column; if (hidden) { return null; } return ( - + {cell.render("Cell") as any} ); diff --git a/packages/react-formio/src/components/table/filters/selectColumnFilter.component.spec.tsx b/packages/react-formio/src/components/table/filters/selectColumnFilter.component.spec.tsx index a82999fb..ef98be12 100644 --- a/packages/react-formio/src/components/table/filters/selectColumnFilter.component.spec.tsx +++ b/packages/react-formio/src/components/table/filters/selectColumnFilter.component.spec.tsx @@ -45,4 +45,25 @@ describe("SelectColumnFilter", () => { expect(screen.queryByText("select-choice-1")).toBeNull(); expect(screen.getByText("fake-choice")).toBeDefined(); }); + + it("should display select with custom choices (function)", async () => { + const mockSetFilter = jest.fn(); + const props = { + name: "data.id", + setFilter: mockSetFilter, + column: { + id: "id", + preFilteredRows: [{ values: { id: "select-choice-1" } }, { values: { id: "select-choice-2" } }], + choices: () => [{ label: "fake-choice", value: "fake-choice" }] + } + }; + + render( + // @ts-ignore + + ); + + expect(screen.queryByText("select-choice-1")).toBeNull(); + expect(screen.getByText("fake-choice")).toBeDefined(); + }); }); diff --git a/packages/react-formio/src/components/table/filters/selectColumnFilter.component.tsx b/packages/react-formio/src/components/table/filters/selectColumnFilter.component.tsx index 948196cd..ee7c4afe 100644 --- a/packages/react-formio/src/components/table/filters/selectColumnFilter.component.tsx +++ b/packages/react-formio/src/components/table/filters/selectColumnFilter.component.tsx @@ -3,24 +3,50 @@ import { FilterProps } from "react-table"; import { Select } from "../../select/select.component"; -export function SelectColumnFilter = {}>({ column }: FilterProps) { - const { id, preFilteredRows, filterValue, setFilter } = column; +export function useSelectColumnFilter = {}>(props: FilterProps) { + const { column } = props; + const { id, preFilteredRows } = column; const { choices: customChoices } = column as any; + const { filterValue, setFilter } = column; - const choices = - customChoices || - [...new Set(preFilteredRows.map((row) => row.values[id]))].filter((value) => value).map((value) => ({ label: value, value })); + const choices = (() => { + if (customChoices) { + if (typeof customChoices === "function") { + return customChoices(props); + } + return customChoices; + } + + return [...new Set(preFilteredRows.map((row) => row.values[id]))] + .filter((value) => value) + .map((value) => ({ + label: value, + value + })); + })(); + + const onChange = (_: string, value: any) => { + setFilter(value || undefined); + }; + + return { + value: filterValue, + onChange, + choices: [{ value: "", label: "All" }].concat(choices) + }; +} + +export function SelectColumnFilter = {}>(props: FilterProps) { + const { value, choices, onChange } = useSelectColumnFilter(props); return (