@vuu-ui/vuu-data-react 2.1.19-beta.1 → 2.1.19-beta.3
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 +90 -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 +41 -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 +105 -0
- package/cjs/data-editing/get-data-item-edit-control.js.map +1 -0
- package/cjs/data-editing/useEditForm.js +258 -0
- package/cjs/data-editing/useEditForm.js.map +1 -0
- package/cjs/datasource-provider/VuuDataSourceProvider.js +34 -0
- package/cjs/datasource-provider/VuuDataSourceProvider.js.map +1 -0
- package/cjs/datasource-provider/useAutoLoginToVuuServer.js +52 -0
- package/cjs/datasource-provider/useAutoLoginToVuuServer.js.map +1 -0
- package/cjs/hooks/useLookupValues.js +100 -0
- package/cjs/hooks/useLookupValues.js.map +1 -0
- package/cjs/hooks/useSessionDataSource.js +58 -0
- package/cjs/hooks/useSessionDataSource.js.map +1 -0
- package/cjs/hooks/useTypeaheadSuggestions.js +57 -0
- package/cjs/hooks/useTypeaheadSuggestions.js.map +1 -0
- package/cjs/hooks/useVisualLinks.js +84 -0
- package/cjs/hooks/useVisualLinks.js.map +1 -0
- package/cjs/hooks/useVuuMenuActions.js +352 -0
- package/cjs/hooks/useVuuMenuActions.js.map +1 -0
- package/cjs/hooks/useVuuTables.js +38 -0
- package/cjs/hooks/useVuuTables.js.map +1 -0
- package/cjs/index.js +42 -0
- package/cjs/index.js.map +1 -0
- package/cjs/lost-connection-indicator/LostConnectionIndicator.css.js +6 -0
- package/cjs/lost-connection-indicator/LostConnectionIndicator.css.js.map +1 -0
- package/cjs/lost-connection-indicator/LostConnectionIndicator.js +24 -0
- package/cjs/lost-connection-indicator/LostConnectionIndicator.js.map +1 -0
- package/cjs/lost-connection-indicator/useLostConnection.js +34 -0
- package/cjs/lost-connection-indicator/useLostConnection.js.map +1 -0
- package/cjs/session-editing-form/SessionEditingForm.css.js +6 -0
- package/cjs/session-editing-form/SessionEditingForm.css.js.map +1 -0
- package/cjs/session-editing-form/SessionEditingForm.js +270 -0
- package/cjs/session-editing-form/SessionEditingForm.js.map +1 -0
- 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 +88 -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 +37 -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 +103 -0
- package/esm/data-editing/get-data-item-edit-control.js.map +1 -0
- package/esm/data-editing/useEditForm.js +256 -0
- package/esm/data-editing/useEditForm.js.map +1 -0
- package/esm/datasource-provider/VuuDataSourceProvider.js +32 -0
- package/esm/datasource-provider/VuuDataSourceProvider.js.map +1 -0
- package/esm/datasource-provider/useAutoLoginToVuuServer.js +50 -0
- package/esm/datasource-provider/useAutoLoginToVuuServer.js.map +1 -0
- package/esm/hooks/useLookupValues.js +98 -0
- package/esm/hooks/useLookupValues.js.map +1 -0
- package/esm/hooks/useSessionDataSource.js +56 -0
- package/esm/hooks/useSessionDataSource.js.map +1 -0
- package/esm/hooks/useTypeaheadSuggestions.js +54 -0
- package/esm/hooks/useTypeaheadSuggestions.js.map +1 -0
- package/esm/hooks/useVisualLinks.js +82 -0
- package/esm/hooks/useVisualLinks.js.map +1 -0
- package/esm/hooks/useVuuMenuActions.js +348 -0
- package/esm/hooks/useVuuMenuActions.js.map +1 -0
- package/esm/hooks/useVuuTables.js +36 -0
- package/esm/hooks/useVuuTables.js.map +1 -0
- package/esm/index.js +16 -0
- package/esm/index.js.map +1 -0
- package/esm/lost-connection-indicator/LostConnectionIndicator.css.js +4 -0
- package/esm/lost-connection-indicator/LostConnectionIndicator.css.js.map +1 -0
- package/esm/lost-connection-indicator/LostConnectionIndicator.js +22 -0
- package/esm/lost-connection-indicator/LostConnectionIndicator.js.map +1 -0
- package/esm/lost-connection-indicator/useLostConnection.js +32 -0
- package/esm/lost-connection-indicator/useLostConnection.js.map +1 -0
- package/esm/session-editing-form/SessionEditingForm.css.js +4 -0
- package/esm/session-editing-form/SessionEditingForm.css.js.map +1 -0
- package/esm/session-editing-form/SessionEditingForm.js +268 -0
- package/esm/session-editing-form/SessionEditingForm.js.map +1 -0
- package/package.json +19 -17
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var vuuUtils = require('@vuu-ui/vuu-utils');
|
|
5
|
+
var core = require('@salt-ds/core');
|
|
6
|
+
var react = require('react');
|
|
7
|
+
var UnsavedChangesReport = require('./UnsavedChangesReport.js');
|
|
8
|
+
var editRuleValidationChecker = require('./edit-rule-validation-checker.js');
|
|
9
|
+
var formEditState = require('./form-edit-state.js');
|
|
10
|
+
var vuuUiControls = require('@vuu-ui/vuu-ui-controls');
|
|
11
|
+
|
|
12
|
+
const CLEAN_VALIDATION = {
|
|
13
|
+
ok: true,
|
|
14
|
+
messages: {}
|
|
15
|
+
};
|
|
16
|
+
const getValidationChecker = (descriptor, editPhase) => {
|
|
17
|
+
const rules = editRuleValidationChecker.getEditValidationRules(descriptor, editPhase) ?? [];
|
|
18
|
+
return editRuleValidationChecker.buildValidationChecker(rules);
|
|
19
|
+
};
|
|
20
|
+
const nextValidationState = (state, dataDescriptor, value) => {
|
|
21
|
+
const check = getValidationChecker(dataDescriptor, "change");
|
|
22
|
+
const result = check(value, "change");
|
|
23
|
+
const { name } = dataDescriptor;
|
|
24
|
+
const { ok: wasOk, messages: existingMessages } = state;
|
|
25
|
+
if (result.ok) {
|
|
26
|
+
if (!wasOk) {
|
|
27
|
+
const fieldsInError = Object.keys(existingMessages);
|
|
28
|
+
if (fieldsInError.includes(name)) {
|
|
29
|
+
if (fieldsInError.length === 1) {
|
|
30
|
+
return { ok: true, messages: {} };
|
|
31
|
+
} else {
|
|
32
|
+
const messages = { ...existingMessages };
|
|
33
|
+
delete messages[name];
|
|
34
|
+
return { ok: false, messages };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
} else {
|
|
39
|
+
return {
|
|
40
|
+
ok: false,
|
|
41
|
+
messages: {
|
|
42
|
+
...existingMessages,
|
|
43
|
+
[name]: result.messages.join("\n")
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
return state;
|
|
48
|
+
};
|
|
49
|
+
function find(descriptors, fieldname) {
|
|
50
|
+
const d = descriptors.find(({ name }) => name === fieldname);
|
|
51
|
+
if (d) {
|
|
52
|
+
return d;
|
|
53
|
+
}
|
|
54
|
+
throw Error(`DataValueDescriptor not found for field ${fieldname}`);
|
|
55
|
+
}
|
|
56
|
+
const getField = (target) => {
|
|
57
|
+
const fieldElement = vuuUtils.queryClosest(target, "[data-field]");
|
|
58
|
+
if (fieldElement) {
|
|
59
|
+
return fieldElement.dataset.field;
|
|
60
|
+
} else {
|
|
61
|
+
throw Error("no field ");
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const useEditForm = ({
|
|
65
|
+
dataSource,
|
|
66
|
+
formFieldDescriptors,
|
|
67
|
+
onSubmit
|
|
68
|
+
}) => {
|
|
69
|
+
const { showDialog, closeDialog } = vuuUiControls.useModal();
|
|
70
|
+
const currentDataSource = react.useRef(void 0);
|
|
71
|
+
const formFieldsContainerRef = react.useRef(null);
|
|
72
|
+
const entityRef = react.useRef(void 0);
|
|
73
|
+
const focusedFieldRef = react.useRef("");
|
|
74
|
+
const originalEntityRef = react.useRef(void 0);
|
|
75
|
+
const formEditStateRef = react.useRef(formEditState.CLEAN_FORM);
|
|
76
|
+
const validationStateRef = react.useRef({
|
|
77
|
+
ok: true,
|
|
78
|
+
messages: {}
|
|
79
|
+
});
|
|
80
|
+
const [entity, _setEntity] = react.useState();
|
|
81
|
+
const [, forceUpdate] = react.useState({});
|
|
82
|
+
const setFormEditState = react.useCallback((newState) => {
|
|
83
|
+
formEditStateRef.current = newState;
|
|
84
|
+
}, []);
|
|
85
|
+
const setEntity = react.useCallback(
|
|
86
|
+
(newEntity) => {
|
|
87
|
+
setFormEditState(
|
|
88
|
+
formEditState.buildFormEditState(originalEntityRef.current, newEntity)
|
|
89
|
+
);
|
|
90
|
+
entityRef.current = newEntity;
|
|
91
|
+
_setEntity(newEntity);
|
|
92
|
+
},
|
|
93
|
+
[setFormEditState]
|
|
94
|
+
);
|
|
95
|
+
const submitChanges = react.useCallback(async () => {
|
|
96
|
+
const rpcResponse = await currentDataSource.current?.rpcRequest?.({
|
|
97
|
+
params: {},
|
|
98
|
+
rpcName: "VP_BULK_EDIT_SUBMIT_RPC",
|
|
99
|
+
type: "RPC_REQUEST"
|
|
100
|
+
});
|
|
101
|
+
console.log({ rpcResponse });
|
|
102
|
+
}, []);
|
|
103
|
+
const showSaveOrDiscardPrompt = react.useCallback(async () => {
|
|
104
|
+
const { current: currentEntity } = entityRef;
|
|
105
|
+
const { current: originalEntity } = originalEntityRef;
|
|
106
|
+
let resolver = void 0;
|
|
107
|
+
const save = async () => {
|
|
108
|
+
await submitChanges();
|
|
109
|
+
closeDialog();
|
|
110
|
+
resolver?.("saved");
|
|
111
|
+
};
|
|
112
|
+
const discard = () => {
|
|
113
|
+
closeDialog();
|
|
114
|
+
resolver?.("discarded");
|
|
115
|
+
};
|
|
116
|
+
requestAnimationFrame(() => {
|
|
117
|
+
showDialog(
|
|
118
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
119
|
+
UnsavedChangesReport.UnsavedChangesReport,
|
|
120
|
+
{
|
|
121
|
+
entity: originalEntity,
|
|
122
|
+
editedEntity: currentEntity
|
|
123
|
+
}
|
|
124
|
+
),
|
|
125
|
+
"Unsaved Changes",
|
|
126
|
+
[
|
|
127
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Button, { onClick: discard, children: "Discard Changes" }, "cancel"),
|
|
128
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Button, { onClick: save, children: "Save Changes" }, "submit")
|
|
129
|
+
],
|
|
130
|
+
true
|
|
131
|
+
// hideCloseButton
|
|
132
|
+
);
|
|
133
|
+
});
|
|
134
|
+
return new Promise((resolve) => {
|
|
135
|
+
resolver = resolve;
|
|
136
|
+
});
|
|
137
|
+
}, [closeDialog, showDialog, submitChanges]);
|
|
138
|
+
react.useMemo(async () => {
|
|
139
|
+
if (dataSource) {
|
|
140
|
+
if (formEditStateRef.current.isClean === false) {
|
|
141
|
+
await showSaveOrDiscardPrompt();
|
|
142
|
+
}
|
|
143
|
+
currentDataSource.current = dataSource;
|
|
144
|
+
originalEntityRef.current = void 0;
|
|
145
|
+
const columnMap = vuuUtils.buildColumnMap(dataSource.columns);
|
|
146
|
+
dataSource?.subscribe({ range: vuuUtils.Range(0, 1) }, (message) => {
|
|
147
|
+
if (vuuUtils.messageHasDataRows(message)) {
|
|
148
|
+
const [row] = message.rows;
|
|
149
|
+
if (row) {
|
|
150
|
+
const entity2 = vuuUtils.dataSourceRowToEntity(row, columnMap);
|
|
151
|
+
if (originalEntityRef.current === void 0) {
|
|
152
|
+
originalEntityRef.current = entity2;
|
|
153
|
+
setEntity(entity2);
|
|
154
|
+
}
|
|
155
|
+
const { editedFields: editedFields2 } = formEditState.buildFormEditState(
|
|
156
|
+
entityRef.current,
|
|
157
|
+
entity2
|
|
158
|
+
);
|
|
159
|
+
if (editedFields2.length === 1) {
|
|
160
|
+
setEntity(entity2);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}, [dataSource, setEntity, showSaveOrDiscardPrompt]);
|
|
167
|
+
const setValidationState = react.useCallback((state) => {
|
|
168
|
+
validationStateRef.current = state;
|
|
169
|
+
forceUpdate({});
|
|
170
|
+
}, []);
|
|
171
|
+
const handleFieldCommit = react.useCallback(
|
|
172
|
+
async (_, value) => {
|
|
173
|
+
const { current: fieldName } = focusedFieldRef;
|
|
174
|
+
const dataDescriptor = find(formFieldDescriptors, fieldName);
|
|
175
|
+
const { current: state } = validationStateRef;
|
|
176
|
+
const newState = nextValidationState(state, dataDescriptor, value);
|
|
177
|
+
if (newState !== state) {
|
|
178
|
+
setValidationState(newState);
|
|
179
|
+
}
|
|
180
|
+
if (newState.ok && dataSource?.tableSchema) {
|
|
181
|
+
const { key } = dataSource.tableSchema;
|
|
182
|
+
const keyValue = entity?.[key];
|
|
183
|
+
const response = await dataSource.rpcRequest?.({
|
|
184
|
+
params: {
|
|
185
|
+
column: fieldName,
|
|
186
|
+
data: value,
|
|
187
|
+
key: keyValue
|
|
188
|
+
},
|
|
189
|
+
rpcName: "editCell",
|
|
190
|
+
type: "RPC_REQUEST"
|
|
191
|
+
});
|
|
192
|
+
console.log({ response });
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
[dataSource, entity, formFieldDescriptors, setValidationState]
|
|
196
|
+
);
|
|
197
|
+
const handleFieldChange = react.useCallback(
|
|
198
|
+
(evt) => {
|
|
199
|
+
const { current: fieldName } = focusedFieldRef;
|
|
200
|
+
if (fieldName) {
|
|
201
|
+
const input = vuuUtils.queryClosest(evt.target, "input", true);
|
|
202
|
+
const dataDescriptor = find(formFieldDescriptors, fieldName);
|
|
203
|
+
const value = input.value;
|
|
204
|
+
const { current: state } = validationStateRef;
|
|
205
|
+
const newState = nextValidationState(state, dataDescriptor, value);
|
|
206
|
+
if (newState !== state) {
|
|
207
|
+
setValidationState(newState);
|
|
208
|
+
}
|
|
209
|
+
setEntity({ ...entity, [fieldName]: value });
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
[entity, formFieldDescriptors, setEntity, setValidationState]
|
|
213
|
+
);
|
|
214
|
+
const handleFormSubmit = react.useCallback(async () => {
|
|
215
|
+
submitChanges();
|
|
216
|
+
setFormEditState(formEditState.CLEAN_FORM);
|
|
217
|
+
originalEntityRef.current = entity;
|
|
218
|
+
onSubmit?.();
|
|
219
|
+
forceUpdate({});
|
|
220
|
+
}, [entity, onSubmit, setFormEditState, submitChanges]);
|
|
221
|
+
const handleFormCancel = react.useCallback(async () => {
|
|
222
|
+
setFormEditState(formEditState.CLEAN_FORM);
|
|
223
|
+
setValidationState(CLEAN_VALIDATION);
|
|
224
|
+
setEntity(originalEntityRef.current);
|
|
225
|
+
}, [setEntity, setFormEditState, setValidationState]);
|
|
226
|
+
const handleFocus = react.useCallback((evt) => {
|
|
227
|
+
if (formFieldsContainerRef.current?.contains(evt.target)) {
|
|
228
|
+
const fieldName = getField(evt.target);
|
|
229
|
+
if (fieldName) {
|
|
230
|
+
if (fieldName) {
|
|
231
|
+
focusedFieldRef.current = fieldName;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}, []);
|
|
236
|
+
const {
|
|
237
|
+
current: { ok, messages: errorMessages }
|
|
238
|
+
} = validationStateRef;
|
|
239
|
+
const {
|
|
240
|
+
current: { isClean, editedFields }
|
|
241
|
+
} = formEditStateRef;
|
|
242
|
+
return {
|
|
243
|
+
editedFields,
|
|
244
|
+
editEntity: entity,
|
|
245
|
+
errorMessages,
|
|
246
|
+
formFieldsContainerRef,
|
|
247
|
+
isClean,
|
|
248
|
+
ok,
|
|
249
|
+
onCancel: handleFormCancel,
|
|
250
|
+
onChange: handleFieldChange,
|
|
251
|
+
onCommit: handleFieldCommit,
|
|
252
|
+
onFocus: handleFocus,
|
|
253
|
+
onSubmit: handleFormSubmit
|
|
254
|
+
};
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
exports.useEditForm = useEditForm;
|
|
258
|
+
//# sourceMappingURL=useEditForm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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":["getEditValidationRules","buildValidationChecker","queryClosest","useModal","useRef","CLEAN_FORM","useState","useCallback","buildFormEditState","jsx","UnsavedChangesReport","Button","useMemo","buildColumnMap","Range","messageHasDataRows","entity","dataSourceRowToEntity","editedFields"],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var vuuDataRemote = require('@vuu-ui/vuu-data-remote');
|
|
5
|
+
var vuuUtils = require('@vuu-ui/vuu-utils');
|
|
6
|
+
var useAutoLoginToVuuServer = require('./useAutoLoginToVuuServer.js');
|
|
7
|
+
|
|
8
|
+
const getServerAPI = () => vuuDataRemote.ConnectionManager.serverAPI;
|
|
9
|
+
const VuuDataSourceProvider = ({
|
|
10
|
+
authenticate,
|
|
11
|
+
autoConnect = false,
|
|
12
|
+
autoLogin = false,
|
|
13
|
+
children,
|
|
14
|
+
websocketUrl
|
|
15
|
+
}) => {
|
|
16
|
+
useAutoLoginToVuuServer.useAutoLoginToVuuServer({
|
|
17
|
+
authenticate,
|
|
18
|
+
autoConnect,
|
|
19
|
+
autoLogin,
|
|
20
|
+
websocketUrl
|
|
21
|
+
});
|
|
22
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
23
|
+
vuuUtils.DataProvider,
|
|
24
|
+
{
|
|
25
|
+
VuuDataSource: vuuDataRemote.VuuDataSource,
|
|
26
|
+
getServerAPI,
|
|
27
|
+
isLocalData: false,
|
|
28
|
+
children
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
exports.VuuDataSourceProvider = VuuDataSourceProvider;
|
|
34
|
+
//# sourceMappingURL=VuuDataSourceProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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\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":["ConnectionManager","useAutoLoginToVuuServer","jsx","DataProvider","VuuDataSource"],"mappings":";;;;;;;AAKA,MAAM,YAAA,GAAe,MAAMA,+BAAkB,CAAA,SAAA;AAEtC,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,EAAwBC,+CAAA,CAAA;AAAA,IACtB,YAAA;AAAA,IACA,WAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EACE,uBAAAC,cAAA;AAAA,IAACC,qBAAA;AAAA,IAAA;AAAA,qBACCC,2BAAA;AAAA,MACA,YAAA;AAAA,MACA,WAAa,EAAA,KAAA;AAAA,MAEZ;AAAA;AAAA,GACH;AAEJ;;;;"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var vuuDataRemote = require('@vuu-ui/vuu-data-remote');
|
|
5
|
+
var react = require('react');
|
|
6
|
+
|
|
7
|
+
const useAutoLoginToVuuServer = ({
|
|
8
|
+
authenticate = true,
|
|
9
|
+
autoConnect = true,
|
|
10
|
+
// autoLogin = true,
|
|
11
|
+
secure = true,
|
|
12
|
+
token: tokenProp = "no-token",
|
|
13
|
+
user = "steve",
|
|
14
|
+
websocketUrl
|
|
15
|
+
} = {}) => {
|
|
16
|
+
const [errorMessage, setErrorMessage] = react.useState("");
|
|
17
|
+
react.useEffect(() => {
|
|
18
|
+
const connect = async () => {
|
|
19
|
+
try {
|
|
20
|
+
let token = tokenProp;
|
|
21
|
+
if (authenticate) {
|
|
22
|
+
const response = await vuuDataRemote.authenticate(user, "xyz", "/api/authn");
|
|
23
|
+
token = response.token;
|
|
24
|
+
}
|
|
25
|
+
const url = websocketUrl ?? `${secure ? "wss" : "ws"}://localhost/8090/websocket`;
|
|
26
|
+
vuuDataRemote.ConnectionManager.connect({
|
|
27
|
+
url,
|
|
28
|
+
token
|
|
29
|
+
});
|
|
30
|
+
} catch (e) {
|
|
31
|
+
if (e instanceof Error) {
|
|
32
|
+
console.error(e.message);
|
|
33
|
+
setErrorMessage(e.message);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
if (autoConnect) {
|
|
38
|
+
connect();
|
|
39
|
+
}
|
|
40
|
+
return () => {
|
|
41
|
+
if (autoConnect) {
|
|
42
|
+
vuuDataRemote.ConnectionManager.disconnect();
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}, [authenticate, autoConnect, secure, tokenProp, user, websocketUrl]);
|
|
46
|
+
if (errorMessage) {
|
|
47
|
+
return /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Unable to authenticate against Vuu Server A Vuu Server instance must be running to show this example." });
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
exports.useAutoLoginToVuuServer = useAutoLoginToVuuServer;
|
|
52
|
+
//# sourceMappingURL=useAutoLoginToVuuServer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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":["useState","useEffect","vuuAuthenticate","ConnectionManager","jsx"],"mappings":";;;;;;AAMO,MAAM,0BAA0B,CAAC;AAAA,EACtC,YAAe,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,GAAIA,eAAS,EAAE,CAAA;AACnD,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,MAAM,UAAU,YAAY;AAC1B,MAAI,IAAA;AACF,QAAA,IAAI,KAAQ,GAAA,SAAA;AACZ,QAAA,IAAI,YAAc,EAAA;AAChB,UAAA,MAAM,QAAW,GAAA,MAAMC,0BAAgB,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,QAAAC,+BAAA,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,QAAAA,+BAAA,CAAkB,UAAW,EAAA;AAAA;AAC/B,KACF;AAAA,GACF,EAAG,CAAC,YAAc,EAAA,WAAA,EAAa,QAAQ,SAAW,EAAA,IAAA,EAAM,YAAY,CAAC,CAAA;AAErE,EAAA,IAAI,YAAc,EAAA;AAChB,IACE,uBAAAC,cAAA,CAAC,OAAE,QAGH,EAAA,uGAAA,EAAA,CAAA;AAAA;AAGN;;;;"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var vuuDataRemote = require('@vuu-ui/vuu-data-remote');
|
|
4
|
+
var vuuUtils = require('@vuu-ui/vuu-utils');
|
|
5
|
+
var react = require('react');
|
|
6
|
+
|
|
7
|
+
const NO_VALUES = [];
|
|
8
|
+
const toListOption = (value) => ({
|
|
9
|
+
label: value,
|
|
10
|
+
value
|
|
11
|
+
});
|
|
12
|
+
const lookupValueMap = /* @__PURE__ */ new Map();
|
|
13
|
+
const loadLookupValues = ({
|
|
14
|
+
labelColumn,
|
|
15
|
+
table,
|
|
16
|
+
valueColumn
|
|
17
|
+
}) => {
|
|
18
|
+
const tableKey = `${table.module}:${table.table}`;
|
|
19
|
+
const lookupValues = lookupValueMap.get(tableKey);
|
|
20
|
+
if (lookupValues) {
|
|
21
|
+
return lookupValues;
|
|
22
|
+
} else {
|
|
23
|
+
const promise = new Promise((resolve) => {
|
|
24
|
+
const columns = [valueColumn, labelColumn];
|
|
25
|
+
const columnMap = vuuUtils.buildColumnMap(columns);
|
|
26
|
+
const dataSource = new vuuDataRemote.VuuDataSource({
|
|
27
|
+
bufferSize: 0,
|
|
28
|
+
table
|
|
29
|
+
});
|
|
30
|
+
dataSource.subscribe(
|
|
31
|
+
{
|
|
32
|
+
columns,
|
|
33
|
+
range: vuuUtils.Range(0, 100)
|
|
34
|
+
},
|
|
35
|
+
(message) => {
|
|
36
|
+
if (message.type === "viewport-update") {
|
|
37
|
+
if (message.rows) {
|
|
38
|
+
const listOptions = message.rows.map((row) => ({
|
|
39
|
+
value: row[columnMap[valueColumn]],
|
|
40
|
+
label: row[columnMap[labelColumn]]
|
|
41
|
+
}));
|
|
42
|
+
resolve(listOptions);
|
|
43
|
+
dataSource.unsubscribe();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
});
|
|
49
|
+
lookupValueMap.set(tableKey, promise);
|
|
50
|
+
return promise;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const getLookupDetails = ({ name, type }) => {
|
|
54
|
+
if (vuuUtils.isTypeDescriptor(type) && vuuUtils.isLookupRenderer(type.renderer)) {
|
|
55
|
+
return type.renderer.lookup;
|
|
56
|
+
} else {
|
|
57
|
+
throw Error(
|
|
58
|
+
`useLookupValues column ${name} is not configured to use lookup values`
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const useLookupValues = (column, initialValueProp) => {
|
|
63
|
+
const { type: columnType } = column;
|
|
64
|
+
const { getLookupValues } = vuuUtils.useShellContext();
|
|
65
|
+
const initialState = react.useMemo(() => {
|
|
66
|
+
if (vuuUtils.isTypeDescriptor(columnType) && vuuUtils.isValueListRenderer(columnType?.renderer)) {
|
|
67
|
+
const values2 = columnType.renderer.values.map(toListOption);
|
|
68
|
+
return {
|
|
69
|
+
initialValue: vuuUtils.getSelectedOption(values2, initialValueProp) ?? null,
|
|
70
|
+
values: values2
|
|
71
|
+
};
|
|
72
|
+
} else {
|
|
73
|
+
const lookupDetails = getLookupDetails(column);
|
|
74
|
+
const values2 = getLookupValues?.(lookupDetails.table) ?? NO_VALUES;
|
|
75
|
+
return {
|
|
76
|
+
initialValue: vuuUtils.getSelectedOption(values2, initialValueProp) ?? null,
|
|
77
|
+
values: values2
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}, [column, columnType, getLookupValues, initialValueProp]);
|
|
81
|
+
const [{ initialValue, values }, setLookupState] = react.useState(initialState);
|
|
82
|
+
react.useMemo(() => {
|
|
83
|
+
if (values === NO_VALUES) {
|
|
84
|
+
const lookupDetails = getLookupDetails(column);
|
|
85
|
+
loadLookupValues(lookupDetails).then(
|
|
86
|
+
(values2) => setLookupState({
|
|
87
|
+
initialValue: vuuUtils.getSelectedOption(values2, initialValueProp) ?? null,
|
|
88
|
+
values: values2
|
|
89
|
+
})
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
}, [values, column, initialValueProp]);
|
|
93
|
+
return {
|
|
94
|
+
initialValue,
|
|
95
|
+
values
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
exports.useLookupValues = useLookupValues;
|
|
100
|
+
//# sourceMappingURL=useLookupValues.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useLookupValues.js","sources":["../../../../packages/vuu-data-react/src/hooks/useLookupValues.ts"],"sourcesContent":["import {\n ColumnDescriptor,\n ListOption,\n LookupTableDetails,\n} from \"@vuu-ui/vuu-table-types\";\nimport { VuuDataSource } from \"@vuu-ui/vuu-data-remote\";\nimport {\n buildColumnMap,\n getSelectedOption,\n isLookupRenderer,\n isTypeDescriptor,\n isValueListRenderer,\n Range,\n useShellContext,\n} from \"@vuu-ui/vuu-utils\";\nimport { useMemo, useState } from \"react\";\n\nconst NO_VALUES: ListOption[] = [];\n\nconst toListOption = (value: string): ListOption => ({\n label: value,\n value,\n});\n\nconst lookupValueMap = new Map<string, Promise<ListOption[]>>();\n\nconst loadLookupValues = ({\n labelColumn,\n table,\n valueColumn,\n}: LookupTableDetails): Promise<ListOption[]> => {\n const tableKey = `${table.module}:${table.table}`;\n const lookupValues = lookupValueMap.get(tableKey);\n if (lookupValues) {\n return lookupValues;\n } else {\n const promise: Promise<ListOption[]> = new Promise((resolve) => {\n const columns = [valueColumn, labelColumn];\n const columnMap = buildColumnMap(columns);\n const dataSource = new VuuDataSource({\n bufferSize: 0,\n table,\n });\n dataSource.subscribe(\n {\n columns,\n range: Range(0, 100),\n },\n (message) => {\n if (message.type === \"viewport-update\") {\n //TODO check we have full dataset\n if (message.rows) {\n const listOptions = message.rows.map<ListOption>((row) => ({\n value: row[columnMap[valueColumn]] as string | number,\n label: row[columnMap[labelColumn]] as string,\n }));\n resolve(listOptions);\n dataSource.unsubscribe();\n }\n }\n },\n );\n });\n lookupValueMap.set(tableKey, promise);\n return promise;\n }\n};\n\ntype LookupState = {\n initialValue: ListOption | null;\n values: ListOption[];\n};\n\nconst getLookupDetails = ({ name, type }: ColumnDescriptor) => {\n if (isTypeDescriptor(type) && isLookupRenderer(type.renderer)) {\n return type.renderer.lookup;\n } else {\n throw Error(\n `useLookupValues column ${name} is not configured to use lookup values`,\n );\n }\n};\n\nexport const useLookupValues = (\n column: ColumnDescriptor,\n initialValueProp: number | string,\n) => {\n const { type: columnType } = column;\n const { getLookupValues } = useShellContext();\n\n const initialState = useMemo<LookupState>(() => {\n if (\n isTypeDescriptor(columnType) &&\n isValueListRenderer(columnType?.renderer)\n ) {\n const values = columnType.renderer.values.map(toListOption);\n return {\n initialValue: getSelectedOption(values, initialValueProp) ?? null,\n values,\n };\n } else {\n const lookupDetails = getLookupDetails(column);\n const values = getLookupValues?.(lookupDetails.table) ?? NO_VALUES;\n\n return {\n initialValue: getSelectedOption(values, initialValueProp) ?? null,\n values,\n };\n }\n }, [column, columnType, getLookupValues, initialValueProp]);\n\n const [{ initialValue, values }, setLookupState] =\n useState<LookupState>(initialState);\n\n useMemo(() => {\n if (values === NO_VALUES) {\n const lookupDetails = getLookupDetails(column);\n loadLookupValues(lookupDetails).then((values) =>\n setLookupState({\n initialValue: getSelectedOption(values, initialValueProp) ?? null,\n values,\n }),\n );\n }\n }, [values, column, initialValueProp]);\n\n return {\n initialValue,\n values,\n };\n};\n"],"names":["buildColumnMap","VuuDataSource","Range","isTypeDescriptor","isLookupRenderer","useShellContext","useMemo","isValueListRenderer","values","getSelectedOption","useState"],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var vuuUtils = require('@vuu-ui/vuu-utils');
|
|
4
|
+
var react = require('react');
|
|
5
|
+
|
|
6
|
+
const sessionState = /* @__PURE__ */ new Map();
|
|
7
|
+
const useSessionDataSource = (props) => {
|
|
8
|
+
const { VuuDataSource } = vuuUtils.useData();
|
|
9
|
+
const dataSourceConfigRef = react.useRef(void 0);
|
|
10
|
+
const getDataSource = react.useCallback(
|
|
11
|
+
(sessionKey, dataSourceConstructorProps) => {
|
|
12
|
+
let ds = sessionState.get(sessionKey);
|
|
13
|
+
if (ds) {
|
|
14
|
+
return ds;
|
|
15
|
+
}
|
|
16
|
+
if (dataSourceConstructorProps?.columns) {
|
|
17
|
+
ds = new VuuDataSource({
|
|
18
|
+
...dataSourceConstructorProps,
|
|
19
|
+
viewport: sessionKey,
|
|
20
|
+
...dataSourceConfigRef.current
|
|
21
|
+
});
|
|
22
|
+
if (props?.onConfigChange) {
|
|
23
|
+
ds.on("config", props.onConfigChange);
|
|
24
|
+
}
|
|
25
|
+
sessionState.set(sessionKey, ds);
|
|
26
|
+
return ds;
|
|
27
|
+
} else {
|
|
28
|
+
throw Error(
|
|
29
|
+
`[useSessionDataSource] unable to create new DataSource, columns have not been defined `
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
[VuuDataSource, props?.onConfigChange]
|
|
34
|
+
);
|
|
35
|
+
const clearDataSource = react.useCallback(
|
|
36
|
+
(sessionKey, unsubscribe) => {
|
|
37
|
+
const ds = sessionState.get(sessionKey);
|
|
38
|
+
if (ds) {
|
|
39
|
+
sessionState.delete(sessionKey);
|
|
40
|
+
if (unsubscribe === true) {
|
|
41
|
+
ds.unsubscribe();
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
console.warn(
|
|
45
|
+
`[useSessionbDatasource] clearDataSource ${sessionKey} not found `
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
[]
|
|
50
|
+
);
|
|
51
|
+
return {
|
|
52
|
+
clearDataSource,
|
|
53
|
+
getDataSource
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
exports.useSessionDataSource = useSessionDataSource;
|
|
58
|
+
//# sourceMappingURL=useSessionDataSource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSessionDataSource.js","sources":["../../../../packages/vuu-data-react/src/hooks/useSessionDataSource.ts"],"sourcesContent":["import type {\n DataSource,\n DataSourceConfig,\n DataSourceConfigChangeHandler,\n DataSourceConstructorProps,\n} from \"@vuu-ui/vuu-data-types\";\nimport { useData } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useRef } from \"react\";\n\nconst sessionState = new Map<string, DataSource>();\n\nexport interface SessionStateHookProps {\n onConfigChange?: DataSourceConfigChangeHandler;\n}\n\nexport const useSessionDataSource = (props?: SessionStateHookProps) => {\n const { VuuDataSource } = useData();\n\n const dataSourceConfigRef = useRef<DataSourceConfig | undefined>(undefined);\n\n const getDataSource = useCallback(\n (\n sessionKey: string,\n dataSourceConstructorProps?: DataSourceConstructorProps,\n ) => {\n let ds = sessionState.get(sessionKey);\n if (ds) {\n return ds;\n }\n\n if (dataSourceConstructorProps?.columns) {\n ds = new VuuDataSource({\n ...dataSourceConstructorProps,\n viewport: sessionKey,\n ...dataSourceConfigRef.current,\n });\n if (props?.onConfigChange) {\n ds.on(\"config\", props.onConfigChange);\n }\n sessionState.set(sessionKey, ds);\n return ds;\n } else {\n throw Error(\n `[useSessionDataSource] unable to create new DataSource, columns have not been defined `,\n );\n }\n },\n [VuuDataSource, props?.onConfigChange],\n );\n\n const clearDataSource = useCallback(\n (sessionKey: string, unsubscribe?: boolean) => {\n const ds = sessionState.get(sessionKey);\n if (ds) {\n sessionState.delete(sessionKey);\n if (unsubscribe === true) {\n ds.unsubscribe();\n }\n } else {\n console.warn(\n `[useSessionbDatasource] clearDataSource ${sessionKey} not found `,\n );\n }\n },\n [],\n );\n\n return {\n clearDataSource,\n getDataSource,\n };\n};\n"],"names":["useData","useRef","useCallback"],"mappings":";;;;;AASA,MAAM,YAAA,uBAAmB,GAAwB,EAAA;AAMpC,MAAA,oBAAA,GAAuB,CAAC,KAAkC,KAAA;AACrE,EAAM,MAAA,EAAE,aAAc,EAAA,GAAIA,gBAAQ,EAAA;AAElC,EAAM,MAAA,mBAAA,GAAsBC,aAAqC,KAAS,CAAA,CAAA;AAE1E,EAAA,MAAM,aAAgB,GAAAC,iBAAA;AAAA,IACpB,CACE,YACA,0BACG,KAAA;AACH,MAAI,IAAA,EAAA,GAAK,YAAa,CAAA,GAAA,CAAI,UAAU,CAAA;AACpC,MAAA,IAAI,EAAI,EAAA;AACN,QAAO,OAAA,EAAA;AAAA;AAGT,MAAA,IAAI,4BAA4B,OAAS,EAAA;AACvC,QAAA,EAAA,GAAK,IAAI,aAAc,CAAA;AAAA,UACrB,GAAG,0BAAA;AAAA,UACH,QAAU,EAAA,UAAA;AAAA,UACV,GAAG,mBAAoB,CAAA;AAAA,SACxB,CAAA;AACD,QAAA,IAAI,OAAO,cAAgB,EAAA;AACzB,UAAG,EAAA,CAAA,EAAA,CAAG,QAAU,EAAA,KAAA,CAAM,cAAc,CAAA;AAAA;AAEtC,QAAa,YAAA,CAAA,GAAA,CAAI,YAAY,EAAE,CAAA;AAC/B,QAAO,OAAA,EAAA;AAAA,OACF,MAAA;AACL,QAAM,MAAA,KAAA;AAAA,UACJ,CAAA,sFAAA;AAAA,SACF;AAAA;AACF,KACF;AAAA,IACA,CAAC,aAAe,EAAA,KAAA,EAAO,cAAc;AAAA,GACvC;AAEA,EAAA,MAAM,eAAkB,GAAAA,iBAAA;AAAA,IACtB,CAAC,YAAoB,WAA0B,KAAA;AAC7C,MAAM,MAAA,EAAA,GAAK,YAAa,CAAA,GAAA,CAAI,UAAU,CAAA;AACtC,MAAA,IAAI,EAAI,EAAA;AACN,QAAA,YAAA,CAAa,OAAO,UAAU,CAAA;AAC9B,QAAA,IAAI,gBAAgB,IAAM,EAAA;AACxB,UAAA,EAAA,CAAG,WAAY,EAAA;AAAA;AACjB,OACK,MAAA;AACL,QAAQ,OAAA,CAAA,IAAA;AAAA,UACN,2CAA2C,UAAU,CAAA,WAAA;AAAA,SACvD;AAAA;AACF,KACF;AAAA,IACA;AAAC,GACH;AAEA,EAAO,OAAA;AAAA,IACL,eAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var vuuUtils = require('@vuu-ui/vuu-utils');
|
|
4
|
+
var react = require('react');
|
|
5
|
+
|
|
6
|
+
const getTypeaheadParams = (table, column, text = "", selectedValues = []) => {
|
|
7
|
+
if (text !== "" && !selectedValues.includes(text.toLowerCase())) {
|
|
8
|
+
return [table, column, text];
|
|
9
|
+
}
|
|
10
|
+
return [table, column];
|
|
11
|
+
};
|
|
12
|
+
const useTypeaheadSuggestions = () => {
|
|
13
|
+
const dataSource = vuuUtils.useDataSource(false);
|
|
14
|
+
return react.useCallback(
|
|
15
|
+
async ([{ module, table }, column, starts]) => {
|
|
16
|
+
if (dataSource === void 0) {
|
|
17
|
+
console.warn(
|
|
18
|
+
`[useTypeaheadSuggestions] no dataSource provided (use DataSourceProvider)`
|
|
19
|
+
);
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
const rpcMessage = starts === void 0 ? {
|
|
23
|
+
params: {
|
|
24
|
+
column,
|
|
25
|
+
module,
|
|
26
|
+
table
|
|
27
|
+
},
|
|
28
|
+
rpcName: "getUniqueFieldValues",
|
|
29
|
+
type: "RPC_REQUEST"
|
|
30
|
+
} : {
|
|
31
|
+
params: {
|
|
32
|
+
column,
|
|
33
|
+
module,
|
|
34
|
+
starts,
|
|
35
|
+
table
|
|
36
|
+
},
|
|
37
|
+
rpcName: "getUniqueFieldValuesStartingWith",
|
|
38
|
+
type: "RPC_REQUEST"
|
|
39
|
+
};
|
|
40
|
+
try {
|
|
41
|
+
const response = await dataSource.rpcRequest?.(rpcMessage);
|
|
42
|
+
if (response?.type === "SUCCESS_RESULT") {
|
|
43
|
+
return response.data;
|
|
44
|
+
} else {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
} catch (err) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
[dataSource]
|
|
52
|
+
);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
exports.getTypeaheadParams = getTypeaheadParams;
|
|
56
|
+
exports.useTypeaheadSuggestions = useTypeaheadSuggestions;
|
|
57
|
+
//# sourceMappingURL=useTypeaheadSuggestions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTypeaheadSuggestions.js","sources":["../../../../packages/vuu-data-react/src/hooks/useTypeaheadSuggestions.ts"],"sourcesContent":["import { SuggestionFetcher, TableSchemaTable } from \"@vuu-ui/vuu-data-types\";\nimport {\n TypeaheadParams,\n VuuRpcServiceRequest,\n} from \"@vuu-ui/vuu-protocol-types\";\nimport { useDataSource } from \"@vuu-ui/vuu-utils\";\nimport { useCallback } from \"react\";\n\nexport const getTypeaheadParams = (\n table: TableSchemaTable,\n column: string,\n text = \"\",\n selectedValues: string[] = [],\n): TypeaheadParams => {\n if (text !== \"\" && !selectedValues.includes(text.toLowerCase())) {\n return [table, column, text];\n }\n return [table, column];\n};\n\nexport const useTypeaheadSuggestions = () => {\n const dataSource = useDataSource(false);\n return useCallback<SuggestionFetcher>(\n async ([{ module, table }, column, starts]: TypeaheadParams) => {\n if (dataSource === undefined) {\n console.warn(\n `[useTypeaheadSuggestions] no dataSource provided (use DataSourceProvider)`,\n );\n return false;\n }\n const rpcMessage: Omit<VuuRpcServiceRequest, \"context\"> =\n starts === undefined\n ? {\n params: {\n column,\n module,\n table,\n },\n rpcName: \"getUniqueFieldValues\",\n type: \"RPC_REQUEST\",\n }\n : {\n params: {\n column,\n module,\n starts,\n table,\n },\n rpcName: \"getUniqueFieldValuesStartingWith\",\n type: \"RPC_REQUEST\",\n };\n\n try {\n // We don't just return rpcCall . In the case of an\n // error we will be returning the rejected promise, bypassing\n // the catch block below.\n const response = await dataSource.rpcRequest?.(rpcMessage);\n if (response?.type === \"SUCCESS_RESULT\") {\n return response.data as string[];\n } else {\n return false;\n }\n } catch (err) {\n return false;\n }\n },\n [dataSource],\n );\n};\n"],"names":["useDataSource","useCallback"],"mappings":";;;;;AAQa,MAAA,kBAAA,GAAqB,CAChC,KACA,EAAA,MAAA,EACA,OAAO,EACP,EAAA,cAAA,GAA2B,EACP,KAAA;AACpB,EAAI,IAAA,IAAA,KAAS,MAAM,CAAC,cAAA,CAAe,SAAS,IAAK,CAAA,WAAA,EAAa,CAAG,EAAA;AAC/D,IAAO,OAAA,CAAC,KAAO,EAAA,MAAA,EAAQ,IAAI,CAAA;AAAA;AAE7B,EAAO,OAAA,CAAC,OAAO,MAAM,CAAA;AACvB;AAEO,MAAM,0BAA0B,MAAM;AAC3C,EAAM,MAAA,UAAA,GAAaA,uBAAc,KAAK,CAAA;AACtC,EAAO,OAAAC,iBAAA;AAAA,IACL,OAAO,CAAC,EAAE,MAAA,EAAQ,OAAS,EAAA,MAAA,EAAQ,MAAM,CAAuB,KAAA;AAC9D,MAAA,IAAI,eAAe,KAAW,CAAA,EAAA;AAC5B,QAAQ,OAAA,CAAA,IAAA;AAAA,UACN,CAAA,yEAAA;AAAA,SACF;AACA,QAAO,OAAA,KAAA;AAAA;AAET,MAAM,MAAA,UAAA,GACJ,WAAW,KACP,CAAA,GAAA;AAAA,QACE,MAAQ,EAAA;AAAA,UACN,MAAA;AAAA,UACA,MAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,OAAS,EAAA,sBAAA;AAAA,QACT,IAAM,EAAA;AAAA,OAER,GAAA;AAAA,QACE,MAAQ,EAAA;AAAA,UACN,MAAA;AAAA,UACA,MAAA;AAAA,UACA,MAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,OAAS,EAAA,kCAAA;AAAA,QACT,IAAM,EAAA;AAAA,OACR;AAEN,MAAI,IAAA;AAIF,QAAA,MAAM,QAAW,GAAA,MAAM,UAAW,CAAA,UAAA,GAAa,UAAU,CAAA;AACzD,QAAI,IAAA,QAAA,EAAU,SAAS,gBAAkB,EAAA;AACvC,UAAA,OAAO,QAAS,CAAA,IAAA;AAAA,SACX,MAAA;AACL,UAAO,OAAA,KAAA;AAAA;AACT,eACO,GAAK,EAAA;AACZ,QAAO,OAAA,KAAA;AAAA;AACT,KACF;AAAA,IACA,CAAC,UAAU;AAAA,GACb;AACF;;;;;"}
|