@vuu-ui/vuu-data-react 0.13.6 → 0.13.8

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.
Files changed (85) hide show
  1. package/cjs/index.js +1556 -40
  2. package/cjs/index.js.map +1 -1
  3. package/esm/index.js +1535 -15
  4. package/esm/index.js.map +1 -1
  5. package/package.json +14 -14
  6. package/cjs/data-editing/EditForm.css.js +0 -6
  7. package/cjs/data-editing/EditForm.css.js.map +0 -1
  8. package/cjs/data-editing/EditForm.js +0 -90
  9. package/cjs/data-editing/EditForm.js.map +0 -1
  10. package/cjs/data-editing/UnsavedChangesReport.css.js +0 -6
  11. package/cjs/data-editing/UnsavedChangesReport.css.js.map +0 -1
  12. package/cjs/data-editing/UnsavedChangesReport.js +0 -29
  13. package/cjs/data-editing/UnsavedChangesReport.js.map +0 -1
  14. package/cjs/data-editing/edit-rule-validation-checker.js +0 -41
  15. package/cjs/data-editing/edit-rule-validation-checker.js.map +0 -1
  16. package/cjs/data-editing/edit-validation-rules.js +0 -52
  17. package/cjs/data-editing/edit-validation-rules.js.map +0 -1
  18. package/cjs/data-editing/form-edit-state.js +0 -26
  19. package/cjs/data-editing/form-edit-state.js.map +0 -1
  20. package/cjs/data-editing/get-data-item-edit-control.js +0 -56
  21. package/cjs/data-editing/get-data-item-edit-control.js.map +0 -1
  22. package/cjs/data-editing/useEditForm.js +0 -249
  23. package/cjs/data-editing/useEditForm.js.map +0 -1
  24. package/cjs/datasource-provider/RestDataSourceProvider.js +0 -78
  25. package/cjs/datasource-provider/RestDataSourceProvider.js.map +0 -1
  26. package/cjs/datasource-provider/VuuDataSourceProvider.js +0 -34
  27. package/cjs/datasource-provider/VuuDataSourceProvider.js.map +0 -1
  28. package/cjs/datasource-provider/useAutoLoginToVuuServer.js +0 -54
  29. package/cjs/datasource-provider/useAutoLoginToVuuServer.js.map +0 -1
  30. package/cjs/hooks/useLookupValues.js +0 -100
  31. package/cjs/hooks/useLookupValues.js.map +0 -1
  32. package/cjs/hooks/useSessionDataSource.js +0 -72
  33. package/cjs/hooks/useSessionDataSource.js.map +0 -1
  34. package/cjs/hooks/useTypeaheadSuggestions.js +0 -41
  35. package/cjs/hooks/useTypeaheadSuggestions.js.map +0 -1
  36. package/cjs/hooks/useVisualLinks.js +0 -83
  37. package/cjs/hooks/useVisualLinks.js.map +0 -1
  38. package/cjs/hooks/useVuuMenuActions.js +0 -362
  39. package/cjs/hooks/useVuuMenuActions.js.map +0 -1
  40. package/cjs/hooks/useVuuTables.js +0 -38
  41. package/cjs/hooks/useVuuTables.js.map +0 -1
  42. package/cjs/session-editing-form/SessionEditingForm.css.js +0 -6
  43. package/cjs/session-editing-form/SessionEditingForm.css.js.map +0 -1
  44. package/cjs/session-editing-form/SessionEditingForm.js +0 -269
  45. package/cjs/session-editing-form/SessionEditingForm.js.map +0 -1
  46. package/esm/data-editing/EditForm.css.js +0 -4
  47. package/esm/data-editing/EditForm.css.js.map +0 -1
  48. package/esm/data-editing/EditForm.js +0 -88
  49. package/esm/data-editing/EditForm.js.map +0 -1
  50. package/esm/data-editing/UnsavedChangesReport.css.js +0 -4
  51. package/esm/data-editing/UnsavedChangesReport.css.js.map +0 -1
  52. package/esm/data-editing/UnsavedChangesReport.js +0 -27
  53. package/esm/data-editing/UnsavedChangesReport.js.map +0 -1
  54. package/esm/data-editing/edit-rule-validation-checker.js +0 -37
  55. package/esm/data-editing/edit-rule-validation-checker.js.map +0 -1
  56. package/esm/data-editing/edit-validation-rules.js +0 -50
  57. package/esm/data-editing/edit-validation-rules.js.map +0 -1
  58. package/esm/data-editing/form-edit-state.js +0 -23
  59. package/esm/data-editing/form-edit-state.js.map +0 -1
  60. package/esm/data-editing/get-data-item-edit-control.js +0 -54
  61. package/esm/data-editing/get-data-item-edit-control.js.map +0 -1
  62. package/esm/data-editing/useEditForm.js +0 -247
  63. package/esm/data-editing/useEditForm.js.map +0 -1
  64. package/esm/datasource-provider/RestDataSourceProvider.js +0 -75
  65. package/esm/datasource-provider/RestDataSourceProvider.js.map +0 -1
  66. package/esm/datasource-provider/VuuDataSourceProvider.js +0 -32
  67. package/esm/datasource-provider/VuuDataSourceProvider.js.map +0 -1
  68. package/esm/datasource-provider/useAutoLoginToVuuServer.js +0 -52
  69. package/esm/datasource-provider/useAutoLoginToVuuServer.js.map +0 -1
  70. package/esm/hooks/useLookupValues.js +0 -98
  71. package/esm/hooks/useLookupValues.js.map +0 -1
  72. package/esm/hooks/useSessionDataSource.js +0 -70
  73. package/esm/hooks/useSessionDataSource.js.map +0 -1
  74. package/esm/hooks/useTypeaheadSuggestions.js +0 -38
  75. package/esm/hooks/useTypeaheadSuggestions.js.map +0 -1
  76. package/esm/hooks/useVisualLinks.js +0 -81
  77. package/esm/hooks/useVisualLinks.js.map +0 -1
  78. package/esm/hooks/useVuuMenuActions.js +0 -358
  79. package/esm/hooks/useVuuMenuActions.js.map +0 -1
  80. package/esm/hooks/useVuuTables.js +0 -36
  81. package/esm/hooks/useVuuTables.js.map +0 -1
  82. package/esm/session-editing-form/SessionEditingForm.css.js +0 -4
  83. package/esm/session-editing-form/SessionEditingForm.css.js.map +0 -1
  84. package/esm/session-editing-form/SessionEditingForm.js +0 -267
  85. package/esm/session-editing-form/SessionEditingForm.js.map +0 -1
