@vuu-ui/vuu-data-react 0.8.91 → 0.8.93
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/cjs/data-editing/EditForm.css.js +6 -0
- package/cjs/data-editing/EditForm.css.js.map +1 -0
- package/cjs/data-editing/EditForm.js +97 -0
- package/cjs/data-editing/EditForm.js.map +1 -0
- package/cjs/data-editing/UnsavedChangesReport.css.js +6 -0
- package/cjs/data-editing/UnsavedChangesReport.css.js.map +1 -0
- package/cjs/data-editing/UnsavedChangesReport.js +29 -0
- package/cjs/data-editing/UnsavedChangesReport.js.map +1 -0
- package/cjs/data-editing/edit-rule-validation-checker.js +36 -0
- package/cjs/data-editing/edit-rule-validation-checker.js.map +1 -0
- package/cjs/data-editing/edit-validation-rules.js +52 -0
- package/cjs/data-editing/edit-validation-rules.js.map +1 -0
- package/cjs/data-editing/form-edit-state.js +26 -0
- package/cjs/data-editing/form-edit-state.js.map +1 -0
- package/cjs/data-editing/get-data-item-edit-control.js +54 -0
- package/cjs/data-editing/get-data-item-edit-control.js.map +1 -0
- package/cjs/data-editing/useEditForm.js +244 -0
- package/cjs/data-editing/useEditForm.js.map +1 -0
- package/cjs/hooks/useVuuMenuActions.js +1 -1
- package/cjs/hooks/useVuuMenuActions.js.map +1 -1
- package/cjs/index.js +10 -2
- package/cjs/index.js.map +1 -1
- package/esm/data-editing/EditForm.css.js +4 -0
- package/esm/data-editing/EditForm.css.js.map +1 -0
- package/esm/data-editing/EditForm.js +95 -0
- package/esm/data-editing/EditForm.js.map +1 -0
- package/esm/data-editing/UnsavedChangesReport.css.js +4 -0
- package/esm/data-editing/UnsavedChangesReport.css.js.map +1 -0
- package/esm/data-editing/UnsavedChangesReport.js +27 -0
- package/esm/data-editing/UnsavedChangesReport.js.map +1 -0
- package/esm/data-editing/edit-rule-validation-checker.js +32 -0
- package/esm/data-editing/edit-rule-validation-checker.js.map +1 -0
- package/esm/data-editing/edit-validation-rules.js +50 -0
- package/esm/data-editing/edit-validation-rules.js.map +1 -0
- package/esm/data-editing/form-edit-state.js +23 -0
- package/esm/data-editing/form-edit-state.js.map +1 -0
- package/esm/data-editing/get-data-item-edit-control.js +52 -0
- package/esm/data-editing/get-data-item-edit-control.js.map +1 -0
- package/esm/data-editing/useEditForm.js +242 -0
- package/esm/data-editing/useEditForm.js.map +1 -0
- package/esm/hooks/useVuuMenuActions.js +1 -1
- package/esm/hooks/useVuuMenuActions.js.map +1 -1
- package/esm/index.js +4 -1
- package/esm/index.js.map +1 -1
- package/package.json +13 -13
- package/types/data-editing/EditForm.d.ts +8 -0
- package/types/data-editing/UnsavedChangesReport.d.ts +7 -0
- package/types/data-editing/edit-rule-validation-checker.d.ts +4 -0
- package/types/data-editing/edit-validation-rules.d.ts +1 -0
- package/types/data-editing/form-edit-state.d.ts +7 -0
- package/types/data-editing/get-data-item-edit-control.d.ts +17 -0
- package/types/data-editing/index.d.ts +4 -1
- package/types/data-editing/useEditForm.d.ts +17 -0
- package/cjs/data-editing/date-editing-utils.js +0 -31
- package/cjs/data-editing/date-editing-utils.js.map +0 -1
- package/esm/data-editing/date-editing-utils.js +0 -29
- package/esm/data-editing/date-editing-utils.js.map +0 -1
- package/types/data-editing/date-editing-utils.d.ts +0 -13
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
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";
|
|
4
|
+
|
|
5
|
+
module.exports = editFormCss;
|
|
6
|
+
//# sourceMappingURL=EditForm.css.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditForm.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var getDataItemEditControl = require('./get-data-item-edit-control.js');
|
|
5
|
+
require('@vuu-ui/vuu-utils');
|
|
6
|
+
var styles = require('@salt-ds/styles');
|
|
7
|
+
var window = require('@salt-ds/window');
|
|
8
|
+
require('@vuu-ui/vuu-data-remote');
|
|
9
|
+
require('react');
|
|
10
|
+
require('@vuu-ui/vuu-popups');
|
|
11
|
+
require('@vuu-ui/vuu-table');
|
|
12
|
+
var core = require('@salt-ds/core');
|
|
13
|
+
var cx = require('clsx');
|
|
14
|
+
require('@vuu-ui/vuu-layout');
|
|
15
|
+
require('@vuu-ui/vuu-ui-controls');
|
|
16
|
+
var editValidationRules = require('./edit-validation-rules.js');
|
|
17
|
+
var useEditForm = require('./useEditForm.js');
|
|
18
|
+
var EditForm$1 = require('./EditForm.css.js');
|
|
19
|
+
|
|
20
|
+
const classBase = "EditForm";
|
|
21
|
+
editValidationRules.registerRules();
|
|
22
|
+
const EditForm = ({
|
|
23
|
+
className,
|
|
24
|
+
dataSource,
|
|
25
|
+
formFieldDescriptors,
|
|
26
|
+
onSubmit: onSubmitProp,
|
|
27
|
+
...htmlAttributes
|
|
28
|
+
}) => {
|
|
29
|
+
const targetWindow = window.useWindow();
|
|
30
|
+
styles.useComponentCssInjection({
|
|
31
|
+
testId: "vuu-edit-form",
|
|
32
|
+
css: EditForm$1,
|
|
33
|
+
window: targetWindow
|
|
34
|
+
});
|
|
35
|
+
const {
|
|
36
|
+
editedFields,
|
|
37
|
+
editEntity,
|
|
38
|
+
errorMessages,
|
|
39
|
+
formFieldsContainerRef,
|
|
40
|
+
isClean,
|
|
41
|
+
ok,
|
|
42
|
+
onCancel,
|
|
43
|
+
onChange,
|
|
44
|
+
onCommit,
|
|
45
|
+
onFocus,
|
|
46
|
+
onSubmit
|
|
47
|
+
} = useEditForm.useEditForm({
|
|
48
|
+
dataSource,
|
|
49
|
+
formFieldDescriptors,
|
|
50
|
+
onSubmit: onSubmitProp
|
|
51
|
+
});
|
|
52
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
53
|
+
"div",
|
|
54
|
+
{
|
|
55
|
+
...htmlAttributes,
|
|
56
|
+
className: cx(classBase, className),
|
|
57
|
+
onFocus,
|
|
58
|
+
children: [
|
|
59
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `${classBase}-form-fields`, ref: formFieldsContainerRef, children: formFieldDescriptors.map((dataDescriptor) => {
|
|
60
|
+
const { name, label = name } = dataDescriptor;
|
|
61
|
+
const errorMessage = errorMessages[name];
|
|
62
|
+
const isEdited = !isClean && editedFields.includes(name);
|
|
63
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
64
|
+
"div",
|
|
65
|
+
{
|
|
66
|
+
className: `${classBase}-field`,
|
|
67
|
+
"data-edited": isEdited,
|
|
68
|
+
children: [
|
|
69
|
+
/* @__PURE__ */ jsxRuntime.jsxs(core.FormField, { "data-field": name, children: [
|
|
70
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.FormFieldLabel, { children: label }),
|
|
71
|
+
getDataItemEditControl.getDataItemEditControl({
|
|
72
|
+
InputProps: {
|
|
73
|
+
onChange,
|
|
74
|
+
value: editEntity?.[name]?.toString() ?? ""
|
|
75
|
+
},
|
|
76
|
+
dataDescriptor,
|
|
77
|
+
errorMessage,
|
|
78
|
+
onCommit
|
|
79
|
+
})
|
|
80
|
+
] }),
|
|
81
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `${classBase}-edit-indicator` })
|
|
82
|
+
]
|
|
83
|
+
},
|
|
84
|
+
name
|
|
85
|
+
);
|
|
86
|
+
}) }),
|
|
87
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${classBase}-buttons`, children: [
|
|
88
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Button, { disabled: isClean, onClick: onCancel, children: "Cancel" }),
|
|
89
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Button, { onClick: onSubmit, disabled: !ok || isClean, children: "Save" })
|
|
90
|
+
] })
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
exports.EditForm = EditForm;
|
|
97
|
+
//# sourceMappingURL=EditForm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditForm.js","sources":["../../src/data-editing/EditForm.tsx"],"sourcesContent":["import { getDataItemEditControl } from \"@vuu-ui/vuu-data-react\";\nimport { DataSource, DataValueDescriptor } from \"@vuu-ui/vuu-data-types\";\nimport { 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 { useEditForm } from \"./useEditForm\";\n\nimport editFormCss from \"./EditForm.css\";\n\nconst classBase = \"EditForm\";\n\nregisterRules();\n\nexport interface EditFormProps extends HTMLAttributes<HTMLDivElement> {\n dataSource?: DataSource;\n formFieldDescriptors: DataValueDescriptor[];\n onSubmit?: () => void;\n}\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":["registerRules","useWindow","useComponentCssInjection","editFormCss","useEditForm","jsxs","jsx","FormField","FormFieldLabel","getDataItemEditControl","Button"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
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";
|
|
4
|
+
|
|
5
|
+
module.exports = unsavedChangesCss;
|
|
6
|
+
//# sourceMappingURL=UnsavedChangesReport.css.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UnsavedChangesReport.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var styles = require('@salt-ds/styles');
|
|
5
|
+
var window = require('@salt-ds/window');
|
|
6
|
+
var formEditState = require('./form-edit-state.js');
|
|
7
|
+
var UnsavedChangesReport$1 = require('./UnsavedChangesReport.css.js');
|
|
8
|
+
|
|
9
|
+
const classBase = "vuuUnsavedChanges";
|
|
10
|
+
const UnsavedChangesReport = ({
|
|
11
|
+
entity,
|
|
12
|
+
editedEntity
|
|
13
|
+
}) => {
|
|
14
|
+
const targetWindow = window.useWindow();
|
|
15
|
+
styles.useComponentCssInjection({
|
|
16
|
+
testId: "vuu-unsaved-changes-report",
|
|
17
|
+
css: UnsavedChangesReport$1,
|
|
18
|
+
window: targetWindow
|
|
19
|
+
});
|
|
20
|
+
const { editedFields } = formEditState.buildFormEditState(entity, editedEntity);
|
|
21
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: classBase, children: /* @__PURE__ */ jsxRuntime.jsx("table", { className: `${classBase}-table`, children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: editedFields.map((fieldName, i) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: `${classBase}-row`, children: [
|
|
22
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: `${classBase}-fieldName`, children: fieldName }),
|
|
23
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: `${classBase}-old`, children: entity[fieldName] }),
|
|
24
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: `${classBase}-new`, children: editedEntity[fieldName] })
|
|
25
|
+
] }, i)) }) }) });
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
exports.UnsavedChangesReport = UnsavedChangesReport;
|
|
29
|
+
//# sourceMappingURL=UnsavedChangesReport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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":["useWindow","useComponentCssInjection","unsavedChangesCss","buildFormEditState","jsx"],"mappings":";;;;;;;;AAOA,MAAM,SAAY,GAAA,mBAAA,CAAA;AAOX,MAAM,uBAAuB,CAAC;AAAA,EACnC,MAAA;AAAA,EACA,YAAA;AACF,CAAiC,KAAA;AAC/B,EAAA,MAAM,eAAeA,gBAAU,EAAA,CAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,4BAAA;AAAA,IACR,GAAK,EAAAC,sBAAA;AAAA,IACL,MAAQ,EAAA,YAAA;AAAA,GACT,CAAA,CAAA;AAED,EAAA,MAAM,EAAE,YAAA,EAAiB,GAAAC,gCAAA,CAAmB,QAAQ,YAAY,CAAA,CAAA;AAEhE,EACE,uBAAAC,cAAA,CAAC,SAAI,SAAW,EAAA,SAAA,EACd,yCAAC,OAAM,EAAA,EAAA,SAAA,EAAW,CAAG,EAAA,SAAS,CAC5B,MAAA,CAAA,EAAA,QAAA,kBAAAA,cAAA,CAAC,WACE,QAAa,EAAA,YAAA,CAAA,GAAA,CAAI,CAAC,SAAW,EAAA,CAAA,qCAC3B,IAAG,EAAA,EAAA,SAAA,EAAW,CAAG,EAAA,SAAS,CACzB,IAAA,CAAA,EAAA,QAAA,EAAA;AAAA,oBAAAA,cAAA,CAAC,IAAG,EAAA,EAAA,SAAA,EAAW,CAAG,EAAA,SAAS,cAAe,QAAU,EAAA,SAAA,EAAA,CAAA;AAAA,oBACpDA,cAAA,CAAC,QAAG,SAAW,EAAA,CAAA,EAAG,SAAS,CAAS,IAAA,CAAA,EAAA,QAAA,EAAA,MAAA,CAAO,SAAS,CAAE,EAAA,CAAA;AAAA,oBACtDA,cAAA,CAAC,QAAG,SAAW,EAAA,CAAA,EAAG,SAAS,CAAS,IAAA,CAAA,EAAA,QAAA,EAAA,YAAA,CAAa,SAAS,CAAE,EAAA,CAAA;AAAA,GAAA,EAAA,EAHtB,CAIxC,CACD,CACH,EAAA,CAAA,EACF,CACF,EAAA,CAAA,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var vuuUtils = require('@vuu-ui/vuu-utils');
|
|
4
|
+
|
|
5
|
+
const OK = { ok: true };
|
|
6
|
+
const NO_VALIDATION_RULES = [];
|
|
7
|
+
function getEditValidationRules(descriptor, apply) {
|
|
8
|
+
if (vuuUtils.isTypeDescriptor(descriptor.type)) {
|
|
9
|
+
return descriptor.type.rules?.filter(({ apply: a = "commit" }) => a === apply) ?? NO_VALIDATION_RULES;
|
|
10
|
+
}
|
|
11
|
+
return NO_VALIDATION_RULES;
|
|
12
|
+
}
|
|
13
|
+
const buildValidationChecker = (rules) => (value) => applyRules(rules, value);
|
|
14
|
+
function applyRules(rules, value) {
|
|
15
|
+
const result = { ok: true };
|
|
16
|
+
for (const rule of rules) {
|
|
17
|
+
const applyRuleToValue = vuuUtils.getEditRuleValidator(rule.name);
|
|
18
|
+
if (applyRuleToValue) {
|
|
19
|
+
const res = applyRuleToValue(rule, value);
|
|
20
|
+
if (!res.ok) {
|
|
21
|
+
result.ok = false;
|
|
22
|
+
(result.messages ?? (result.messages = [])).push(res.message);
|
|
23
|
+
}
|
|
24
|
+
} else {
|
|
25
|
+
throw Error(
|
|
26
|
+
`editable-utils applyRules, no validator registered for rule '${rule.name}'`
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
exports.OK = OK;
|
|
34
|
+
exports.buildValidationChecker = buildValidationChecker;
|
|
35
|
+
exports.getEditValidationRules = getEditValidationRules;
|
|
36
|
+
//# sourceMappingURL=edit-rule-validation-checker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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 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 apply: \"change\" | \"commit\",\n) {\n if (isTypeDescriptor(descriptor.type)) {\n return (\n descriptor.type.rules?.filter(({ apply: a = \"commit\" }) => a === apply) ??\n NO_VALIDATION_RULES\n );\n }\n\n return NO_VALIDATION_RULES;\n}\n\nexport const buildValidationChecker =\n (rules: EditValidationRule[]): DataValueValidationChecker =>\n (value?: VuuRowDataItemType) =>\n applyRules(rules, value);\n\nfunction applyRules(rules: EditValidationRule[], value?: VuuRowDataItemType) {\n const result: { ok: boolean; messages?: string[] } = { ok: true };\n for (const rule of rules) {\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 return result as DataValueValidationResult;\n}\n"],"names":["isTypeDescriptor","getEditRuleValidator"],"mappings":";;;;AAUa,MAAA,EAAA,GAAsC,EAAE,EAAA,EAAI,IAAK,GAAA;AAE9D,MAAM,sBAA4C,EAAC,CAAA;AAEnC,SAAA,sBAAA,CACd,YACA,KACA,EAAA;AACA,EAAI,IAAAA,yBAAA,CAAiB,UAAW,CAAA,IAAI,CAAG,EAAA;AACrC,IAAA,OACE,UAAW,CAAA,IAAA,CAAK,KAAO,EAAA,MAAA,CAAO,CAAC,EAAE,KAAO,EAAA,CAAA,GAAI,QAAS,EAAA,KAAM,CAAM,KAAA,KAAK,CACtE,IAAA,mBAAA,CAAA;AAAA,GAEJ;AAEA,EAAO,OAAA,mBAAA,CAAA;AACT,CAAA;AAEO,MAAM,yBACX,CAAC,KAAA,KACD,CAAC,KACC,KAAA,UAAA,CAAW,OAAO,KAAK,EAAA;AAE3B,SAAS,UAAA,CAAW,OAA6B,KAA4B,EAAA;AAC3E,EAAM,MAAA,MAAA,GAA+C,EAAE,EAAA,EAAI,IAAK,EAAA,CAAA;AAChE,EAAA,KAAA,MAAW,QAAQ,KAAO,EAAA;AACxB,IAAM,MAAA,gBAAA,GAAmBC,6BAAqB,CAAA,IAAA,CAAK,IAAI,CAAA,CAAA;AACvD,IAAA,IAAI,gBAAkB,EAAA;AACpB,MAAM,MAAA,GAAA,GAAM,gBAAiB,CAAA,IAAA,EAAM,KAAK,CAAA,CAAA;AACxC,MAAI,IAAA,CAAC,IAAI,EAAI,EAAA;AACX,QAAA,MAAA,CAAO,EAAK,GAAA,KAAA,CAAA;AACZ,QAAC,CAAA,MAAA,CAAO,aAAa,MAAO,CAAA,QAAA,GAAW,EAAK,CAAA,EAAA,IAAA,CAAK,IAAI,OAAO,CAAA,CAAA;AAAA,OAC9D;AAAA,KACK,MAAA;AACL,MAAM,MAAA,KAAA;AAAA,QACJ,CAAA,6DAAA,EAAgE,KAAK,IAAI,CAAA,CAAA,CAAA;AAAA,OAC3E,CAAA;AAAA,KACF;AAAA,GACF;AACA,EAAO,OAAA,MAAA,CAAA;AACT;;;;;;"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var vuuUtils = require('@vuu-ui/vuu-utils');
|
|
4
|
+
var editRuleValidationChecker = require('./edit-rule-validation-checker.js');
|
|
5
|
+
|
|
6
|
+
const isString = (value) => typeof value === "string";
|
|
7
|
+
const NUMERIC = /^(?:[0-9]|\.)+$/;
|
|
8
|
+
const CharValidatorNumeric = (rule, value) => {
|
|
9
|
+
if (isString(value)) {
|
|
10
|
+
if (value.trim() === "") {
|
|
11
|
+
return editRuleValidationChecker.OK;
|
|
12
|
+
} else if (value.match(NUMERIC)) {
|
|
13
|
+
return editRuleValidationChecker.OK;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return { ok: false, message: "only numeric characters are permitted" };
|
|
17
|
+
};
|
|
18
|
+
const ValueValidatorInteger = (rule, value) => {
|
|
19
|
+
if (isString(value)) {
|
|
20
|
+
if (value.trim() === "") {
|
|
21
|
+
return editRuleValidationChecker.OK;
|
|
22
|
+
} else {
|
|
23
|
+
if (!value.match(NUMERIC)) {
|
|
24
|
+
return {
|
|
25
|
+
ok: false,
|
|
26
|
+
message: "value must be an integer, invalid character"
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
if (parseFloat(value) === parseInt(value)) {
|
|
30
|
+
return editRuleValidationChecker.OK;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return { ok: false, message: "must be an integer value" };
|
|
35
|
+
};
|
|
36
|
+
const registerRules = () => {
|
|
37
|
+
vuuUtils.registerComponent(
|
|
38
|
+
"char-numeric",
|
|
39
|
+
CharValidatorNumeric,
|
|
40
|
+
"data-edit-validator",
|
|
41
|
+
{}
|
|
42
|
+
);
|
|
43
|
+
vuuUtils.registerComponent(
|
|
44
|
+
"value-integer",
|
|
45
|
+
ValueValidatorInteger,
|
|
46
|
+
"data-edit-validator",
|
|
47
|
+
{}
|
|
48
|
+
);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
exports.registerRules = registerRules;
|
|
52
|
+
//# sourceMappingURL=edit-validation-rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit-validation-rules.js","sources":["../../src/data-editing/edit-validation-rules.ts"],"sourcesContent":["import { registerComponent } from \"@vuu-ui/vuu-utils\";\nimport { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { EditRuleValidator } from \"@vuu-ui/vuu-data-types\";\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":["OK","registerComponent"],"mappings":";;;;;AAKA,MAAM,QAAW,GAAA,CAAC,KAChB,KAAA,OAAO,KAAU,KAAA,QAAA,CAAA;AAEnB,MAAM,OAAU,GAAA,iBAAA,CAAA;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,OAAAA,4BAAA,CAAA;AAAA,KACE,MAAA,IAAA,KAAA,CAAM,KAAM,CAAA,OAAO,CAAG,EAAA;AAC/B,MAAO,OAAAA,4BAAA,CAAA;AAAA,KACT;AAAA,GACF;AACA,EAAA,OAAO,EAAE,EAAA,EAAI,KAAO,EAAA,OAAA,EAAS,uCAAwC,EAAA,CAAA;AACvE,CAAA,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,OAAAA,4BAAA,CAAA;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,6CAAA;AAAA,SACX,CAAA;AAAA,OACF;AACA,MAAA,IAAI,UAAW,CAAA,KAAK,CAAM,KAAA,QAAA,CAAS,KAAK,CAAG,EAAA;AACzC,QAAO,OAAAA,4BAAA,CAAA;AAAA,OACT;AAAA,KACF;AAAA,GACF;AACA,EAAA,OAAO,EAAE,EAAA,EAAI,KAAO,EAAA,OAAA,EAAS,0BAA2B,EAAA,CAAA;AAC1D,CAAA,CAAA;AAEO,MAAM,gBAAgB,MAAM;AACjC,EAAAC,0BAAA;AAAA,IACE,cAAA;AAAA,IACA,oBAAA;AAAA,IACA,qBAAA;AAAA,IACA,EAAC;AAAA,GACH,CAAA;AACA,EAAAA,0BAAA;AAAA,IACE,eAAA;AAAA,IACA,qBAAA;AAAA,IACA,qBAAA;AAAA,IACA,EAAC;AAAA,GACH,CAAA;AACF;;;;"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const CLEAN_FORM = {
|
|
4
|
+
isClean: true,
|
|
5
|
+
editedFields: []
|
|
6
|
+
};
|
|
7
|
+
const buildFormEditState = (entity, newEntity) => {
|
|
8
|
+
if (entity === void 0) {
|
|
9
|
+
return CLEAN_FORM;
|
|
10
|
+
} else {
|
|
11
|
+
const editedFields = [];
|
|
12
|
+
for (const [fieldName, value] of Object.entries(entity)) {
|
|
13
|
+
if (value !== newEntity[fieldName]) {
|
|
14
|
+
editedFields.push(fieldName);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
isClean: editedFields.length === 0,
|
|
19
|
+
editedFields
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
exports.CLEAN_FORM = CLEAN_FORM;
|
|
25
|
+
exports.buildFormEditState = buildFormEditState;
|
|
26
|
+
//# sourceMappingURL=form-edit-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-edit-state.js","sources":["../../src/data-editing/form-edit-state.ts"],"sourcesContent":["import { Entity } from \"@vuu-ui/vuu-utils\";\n\nexport type FormEditState = {\n isClean: boolean;\n editedFields: string[];\n};\n\nexport const CLEAN_FORM: FormEditState = {\n isClean: true,\n editedFields: [],\n};\n\nexport const buildFormEditState = (\n entity: Entity | undefined,\n newEntity: Entity,\n): FormEditState => {\n if (entity === undefined) {\n return CLEAN_FORM;\n } else {\n const editedFields: string[] = [];\n for (const [fieldName, value] of Object.entries(entity)) {\n if (value !== newEntity[fieldName]) {\n editedFields.push(fieldName);\n }\n }\n\n return {\n isClean: editedFields.length === 0,\n editedFields,\n };\n }\n};\n"],"names":[],"mappings":";;AAOO,MAAM,UAA4B,GAAA;AAAA,EACvC,OAAS,EAAA,IAAA;AAAA,EACT,cAAc,EAAC;AACjB,EAAA;AAEa,MAAA,kBAAA,GAAqB,CAChC,MAAA,EACA,SACkB,KAAA;AAClB,EAAA,IAAI,WAAW,KAAW,CAAA,EAAA;AACxB,IAAO,OAAA,UAAA,CAAA;AAAA,GACF,MAAA;AACL,IAAA,MAAM,eAAyB,EAAC,CAAA;AAChC,IAAA,KAAA,MAAW,CAAC,SAAW,EAAA,KAAK,KAAK,MAAO,CAAA,OAAA,CAAQ,MAAM,CAAG,EAAA;AACvD,MAAI,IAAA,KAAA,KAAU,SAAU,CAAA,SAAS,CAAG,EAAA;AAClC,QAAA,YAAA,CAAa,KAAK,SAAS,CAAA,CAAA;AAAA,OAC7B;AAAA,KACF;AAEA,IAAO,OAAA;AAAA,MACL,OAAA,EAAS,aAAa,MAAW,KAAA,CAAA;AAAA,MACjC,YAAA;AAAA,KACF,CAAA;AAAA,GACF;AACF;;;;;"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var vuuUiControls = require('@vuu-ui/vuu-ui-controls');
|
|
5
|
+
var vuuUtils = require('@vuu-ui/vuu-utils');
|
|
6
|
+
|
|
7
|
+
const getDataItemEditControl = ({
|
|
8
|
+
InputProps: InputProps2,
|
|
9
|
+
dataDescriptor,
|
|
10
|
+
errorMessage,
|
|
11
|
+
onCommit,
|
|
12
|
+
suggestionProvider,
|
|
13
|
+
table
|
|
14
|
+
}) => {
|
|
15
|
+
const handleCommitNumber = (evt, value) => {
|
|
16
|
+
console.log(`value`);
|
|
17
|
+
onCommit(evt, value.toString());
|
|
18
|
+
};
|
|
19
|
+
if (dataDescriptor.editable === false) {
|
|
20
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
21
|
+
vuuUiControls.VuuInput,
|
|
22
|
+
{
|
|
23
|
+
variant: "secondary",
|
|
24
|
+
...InputProps2,
|
|
25
|
+
onCommit,
|
|
26
|
+
readOnly: true
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
} else if (vuuUtils.isDateTimeDataValue(dataDescriptor)) {
|
|
30
|
+
return /* @__PURE__ */ jsxRuntime.jsx(vuuUiControls.VuuDatePicker, { onCommit: handleCommitNumber });
|
|
31
|
+
} else if (dataDescriptor.serverDataType === "string" && suggestionProvider && table) {
|
|
32
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
33
|
+
vuuUiControls.VuuTypeaheadInput,
|
|
34
|
+
{
|
|
35
|
+
column: dataDescriptor.name,
|
|
36
|
+
onCommit,
|
|
37
|
+
suggestionProvider,
|
|
38
|
+
table
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
43
|
+
vuuUiControls.VuuInput,
|
|
44
|
+
{
|
|
45
|
+
variant: "secondary",
|
|
46
|
+
...InputProps2,
|
|
47
|
+
onCommit,
|
|
48
|
+
errorMessage
|
|
49
|
+
}
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
exports.getDataItemEditControl = getDataItemEditControl;
|
|
54
|
+
//# sourceMappingURL=get-data-item-edit-control.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-data-item-edit-control.js","sources":["../../src/data-editing/get-data-item-edit-control.tsx"],"sourcesContent":["import {\n DataValueDescriptor,\n SuggestionProvider,\n TableSchemaTable,\n} from \"@vuu-ui/vuu-data-types\";\nimport {\n VuuDatePicker,\n VuuInput,\n VuuTypeaheadInput,\n} from \"@vuu-ui/vuu-ui-controls\";\nimport { CommitHandler, isDateTimeDataValue } from \"@vuu-ui/vuu-utils\";\nimport { InputProps } from \"@salt-ds/core\";\n\nexport interface DataItemEditControlProps {\n InputProps?: Partial<InputProps>;\n /**\n * A table column or form field Descriptor.\n */\n dataDescriptor: DataValueDescriptor;\n errorMessage?: string;\n onCommit: CommitHandler<HTMLElement, string | undefined>;\n suggestionProvider?: SuggestionProvider;\n table?: TableSchemaTable;\n}\n\nexport type ValidationStatus = \"initial\" | true | string;\n\nexport const getDataItemEditControl = ({\n InputProps,\n dataDescriptor,\n errorMessage,\n onCommit,\n suggestionProvider,\n table,\n}: DataItemEditControlProps) => {\n const handleCommitNumber: CommitHandler<HTMLElement, number> = (\n evt,\n value,\n ) => {\n console.log(`value`);\n onCommit(evt, value.toString());\n };\n\n if (dataDescriptor.editable === false) {\n return (\n <VuuInput\n variant=\"secondary\"\n {...InputProps}\n onCommit={onCommit}\n readOnly\n />\n );\n } else if (isDateTimeDataValue(dataDescriptor)) {\n return <VuuDatePicker onCommit={handleCommitNumber} />;\n } else if (\n dataDescriptor.serverDataType === \"string\" &&\n suggestionProvider &&\n table\n ) {\n return (\n <VuuTypeaheadInput\n column={dataDescriptor.name}\n onCommit={onCommit}\n suggestionProvider={suggestionProvider}\n table={table}\n />\n );\n }\n return (\n <VuuInput\n variant=\"secondary\"\n {...InputProps}\n onCommit={onCommit}\n errorMessage={errorMessage}\n />\n );\n};\n"],"names":["InputProps","jsx","VuuInput","isDateTimeDataValue","VuuDatePicker","VuuTypeaheadInput"],"mappings":";;;;;;AA2BO,MAAM,yBAAyB,CAAC;AAAA,EACrC,UAAAA,EAAAA,WAAAA;AAAA,EACA,cAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA,kBAAA;AAAA,EACA,KAAA;AACF,CAAgC,KAAA;AAC9B,EAAM,MAAA,kBAAA,GAAyD,CAC7D,GAAA,EACA,KACG,KAAA;AACH,IAAA,OAAA,CAAQ,IAAI,CAAO,KAAA,CAAA,CAAA,CAAA;AACnB,IAAS,QAAA,CAAA,GAAA,EAAK,KAAM,CAAA,QAAA,EAAU,CAAA,CAAA;AAAA,GAChC,CAAA;AAEA,EAAI,IAAA,cAAA,CAAe,aAAa,KAAO,EAAA;AACrC,IACE,uBAAAC,cAAA;AAAA,MAACC,sBAAA;AAAA,MAAA;AAAA,QACC,OAAQ,EAAA,WAAA;AAAA,QACP,GAAGF,WAAAA;AAAA,QACJ,QAAA;AAAA,QACA,QAAQ,EAAA,IAAA;AAAA,OAAA;AAAA,KACV,CAAA;AAAA,GAEJ,MAAA,IAAWG,4BAAoB,CAAA,cAAc,CAAG,EAAA;AAC9C,IAAO,uBAAAF,cAAA,CAACG,2BAAc,EAAA,EAAA,QAAA,EAAU,kBAAoB,EAAA,CAAA,CAAA;AAAA,GAEpD,MAAA,IAAA,cAAA,CAAe,cAAmB,KAAA,QAAA,IAClC,sBACA,KACA,EAAA;AACA,IACE,uBAAAH,cAAA;AAAA,MAACI,+BAAA;AAAA,MAAA;AAAA,QACC,QAAQ,cAAe,CAAA,IAAA;AAAA,QACvB,QAAA;AAAA,QACA,kBAAA;AAAA,QACA,KAAA;AAAA,OAAA;AAAA,KACF,CAAA;AAAA,GAEJ;AACA,EACE,uBAAAJ,cAAA;AAAA,IAACC,sBAAA;AAAA,IAAA;AAAA,MACC,OAAQ,EAAA,WAAA;AAAA,MACP,GAAGF,WAAAA;AAAA,MACJ,QAAA;AAAA,MACA,YAAA;AAAA,KAAA;AAAA,GACF,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var vuuPopups = require('@vuu-ui/vuu-popups');
|
|
5
|
+
var vuuUtils = require('@vuu-ui/vuu-utils');
|
|
6
|
+
var core = require('@salt-ds/core');
|
|
7
|
+
var react = require('react');
|
|
8
|
+
var UnsavedChangesReport = require('./UnsavedChangesReport.js');
|
|
9
|
+
var editRuleValidationChecker = require('./edit-rule-validation-checker.js');
|
|
10
|
+
var formEditState = require('./form-edit-state.js');
|
|
11
|
+
|
|
12
|
+
const getValidationChecker = (descriptor, apply) => {
|
|
13
|
+
const rules = editRuleValidationChecker.getEditValidationRules(descriptor, apply);
|
|
14
|
+
return editRuleValidationChecker.buildValidationChecker(rules);
|
|
15
|
+
};
|
|
16
|
+
const nextValidationState = (state, dataDescriptor, value) => {
|
|
17
|
+
const check = getValidationChecker(dataDescriptor, "change");
|
|
18
|
+
const result = check(value);
|
|
19
|
+
const { name } = dataDescriptor;
|
|
20
|
+
const { ok: wasOk, messages: existingMessages } = state;
|
|
21
|
+
if (result.ok) {
|
|
22
|
+
if (!wasOk) {
|
|
23
|
+
const fieldsInError = Object.keys(existingMessages);
|
|
24
|
+
if (fieldsInError.includes(name)) {
|
|
25
|
+
if (fieldsInError.length === 1) {
|
|
26
|
+
return { ok: true, messages: {} };
|
|
27
|
+
} else {
|
|
28
|
+
const messages = { ...existingMessages };
|
|
29
|
+
delete messages[name];
|
|
30
|
+
return { ok: false, messages };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
} else {
|
|
35
|
+
return {
|
|
36
|
+
ok: false,
|
|
37
|
+
messages: {
|
|
38
|
+
...existingMessages,
|
|
39
|
+
[name]: result.messages.join("\n")
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return state;
|
|
44
|
+
};
|
|
45
|
+
function find(descriptors, fieldname) {
|
|
46
|
+
const d = descriptors.find(({ name }) => name === fieldname);
|
|
47
|
+
if (d) {
|
|
48
|
+
return d;
|
|
49
|
+
}
|
|
50
|
+
throw Error(`DataValueDescriptor not found for field ${fieldname}`);
|
|
51
|
+
}
|
|
52
|
+
const getField = (target) => {
|
|
53
|
+
const fieldElement = vuuUtils.queryClosest(target, "[data-field]");
|
|
54
|
+
if (fieldElement) {
|
|
55
|
+
return fieldElement.dataset.field;
|
|
56
|
+
} else {
|
|
57
|
+
throw Error("no field ");
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
const useEditForm = ({
|
|
61
|
+
dataSource,
|
|
62
|
+
formFieldDescriptors,
|
|
63
|
+
onSubmit
|
|
64
|
+
}) => {
|
|
65
|
+
const { showDialog, closeDialog } = vuuPopups.useDialogContext();
|
|
66
|
+
const currentDataSource = react.useRef();
|
|
67
|
+
const formFieldsContainerRef = react.useRef(null);
|
|
68
|
+
const entityRef = react.useRef();
|
|
69
|
+
const focusedFieldRef = react.useRef("");
|
|
70
|
+
const originalEntityRef = react.useRef();
|
|
71
|
+
const formEditStateRef = react.useRef(formEditState.CLEAN_FORM);
|
|
72
|
+
const validationStateRef = react.useRef({
|
|
73
|
+
ok: true,
|
|
74
|
+
messages: {}
|
|
75
|
+
});
|
|
76
|
+
const [entity, _setEntity] = react.useState();
|
|
77
|
+
const [, forceUpdate] = react.useState({});
|
|
78
|
+
const setFormEditState = react.useCallback((newState) => {
|
|
79
|
+
formEditStateRef.current = newState;
|
|
80
|
+
}, []);
|
|
81
|
+
const setEntity = react.useCallback(
|
|
82
|
+
(newEntity) => {
|
|
83
|
+
setFormEditState(
|
|
84
|
+
formEditState.buildFormEditState(originalEntityRef.current, newEntity)
|
|
85
|
+
);
|
|
86
|
+
entityRef.current = newEntity;
|
|
87
|
+
_setEntity(newEntity);
|
|
88
|
+
},
|
|
89
|
+
[setFormEditState]
|
|
90
|
+
);
|
|
91
|
+
const submitChanges = react.useCallback(async () => {
|
|
92
|
+
const rpcResponse = await currentDataSource.current?.rpcCall?.(
|
|
93
|
+
vuuUtils.viewportRpcRequest("VP_BULK_EDIT_SUBMIT_RPC")
|
|
94
|
+
);
|
|
95
|
+
console.log({ rpcResponse });
|
|
96
|
+
}, []);
|
|
97
|
+
const showSaveOrDiscardPrompt = react.useCallback(async () => {
|
|
98
|
+
const { current: currentEntity } = entityRef;
|
|
99
|
+
const { current: originalEntity } = originalEntityRef;
|
|
100
|
+
let resolver = void 0;
|
|
101
|
+
const save = async () => {
|
|
102
|
+
await submitChanges();
|
|
103
|
+
closeDialog();
|
|
104
|
+
resolver?.("saved");
|
|
105
|
+
};
|
|
106
|
+
const discard = () => {
|
|
107
|
+
closeDialog();
|
|
108
|
+
resolver?.("discarded");
|
|
109
|
+
};
|
|
110
|
+
requestAnimationFrame(() => {
|
|
111
|
+
showDialog(
|
|
112
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
113
|
+
UnsavedChangesReport.UnsavedChangesReport,
|
|
114
|
+
{
|
|
115
|
+
entity: originalEntity,
|
|
116
|
+
editedEntity: currentEntity
|
|
117
|
+
}
|
|
118
|
+
),
|
|
119
|
+
"Unsaved Changes",
|
|
120
|
+
[
|
|
121
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Button, { onClick: discard, children: "Discard Changes" }, "cancel"),
|
|
122
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Button, { onClick: save, children: "Save Changes" }, "submit")
|
|
123
|
+
],
|
|
124
|
+
true
|
|
125
|
+
// hideCloseButton
|
|
126
|
+
);
|
|
127
|
+
});
|
|
128
|
+
return new Promise((resolve) => {
|
|
129
|
+
resolver = resolve;
|
|
130
|
+
});
|
|
131
|
+
}, [closeDialog, showDialog, submitChanges]);
|
|
132
|
+
react.useMemo(async () => {
|
|
133
|
+
if (dataSource) {
|
|
134
|
+
if (formEditStateRef.current.isClean === false) {
|
|
135
|
+
await showSaveOrDiscardPrompt();
|
|
136
|
+
}
|
|
137
|
+
currentDataSource.current = dataSource;
|
|
138
|
+
originalEntityRef.current = void 0;
|
|
139
|
+
const columnMap = vuuUtils.buildColumnMap(dataSource.columns);
|
|
140
|
+
dataSource?.subscribe({ range: { from: 0, to: 1 } }, (message) => {
|
|
141
|
+
if (vuuUtils.messageHasDataRows(message)) {
|
|
142
|
+
const [row] = message.rows;
|
|
143
|
+
if (row) {
|
|
144
|
+
const entity2 = vuuUtils.dataSourceRowToEntity(row, columnMap);
|
|
145
|
+
if (originalEntityRef.current === void 0) {
|
|
146
|
+
originalEntityRef.current = entity2;
|
|
147
|
+
setEntity(entity2);
|
|
148
|
+
}
|
|
149
|
+
const { editedFields: editedFields2 } = formEditState.buildFormEditState(
|
|
150
|
+
entityRef.current,
|
|
151
|
+
entity2
|
|
152
|
+
);
|
|
153
|
+
if (editedFields2.length === 1) {
|
|
154
|
+
setEntity(entity2);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}, [dataSource, setEntity, showSaveOrDiscardPrompt]);
|
|
161
|
+
const setValidationState = react.useCallback((state) => {
|
|
162
|
+
validationStateRef.current = state;
|
|
163
|
+
forceUpdate({});
|
|
164
|
+
}, []);
|
|
165
|
+
const handleFieldCommit = react.useCallback(
|
|
166
|
+
(evt, value) => {
|
|
167
|
+
const { current: fieldName } = focusedFieldRef;
|
|
168
|
+
const dataDescriptor = find(formFieldDescriptors, fieldName);
|
|
169
|
+
const { current: state } = validationStateRef;
|
|
170
|
+
const newState = nextValidationState(state, dataDescriptor, value);
|
|
171
|
+
if (newState !== state) {
|
|
172
|
+
setValidationState(newState);
|
|
173
|
+
}
|
|
174
|
+
if (newState.ok && dataSource?.tableSchema) {
|
|
175
|
+
const { key } = dataSource.tableSchema;
|
|
176
|
+
const keyValue = entity?.[key];
|
|
177
|
+
dataSource?.applyEdit(keyValue, fieldName, value).then((rpcResponse) => {
|
|
178
|
+
console.log({ rpcResponse });
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
[dataSource, entity, formFieldDescriptors, setValidationState]
|
|
183
|
+
);
|
|
184
|
+
const handleFieldChange = react.useCallback(
|
|
185
|
+
(evt) => {
|
|
186
|
+
const { current: fieldName } = focusedFieldRef;
|
|
187
|
+
if (fieldName) {
|
|
188
|
+
const input = vuuUtils.queryClosest(evt.target, "input", true);
|
|
189
|
+
const dataDescriptor = find(formFieldDescriptors, fieldName);
|
|
190
|
+
const value = input.value;
|
|
191
|
+
const { current: state } = validationStateRef;
|
|
192
|
+
const newState = nextValidationState(state, dataDescriptor, value);
|
|
193
|
+
if (newState !== state) {
|
|
194
|
+
setValidationState(newState);
|
|
195
|
+
}
|
|
196
|
+
setEntity({ ...entity, [fieldName]: value });
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
[entity, formFieldDescriptors, setEntity, setValidationState]
|
|
200
|
+
);
|
|
201
|
+
const handleFormSubmit = react.useCallback(async () => {
|
|
202
|
+
submitChanges();
|
|
203
|
+
setFormEditState(formEditState.CLEAN_FORM);
|
|
204
|
+
originalEntityRef.current = entity;
|
|
205
|
+
onSubmit?.();
|
|
206
|
+
forceUpdate({});
|
|
207
|
+
}, [entity, onSubmit, setFormEditState, submitChanges]);
|
|
208
|
+
const handleFormCancel = react.useCallback(async () => {
|
|
209
|
+
setFormEditState(formEditState.CLEAN_FORM);
|
|
210
|
+
setEntity(originalEntityRef.current);
|
|
211
|
+
}, [setEntity, setFormEditState]);
|
|
212
|
+
const handleFocus = react.useCallback((evt) => {
|
|
213
|
+
if (formFieldsContainerRef.current?.contains(evt.target)) {
|
|
214
|
+
const fieldName = getField(evt.target);
|
|
215
|
+
if (fieldName) {
|
|
216
|
+
if (fieldName) {
|
|
217
|
+
focusedFieldRef.current = fieldName;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}, []);
|
|
222
|
+
const {
|
|
223
|
+
current: { ok, messages: errorMessages }
|
|
224
|
+
} = validationStateRef;
|
|
225
|
+
const {
|
|
226
|
+
current: { isClean, editedFields }
|
|
227
|
+
} = formEditStateRef;
|
|
228
|
+
return {
|
|
229
|
+
editedFields,
|
|
230
|
+
editEntity: entity,
|
|
231
|
+
errorMessages,
|
|
232
|
+
formFieldsContainerRef,
|
|
233
|
+
isClean,
|
|
234
|
+
ok,
|
|
235
|
+
onCancel: handleFormCancel,
|
|
236
|
+
onChange: handleFieldChange,
|
|
237
|
+
onCommit: handleFieldCommit,
|
|
238
|
+
onFocus: handleFocus,
|
|
239
|
+
onSubmit: handleFormSubmit
|
|
240
|
+
};
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
exports.useEditForm = useEditForm;
|
|
244
|
+
//# sourceMappingURL=useEditForm.js.map
|