@tsed/react-formio 3.0.0-alpha.10 → 3.0.0-alpha.11
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/dist/hooks/keyboard.constants.d.ts +38 -0
- package/dist/hooks/keyboard.constants.js +7 -0
- package/dist/hooks/keyboard.constants.js.map +1 -0
- package/dist/hooks/useKeyboardControls.d.ts +12 -0
- package/dist/hooks/useKeyboardControls.js +35 -0
- package/dist/hooks/useKeyboardControls.js.map +1 -0
- package/dist/interfaces/Operation.d.ts +12 -2
- package/dist/molecules/button/Button.d.ts +18 -5
- package/dist/molecules/button/Button.js +29 -30
- package/dist/molecules/button/Button.js.map +1 -1
- package/dist/molecules/card/Card.js +7 -5
- package/dist/molecules/card/Card.js.map +1 -1
- package/dist/molecules/forms/input-tags/InputTags.js +14 -14
- package/dist/molecules/forms/input-tags/InputTags.js.map +1 -1
- package/dist/molecules/table/Table.d.ts +11 -3
- package/dist/molecules/table/Table.js +8 -3
- package/dist/molecules/table/Table.js.map +1 -1
- package/dist/molecules/table/components/DefaultCellOperations.d.ts +12 -4
- package/dist/molecules/table/components/DefaultCellOperations.js +12 -6
- package/dist/molecules/table/components/DefaultCellOperations.js.map +1 -1
- package/dist/molecules/table/components/DefaultOperationButton.d.ts +12 -4
- package/dist/molecules/table/components/DefaultOperationButton.js.map +1 -1
- package/dist/molecules/table/hooks/useTable.d.ts +12 -4
- package/dist/molecules/table/hooks/useTable.js.map +1 -1
- package/dist/molecules/tabs/Tab.d.ts +13 -0
- package/dist/molecules/tabs/Tab.js +67 -0
- package/dist/molecules/tabs/Tab.js.map +1 -0
- package/dist/molecules/tabs/TabList.d.ts +2 -0
- package/dist/molecules/tabs/TabList.js +24 -0
- package/dist/molecules/tabs/TabList.js.map +1 -0
- package/dist/molecules/tabs/TabPanel.d.ts +9 -0
- package/dist/molecules/tabs/TabPanel.js +27 -0
- package/dist/molecules/tabs/TabPanel.js.map +1 -0
- package/dist/molecules/tabs/Tabs.d.ts +4 -16
- package/dist/molecules/tabs/Tabs.js +7 -67
- package/dist/molecules/tabs/Tabs.js.map +1 -1
- package/dist/molecules/tabs/TabsBody.d.ts +1 -0
- package/dist/molecules/tabs/TabsBody.js +10 -0
- package/dist/molecules/tabs/TabsBody.js.map +1 -0
- package/dist/molecules/tabs/TabsLegacy.d.ts +17 -0
- package/dist/molecules/tabs/TabsLegacy.js +49 -0
- package/dist/molecules/tabs/TabsLegacy.js.map +1 -0
- package/dist/molecules/tabs/all.d.ts +5 -0
- package/dist/molecules/tabs/all.js +13 -0
- package/dist/molecules/tabs/all.js.map +1 -0
- package/dist/molecules/tabs/context/TabControl.d.ts +52 -0
- package/dist/molecules/tabs/context/TabControl.js +85 -0
- package/dist/molecules/tabs/context/TabControl.js.map +1 -0
- package/dist/molecules/tabs/hooks/tabControl.d.ts +44 -0
- package/dist/molecules/tabs/hooks/tabControl.js +34 -0
- package/dist/molecules/tabs/hooks/tabControl.js.map +1 -0
- package/dist/organisms/form/actions/FormAction.js.map +1 -0
- package/dist/organisms/form/builder/FormEdit.d.ts +3 -1
- package/dist/organisms/form/builder/FormEdit.js +38 -35
- package/dist/organisms/form/builder/FormEdit.js.map +1 -1
- package/dist/organisms/form/builder/useFormEdit.js +17 -17
- package/dist/organisms/form/builder/useFormEdit.js.map +1 -1
- package/dist/organisms/form/exports/FormExport.d.ts +5 -0
- package/dist/organisms/form/exports/FormExport.js +55 -0
- package/dist/organisms/form/exports/FormExport.js.map +1 -0
- package/dist/organisms/form/preview/FormPreview.d.ts +6 -0
- package/dist/organisms/form/preview/FormPreview.js +11 -0
- package/dist/organisms/form/preview/FormPreview.js.map +1 -0
- package/dist/organisms/table/submissions/SubmissionsTable.d.ts +11 -3
- package/dist/organisms/table/submissions/SubmissionsTable.js +4 -1
- package/dist/organisms/table/submissions/SubmissionsTable.js.map +1 -1
- package/dist/organisms/views/FormViews.d.ts +24 -0
- package/dist/organisms/views/FormViews.js +96 -0
- package/dist/organisms/views/FormViews.js.map +1 -0
- package/package.json +3 -3
- package/src/hooks/keyboard.constants.ts +40 -0
- package/src/hooks/useKeyboardControls.spec.tsx +208 -0
- package/src/hooks/useKeyboardControls.ts +84 -0
- package/src/interfaces/Operation.ts +9 -3
- package/src/molecules/button/Button.tsx +43 -24
- package/src/molecules/card/Card.tsx +4 -0
- package/src/molecules/forms/input-tags/InputTags.tsx +1 -1
- package/src/molecules/pagination/Pagination.stories.tsx +0 -7
- package/src/molecules/table/Table.stories.tsx +34 -1
- package/src/molecules/table/Table.tsx +12 -6
- package/src/molecules/table/components/DefaultCellOperations.tsx +13 -7
- package/src/molecules/table/components/DefaultOperationButton.tsx +5 -4
- package/src/molecules/table/hooks/useTable.tsx +5 -5
- package/src/molecules/tabs/Tab.tsx +106 -0
- package/src/molecules/tabs/TabList.tsx +37 -0
- package/src/molecules/tabs/TabPanel.tsx +37 -0
- package/src/molecules/tabs/Tabs.spec.tsx +126 -73
- package/src/molecules/tabs/Tabs.stories.tsx +298 -65
- package/src/molecules/tabs/Tabs.tsx +10 -81
- package/src/molecules/tabs/TabsBody.tsx +11 -0
- package/src/molecules/tabs/TabsLegacy.stories.tsx +103 -0
- package/src/molecules/tabs/TabsLegacy.tsx +84 -0
- package/src/molecules/tabs/all.ts +5 -0
- package/src/molecules/tabs/context/TabControl.tsx +166 -0
- package/src/molecules/tabs/hooks/tabControl.spec.tsx +388 -0
- package/src/molecules/tabs/hooks/tabControl.ts +52 -0
- package/src/organisms/__fixtures__/form-firstname.fixture.json +1 -0
- package/src/organisms/__fixtures__/form.fixture.json +1 -0
- package/src/organisms/form/actions/FormAction.stories.tsx +422 -0
- package/src/organisms/form/builder/FormEdit.tsx +7 -1
- package/src/organisms/form/builder/useFormEdit.ts +1 -1
- package/src/organisms/form/exports/FormExport.stories.tsx +71 -0
- package/src/organisms/form/exports/FormExport.tsx +58 -0
- package/src/organisms/form/preview/FormPreview.stories.tsx +61 -0
- package/src/organisms/form/preview/FormPreview.tsx +21 -0
- package/src/organisms/table/actions/ActionsTable.stories.tsx +36 -34
- package/src/organisms/table/submissions/SubmissionsTable.stories.tsx +103 -57
- package/src/organisms/table/submissions/SubmissionsTable.tsx +10 -4
- package/src/organisms/views/FormViews.stories.tsx +224 -0
- package/src/organisms/views/FormViews.tsx +146 -0
- package/dist/organisms/form/action/FormAction.js.map +0 -1
- package/src/organisms/form/action/FormAction.stories.tsx +0 -364
- /package/dist/organisms/form/{action → actions}/FormAction.d.ts +0 -0
- /package/dist/organisms/form/{action → actions}/FormAction.js +0 -0
- /package/src/organisms/form/{action → actions}/FormAction.tsx +0 -0
|
@@ -36,19 +36,47 @@ export default {
|
|
|
36
36
|
action: "onAddAction"
|
|
37
37
|
}
|
|
38
38
|
},
|
|
39
|
+
args: {
|
|
40
|
+
availableActions: availableActions.map(({ name, title }) => ({
|
|
41
|
+
label: title,
|
|
42
|
+
value: name
|
|
43
|
+
})),
|
|
44
|
+
data: data as never,
|
|
45
|
+
operations: [
|
|
46
|
+
{
|
|
47
|
+
title: "Edit",
|
|
48
|
+
action: "edit",
|
|
49
|
+
alias: "row",
|
|
50
|
+
path: "/resources/:resourceId/submissions/:submissionId",
|
|
51
|
+
icon: "edit",
|
|
52
|
+
permissionsResolver() {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
action: "delete",
|
|
58
|
+
path: "/resources/:resourceId/submissions/:submissionId/delete",
|
|
59
|
+
icon: "trash",
|
|
60
|
+
buttonType: "danger",
|
|
61
|
+
permissionsResolver() {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
},
|
|
39
67
|
parameters: {}
|
|
40
68
|
} satisfies Meta<typeof ActionsTable>;
|
|
41
69
|
|
|
42
70
|
type Story = StoryObj<typeof ActionsTable>;
|
|
43
71
|
|
|
44
|
-
export const
|
|
72
|
+
export const Usage: Story = {
|
|
45
73
|
async play({ canvasElement, args }) {
|
|
46
74
|
const canvas = within(canvasElement);
|
|
47
75
|
|
|
48
76
|
const select = canvas.getByTestId("action-table-select");
|
|
49
77
|
const addButton = canvas.getByTestId("action-table-add");
|
|
50
78
|
|
|
51
|
-
expect(addButton).toHaveAttribute("disabled");
|
|
79
|
+
await expect(addButton).toHaveAttribute("disabled");
|
|
52
80
|
|
|
53
81
|
await userEvent.selectOptions(select, "save", {
|
|
54
82
|
delay: 100
|
|
@@ -56,56 +84,30 @@ export const Sandbox: Story = {
|
|
|
56
84
|
|
|
57
85
|
await userEvent.click(addButton);
|
|
58
86
|
|
|
59
|
-
expect(args.onAddAction).toHaveBeenCalledWith("save");
|
|
87
|
+
await expect(args.onAddAction).toHaveBeenCalledWith("save");
|
|
60
88
|
|
|
61
89
|
const editButton = await canvas.getByRole("button", { name: /Operation button: Edit/i });
|
|
62
90
|
const deleteButton = await canvas.getByRole("button", { name: /Operation button: delete/i });
|
|
63
91
|
|
|
64
|
-
expect(editButton).toBeInTheDocument();
|
|
65
|
-
expect(deleteButton).toBeInTheDocument();
|
|
92
|
+
await expect(editButton).toBeInTheDocument();
|
|
93
|
+
await expect(deleteButton).toBeInTheDocument();
|
|
66
94
|
|
|
67
95
|
await userEvent.click(editButton);
|
|
68
96
|
|
|
69
|
-
expect(args.onClick).toHaveBeenCalledWith(
|
|
97
|
+
await expect(args.onClick).toHaveBeenCalledWith(
|
|
70
98
|
args.data[0],
|
|
71
99
|
args.operations!.find(({ action }) => action === "edit")
|
|
72
100
|
);
|
|
73
101
|
|
|
74
102
|
await userEvent.click(deleteButton);
|
|
75
103
|
|
|
76
|
-
expect(args.onClick).toHaveBeenCalledWith(
|
|
104
|
+
await expect(args.onClick).toHaveBeenCalledWith(
|
|
77
105
|
args.data[0],
|
|
78
106
|
args.operations!.find(({ action }) => action === "delete")
|
|
79
107
|
);
|
|
80
108
|
},
|
|
81
109
|
args: {
|
|
82
110
|
onAddAction: fn(),
|
|
83
|
-
onClick: fn()
|
|
84
|
-
availableActions: availableActions.map(({ name, title }) => ({
|
|
85
|
-
label: title,
|
|
86
|
-
value: name
|
|
87
|
-
})),
|
|
88
|
-
data: data as never,
|
|
89
|
-
operations: [
|
|
90
|
-
{
|
|
91
|
-
title: "Edit",
|
|
92
|
-
action: "edit",
|
|
93
|
-
alias: "row",
|
|
94
|
-
path: "/resources/:resourceId/submissions/:submissionId",
|
|
95
|
-
icon: "edit",
|
|
96
|
-
permissionsResolver() {
|
|
97
|
-
return true;
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
action: "delete",
|
|
102
|
-
path: "/resources/:resourceId/submissions/:submissionId/delete",
|
|
103
|
-
icon: "trash",
|
|
104
|
-
buttonType: "danger",
|
|
105
|
-
permissionsResolver() {
|
|
106
|
-
return true;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
]
|
|
111
|
+
onClick: fn()
|
|
110
112
|
}
|
|
111
113
|
};
|
|
@@ -4,16 +4,44 @@ import "../../../molecules/forms/select/all";
|
|
|
4
4
|
import "../../../molecules/pagination/all";
|
|
5
5
|
import "../../../molecules/table/all";
|
|
6
6
|
|
|
7
|
+
import { Meta, StoryObj } from "@storybook/react";
|
|
7
8
|
import { useState } from "react";
|
|
8
9
|
|
|
9
10
|
import { mapPagination } from "../../../utils/mapPagination";
|
|
10
|
-
import
|
|
11
|
+
import FormSchema from "../../__fixtures__/form-schema.json";
|
|
11
12
|
import formSubmissions from "../../__fixtures__/form-submissions.json";
|
|
12
13
|
import { SubmissionsTable } from "./SubmissionsTable";
|
|
13
14
|
|
|
15
|
+
function Wrapper(args: any) {
|
|
16
|
+
const [skip, setSkip] = useState(0);
|
|
17
|
+
const [limit, setLimit] = useState(10);
|
|
18
|
+
const [serverCount] = useState(87);
|
|
19
|
+
|
|
20
|
+
const onChange = (obj: any) => {
|
|
21
|
+
setLimit(obj.pageSize);
|
|
22
|
+
setSkip(obj.pageIndex * obj.pageSize);
|
|
23
|
+
args.onChange && args.onChange(obj);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<SubmissionsTable
|
|
28
|
+
{...args}
|
|
29
|
+
onChange={onChange}
|
|
30
|
+
{...mapPagination({
|
|
31
|
+
skip,
|
|
32
|
+
limit,
|
|
33
|
+
serverCount
|
|
34
|
+
})}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
14
39
|
/**
|
|
40
|
+
* SubmissionsTable component displays form submissions in a table format with filtering,
|
|
41
|
+
* pagination, and action buttons for each submission.
|
|
42
|
+
*
|
|
15
43
|
* ```tsx
|
|
16
|
-
* import {SubmissionsTable} from "@tsed/react-formio/organisms/table/submissions/SubmissionsTable";
|
|
44
|
+
* import { SubmissionsTable } from "@tsed/react-formio/organisms/table/submissions/SubmissionsTable";
|
|
17
45
|
* ```
|
|
18
46
|
*/
|
|
19
47
|
export default {
|
|
@@ -21,76 +49,94 @@ export default {
|
|
|
21
49
|
component: SubmissionsTable,
|
|
22
50
|
argTypes: {
|
|
23
51
|
form: {
|
|
52
|
+
description: "The form schema used to determine table columns",
|
|
24
53
|
control: "object"
|
|
25
54
|
},
|
|
26
55
|
data: {
|
|
56
|
+
description: "Array of submission data to display in the table",
|
|
27
57
|
control: "object"
|
|
28
58
|
},
|
|
29
59
|
operations: {
|
|
60
|
+
description: "Array of operations/actions available for each submission",
|
|
30
61
|
control: "object"
|
|
31
62
|
},
|
|
32
|
-
|
|
33
|
-
|
|
63
|
+
onChange: {
|
|
64
|
+
description: "Callback when table state changes (sorting, filtering, pagination)",
|
|
65
|
+
action: "onChange"
|
|
34
66
|
},
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
},
|
|
38
|
-
disableFilters: {
|
|
39
|
-
control: "boolean"
|
|
40
|
-
},
|
|
41
|
-
disablePagination: {
|
|
42
|
-
control: "boolean"
|
|
67
|
+
i18n: {
|
|
68
|
+
description: "Internationalization function"
|
|
43
69
|
}
|
|
44
70
|
},
|
|
45
|
-
parameters: {
|
|
46
|
-
|
|
71
|
+
parameters: {
|
|
72
|
+
docs: {
|
|
73
|
+
description: {
|
|
74
|
+
component:
|
|
75
|
+
"Component that displays form submissions in a table format with filtering, pagination, and action buttons for each submission."
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
args: {
|
|
80
|
+
form: FormSchema as any,
|
|
81
|
+
data: formSubmissions,
|
|
82
|
+
operations: [
|
|
83
|
+
{
|
|
84
|
+
title: "Edit",
|
|
85
|
+
action: "edit",
|
|
86
|
+
alias: "row",
|
|
87
|
+
path: "/resources/:resourceId/submissions/:submissionId",
|
|
88
|
+
icon: "edit",
|
|
89
|
+
permissionsResolver() {
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
action: "delete",
|
|
95
|
+
path: "/resources/:resourceId/submissions/:submissionId/delete",
|
|
96
|
+
icon: "trash",
|
|
97
|
+
buttonType: "danger",
|
|
98
|
+
permissionsResolver() {
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
},
|
|
104
|
+
render: Wrapper
|
|
105
|
+
} satisfies Meta<typeof SubmissionsTable>;
|
|
47
106
|
|
|
48
|
-
|
|
49
|
-
const [skip, setSkip] = useState(0);
|
|
50
|
-
const [limit, setLimit] = useState(10);
|
|
51
|
-
const [serverCount] = useState(87);
|
|
107
|
+
type Story = StoryObj<typeof SubmissionsTable>;
|
|
52
108
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
};
|
|
109
|
+
/**
|
|
110
|
+
* Standard table with default settings
|
|
111
|
+
*/
|
|
112
|
+
export const Default: Story = {};
|
|
58
113
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
serverCount
|
|
67
|
-
})}
|
|
68
|
-
/>
|
|
69
|
-
);
|
|
114
|
+
/**
|
|
115
|
+
* Empty table with no data
|
|
116
|
+
*/
|
|
117
|
+
export const Empty: Story = {
|
|
118
|
+
args: {
|
|
119
|
+
data: []
|
|
120
|
+
}
|
|
70
121
|
};
|
|
71
122
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
icon: "trash",
|
|
90
|
-
buttonType: "danger",
|
|
91
|
-
permissionsResolver() {
|
|
92
|
-
return true;
|
|
93
|
-
}
|
|
123
|
+
/**
|
|
124
|
+
* Table with custom translations
|
|
125
|
+
*/
|
|
126
|
+
export const Translated: Story = {
|
|
127
|
+
args: {
|
|
128
|
+
i18n: (key: string) => {
|
|
129
|
+
const translations: Record<string, string> = {
|
|
130
|
+
"Search...": "Rechercher...",
|
|
131
|
+
"No results found": "Aucun résultat trouvé",
|
|
132
|
+
"Loading...": "Chargement...",
|
|
133
|
+
Page: "Page",
|
|
134
|
+
of: "sur",
|
|
135
|
+
rows: "lignes",
|
|
136
|
+
Edit: "Éditer",
|
|
137
|
+
Delete: "Supprimer"
|
|
138
|
+
};
|
|
139
|
+
return translations[key] || key;
|
|
94
140
|
}
|
|
95
|
-
|
|
141
|
+
}
|
|
96
142
|
};
|
|
@@ -1,13 +1,19 @@
|
|
|
1
|
-
import type { FormType, SubmissionType } from "../../../interfaces";
|
|
1
|
+
import type { FormType, JSON, SubmissionType } from "../../../interfaces";
|
|
2
2
|
import { Table, type TableProps } from "../../../molecules/table/Table";
|
|
3
3
|
import { mapFormToColumns } from "../../../molecules/table/utils/mapFormToColumns.js";
|
|
4
4
|
|
|
5
|
-
export type SubmissionsTableProps =
|
|
5
|
+
export type SubmissionsTableProps<Data extends { [key: string]: JSON } = { [key: string]: JSON }> = Omit<
|
|
6
|
+
TableProps<SubmissionType<Data>>,
|
|
7
|
+
"columns"
|
|
8
|
+
> & {
|
|
6
9
|
form?: FormType;
|
|
7
10
|
};
|
|
8
11
|
|
|
9
|
-
export function SubmissionsTable
|
|
12
|
+
export function SubmissionsTable<Data extends { [key: string]: JSON } = { [key: string]: JSON }>({
|
|
13
|
+
form,
|
|
14
|
+
...props
|
|
15
|
+
}: SubmissionsTableProps<Data>) {
|
|
10
16
|
const columns: any[] | undefined = form && mapFormToColumns(form);
|
|
11
17
|
|
|
12
|
-
return <Table {...props} columns={columns!} />;
|
|
18
|
+
return <Table {...(props as any)} columns={columns!} />;
|
|
13
19
|
}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import "../../molecules/button/Button";
|
|
2
|
+
import "../../molecules/forms/input-text/InputText";
|
|
3
|
+
import "../../molecules/forms/select/all";
|
|
4
|
+
import "../../molecules/forms/form-control/FormControl";
|
|
5
|
+
import "../../molecules/pagination/all";
|
|
6
|
+
import "../../molecules/table/all";
|
|
7
|
+
import "../../molecules/tabs/all";
|
|
8
|
+
import "../../molecules/card/Card";
|
|
9
|
+
import "../form/builder/all";
|
|
10
|
+
import "../form/Form";
|
|
11
|
+
|
|
12
|
+
import { Meta, StoryObj } from "@storybook/react";
|
|
13
|
+
|
|
14
|
+
import ActionsTableStory from "../table/actions/ActionsTable.stories.js";
|
|
15
|
+
import SubmissionsTableStory from "../table/submissions/SubmissionsTable.stories.js";
|
|
16
|
+
import { FormViews } from "./FormViews.js";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* FormViews component displays a tabbed interface for managing forms with tabs for editing,
|
|
20
|
+
* viewing submissions, previewing, managing actions, controlling access, exporting, and configuring settings.
|
|
21
|
+
*
|
|
22
|
+
* ```tsx
|
|
23
|
+
* import { FormViews } from "@tsed/react-formio/organisms/views/FormViews";
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* ## Implementation
|
|
27
|
+
*
|
|
28
|
+
* ```tsx
|
|
29
|
+
* import type { FormType } from "../../interfaces/index.js";
|
|
30
|
+
* import type { Tab as DefaultTab } from "../../molecules/tabs/Tab.js";
|
|
31
|
+
* import type { TabList as DefaultTabList } from "../../molecules/tabs/TabList.js";
|
|
32
|
+
* import type { TabPanel as DefaultTabPanel } from "../../molecules/tabs/TabPanel.js";
|
|
33
|
+
* import type { Tabs as DefaultTabs } from "../../molecules/tabs/Tabs.js";
|
|
34
|
+
* import type { TabsBody as DefaultTabsBody } from "../../molecules/tabs/TabsBody.js";
|
|
35
|
+
* import { getComponent } from "../../registries/components.js";
|
|
36
|
+
* import { FormAccess, type FormAccessProps } from "../form/access/FormAccess.js";
|
|
37
|
+
* import { FormEdit, type FormEditProps } from "../form/builder/FormEdit.js";
|
|
38
|
+
* import { FormExport } from "../form/exports/FormExport.js";
|
|
39
|
+
* import { FormPreview } from "../form/preview/FormPreview.js";
|
|
40
|
+
* import { FormSettings } from "../form/settings/FormSettings.js";
|
|
41
|
+
* import { ActionsTable, type ActionsTableProps } from "../table/actions/ActionsTable.js";
|
|
42
|
+
* import { SubmissionsTable, type SubmissionsTableProps } from "../table/submissions/SubmissionsTable.js";
|
|
43
|
+
*
|
|
44
|
+
* export type FormViewsProps = {
|
|
45
|
+
* form: FormEditProps["form"];
|
|
46
|
+
* submissions: SubmissionsTableProps["data"];
|
|
47
|
+
* availableActions: ActionsTableProps["availableActions"];
|
|
48
|
+
* actions: ActionsTableProps["data"];
|
|
49
|
+
* roles?: FormAccessProps["roles"];
|
|
50
|
+
* i18n?: (key: string) => string;
|
|
51
|
+
* onAction: () => void;
|
|
52
|
+
* operations: SubmissionsTableProps["operations"];
|
|
53
|
+
* };
|
|
54
|
+
*
|
|
55
|
+
* export function FormViews({ form, roles, availableActions, actions, submissions, operations, i18n = (f) => f }: FormViewsProps) {
|
|
56
|
+
* const Tabs = getComponent<typeof DefaultTabs>("Tabs");
|
|
57
|
+
* const TabList = getComponent<typeof DefaultTabList>("TabList");
|
|
58
|
+
* const Tab = getComponent<typeof DefaultTab>("Tab");
|
|
59
|
+
* const TabsBody = getComponent<typeof DefaultTabsBody>("TabsBody");
|
|
60
|
+
* const TabPanel = getComponent<typeof DefaultTabPanel>("TabPanel");
|
|
61
|
+
*
|
|
62
|
+
* return (
|
|
63
|
+
* <Tabs>
|
|
64
|
+
* <TabList>
|
|
65
|
+
* <Tab value={0} icon='edit'>
|
|
66
|
+
* {i18n("Edit")}
|
|
67
|
+
* </Tab>
|
|
68
|
+
* <Tab value={1} icon='data'>
|
|
69
|
+
* {i18n("Data")}
|
|
70
|
+
* </Tab>
|
|
71
|
+
* <Tab value={2} icon='test-tube'>
|
|
72
|
+
* {i18n("Preview")}
|
|
73
|
+
* </Tab>
|
|
74
|
+
* <Tab value={3} icon='paper-plane'>
|
|
75
|
+
* {i18n("Actions")}
|
|
76
|
+
* </Tab>
|
|
77
|
+
* <Tab value={4} icon='lock'>
|
|
78
|
+
* {i18n("Access")}
|
|
79
|
+
* </Tab>
|
|
80
|
+
* <Tab value={5} icon='download'>
|
|
81
|
+
* {i18n("Export")}
|
|
82
|
+
* </Tab>
|
|
83
|
+
* <Tab value={6} icon='cog'>
|
|
84
|
+
* {i18n("Settings")}
|
|
85
|
+
* </Tab>
|
|
86
|
+
* </TabList>
|
|
87
|
+
* <TabsBody>
|
|
88
|
+
* <TabPanel value={0} className='p-3 border-l-1 border-b-1 border-r-1 border-gray-300'>
|
|
89
|
+
* <FormEdit form={form} options={{ i18n }} />
|
|
90
|
+
* </TabPanel>
|
|
91
|
+
* <TabPanel value={1}>
|
|
92
|
+
* <SubmissionsTable className={"border-top-0"} form={form as FormType} data={submissions} i18n={i18n} operations={operations} />
|
|
93
|
+
* </TabPanel>
|
|
94
|
+
* <TabPanel value={2}>
|
|
95
|
+
* <FormPreview form={form as FormType} i18n={i18n} />
|
|
96
|
+
* </TabPanel>
|
|
97
|
+
* <TabPanel value={3}>
|
|
98
|
+
* <ActionsTable className={"border-top-0"} availableActions={availableActions} data={actions} operations={[]} i18n={i18n} />
|
|
99
|
+
* </TabPanel>
|
|
100
|
+
* <TabPanel value={4} className='pt-3'>
|
|
101
|
+
* <FormAccess form={form as FormType} roles={roles} options={{ i18n }} />
|
|
102
|
+
* </TabPanel>
|
|
103
|
+
* <TabPanel value={5} className='pt-3'>
|
|
104
|
+
* <FormExport i18n={i18n} />
|
|
105
|
+
* </TabPanel>
|
|
106
|
+
* <TabPanel value={6} className='p-3 border-l-1 border-b-1 border-r-1 border-gray-300'>
|
|
107
|
+
* <FormSettings form={form as FormType} options={{}} />
|
|
108
|
+
* </TabPanel>
|
|
109
|
+
* </TabsBody>
|
|
110
|
+
* </Tabs>
|
|
111
|
+
* );
|
|
112
|
+
* }
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
export default {
|
|
116
|
+
title: "views/FormViews",
|
|
117
|
+
component: FormViews,
|
|
118
|
+
argTypes: {
|
|
119
|
+
form: {
|
|
120
|
+
description: "The form object to manage",
|
|
121
|
+
control: "object"
|
|
122
|
+
},
|
|
123
|
+
submissions: {
|
|
124
|
+
description: "Submission data to display in the Data tab",
|
|
125
|
+
control: "object"
|
|
126
|
+
},
|
|
127
|
+
// operations: {
|
|
128
|
+
// description: "Operations available for submissions",
|
|
129
|
+
// control: "object"
|
|
130
|
+
// },
|
|
131
|
+
roles: {
|
|
132
|
+
description: "Roles for access control",
|
|
133
|
+
control: "object"
|
|
134
|
+
},
|
|
135
|
+
i18n: {
|
|
136
|
+
description: "Internationalization function"
|
|
137
|
+
},
|
|
138
|
+
onAction: {
|
|
139
|
+
action: "onAction",
|
|
140
|
+
description: "Callback when an action is triggered"
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
parameters: {
|
|
144
|
+
docs: {
|
|
145
|
+
description: {
|
|
146
|
+
component:
|
|
147
|
+
"Component that displays a tabbed interface for managing forms with tabs for editing, viewing submissions, previewing, managing actions, controlling access, exporting, and configuring settings."
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
} satisfies Meta<typeof FormViews>;
|
|
152
|
+
|
|
153
|
+
type Story = StoryObj<typeof FormViews>;
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Basic form view with a simple form
|
|
157
|
+
*/
|
|
158
|
+
export const Usage: Story = {
|
|
159
|
+
args: {
|
|
160
|
+
form: SubmissionsTableStory.args.form as any,
|
|
161
|
+
submissions: SubmissionsTableStory.args.data as any,
|
|
162
|
+
// operations: SubmissionsTableStory.args.operations,
|
|
163
|
+
actions: ActionsTableStory.args.data as any,
|
|
164
|
+
roles: [
|
|
165
|
+
{
|
|
166
|
+
_id: "1",
|
|
167
|
+
title: "Administrator"
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
_id: "2",
|
|
171
|
+
title: "Authenticated"
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
_id: "3",
|
|
175
|
+
title: "Anonymous"
|
|
176
|
+
}
|
|
177
|
+
],
|
|
178
|
+
i18n: (key: string) => key,
|
|
179
|
+
onAction: () => console.log("Action triggered")
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Form view with translated labels
|
|
185
|
+
*/
|
|
186
|
+
export const Translated: Story = {
|
|
187
|
+
args: {
|
|
188
|
+
form: SubmissionsTableStory.args.form as any,
|
|
189
|
+
submissions: SubmissionsTableStory.args.data as any,
|
|
190
|
+
// operations: SubmissionsTableStory.args.operations,
|
|
191
|
+
actions: ActionsTableStory.args.data as any,
|
|
192
|
+
roles: [
|
|
193
|
+
{
|
|
194
|
+
_id: "1",
|
|
195
|
+
title: "Administrator"
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
_id: "2",
|
|
199
|
+
title: "Authenticated"
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
_id: "3",
|
|
203
|
+
title: "Anonymous"
|
|
204
|
+
}
|
|
205
|
+
],
|
|
206
|
+
i18n: (key: string) => {
|
|
207
|
+
const translations: Record<string, string> = {
|
|
208
|
+
Edit: "Éditer",
|
|
209
|
+
Data: "Données",
|
|
210
|
+
Preview: "Aperçu",
|
|
211
|
+
Actions: "Actions",
|
|
212
|
+
Access: "Accès",
|
|
213
|
+
Export: "Exporter",
|
|
214
|
+
Settings: "Paramètres",
|
|
215
|
+
"Form with First Name": "Formulaire avec prénom",
|
|
216
|
+
"First name": "Prénom",
|
|
217
|
+
"Last name": "Nom de famille",
|
|
218
|
+
Submit: "Soumettre"
|
|
219
|
+
};
|
|
220
|
+
return translations[key] || key;
|
|
221
|
+
},
|
|
222
|
+
onAction: () => console.log("Action triggered")
|
|
223
|
+
}
|
|
224
|
+
};
|