@@ -1,38 +0,0 @@
1
- 'use strict';
2
-
3
- var vuuUtils = require('@vuu-ui/vuu-utils');
4
- var react = require('react');
5
-
6
- const useVuuTables = () => {
7
- const [tableSchemas, setTableSchemas] = react.useState();
8
- const { getServerAPI } = vuuUtils.useData();
9
- const buildTables = react.useCallback((schemas) => {
10
- const vuuTables = /* @__PURE__ */ new Map();
11
- schemas.forEach((schema) => {
12
- const { module, table } = schema.table;
13
- vuuTables.set(`${module}:${table}`, schema);
14
- });
15
- return vuuTables;
16
- }, []);
17
- react.useEffect(() => {
18
- async function fetchTableMetadata() {
19
- try {
20
- const server = await getServerAPI();
21
- const { tables } = await server.getTableList();
22
- const tableSchemas2 = await Promise.all(
23
- tables.map((vuuTable) => server.getTableSchema(vuuTable))
24
- );
25
- setTableSchemas(tableSchemas2);
26
- } catch (err) {
27
- console.warn(
28
- `useVuuTables: error fetching table metadata ${String(err)}`
29
- );
30
- }
31
- }
32
- fetchTableMetadata();
33
- }, [buildTables, getServerAPI]);
34
- return tableSchemas;
35
- };
36
-
37
- exports.useVuuTables = useVuuTables;
38
- //# sourceMappingURL=useVuuTables.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useVuuTables.js","sources":["../../src/hooks/useVuuTables.ts"],"sourcesContent":["import type { TableSchema } from \"@vuu-ui/vuu-data-types\";\nimport { useData } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useEffect, useState } from \"react\";\n\nexport const useVuuTables = () => {\n const [tableSchemas, setTableSchemas] = useState<TableSchema[] | undefined>();\n\n const { getServerAPI } = useData();\n\n const buildTables = useCallback((schemas: TableSchema[]) => {\n const vuuTables = new Map<string, TableSchema>();\n schemas.forEach((schema) => {\n const { module, table } = schema.table;\n vuuTables.set(`${module}:${table}`, schema);\n });\n return vuuTables;\n }, []);\n\n useEffect(() => {\n async function fetchTableMetadata() {\n try {\n const server = await getServerAPI();\n const { tables } = await server.getTableList();\n const tableSchemas = await Promise.all(\n tables.map((vuuTable) => server.getTableSchema(vuuTable)),\n );\n setTableSchemas(tableSchemas);\n } catch (err) {\n console.warn(\n `useVuuTables: error fetching table metadata ${String(err)}`,\n );\n }\n }\n\n fetchTableMetadata();\n }, [buildTables, getServerAPI]);\n\n return tableSchemas;\n};\n"],"names":["useState","useData","useCallback","useEffect","tableSchemas"],"mappings":";;;;;AAIO,MAAM,eAAe,MAAM;AAChC,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAIA,cAAoC,EAAA;AAE5E,EAAM,MAAA,EAAE,YAAa,EAAA,GAAIC,gBAAQ,EAAA;AAEjC,EAAM,MAAA,WAAA,GAAcC,iBAAY,CAAA,CAAC,OAA2B,KAAA;AAC1D,IAAM,MAAA,SAAA,uBAAgB,GAAyB,EAAA;AAC/C,IAAQ,OAAA,CAAA,OAAA,CAAQ,CAAC,MAAW,KAAA;AAC1B,MAAA,MAAM,EAAE,MAAA,EAAQ,KAAM,EAAA,GAAI,MAAO,CAAA,KAAA;AACjC,MAAA,SAAA,CAAU,IAAI,CAAG,EAAA,MAAM,CAAI,CAAA,EAAA,KAAK,IAAI,MAAM,CAAA;AAAA,KAC3C,CAAA;AACD,IAAO,OAAA,SAAA;AAAA,GACT,EAAG,EAAE,CAAA;AAEL,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,eAAe,kBAAqB,GAAA;AAClC,MAAI,IAAA;AACF,QAAM,MAAA,MAAA,GAAS,MAAM,YAAa,EAAA;AAClC,QAAA,MAAM,EAAE,MAAA,EAAW,GAAA,MAAM,OAAO,YAAa,EAAA;AAC7C,QAAMC,MAAAA,aAAAA,GAAe,MAAM,OAAQ,CAAA,GAAA;AAAA,UACjC,OAAO,GAAI,CAAA,CAAC,aAAa,MAAO,CAAA,cAAA,CAAe,QAAQ,CAAC;AAAA,SAC1D;AACA,QAAA,eAAA,CAAgBA,aAAY,CAAA;AAAA,eACrB,GAAK,EAAA;AACZ,QAAQ,OAAA,CAAA,IAAA;AAAA,UACN,CAAA,4CAAA,EAA+C,MAAO,CAAA,GAAG,CAAC,CAAA;AAAA,SAC5D;AAAA;AACF;AAGF,IAAmB,kBAAA,EAAA;AAAA,GAClB,EAAA,CAAC,WAAa,EAAA,YAAY,CAAC,CAAA;AAE9B,EAAO,OAAA,YAAA;AACT;;;;"}
@@ -1,6 +0,0 @@
1
- 'use strict';
2
-
3
- var sessionEditingFormCss = ".vuuSessionEditingForm {\n display: flex;\n flex-direction: column;\n gap: 3px;\n min-width: 400px;\n}\n\n.vuuSessionEditingForm-content {\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n gap: 3px;\n overflow: auto;\n padding: var(--salt-spacing-200);\n}\n\n\n.vuuSessionEditingForm-fieldValue.vuuReadOnly {\n font-weight: var(--salt-text-label-fontWeight-strong);\n}\n\n.vuuSessionEditingForm-buttonbar {\n align-items: center;\n border-top: solid 1px var(--salt-container-primary-borderColor);\n box-sizing: content-box;\n display: flex;\n justify-content: flex-end;\n flex: 0 0 autox;\n gap: 6px;\n height: var(--salt-size-base);\n margin: var(--salt-spacing-200);\n padding-top: var(--salt-spacing-200);\n\n}\n\n.vuuSessionEditingForm-errorBanner {\n --vuu-icon-left: 3px;\n --vuu-icon-size: 18px;\n --vuu-icon-top: 3px;\n border: solid 1px var(--salt-status-error-borderColor);\n line-height: 24px;\n padding: 0 6px 0 26px;\n position: relative;\n}";
4
-
5
- module.exports = sessionEditingFormCss;
6
- //# sourceMappingURL=SessionEditingForm.css.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SessionEditingForm.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
@@ -1,269 +0,0 @@
1
- 'use strict';
2
-
3
- var jsxRuntime = require('react/jsx-runtime');
4
- var vuuDataRemote = require('@vuu-ui/vuu-data-remote');
5
- var vuuUtils = require('@vuu-ui/vuu-utils');
6
- var core = require('@salt-ds/core');
7
- var styles = require('@salt-ds/styles');
8
- var window = require('@salt-ds/window');
9
- var cx = require('clsx');
10
- var react = require('react');
11
- var SessionEditingForm$1 = require('./SessionEditingForm.css.js');
12
-
13
- const classBase = "vuuSessionEditingForm";
14
- const getField = (fields, name) => {
15
- const field = fields.find((f) => f.name === name);
16
- if (field) {
17
- return field;
18
- } else {
19
- throw Error(`SessionEditingForm, no field '${name}' found`);
20
- }
21
- };
22
- const getFieldNameAndValue = ({
23
- target
24
- }) => {
25
- const formField = vuuUtils.queryClosest(target, ".saltFormField");
26
- if (formField) {
27
- const {
28
- dataset: { field }
29
- } = formField;
30
- if (field === void 0) {
31
- throw Error("SessionEditingForm, form field has no field data attribute");
32
- }
33
- return [field, target.value];
34
- } else {
35
- throw Error("Form control is not enclosed in FormField");
36
- }
37
- };
38
- const Status = {
39
- uninitialised: 0,
40
- unchanged: 1,
41
- changed: 2,
42
- invalid: 3
43
- };
44
- const getDataSource = (dataSource, schema) => {
45
- if (dataSource) {
46
- return dataSource;
47
- } else if (schema) {
48
- return new vuuDataRemote.VuuDataSource({
49
- bufferSize: 0,
50
- table: schema.table,
51
- columns: schema.columns.map((col) => col.name)
52
- });
53
- } else {
54
- throw Error(
55
- "SessionEditingForm: either a DataSource or a TableSchema must be provided"
56
- );
57
- }
58
- };
59
- const SessionEditingForm = ({
60
- className,
61
- config: { fields, key: keyField },
62
- dataSource: dataSourceProp,
63
- id: idProp,
64
- onClose,
65
- schema,
66
- ...htmlAttributes
67
- }) => {
68
- const targetWindow = window.useWindow();
69
- styles.useComponentCssInjection({
70
- testId: "vuu-session-editing-form",
71
- css: SessionEditingForm$1,
72
- window: targetWindow
73
- });
74
- const [fieldStatusValues, setFieldStatusValues] = react.useState({});
75
- const [values, setValues] = react.useState();
76
- const [errorMessage, setErrorMessage] = react.useState("");
77
- const formContentRef = react.useRef(null);
78
- const initialDataRef = react.useRef(void 0);
79
- const dataStatusRef = react.useRef(Status.uninitialised);
80
- const dataSource = react.useMemo(() => {
81
- const ds = getDataSource(dataSourceProp, schema);
82
- const { columns } = ds;
83
- const columnMap = vuuUtils.buildColumnMap(ds.columns);
84
- const applyServerData = (data) => {
85
- if (columnMap) {
86
- const values2 = {};
87
- for (const column of columns) {
88
- values2[column] = data[columnMap[column]];
89
- }
90
- if (dataStatusRef.current === Status.uninitialised) {
91
- dataStatusRef.current = Status.unchanged;
92
- initialDataRef.current = values2;
93
- }
94
- setValues(values2);
95
- }
96
- };
97
- ds.subscribe({ range: vuuUtils.Range(0, 5) }, (message) => {
98
- if (message.type === "viewport-update" && message.rows) {
99
- if (dataStatusRef.current === Status.uninitialised) {
100
- applyServerData(message.rows[0]);
101
- } else {
102
- console.log("what do we do with server updates");
103
- }
104
- }
105
- });
106
- return ds;
107
- }, [dataSourceProp, schema]);
108
- const id = core.useIdMemo(idProp);
109
- const handleChange = react.useCallback(
110
- (evt) => {
111
- const [field, value] = getFieldNameAndValue(evt);
112
- const { type } = getField(fields, field);
113
- const typedValue = vuuUtils.getTypedValue(value, type);
114
- setValues((values2 = {}) => {
115
- const newValues = {
116
- ...values2,
117
- [field]: typedValue
118
- };
119
- const notUpdated = vuuUtils.shallowEquals(newValues, initialDataRef.current);
120
- dataStatusRef.current = notUpdated ? Status.unchanged : typedValue !== void 0 ? Status.changed : Status.invalid;
121
- return newValues;
122
- });
123
- },
124
- [fields]
125
- );
126
- const handleBlur = react.useCallback(
127
- (evt) => {
128
- const [field, value] = getFieldNameAndValue(evt);
129
- const rowKey = values?.[keyField];
130
- const { type } = getField(fields, field);
131
- const typedValue = vuuUtils.getTypedValue(value, type, true);
132
- if (typeof rowKey === "string") {
133
- dataSource.menuRpcCall(vuuUtils.vuuEditCellRequest(rowKey, field, typedValue)).then((response) => {
134
- if (vuuUtils.isErrorResponse(response)) {
135
- console.log(`edit rejected ${response.error}`);
136
- setFieldStatusValues((map) => ({
137
- ...map,
138
- [field]: response.error
139
- }));
140
- } else {
141
- setFieldStatusValues((map) => ({
142
- ...map,
143
- [field]: void 0
144
- }));
145
- }
146
- });
147
- }
148
- },
149
- [dataSource, fields, keyField, values]
150
- );
151
- const applyAction = react.useCallback(
152
- (action) => {
153
- if (action.type === "CLOSE_DIALOG_ACTION") {
154
- onClose?.();
155
- }
156
- },
157
- [onClose]
158
- );
159
- const handleSubmit = react.useCallback(async () => {
160
- const rpcResponse = await dataSource.menuRpcCall({
161
- type: "VP_EDIT_SUBMIT_FORM_RPC"
162
- });
163
- if (vuuUtils.isErrorResponse(rpcResponse)) {
164
- setErrorMessage(rpcResponse.error);
165
- } else if (vuuUtils.isActionMessage(rpcResponse)) {
166
- applyAction(rpcResponse.action);
167
- }
168
- }, [applyAction, dataSource]);
169
- const handleKeyDown = react.useCallback(
170
- (evt) => {
171
- if (evt.key === "Enter" && dataStatusRef.current === Status.changed) {
172
- handleSubmit();
173
- }
174
- },
175
- [handleSubmit]
176
- );
177
- const handleCancel = react.useCallback(() => {
178
- onClose?.();
179
- }, [onClose]);
180
- const getFormControl = (field) => {
181
- const value = String(values?.[field.name] ?? "");
182
- if (field.readonly || field.name === keyField) {
183
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${classBase}-fieldValue vuuReadOnly`, children: value });
184
- } else {
185
- return /* @__PURE__ */ jsxRuntime.jsx(
186
- core.Input,
187
- {
188
- className: `${classBase}-fieldValue`,
189
- onBlur: handleBlur,
190
- onChange: handleChange,
191
- value,
192
- id: `${id}-input-${field.name}`
193
- }
194
- );
195
- }
196
- };
197
- react.useEffect(() => {
198
- if (formContentRef.current) {
199
- const firstInput = formContentRef.current.querySelector(
200
- "input"
201
- );
202
- if (firstInput) {
203
- setTimeout(() => {
204
- firstInput.focus();
205
- firstInput.select();
206
- }, 100);
207
- }
208
- }
209
- }, []);
210
- react.useEffect(() => {
211
- return () => {
212
- if (dataSource) {
213
- dataSource.unsubscribe();
214
- }
215
- };
216
- }, [dataSource]);
217
- const isDirty = dataStatusRef.current === Status.changed;
218
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ...htmlAttributes, className: cx(classBase, className), children: [
219
- errorMessage ? /* @__PURE__ */ jsxRuntime.jsx(
220
- "div",
221
- {
222
- className: `${classBase}-errorBanner`,
223
- "data-icon": "error",
224
- title: errorMessage,
225
- children: "Error, edit(s) not saved"
226
- }
227
- ) : void 0,
228
- /* @__PURE__ */ jsxRuntime.jsx(
229
- "div",
230
- {
231
- className: `${classBase}-content`,
232
- ref: formContentRef,
233
- onKeyDown: handleKeyDown,
234
- children: fields.map((field) => /* @__PURE__ */ jsxRuntime.jsxs(
235
- core.FormField,
236
- {
237
- className: `${classBase}-field`,
238
- "data-field": field.name,
239
- necessity: field.required ? "required" : "optional",
240
- readOnly: field.readonly,
241
- validationStatus: fieldStatusValues[field.name] ? "error" : void 0,
242
- children: [
243
- /* @__PURE__ */ jsxRuntime.jsx(core.FormFieldLabel, { children: field?.label ?? field.description }),
244
- getFormControl(field),
245
- /* @__PURE__ */ jsxRuntime.jsx(core.FormFieldHelperText, { children: fieldStatusValues[field.name] ?? "" })
246
- ]
247
- },
248
- field.name
249
- ))
250
- }
251
- ),
252
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${classBase}-buttonbar salt-theme salt-density-high`, children: [
253
- /* @__PURE__ */ jsxRuntime.jsx(
254
- core.Button,
255
- {
256
- type: "submit",
257
- variant: "cta",
258
- disabled: !isDirty,
259
- onClick: handleSubmit,
260
- children: "Submit"
261
- }
262
- ),
263
- /* @__PURE__ */ jsxRuntime.jsx(core.Button, { variant: "secondary", onClick: handleCancel, children: "Cancel" })
264
- ] })
265
- ] });
266
- };
267
-
268
- exports.SessionEditingForm = SessionEditingForm;
269
- //# sourceMappingURL=SessionEditingForm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SessionEditingForm.js","sources":["../../src/session-editing-form/SessionEditingForm.tsx"],"sourcesContent":["import { VuuDataSource } from \"@vuu-ui/vuu-data-remote\";\nimport { DataSource, TableSchema } from \"@vuu-ui/vuu-data-types\";\nimport {\n VuuColumnDataType,\n VuuDataRow,\n VuuRowDataItemType,\n VuuRpcAction,\n} from \"@vuu-ui/vuu-protocol-types\";\nimport {\n buildColumnMap,\n getTypedValue,\n isActionMessage,\n isErrorResponse,\n queryClosest,\n Range,\n shallowEquals,\n vuuEditCellRequest,\n} from \"@vuu-ui/vuu-utils\";\nimport {\n Button,\n FormField,\n FormFieldHelperText,\n FormFieldLabel,\n Input,\n useIdMemo,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport {\n ChangeEvent,\n ChangeEventHandler,\n FocusEvent,\n FocusEventHandler,\n HTMLAttributes,\n KeyboardEventHandler,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport sessionEditingFormCss from \"./SessionEditingForm.css\";\n\nexport type FormFieldDescriptor = {\n isKeyField?: boolean;\n label?: string;\n name: string;\n type: VuuColumnDataType;\n description: string;\n readonly?: boolean;\n required?: boolean;\n};\n\nexport type FormConfig = {\n title: string;\n key: string;\n fields: FormFieldDescriptor[];\n};\n\nexport interface SessionEditingFormProps\n extends HTMLAttributes<HTMLDivElement> {\n config: FormConfig;\n onClose?: () => void;\n dataSource?: DataSource;\n schema?: TableSchema;\n}\n\nconst classBase = \"vuuSessionEditingForm\";\n\nconst getField = (\n fields: FormFieldDescriptor[],\n name: string,\n): FormFieldDescriptor => {\n const field = fields.find((f) => f.name === name);\n if (field) {\n return field;\n } else {\n throw Error(`SessionEditingForm, no field '${name}' found`);\n }\n};\n\nconst getFieldNameAndValue = ({\n target,\n}: ChangeEvent<HTMLInputElement> | FocusEvent<HTMLInputElement>): [\n string,\n string,\n] => {\n const formField = queryClosest(target, \".saltFormField\");\n if (formField) {\n const {\n dataset: { field },\n } = formField;\n if (field === undefined) {\n throw Error(\"SessionEditingForm, form field has no field data attribute\");\n }\n return [field, target.value];\n } else {\n throw Error(\"Form control is not enclosed in FormField\");\n }\n};\n\nconst Status = {\n uninitialised: 0,\n unchanged: 1,\n changed: 2,\n invalid: 3,\n};\n\nconst getDataSource = (\n dataSource?: DataSource,\n schema?: TableSchema,\n): DataSource => {\n if (dataSource) {\n return dataSource;\n } else if (schema) {\n return new VuuDataSource({\n bufferSize: 0,\n table: schema.table,\n columns: schema.columns.map((col) => col.name),\n }) as DataSource;\n } else {\n throw Error(\n \"SessionEditingForm: either a DataSource or a TableSchema must be provided\",\n );\n }\n};\n\ntype FormValues = { [key: string]: VuuRowDataItemType | undefined };\n\nexport const SessionEditingForm = ({\n className,\n config: { fields, key: keyField },\n dataSource: dataSourceProp,\n id: idProp,\n onClose,\n schema,\n ...htmlAttributes\n}: SessionEditingFormProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-session-editing-form\",\n css: sessionEditingFormCss,\n window: targetWindow,\n });\n\n const [fieldStatusValues, setFieldStatusValues] = useState<\n Record<string, string | undefined>\n >({});\n const [values, setValues] = useState<FormValues>();\n const [errorMessage, setErrorMessage] = useState(\"\");\n const formContentRef = useRef<HTMLDivElement>(null);\n const initialDataRef = useRef<FormValues>(undefined);\n const dataStatusRef = useRef(Status.uninitialised);\n\n const dataSource = useMemo(() => {\n const ds = getDataSource(dataSourceProp, schema);\n const { columns } = ds;\n const columnMap = buildColumnMap(ds.columns);\n\n const applyServerData = (data: VuuDataRow) => {\n if (columnMap) {\n const values: { [key: string]: VuuRowDataItemType } = {};\n for (const column of columns) {\n values[column] = data[columnMap[column]];\n }\n if (dataStatusRef.current === Status.uninitialised) {\n dataStatusRef.current = Status.unchanged;\n initialDataRef.current = values;\n }\n setValues(values);\n }\n };\n\n ds.subscribe({ range: Range(0, 5) }, (message) => {\n if (message.type === \"viewport-update\" && message.rows) {\n if (dataStatusRef.current === Status.uninitialised) {\n applyServerData(message.rows[0]);\n } else {\n console.log(\"what do we do with server updates\");\n }\n }\n });\n return ds;\n }, [dataSourceProp, schema]);\n\n const id = useIdMemo(idProp);\n\n const handleChange = useCallback<ChangeEventHandler<HTMLInputElement>>(\n (evt) => {\n const [field, value] = getFieldNameAndValue(evt);\n const { type } = getField(fields, field);\n const typedValue = getTypedValue(value, type);\n setValues((values = {}) => {\n const newValues = {\n ...values,\n [field]: typedValue,\n };\n const notUpdated = shallowEquals(newValues, initialDataRef.current);\n dataStatusRef.current = notUpdated\n ? Status.unchanged\n : typedValue !== undefined\n ? Status.changed\n : Status.invalid;\n return newValues;\n });\n },\n [fields],\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLInputElement>>(\n (evt) => {\n const [field, value] = getFieldNameAndValue(evt);\n const rowKey = values?.[keyField];\n // TODO link this with client side validation if we're going to use it\n const { type } = getField(fields, field);\n const typedValue = getTypedValue(value, type, true);\n if (typeof rowKey === \"string\") {\n dataSource\n .menuRpcCall(vuuEditCellRequest(rowKey, field, typedValue))\n .then((response) => {\n if (isErrorResponse(response)) {\n console.log(`edit rejected ${response.error}`);\n setFieldStatusValues((map) => ({\n ...map,\n [field]: response.error,\n }));\n } else {\n setFieldStatusValues((map) => ({\n ...map,\n [field]: undefined,\n }));\n }\n });\n }\n },\n [dataSource, fields, keyField, values],\n );\n\n const applyAction = useCallback(\n (action: VuuRpcAction) => {\n if (action.type === \"CLOSE_DIALOG_ACTION\") {\n onClose?.();\n }\n },\n [onClose],\n );\n\n const handleSubmit = useCallback(async () => {\n const rpcResponse = await dataSource.menuRpcCall({\n type: \"VP_EDIT_SUBMIT_FORM_RPC\",\n });\n if (isErrorResponse(rpcResponse)) {\n setErrorMessage(rpcResponse.error);\n } else if (isActionMessage(rpcResponse)) {\n applyAction(rpcResponse.action);\n }\n }, [applyAction, dataSource]);\n\n const handleKeyDown = useCallback<KeyboardEventHandler>(\n (evt) => {\n if (evt.key === \"Enter\" && dataStatusRef.current === Status.changed) {\n handleSubmit();\n }\n },\n [handleSubmit],\n );\n\n const handleCancel = useCallback(() => {\n onClose?.();\n }, [onClose]);\n\n const getFormControl = (field: FormFieldDescriptor) => {\n const value = String(values?.[field.name] ?? \"\");\n if (field.readonly || field.name === keyField) {\n return (\n <div className={`${classBase}-fieldValue vuuReadOnly`}>{value}</div>\n );\n } else {\n return (\n <Input\n className={`${classBase}-fieldValue`}\n onBlur={handleBlur}\n onChange={handleChange}\n value={value}\n id={`${id}-input-${field.name}`}\n />\n );\n }\n };\n\n useEffect(() => {\n if (formContentRef.current) {\n const firstInput = formContentRef.current.querySelector(\n \"input\",\n ) as HTMLInputElement;\n if (firstInput) {\n setTimeout(() => {\n firstInput.focus();\n firstInput.select();\n }, 100);\n }\n }\n }, []);\n\n useEffect(() => {\n return () => {\n if (dataSource) {\n dataSource.unsubscribe();\n }\n };\n }, [dataSource]);\n\n const isDirty = dataStatusRef.current === Status.changed;\n return (\n <div {...htmlAttributes} className={cx(classBase, className)}>\n {errorMessage ? (\n <div\n className={`${classBase}-errorBanner`}\n data-icon=\"error\"\n title={errorMessage}\n >\n Error, edit(s) not saved\n </div>\n ) : undefined}\n <div\n className={`${classBase}-content`}\n ref={formContentRef}\n onKeyDown={handleKeyDown}\n >\n {fields.map((field) => (\n <FormField\n className={`${classBase}-field`}\n data-field={field.name}\n key={field.name}\n necessity={field.required ? \"required\" : \"optional\"}\n readOnly={field.readonly}\n validationStatus={\n fieldStatusValues[field.name] ? \"error\" : undefined\n }\n >\n <FormFieldLabel>{field?.label ?? field.description}</FormFieldLabel>\n {getFormControl(field)}\n <FormFieldHelperText>\n {fieldStatusValues[field.name] ?? \"\"}\n </FormFieldHelperText>\n </FormField>\n ))}\n </div>\n <div className={`${classBase}-buttonbar salt-theme salt-density-high`}>\n <Button\n type=\"submit\"\n variant=\"cta\"\n disabled={!isDirty}\n onClick={handleSubmit}\n >\n Submit\n </Button>\n <Button variant=\"secondary\" onClick={handleCancel}>\n Cancel\n </Button>\n </div>\n </div>\n );\n};\n"],"names":["queryClosest","VuuDataSource","useWindow","useComponentCssInjection","sessionEditingFormCss","useState","useRef","useMemo","buildColumnMap","values","Range","useIdMemo","useCallback","getTypedValue","shallowEquals","vuuEditCellRequest","isErrorResponse","isActionMessage","jsx","Input","useEffect","jsxs","FormField","FormFieldLabel","FormFieldHelperText","Button"],"mappings":"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"}
@@ -1,4 +0,0 @@
1
- var editFormCss = ".EditForm {\n display: flex;\n flex-direction: column;\n gap: var(--salt-spacing-400);\n height: 100%;\n padding: var(--salt-spacing-200) var(--salt-spacing-200)\n var(--salt-spacing-200) var(--salt-spacing-400);\n width: 100%;\n}\n\n.EditForm-form-fields {\n display: flex;\n flex-direction: column;\n gap: var(--salt-spacing-400);\n}\n\n.EditForm-buttons {\n align-items: center;\n display: flex;\n gap: var(--salt-spacing-200);\n justify-content: flex-end;\n}\n\n.EditForm-field {\n display: flex;\n\n .saltFormField {\n flex: 1 1 auto;\n }\n\n .EditForm-edit-indicator {\n flex: 0 0 14px;\n position: relative;\n }\n\n &[data-edited=\"true\"] {\n .EditForm-edit-indicator:after {\n background-color: var(--salt-content-secondary-foreground);\n border-radius: 5px;\n content: \"\";\n height: 10px;\n position: absolute;\n top: 50%;\n right: -3px;\n width: 10px;\n }\n }\n}\n";
2
-
3
- export { editFormCss as default };
4
- //# sourceMappingURL=EditForm.css.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"EditForm.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -1,88 +0,0 @@
1
- import { jsxs, jsx } from 'react/jsx-runtime';
2
- import { FormField, FormFieldLabel, Button } from '@salt-ds/core';
3
- import { useComponentCssInjection } from '@salt-ds/styles';
4
- import { useWindow } from '@salt-ds/window';
5
- import cx from 'clsx';
6
- import { registerRules } from './edit-validation-rules.js';
7
- import { useEditForm } from './useEditForm.js';
8
- import editFormCss from './EditForm.css.js';
9
- import { getDataItemEditControl } from './get-data-item-edit-control.js';
10
-
11
- const classBase = "EditForm";
12
- registerRules();
13
- const EditForm = ({
14
- className,
15
- dataSource,
16
- formFieldDescriptors,
17
- onSubmit: onSubmitProp,
18
- ...htmlAttributes
19
- }) => {
20
- const targetWindow = useWindow();
21
- useComponentCssInjection({
22
- testId: "vuu-edit-form",
23
- css: editFormCss,
24
- window: targetWindow
25
- });
26
- const {
27
- editedFields,
28
- editEntity,
29
- errorMessages,
30
- formFieldsContainerRef,
31
- isClean,
32
- ok,
33
- onCancel,
34
- onChange,
35
- onCommit,
36
- onFocus,
37
- onSubmit
38
- } = useEditForm({
39
- dataSource,
40
- formFieldDescriptors,
41
- onSubmit: onSubmitProp
42
- });
43
- return /* @__PURE__ */ jsxs(
44
- "div",
45
- {
46
- ...htmlAttributes,
47
- className: cx(classBase, className),
48
- onFocus,
49
- children: [
50
- /* @__PURE__ */ jsx("div", { className: `${classBase}-form-fields`, ref: formFieldsContainerRef, children: formFieldDescriptors.map((dataDescriptor) => {
51
- const { name, label = name } = dataDescriptor;
52
- const errorMessage = errorMessages[name];
53
- const isEdited = !isClean && editedFields.includes(name);
54
- return /* @__PURE__ */ jsxs(
55
- "div",
56
- {
57
- className: `${classBase}-field`,
58
- "data-edited": isEdited,
59
- children: [
60
- /* @__PURE__ */ jsxs(FormField, { "data-field": name, children: [
61
- /* @__PURE__ */ jsx(FormFieldLabel, { children: label }),
62
- getDataItemEditControl({
63
- InputProps: {
64
- onChange,
65
- value: editEntity?.[name]?.toString() ?? ""
66
- },
67
- dataDescriptor,
68
- errorMessage,
69
- onCommit
70
- })
71
- ] }),
72
- /* @__PURE__ */ jsx("div", { className: `${classBase}-edit-indicator` })
73
- ]
74
- },
75
- name
76
- );
77
- }) }),
78
- /* @__PURE__ */ jsxs("div", { className: `${classBase}-buttons`, children: [
79
- /* @__PURE__ */ jsx(Button, { disabled: isClean, onClick: onCancel, children: "Cancel" }),
80
- /* @__PURE__ */ jsx(Button, { onClick: onSubmit, disabled: !ok || isClean, children: "Save" })
81
- ] })
82
- ]
83
- }
84
- );
85
- };
86
-
87
- export { EditForm };
88
- //# sourceMappingURL=EditForm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"EditForm.js","sources":["../../src/data-editing/EditForm.tsx"],"sourcesContent":["import { Button, FormField, FormFieldLabel } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport { HTMLAttributes } from \"react\";\nimport { registerRules } from \"./edit-validation-rules\";\nimport { EditFormHookProps, useEditForm } from \"./useEditForm\";\n\nimport editFormCss from \"./EditForm.css\";\nimport { getDataItemEditControl } from \"./get-data-item-edit-control\";\n\nconst classBase = \"EditForm\";\n\nregisterRules();\n\nexport interface EditFormProps\n extends EditFormHookProps,\n Omit<HTMLAttributes<HTMLDivElement>, \"onSubmit\"> {}\n\nexport const EditForm = ({\n className,\n dataSource,\n formFieldDescriptors,\n onSubmit: onSubmitProp,\n ...htmlAttributes\n}: EditFormProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-edit-form\",\n css: editFormCss,\n window: targetWindow,\n });\n\n const {\n editedFields,\n editEntity,\n errorMessages,\n formFieldsContainerRef,\n isClean,\n ok,\n onCancel,\n onChange,\n onCommit,\n onFocus,\n onSubmit,\n } = useEditForm({\n dataSource,\n formFieldDescriptors,\n onSubmit: onSubmitProp,\n });\n\n return (\n <div\n {...htmlAttributes}\n className={cx(classBase, className)}\n onFocus={onFocus}\n >\n <div className={`${classBase}-form-fields`} ref={formFieldsContainerRef}>\n {formFieldDescriptors.map((dataDescriptor) => {\n const { name, label = name } = dataDescriptor;\n const errorMessage = errorMessages[name];\n const isEdited = !isClean && editedFields.includes(name);\n\n return (\n <div\n className={`${classBase}-field`}\n key={name}\n data-edited={isEdited}\n >\n <FormField data-field={name}>\n <FormFieldLabel>{label}</FormFieldLabel>\n {getDataItemEditControl({\n InputProps: {\n onChange,\n value: editEntity?.[name]?.toString() ?? \"\",\n },\n dataDescriptor,\n errorMessage,\n onCommit,\n })}\n </FormField>\n <div className={`${classBase}-edit-indicator`} />\n </div>\n );\n })}\n </div>\n <div className={`${classBase}-buttons`}>\n <Button disabled={isClean} onClick={onCancel}>\n Cancel\n </Button>\n <Button onClick={onSubmit} disabled={!ok || isClean}>\n Save\n </Button>\n </div>\n </div>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;AAWA,MAAM,SAAY,GAAA,UAAA;AAElB,aAAc,EAAA;AAMP,MAAM,WAAW,CAAC;AAAA,EACvB,SAAA;AAAA,EACA,UAAA;AAAA,EACA,oBAAA;AAAA,EACA,QAAU,EAAA,YAAA;AAAA,EACV,GAAG;AACL,CAAqB,KAAA;AACnB,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,eAAA;AAAA,IACR,GAAK,EAAA,WAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAM,MAAA;AAAA,IACJ,YAAA;AAAA,IACA,UAAA;AAAA,IACA,aAAA;AAAA,IACA,sBAAA;AAAA,IACA,OAAA;AAAA,IACA,EAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,MACE,WAAY,CAAA;AAAA,IACd,UAAA;AAAA,IACA,oBAAA;AAAA,IACA,QAAU,EAAA;AAAA,GACX,CAAA;AAED,EACE,uBAAA,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACE,GAAG,cAAA;AAAA,MACJ,SAAA,EAAW,EAAG,CAAA,SAAA,EAAW,SAAS,CAAA;AAAA,MAClC,OAAA;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAC,GAAA,CAAA,KAAA,EAAA,EAAI,SAAW,EAAA,CAAA,EAAG,SAAS,CAAA,YAAA,CAAA,EAAgB,KAAK,sBAC9C,EAAA,QAAA,EAAA,oBAAA,CAAqB,GAAI,CAAA,CAAC,cAAmB,KAAA;AAC5C,UAAA,MAAM,EAAE,IAAA,EAAM,KAAQ,GAAA,IAAA,EAAS,GAAA,cAAA;AAC/B,UAAM,MAAA,YAAA,GAAe,cAAc,IAAI,CAAA;AACvC,UAAA,MAAM,QAAW,GAAA,CAAC,OAAW,IAAA,YAAA,CAAa,SAAS,IAAI,CAAA;AAEvD,UACE,uBAAA,IAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAW,GAAG,SAAS,CAAA,MAAA,CAAA;AAAA,cAEvB,aAAa,EAAA,QAAA;AAAA,cAEb,QAAA,EAAA;AAAA,gCAAC,IAAA,CAAA,SAAA,EAAA,EAAU,cAAY,IACrB,EAAA,QAAA,EAAA;AAAA,kCAAA,GAAA,CAAC,kBAAgB,QAAM,EAAA,KAAA,EAAA,CAAA;AAAA,kBACtB,sBAAuB,CAAA;AAAA,oBACtB,UAAY,EAAA;AAAA,sBACV,QAAA;AAAA,sBACA,KAAO,EAAA,UAAA,GAAa,IAAI,CAAA,EAAG,UAAc,IAAA;AAAA,qBAC3C;AAAA,oBACA,cAAA;AAAA,oBACA,YAAA;AAAA,oBACA;AAAA,mBACD;AAAA,iBACH,EAAA,CAAA;AAAA,gCACC,GAAA,CAAA,KAAA,EAAA,EAAI,SAAW,EAAA,CAAA,EAAG,SAAS,CAAmB,eAAA,CAAA,EAAA;AAAA;AAAA,aAAA;AAAA,YAf1C;AAAA,WAgBP;AAAA,SAEH,CACH,EAAA,CAAA;AAAA,wBACC,IAAA,CAAA,KAAA,EAAA,EAAI,SAAW,EAAA,CAAA,EAAG,SAAS,CAC1B,QAAA,CAAA,EAAA,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,MAAO,EAAA,EAAA,QAAA,EAAU,OAAS,EAAA,OAAA,EAAS,UAAU,QAE9C,EAAA,QAAA,EAAA,CAAA;AAAA,0BACA,GAAA,CAAC,UAAO,OAAS,EAAA,QAAA,EAAU,UAAU,CAAC,EAAA,IAAM,SAAS,QAErD,EAAA,MAAA,EAAA;AAAA,SACF,EAAA;AAAA;AAAA;AAAA,GACF;AAEJ;;;;"}
@@ -1,4 +0,0 @@
1
- var unsavedChangesCss = ".vuuUnsavedChanges-table {\n border-collapse: collapse;\n width: 100%;\n}\n\n.vuuUnsavedChanges-row {\n box-sizing: content-box;\n border-bottom: solid 1px var(--salt-separable-secondary-borderColor);\n height: 32px;\n\n td {\n padding: 0 var(--salt-spacing-200);\n }\n}\n\n.vuuUnsavedChanges-fieldName {\n text-transform: capitalize;\n}\n\n.vuuUnsavedChanges-new {\n font-weight: bold;\n}\n";
2
-
3
- export { unsavedChangesCss as default };
4
- //# sourceMappingURL=UnsavedChangesReport.css.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"UnsavedChangesReport.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -1,27 +0,0 @@
1
- import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { useComponentCssInjection } from '@salt-ds/styles';
3
- import { useWindow } from '@salt-ds/window';
4
- import { buildFormEditState } from './form-edit-state.js';
5
- import unsavedChangesCss from './UnsavedChangesReport.css.js';
6
-
7
- const classBase = "vuuUnsavedChanges";
8
- const UnsavedChangesReport = ({
9
- entity,
10
- editedEntity
11
- }) => {
12
- const targetWindow = useWindow();
13
- useComponentCssInjection({
14
- testId: "vuu-unsaved-changes-report",
15
- css: unsavedChangesCss,
16
- window: targetWindow
17
- });
18
- const { editedFields } = buildFormEditState(entity, editedEntity);
19
- return /* @__PURE__ */ jsx("div", { className: classBase, children: /* @__PURE__ */ jsx("table", { className: `${classBase}-table`, children: /* @__PURE__ */ jsx("tbody", { children: editedFields.map((fieldName, i) => /* @__PURE__ */ jsxs("tr", { className: `${classBase}-row`, children: [
20
- /* @__PURE__ */ jsx("td", { className: `${classBase}-fieldName`, children: fieldName }),
21
- /* @__PURE__ */ jsx("td", { className: `${classBase}-old`, children: entity[fieldName] }),
22
- /* @__PURE__ */ jsx("td", { className: `${classBase}-new`, children: editedEntity[fieldName] })
23
- ] }, i)) }) }) });
24
- };
25
-
26
- export { UnsavedChangesReport };
27
- //# sourceMappingURL=UnsavedChangesReport.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"UnsavedChangesReport.js","sources":["../../src/data-editing/UnsavedChangesReport.tsx"],"sourcesContent":["import { Entity } from \"@vuu-ui/vuu-utils\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { buildFormEditState } from \"./form-edit-state\";\n\nimport unsavedChangesCss from \"./UnsavedChangesReport.css\";\n\nconst classBase = \"vuuUnsavedChanges\";\n\nexport interface UnsavedChangesReportProps<T extends Entity = Entity> {\n entity: T;\n editedEntity: T;\n}\n\nexport const UnsavedChangesReport = ({\n entity,\n editedEntity,\n}: UnsavedChangesReportProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-unsaved-changes-report\",\n css: unsavedChangesCss,\n window: targetWindow,\n });\n\n const { editedFields } = buildFormEditState(entity, editedEntity);\n\n return (\n <div className={classBase}>\n <table className={`${classBase}-table`}>\n <tbody>\n {editedFields.map((fieldName, i) => (\n <tr className={`${classBase}-row`} key={i}>\n <td className={`${classBase}-fieldName`}>{fieldName}</td>\n <td className={`${classBase}-old`}>{entity[fieldName]}</td>\n <td className={`${classBase}-new`}>{editedEntity[fieldName]}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n};\n"],"names":[],"mappings":";;;;;;AAOA,MAAM,SAAY,GAAA,mBAAA;AAOX,MAAM,uBAAuB,CAAC;AAAA,EACnC,MAAA;AAAA,EACA;AACF,CAAiC,KAAA;AAC/B,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,4BAAA;AAAA,IACR,GAAK,EAAA,iBAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,MAAM,EAAE,YAAA,EAAiB,GAAA,kBAAA,CAAmB,QAAQ,YAAY,CAAA;AAEhE,EACE,uBAAA,GAAA,CAAC,SAAI,SAAW,EAAA,SAAA,EACd,8BAAC,OAAM,EAAA,EAAA,SAAA,EAAW,CAAG,EAAA,SAAS,CAC5B,MAAA,CAAA,EAAA,QAAA,kBAAA,GAAA,CAAC,WACE,QAAa,EAAA,YAAA,CAAA,GAAA,CAAI,CAAC,SAAW,EAAA,CAAA,0BAC3B,IAAG,EAAA,EAAA,SAAA,EAAW,CAAG,EAAA,SAAS,CACzB,IAAA,CAAA,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,IAAG,EAAA,EAAA,SAAA,EAAW,CAAG,EAAA,SAAS,cAAe,QAAU,EAAA,SAAA,EAAA,CAAA;AAAA,oBACpD,GAAA,CAAC,QAAG,SAAW,EAAA,CAAA,EAAG,SAAS,CAAS,IAAA,CAAA,EAAA,QAAA,EAAA,MAAA,CAAO,SAAS,CAAE,EAAA,CAAA;AAAA,oBACtD,GAAA,CAAC,QAAG,SAAW,EAAA,CAAA,EAAG,SAAS,CAAS,IAAA,CAAA,EAAA,QAAA,EAAA,YAAA,CAAa,SAAS,CAAE,EAAA;AAAA,GAAA,EAAA,EAHtB,CAIxC,CACD,CACH,EAAA,CAAA,EACF,CACF,EAAA,CAAA;AAEJ;;;;"}
@@ -1,37 +0,0 @@
1
- import { isTypeDescriptor, getEditRuleValidator } from '@vuu-ui/vuu-utils';
2
-
3
- const OK = { ok: true };
4
- const NO_VALIDATION_RULES = [];
5
- function getEditValidationRules(descriptor, editPhase) {
6
- if (isTypeDescriptor(descriptor.type)) {
7
- return editPhase === "*" ? descriptor.type.rules ?? [] : descriptor.type.rules?.filter(
8
- ({ phase: a = "commit" }) => a === editPhase
9
- ) ?? NO_VALIDATION_RULES;
10
- }
11
- return NO_VALIDATION_RULES;
12
- }
13
- const buildValidationChecker = (rules) => (value, editPhase) => applyRules(rules, value, editPhase);
14
- function applyRules(rules, value, editPhase = "commit") {
15
- const result = { ok: true };
16
- for (const rule of rules) {
17
- const { phase = "commit" } = rule;
18
- if (editPhase === "*" || phase === editPhase) {
19
- const applyRuleToValue = getEditRuleValidator(rule.name);
20
- if (applyRuleToValue) {
21
- const res = applyRuleToValue(rule, value);
22
- if (!res.ok) {
23
- result.ok = false;
24
- (result.messages ?? (result.messages = [])).push(res.message);
25
- }
26
- } else {
27
- throw Error(
28
- `editable-utils applyRules, no validator registered for rule '${rule.name}'`
29
- );
30
- }
31
- }
32
- }
33
- return result;
34
- }
35
-
36
- export { OK, buildValidationChecker, getEditValidationRules };
37
- //# sourceMappingURL=edit-rule-validation-checker.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"edit-rule-validation-checker.js","sources":["../../src/data-editing/edit-rule-validation-checker.ts"],"sourcesContent":["import type {\n DataValueDescriptor,\n DataValueValidationChecker,\n DataValueValidationResult,\n EditPhase,\n EditRuleValidationSuccessResult,\n EditValidationRule,\n} from \"@vuu-ui/vuu-data-types\";\nimport type { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { getEditRuleValidator, isTypeDescriptor } from \"@vuu-ui/vuu-utils\";\n\nexport const OK: EditRuleValidationSuccessResult = { ok: true };\n\nconst NO_VALIDATION_RULES: EditValidationRule[] = [] as const;\n\nexport function getEditValidationRules(\n descriptor: DataValueDescriptor,\n editPhase: EditPhase | \"*\",\n) {\n if (isTypeDescriptor(descriptor.type)) {\n return editPhase === \"*\"\n ? (descriptor.type.rules ?? [])\n : (descriptor.type.rules?.filter(\n ({ phase: a = \"commit\" }) => a === editPhase,\n ) ?? NO_VALIDATION_RULES);\n }\n\n return NO_VALIDATION_RULES;\n}\n\nexport const buildValidationChecker =\n (rules: EditValidationRule[]): DataValueValidationChecker =>\n (value: VuuRowDataItemType | undefined, editPhase: EditPhase | \"*\") =>\n applyRules(rules, value, editPhase);\n\nfunction applyRules(\n rules: EditValidationRule[],\n value?: VuuRowDataItemType,\n editPhase: EditPhase | \"*\" = \"commit\",\n) {\n const result: { ok: boolean; messages?: string[] } = { ok: true };\n for (const rule of rules) {\n const { phase = \"commit\" } = rule;\n if (editPhase === \"*\" || phase === editPhase) {\n const applyRuleToValue = getEditRuleValidator(rule.name);\n if (applyRuleToValue) {\n const res = applyRuleToValue(rule, value);\n if (!res.ok) {\n result.ok = false;\n (result.messages ?? (result.messages = [])).push(res.message);\n }\n } else {\n throw Error(\n `editable-utils applyRules, no validator registered for rule '${rule.name}'`,\n );\n }\n }\n }\n return result as DataValueValidationResult;\n}\n"],"names":[],"mappings":";;AAWa,MAAA,EAAA,GAAsC,EAAE,EAAA,EAAI,IAAK;AAE9D,MAAM,sBAA4C,EAAC;AAEnC,SAAA,sBAAA,CACd,YACA,SACA,EAAA;AACA,EAAI,IAAA,gBAAA,CAAiB,UAAW,CAAA,IAAI,CAAG,EAAA;AACrC,IAAO,OAAA,SAAA,KAAc,MAChB,UAAW,CAAA,IAAA,CAAK,SAAS,EAAC,GAC1B,UAAW,CAAA,IAAA,CAAK,KAAO,EAAA,MAAA;AAAA,MACtB,CAAC,EAAE,KAAA,EAAO,CAAI,GAAA,QAAA,OAAe,CAAM,KAAA;AAAA,KAChC,IAAA,mBAAA;AAAA;AAGX,EAAO,OAAA,mBAAA;AACT;AAEa,MAAA,sBAAA,GACX,CAAC,KACD,KAAA,CAAC,OAAuC,SACtC,KAAA,UAAA,CAAW,KAAO,EAAA,KAAA,EAAO,SAAS;AAEtC,SAAS,UACP,CAAA,KAAA,EACA,KACA,EAAA,SAAA,GAA6B,QAC7B,EAAA;AACA,EAAM,MAAA,MAAA,GAA+C,EAAE,EAAA,EAAI,IAAK,EAAA;AAChE,EAAA,KAAA,MAAW,QAAQ,KAAO,EAAA;AACxB,IAAM,MAAA,EAAE,KAAQ,GAAA,QAAA,EAAa,GAAA,IAAA;AAC7B,IAAI,IAAA,SAAA,KAAc,GAAO,IAAA,KAAA,KAAU,SAAW,EAAA;AAC5C,MAAM,MAAA,gBAAA,GAAmB,oBAAqB,CAAA,IAAA,CAAK,IAAI,CAAA;AACvD,MAAA,IAAI,gBAAkB,EAAA;AACpB,QAAM,MAAA,GAAA,GAAM,gBAAiB,CAAA,IAAA,EAAM,KAAK,CAAA;AACxC,QAAI,IAAA,CAAC,IAAI,EAAI,EAAA;AACX,UAAA,MAAA,CAAO,EAAK,GAAA,KAAA;AACZ,UAAC,CAAA,MAAA,CAAO,aAAa,MAAO,CAAA,QAAA,GAAW,EAAK,CAAA,EAAA,IAAA,CAAK,IAAI,OAAO,CAAA;AAAA;AAC9D,OACK,MAAA;AACL,QAAM,MAAA,KAAA;AAAA,UACJ,CAAA,6DAAA,EAAgE,KAAK,IAAI,CAAA,CAAA;AAAA,SAC3E;AAAA;AACF;AACF;AAEF,EAAO,OAAA,MAAA;AACT;;;;"}
@@ -1,50 +0,0 @@
1
- import { registerComponent } from '@vuu-ui/vuu-utils';
2
- import { OK } from './edit-rule-validation-checker.js';
3
-
4
- const isString = (value) => typeof value === "string";
5
- const NUMERIC = /^(?:[0-9]|\.)+$/;
6
- const CharValidatorNumeric = (rule, value) => {
7
- if (isString(value)) {
8
- if (value.trim() === "") {
9
- return OK;
10
- } else if (value.match(NUMERIC)) {
11
- return OK;
12
- }
13
- }
14
- return { ok: false, message: "only numeric characters are permitted" };
15
- };
16
- const ValueValidatorInteger = (rule, value) => {
17
- if (isString(value)) {
18
- if (value.trim() === "") {
19
- return OK;
20
- } else {
21
- if (!value.match(NUMERIC)) {
22
- return {
23
- ok: false,
24
- message: "value must be an integer, invalid character"
25
- };
26
- }
27
- if (parseFloat(value) === parseInt(value)) {
28
- return OK;
29
- }
30
- }
31
- }
32
- return { ok: false, message: "must be an integer value" };
33
- };
34
- const registerRules = () => {
35
- registerComponent(
36
- "char-numeric",
37
- CharValidatorNumeric,
38
- "data-edit-validator",
39
- {}
40
- );
41
- registerComponent(
42
- "value-integer",
43
- ValueValidatorInteger,
44
- "data-edit-validator",
45
- {}
46
- );
47
- };
48
-
49
- export { registerRules };
50
- //# sourceMappingURL=edit-validation-rules.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"edit-validation-rules.js","sources":["../../src/data-editing/edit-validation-rules.ts"],"sourcesContent":["import type { EditRuleValidator } from \"@vuu-ui/vuu-data-types\";\nimport type { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { registerComponent } from \"@vuu-ui/vuu-utils\";\nimport { OK } from \"./edit-rule-validation-checker\";\n\nconst isString = (value?: VuuRowDataItemType): value is string =>\n typeof value === \"string\";\n\nconst NUMERIC = /^(?:[0-9]|\\.)+$/;\n\nconst CharValidatorNumeric: EditRuleValidator = (rule, value) => {\n if (isString(value)) {\n if (value.trim() === \"\") {\n return OK;\n } else if (value.match(NUMERIC)) {\n return OK;\n }\n }\n return { ok: false, message: \"only numeric characters are permitted\" };\n};\n\nconst ValueValidatorInteger: EditRuleValidator = (rule, value) => {\n if (isString(value)) {\n if (value.trim() === \"\") {\n return OK;\n } else {\n if (!value.match(NUMERIC)) {\n return {\n ok: false,\n message: \"value must be an integer, invalid character\",\n };\n }\n if (parseFloat(value) === parseInt(value)) {\n return OK;\n }\n }\n }\n return { ok: false, message: \"must be an integer value\" };\n};\n\nexport const registerRules = () => {\n registerComponent(\n \"char-numeric\",\n CharValidatorNumeric,\n \"data-edit-validator\",\n {},\n );\n registerComponent(\n \"value-integer\",\n ValueValidatorInteger,\n \"data-edit-validator\",\n {},\n );\n};\n"],"names":[],"mappings":";;;AAKA,MAAM,QAAW,GAAA,CAAC,KAChB,KAAA,OAAO,KAAU,KAAA,QAAA;AAEnB,MAAM,OAAU,GAAA,iBAAA;AAEhB,MAAM,oBAAA,GAA0C,CAAC,IAAA,EAAM,KAAU,KAAA;AAC/D,EAAI,IAAA,QAAA,CAAS,KAAK,CAAG,EAAA;AACnB,IAAI,IAAA,KAAA,CAAM,IAAK,EAAA,KAAM,EAAI,EAAA;AACvB,MAAO,OAAA,EAAA;AAAA,KACE,MAAA,IAAA,KAAA,CAAM,KAAM,CAAA,OAAO,CAAG,EAAA;AAC/B,MAAO,OAAA,EAAA;AAAA;AACT;AAEF,EAAA,OAAO,EAAE,EAAA,EAAI,KAAO,EAAA,OAAA,EAAS,uCAAwC,EAAA;AACvE,CAAA;AAEA,MAAM,qBAAA,GAA2C,CAAC,IAAA,EAAM,KAAU,KAAA;AAChE,EAAI,IAAA,QAAA,CAAS,KAAK,CAAG,EAAA;AACnB,IAAI,IAAA,KAAA,CAAM,IAAK,EAAA,KAAM,EAAI,EAAA;AACvB,MAAO,OAAA,EAAA;AAAA,KACF,MAAA;AACL,MAAA,IAAI,CAAC,KAAA,CAAM,KAAM,CAAA,OAAO,CAAG,EAAA;AACzB,QAAO,OAAA;AAAA,UACL,EAAI,EAAA,KAAA;AAAA,UACJ,OAAS,EAAA;AAAA,SACX;AAAA;AAEF,MAAA,IAAI,UAAW,CAAA,KAAK,CAAM,KAAA,QAAA,CAAS,KAAK,CAAG,EAAA;AACzC,QAAO,OAAA,EAAA;AAAA;AACT;AACF;AAEF,EAAA,OAAO,EAAE,EAAA,EAAI,KAAO,EAAA,OAAA,EAAS,0BAA2B,EAAA;AAC1D,CAAA;AAEO,MAAM,gBAAgB,MAAM;AACjC,EAAA,iBAAA;AAAA,IACE,cAAA;AAAA,IACA,oBAAA;AAAA,IACA,qBAAA;AAAA,IACA;AAAC,GACH;AACA,EAAA,iBAAA;AAAA,IACE,eAAA;AAAA,IACA,qBAAA;AAAA,IACA,qBAAA;AAAA,IACA;AAAC,GACH;AACF;;;;"}
@@ -1,23 +0,0 @@
1
- const CLEAN_FORM = {
2
- isClean: true,
3
- editedFields: []
4
- };
5
- const buildFormEditState = (entity, newEntity) => {
6
- if (entity === void 0) {
7
- return CLEAN_FORM;
8
- } else {
9
- const editedFields = [];
10
- for (const [fieldName, value] of Object.entries(entity)) {
11
- if (value !== newEntity[fieldName]) {
12
- editedFields.push(fieldName);
13
- }
14
- }
15
- return {
16
- isClean: editedFields.length === 0,
17
- editedFields
18
- };
19
- }
20
- };
21
-
22
- export { CLEAN_FORM, buildFormEditState };
23
- //# sourceMappingURL=form-edit-state.js.map