@cratis/components 0.1.9 → 0.1.12
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/cjs/CommandForm/CommandFormFields.js +9 -3
- package/dist/cjs/CommandForm/CommandFormFields.js.map +1 -1
- package/dist/cjs/CommandForm/ValidationMessage.js +24 -0
- package/dist/cjs/CommandForm/ValidationMessage.js.map +1 -0
- package/dist/cjs/CommandForm/asCommandFormField.js +47 -0
- package/dist/cjs/CommandForm/asCommandFormField.js.map +1 -0
- package/dist/cjs/CommandForm/fields/CheckboxField.js +13 -0
- package/dist/cjs/CommandForm/fields/CheckboxField.js.map +1 -0
- package/dist/cjs/CommandForm/fields/DropdownField.js +13 -0
- package/dist/cjs/CommandForm/fields/DropdownField.js.map +1 -0
- package/dist/cjs/CommandForm/fields/InputTextField.js +13 -0
- package/dist/cjs/CommandForm/fields/InputTextField.js.map +1 -0
- package/dist/cjs/CommandForm/fields/NumberField.js +13 -0
- package/dist/cjs/CommandForm/fields/NumberField.js.map +1 -0
- package/dist/cjs/CommandForm/fields/SliderField.js +17 -0
- package/dist/cjs/CommandForm/fields/SliderField.js.map +1 -0
- package/dist/cjs/CommandForm/fields/TextAreaField.js +13 -0
- package/dist/cjs/CommandForm/fields/TextAreaField.js.map +1 -0
- package/dist/cjs/CommandForm/index.js +15 -7
- package/dist/cjs/CommandForm/index.js.map +1 -1
- package/dist/cjs/PivotViewer/PivotViewer.css +1258 -0
- package/dist/cjs/PivotViewer/PivotViewer.js +14 -0
- package/dist/cjs/PivotViewer/PivotViewer.js.map +1 -1
- package/dist/cjs/PivotViewer/components/PivotCanvas.js +33 -10
- package/dist/cjs/PivotViewer/components/PivotCanvas.js.map +1 -1
- package/dist/cjs/PivotViewer/components/PivotViewerMain.js +1 -1
- package/dist/cjs/PivotViewer/components/PivotViewerMain.js.map +1 -1
- package/dist/cjs/PivotViewer/components/Spinner.css +77 -0
- package/dist/cjs/PivotViewer/components/pivot/sprites.js +79 -15
- package/dist/cjs/PivotViewer/components/pivot/sprites.js.map +1 -1
- package/dist/cjs/PivotViewer/components/pivot/visibility.js +36 -10
- package/dist/cjs/PivotViewer/components/pivot/visibility.js.map +1 -1
- package/dist/cjs/PivotViewer/engine/layout.js +2 -1
- package/dist/cjs/PivotViewer/engine/layout.js.map +1 -1
- package/dist/cjs/PivotViewer/hooks/usePivotEngine.js +37 -2
- package/dist/cjs/PivotViewer/hooks/usePivotEngine.js.map +1 -1
- package/dist/cjs/PivotViewer/index.js +3 -0
- package/dist/cjs/PivotViewer/index.js.map +1 -1
- package/dist/cjs/PivotViewer/types.js +22 -0
- package/dist/cjs/PivotViewer/types.js.map +1 -0
- package/dist/cjs/TimeMachine/EventsView.css +213 -0
- package/dist/cjs/TimeMachine/TimeMachine.css +567 -0
- package/dist/cjs/TimeMachine/TimeMachine.js +8 -3
- package/dist/cjs/TimeMachine/TimeMachine.js.map +1 -1
- package/dist/esm/CommandForm/CommandForm.stories.d.ts +1 -0
- package/dist/esm/CommandForm/CommandForm.stories.d.ts.map +1 -1
- package/dist/esm/CommandForm/CommandForm.stories.js +34 -1
- package/dist/esm/CommandForm/CommandForm.stories.js.map +1 -1
- package/dist/esm/CommandForm/CommandFormFields.d.ts.map +1 -1
- package/dist/esm/CommandForm/CommandFormFields.js +9 -3
- package/dist/esm/CommandForm/CommandFormFields.js.map +1 -1
- package/dist/esm/CommandForm/UserRegistrationCommand.d.ts +63 -0
- package/dist/esm/CommandForm/UserRegistrationCommand.d.ts.map +1 -0
- package/dist/esm/CommandForm/UserRegistrationCommand.js +143 -0
- package/dist/esm/CommandForm/UserRegistrationCommand.js.map +1 -0
- package/dist/esm/CommandForm/ValidationMessage.d.ts +8 -0
- package/dist/esm/CommandForm/ValidationMessage.d.ts.map +1 -0
- package/dist/esm/CommandForm/ValidationMessage.js +22 -0
- package/dist/esm/CommandForm/ValidationMessage.js.map +1 -0
- package/dist/esm/CommandForm/asCommandFormField.d.ts +32 -0
- package/dist/esm/CommandForm/asCommandFormField.d.ts.map +1 -0
- package/dist/esm/CommandForm/asCommandFormField.js +45 -0
- package/dist/esm/CommandForm/asCommandFormField.js.map +1 -0
- package/dist/esm/CommandForm/fields/CheckboxField.d.ts +10 -0
- package/dist/esm/CommandForm/fields/CheckboxField.d.ts.map +1 -0
- package/dist/esm/CommandForm/fields/CheckboxField.js +11 -0
- package/dist/esm/CommandForm/fields/CheckboxField.js.map +1 -0
- package/dist/esm/CommandForm/fields/DropdownField.d.ts +15 -0
- package/dist/esm/CommandForm/fields/DropdownField.d.ts.map +1 -0
- package/dist/esm/CommandForm/fields/DropdownField.js +11 -0
- package/dist/esm/CommandForm/fields/DropdownField.js.map +1 -0
- package/dist/esm/CommandForm/fields/InputTextField.d.ts +11 -0
- package/dist/esm/CommandForm/fields/InputTextField.d.ts.map +1 -0
- package/dist/esm/CommandForm/fields/InputTextField.js +11 -0
- package/dist/esm/CommandForm/fields/InputTextField.js.map +1 -0
- package/dist/esm/CommandForm/fields/NumberField.d.ts +13 -0
- package/dist/esm/CommandForm/fields/NumberField.d.ts.map +1 -0
- package/dist/esm/CommandForm/fields/NumberField.js +11 -0
- package/dist/esm/CommandForm/fields/NumberField.js.map +1 -0
- package/dist/esm/CommandForm/fields/SliderField.d.ts +12 -0
- package/dist/esm/CommandForm/fields/SliderField.d.ts.map +1 -0
- package/dist/esm/CommandForm/fields/SliderField.js +15 -0
- package/dist/esm/CommandForm/fields/SliderField.js.map +1 -0
- package/dist/esm/CommandForm/fields/TextAreaField.d.ts +12 -0
- package/dist/esm/CommandForm/fields/TextAreaField.d.ts.map +1 -0
- package/dist/esm/CommandForm/fields/TextAreaField.js +11 -0
- package/dist/esm/CommandForm/fields/TextAreaField.js.map +1 -0
- package/dist/esm/CommandForm/fields/index.d.ts +7 -0
- package/dist/esm/CommandForm/fields/index.d.ts.map +1 -0
- package/dist/esm/CommandForm/fields/index.js +7 -0
- package/dist/esm/CommandForm/fields/index.js.map +1 -0
- package/dist/esm/CommandForm/index.d.ts +3 -4
- package/dist/esm/CommandForm/index.d.ts.map +1 -1
- package/dist/esm/CommandForm/index.js +8 -4
- package/dist/esm/CommandForm/index.js.map +1 -1
- package/dist/esm/PivotViewer/PivotViewer.css +1258 -0
- package/dist/esm/PivotViewer/PivotViewer.d.ts.map +1 -1
- package/dist/esm/PivotViewer/PivotViewer.js +14 -0
- package/dist/esm/PivotViewer/PivotViewer.js.map +1 -1
- package/dist/esm/PivotViewer/PivotViewer.stories.d.ts +1 -0
- package/dist/esm/PivotViewer/PivotViewer.stories.d.ts.map +1 -1
- package/dist/esm/PivotViewer/PivotViewer.stories.js +43 -3
- package/dist/esm/PivotViewer/PivotViewer.stories.js.map +1 -1
- package/dist/esm/PivotViewer/components/PivotCanvas.d.ts.map +1 -1
- package/dist/esm/PivotViewer/components/PivotCanvas.js +33 -10
- package/dist/esm/PivotViewer/components/PivotCanvas.js.map +1 -1
- package/dist/esm/PivotViewer/components/PivotViewerMain.js +1 -1
- package/dist/esm/PivotViewer/components/PivotViewerMain.js.map +1 -1
- package/dist/esm/PivotViewer/components/Spinner.css +77 -0
- package/dist/esm/PivotViewer/components/pivot/sprites.d.ts.map +1 -1
- package/dist/esm/PivotViewer/components/pivot/sprites.js +79 -15
- package/dist/esm/PivotViewer/components/pivot/sprites.js.map +1 -1
- package/dist/esm/PivotViewer/components/pivot/visibility.d.ts.map +1 -1
- package/dist/esm/PivotViewer/components/pivot/visibility.js +36 -10
- package/dist/esm/PivotViewer/components/pivot/visibility.js.map +1 -1
- package/dist/esm/PivotViewer/engine/layout.js +2 -1
- package/dist/esm/PivotViewer/engine/layout.js.map +1 -1
- package/dist/esm/PivotViewer/engine/pivot.worker.d.ts.map +1 -1
- package/dist/esm/PivotViewer/engine/pivot.worker.js +22 -7
- package/dist/esm/PivotViewer/engine/pivot.worker.js.map +1 -1
- package/dist/esm/PivotViewer/hooks/useFilteredData.d.ts +2 -2
- package/dist/esm/PivotViewer/hooks/useFilteredData.d.ts.map +1 -1
- package/dist/esm/PivotViewer/hooks/useFilteredData.js +4 -2
- package/dist/esm/PivotViewer/hooks/useFilteredData.js.map +1 -1
- package/dist/esm/PivotViewer/hooks/usePivotEngine.d.ts.map +1 -1
- package/dist/esm/PivotViewer/hooks/usePivotEngine.js +37 -2
- package/dist/esm/PivotViewer/hooks/usePivotEngine.js.map +1 -1
- package/dist/esm/PivotViewer/index.d.ts +2 -1
- package/dist/esm/PivotViewer/index.d.ts.map +1 -1
- package/dist/esm/PivotViewer/index.js +1 -0
- package/dist/esm/PivotViewer/index.js.map +1 -1
- package/dist/esm/PivotViewer/types.d.ts +4 -1
- package/dist/esm/PivotViewer/types.d.ts.map +1 -1
- package/dist/esm/PivotViewer/types.js +19 -2
- package/dist/esm/PivotViewer/types.js.map +1 -1
- package/dist/esm/TimeMachine/EventsView.css +213 -0
- package/dist/esm/TimeMachine/TimeMachine.css +567 -0
- package/dist/esm/TimeMachine/TimeMachine.d.ts.map +1 -1
- package/dist/esm/TimeMachine/TimeMachine.js +8 -3
- package/dist/esm/TimeMachine/TimeMachine.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +31 -32
- package/.storybook/main.ts +0 -24
- package/CommandDialog/CommandDialog.stories.tsx +0 -25
- package/CommandDialog/CommandDialog.tsx +0 -161
- package/CommandDialog/index.ts +0 -4
- package/CommandForm/CommandForm.stories.tsx +0 -24
- package/CommandForm/CommandForm.tsx +0 -266
- package/CommandForm/CommandFormField.tsx +0 -27
- package/CommandForm/CommandFormFields.tsx +0 -142
- package/CommandForm/DatePickerField.tsx +0 -57
- package/CommandForm/DropdownField.tsx +0 -65
- package/CommandForm/InputTextField.tsx +0 -62
- package/CommandForm/SliderField.tsx +0 -68
- package/CommandForm/index.ts +0 -10
- package/Common/ErrorBoundary.stories.tsx +0 -10
- package/Common/ErrorBoundary.tsx +0 -41
- package/Common/FormElement.stories.tsx +0 -10
- package/Common/FormElement.tsx +0 -20
- package/Common/Page.stories.tsx +0 -10
- package/Common/Page.tsx +0 -21
- package/Common/index.ts +0 -6
- package/DataPage/DataPage.stories.tsx +0 -10
- package/DataPage/DataPage.tsx +0 -191
- package/DataPage/index.ts +0 -4
- package/DataTables/DataTableForObservableQuery.stories.tsx +0 -10
- package/DataTables/DataTableForObservableQuery.tsx +0 -97
- package/DataTables/DataTableForQuery.stories.tsx +0 -10
- package/DataTables/DataTableForQuery.tsx +0 -97
- package/DataTables/index.ts +0 -5
- package/Dialogs/BusyIndicatorDialog.stories.tsx +0 -26
- package/Dialogs/BusyIndicatorDialog.tsx +0 -26
- package/Dialogs/ConfirmationDialog.stories.tsx +0 -36
- package/Dialogs/ConfirmationDialog.tsx +0 -75
- package/Dialogs/index.ts +0 -5
- package/Dropdown/Dropdown.tsx +0 -23
- package/Dropdown/index.ts +0 -4
- package/PivotViewer/PivotViewer.stories.tsx +0 -24
- package/PivotViewer/PivotViewer.tsx +0 -791
- package/PivotViewer/components/AxisLabels.tsx +0 -69
- package/PivotViewer/components/DetailPanel.tsx +0 -108
- package/PivotViewer/components/FilterPanel.tsx +0 -189
- package/PivotViewer/components/FilterPanelContainer.tsx +0 -10
- package/PivotViewer/components/PivotCanvas.tsx +0 -660
- package/PivotViewer/components/PivotViewerMain.tsx +0 -229
- package/PivotViewer/components/RangeHistogramFilter.tsx +0 -220
- package/PivotViewer/components/Spinner.tsx +0 -21
- package/PivotViewer/components/Toolbar.tsx +0 -130
- package/PivotViewer/components/ToolbarContainer.tsx +0 -10
- package/PivotViewer/components/index.ts +0 -12
- package/PivotViewer/components/pivot/animation.ts +0 -108
- package/PivotViewer/components/pivot/buckets.ts +0 -152
- package/PivotViewer/components/pivot/colorResolver.ts +0 -67
- package/PivotViewer/components/pivot/constants.ts +0 -46
- package/PivotViewer/components/pivot/sprites.ts +0 -265
- package/PivotViewer/components/pivot/visibility.ts +0 -319
- package/PivotViewer/constants.ts +0 -9
- package/PivotViewer/engine/layout.ts +0 -149
- package/PivotViewer/engine/pivot.worker.ts +0 -86
- package/PivotViewer/engine/store.ts +0 -437
- package/PivotViewer/engine/types.ts +0 -255
- package/PivotViewer/hooks/index.ts +0 -13
- package/PivotViewer/hooks/useContainerDimensions.ts +0 -45
- package/PivotViewer/hooks/useDimensionState.ts +0 -53
- package/PivotViewer/hooks/useFilterOptions.ts +0 -36
- package/PivotViewer/hooks/useFilterPanelDrag.ts +0 -49
- package/PivotViewer/hooks/useFilterState.ts +0 -106
- package/PivotViewer/hooks/useFilteredData.ts +0 -119
- package/PivotViewer/hooks/usePanning.ts +0 -163
- package/PivotViewer/hooks/usePivotEngine.ts +0 -252
- package/PivotViewer/hooks/useSelectedItem.ts +0 -402
- package/PivotViewer/hooks/useWheelZoom.ts +0 -114
- package/PivotViewer/hooks/useZoomState.ts +0 -34
- package/PivotViewer/index.ts +0 -7
- package/PivotViewer/types.ts +0 -59
- package/PivotViewer/utils/animations.ts +0 -249
- package/PivotViewer/utils/constants.ts +0 -20
- package/PivotViewer/utils/index.ts +0 -6
- package/PivotViewer/utils/selection.ts +0 -292
- package/PivotViewer/utils/utils.ts +0 -259
- package/TimeMachine/EventsView.stories.tsx +0 -10
- package/TimeMachine/EventsView.tsx +0 -119
- package/TimeMachine/Properties.stories.tsx +0 -10
- package/TimeMachine/Properties.tsx +0 -98
- package/TimeMachine/ReadModelView.stories.tsx +0 -10
- package/TimeMachine/ReadModelView.tsx +0 -143
- package/TimeMachine/TimeMachine.stories.tsx +0 -10
- package/TimeMachine/TimeMachine.tsx +0 -244
- package/TimeMachine/index.ts +0 -8
- package/TimeMachine/types.ts +0 -23
- package/dist/cjs/CommandForm/DatePickerField.js +0 -31
- package/dist/cjs/CommandForm/DatePickerField.js.map +0 -1
- package/dist/cjs/CommandForm/DropdownField.js +0 -31
- package/dist/cjs/CommandForm/DropdownField.js.map +0 -1
- package/dist/cjs/CommandForm/InputTextField.js +0 -32
- package/dist/cjs/CommandForm/InputTextField.js.map +0 -1
- package/dist/cjs/CommandForm/SliderField.js +0 -34
- package/dist/cjs/CommandForm/SliderField.js.map +0 -1
- package/dist/esm/CommandForm/DatePickerField.d.ts +0 -20
- package/dist/esm/CommandForm/DatePickerField.d.ts.map +0 -1
- package/dist/esm/CommandForm/DatePickerField.js +0 -29
- package/dist/esm/CommandForm/DatePickerField.js.map +0 -1
- package/dist/esm/CommandForm/DropdownField.d.ts +0 -24
- package/dist/esm/CommandForm/DropdownField.d.ts.map +0 -1
- package/dist/esm/CommandForm/DropdownField.js +0 -29
- package/dist/esm/CommandForm/DropdownField.js.map +0 -1
- package/dist/esm/CommandForm/InputTextField.d.ts +0 -20
- package/dist/esm/CommandForm/InputTextField.d.ts.map +0 -1
- package/dist/esm/CommandForm/InputTextField.js +0 -30
- package/dist/esm/CommandForm/InputTextField.js.map +0 -1
- package/dist/esm/CommandForm/SliderField.d.ts +0 -23
- package/dist/esm/CommandForm/SliderField.d.ts.map +0 -1
- package/dist/esm/CommandForm/SliderField.js +0 -32
- package/dist/esm/CommandForm/SliderField.js.map +0 -1
- package/global.d.ts +0 -11
- package/index.ts +0 -22
- package/useOverlayZIndex.ts +0 -32
- package/vite.config.ts +0 -80
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cratis/components",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "Cratis",
|
|
6
6
|
"license": "MIT",
|
|
@@ -12,9 +12,7 @@
|
|
|
12
12
|
"access": "public"
|
|
13
13
|
},
|
|
14
14
|
"files": [
|
|
15
|
-
"dist"
|
|
16
|
-
"**/*.ts",
|
|
17
|
-
"**/*.tsx"
|
|
15
|
+
"dist"
|
|
18
16
|
],
|
|
19
17
|
"type": "module",
|
|
20
18
|
"main": "dist/cjs/index.js",
|
|
@@ -72,6 +70,7 @@
|
|
|
72
70
|
"prepare": "yarn g:build",
|
|
73
71
|
"clean": "yarn g:clean",
|
|
74
72
|
"build": "tsc -p tsconfig.json",
|
|
73
|
+
"copy-css": "./scripts/copy-css.sh",
|
|
75
74
|
"lint": "yarn g:lint",
|
|
76
75
|
"lint:ci": "yarn g:lint:ci",
|
|
77
76
|
"test": "yarn g:test",
|
|
@@ -81,27 +80,27 @@
|
|
|
81
80
|
"build-storybook": "storybook build"
|
|
82
81
|
},
|
|
83
82
|
"devDependencies": {
|
|
84
|
-
"@eslint/eslintrc": "^3.3.
|
|
85
|
-
"@eslint/js": "^9.39.
|
|
86
|
-
"@storybook/react": "^10.1.
|
|
87
|
-
"@storybook/react-vite": "^10.1.
|
|
88
|
-
"@tailwindcss/postcss": "^4.1.
|
|
89
|
-
"@tailwindcss/vite": "^4.1.
|
|
83
|
+
"@eslint/eslintrc": "^3.3.3",
|
|
84
|
+
"@eslint/js": "^9.39.2",
|
|
85
|
+
"@storybook/react": "^10.1.11",
|
|
86
|
+
"@storybook/react-vite": "^10.1.11",
|
|
87
|
+
"@tailwindcss/postcss": "^4.1.18",
|
|
88
|
+
"@tailwindcss/vite": "^4.1.18",
|
|
90
89
|
"@types/chai": "^5.2.3",
|
|
91
90
|
"@types/chai-as-promised": "^8.0.2",
|
|
92
91
|
"@types/leaflet": "^1.9.21",
|
|
93
92
|
"@types/mocha": "^10.0.10",
|
|
94
|
-
"@types/node": "^
|
|
93
|
+
"@types/node": "^25.0.3",
|
|
95
94
|
"@types/react": "^19.2.7",
|
|
96
95
|
"@types/react-dom": "^19.2.3",
|
|
97
96
|
"@types/sinon": "^21.0.0",
|
|
98
97
|
"@types/sinon-chai": "^4.0.0",
|
|
99
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
100
|
-
"@typescript-eslint/parser": "^8.
|
|
101
|
-
"@vitejs/plugin-react": "^5.1.
|
|
102
|
-
"@vitest/coverage-v8": "^4.0.
|
|
103
|
-
"autoprefixer": "^10.4.
|
|
104
|
-
"chai": "^6.2.
|
|
98
|
+
"@typescript-eslint/eslint-plugin": "^8.52.0",
|
|
99
|
+
"@typescript-eslint/parser": "^8.52.0",
|
|
100
|
+
"@vitejs/plugin-react": "^5.1.2",
|
|
101
|
+
"@vitest/coverage-v8": "^4.0.16",
|
|
102
|
+
"autoprefixer": "^10.4.23",
|
|
103
|
+
"chai": "^6.2.2",
|
|
105
104
|
"chai-as-promised": "^8.0.2",
|
|
106
105
|
"edit-json-file": "^1.8.1",
|
|
107
106
|
"eslint": "^9.39.1",
|
|
@@ -111,7 +110,7 @@
|
|
|
111
110
|
"eslint-plugin-no-null": "^1.0.2",
|
|
112
111
|
"eslint-plugin-prettier": "^5.5.4",
|
|
113
112
|
"eslint-plugin-react": "^7.37.5",
|
|
114
|
-
"glob": "^
|
|
113
|
+
"glob": "^13.0.0",
|
|
115
114
|
"globals": "^16.5.0",
|
|
116
115
|
"mocha": "^11.7.5",
|
|
117
116
|
"module-alias": "^2.2.3",
|
|
@@ -122,25 +121,25 @@
|
|
|
122
121
|
"rollup-plugin-commonjs": "^10.1.0",
|
|
123
122
|
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
124
123
|
"rollup-plugin-typescript2": "^0.36.0",
|
|
125
|
-
"sinon": "^21.0.
|
|
124
|
+
"sinon": "^21.0.1",
|
|
126
125
|
"sinon-chai": "^4.0.1",
|
|
127
|
-
"storybook": "^10.1.
|
|
128
|
-
"tailwindcss": "^
|
|
126
|
+
"storybook": "^10.1.11",
|
|
127
|
+
"tailwindcss": "^4.1.18",
|
|
129
128
|
"ts-node": "^10.9.2",
|
|
130
129
|
"typescript": "^5.9.3",
|
|
131
|
-
"typescript-eslint": "^8.
|
|
132
|
-
"vite": "^7.
|
|
130
|
+
"typescript-eslint": "^8.52.0",
|
|
131
|
+
"vite": "^7.3.1",
|
|
133
132
|
"vite-plugin-commonjs": "^0.10.4",
|
|
134
|
-
"vite-tsconfig-paths": "^
|
|
135
|
-
"vitest": "^4.0.
|
|
133
|
+
"vite-tsconfig-paths": "^6.0.3",
|
|
134
|
+
"vitest": "^4.0.16"
|
|
136
135
|
},
|
|
137
136
|
"dependencies": {
|
|
138
|
-
"@cratis/arc": "^18.
|
|
139
|
-
"@cratis/arc.react": "^18.
|
|
140
|
-
"@cratis/arc.vite": "^18.
|
|
141
|
-
"allotment": "1.20.
|
|
142
|
-
"framer-motion": "12.
|
|
143
|
-
"pixi.js": "^8.
|
|
137
|
+
"@cratis/arc": "^18.7.17",
|
|
138
|
+
"@cratis/arc.react": "^18.7.17",
|
|
139
|
+
"@cratis/arc.vite": "^18.7.17",
|
|
140
|
+
"allotment": "1.20.5",
|
|
141
|
+
"framer-motion": "12.24.11",
|
|
142
|
+
"pixi.js": "^8.15.0",
|
|
144
143
|
"primeicons": "7.0.0",
|
|
145
144
|
"primereact": "10.9.7",
|
|
146
145
|
"quill": "^2.0.3",
|
|
@@ -148,7 +147,7 @@
|
|
|
148
147
|
"react-dom": "19.2.3",
|
|
149
148
|
"react-icons": "5.5.0",
|
|
150
149
|
"react-leaflet": "^5.0.0",
|
|
151
|
-
"react-router-dom": "7.
|
|
150
|
+
"react-router-dom": "7.12.0",
|
|
152
151
|
"reflect-metadata": "0.2.2",
|
|
153
152
|
"ts-deepmerge": "7.0.3",
|
|
154
153
|
"tsyringe": "4.10.0",
|
package/.storybook/main.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
-
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
-
|
|
4
|
-
import type { StorybookConfig } from '@storybook/react-vite';
|
|
5
|
-
import type { UserConfig as ViteConfig } from 'vite';
|
|
6
|
-
|
|
7
|
-
const config: StorybookConfig = {
|
|
8
|
-
stories: ['../**/*.stories.@(js|jsx|ts|tsx)'],
|
|
9
|
-
addons: [],
|
|
10
|
-
framework: {
|
|
11
|
-
name: '@storybook/react-vite',
|
|
12
|
-
options: {}
|
|
13
|
-
},
|
|
14
|
-
core: { builder: '@storybook/builder-vite' },
|
|
15
|
-
staticDirs: ['../public'],
|
|
16
|
-
// Ensure Vite dev server does not open the browser when Storybook starts
|
|
17
|
-
async viteFinal(existingConfig: ViteConfig) {
|
|
18
|
-
const cfg: ViteConfig = { ...existingConfig };
|
|
19
|
-
cfg.server = { ...(cfg.server || {}), open: false } as unknown;
|
|
20
|
-
return cfg;
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export default config;
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
-
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
-
|
|
4
|
-
import React from 'react';
|
|
5
|
-
import { Meta, StoryObj } from '@storybook/react';
|
|
6
|
-
import { CommandDialog } from './CommandDialog';
|
|
7
|
-
|
|
8
|
-
const meta: Meta<typeof CommandDialog> = {
|
|
9
|
-
title: 'CommandDialog/CommandDialog',
|
|
10
|
-
component: CommandDialog,
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export default meta;
|
|
14
|
-
type Story = StoryObj<typeof CommandDialog>;
|
|
15
|
-
|
|
16
|
-
export const Default: Story = {
|
|
17
|
-
args: {
|
|
18
|
-
|
|
19
|
-
},
|
|
20
|
-
render: (args) => (
|
|
21
|
-
<div className="storybook-wrapper">
|
|
22
|
-
<CommandDialog {...args} />
|
|
23
|
-
</div>
|
|
24
|
-
)
|
|
25
|
-
};
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
-
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
-
|
|
4
|
-
import { ICommandResult } from '@cratis/arc/commands';
|
|
5
|
-
import { Constructor } from '@cratis/fundamentals';
|
|
6
|
-
import { Dialog } from 'primereact/dialog';
|
|
7
|
-
import { Button } from 'primereact/button';
|
|
8
|
-
import React, { createContext, useContext } from 'react';
|
|
9
|
-
import { CommandForm, useCommandFormContext, BeforeExecuteCallback } from '../CommandForm/CommandForm';
|
|
10
|
-
import { useCommandInstance } from '../CommandForm/CommandForm';
|
|
11
|
-
|
|
12
|
-
export type FieldValidator<TCommand> = (command: TCommand, fieldName: string, oldValue: unknown, newValue: unknown) => string | undefined;
|
|
13
|
-
export type FieldChangeCallback<TCommand> = (command: TCommand, fieldName: string, oldValue: unknown, newValue: unknown) => void;
|
|
14
|
-
|
|
15
|
-
export interface CommandDialogProps<TCommand, TResponse = object> {
|
|
16
|
-
command: Constructor<TCommand>;
|
|
17
|
-
initialValues?: Partial<TCommand>;
|
|
18
|
-
currentValues?: Partial<TCommand> | undefined;
|
|
19
|
-
visible: boolean;
|
|
20
|
-
header: string;
|
|
21
|
-
confirmLabel?: string;
|
|
22
|
-
cancelLabel?: string;
|
|
23
|
-
confirmIcon?: string;
|
|
24
|
-
cancelIcon?: string;
|
|
25
|
-
onConfirm: (result: ICommandResult<TResponse>) => void | Promise<void>;
|
|
26
|
-
onCancel: () => void;
|
|
27
|
-
onFieldValidate?: FieldValidator<TCommand>;
|
|
28
|
-
onFieldChange?: FieldChangeCallback<TCommand>;
|
|
29
|
-
onBeforeExecute?: BeforeExecuteCallback<TCommand>;
|
|
30
|
-
children?: React.ReactNode;
|
|
31
|
-
style?: React.CSSProperties;
|
|
32
|
-
width?: string;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
interface CommandDialogContextValue<TCommand = unknown> {
|
|
36
|
-
onSuccess: (result: ICommandResult<any>) => void | Promise<void>;
|
|
37
|
-
onCancel: () => void;
|
|
38
|
-
confirmLabel: string;
|
|
39
|
-
cancelLabel: string;
|
|
40
|
-
confirmIcon: string;
|
|
41
|
-
cancelIcon: string;
|
|
42
|
-
onFieldValidate?: FieldValidator<TCommand>;
|
|
43
|
-
onFieldChange?: FieldChangeCallback<TCommand>;
|
|
44
|
-
onBeforeExecute?: BeforeExecuteCallback<TCommand>;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const CommandDialogContext = createContext<CommandDialogContextValue<unknown> | undefined>(undefined);
|
|
48
|
-
|
|
49
|
-
export const useCommandDialogContext = <TCommand = unknown,>() => {
|
|
50
|
-
const context = useContext(CommandDialogContext);
|
|
51
|
-
if (!context) {
|
|
52
|
-
throw new Error('useCommandDialogContext must be used within a CommandDialog');
|
|
53
|
-
}
|
|
54
|
-
return context as CommandDialogContextValue<TCommand>;
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
const CommandDialogFormContent = () => {
|
|
58
|
-
const command = useCommandInstance();
|
|
59
|
-
const { setCommandResult, setCommandValues, isValid, onBeforeExecute } = useCommandFormContext();
|
|
60
|
-
const { onSuccess: onConfirm, onCancel, confirmLabel, cancelLabel, confirmIcon, cancelIcon } = useCommandDialogContext();
|
|
61
|
-
|
|
62
|
-
const handleConfirm = async () => {
|
|
63
|
-
if (onBeforeExecute) {
|
|
64
|
-
const transformedValues = onBeforeExecute(command);
|
|
65
|
-
setCommandValues(transformedValues);
|
|
66
|
-
}
|
|
67
|
-
const result = await command.execute();
|
|
68
|
-
if (result.isSuccess) {
|
|
69
|
-
await onConfirm(result);
|
|
70
|
-
} else {
|
|
71
|
-
setCommandResult(result);
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const handleCancel = () => {
|
|
76
|
-
onCancel();
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
return (
|
|
80
|
-
<>
|
|
81
|
-
<div className="card flex flex-wrap justify-content-center gap-3 mt-8">
|
|
82
|
-
<Button label={confirmLabel} icon={confirmIcon} onClick={handleConfirm} disabled={!isValid} />
|
|
83
|
-
<Button label={cancelLabel} icon={cancelIcon} severity='secondary' onClick={handleCancel} />
|
|
84
|
-
</div>
|
|
85
|
-
</>
|
|
86
|
-
);
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const CommandDialogFieldsWrapper = (props: { children: React.ReactNode }) => {
|
|
90
|
-
React.Children.forEach(props.children, child => {
|
|
91
|
-
if (React.isValidElement(child)) {
|
|
92
|
-
const component = child.type as any;
|
|
93
|
-
if (component.displayName !== 'CommandFormField') {
|
|
94
|
-
throw new Error(`Only CommandFormField components are allowed as children of CommandDialog.Fields. Got: ${component.displayName || component.name || 'Unknown'}`);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
return (
|
|
100
|
-
<CommandForm.Fields>
|
|
101
|
-
{props.children}
|
|
102
|
-
</CommandForm.Fields>
|
|
103
|
-
);
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
const CommandDialogComponent = <TCommand extends object = any, TResponse = object>(props: CommandDialogProps<TCommand, TResponse>) => {
|
|
107
|
-
const {
|
|
108
|
-
command,
|
|
109
|
-
initialValues,
|
|
110
|
-
currentValues,
|
|
111
|
-
visible,
|
|
112
|
-
header,
|
|
113
|
-
confirmLabel = 'Confirm',
|
|
114
|
-
cancelLabel = 'Cancel',
|
|
115
|
-
confirmIcon = 'pi pi-check',
|
|
116
|
-
cancelIcon = 'pi pi-times',
|
|
117
|
-
onConfirm,
|
|
118
|
-
onCancel,
|
|
119
|
-
onFieldValidate,
|
|
120
|
-
onFieldChange,
|
|
121
|
-
onBeforeExecute,
|
|
122
|
-
children,
|
|
123
|
-
style = { width: '50vw' },
|
|
124
|
-
width
|
|
125
|
-
} = props;
|
|
126
|
-
|
|
127
|
-
const dialogStyle = width ? { ...style, width } : style;
|
|
128
|
-
|
|
129
|
-
const contextValue: CommandDialogContextValue<TCommand> = {
|
|
130
|
-
onSuccess: onConfirm,
|
|
131
|
-
onCancel,
|
|
132
|
-
confirmLabel,
|
|
133
|
-
cancelLabel,
|
|
134
|
-
confirmIcon,
|
|
135
|
-
cancelIcon,
|
|
136
|
-
onFieldValidate,
|
|
137
|
-
onFieldChange,
|
|
138
|
-
onBeforeExecute
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
return (
|
|
142
|
-
<Dialog
|
|
143
|
-
header={header}
|
|
144
|
-
visible={visible}
|
|
145
|
-
style={dialogStyle}
|
|
146
|
-
onHide={onCancel}
|
|
147
|
-
contentStyle={{ overflow: 'visible' }}
|
|
148
|
-
>
|
|
149
|
-
<CommandDialogContext.Provider value={contextValue}>
|
|
150
|
-
<CommandForm command={command} initialValues={initialValues} currentValues={currentValues} onFieldValidate={onFieldValidate} onFieldChange={onFieldChange} onBeforeExecute={onBeforeExecute}>
|
|
151
|
-
{children}
|
|
152
|
-
<CommandDialogFormContent />
|
|
153
|
-
</CommandForm>
|
|
154
|
-
</CommandDialogContext.Provider>
|
|
155
|
-
</Dialog>
|
|
156
|
-
);
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
CommandDialogComponent.Fields = CommandDialogFieldsWrapper;
|
|
160
|
-
|
|
161
|
-
export const CommandDialog = CommandDialogComponent;
|
package/CommandDialog/index.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
-
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
-
|
|
4
|
-
import React from 'react';
|
|
5
|
-
import { Meta, StoryObj } from '@storybook/react';
|
|
6
|
-
import { CommandForm } from './CommandForm';
|
|
7
|
-
|
|
8
|
-
const meta: Meta<typeof CommandForm> = {
|
|
9
|
-
title: 'CommandForm/CommandForm',
|
|
10
|
-
component: CommandForm,
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export default meta;
|
|
14
|
-
type Story = StoryObj<typeof CommandForm>;
|
|
15
|
-
export const Default: Story = {
|
|
16
|
-
args: {
|
|
17
|
-
|
|
18
|
-
},
|
|
19
|
-
render: (args) => (
|
|
20
|
-
<div className="storybook-wrapper">
|
|
21
|
-
<CommandForm {...args} />
|
|
22
|
-
</div>
|
|
23
|
-
)
|
|
24
|
-
};
|
|
@@ -1,266 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
-
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
-
|
|
4
|
-
import { CommandFormFields, ColumnInfo } from './CommandFormFields';
|
|
5
|
-
import { Constructor } from '@cratis/fundamentals';
|
|
6
|
-
import { useCommand, SetCommandValues } from '@cratis/arc.react/commands';
|
|
7
|
-
import { ICommandResult } from '@cratis/arc/commands';
|
|
8
|
-
import React, { createContext, useContext, useMemo, useState, useCallback } from 'react';
|
|
9
|
-
import type { CommandFormFieldProps } from './CommandFormField';
|
|
10
|
-
import { Panel } from 'primereact/panel';
|
|
11
|
-
|
|
12
|
-
export type BeforeExecuteCallback<TCommand> = (values: TCommand) => TCommand;
|
|
13
|
-
|
|
14
|
-
export interface CommandFormProps<TCommand extends object> {
|
|
15
|
-
command: Constructor<TCommand>;
|
|
16
|
-
initialValues?: Partial<TCommand>;
|
|
17
|
-
currentValues?: Partial<TCommand> | undefined;
|
|
18
|
-
onFieldValidate?: (command: TCommand, fieldName: string, oldValue: unknown, newValue: unknown) => string | undefined;
|
|
19
|
-
onFieldChange?: (command: TCommand, fieldName: string, oldValue: unknown, newValue: unknown) => void;
|
|
20
|
-
onBeforeExecute?: BeforeExecuteCallback<TCommand>;
|
|
21
|
-
children?: React.ReactNode;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
interface CommandFormContextValue<TCommand> {
|
|
25
|
-
command: Constructor<TCommand>;
|
|
26
|
-
commandInstance: TCommand;
|
|
27
|
-
setCommandValues: SetCommandValues<TCommand>;
|
|
28
|
-
commandResult?: ICommandResult<unknown>;
|
|
29
|
-
setCommandResult: (result: ICommandResult<unknown>) => void;
|
|
30
|
-
getFieldError: (propertyName: string) => string | undefined;
|
|
31
|
-
isValid: boolean;
|
|
32
|
-
setFieldValidity: (fieldName: string, isValid: boolean) => void;
|
|
33
|
-
onFieldValidate?: (command: TCommand, fieldName: string, oldValue: unknown, newValue: unknown) => string | undefined;
|
|
34
|
-
onFieldChange?: (command: TCommand, fieldName: string, oldValue: unknown, newValue: unknown) => void;
|
|
35
|
-
onBeforeExecute?: BeforeExecuteCallback<TCommand>;
|
|
36
|
-
customFieldErrors: Record<string, string>;
|
|
37
|
-
setCustomFieldError: (fieldName: string, error: string | undefined) => void;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const CommandFormContext = createContext<CommandFormContextValue<any> | undefined>(undefined);
|
|
41
|
-
|
|
42
|
-
export const useCommandFormContext = <TCommand,>() => {
|
|
43
|
-
const context = useContext(CommandFormContext);
|
|
44
|
-
if (!context) {
|
|
45
|
-
throw new Error('useCommandFormContext must be used within a CommandForm');
|
|
46
|
-
}
|
|
47
|
-
return context as CommandFormContextValue<TCommand>;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
// Hook to get just the command instance for easier access
|
|
51
|
-
export const useCommandInstance = <TCommand = any>() => {
|
|
52
|
-
const { commandInstance } = useCommandFormContext<any>();
|
|
53
|
-
return commandInstance as TCommand;
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
// Hook to get setCommandResult for easier access
|
|
57
|
-
export const useSetCommandResult = () => {
|
|
58
|
-
const { setCommandResult } = useCommandFormContext();
|
|
59
|
-
return setCommandResult;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
const CommandFormFieldsWrapper = (props: { children: React.ReactNode }) => {
|
|
63
|
-
React.Children.forEach(props.children, child => {
|
|
64
|
-
if (React.isValidElement(child)) {
|
|
65
|
-
const component = child.type as any;
|
|
66
|
-
if (component.displayName !== 'CommandFormField') {
|
|
67
|
-
throw new Error(`Only CommandFormField components are allowed as children of CommandForm.Fields. Got: ${component.displayName || component.name || 'Unknown'}`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
return <></>;
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
CommandFormFieldsWrapper.displayName = 'CommandFormFieldsWrapper';
|
|
76
|
-
|
|
77
|
-
const getCommandFormFields = <TCommand,>(props: { children?: React.ReactNode }): { fieldsOrColumns: React.ReactElement[] | ColumnInfo[], otherChildren: React.ReactNode[], initialValuesFromFields: Partial<TCommand> } => {
|
|
78
|
-
if (!props.children) {
|
|
79
|
-
return { fieldsOrColumns: [], otherChildren: [], initialValuesFromFields: {} };
|
|
80
|
-
}
|
|
81
|
-
let fields: React.ReactElement<CommandFormFieldProps<any>>[] = [];
|
|
82
|
-
const columns: ColumnInfo[] = [];
|
|
83
|
-
let hasColumns = false;
|
|
84
|
-
const otherChildren: React.ReactNode[] = [];
|
|
85
|
-
let initialValuesFromFields: Partial<TCommand> = {};
|
|
86
|
-
|
|
87
|
-
const extractInitialValue = (field: React.ReactElement) => {
|
|
88
|
-
const fieldProps = field.props as any;
|
|
89
|
-
if (fieldProps.currentValue !== undefined && fieldProps.value) {
|
|
90
|
-
const propertyAccessor = fieldProps.value;
|
|
91
|
-
const propertyName = getPropertyNameFromAccessor(propertyAccessor);
|
|
92
|
-
if (propertyName) {
|
|
93
|
-
initialValuesFromFields = { ...initialValuesFromFields, [propertyName]: fieldProps.currentValue } as Partial<TCommand>;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
React.Children.toArray(props.children).forEach(child => {
|
|
99
|
-
if (!React.isValidElement(child)) {
|
|
100
|
-
otherChildren.push(child);
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const component = child.type as any;
|
|
105
|
-
|
|
106
|
-
// Check if child is a CommandFormColumn
|
|
107
|
-
if (component.displayName === 'CommandFormColumn') {
|
|
108
|
-
hasColumns = true;
|
|
109
|
-
const childProps = child.props as { children?: React.ReactNode };
|
|
110
|
-
const columnFields = React.Children.toArray(childProps.children).filter(child => {
|
|
111
|
-
if (React.isValidElement(child)) {
|
|
112
|
-
const comp = child.type as any;
|
|
113
|
-
if (comp.displayName === 'CommandFormField') {
|
|
114
|
-
extractInitialValue(child as React.ReactElement);
|
|
115
|
-
return true;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
return false;
|
|
119
|
-
}) as React.ReactElement[];
|
|
120
|
-
columns.push({ fields: columnFields as React.ReactElement<CommandFormFieldProps<any>>[] });
|
|
121
|
-
}
|
|
122
|
-
// Check if child is a CommandFormField (direct child)
|
|
123
|
-
else if (component.displayName === 'CommandFormField') {
|
|
124
|
-
extractInitialValue(child as React.ReactElement);
|
|
125
|
-
fields.push(child as React.ReactElement<CommandFormFieldProps<any>>);
|
|
126
|
-
}
|
|
127
|
-
// Check if child is Fields wrapper (backwards compatibility)
|
|
128
|
-
else if (component === CommandFormFieldsWrapper || component.displayName === 'CommandFormFieldsWrapper') {
|
|
129
|
-
const childProps = child.props as { children: React.ReactNode };
|
|
130
|
-
const relevantChildren = React.Children.toArray(childProps.children).filter(child => {
|
|
131
|
-
if (React.isValidElement(child)) {
|
|
132
|
-
const component = child.type as any;
|
|
133
|
-
if (component.displayName === 'CommandFormField') {
|
|
134
|
-
extractInitialValue(child as React.ReactElement);
|
|
135
|
-
return true;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
return false;
|
|
139
|
-
}) as React.ReactElement[];
|
|
140
|
-
fields = [...fields, ...(relevantChildren as React.ReactElement<CommandFormFieldProps<any>>[])];
|
|
141
|
-
}
|
|
142
|
-
// Everything else is not a field, keep it as other children
|
|
143
|
-
else {
|
|
144
|
-
otherChildren.push(child);
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
return { fieldsOrColumns: hasColumns ? columns : fields, otherChildren, initialValuesFromFields };
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
// Helper function to extract property name from accessor function
|
|
152
|
-
function getPropertyNameFromAccessor<T>(accessor: (obj: T) => unknown): string {
|
|
153
|
-
const fnStr = accessor.toString();
|
|
154
|
-
const match = fnStr.match(/\.([a-zA-Z_$][a-zA-Z0-9_$]*)/);
|
|
155
|
-
return match ? match[1] : '';
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const CommandFormComponent = <TCommand extends object = any>(props: CommandFormProps<TCommand>) => {
|
|
159
|
-
const { fieldsOrColumns, otherChildren, initialValuesFromFields } = useMemo(() => getCommandFormFields<TCommand>(props), [props.children]);
|
|
160
|
-
|
|
161
|
-
// Extract matching properties from currentValues
|
|
162
|
-
const valuesFromCurrentValues = useMemo(() => {
|
|
163
|
-
if (!props.currentValues) return {};
|
|
164
|
-
|
|
165
|
-
const tempCommand = new props.command();
|
|
166
|
-
const commandProperties = (tempCommand as any).properties || [];
|
|
167
|
-
const extracted: Partial<TCommand> = {};
|
|
168
|
-
|
|
169
|
-
commandProperties.forEach((propertyName: string) => {
|
|
170
|
-
if ((props.currentValues as any)[propertyName] !== undefined) {
|
|
171
|
-
(extracted as any)[propertyName] = (props.currentValues as any)[propertyName];
|
|
172
|
-
}
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
return extracted;
|
|
176
|
-
}, [props.currentValues, props.command]);
|
|
177
|
-
|
|
178
|
-
// Merge initialValues prop with values extracted from field currentValue props and currentValues
|
|
179
|
-
const mergedInitialValues = useMemo(() => ({
|
|
180
|
-
...valuesFromCurrentValues,
|
|
181
|
-
...initialValuesFromFields,
|
|
182
|
-
...props.initialValues
|
|
183
|
-
}), [valuesFromCurrentValues, initialValuesFromFields, props.initialValues]);
|
|
184
|
-
|
|
185
|
-
// useCommand returns [instance, setter] for the typed command. Provide generics so commandInstance is TCommand.
|
|
186
|
-
const [commandInstance, setCommandValues] = useCommand<any>(props.command as Constructor<any>, mergedInitialValues as Partial<any>);
|
|
187
|
-
const [commandResult, setCommandResult] = useState<ICommandResult<unknown> | undefined>(undefined);
|
|
188
|
-
const [fieldValidities, setFieldValidities] = useState<Record<string, boolean>>({});
|
|
189
|
-
const [customFieldErrors, setCustomFieldErrors] = useState<Record<string, string>>({});
|
|
190
|
-
|
|
191
|
-
// Update command values when mergedInitialValues changes (e.g., when data loads asynchronously)
|
|
192
|
-
React.useEffect(() => {
|
|
193
|
-
if (mergedInitialValues && Object.keys(mergedInitialValues).length > 0) {
|
|
194
|
-
setCommandValues(mergedInitialValues as TCommand);
|
|
195
|
-
}
|
|
196
|
-
}, [mergedInitialValues, setCommandValues]);
|
|
197
|
-
|
|
198
|
-
const isValid = Object.values(fieldValidities).every(valid => valid);
|
|
199
|
-
|
|
200
|
-
const setFieldValidity = useCallback((fieldName: string, isFieldValid: boolean) => {
|
|
201
|
-
setFieldValidities(prev => ({ ...prev, [fieldName]: isFieldValid }));
|
|
202
|
-
}, []);
|
|
203
|
-
|
|
204
|
-
const setCustomFieldError = useCallback((fieldName: string, error: string | undefined) => {
|
|
205
|
-
setCustomFieldErrors(prev => {
|
|
206
|
-
if (error === undefined) {
|
|
207
|
-
const newErrors = { ...prev };
|
|
208
|
-
delete newErrors[fieldName];
|
|
209
|
-
return newErrors;
|
|
210
|
-
}
|
|
211
|
-
return { ...prev, [fieldName]: error };
|
|
212
|
-
});
|
|
213
|
-
}, []);
|
|
214
|
-
|
|
215
|
-
const getFieldError = (propertyName: string): string | undefined => {
|
|
216
|
-
// Check custom field errors first
|
|
217
|
-
if (customFieldErrors[propertyName]) {
|
|
218
|
-
return customFieldErrors[propertyName];
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
if (!commandResult || !commandResult.validationResults) {
|
|
222
|
-
return undefined;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
for (const validationResult of commandResult.validationResults) {
|
|
226
|
-
if (validationResult.members && validationResult.members.includes(propertyName)) {
|
|
227
|
-
return validationResult.message;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
return undefined;
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
const exceptionMessages = commandResult?.exceptionMessages || [];
|
|
235
|
-
const hasColumns = fieldsOrColumns.length > 0 && 'fields' in fieldsOrColumns[0];
|
|
236
|
-
|
|
237
|
-
return (
|
|
238
|
-
<CommandFormContext.Provider value={{ command: props.command, commandInstance, setCommandValues, commandResult, setCommandResult, getFieldError, isValid, setFieldValidity, onFieldValidate: props.onFieldValidate, onFieldChange: props.onFieldChange, onBeforeExecute: props.onBeforeExecute, customFieldErrors, setCustomFieldError }}>
|
|
239
|
-
<CommandFormFields fields={hasColumns ? undefined : (fieldsOrColumns as React.ReactElement<CommandFormFieldProps<any>>[])} columns={hasColumns ? fieldsOrColumns as ColumnInfo[] : undefined} />
|
|
240
|
-
{exceptionMessages.length > 0 && (
|
|
241
|
-
<div className="card flex flex-row gap-3 mt-3">
|
|
242
|
-
<Panel header="The server responded with" className="w-full">
|
|
243
|
-
<ul>
|
|
244
|
-
{exceptionMessages.map((msg, idx) => (
|
|
245
|
-
<li key={idx}>{msg}</li>
|
|
246
|
-
))}
|
|
247
|
-
</ul>
|
|
248
|
-
</Panel>
|
|
249
|
-
</div>
|
|
250
|
-
)}
|
|
251
|
-
{otherChildren}
|
|
252
|
-
</CommandFormContext.Provider>
|
|
253
|
-
);
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
const CommandFormColumnComponent = (_props: { children: React.ReactNode }) => {
|
|
257
|
-
void _props;
|
|
258
|
-
return <></>;
|
|
259
|
-
};
|
|
260
|
-
|
|
261
|
-
CommandFormColumnComponent.displayName = 'CommandFormColumn';
|
|
262
|
-
|
|
263
|
-
CommandFormComponent.Fields = CommandFormFieldsWrapper;
|
|
264
|
-
CommandFormComponent.Column = CommandFormColumnComponent;
|
|
265
|
-
|
|
266
|
-
export const CommandForm = CommandFormComponent;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
-
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
-
|
|
4
|
-
import type { PropertyAccessor } from '@cratis/fundamentals';
|
|
5
|
-
|
|
6
|
-
export interface CommandFormFieldProps<TCommand = unknown> {
|
|
7
|
-
icon?: React.ReactElement;
|
|
8
|
-
/** Accessor function that selects a property on the command, e.g. c => c.name */
|
|
9
|
-
value?: PropertyAccessor<TCommand>;
|
|
10
|
-
/** Current value for the property (injected by CommandFormFields) */
|
|
11
|
-
currentValue?: unknown;
|
|
12
|
-
/** Called when the field value changes (injected by CommandFormFields) */
|
|
13
|
-
onValueChange?: (value: unknown) => void;
|
|
14
|
-
onChange?: (value: unknown) => void;
|
|
15
|
-
required?: boolean;
|
|
16
|
-
title?: string;
|
|
17
|
-
description?: string;
|
|
18
|
-
propertyDescriptor?: unknown;
|
|
19
|
-
fieldName?: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export const CommandFormField = <TCommand,>(_props?: CommandFormFieldProps<TCommand>) => {
|
|
23
|
-
void _props;
|
|
24
|
-
return <></>;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
CommandFormField.displayName = 'CommandFormField';
|