Skip to content

Commit 3bd4c9c

Browse files
committed
feat(react-formio): add possibility to give custom choices function to column property
1 parent 0c0ed88 commit 3bd4c9c

File tree

17 files changed

+1254
-1143
lines changed

17 files changed

+1254
-1143
lines changed

.github/workflows/build.yml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ jobs:
1414
runs-on: ubuntu-latest
1515
strategy:
1616
matrix:
17-
node-version: [18.x]
17+
node-version: [20.x]
1818

1919
steps:
20-
- uses: actions/checkout@v2
20+
- uses: actions/checkout@v3
2121
- name: Use Node.js ${{ matrix.node-version }}
22-
uses: actions/setup-node@v1
22+
uses: actions/setup-node@v3
2323
with:
2424
node-version: ${{ matrix.node-version }}
2525
- name: Install dependencies
@@ -33,12 +33,12 @@ jobs:
3333
strategy:
3434
matrix:
3535
os: [ubuntu-latest]
36-
node-version: [18.x]
36+
node-version: [20.x]
3737

3838
steps:
3939
- uses: actions/checkout@v2
4040
- name: Use Node.js ${{ matrix.node-version }}
41-
uses: actions/setup-node@v1
41+
uses: actions/setup-node@v3
4242
with:
4343
node-version: ${{ matrix.node-version }}
4444
- name: Install dependencies
@@ -53,12 +53,12 @@ jobs:
5353

5454
strategy:
5555
matrix:
56-
node-version: [18.x]
56+
node-version: [20.x]
5757

5858
steps:
59-
- uses: actions/checkout@v2
59+
- uses: actions/checkout@v3
6060
- name: Use Node.js ${{ matrix.node-version }}
61-
uses: actions/setup-node@v1
61+
uses: actions/setup-node@v3
6262
with:
6363
node-version: ${{ matrix.node-version }}
6464
- name: Install dependencies
@@ -84,12 +84,12 @@ jobs:
8484

8585
strategy:
8686
matrix:
87-
node-version: [18.x]
87+
node-version: [20.x]
8888

8989
steps:
9090
- uses: actions/checkout@v2
9191
- name: Use Node.js ${{ matrix.node-version }}
92-
uses: actions/setup-node@v1
92+
uses: actions/setup-node@v3
9393
with:
9494
node-version: ${{ matrix.node-version }}
9595
- name: Install dependencies

.yarnrc.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
nodeLinker: node-modules
22
enableGlobalCache: true
3+
enableImmutableInstalls: false
34
yarnPath: .yarn/releases/yarn-4.1.1.cjs

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@
104104
"prettier": "^2.6.2",
105105
"prettier-eslint": "^14.0.3",
106106
"rimraf": "^3.0.2",
107-
"semantic-release": "19.0.3",
108-
"semantic-release-slack-bot": "3.5.3",
107+
"semantic-release": "23.0.5",
108+
"semantic-release-slack-bot": "4.0.2",
109109
"typescript": "4.9.5",
110110
"webpack": "4.44.2"
111111
},

packages/config/package.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,5 @@
1717
"devDependencies": {
1818
"@tsed/tailwind": "2.2.3",
1919
"@tsed/yarn-workspaces": "1.19.3"
20-
},
21-
"dependencies": {},
22-
"peerDependencies": {}
23-
}
20+
}
21+
}

packages/react-formio-container/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,5 @@
8989
"tooltip.js": {
9090
"optional": false
9191
}
92-
},
93-
"dependencies": {}
92+
}
9493
}

packages/react-formio/src/components/table/components/defaultCells.component.tsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
11
import React from "react";
22
import { Row } from "react-table";
33

