@tsed/react-formio 2.2.2 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsed/react-formio",
3
- "version": "2.2.2",
3
+ "version": "2.3.0",
4
4
  "description": "Provide a react formio wrapper. Written in TypeScript.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.modern.js",
@@ -31,8 +31,8 @@
31
31
  "tooltip.js": ">=1.3.3"
32
32
  },
33
33
  "devDependencies": {
34
- "@tsed/tailwind": "2.2.2",
35
- "@tsed/tailwind-formio": "2.2.2"
34
+ "@tsed/tailwind": "2.3.0",
35
+ "@tsed/tailwind-formio": "2.3.0"
36
36
  },
37
37
  "repository": "https://github.com/TypedProject/tsed-formio",
38
38
  "bugs": {
@@ -126,7 +126,7 @@ export function Pagination(props: PaginationProps) {
126
126
  )}
127
127
  {totalLength !== undefined && (
128
128
  <li className={"mb-3 flex items-center"} data-testid='pagination-total-items'>
129
- {i18n("Total")}: <strong>{new Intl.NumberFormat(undefined).format(totalLength)}</strong> {i18n("items")}
129
+ {i18n("Total")}: <strong className='mx-1'>{new Intl.NumberFormat(undefined).format(totalLength)}</strong> {i18n("items")}
130
130
  </li>
131
131
  )}
132
132
  </nav>
@@ -1,18 +1,27 @@
1
1
  import React from "react";
2
2
  import { Row } from "react-table";
3
3
 
4
+ import type { ExtendedCell } from "../hooks/useCustomTable.hook";
5
+
4
6
  export function DefaultCells<Data extends object = {}>({ row }: { row: Row<Data> }) {
5
7
  return (
6
8
  <>
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;
9
11
 
10
12
  if (hidden) {
11
13
  return null;
12
14
  }
13
15
 
14
16
  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
+ >
16
25
  {cell.render("Cell") as any}
17
26
  </td>
18
27
  );
@@ -45,4 +45,25 @@ describe("SelectColumnFilter", () => {
45
45
  expect(screen.queryByText("select-choice-1")).toBeNull();
46
46
  expect(screen.getByText("fake-choice")).toBeDefined();
47
47
  });
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
+ });
48
69
  });
@@ -3,24 +3,50 @@ import { FilterProps } from "react-table";
3
3
 
4
4
  import { Select } from "../../select/select.component";
5
5
 
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;
8
9
  const { choices: customChoices } = column as any;
10
+ const { filterValue, setFilter } = column;
9
11
 
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);
13
41
 
14
42
  return (
15
43
  <Select
16
- key={`filter-${column.id}`}
17
- name={`filter-${column.id}`}
44
+ key={`filter-${props.column.id}`}
45
+ name={`filter-${props.column.id}`}
18
46
  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}
24
50
  />
25
51
  );
26
52
  }
@@ -1,6 +1,18 @@
1
1
  import noop from "lodash/noop";
2
2
  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";
4
16
 
5
17
  import { OnClickOperation, Operation, QueryOptions } from "../../../interfaces";
6
18
  import { Pagination as DefaultPagination } from "../../pagination/pagination.component";
@@ -11,7 +23,25 @@ import { DefaultColumnFilter } from "../filters/defaultColumnFilter.component";
11
23
  import { swapElements } from "../utils/swapElements";
12
24
  import { useOperations } from "./useOperations.hook";
13
25
 
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
+
14
39
  export interface TableProps<Data extends object = any> extends TableOptions<Data>, Partial<QueryOptions> {
40
+ /**
41
+ * extended columns interface
42
+ */
43
+ columns: ReadonlyArray<ExtendedColumn<Data>>;
44
+
15
45
  className?: string;
16
46
  /**
17
47
  * Call the listener when a filter / pagination / sort change.
@@ -3,6 +3,7 @@ import React, { PropsWithChildren } from "react";
3
3
 
4
4
  import { DrapNDropContainer } from "./components/dragNDropContainer";
5
5
  import { TableProps, useCustomTable } from "./hooks/useCustomTable.hook";
6
+
6
7
  export function Table<Data extends object = any>(props: PropsWithChildren<TableProps<Data>>) {
7
8
  const {
8
9
  className,
@@ -1,22 +1,23 @@
1
1
  import { Components, ExtendedComponentSchema } from "formiojs";
2
2
  import FormioUtils from "formiojs/utils";
3
3
  import React from "react";
4
- import { Column } from "react-table";
5
4
 
6
5
  import { FormSchema } from "../../../interfaces";
7
6
  import { DefaultCell } from "../components/defaultCell.component";
8
7
  import { SelectColumnFilter } from "../filters/selectColumnFilter.component";
8
+ import { ExtendedColumn } from "../hooks/useCustomTable.hook";
9
9
 
10
- export function mapFormToColumns(form: FormSchema): Column[] {
11
- const columns: Column[] = [];
10
+ export function mapFormToColumns(form: FormSchema): ExtendedColumn[] {
11
+ const columns: ExtendedColumn[] = [];
12
12
 
13
13
  FormioUtils.eachComponent(form.components, (component: ExtendedComponentSchema) => {
14
14
  if (component.tableView && component.key) {
15
15
  const cmp: any = Components.create(component, {}, null, true);
16
16
 
17
- const column: Column = {
17
+ const column: ExtendedColumn = {
18
18
  Header: component.label || component.title || component.key,
19
19
  accessor: `data.${component.key}`,
20
+ className: "text-center",
20
21
  Cell: (props: any) => <DefaultCell {...props} render={(value: any) => cmp.asString(value)} />
21
22
  };
22
23