From 553a4e639b2aeca268a93a42bb5ed7029f329863 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 --- .../components/defaultCells.component.tsx | 13 +++-- .../selectColumnFilter.component.spec.tsx | 21 ++++++++ .../filters/selectColumnFilter.component.tsx | 50 ++++++++++++++----- 3 files changed, 69 insertions(+), 15 deletions(-) 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..23ed521c 100644 --- a/packages/react-formio/src/components/table/components/defaultCells.component.tsx +++ b/packages/react-formio/src/components/table/components/defaultCells.component.tsx @@ -1,10 +1,10 @@ import React from "react"; -import { Row } from "react-table"; +import { Cell, Row } from "react-table"; export function DefaultCells({ row }: { row: Row }) { return ( <> - {row.cells.map((cell, i) => { + {row.cells.map((cell: Cell & { column: { className?: string; style?: React.CSSProperties } }, i) => { const { hidden, colspan } = cell.column as any; if (hidden) { @@ -12,7 +12,14 @@ export function DefaultCells({ row }: { row: Row } 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 (