4+
import type { ExtendedCell } from "../hooks/useCustomTable.hook";
5+
46
export function DefaultCells<Data extends object = {}>({ row }: { row: Row<Data> }) {
57
return (
68
<>
7-
{row.cells.map((cell, i) => {
8-
const { hidden, colspan } = cell.column as any;
9+
{row.cells.map((cell: ExtendedCell<Data>, i) => {
10+
const { hidden, colspan } = cell.column;
911

1012
if (hidden) {
1113
return null;
1214
}
1315

1416
return (
15-
<td colSpan={colspan} {...cell.getCellProps()} key={`tableInstance.page.cells.${cell.value || "value"}.${i}`}>
17+
<td
18+
colSpan={colspan}
19+
{...cell.getCellProps({
20+
className: cell.column.className,
21+
style: cell.column.style
22+
})}
23+
key={`tableInstance.page.cells.${cell.value || "value"}.${i}`}
24+
>
1625
{cell.render("Cell") as any}
1726
</td>
1827
);

packages/react-formio/src/components/table/filters/selectColumnFilter.component.spec.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,25 @@ describe("SelectColumnFilter", () => {
4545
expect(screen.queryByText("select-choice-1")).toBeNull();
4646
expect(screen.getByText("fake-choice")).toBeDefined();
4747
});
48+
49+
it("should display select with custom choices (function)", async () => {
50+
const mockSetFilter = jest.fn();
51+
const props = {
52+
name: "data.id",
53+
setFilter: mockSetFilter,
54+
column: {
55+
id: "id",
56+
preFilteredRows: [{ values: { id: "select-choice-1" } }, { values: { id: "select-choice-2" } }],
57+
choices: () => [{ label: "fake-choice", value: "fake-choice" }]
58+
}
59+
};
60+
61+
render(
62+
// @ts-ignore
63+
<SelectColumnFilter {...props} />
64+
);
65+
66+
expect(screen.queryByText("select-choice-1")).toBeNull();
67+
expect(screen.getByText("fake-choice")).toBeDefined();
68+
});
4869
});

packages/react-formio/src/components/table/filters/selectColumnFilter.component.tsx

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,50 @@ import { FilterProps } from "react-table";
33

44
import { Select } from "../../select/select.component";
55

6-
export function SelectColumnFilter<D extends Record<string, unknown> = {}>({ column }: FilterProps<D>) {
7-
const { id, preFilteredRows, filterValue, setFilter } = column;
6+
export function useSelectColumnFilter<D extends Record<string, unknown> = {}>(props: FilterProps<D>) {
7+
const { column } = props;
8+
const { id, preFilteredRows } = column;
89
const { choices: customChoices } = column as any;
10+
const { filterValue, setFilter } = column;
911

10-
const choices =
11-
customChoices ||
12-
[...new Set(preFilteredRows.map((row) => row.values[id]))].filter((value) => value).map((value) => ({ label: value, value }));
12+
const choices = (() => {
13+
if (customChoices) {
14+
if (typeof customChoices === "function") {
15+
return customChoices(props);
16+
}
17+
return customChoices;
18+
}
19+
20+
return [...new Set(preFilteredRows.map((row) => row.values[id]))]
21+
.filter((value) => value)
22+
.map((value) => ({
23+
label: value,
24+
value
25+
}));
26+
})();
27+
28+
const onChange = (_: string, value: any) => {
29+
setFilter(value || undefined);
30+
};
31+
32+
return {
33+
value: filterValue,
34+
onChange,
35+
choices: [{ value: "", label: "All" }].concat(choices)
36+
};
37+
}
38+
39+
export function SelectColumnFilter<D extends Record<string, unknown> = {}>(props: FilterProps<D>) {
40+
const { value, choices, onChange } = useSelectColumnFilter(props);
1341

1442
return (
1543
<Select
16-
key={`filter-${column.id}`}
17-
name={`filter-${column.id}`}
44+
key={`filter-${props.column.id}`}
45+
name={`filter-${props.column.id}`}
1846
size={"sm"}
19-
value={filterValue}
20-
choices={[{ value: "", label: "All" }].concat(choices)}
21-
onChange={(name, value) => {
22-
setFilter(value || undefined);
23-
}}
47+
value={value}
48+
choices={choices}
49+
onChange={onChange}
2450
/>
2551
);
2652
}

packages/react-formio/src/components/table/hooks/useCustomTable.hook.tsx

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
import noop from "lodash/noop";
22
import React, { PropsWithChildren, useEffect, useState } from "react";
3-
import { CellProps, FilterProps, Renderer, TableOptions, useFilters, useGroupBy, usePagination, useSortBy, useTable } from "react-table";
3+
import {
4+
Cell,
5+
CellProps,
6+
Column,
7+
FilterProps,
8+
Renderer,
9+
TableOptions,
10+
useFilters,
11+
useGroupBy,
12+
usePagination,
13+
useSortBy,
14+
useTable
15+
} from "react-table";
416

517
import { OnClickOperation, Operation, QueryOptions } from "../../../interfaces";
618
import { Pagination as DefaultPagination } from "../../pagination/pagination.component";
@@ -11,7 +23,25 @@ import { DefaultColumnFilter } from "../filters/defaultColumnFilter.component";
1123
import { swapElements } from "../utils/swapElements";
1224
import { useOperations } from "./useOperations.hook";
1325

26+
export interface ExtraColumnProps {
27+
colspan?: number;
28+
hidden?: boolean;
29+
className?: string;
30+
style?: React.CSSProperties;
31+
}
32+
33+
export type ExtendedColumn<Data extends object = any> = Column<Data> & ExtraColumnProps;
34+
35+
export type ExtendedCell<Data extends object = any> = Cell<Data, any> & {
36+
column: ExtraColumnProps;
37+
};
38+
1439
export interface TableProps<Data extends object = any> extends TableOptions<Data>, Partial<QueryOptions> {
40+
/**
41+
* extended columns interface
42+
*/
43+
columns: ReadonlyArray<ExtendedColumn<Data>>;
44+
1545
className?: string;
1646
/**
1747
* Call the listener when a filter / pagination / sort change.

packages/react-formio/src/components/table/table.component.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React, { PropsWithChildren } from "react";
33

44
import { DrapNDropContainer } from "./components/dragNDropContainer";
55
import { TableProps, useCustomTable } from "./hooks/useCustomTable.hook";
6+
67
export function Table<Data extends object = any>(props: PropsWithChildren<TableProps<Data>>) {
78
const {
89
className,

0 commit comments

Comments
 (0)