@tsed/react-formio 1.11.2 → 1.12.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/.env +2 -1
- package/craco.config.js +11 -1
- package/dist/components/alert/alert.component.spec.d.ts +1 -0
- package/dist/components/alert/alert.stories.d.ts +15 -0
- package/dist/components/form-action/formAction.stories.d.ts +90 -414
- package/dist/components/input-text/inputText.component.d.ts +1 -1
- package/dist/components/input-text/inputText.component.spec.d.ts +1 -0
- package/dist/components/select/select.component.spec.d.ts +1 -0
- package/dist/components/tabs/tabs.component.spec.d.ts +1 -0
- package/dist/index.js +60 -30
- package/dist/index.js.map +1 -1
- package/dist/index.modern.js +59 -31
- package/dist/index.modern.js.map +1 -1
- package/jest.config.js +1 -1
- package/package.json +5 -9
- package/readme.md +74 -79
- package/src/components/__fixtures__/form-schema.json +10 -42
- package/src/components/__fixtures__/form.fixture.json +1 -1
- package/src/components/actions-table/actionsTable.component.spec.tsx +4 -13
- package/src/components/actions-table/actionsTable.component.tsx +3 -11
- package/src/components/alert/alert.component.spec.tsx +97 -0
- package/src/components/alert/alert.component.tsx +2 -8
- package/src/components/alert/alert.stories.tsx +17 -0
- package/src/components/card/card.component.tsx +1 -5
- package/src/components/form/form.component.tsx +1 -7
- package/src/components/form/useForm.hook.ts +4 -13
- package/src/components/form-access/formAccess.component.tsx +19 -82
- package/src/components/form-access/formAccess.schema.ts +7 -23
- package/src/components/form-access/formAccess.stories.tsx +2 -9
- package/src/components/form-access/formAccess.utils.spec.ts +4 -22
- package/src/components/form-access/formAccess.utils.ts +7 -29
- package/src/components/form-action/formAction.component.tsx +3 -19
- package/src/components/form-action/formAction.stories.tsx +251 -672
- package/src/components/form-builder/formBuilder.component.tsx +4 -13
- package/src/components/form-builder/formBuilder.stories.tsx +12 -24
- package/src/components/form-control/formControl.component.tsx +2 -8
- package/src/components/form-edit/formCtas.component.tsx +5 -23
- package/src/components/form-edit/formEdit.component.tsx +2 -20
- package/src/components/form-edit/formEdit.reducer.ts +2 -8
- package/src/components/form-edit/formEdit.stories.tsx +3 -15
- package/src/components/form-edit/formParameters.component.tsx +3 -20
- package/src/components/form-edit/useFormEdit.hook.ts +2 -9
- package/src/components/form-settings/formSettings.component.spec.tsx +2 -9
- package/src/components/form-settings/formSettings.component.tsx +6 -34
- package/src/components/form-settings/formSettings.stories.tsx +1 -6
- package/src/components/form-settings/formSettings.utils.spec.ts +1 -4
- package/src/components/form-settings/formSettings.utils.ts +2 -7
- package/src/components/forms-table/components/formCell.component.tsx +2 -6
- package/src/components/forms-table/formsTable.component.tsx +2 -7
- package/src/components/input-tags/inputTags.component.tsx +10 -34
- package/src/components/input-tags/inputTags.stories.tsx +4 -14
- package/src/components/input-text/inputText.component.spec.tsx +56 -0
- package/src/components/input-text/inputText.component.tsx +4 -5
- package/src/components/input-text/inputText.stories.tsx +6 -26
- package/src/components/loader/loader.component.tsx +2 -11
- package/src/components/modal/modal.component.spec.tsx +8 -14
- package/src/components/modal/modal.component.tsx +6 -27
- package/src/components/modal/modal.stories.tsx +1 -5
- package/src/components/modal/removeModal.component.tsx +4 -22
- package/src/components/pagination/pagination.component.spec.tsx +12 -38
- package/src/components/pagination/pagination.component.tsx +8 -41
- package/src/components/pagination/pagination.stories.tsx +1 -5
- package/src/components/react-component/reactComponent.component.tsx +3 -11
- package/src/components/select/select.component.spec.tsx +86 -0
- package/src/components/select/select.component.tsx +11 -15
- package/src/components/select/select.stories.tsx +6 -26
- package/src/components/submissions-table/submissionsTable.component.tsx +1 -3
- package/src/components/submissions-table/submissionsTable.stories.tsx +1 -1
- package/src/components/table/components/defaultArrowSort.component.tsx +1 -10
- package/src/components/table/components/defaultCell.component.tsx +1 -4
- package/src/components/table/components/defaultCellHeader.component.tsx +4 -14
- package/src/components/table/components/defaultCellOperations.component.tsx +14 -25
- package/src/components/table/components/defaultOperationButton.component.tsx +2 -10
- package/src/components/table/filters/defaultColumnFilter.component.spec.tsx +1 -1
- package/src/components/table/filters/selectColumnFilter.component.spec.tsx +2 -10
- package/src/components/table/filters/selectColumnFilter.component.tsx +2 -6
- package/src/components/table/table.component.tsx +13 -53
- package/src/components/table/table.stories.tsx +1 -1
- package/src/components/table/utils/getPageNumbers.ts +3 -11
- package/src/components/table/utils/mapFormToColumns.tsx +14 -22
- package/src/components/table/utils/useOperations.hook.tsx +2 -12
- package/src/components/tabs/tabs.component.spec.tsx +86 -0
- package/src/components/tabs/tabs.component.stories.tsx +2 -9
- package/src/components/tabs/tabs.component.tsx +9 -43
- package/src/interfaces/Operation.ts +1 -4
- package/src/react-table.d.ts +9 -28
- package/src/stores/action/action.actions.ts +31 -33
- package/src/stores/action/action.reducers.spec.ts +1 -8
- package/src/stores/action/action.reducers.ts +1 -8
- package/src/stores/action/action.selectors.ts +1 -2
- package/src/stores/action-info/action-info.actions.spec.ts +1 -5
- package/src/stores/action-info/action-info.actions.ts +16 -19
- package/src/stores/action-info/action-info.reducers.spec.ts +1 -6
- package/src/stores/action-info/action-info.reducers.ts +1 -6
- package/src/stores/action-info/action-info.selectors.ts +1 -4
- package/src/stores/actions/actions.actions.spec.ts +1 -6
- package/src/stores/actions/actions.actions.ts +16 -19
- package/src/stores/actions/actions.reducers.spec.ts +1 -6
- package/src/stores/actions/actions.reducers.ts +1 -6
- package/src/stores/actions/actions.selectors.ts +2 -4
- package/src/stores/auth/auth.reducers.ts +1 -4
- package/src/stores/auth/auth.selectors.spec.ts +1 -5
- package/src/stores/auth/auth.selectors.ts +3 -6
- package/src/stores/auth/auth.utils.tsx +2 -8
- package/src/stores/auth/getAccess.action.spec.ts +11 -54
- package/src/stores/auth/getAccess.action.ts +1 -6
- package/src/stores/auth/initAuth.action.ts +15 -17
- package/src/stores/form/form.actions.spec.ts +8 -39
- package/src/stores/form/form.actions.ts +55 -64
- package/src/stores/form/form.reducers.spec.ts +1 -7
- package/src/stores/form/form.reducers.ts +1 -8
- package/src/stores/form/form.selectors.ts +1 -2
- package/src/stores/forms/forms.actions.spec.ts +5 -18
- package/src/stores/forms/forms.actions.ts +17 -21
- package/src/stores/forms/forms.reducers.spec.ts +1 -6
- package/src/stores/forms/forms.reducers.ts +2 -13
- package/src/stores/forms/forms.selectors.ts +2 -4
- package/src/stores/index.spec.ts +6 -9
- package/src/stores/root/root.selectors.spec.ts +1 -6
- package/src/stores/root/root.selectors.ts +6 -24
- package/src/stores/submission/submission.actions.spec.ts +11 -33
- package/src/stores/submission/submission.actions.ts +57 -66
- package/src/stores/submission/submission.reducers.spec.ts +17 -27
- package/src/stores/submission/submission.reducers.ts +1 -4
- package/src/stores/submission/submission.selectors.ts +1 -4
- package/src/stores/submissions/submissions.actions.spec.ts +5 -18
- package/src/stores/submissions/submissions.actions.ts +17 -26
- package/src/stores/submissions/submissions.reducers.spec.ts +3 -12
- package/src/stores/submissions/submissions.reducers.ts +3 -17
- package/src/stores/submissions/submissions.selectors.spec.ts +1 -4
- package/src/stores/submissions/submissions.selectors.ts +2 -4
- package/src/utils/getEventValue.ts +1 -4
- package/src/utils/iconClass.ts +2 -10
- package/src/utils/mapPagination.ts +1 -6
- package/src/utils/mapRequestParams.ts +2 -12
- package/src/utils/url.test.ts +4 -12
- package/src/utils/url.ts +2 -7
- package/tsconfig.json +4 -12
- package/tsconfig.test.json +1 -1
- package/.eslintrc +0 -47
- package/.prettierrc +0 -10
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { fireEvent, render } from "@testing-library/react";
|
|
3
|
+
import { Choicesjs, Sandbox } from "./select.stories";
|
|
4
|
+
|
|
5
|
+
describe("Select", () => {
|
|
6
|
+
describe("select component Sandbox version", () => {
|
|
7
|
+
it("should render the select component", () => {
|
|
8
|
+
const { getByTestId } = render(<Sandbox {...Sandbox.args} name={"test-sandbox"} />);
|
|
9
|
+
|
|
10
|
+
expect(getByTestId("select_test-sandbox")).toBeInTheDocument();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it("should render the select component with a different size", () => {
|
|
14
|
+
const { getByTestId } = render(<Sandbox {...Sandbox.args} size='small' name={"test-sandbox"} />);
|
|
15
|
+
const select = getByTestId("select_test-sandbox");
|
|
16
|
+
expect(select).toBeInTheDocument();
|
|
17
|
+
expect(select).toHaveClass("form-control-small");
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("should render select options with 'Placeholder test' as first value", () => {
|
|
21
|
+
const choices = [
|
|
22
|
+
{ label: "test1", value: "value1" },
|
|
23
|
+
{ label: "test2", value: "value2" }
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
const placeHolderTest = "Placeholder test";
|
|
27
|
+
|
|
28
|
+
const { getByRole } = render(<Sandbox {...Sandbox.args} placeholder={placeHolderTest} choices={choices} name={"test-sandbox"} />);
|
|
29
|
+
|
|
30
|
+
expect(getByRole("option", { name: "Placeholder test" })).toBeInTheDocument();
|
|
31
|
+
expect(getByRole("option", { name: "test1" })).toBeInTheDocument();
|
|
32
|
+
expect(getByRole("option", { name: "test2" })).toBeInTheDocument();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("should have Placeholder label as selected option by default", () => {
|
|
36
|
+
const choices = [
|
|
37
|
+
{ label: "test1", value: "value1" },
|
|
38
|
+
{ label: "test2", value: "value2" }
|
|
39
|
+
];
|
|
40
|
+
const placeHolderTest = "Placeholder test";
|
|
41
|
+
|
|
42
|
+
const { getByRole } = render(<Sandbox {...Sandbox.args} placeholder={placeHolderTest} choices={choices} name={"test-sandbox"} />);
|
|
43
|
+
const option = getByRole("option", { name: placeHolderTest }) as HTMLOptionElement;
|
|
44
|
+
|
|
45
|
+
expect(option.selected).toBeTruthy();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("should change the value of the selected option when you click on another choice", () => {
|
|
49
|
+
const choices = [
|
|
50
|
+
{ label: "test1", value: "value1" },
|
|
51
|
+
{ label: "test2", value: "value2" }
|
|
52
|
+
];
|
|
53
|
+
const placeHolderTest = "Placeholder test";
|
|
54
|
+
const onChange = jest.fn();
|
|
55
|
+
|
|
56
|
+
const { getByRole, getByTestId } = render(
|
|
57
|
+
<Sandbox {...Sandbox.args} placeholder={placeHolderTest} choices={choices} name={"test-sandbox"} onChange={onChange} />
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
fireEvent.change(getByTestId("select_test-sandbox"), {
|
|
61
|
+
target: { value: "value1" }
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const option = getByRole("option", { name: "test1" }) as HTMLOptionElement;
|
|
65
|
+
|
|
66
|
+
expect(option.selected).toBeTruthy();
|
|
67
|
+
expect(onChange).toHaveBeenCalledWith("test-sandbox", "value1");
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
describe("select component Choicesjs version", () => {
|
|
72
|
+
it("should render select options with 'test1' as first value", () => {
|
|
73
|
+
const choices = [
|
|
74
|
+
{ label: "test1", value: "value1" },
|
|
75
|
+
{ label: "test2", value: "value2" }
|
|
76
|
+
];
|
|
77
|
+
const placeHolderTest = "Placeholder test";
|
|
78
|
+
|
|
79
|
+
const { getByRole } = render(
|
|
80
|
+
<Choicesjs {...Choicesjs.args} layout={"choicesjs"} choices={choices} placeholder={placeHolderTest} name={"test-choicesjs"} />
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
expect(getByRole("option", { name: "test1" })).toBeInTheDocument();
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
});
|
|
@@ -3,10 +3,7 @@ import classnames from "classnames";
|
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
4
|
import React, { ReactElement, useEffect, useRef } from "react";
|
|
5
5
|
import { getEventValue } from "../../utils/getEventValue";
|
|
6
|
-
import {
|
|
7
|
-
FormControl,
|
|
8
|
-
FormControlProps
|
|
9
|
-
} from "../form-control/formControl.component";
|
|
6
|
+
import { FormControl, FormControlProps } from "../form-control/formControl.component";
|
|
10
7
|
|
|
11
8
|
export interface SelectProps<T = any> extends FormControlProps {
|
|
12
9
|
value?: any;
|
|
@@ -27,7 +24,7 @@ export function Select<T = any>({
|
|
|
27
24
|
onChange,
|
|
28
25
|
required,
|
|
29
26
|
value,
|
|
30
|
-
choices
|
|
27
|
+
choices,
|
|
31
28
|
description,
|
|
32
29
|
placeholder,
|
|
33
30
|
prefix,
|
|
@@ -56,18 +53,17 @@ export function Select<T = any>({
|
|
|
56
53
|
choices =
|
|
57
54
|
layout === "choicesjs" || multiple || !placeholder
|
|
58
55
|
? choices
|
|
59
|
-
: ([
|
|
56
|
+
: ([
|
|
57
|
+
{
|
|
58
|
+
label: placeholder,
|
|
59
|
+
value: ""
|
|
60
|
+
},
|
|
61
|
+
...choices
|
|
62
|
+
] as any[]);
|
|
60
63
|
|
|
61
64
|
return (
|
|
62
|
-
<FormControl
|
|
63
|
-
|
|
64
|
-
label={label}
|
|
65
|
-
required={required}
|
|
66
|
-
description={description}
|
|
67
|
-
prefix={prefix}
|
|
68
|
-
suffix={suffix}
|
|
69
|
-
shadow={false}
|
|
70
|
-
>
|
|
65
|
+
<FormControl name={name} label={label} required={required} description={description} prefix={prefix} suffix={suffix} shadow={false}>
|
|
66
|
+
{/* eslint-disable-next-line jsx-a11y/no-onchange */}
|
|
71
67
|
<select
|
|
72
68
|
ref={ref}
|
|
73
69
|
{...props}
|
|
@@ -8,13 +8,13 @@ const choices = [
|
|
|
8
8
|
];
|
|
9
9
|
|
|
10
10
|
const useValue = (args: any) => {
|
|
11
|
-
const [value,
|
|
11
|
+
const [value, setValue] = useState(args.value);
|
|
12
12
|
|
|
13
13
|
return {
|
|
14
14
|
...args,
|
|
15
15
|
value,
|
|
16
16
|
onChange(name: string, value: any) {
|
|
17
|
-
|
|
17
|
+
setValue(value);
|
|
18
18
|
args.onChange(name, value);
|
|
19
19
|
}
|
|
20
20
|
};
|
|
@@ -92,12 +92,7 @@ Choicesjs.args = {
|
|
|
92
92
|
};
|
|
93
93
|
|
|
94
94
|
export const ChoicesjsPrefix = (args: any) => {
|
|
95
|
-
return (
|
|
96
|
-
<Select
|
|
97
|
-
prefix={<i className={iconClass(undefined, "calendar")} />}
|
|
98
|
-
{...useValue(args)}
|
|
99
|
-
/>
|
|
100
|
-
);
|
|
95
|
+
return <Select prefix={<i className={iconClass(undefined, "calendar")} />} {...useValue(args)} />;
|
|
101
96
|
};
|
|
102
97
|
|
|
103
98
|
ChoicesjsPrefix.args = {
|
|
@@ -111,12 +106,7 @@ ChoicesjsPrefix.args = {
|
|
|
111
106
|
};
|
|
112
107
|
|
|
113
108
|
export const WithPrefix = (args: any) => {
|
|
114
|
-
return (
|
|
115
|
-
<Select
|
|
116
|
-
prefix={<i className={iconClass(undefined, "calendar")} />}
|
|
117
|
-
{...useValue(args)}
|
|
118
|
-
/>
|
|
119
|
-
);
|
|
109
|
+
return <Select prefix={<i className={iconClass(undefined, "calendar")} />} {...useValue(args)} />;
|
|
120
110
|
};
|
|
121
111
|
|
|
122
112
|
WithPrefix.args = {
|
|
@@ -128,12 +118,7 @@ WithPrefix.args = {
|
|
|
128
118
|
};
|
|
129
119
|
|
|
130
120
|
export const WithSuffix = (args: any) => {
|
|
131
|
-
return (
|
|
132
|
-
<Select
|
|
133
|
-
suffix={<i className={iconClass(undefined, "calendar")} />}
|
|
134
|
-
{...useValue(args)}
|
|
135
|
-
/>
|
|
136
|
-
);
|
|
121
|
+
return <Select suffix={<i className={iconClass(undefined, "calendar")} />} {...useValue(args)} />;
|
|
137
122
|
};
|
|
138
123
|
|
|
139
124
|
WithSuffix.args = {
|
|
@@ -174,12 +159,7 @@ ChoicesjsMultiple.args = {
|
|
|
174
159
|
};
|
|
175
160
|
|
|
176
161
|
export const Sizing = (args: any) => {
|
|
177
|
-
return (
|
|
178
|
-
<Select
|
|
179
|
-
suffix={<i className={iconClass(undefined, "dollar")} />}
|
|
180
|
-
{...useValue(args)}
|
|
181
|
-
/>
|
|
182
|
-
);
|
|
162
|
+
return <Select suffix={<i className={iconClass(undefined, "dollar")} />} {...useValue(args)} />;
|
|
183
163
|
};
|
|
184
164
|
|
|
185
165
|
Sizing.args = {
|
|
@@ -8,9 +8,7 @@ export type SubmissionsTableProps = Omit<TableProps<Submission>, "columns"> & {
|
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
export function SubmissionsTable({ form, ...props }: SubmissionsTableProps) {
|
|
11
|
-
const columns: any[] = React.useMemo(() => form && mapFormToColumns(form), [
|
|
12
|
-
form
|
|
13
|
-
]);
|
|
11
|
+
const columns: any[] = React.useMemo(() => form && mapFormToColumns(form), [form]);
|
|
14
12
|
|
|
15
13
|
return <Table {...props} columns={columns} />;
|
|
16
14
|
}
|
|
@@ -5,16 +5,7 @@ export function DefaultArrowSort({ column }: any) {
|
|
|
5
5
|
const { isSorted, isSortedDesc } = column;
|
|
6
6
|
return (
|
|
7
7
|
<span className={"table-arrow-sort"}>
|
|
8
|
-
{isSorted ? (
|
|
9
|
-
<i
|
|
10
|
-
className={iconClass(
|
|
11
|
-
undefined,
|
|
12
|
-
isSortedDesc ? "sort-up" : "sort-down"
|
|
13
|
-
)}
|
|
14
|
-
/>
|
|
15
|
-
) : (
|
|
16
|
-
""
|
|
17
|
-
)}
|
|
8
|
+
{isSorted ? <i className={iconClass(undefined, isSortedDesc ? "sort-up" : "sort-down")} /> : ""}
|
|
18
9
|
</span>
|
|
19
10
|
);
|
|
20
11
|
}
|
|
@@ -1,29 +1,19 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { HeaderGroup } from "react-table";
|
|
3
3
|
|
|
4
|
-
export interface DefaultCellHeaderProps<Data extends object = any>
|
|
5
|
-
extends Record<string, unknown> {
|
|
4
|
+
export interface DefaultCellHeaderProps<Data extends object = any> extends Record<string, unknown> {
|
|
6
5
|
column: HeaderGroup<Data>;
|
|
7
6
|
}
|
|
8
7
|
|
|
9
|
-
export function DefaultCellHeader<Data extends Record<string, unknown> = {}>({
|
|
10
|
-
column
|
|
11
|
-
}: DefaultCellHeaderProps) {
|
|
8
|
+
export function DefaultCellHeader<Data extends Record<string, unknown> = {}>({ column }: DefaultCellHeaderProps) {
|
|
12
9
|
return (
|
|
13
10
|
<div className={"table-cell-header"}>
|
|
14
|
-
<div
|
|
15
|
-
className='table-cell-header__label'
|
|
16
|
-
{...column.getSortByToggleProps()}
|
|
17
|
-
>
|
|
11
|
+
<div className='table-cell-header__label' {...column.getSortByToggleProps()}>
|
|
18
12
|
<span>{column.render("Header")}</span>
|
|
19
13
|
|
|
20
14
|
{column.render("ArrowSort")}
|
|
21
15
|
</div>
|
|
22
|
-
{column.canFilter ? (
|
|
23
|
-
<div className='table-cell-header__filter'>
|
|
24
|
-
{column.render("Filter")}
|
|
25
|
-
</div>
|
|
26
|
-
) : null}
|
|
16
|
+
{column.canFilter ? <div className='table-cell-header__filter'>{column.render("Filter")}</div> : null}
|
|
27
17
|
</div>
|
|
28
18
|
);
|
|
29
19
|
}
|
|
@@ -1,36 +1,25 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { DefaultOperationButton } from "./defaultOperationButton.component";
|
|
3
3
|
|
|
4
|
-
export function DefaultCellOperations({
|
|
5
|
-
operations,
|
|
6
|
-
row,
|
|
7
|
-
onClick,
|
|
8
|
-
ctx,
|
|
9
|
-
i18n
|
|
10
|
-
}: any) {
|
|
4
|
+
export function DefaultCellOperations({ operations, row, onClick, ctx, i18n }: any) {
|
|
11
5
|
const data = row.original;
|
|
12
6
|
|
|
13
7
|
return (
|
|
14
8
|
<div className='btn-group'>
|
|
15
9
|
{operations
|
|
16
|
-
.filter(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
ctx={ctx}
|
|
30
|
-
/>
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
)}
|
|
10
|
+
.filter(({ permissionsResolver }: any) => !permissionsResolver || permissionsResolver(data, ctx))
|
|
11
|
+
.map(({ OperationButton = DefaultOperationButton, ...operation }: any) => {
|
|
12
|
+
return (
|
|
13
|
+
<OperationButton
|
|
14
|
+
key={operation.action}
|
|
15
|
+
{...operation}
|
|
16
|
+
onClick={(action: string) => onClick(data, action)}
|
|
17
|
+
data={data}
|
|
18
|
+
i18n={i18n}
|
|
19
|
+
ctx={ctx}
|
|
20
|
+
/>
|
|
21
|
+
);
|
|
22
|
+
})}
|
|
34
23
|
</div>
|
|
35
24
|
);
|
|
36
25
|
}
|
|
@@ -31,13 +31,7 @@ export function DefaultOperationButton(props: OperationButtonProps) {
|
|
|
31
31
|
|
|
32
32
|
return (
|
|
33
33
|
<button
|
|
34
|
-
className={classnames(
|
|
35
|
-
className,
|
|
36
|
-
["btn", buttonOutline && "outline", buttonType]
|
|
37
|
-
.filter(Boolean)
|
|
38
|
-
.join("-"),
|
|
39
|
-
`btn-${buttonSize}`
|
|
40
|
-
)}
|
|
34
|
+
className={classnames(className, ["btn", buttonOutline && "outline", buttonType].filter(Boolean).join("-"), `btn-${buttonSize}`)}
|
|
41
35
|
onClick={stopPropagationWrapper(() => onClick(action))}
|
|
42
36
|
>
|
|
43
37
|
{icon ? (
|
|
@@ -45,9 +39,7 @@ export function DefaultOperationButton(props: OperationButtonProps) {
|
|
|
45
39
|
<i className={iconClass(undefined, icon)} /> {title && " "}
|
|
46
40
|
</>
|
|
47
41
|
) : null}
|
|
48
|
-
{title && (
|
|
49
|
-
<span className={icon && title ? "ml-1" : ""}>{i18n(title)}</span>
|
|
50
|
-
)}
|
|
42
|
+
{title && <span className={icon && title ? "ml-1" : ""}>{i18n(title)}</span>}
|
|
51
43
|
</button>
|
|
52
44
|
);
|
|
53
45
|
}
|
|
@@ -13,13 +13,13 @@ describe("DefaultColumnFilter", () => {
|
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
const { getByRole } = render(
|
|
16
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
17
16
|
// @ts-ignore
|
|
18
17
|
<DefaultColumnFilter {...props} />
|
|
19
18
|
);
|
|
20
19
|
|
|
21
20
|
const input = getByRole("textbox");
|
|
22
21
|
|
|
22
|
+
// eslint-disable-next-line testing-library/no-unnecessary-act
|
|
23
23
|
await act(async () => {
|
|
24
24
|
fireEvent.change(input, { target: { value: "value-test" } });
|
|
25
25
|
|
|
@@ -11,15 +11,11 @@ describe("SelectColumnFilter", () => {
|
|
|
11
11
|
setFilter: mockSetFilter,
|
|
12
12
|
column: {
|
|
13
13
|
id: "id",
|
|
14
|
-
preFilteredRows: [
|
|
15
|
-
{ values: { id: "select-choice-1" } },
|
|
16
|
-
{ values: { id: "select-choice-2" } }
|
|
17
|
-
]
|
|
14
|
+
preFilteredRows: [{ values: { id: "select-choice-1" } }, { values: { id: "select-choice-2" } }]
|
|
18
15
|
}
|
|
19
16
|
};
|
|
20
17
|
|
|
21
18
|
const { getByText } = render(
|
|
22
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
23
19
|
// @ts-ignore
|
|
24
20
|
<SelectColumnFilter {...props} />
|
|
25
21
|
);
|
|
@@ -34,16 +30,12 @@ describe("SelectColumnFilter", () => {
|
|
|
34
30
|
setFilter: mockSetFilter,
|
|
35
31
|
column: {
|
|
36
32
|
id: "id",
|
|
37
|
-
preFilteredRows: [
|
|
38
|
-
{ values: { id: "select-choice-1" } },
|
|
39
|
-
{ values: { id: "select-choice-2" } }
|
|
40
|
-
],
|
|
33
|
+
preFilteredRows: [{ values: { id: "select-choice-1" } }, { values: { id: "select-choice-2" } }],
|
|
41
34
|
choices: [{ label: "fake-choice", value: "fake-choice" }]
|
|
42
35
|
}
|
|
43
36
|
};
|
|
44
37
|
|
|
45
38
|
const { queryByText, getByText } = render(
|
|
46
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
47
39
|
// @ts-ignore
|
|
48
40
|
<SelectColumnFilter {...props} />
|
|
49
41
|
);
|
|
@@ -2,17 +2,13 @@ import React from "react";
|
|
|
2
2
|
import { FilterProps } from "react-table";
|
|
3
3
|
import { Select } from "../../select/select.component";
|
|
4
4
|
|
|
5
|
-
export function SelectColumnFilter<D extends Record<string, unknown> = {}>({
|
|
6
|
-
column
|
|
7
|
-
}: FilterProps<D>) {
|
|
5
|
+
export function SelectColumnFilter<D extends Record<string, unknown> = {}>({ column }: FilterProps<D>) {
|
|
8
6
|
const { id, preFilteredRows, filterValue, setFilter } = column;
|
|
9
7
|
const { choices: customChoices } = column as any;
|
|
10
8
|
|
|
11
9
|
const choices =
|
|
12
10
|
customChoices ||
|
|
13
|
-
[...new Set(preFilteredRows.map((row) => row.values[id]))]
|
|
14
|
-
.filter((value) => value)
|
|
15
|
-
.map((value) => ({ label: value, value }));
|
|
11
|
+
[...new Set(preFilteredRows.map((row) => row.values[id]))].filter((value) => value).map((value) => ({ label: value, value }));
|
|
16
12
|
|
|
17
13
|
return (
|
|
18
14
|
<Select
|
|
@@ -1,30 +1,15 @@
|
|
|
1
1
|
import classnames from "classnames";
|
|
2
2
|
import noop from "lodash/noop";
|
|
3
3
|
import React, { PropsWithChildren } from "react";
|
|
4
|
-
import {
|
|
5
|
-
CellProps,
|
|
6
|
-
FilterProps,
|
|
7
|
-
Renderer,
|
|
8
|
-
TableOptions,
|
|
9
|
-
useFilters,
|
|
10
|
-
useGroupBy,
|
|
11
|
-
usePagination,
|
|
12
|
-
useSortBy,
|
|
13
|
-
useTable
|
|
14
|
-
} from "react-table";
|
|
4
|
+
import { CellProps, FilterProps, Renderer, TableOptions, useFilters, useGroupBy, usePagination, useSortBy, useTable } from "react-table";
|
|
15
5
|
import { OnClickOperation, Operation, QueryOptions } from "../../interfaces";
|
|
16
6
|
import { Pagination as DefaultPagination } from "../pagination/pagination.component";
|
|
17
7
|
import { DefaultArrowSort } from "./components/defaultArrowSort.component";
|
|
18
|
-
import {
|
|
19
|
-
DefaultCellHeader,
|
|
20
|
-
DefaultCellHeaderProps
|
|
21
|
-
} from "./components/defaultCellHeader.component";
|
|
8
|
+
import { DefaultCellHeader, DefaultCellHeaderProps } from "./components/defaultCellHeader.component";
|
|
22
9
|
import { DefaultColumnFilter } from "./filters/defaultColumnFilter.component";
|
|
23
10
|
import { useOperations } from "./utils/useOperations.hook";
|
|
24
11
|
|
|
25
|
-
export interface TableProps<Data extends object = any>
|
|
26
|
-
extends TableOptions<Data>,
|
|
27
|
-
Partial<QueryOptions> {
|
|
12
|
+
export interface TableProps<Data extends object = any> extends TableOptions<Data>, Partial<QueryOptions> {
|
|
28
13
|
className?: string;
|
|
29
14
|
/**
|
|
30
15
|
* Call the listener when a filter / pagination / sort change.
|
|
@@ -93,14 +78,9 @@ export interface TableProps<Data extends object = any>
|
|
|
93
78
|
i18n?: (f: string) => string;
|
|
94
79
|
}
|
|
95
80
|
|
|
96
|
-
function getOperationCallback(
|
|
97
|
-
operations: Operation[],
|
|
98
|
-
onClick: OnClickOperation
|
|
99
|
-
) {
|
|
81
|
+
function getOperationCallback(operations: Operation[], onClick: OnClickOperation) {
|
|
100
82
|
return (data: any, action: string) => {
|
|
101
|
-
const operation = operations.find(
|
|
102
|
-
(operation) => operation.action === action || operation.alias === action
|
|
103
|
-
);
|
|
83
|
+
const operation = operations.find((operation) => operation.action === action || operation.alias === action);
|
|
104
84
|
if (operation) {
|
|
105
85
|
onClick(data, operation);
|
|
106
86
|
}
|
|
@@ -108,9 +88,7 @@ function getOperationCallback(
|
|
|
108
88
|
}
|
|
109
89
|
|
|
110
90
|
function DefaultLoader() {
|
|
111
|
-
return
|
|
112
|
-
<div className={"text-center p-2 pb-4 font-bold"}>Loading in progress</div>
|
|
113
|
-
);
|
|
91
|
+
return <div className={"text-center p-2 pb-4 font-bold"}>Loading in progress</div>;
|
|
114
92
|
}
|
|
115
93
|
|
|
116
94
|
function DefaultEmptyData() {
|
|
@@ -119,9 +97,7 @@ function DefaultEmptyData() {
|
|
|
119
97
|
|
|
120
98
|
const hooks = [useFilters, useGroupBy, useSortBy, usePagination];
|
|
121
99
|
|
|
122
|
-
export function Table<Data extends object = any>(
|
|
123
|
-
props: PropsWithChildren<TableProps<Data>>
|
|
124
|
-
) {
|
|
100
|
+
export function Table<Data extends object = any>(props: PropsWithChildren<TableProps<Data>>) {
|
|
125
101
|
const {
|
|
126
102
|
children,
|
|
127
103
|
className = "",
|
|
@@ -177,12 +153,9 @@ export function Table<Data extends object = any>(
|
|
|
177
153
|
pageSize: controlledPageSize || 10,
|
|
178
154
|
sortBy: controlledSortBy || []
|
|
179
155
|
} as any,
|
|
180
|
-
manualPagination:
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
props.manualSortBy === undefined ? true : props.manualPagination,
|
|
184
|
-
manualFilters:
|
|
185
|
-
props.manualFilters === undefined ? true : props.manualFilters,
|
|
156
|
+
manualPagination: props.manualPagination === undefined ? true : props.manualPagination,
|
|
157
|
+
manualSortBy: props.manualSortBy === undefined ? true : props.manualPagination,
|
|
158
|
+
manualFilters: props.manualFilters === undefined ? true : props.manualFilters,
|
|
186
159
|
disableFilters,
|
|
187
160
|
filterId,
|
|
188
161
|
setFilterId
|
|
@@ -216,10 +189,7 @@ export function Table<Data extends object = any>(
|
|
|
216
189
|
>
|
|
217
190
|
<thead>
|
|
218
191
|
{tableInstance.headerGroups.map((headerGroup, i) => (
|
|
219
|
-
<tr
|
|
220
|
-
key={`tableInstance.headerGroups${i}`}
|
|
221
|
-
{...headerGroup.getHeaderGroupProps()}
|
|
222
|
-
>
|
|
192
|
+
<tr key={`tableInstance.headerGroups${i}`} {...headerGroup.getHeaderGroupProps()}>
|
|
223
193
|
{headerGroup.headers.map((column) => (
|
|
224
194
|
<th
|
|
225
195
|
key={`tableInstance.headers.column.${column.id}`}
|
|
@@ -237,24 +207,14 @@ export function Table<Data extends object = any>(
|
|
|
237
207
|
{tableInstance.page.map((row) => {
|
|
238
208
|
tableInstance.prepareRow(row);
|
|
239
209
|
return (
|
|
240
|
-
<tr
|
|
241
|
-
key={`tableInstance.page.${row.id}`}
|
|
242
|
-
onClick={() => _onClick(row.original, "row")}
|
|
243
|
-
{...row.getRowProps()}
|
|
244
|
-
>
|
|
210
|
+
<tr key={`tableInstance.page.${row.id}`} onClick={() => _onClick(row.original, "row")} {...row.getRowProps()}>
|
|
245
211
|
{row.cells.map((cell, i) => {
|
|
246
212
|
const { hidden, colspan } = cell.column as any;
|
|
247
213
|
if (hidden) {
|
|
248
214
|
return null;
|
|
249
215
|
}
|
|
250
216
|
return (
|
|
251
|
-
<td
|
|
252
|
-
key={`tableInstance.page.cells.${
|
|
253
|
-
cell.value || "value"
|
|
254
|
-
}.${i}`}
|
|
255
|
-
colSpan={colspan}
|
|
256
|
-
{...cell.getCellProps()}
|
|
257
|
-
>
|
|
217
|
+
<td key={`tableInstance.page.cells.${cell.value || "value"}.${i}`} colSpan={colspan} {...cell.getCellProps()}>
|
|
258
218
|
{cell.render("Cell")}
|
|
259
219
|
</td>
|
|
260
220
|
);
|
|
@@ -13,23 +13,15 @@ function range(from: number, to: number, step = 1): any[] {
|
|
|
13
13
|
return range;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
export function getPageNumbers({
|
|
17
|
-
currentPage,
|
|
18
|
-
pageNeighbours = 1,
|
|
19
|
-
totalPages
|
|
20
|
-
}: any) {
|
|
16
|
+
export function getPageNumbers({ currentPage, pageNeighbours = 1, totalPages }: any) {
|
|
21
17
|
const totalNumbers = pageNeighbours * 2 + 3;
|
|
22
18
|
const totalBlocks = totalNumbers + 2;
|
|
23
19
|
|
|
24
20
|
if (totalPages > totalBlocks) {
|
|
25
21
|
const calculatedStartPage = Math.max(2, currentPage - pageNeighbours);
|
|
26
|
-
const calculatedEndPage = Math.min(
|
|
27
|
-
totalPages - 1,
|
|
28
|
-
currentPage + pageNeighbours
|
|
29
|
-
);
|
|
22
|
+
const calculatedEndPage = Math.min(totalPages - 1, currentPage + pageNeighbours);
|
|
30
23
|
const startPage = calculatedStartPage === 3 ? 2 : calculatedStartPage;
|
|
31
|
-
const endPage =
|
|
32
|
-
calculatedEndPage === totalPages - 2 ? totalPages - 1 : calculatedEndPage;
|
|
24
|
+
const endPage = calculatedEndPage === totalPages - 2 ? totalPages - 1 : calculatedEndPage;
|
|
33
25
|
|
|
34
26
|
let pages = range(startPage, endPage);
|
|
35
27
|
|
|
@@ -9,32 +9,24 @@ import { SelectColumnFilter } from "../filters/selectColumnFilter.component";
|
|
|
9
9
|
export function mapFormToColumns(form: FormSchema): Column[] {
|
|
10
10
|
const columns: Column[] = [];
|
|
11
11
|
|
|
12
|
-
FormioUtils.eachComponent(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (component.tableView && component.key) {
|
|
16
|
-
const cmp: any = Components.create(component, null, null, true);
|
|
12
|
+
FormioUtils.eachComponent(form.components, (component: ExtendedComponentSchema) => {
|
|
13
|
+
if (component.tableView && component.key) {
|
|
14
|
+
const cmp: any = Components.create(component, null, null, true);
|
|
17
15
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
{...props}
|
|
24
|
-
render={(value: any) => cmp.asString(value)}
|
|
25
|
-
/>
|
|
26
|
-
)
|
|
27
|
-
};
|
|
16
|
+
const column: Column = {
|
|
17
|
+
Header: component.label || component.title || component.key,
|
|
18
|
+
accessor: `data.${component.key}`,
|
|
19
|
+
Cell: (props: any) => <DefaultCell {...props} render={(value: any) => cmp.asString(value)} />
|
|
20
|
+
};
|
|
28
21
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
columns.push(column);
|
|
22
|
+
if (component.type === "select" && component.dataSrc === "values") {
|
|
23
|
+
column.Filter = SelectColumnFilter;
|
|
24
|
+
(column as any).choices = component.data.values;
|
|
35
25
|
}
|
|
26
|
+
|
|
27
|
+
columns.push(column);
|
|
36
28
|
}
|
|
37
|
-
);
|
|
29
|
+
});
|
|
38
30
|
|
|
39
31
|
return columns;
|
|
40
32
|
}
|