@vuu-ui/vuu-data-react 3.0.0 → 3.1.0-beta.1
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/package.json +24 -20
- package/src/data-editing/EditForm.css.js +53 -0
- package/src/data-editing/EditForm.mjs +82 -0
- package/src/data-editing/UnsavedChangesReport.css.js +27 -0
- package/src/data-editing/UnsavedChangesReport.mjs +41 -0
- package/src/data-editing/edit-rule-validation-checker.mjs +30 -0
- package/src/data-editing/edit-validation-rules.mjs +33 -0
- package/src/data-editing/form-edit-state.mjs +16 -0
- package/src/data-editing/get-data-item-edit-control.mjs +63 -0
- package/src/data-editing/index.mjs +6 -0
- package/src/data-editing/useEditForm.mjs +253 -0
- package/src/datasource-provider/VuuDataSourceProvider.mjs +20 -0
- package/src/datasource-provider/index.mjs +1 -0
- package/src/datasource-provider/useAutoLoginToVuuServer.mjs +42 -0
- package/src/hooks/useLookupValues.mjs +93 -0
- package/src/hooks/useSessionDataSource.mjs +37 -0
- package/src/hooks/useTypeaheadSuggestions.mjs +50 -0
- package/src/hooks/useVisualLinks.mjs +87 -0
- package/src/hooks/useVuuMenuActions.mjs +269 -0
- package/src/hooks/useVuuTables.mjs +32 -0
- package/src/index.mjs +10 -0
- package/src/lost-connection-indicator/LostConnectionIndicator.css.js +29 -0
- package/src/lost-connection-indicator/LostConnectionIndicator.mjs +30 -0
- package/src/lost-connection-indicator/useLostConnection.mjs +28 -0
- package/src/session-editing-form/SessionEditingForm.css.js +47 -0
- package/src/session-editing-form/SessionEditingForm.mjs +236 -0
- package/src/session-editing-form/index.mjs +1 -0
- package/cjs/data-editing/EditForm.css.js +0 -6
- package/cjs/data-editing/EditForm.css.js.map +0 -1
- package/cjs/data-editing/EditForm.js +0 -90
- package/cjs/data-editing/EditForm.js.map +0 -1
- package/cjs/data-editing/UnsavedChangesReport.css.js +0 -6
- package/cjs/data-editing/UnsavedChangesReport.css.js.map +0 -1
- package/cjs/data-editing/UnsavedChangesReport.js +0 -29
- package/cjs/data-editing/UnsavedChangesReport.js.map +0 -1
- package/cjs/data-editing/edit-rule-validation-checker.js +0 -41
- package/cjs/data-editing/edit-rule-validation-checker.js.map +0 -1
- package/cjs/data-editing/edit-validation-rules.js +0 -52
- package/cjs/data-editing/edit-validation-rules.js.map +0 -1
- package/cjs/data-editing/form-edit-state.js +0 -26
- package/cjs/data-editing/form-edit-state.js.map +0 -1
- package/cjs/data-editing/get-data-item-edit-control.js +0 -106
- package/cjs/data-editing/get-data-item-edit-control.js.map +0 -1
- package/cjs/data-editing/useEditForm.js +0 -258
- package/cjs/data-editing/useEditForm.js.map +0 -1
- package/cjs/datasource-provider/VuuDataSourceProvider.js +0 -34
- package/cjs/datasource-provider/VuuDataSourceProvider.js.map +0 -1
- package/cjs/datasource-provider/useAutoLoginToVuuServer.js +0 -52
- package/cjs/datasource-provider/useAutoLoginToVuuServer.js.map +0 -1
- package/cjs/hooks/useLookupValues.js +0 -100
- package/cjs/hooks/useLookupValues.js.map +0 -1
- package/cjs/hooks/useSessionDataSource.js +0 -58
- package/cjs/hooks/useSessionDataSource.js.map +0 -1
- package/cjs/hooks/useTypeaheadSuggestions.js +0 -57
- package/cjs/hooks/useTypeaheadSuggestions.js.map +0 -1
- package/cjs/hooks/useVisualLinks.js +0 -84
- package/cjs/hooks/useVisualLinks.js.map +0 -1
- package/cjs/hooks/useVuuMenuActions.js +0 -352
- package/cjs/hooks/useVuuMenuActions.js.map +0 -1
- package/cjs/hooks/useVuuTables.js +0 -38
- package/cjs/hooks/useVuuTables.js.map +0 -1
- package/cjs/index.js +0 -42
- package/cjs/index.js.map +0 -1
- package/cjs/lost-connection-indicator/LostConnectionIndicator.css.js +0 -6
- package/cjs/lost-connection-indicator/LostConnectionIndicator.css.js.map +0 -1
- package/cjs/lost-connection-indicator/LostConnectionIndicator.js +0 -24
- package/cjs/lost-connection-indicator/LostConnectionIndicator.js.map +0 -1
- package/cjs/lost-connection-indicator/useLostConnection.js +0 -34
- package/cjs/lost-connection-indicator/useLostConnection.js.map +0 -1
- package/cjs/session-editing-form/SessionEditingForm.css.js +0 -6
- package/cjs/session-editing-form/SessionEditingForm.css.js.map +0 -1
- package/cjs/session-editing-form/SessionEditingForm.js +0 -270
- package/cjs/session-editing-form/SessionEditingForm.js.map +0 -1
- package/esm/data-editing/EditForm.css.js +0 -4
- package/esm/data-editing/EditForm.css.js.map +0 -1
- package/esm/data-editing/EditForm.js +0 -88
- package/esm/data-editing/EditForm.js.map +0 -1
- package/esm/data-editing/UnsavedChangesReport.css.js +0 -4
- package/esm/data-editing/UnsavedChangesReport.css.js.map +0 -1
- package/esm/data-editing/UnsavedChangesReport.js +0 -27
- package/esm/data-editing/UnsavedChangesReport.js.map +0 -1
- package/esm/data-editing/edit-rule-validation-checker.js +0 -37
- package/esm/data-editing/edit-rule-validation-checker.js.map +0 -1
- package/esm/data-editing/edit-validation-rules.js +0 -50
- package/esm/data-editing/edit-validation-rules.js.map +0 -1
- package/esm/data-editing/form-edit-state.js +0 -23
- package/esm/data-editing/form-edit-state.js.map +0 -1
- package/esm/data-editing/get-data-item-edit-control.js +0 -104
- package/esm/data-editing/get-data-item-edit-control.js.map +0 -1
- package/esm/data-editing/useEditForm.js +0 -256
- package/esm/data-editing/useEditForm.js.map +0 -1
- package/esm/datasource-provider/VuuDataSourceProvider.js +0 -32
- package/esm/datasource-provider/VuuDataSourceProvider.js.map +0 -1
- package/esm/datasource-provider/useAutoLoginToVuuServer.js +0 -50
- package/esm/datasource-provider/useAutoLoginToVuuServer.js.map +0 -1
- package/esm/hooks/useLookupValues.js +0 -98
- package/esm/hooks/useLookupValues.js.map +0 -1
- package/esm/hooks/useSessionDataSource.js +0 -56
- package/esm/hooks/useSessionDataSource.js.map +0 -1
- package/esm/hooks/useTypeaheadSuggestions.js +0 -54
- package/esm/hooks/useTypeaheadSuggestions.js.map +0 -1
- package/esm/hooks/useVisualLinks.js +0 -82
- package/esm/hooks/useVisualLinks.js.map +0 -1
- package/esm/hooks/useVuuMenuActions.js +0 -348
- package/esm/hooks/useVuuMenuActions.js.map +0 -1
- package/esm/hooks/useVuuTables.js +0 -36
- package/esm/hooks/useVuuTables.js.map +0 -1
- package/esm/index.js +0 -16
- package/esm/index.js.map +0 -1
- package/esm/lost-connection-indicator/LostConnectionIndicator.css.js +0 -4
- package/esm/lost-connection-indicator/LostConnectionIndicator.css.js.map +0 -1
- package/esm/lost-connection-indicator/LostConnectionIndicator.js +0 -22
- package/esm/lost-connection-indicator/LostConnectionIndicator.js.map +0 -1
- package/esm/lost-connection-indicator/useLostConnection.js +0 -32
- package/esm/lost-connection-indicator/useLostConnection.js.map +0 -1
- package/esm/session-editing-form/SessionEditingForm.css.js +0 -4
- package/esm/session-editing-form/SessionEditingForm.css.js.map +0 -1
- package/esm/session-editing-form/SessionEditingForm.js +0 -268
- package/esm/session-editing-form/SessionEditingForm.js.map +0 -1
|
@@ -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":["../../../../packages/vuu-data-react/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":["../../../../packages/vuu-data-react/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
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"form-edit-state.js","sources":["../../../../packages/vuu-data-react/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;AAChB;AAEa,MAAA,kBAAA,GAAqB,CAChC,MAAA,EACA,SACkB,KAAA;AAClB,EAAA,IAAI,WAAW,KAAW,CAAA,EAAA;AACxB,IAAO,OAAA,UAAA;AAAA,GACF,MAAA;AACL,IAAA,MAAM,eAAyB,EAAC;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;AAAA;AAC7B;AAGF,IAAO,OAAA;AAAA,MACL,OAAA,EAAS,aAAa,MAAW,KAAA,CAAA;AAAA,MACjC;AAAA,KACF;AAAA;AAEJ;;;;"}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { VuuInput, VuuTimePicker, VuuDatePicker, VuuTypeaheadInput } from '@vuu-ui/vuu-ui-controls';
|
|
3
|
-
import { isDataValueEditable, isTimeDataValue, asTimeString, isDateTimeDataValue } from '@vuu-ui/vuu-utils';
|
|
4
|
-
import { ToggleFilter } from '@vuu-ui/vuu-filters';
|
|
5
|
-
|
|
6
|
-
const getDataItemEditControl = ({
|
|
7
|
-
InputProps,
|
|
8
|
-
TypeaheadProps,
|
|
9
|
-
className,
|
|
10
|
-
commitOnBlur,
|
|
11
|
-
commitWhenCleared,
|
|
12
|
-
dataDescriptor,
|
|
13
|
-
editOperation = "update",
|
|
14
|
-
errorMessage,
|
|
15
|
-
onCommit,
|
|
16
|
-
table,
|
|
17
|
-
values,
|
|
18
|
-
variant
|
|
19
|
-
}) => {
|
|
20
|
-
const handleCommitNumber = (evt, value) => {
|
|
21
|
-
onCommit(evt, value.toString());
|
|
22
|
-
};
|
|
23
|
-
const dataVariant = variant && variant !== "toggle" ? variant : void 0;
|
|
24
|
-
if (!isDataValueEditable(dataDescriptor, editOperation, true)) {
|
|
25
|
-
return /* @__PURE__ */ jsx(
|
|
26
|
-
VuuInput,
|
|
27
|
-
{
|
|
28
|
-
variant: "secondary",
|
|
29
|
-
...InputProps,
|
|
30
|
-
onCommit,
|
|
31
|
-
readOnly: true,
|
|
32
|
-
"data-edit-control": true
|
|
33
|
-
}
|
|
34
|
-
);
|
|
35
|
-
} else if (isTimeDataValue(dataDescriptor)) {
|
|
36
|
-
if (InputProps?.inputProps) {
|
|
37
|
-
const { value, onChange } = InputProps.inputProps;
|
|
38
|
-
return /* @__PURE__ */ jsx(
|
|
39
|
-
VuuTimePicker,
|
|
40
|
-
{
|
|
41
|
-
className,
|
|
42
|
-
value: asTimeString(value, true),
|
|
43
|
-
onChange,
|
|
44
|
-
onCommit,
|
|
45
|
-
"data-edit-control": true
|
|
46
|
-
}
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
} else if (isDateTimeDataValue(dataDescriptor)) {
|
|
50
|
-
return /* @__PURE__ */ jsx(
|
|
51
|
-
VuuDatePicker,
|
|
52
|
-
{
|
|
53
|
-
className,
|
|
54
|
-
onCommit: handleCommitNumber,
|
|
55
|
-
"data-edit-control": true
|
|
56
|
-
}
|
|
57
|
-
);
|
|
58
|
-
} else if (dataDescriptor.serverDataType === "string" && table) {
|
|
59
|
-
if (variant === "toggle" && values?.length) {
|
|
60
|
-
return /* @__PURE__ */ jsx(
|
|
61
|
-
ToggleFilter,
|
|
62
|
-
{
|
|
63
|
-
className,
|
|
64
|
-
column: dataDescriptor.name,
|
|
65
|
-
"data-edit-control": true,
|
|
66
|
-
onCommit,
|
|
67
|
-
table,
|
|
68
|
-
values,
|
|
69
|
-
value: InputProps?.inputProps?.value ?? "all"
|
|
70
|
-
}
|
|
71
|
-
);
|
|
72
|
-
} else {
|
|
73
|
-
return /* @__PURE__ */ jsx(
|
|
74
|
-
VuuTypeaheadInput,
|
|
75
|
-
{
|
|
76
|
-
...InputProps,
|
|
77
|
-
...TypeaheadProps,
|
|
78
|
-
className,
|
|
79
|
-
column: dataDescriptor.name,
|
|
80
|
-
"data-edit-control": true,
|
|
81
|
-
"data-variant": dataVariant,
|
|
82
|
-
onCommit,
|
|
83
|
-
table
|
|
84
|
-
}
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
return /* @__PURE__ */ jsx(
|
|
89
|
-
VuuInput,
|
|
90
|
-
{
|
|
91
|
-
variant: "secondary",
|
|
92
|
-
...InputProps,
|
|
93
|
-
className,
|
|
94
|
-
commitOnBlur,
|
|
95
|
-
commitWhenCleared,
|
|
96
|
-
onCommit,
|
|
97
|
-
errorMessage,
|
|
98
|
-
"data-edit-control": true
|
|
99
|
-
}
|
|
100
|
-
);
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
export { getDataItemEditControl };
|
|
104
|
-
//# sourceMappingURL=get-data-item-edit-control.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"get-data-item-edit-control.js","sources":["../../../../packages/vuu-data-react/src/data-editing/get-data-item-edit-control.tsx"],"sourcesContent":["import type {\n DataValueDescriptor,\n TableSchemaTable,\n} from \"@vuu-ui/vuu-data-types\";\nimport {\n VuuDatePicker,\n VuuInput,\n VuuTimePicker,\n VuuTypeaheadInput,\n type VuuTypeaheadInputProps,\n} from \"@vuu-ui/vuu-ui-controls\";\nimport {\n type CommitHandler,\n isDateTimeDataValue,\n isDataValueEditable,\n isTimeDataValue,\n} from \"@vuu-ui/vuu-utils\";\nimport type { InputProps } from \"@salt-ds/core\";\nimport { asTimeString } from \"@vuu-ui/vuu-utils\";\nimport { ToggleFilter } from \"@vuu-ui/vuu-filters\";\n\n/**\n * variant can be used to provide a rendering hint to the filter control rendered.\n * 'toggle' for A ToggleButtonGroup, only suitable for up to 3 value choices\n * 'search' to render a search icon and require at least one character to be entered.\n * 'pick' to show a dropdown list, even before any text is entered, best for smaller lists\n */\nexport type FilterControlVariant = \"search\" | \"pick\" | \"toggle\";\nexport interface DataItemEditControlProps {\n InputProps?: Partial<InputProps>;\n TypeaheadProps?: Pick<\n VuuTypeaheadInputProps,\n | \"highlightFirstSuggestion\"\n | \"minCharacterCountToTriggerSuggestions\"\n | \"selectOnTab\"\n >;\n className?: string;\n commitOnBlur?: boolean;\n commitWhenCleared?: boolean;\n /**\n * A table column or form field Descriptor.\n */\n dataDescriptor: DataValueDescriptor;\n editOperation?: \"insert\" | \"update\";\n errorMessage?: string;\n onCommit: CommitHandler<HTMLElement>;\n table?: TableSchemaTable;\n /**\n * Where provided, only these values will be offered as suggestions.\n * They will be validated against server with Typeahead service, so\n * unavailable options are not offered.\n * Recommended for toggle filters, not usually necessary for other\n * filter variants.\n */\n values?: string[];\n variant?: FilterControlVariant;\n}\n\nexport type ValidationStatus = \"initial\" | true | string;\n\nexport const getDataItemEditControl = ({\n InputProps,\n TypeaheadProps,\n className,\n commitOnBlur,\n commitWhenCleared,\n dataDescriptor,\n editOperation = \"update\",\n errorMessage,\n onCommit,\n table,\n values,\n variant,\n}: DataItemEditControlProps) => {\n const handleCommitNumber: CommitHandler<HTMLElement, number> = (\n evt,\n value,\n ) => {\n onCommit(evt, value.toString());\n };\n\n const dataVariant = variant && variant !== \"toggle\" ? variant : undefined;\n\n // WOnb't this prevent a filter on an non-editable field ?\n if (!isDataValueEditable(dataDescriptor, editOperation, true)) {\n return (\n <VuuInput\n variant=\"secondary\"\n {...InputProps}\n onCommit={onCommit}\n readOnly\n data-edit-control\n />\n );\n } else if (isTimeDataValue(dataDescriptor)) {\n if (InputProps?.inputProps) {\n const { value, onChange } = InputProps.inputProps;\n return (\n <VuuTimePicker\n className={className}\n value={asTimeString(value, true)}\n onChange={onChange}\n onCommit={onCommit}\n data-edit-control\n />\n );\n }\n } else if (isDateTimeDataValue(dataDescriptor)) {\n return (\n <VuuDatePicker\n className={className}\n onCommit={handleCommitNumber}\n data-edit-control\n />\n );\n } else if (dataDescriptor.serverDataType === \"string\" && table) {\n if (variant === \"toggle\" && values?.length) {\n return (\n <ToggleFilter\n className={className}\n column={dataDescriptor.name}\n data-edit-control\n onCommit={onCommit}\n table={table}\n values={values}\n value={InputProps?.inputProps?.value ?? \"all\"}\n />\n );\n } else {\n return (\n <VuuTypeaheadInput\n {...InputProps}\n {...TypeaheadProps}\n className={className}\n column={dataDescriptor.name}\n data-edit-control\n data-variant={dataVariant}\n onCommit={onCommit}\n table={table}\n />\n );\n }\n }\n\n return (\n <VuuInput\n variant=\"secondary\"\n {...InputProps}\n className={className}\n commitOnBlur={commitOnBlur}\n commitWhenCleared={commitWhenCleared}\n onCommit={onCommit}\n errorMessage={errorMessage}\n data-edit-control\n />\n );\n};\n"],"names":[],"mappings":";;;;;AA4DO,MAAM,yBAAyB,CAAC;AAAA,EACrC,UAAA;AAAA,EACA,cAAA;AAAA,EACA,SAAA;AAAA,EACA,YAAA;AAAA,EACA,iBAAA;AAAA,EACA,cAAA;AAAA,EACA,aAAgB,GAAA,QAAA;AAAA,EAChB,YAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAgC,KAAA;AAC9B,EAAM,MAAA,kBAAA,GAAyD,CAC7D,GAAA,EACA,KACG,KAAA;AACH,IAAS,QAAA,CAAA,GAAA,EAAK,KAAM,CAAA,QAAA,EAAU,CAAA;AAAA,GAChC;AAEA,EAAA,MAAM,WAAc,GAAA,OAAA,IAAW,OAAY,KAAA,QAAA,GAAW,OAAU,GAAA,KAAA,CAAA;AAGhE,EAAA,IAAI,CAAC,mBAAA,CAAoB,cAAgB,EAAA,aAAA,EAAe,IAAI,CAAG,EAAA;AAC7D,IACE,uBAAA,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,OAAQ,EAAA,WAAA;AAAA,QACP,GAAG,UAAA;AAAA,QACJ,QAAA;AAAA,QACA,QAAQ,EAAA,IAAA;AAAA,QACR,mBAAiB,EAAA;AAAA;AAAA,KACnB;AAAA,GAEJ,MAAA,IAAW,eAAgB,CAAA,cAAc,CAAG,EAAA;AAC1C,IAAA,IAAI,YAAY,UAAY,EAAA;AAC1B,MAAA,MAAM,EAAE,KAAA,EAAO,QAAS,EAAA,GAAI,UAAW,CAAA,UAAA;AACvC,MACE,uBAAA,GAAA;AAAA,QAAC,aAAA;AAAA,QAAA;AAAA,UACC,SAAA;AAAA,UACA,KAAA,EAAO,YAAa,CAAA,KAAA,EAAO,IAAI,CAAA;AAAA,UAC/B,QAAA;AAAA,UACA,QAAA;AAAA,UACA,mBAAiB,EAAA;AAAA;AAAA,OACnB;AAAA;AAEJ,GACF,MAAA,IAAW,mBAAoB,CAAA,cAAc,CAAG,EAAA;AAC9C,IACE,uBAAA,GAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACC,SAAA;AAAA,QACA,QAAU,EAAA,kBAAA;AAAA,QACV,mBAAiB,EAAA;AAAA;AAAA,KACnB;AAAA,GAEO,MAAA,IAAA,cAAA,CAAe,cAAmB,KAAA,QAAA,IAAY,KAAO,EAAA;AAC9D,IAAI,IAAA,OAAA,KAAY,QAAY,IAAA,MAAA,EAAQ,MAAQ,EAAA;AAC1C,MACE,uBAAA,GAAA;AAAA,QAAC,YAAA;AAAA,QAAA;AAAA,UACC,SAAA;AAAA,UACA,QAAQ,cAAe,CAAA,IAAA;AAAA,UACvB,mBAAiB,EAAA,IAAA;AAAA,UACjB,QAAA;AAAA,UACA,KAAA;AAAA,UACA,MAAA;AAAA,UACA,KAAA,EAAO,UAAY,EAAA,UAAA,EAAY,KAAS,IAAA;AAAA;AAAA,OAC1C;AAAA,KAEG,MAAA;AACL,MACE,uBAAA,GAAA;AAAA,QAAC,iBAAA;AAAA,QAAA;AAAA,UACE,GAAG,UAAA;AAAA,UACH,GAAG,cAAA;AAAA,UACJ,SAAA;AAAA,UACA,QAAQ,cAAe,CAAA,IAAA;AAAA,UACvB,mBAAiB,EAAA,IAAA;AAAA,UACjB,cAAc,EAAA,WAAA;AAAA,UACd,QAAA;AAAA,UACA;AAAA;AAAA,OACF;AAAA;AAEJ;AAGF,EACE,uBAAA,GAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,OAAQ,EAAA,WAAA;AAAA,MACP,GAAG,UAAA;AAAA,MACJ,SAAA;AAAA,MACA,YAAA;AAAA,MACA,iBAAA;AAAA,MACA,QAAA;AAAA,MACA,YAAA;AAAA,MACA,mBAAiB,EAAA;AAAA;AAAA,GACnB;AAEJ;;;;"}
|
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { buildColumnMap, Range, messageHasDataRows, dataSourceRowToEntity, queryClosest } from '@vuu-ui/vuu-utils';
|
|
3
|
-
import { Button } from '@salt-ds/core';
|
|
4
|
-
import { useRef, useState, useCallback, useMemo } from 'react';
|
|
5
|
-
import { UnsavedChangesReport } from './UnsavedChangesReport.js';
|
|
6
|
-
import { getEditValidationRules, buildValidationChecker } from './edit-rule-validation-checker.js';
|
|
7
|
-
import { CLEAN_FORM, buildFormEditState } from './form-edit-state.js';
|
|
8
|
-
import { useModal } from '@vuu-ui/vuu-ui-controls';
|
|
9
|
-
|
|
10
|
-
const CLEAN_VALIDATION = {
|
|
11
|
-
ok: true,
|
|
12
|
-
messages: {}
|
|
13
|
-
};
|
|
14
|
-
const getValidationChecker = (descriptor, editPhase) => {
|
|
15
|
-
const rules = getEditValidationRules(descriptor, editPhase) ?? [];
|
|
16
|
-
return buildValidationChecker(rules);
|
|
17
|
-
};
|
|
18
|
-
const nextValidationState = (state, dataDescriptor, value) => {
|
|
19
|
-
const check = getValidationChecker(dataDescriptor, "change");
|
|
20
|
-
const result = check(value, "change");
|
|
21
|
-
const { name } = dataDescriptor;
|
|
22
|
-
const { ok: wasOk, messages: existingMessages } = state;
|
|
23
|
-
if (result.ok) {
|
|
24
|
-
if (!wasOk) {
|
|
25
|
-
const fieldsInError = Object.keys(existingMessages);
|
|
26
|
-
if (fieldsInError.includes(name)) {
|
|
27
|
-
if (fieldsInError.length === 1) {
|
|
28
|
-
return { ok: true, messages: {} };
|
|
29
|
-
} else {
|
|
30
|
-
const messages = { ...existingMessages };
|
|
31
|
-
delete messages[name];
|
|
32
|
-
return { ok: false, messages };
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
} else {
|
|
37
|
-
return {
|
|
38
|
-
ok: false,
|
|
39
|
-
messages: {
|
|
40
|
-
...existingMessages,
|
|
41
|
-
[name]: result.messages.join("\n")
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
return state;
|
|
46
|
-
};
|
|
47
|
-
function find(descriptors, fieldname) {
|
|
48
|
-
const d = descriptors.find(({ name }) => name === fieldname);
|
|
49
|
-
if (d) {
|
|
50
|
-
return d;
|
|
51
|
-
}
|
|
52
|
-
throw Error(`DataValueDescriptor not found for field ${fieldname}`);
|
|
53
|
-
}
|
|
54
|
-
const getField = (target) => {
|
|
55
|
-
const fieldElement = queryClosest(target, "[data-field]");
|
|
56
|
-
if (fieldElement) {
|
|
57
|
-
return fieldElement.dataset.field;
|
|
58
|
-
} else {
|
|
59
|
-
throw Error("no field ");
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
const useEditForm = ({
|
|
63
|
-
dataSource,
|
|
64
|
-
formFieldDescriptors,
|
|
65
|
-
onSubmit
|
|
66
|
-
}) => {
|
|
67
|
-
const { showDialog, closeDialog } = useModal();
|
|
68
|
-
const currentDataSource = useRef(void 0);
|
|
69
|
-
const formFieldsContainerRef = useRef(null);
|
|
70
|
-
const entityRef = useRef(void 0);
|
|
71
|
-
const focusedFieldRef = useRef("");
|
|
72
|
-
const originalEntityRef = useRef(void 0);
|
|
73
|
-
const formEditStateRef = useRef(CLEAN_FORM);
|
|
74
|
-
const validationStateRef = useRef({
|
|
75
|
-
ok: true,
|
|
76
|
-
messages: {}
|
|
77
|
-
});
|
|
78
|
-
const [entity, _setEntity] = useState();
|
|
79
|
-
const [, forceUpdate] = useState({});
|
|
80
|
-
const setFormEditState = useCallback((newState) => {
|
|
81
|
-
formEditStateRef.current = newState;
|
|
82
|
-
}, []);
|
|
83
|
-
const setEntity = useCallback(
|
|
84
|
-
(newEntity) => {
|
|
85
|
-
setFormEditState(
|
|
86
|
-
buildFormEditState(originalEntityRef.current, newEntity)
|
|
87
|
-
);
|
|
88
|
-
entityRef.current = newEntity;
|
|
89
|
-
_setEntity(newEntity);
|
|
90
|
-
},
|
|
91
|
-
[setFormEditState]
|
|
92
|
-
);
|
|
93
|
-
const submitChanges = useCallback(async () => {
|
|
94
|
-
const rpcResponse = await currentDataSource.current?.rpcRequest?.({
|
|
95
|
-
params: {},
|
|
96
|
-
rpcName: "VP_BULK_EDIT_SUBMIT_RPC",
|
|
97
|
-
type: "RPC_REQUEST"
|
|
98
|
-
});
|
|
99
|
-
console.log({ rpcResponse });
|
|
100
|
-
}, []);
|
|
101
|
-
const showSaveOrDiscardPrompt = useCallback(async () => {
|
|
102
|
-
const { current: currentEntity } = entityRef;
|
|
103
|
-
const { current: originalEntity } = originalEntityRef;
|
|
104
|
-
let resolver = void 0;
|
|
105
|
-
const save = async () => {
|
|
106
|
-
await submitChanges();
|
|
107
|
-
closeDialog();
|
|
108
|
-
resolver?.("saved");
|
|
109
|
-
};
|
|
110
|
-
const discard = () => {
|
|
111
|
-
closeDialog();
|
|
112
|
-
resolver?.("discarded");
|
|
113
|
-
};
|
|
114
|
-
requestAnimationFrame(() => {
|
|
115
|
-
showDialog(
|
|
116
|
-
/* @__PURE__ */ jsx(
|
|
117
|
-
UnsavedChangesReport,
|
|
118
|
-
{
|
|
119
|
-
entity: originalEntity,
|
|
120
|
-
editedEntity: currentEntity
|
|
121
|
-
}
|
|
122
|
-
),
|
|
123
|
-
"Unsaved Changes",
|
|
124
|
-
[
|
|
125
|
-
/* @__PURE__ */ jsx(Button, { onClick: discard, children: "Discard Changes" }, "cancel"),
|
|
126
|
-
/* @__PURE__ */ jsx(Button, { onClick: save, children: "Save Changes" }, "submit")
|
|
127
|
-
],
|
|
128
|
-
true
|
|
129
|
-
// hideCloseButton
|
|
130
|
-
);
|
|
131
|
-
});
|
|
132
|
-
return new Promise((resolve) => {
|
|
133
|
-
resolver = resolve;
|
|
134
|
-
});
|
|
135
|
-
}, [closeDialog, showDialog, submitChanges]);
|
|
136
|
-
useMemo(async () => {
|
|
137
|
-
if (dataSource) {
|
|
138
|
-
if (formEditStateRef.current.isClean === false) {
|
|
139
|
-
await showSaveOrDiscardPrompt();
|
|
140
|
-
}
|
|
141
|
-
currentDataSource.current = dataSource;
|
|
142
|
-
originalEntityRef.current = void 0;
|
|
143
|
-
const columnMap = buildColumnMap(dataSource.columns);
|
|
144
|
-
dataSource?.subscribe({ range: Range(0, 1) }, (message) => {
|
|
145
|
-
if (messageHasDataRows(message)) {
|
|
146
|
-
const [row] = message.rows;
|
|
147
|
-
if (row) {
|
|
148
|
-
const entity2 = dataSourceRowToEntity(row, columnMap);
|
|
149
|
-
if (originalEntityRef.current === void 0) {
|
|
150
|
-
originalEntityRef.current = entity2;
|
|
151
|
-
setEntity(entity2);
|
|
152
|
-
}
|
|
153
|
-
const { editedFields: editedFields2 } = buildFormEditState(
|
|
154
|
-
entityRef.current,
|
|
155
|
-
entity2
|
|
156
|
-
);
|
|
157
|
-
if (editedFields2.length === 1) {
|
|
158
|
-
setEntity(entity2);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
}, [dataSource, setEntity, showSaveOrDiscardPrompt]);
|
|
165
|
-
const setValidationState = useCallback((state) => {
|
|
166
|
-
validationStateRef.current = state;
|
|
167
|
-
forceUpdate({});
|
|
168
|
-
}, []);
|
|
169
|
-
const handleFieldCommit = useCallback(
|
|
170
|
-
async (_, value) => {
|
|
171
|
-
const { current: fieldName } = focusedFieldRef;
|
|
172
|
-
const dataDescriptor = find(formFieldDescriptors, fieldName);
|
|
173
|
-
const { current: state } = validationStateRef;
|
|
174
|
-
const newState = nextValidationState(state, dataDescriptor, value);
|
|
175
|
-
if (newState !== state) {
|
|
176
|
-
setValidationState(newState);
|
|
177
|
-
}
|
|
178
|
-
if (newState.ok && dataSource?.tableSchema) {
|
|
179
|
-
const { key } = dataSource.tableSchema;
|
|
180
|
-
const keyValue = entity?.[key];
|
|
181
|
-
const response = await dataSource.rpcRequest?.({
|
|
182
|
-
params: {
|
|
183
|
-
column: fieldName,
|
|
184
|
-
data: value,
|
|
185
|
-
key: keyValue
|
|
186
|
-
},
|
|
187
|
-
rpcName: "editCell",
|
|
188
|
-
type: "RPC_REQUEST"
|
|
189
|
-
});
|
|
190
|
-
console.log({ response });
|
|
191
|
-
}
|
|
192
|
-
},
|
|
193
|
-
[dataSource, entity, formFieldDescriptors, setValidationState]
|
|
194
|
-
);
|
|
195
|
-
const handleFieldChange = useCallback(
|
|
196
|
-
(evt) => {
|
|
197
|
-
const { current: fieldName } = focusedFieldRef;
|
|
198
|
-
if (fieldName) {
|
|
199
|
-
const input = queryClosest(evt.target, "input", true);
|
|
200
|
-
const dataDescriptor = find(formFieldDescriptors, fieldName);
|
|
201
|
-
const value = input.value;
|
|
202
|
-
const { current: state } = validationStateRef;
|
|
203
|
-
const newState = nextValidationState(state, dataDescriptor, value);
|
|
204
|
-
if (newState !== state) {
|
|
205
|
-
setValidationState(newState);
|
|
206
|
-
}
|
|
207
|
-
setEntity({ ...entity, [fieldName]: value });
|
|
208
|
-
}
|
|
209
|
-
},
|
|
210
|
-
[entity, formFieldDescriptors, setEntity, setValidationState]
|
|
211
|
-
);
|
|
212
|
-
const handleFormSubmit = useCallback(async () => {
|
|
213
|
-
submitChanges();
|
|
214
|
-
setFormEditState(CLEAN_FORM);
|
|
215
|
-
originalEntityRef.current = entity;
|
|
216
|
-
onSubmit?.();
|
|
217
|
-
forceUpdate({});
|
|
218
|
-
}, [entity, onSubmit, setFormEditState, submitChanges]);
|
|
219
|
-
const handleFormCancel = useCallback(async () => {
|
|
220
|
-
setFormEditState(CLEAN_FORM);
|
|
221
|
-
setValidationState(CLEAN_VALIDATION);
|
|
222
|
-
setEntity(originalEntityRef.current);
|
|
223
|
-
}, [setEntity, setFormEditState, setValidationState]);
|
|
224
|
-
const handleFocus = useCallback((evt) => {
|
|
225
|
-
if (formFieldsContainerRef.current?.contains(evt.target)) {
|
|
226
|
-
const fieldName = getField(evt.target);
|
|
227
|
-
if (fieldName) {
|
|
228
|
-
if (fieldName) {
|
|
229
|
-
focusedFieldRef.current = fieldName;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}, []);
|
|
234
|
-
const {
|
|
235
|
-
current: { ok, messages: errorMessages }
|
|
236
|
-
} = validationStateRef;
|
|
237
|
-
const {
|
|
238
|
-
current: { isClean, editedFields }
|
|
239
|
-
} = formEditStateRef;
|
|
240
|
-
return {
|
|
241
|
-
editedFields,
|
|
242
|
-
editEntity: entity,
|
|
243
|
-
errorMessages,
|
|
244
|
-
formFieldsContainerRef,
|
|
245
|
-
isClean,
|
|
246
|
-
ok,
|
|
247
|
-
onCancel: handleFormCancel,
|
|
248
|
-
onChange: handleFieldChange,
|
|
249
|
-
onCommit: handleFieldCommit,
|
|
250
|
-
onFocus: handleFocus,
|
|
251
|
-
onSubmit: handleFormSubmit
|
|
252
|
-
};
|
|
253
|
-
};
|
|
254
|
-
|
|
255
|
-
export { useEditForm };
|
|
256
|
-
//# sourceMappingURL=useEditForm.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useEditForm.js","sources":["../../../../packages/vuu-data-react/src/data-editing/useEditForm.tsx"],"sourcesContent":["import type { DataSource, DataValueDescriptor } from \"@vuu-ui/vuu-data-types\";\nimport type { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport {\n CommitHandler,\n Entity,\n Range,\n buildColumnMap,\n dataSourceRowToEntity,\n messageHasDataRows,\n queryClosest,\n} from \"@vuu-ui/vuu-utils\";\nimport { Button } from \"@salt-ds/core\";\nimport {\n FocusEventHandler,\n SyntheticEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { UnsavedChangesReport } from \"./UnsavedChangesReport\";\nimport {\n buildValidationChecker,\n getEditValidationRules,\n} from \"./edit-rule-validation-checker\";\nimport {\n CLEAN_FORM,\n FormEditState,\n buildFormEditState,\n} from \"./form-edit-state\";\nimport { useModal } from \"@vuu-ui/vuu-ui-controls\";\n\nexport interface EditFormHookProps {\n dataSource?: DataSource;\n formFieldDescriptors: DataValueDescriptor[];\n onSubmit?: () => void;\n}\n\ntype ValidationState = {\n ok: boolean;\n messages: Record<string, string>;\n};\n\nconst CLEAN_VALIDATION: ValidationState = {\n ok: true,\n messages: {},\n};\n\nconst getValidationChecker = (\n descriptor: DataValueDescriptor,\n editPhase: \"change\" | \"commit\",\n) => {\n const rules = getEditValidationRules(descriptor, editPhase) ?? [];\n return buildValidationChecker(rules);\n};\n\nconst nextValidationState = (\n state: ValidationState,\n dataDescriptor: DataValueDescriptor,\n value: VuuRowDataItemType,\n): ValidationState => {\n const check = getValidationChecker(dataDescriptor, \"change\");\n const result = check(value, \"change\");\n const { name } = dataDescriptor;\n\n const { ok: wasOk, messages: existingMessages } = state;\n\n if (result.ok) {\n if (!wasOk) {\n // if this field was the only one in error, the overall state\n // will now be ok, but not if there is still one or more other\n // field still in error.\n const fieldsInError = Object.keys(existingMessages);\n if (fieldsInError.includes(name)) {\n if (fieldsInError.length === 1) {\n return { ok: true, messages: {} };\n } else {\n const messages = { ...existingMessages };\n delete messages[name];\n return { ok: false, messages };\n }\n }\n }\n } else {\n return {\n ok: false,\n messages: {\n ...existingMessages,\n [name]: result.messages.join(\"\\n\"),\n },\n };\n }\n\n return state;\n};\n\nfunction find(descriptors: DataValueDescriptor[], fieldname: string) {\n const d = descriptors.find(({ name }) => name === fieldname);\n if (d) {\n return d;\n }\n throw Error(`DataValueDescriptor not found for field ${fieldname}`);\n}\n\nconst getField = (target: EventTarget | HTMLElement) => {\n const fieldElement = queryClosest(target, \"[data-field]\");\n if (fieldElement) {\n return fieldElement.dataset.field as string;\n } else {\n throw Error(\"no field \");\n }\n};\n\ntype Resolver = (value: unknown) => void;\n\nexport const useEditForm = ({\n dataSource,\n formFieldDescriptors,\n onSubmit,\n}: EditFormHookProps) => {\n const { showDialog, closeDialog } = useModal();\n\n const currentDataSource = useRef<DataSource>(undefined);\n const formFieldsContainerRef = useRef<HTMLDivElement>(null);\n const entityRef = useRef<Entity>(undefined);\n const focusedFieldRef = useRef(\"\");\n const originalEntityRef = useRef<Entity>(undefined);\n const formEditStateRef = useRef<FormEditState>(CLEAN_FORM);\n const validationStateRef = useRef<ValidationState>({\n ok: true,\n messages: {},\n });\n\n const [entity, _setEntity] = useState<Entity>();\n const [, forceUpdate] = useState({});\n\n const setFormEditState = useCallback((newState: FormEditState) => {\n formEditStateRef.current = newState;\n }, []);\n\n const setEntity = useCallback(\n (newEntity: Entity) => {\n setFormEditState(\n buildFormEditState(originalEntityRef.current, newEntity),\n );\n entityRef.current = newEntity;\n _setEntity(newEntity);\n },\n [setFormEditState],\n );\n\n const submitChanges = useCallback(async () => {\n const rpcResponse = await currentDataSource.current?.rpcRequest?.({\n params: {},\n rpcName: \"VP_BULK_EDIT_SUBMIT_RPC\",\n type: \"RPC_REQUEST\",\n });\n console.log({ rpcResponse });\n }, []);\n\n const showSaveOrDiscardPrompt = useCallback(async () => {\n const { current: currentEntity } = entityRef;\n const { current: originalEntity } = originalEntityRef;\n let resolver: Resolver | undefined = undefined;\n const save = async () => {\n await submitChanges();\n closeDialog();\n resolver?.(\"saved\");\n };\n\n const discard = () => {\n closeDialog();\n resolver?.(\"discarded\");\n };\n\n requestAnimationFrame(() => {\n showDialog(\n <UnsavedChangesReport\n entity={originalEntity as Entity}\n editedEntity={currentEntity as Entity}\n />,\n \"Unsaved Changes\",\n [\n <Button key=\"cancel\" onClick={discard}>\n Discard Changes\n </Button>,\n <Button key=\"submit\" onClick={save}>\n Save Changes\n </Button>,\n ],\n true, // hideCloseButton\n );\n });\n\n return new Promise((resolve) => {\n resolver = resolve;\n });\n }, [closeDialog, showDialog, submitChanges]);\n\n useMemo(async () => {\n if (dataSource) {\n if (formEditStateRef.current.isClean === false) {\n await showSaveOrDiscardPrompt();\n }\n\n currentDataSource.current = dataSource;\n\n originalEntityRef.current = undefined;\n\n const columnMap = buildColumnMap(dataSource.columns);\n\n dataSource?.subscribe({ range: Range(0, 1) }, (message) => {\n if (messageHasDataRows(message)) {\n const [row] = message.rows;\n if (row) {\n const entity = dataSourceRowToEntity(row, columnMap);\n if (originalEntityRef.current === undefined) {\n originalEntityRef.current = entity;\n setEntity(entity);\n }\n\n const { editedFields } = buildFormEditState(\n entityRef.current,\n entity,\n );\n\n // for controls which do not yield incremental changes, e.g dropdown, calendar\n // we apply the server update to our entity.\n if (editedFields.length === 1) {\n setEntity(entity);\n }\n\n // Do not overwrite entity here, just check that values returned by server\n // match whats expected\n }\n }\n });\n }\n }, [dataSource, setEntity, showSaveOrDiscardPrompt]);\n\n const setValidationState = useCallback((state: ValidationState) => {\n validationStateRef.current = state;\n forceUpdate({});\n }, []);\n\n const handleFieldCommit = useCallback<CommitHandler<HTMLElement>>(\n async (_, value) => {\n const { current: fieldName } = focusedFieldRef;\n const dataDescriptor = find(formFieldDescriptors, fieldName);\n\n const { current: state } = validationStateRef;\n const newState = nextValidationState(state, dataDescriptor, value);\n if (newState !== state) {\n setValidationState(newState);\n }\n\n if (newState.ok && dataSource?.tableSchema) {\n const { key } = dataSource.tableSchema;\n const keyValue = entity?.[key] as string;\n const response = await dataSource.rpcRequest?.({\n params: {\n column: fieldName,\n data: value,\n key: keyValue,\n },\n rpcName: \"editCell\",\n type: \"RPC_REQUEST\",\n });\n console.log({ response });\n }\n },\n [dataSource, entity, formFieldDescriptors, setValidationState],\n );\n\n const handleFieldChange = useCallback(\n (evt: SyntheticEvent<HTMLInputElement>) => {\n const { current: fieldName } = focusedFieldRef;\n if (fieldName) {\n const input = queryClosest<HTMLInputElement>(evt.target, \"input\", true);\n const dataDescriptor = find(formFieldDescriptors, fieldName);\n const value = input.value as string;\n const { current: state } = validationStateRef;\n const newState = nextValidationState(state, dataDescriptor, value);\n if (newState !== state) {\n setValidationState(newState);\n }\n\n setEntity({ ...entity, [fieldName]: value });\n }\n },\n [entity, formFieldDescriptors, setEntity, setValidationState],\n );\n\n const handleFormSubmit = useCallback(async () => {\n submitChanges();\n setFormEditState(CLEAN_FORM);\n originalEntityRef.current = entity;\n onSubmit?.();\n forceUpdate({});\n }, [entity, onSubmit, setFormEditState, submitChanges]);\n\n const handleFormCancel = useCallback(async () => {\n // const rpcResponse = await dataSource?.rpcCall?.(\n // viewportRpcRequest(\"VP_BULK_EDIT_CANCEL_RPC\"),\n // );\n setFormEditState(CLEAN_FORM);\n setValidationState(CLEAN_VALIDATION);\n // console.log({ rpcResponse });\n setEntity(originalEntityRef.current as Entity);\n }, [setEntity, setFormEditState, setValidationState]);\n\n const handleFocus = useCallback<FocusEventHandler>((evt) => {\n // Ignore focus on popup Calendars, Lists etc\n if (formFieldsContainerRef.current?.contains(evt.target)) {\n const fieldName = getField(evt.target);\n if (fieldName) {\n if (fieldName) {\n focusedFieldRef.current = fieldName;\n }\n }\n }\n }, []);\n\n const {\n current: { ok, messages: errorMessages },\n } = validationStateRef;\n\n const {\n current: { isClean, editedFields },\n } = formEditStateRef;\n\n return {\n editedFields,\n editEntity: entity,\n errorMessages,\n formFieldsContainerRef,\n isClean,\n ok,\n onCancel: handleFormCancel,\n onChange: handleFieldChange,\n onCommit: handleFieldCommit,\n onFocus: handleFocus,\n onSubmit: handleFormSubmit,\n };\n};\n"],"names":["entity","editedFields"],"mappings":";;;;;;;;;AA2CA,MAAM,gBAAoC,GAAA;AAAA,EACxC,EAAI,EAAA,IAAA;AAAA,EACJ,UAAU;AACZ,CAAA;AAEA,MAAM,oBAAA,GAAuB,CAC3B,UAAA,EACA,SACG,KAAA;AACH,EAAA,MAAM,KAAQ,GAAA,sBAAA,CAAuB,UAAY,EAAA,SAAS,KAAK,EAAC;AAChE,EAAA,OAAO,uBAAuB,KAAK,CAAA;AACrC,CAAA;AAEA,MAAM,mBAAsB,GAAA,CAC1B,KACA,EAAA,cAAA,EACA,KACoB,KAAA;AACpB,EAAM,MAAA,KAAA,GAAQ,oBAAqB,CAAA,cAAA,EAAgB,QAAQ,CAAA;AAC3D,EAAM,MAAA,MAAA,GAAS,KAAM,CAAA,KAAA,EAAO,QAAQ,CAAA;AACpC,EAAM,MAAA,EAAE,MAAS,GAAA,cAAA;AAEjB,EAAA,MAAM,EAAE,EAAA,EAAI,KAAO,EAAA,QAAA,EAAU,kBAAqB,GAAA,KAAA;AAElD,EAAA,IAAI,OAAO,EAAI,EAAA;AACb,IAAA,IAAI,CAAC,KAAO,EAAA;AAIV,MAAM,MAAA,aAAA,GAAgB,MAAO,CAAA,IAAA,CAAK,gBAAgB,CAAA;AAClD,MAAI,IAAA,aAAA,CAAc,QAAS,CAAA,IAAI,CAAG,EAAA;AAChC,QAAI,IAAA,aAAA,CAAc,WAAW,CAAG,EAAA;AAC9B,UAAA,OAAO,EAAE,EAAA,EAAI,IAAM,EAAA,QAAA,EAAU,EAAG,EAAA;AAAA,SAC3B,MAAA;AACL,UAAM,MAAA,QAAA,GAAW,EAAE,GAAG,gBAAiB,EAAA;AACvC,UAAA,OAAO,SAAS,IAAI,CAAA;AACpB,UAAO,OAAA,EAAE,EAAI,EAAA,KAAA,EAAO,QAAS,EAAA;AAAA;AAC/B;AACF;AACF,GACK,MAAA;AACL,IAAO,OAAA;AAAA,MACL,EAAI,EAAA,KAAA;AAAA,MACJ,QAAU,EAAA;AAAA,QACR,GAAG,gBAAA;AAAA,QACH,CAAC,IAAI,GAAG,MAAO,CAAA,QAAA,CAAS,KAAK,IAAI;AAAA;AACnC,KACF;AAAA;AAGF,EAAO,OAAA,KAAA;AACT,CAAA;AAEA,SAAS,IAAA,CAAK,aAAoC,SAAmB,EAAA;AACnE,EAAM,MAAA,CAAA,GAAI,YAAY,IAAK,CAAA,CAAC,EAAE,IAAK,EAAA,KAAM,SAAS,SAAS,CAAA;AAC3D,EAAA,IAAI,CAAG,EAAA;AACL,IAAO,OAAA,CAAA;AAAA;AAET,EAAM,MAAA,KAAA,CAAM,CAA2C,wCAAA,EAAA,SAAS,CAAE,CAAA,CAAA;AACpE;AAEA,MAAM,QAAA,GAAW,CAAC,MAAsC,KAAA;AACtD,EAAM,MAAA,YAAA,GAAe,YAAa,CAAA,MAAA,EAAQ,cAAc,CAAA;AACxD,EAAA,IAAI,YAAc,EAAA;AAChB,IAAA,OAAO,aAAa,OAAQ,CAAA,KAAA;AAAA,GACvB,MAAA;AACL,IAAA,MAAM,MAAM,WAAW,CAAA;AAAA;AAE3B,CAAA;AAIO,MAAM,cAAc,CAAC;AAAA,EAC1B,UAAA;AAAA,EACA,oBAAA;AAAA,EACA;AACF,CAAyB,KAAA;AACvB,EAAA,MAAM,EAAE,UAAA,EAAY,WAAY,EAAA,GAAI,QAAS,EAAA;AAE7C,EAAM,MAAA,iBAAA,GAAoB,OAAmB,KAAS,CAAA,CAAA;AACtD,EAAM,MAAA,sBAAA,GAAyB,OAAuB,IAAI,CAAA;AAC1D,EAAM,MAAA,SAAA,GAAY,OAAe,KAAS,CAAA,CAAA;AAC1C,EAAM,MAAA,eAAA,GAAkB,OAAO,EAAE,CAAA;AACjC,EAAM,MAAA,iBAAA,GAAoB,OAAe,KAAS,CAAA,CAAA;AAClD,EAAM,MAAA,gBAAA,GAAmB,OAAsB,UAAU,CAAA;AACzD,EAAA,MAAM,qBAAqB,MAAwB,CAAA;AAAA,IACjD,EAAI,EAAA,IAAA;AAAA,IACJ,UAAU;AAAC,GACZ,CAAA;AAED,EAAA,MAAM,CAAC,MAAA,EAAQ,UAAU,CAAA,GAAI,QAAiB,EAAA;AAC9C,EAAA,MAAM,GAAG,WAAW,CAAI,GAAA,QAAA,CAAS,EAAE,CAAA;AAEnC,EAAM,MAAA,gBAAA,GAAmB,WAAY,CAAA,CAAC,QAA4B,KAAA;AAChE,IAAA,gBAAA,CAAiB,OAAU,GAAA,QAAA;AAAA,GAC7B,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,SAAY,GAAA,WAAA;AAAA,IAChB,CAAC,SAAsB,KAAA;AACrB,MAAA,gBAAA;AAAA,QACE,kBAAA,CAAmB,iBAAkB,CAAA,OAAA,EAAS,SAAS;AAAA,OACzD;AACA,MAAA,SAAA,CAAU,OAAU,GAAA,SAAA;AACpB,MAAA,UAAA,CAAW,SAAS,CAAA;AAAA,KACtB;AAAA,IACA,CAAC,gBAAgB;AAAA,GACnB;AAEA,EAAM,MAAA,aAAA,GAAgB,YAAY,YAAY;AAC5C,IAAA,MAAM,WAAc,GAAA,MAAM,iBAAkB,CAAA,OAAA,EAAS,UAAa,GAAA;AAAA,MAChE,QAAQ,EAAC;AAAA,MACT,OAAS,EAAA,yBAAA;AAAA,MACT,IAAM,EAAA;AAAA,KACP,CAAA;AACD,IAAQ,OAAA,CAAA,GAAA,CAAI,EAAE,WAAA,EAAa,CAAA;AAAA,GAC7B,EAAG,EAAE,CAAA;AAEL,EAAM,MAAA,uBAAA,GAA0B,YAAY,YAAY;AACtD,IAAM,MAAA,EAAE,OAAS,EAAA,aAAA,EAAkB,GAAA,SAAA;AACnC,IAAM,MAAA,EAAE,OAAS,EAAA,cAAA,EAAmB,GAAA,iBAAA;AACpC,IAAA,IAAI,QAAiC,GAAA,KAAA,CAAA;AACrC,IAAA,MAAM,OAAO,YAAY;AACvB,MAAA,MAAM,aAAc,EAAA;AACpB,MAAY,WAAA,EAAA;AACZ,MAAA,QAAA,GAAW,OAAO,CAAA;AAAA,KACpB;AAEA,IAAA,MAAM,UAAU,MAAM;AACpB,MAAY,WAAA,EAAA;AACZ,MAAA,QAAA,GAAW,WAAW,CAAA;AAAA,KACxB;AAEA,IAAA,qBAAA,CAAsB,MAAM;AAC1B,MAAA,UAAA;AAAA,wBACE,GAAA;AAAA,UAAC,oBAAA;AAAA,UAAA;AAAA,YACC,MAAQ,EAAA,cAAA;AAAA,YACR,YAAc,EAAA;AAAA;AAAA,SAChB;AAAA,QACA,iBAAA;AAAA,QACA;AAAA,0BACG,GAAA,CAAA,MAAA,EAAA,EAAoB,OAAS,EAAA,OAAA,EAAS,+BAA3B,QAEZ,CAAA;AAAA,0BACC,GAAA,CAAA,MAAA,EAAA,EAAoB,OAAS,EAAA,IAAA,EAAM,4BAAxB,QAEZ;AAAA,SACF;AAAA,QACA;AAAA;AAAA,OACF;AAAA,KACD,CAAA;AAED,IAAO,OAAA,IAAI,OAAQ,CAAA,CAAC,OAAY,KAAA;AAC9B,MAAW,QAAA,GAAA,OAAA;AAAA,KACZ,CAAA;AAAA,GACA,EAAA,CAAC,WAAa,EAAA,UAAA,EAAY,aAAa,CAAC,CAAA;AAE3C,EAAA,OAAA,CAAQ,YAAY;AAClB,IAAA,IAAI,UAAY,EAAA;AACd,MAAI,IAAA,gBAAA,CAAiB,OAAQ,CAAA,OAAA,KAAY,KAAO,EAAA;AAC9C,QAAA,MAAM,uBAAwB,EAAA;AAAA;AAGhC,MAAA,iBAAA,CAAkB,OAAU,GAAA,UAAA;AAE5B,MAAA,iBAAA,CAAkB,OAAU,GAAA,KAAA,CAAA;AAE5B,MAAM,MAAA,SAAA,GAAY,cAAe,CAAA,UAAA,CAAW,OAAO,CAAA;AAEnD,MAAY,UAAA,EAAA,SAAA,CAAU,EAAE,KAAO,EAAA,KAAA,CAAM,GAAG,CAAC,CAAA,EAAK,EAAA,CAAC,OAAY,KAAA;AACzD,QAAI,IAAA,kBAAA,CAAmB,OAAO,CAAG,EAAA;AAC/B,UAAM,MAAA,CAAC,GAAG,CAAA,GAAI,OAAQ,CAAA,IAAA;AACtB,UAAA,IAAI,GAAK,EAAA;AACP,YAAMA,MAAAA,OAAAA,GAAS,qBAAsB,CAAA,GAAA,EAAK,SAAS,CAAA;AACnD,YAAI,IAAA,iBAAA,CAAkB,YAAY,KAAW,CAAA,EAAA;AAC3C,cAAA,iBAAA,CAAkB,OAAUA,GAAAA,OAAAA;AAC5B,cAAA,SAAA,CAAUA,OAAM,CAAA;AAAA;AAGlB,YAAM,MAAA,EAAE,YAAAC,EAAAA,aAAAA,EAAiB,GAAA,kBAAA;AAAA,cACvB,SAAU,CAAA,OAAA;AAAA,cACVD;AAAA,aACF;AAIA,YAAIC,IAAAA,aAAAA,CAAa,WAAW,CAAG,EAAA;AAC7B,cAAA,SAAA,CAAUD,OAAM,CAAA;AAAA;AAClB;AAIF;AACF,OACD,CAAA;AAAA;AACH,GACC,EAAA,CAAC,UAAY,EAAA,SAAA,EAAW,uBAAuB,CAAC,CAAA;AAEnD,EAAM,MAAA,kBAAA,GAAqB,WAAY,CAAA,CAAC,KAA2B,KAAA;AACjE,IAAA,kBAAA,CAAmB,OAAU,GAAA,KAAA;AAC7B,IAAA,WAAA,CAAY,EAAE,CAAA;AAAA,GAChB,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,iBAAoB,GAAA,WAAA;AAAA,IACxB,OAAO,GAAG,KAAU,KAAA;AAClB,MAAM,MAAA,EAAE,OAAS,EAAA,SAAA,EAAc,GAAA,eAAA;AAC/B,MAAM,MAAA,cAAA,GAAiB,IAAK,CAAA,oBAAA,EAAsB,SAAS,CAAA;AAE3D,MAAM,MAAA,EAAE,OAAS,EAAA,KAAA,EAAU,GAAA,kBAAA;AAC3B,MAAA,MAAM,QAAW,GAAA,mBAAA,CAAoB,KAAO,EAAA,cAAA,EAAgB,KAAK,CAAA;AACjE,MAAA,IAAI,aAAa,KAAO,EAAA;AACtB,QAAA,kBAAA,CAAmB,QAAQ,CAAA;AAAA;AAG7B,MAAI,IAAA,QAAA,CAAS,EAAM,IAAA,UAAA,EAAY,WAAa,EAAA;AAC1C,QAAM,MAAA,EAAE,GAAI,EAAA,GAAI,UAAW,CAAA,WAAA;AAC3B,QAAM,MAAA,QAAA,GAAW,SAAS,GAAG,CAAA;AAC7B,QAAM,MAAA,QAAA,GAAW,MAAM,UAAA,CAAW,UAAa,GAAA;AAAA,UAC7C,MAAQ,EAAA;AAAA,YACN,MAAQ,EAAA,SAAA;AAAA,YACR,IAAM,EAAA,KAAA;AAAA,YACN,GAAK,EAAA;AAAA,WACP;AAAA,UACA,OAAS,EAAA,UAAA;AAAA,UACT,IAAM,EAAA;AAAA,SACP,CAAA;AACD,QAAQ,OAAA,CAAA,GAAA,CAAI,EAAE,QAAA,EAAU,CAAA;AAAA;AAC1B,KACF;AAAA,IACA,CAAC,UAAA,EAAY,MAAQ,EAAA,oBAAA,EAAsB,kBAAkB;AAAA,GAC/D;AAEA,EAAA,MAAM,iBAAoB,GAAA,WAAA;AAAA,IACxB,CAAC,GAA0C,KAAA;AACzC,MAAM,MAAA,EAAE,OAAS,EAAA,SAAA,EAAc,GAAA,eAAA;AAC/B,MAAA,IAAI,SAAW,EAAA;AACb,QAAA,MAAM,KAAQ,GAAA,YAAA,CAA+B,GAAI,CAAA,MAAA,EAAQ,SAAS,IAAI,CAAA;AACtE,QAAM,MAAA,cAAA,GAAiB,IAAK,CAAA,oBAAA,EAAsB,SAAS,CAAA;AAC3D,QAAA,MAAM,QAAQ,KAAM,CAAA,KAAA;AACpB,QAAM,MAAA,EAAE,OAAS,EAAA,KAAA,EAAU,GAAA,kBAAA;AAC3B,QAAA,MAAM,QAAW,GAAA,mBAAA,CAAoB,KAAO,EAAA,cAAA,EAAgB,KAAK,CAAA;AACjE,QAAA,IAAI,aAAa,KAAO,EAAA;AACtB,UAAA,kBAAA,CAAmB,QAAQ,CAAA;AAAA;AAG7B,QAAA,SAAA,CAAU,EAAE,GAAG,MAAA,EAAQ,CAAC,SAAS,GAAG,OAAO,CAAA;AAAA;AAC7C,KACF;AAAA,IACA,CAAC,MAAA,EAAQ,oBAAsB,EAAA,SAAA,EAAW,kBAAkB;AAAA,GAC9D;AAEA,EAAM,MAAA,gBAAA,GAAmB,YAAY,YAAY;AAC/C,IAAc,aAAA,EAAA;AACd,IAAA,gBAAA,CAAiB,UAAU,CAAA;AAC3B,IAAA,iBAAA,CAAkB,OAAU,GAAA,MAAA;AAC5B,IAAW,QAAA,IAAA;AACX,IAAA,WAAA,CAAY,EAAE,CAAA;AAAA,KACb,CAAC,MAAA,EAAQ,QAAU,EAAA,gBAAA,EAAkB,aAAa,CAAC,CAAA;AAEtD,EAAM,MAAA,gBAAA,GAAmB,YAAY,YAAY;AAI/C,IAAA,gBAAA,CAAiB,UAAU,CAAA;AAC3B,IAAA,kBAAA,CAAmB,gBAAgB,CAAA;AAEnC,IAAA,SAAA,CAAU,kBAAkB,OAAiB,CAAA;AAAA,GAC5C,EAAA,CAAC,SAAW,EAAA,gBAAA,EAAkB,kBAAkB,CAAC,CAAA;AAEpD,EAAM,MAAA,WAAA,GAAc,WAA+B,CAAA,CAAC,GAAQ,KAAA;AAE1D,IAAA,IAAI,sBAAuB,CAAA,OAAA,EAAS,QAAS,CAAA,GAAA,CAAI,MAAM,CAAG,EAAA;AACxD,MAAM,MAAA,SAAA,GAAY,QAAS,CAAA,GAAA,CAAI,MAAM,CAAA;AACrC,MAAA,IAAI,SAAW,EAAA;AACb,QAAA,IAAI,SAAW,EAAA;AACb,UAAA,eAAA,CAAgB,OAAU,GAAA,SAAA;AAAA;AAC5B;AACF;AACF,GACF,EAAG,EAAE,CAAA;AAEL,EAAM,MAAA;AAAA,IACJ,OAAS,EAAA,EAAE,EAAI,EAAA,QAAA,EAAU,aAAc;AAAA,GACrC,GAAA,kBAAA;AAEJ,EAAM,MAAA;AAAA,IACJ,OAAA,EAAS,EAAE,OAAA,EAAS,YAAa;AAAA,GAC/B,GAAA,gBAAA;AAEJ,EAAO,OAAA;AAAA,IACL,YAAA;AAAA,IACA,UAAY,EAAA,MAAA;AAAA,IACZ,aAAA;AAAA,IACA,sBAAA;AAAA,IACA,OAAA;AAAA,IACA,EAAA;AAAA,IACA,QAAU,EAAA,gBAAA;AAAA,IACV,QAAU,EAAA,iBAAA;AAAA,IACV,QAAU,EAAA,iBAAA;AAAA,IACV,OAAS,EAAA,WAAA;AAAA,IACT,QAAU,EAAA;AAAA,GACZ;AACF;;;;"}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { VuuDataSource, ConnectionManager } from '@vuu-ui/vuu-data-remote';
|
|
3
|
-
import { DataProvider } from '@vuu-ui/vuu-utils';
|
|
4
|
-
import { useAutoLoginToVuuServer } from './useAutoLoginToVuuServer.js';
|
|
5
|
-
|
|
6
|
-
const getServerAPI = () => ConnectionManager.serverAPI;
|
|
7
|
-
const VuuDataSourceProvider = ({
|
|
8
|
-
authenticate,
|
|
9
|
-
autoConnect = false,
|
|
10
|
-
autoLogin = false,
|
|
11
|
-
children,
|
|
12
|
-
websocketUrl
|
|
13
|
-
}) => {
|
|
14
|
-
useAutoLoginToVuuServer({
|
|
15
|
-
authenticate,
|
|
16
|
-
autoConnect,
|
|
17
|
-
autoLogin,
|
|
18
|
-
websocketUrl
|
|
19
|
-
});
|
|
20
|
-
return /* @__PURE__ */ jsx(
|
|
21
|
-
DataProvider,
|
|
22
|
-
{
|
|
23
|
-
VuuDataSource,
|
|
24
|
-
getServerAPI,
|
|
25
|
-
isLocalData: false,
|
|
26
|
-
children
|
|
27
|
-
}
|
|
28
|
-
);
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export { VuuDataSourceProvider };
|
|
32
|
-
//# sourceMappingURL=VuuDataSourceProvider.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"VuuDataSourceProvider.js","sources":["../../../../packages/vuu-data-react/src/datasource-provider/VuuDataSourceProvider.tsx"],"sourcesContent":["import { ConnectionManager, VuuDataSource } from \"@vuu-ui/vuu-data-remote\";\nimport { DataProvider } from \"@vuu-ui/vuu-utils\";\nimport { ReactNode } from \"react\";\nimport { useAutoLoginToVuuServer } from \"./useAutoLoginToVuuServer\";\n\nconst getServerAPI = () => ConnectionManager.serverAPI;\n\n/**\n * DataSource Providers inject a DataSource constructor, made available\n * to clients via the useData hook. This provider offers the standard \n * VuuDataSource, which will source data from a remote vuu server. \n * \n * In production code, it will generally be used without props, authentication\n * and connection to vuu server will be handled elsewhere. The props are\n * useful for rendering standalone components.\n */\nexport const VuuDataSourceProvider = ({\n authenticate,\n autoConnect = false,\n autoLogin = false,\n children,\n websocketUrl,\n}: {\n authenticate?: boolean;\n autoConnect?: boolean;\n autoLogin?: boolean;\n children: ReactNode;\n websocketUrl?: string;\n}) => {\n useAutoLoginToVuuServer({\n authenticate,\n autoConnect,\n autoLogin,\n websocketUrl,\n });\n\n return (\n <DataProvider\n VuuDataSource={VuuDataSource}\n getServerAPI={getServerAPI}\n isLocalData={false}\n >\n {children}\n </DataProvider>\n );\n};\n"],"names":[],"mappings":";;;;;AAKA,MAAM,YAAA,GAAe,MAAM,iBAAkB,CAAA,SAAA;AAWtC,MAAM,wBAAwB,CAAC;AAAA,EACpC,YAAA;AAAA,EACA,WAAc,GAAA,KAAA;AAAA,EACd,SAAY,GAAA,KAAA;AAAA,EACZ,QAAA;AAAA,EACA;AACF,CAMM,KAAA;AACJ,EAAwB,uBAAA,CAAA;AAAA,IACtB,YAAA;AAAA,IACA,WAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EACE,uBAAA,GAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACC,aAAA;AAAA,MACA,YAAA;AAAA,MACA,WAAa,EAAA,KAAA;AAAA,MAEZ;AAAA;AAAA,GACH;AAEJ;;;;"}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { ConnectionManager, authenticate } from '@vuu-ui/vuu-data-remote';
|
|
3
|
-
import { useState, useEffect } from 'react';
|
|
4
|
-
|
|
5
|
-
const useAutoLoginToVuuServer = ({
|
|
6
|
-
authenticate: authenticate$1 = true,
|
|
7
|
-
autoConnect = true,
|
|
8
|
-
// autoLogin = true,
|
|
9
|
-
secure = true,
|
|
10
|
-
token: tokenProp = "no-token",
|
|
11
|
-
user = "steve",
|
|
12
|
-
websocketUrl
|
|
13
|
-
} = {}) => {
|
|
14
|
-
const [errorMessage, setErrorMessage] = useState("");
|
|
15
|
-
useEffect(() => {
|
|
16
|
-
const connect = async () => {
|
|
17
|
-
try {
|
|
18
|
-
let token = tokenProp;
|
|
19
|
-
if (authenticate$1) {
|
|
20
|
-
const response = await authenticate(user, "xyz", "/api/authn");
|
|
21
|
-
token = response.token;
|
|
22
|
-
}
|
|
23
|
-
const url = websocketUrl ?? `${secure ? "wss" : "ws"}://localhost/8090/websocket`;
|
|
24
|
-
ConnectionManager.connect({
|
|
25
|
-
url,
|
|
26
|
-
token
|
|
27
|
-
});
|
|
28
|
-
} catch (e) {
|
|
29
|
-
if (e instanceof Error) {
|
|
30
|
-
console.error(e.message);
|
|
31
|
-
setErrorMessage(e.message);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
if (autoConnect) {
|
|
36
|
-
connect();
|
|
37
|
-
}
|
|
38
|
-
return () => {
|
|
39
|
-
if (autoConnect) {
|
|
40
|
-
ConnectionManager.disconnect();
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
}, [authenticate$1, autoConnect, secure, tokenProp, user, websocketUrl]);
|
|
44
|
-
if (errorMessage) {
|
|
45
|
-
return /* @__PURE__ */ jsx("p", { children: "Unable to authenticate against Vuu Server A Vuu Server instance must be running to show this example." });
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
export { useAutoLoginToVuuServer };
|
|
50
|
-
//# sourceMappingURL=useAutoLoginToVuuServer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useAutoLoginToVuuServer.js","sources":["../../../../packages/vuu-data-react/src/datasource-provider/useAutoLoginToVuuServer.tsx"],"sourcesContent":["import {\n authenticate as vuuAuthenticate,\n ConnectionManager,\n} from \"@vuu-ui/vuu-data-remote\";\nimport { useEffect, useState } from \"react\";\n\nexport const useAutoLoginToVuuServer = ({\n authenticate = true,\n autoConnect = true,\n // autoLogin = true,\n secure = true,\n token: tokenProp = \"no-token\",\n user = \"steve\",\n websocketUrl,\n}: {\n /**\n * if true, auth url on vuuserver will be used to get token\n * auth url is \"/api/authn\"\n */\n authenticate?: boolean;\n /**\n * true by default, will go ahead and open websocket connection\n */\n autoConnect?: boolean;\n autoLogin?: boolean;\n secure?: boolean;\n /**\n * use with no authenticate step, to provide auth token.\n * Used when vuu server is performing no token check\n */\n token?: string;\n user?: string;\n websocketUrl?: string;\n} = {}) => {\n const [errorMessage, setErrorMessage] = useState(\"\");\n useEffect(() => {\n const connect = async () => {\n try {\n let token = tokenProp;\n if (authenticate) {\n const response = await vuuAuthenticate(user, \"xyz\", \"/api/authn\");\n token = response.token;\n }\n\n const url =\n websocketUrl ?? `${secure ? \"wss\" : \"ws\"}://localhost/8090/websocket`;\n\n ConnectionManager.connect({\n url,\n token,\n });\n } catch (e: unknown) {\n if (e instanceof Error) {\n console.error(e.message);\n setErrorMessage(e.message);\n }\n }\n };\n if (autoConnect) {\n connect();\n }\n\n return () => {\n if (autoConnect) {\n ConnectionManager.disconnect();\n }\n };\n }, [authenticate, autoConnect, secure, tokenProp, user, websocketUrl]);\n\n if (errorMessage) {\n return (\n <p>\n Unable to authenticate against Vuu Server A Vuu Server instance must be\n running to show this example.\n </p>\n );\n }\n};\n"],"names":["authenticate","vuuAuthenticate"],"mappings":";;;;AAMO,MAAM,0BAA0B,CAAC;AAAA,gBACtCA,cAAe,GAAA,IAAA;AAAA,EACf,WAAc,GAAA,IAAA;AAAA;AAAA,EAEd,MAAS,GAAA,IAAA;AAAA,EACT,OAAO,SAAY,GAAA,UAAA;AAAA,EACnB,IAAO,GAAA,OAAA;AAAA,EACP;AACF,CAAA,GAmBI,EAAO,KAAA;AACT,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAAS,EAAE,CAAA;AACnD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,UAAU,YAAY;AAC1B,MAAI,IAAA;AACF,QAAA,IAAI,KAAQ,GAAA,SAAA;AACZ,QAAA,IAAIA,cAAc,EAAA;AAChB,UAAA,MAAM,QAAW,GAAA,MAAMC,YAAgB,CAAA,IAAA,EAAM,OAAO,YAAY,CAAA;AAChE,UAAA,KAAA,GAAQ,QAAS,CAAA,KAAA;AAAA;AAGnB,QAAA,MAAM,GACJ,GAAA,YAAA,IAAgB,CAAG,EAAA,MAAA,GAAS,QAAQ,IAAI,CAAA,2BAAA,CAAA;AAE1C,QAAA,iBAAA,CAAkB,OAAQ,CAAA;AAAA,UACxB,GAAA;AAAA,UACA;AAAA,SACD,CAAA;AAAA,eACM,CAAY,EAAA;AACnB,QAAA,IAAI,aAAa,KAAO,EAAA;AACtB,UAAQ,OAAA,CAAA,KAAA,CAAM,EAAE,OAAO,CAAA;AACvB,UAAA,eAAA,CAAgB,EAAE,OAAO,CAAA;AAAA;AAC3B;AACF,KACF;AACA,IAAA,IAAI,WAAa,EAAA;AACf,MAAQ,OAAA,EAAA;AAAA;AAGV,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,WAAa,EAAA;AACf,QAAA,iBAAA,CAAkB,UAAW,EAAA;AAAA;AAC/B,KACF;AAAA,GACF,EAAG,CAACD,cAAc,EAAA,WAAA,EAAa,QAAQ,SAAW,EAAA,IAAA,EAAM,YAAY,CAAC,CAAA;AAErE,EAAA,IAAI,YAAc,EAAA;AAChB,IACE,uBAAA,GAAA,CAAC,OAAE,QAGH,EAAA,uGAAA,EAAA,CAAA;AAAA;AAGN;;;;"}
|