@vuu-ui/vuu-data-react 0.8.31 → 0.8.32-debug
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/index.js +594 -1
- package/cjs/index.js.map +2 -2
- package/esm/index.js +580 -1
- package/esm/index.js.map +2 -2
- package/package.json +11 -11
- package/LICENSE +0 -201
package/esm/index.js
CHANGED
|
@@ -1,2 +1,581 @@
|
|
|
1
|
-
|
|
1
|
+
// src/hooks/useDataSource.ts
|
|
2
|
+
import { getFullRange, metadataKeys, WindowRange } from "@vuu-ui/vuu-utils";
|
|
3
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
4
|
+
var { SELECTED } = metadataKeys;
|
|
5
|
+
function useDataSource({
|
|
6
|
+
dataSource,
|
|
7
|
+
renderBufferSize = 10
|
|
8
|
+
}) {
|
|
9
|
+
const [, forceUpdate] = useState(null);
|
|
10
|
+
const isMounted = useRef(true);
|
|
11
|
+
const hasUpdated = useRef(false);
|
|
12
|
+
const rafHandle = useRef(null);
|
|
13
|
+
const data = useRef([]);
|
|
14
|
+
const rangeRef = useRef({ from: 0, to: 10 });
|
|
15
|
+
const dataWindow = useMemo(
|
|
16
|
+
() => new MovingWindow(getFullRange(rangeRef.current, renderBufferSize)),
|
|
17
|
+
[renderBufferSize]
|
|
18
|
+
);
|
|
19
|
+
const setData = useCallback(
|
|
20
|
+
(updates) => {
|
|
21
|
+
for (const row of updates) {
|
|
22
|
+
dataWindow.add(row);
|
|
23
|
+
}
|
|
24
|
+
data.current = dataWindow.data.slice();
|
|
25
|
+
hasUpdated.current = true;
|
|
26
|
+
},
|
|
27
|
+
[dataWindow]
|
|
28
|
+
);
|
|
29
|
+
const datasourceMessageHandler = useCallback(
|
|
30
|
+
(message) => {
|
|
31
|
+
if (message.type === "viewport-update") {
|
|
32
|
+
if (message.size !== void 0) {
|
|
33
|
+
dataWindow.setRowCount(message.size);
|
|
34
|
+
}
|
|
35
|
+
if (message.rows) {
|
|
36
|
+
setData(message.rows);
|
|
37
|
+
forceUpdate({});
|
|
38
|
+
} else if (message.size !== void 0) {
|
|
39
|
+
data.current = dataWindow.data.slice();
|
|
40
|
+
hasUpdated.current = true;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
[dataWindow, setData]
|
|
45
|
+
);
|
|
46
|
+
useEffect(
|
|
47
|
+
() => () => {
|
|
48
|
+
if (rafHandle.current) {
|
|
49
|
+
cancelAnimationFrame(rafHandle.current);
|
|
50
|
+
rafHandle.current = null;
|
|
51
|
+
}
|
|
52
|
+
isMounted.current = false;
|
|
53
|
+
},
|
|
54
|
+
[]
|
|
55
|
+
);
|
|
56
|
+
const setRange = useCallback(
|
|
57
|
+
(range) => {
|
|
58
|
+
rangeRef.current = range;
|
|
59
|
+
const fullRange = getFullRange(rangeRef.current, renderBufferSize);
|
|
60
|
+
dataSource.range = fullRange;
|
|
61
|
+
dataWindow.setRange(fullRange.from, fullRange.to);
|
|
62
|
+
},
|
|
63
|
+
[dataSource, dataWindow, renderBufferSize]
|
|
64
|
+
);
|
|
65
|
+
useMemo(() => {
|
|
66
|
+
const { from, to } = rangeRef.current;
|
|
67
|
+
const fullRange = getFullRange({ from, to }, renderBufferSize);
|
|
68
|
+
dataSource.range = fullRange;
|
|
69
|
+
dataWindow.setRange(fullRange.from, fullRange.to);
|
|
70
|
+
}, [dataSource, dataWindow, renderBufferSize]);
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
const { from, to } = getFullRange(rangeRef.current, renderBufferSize);
|
|
73
|
+
dataSource.subscribe(
|
|
74
|
+
{
|
|
75
|
+
range: { from, to }
|
|
76
|
+
},
|
|
77
|
+
datasourceMessageHandler
|
|
78
|
+
);
|
|
79
|
+
}, [dataSource, datasourceMessageHandler, renderBufferSize]);
|
|
80
|
+
useEffect(
|
|
81
|
+
() => () => {
|
|
82
|
+
dataSource.unsubscribe();
|
|
83
|
+
},
|
|
84
|
+
[dataSource]
|
|
85
|
+
);
|
|
86
|
+
return [
|
|
87
|
+
data.current,
|
|
88
|
+
dataWindow.rowCount,
|
|
89
|
+
getFullRange(rangeRef.current, renderBufferSize),
|
|
90
|
+
setRange
|
|
91
|
+
];
|
|
92
|
+
}
|
|
93
|
+
var MovingWindow = class {
|
|
94
|
+
constructor({ from, to }) {
|
|
95
|
+
this.rowCount = 0;
|
|
96
|
+
this.setRowCount = (rowCount) => {
|
|
97
|
+
if (rowCount < this.data.length) {
|
|
98
|
+
this.data.length = rowCount;
|
|
99
|
+
}
|
|
100
|
+
this.rowCount = rowCount;
|
|
101
|
+
};
|
|
102
|
+
this.range = new WindowRange(from, to);
|
|
103
|
+
this.data = new Array(to - from);
|
|
104
|
+
}
|
|
105
|
+
add(data) {
|
|
106
|
+
const [index] = data;
|
|
107
|
+
if (this.isWithinRange(index)) {
|
|
108
|
+
const internalIndex = index - this.range.from;
|
|
109
|
+
this.data[internalIndex] = data;
|
|
110
|
+
if (this.data[internalIndex - 1]) {
|
|
111
|
+
if (this.data[internalIndex - 1][SELECTED] === 1 && data[SELECTED] === 0) {
|
|
112
|
+
data[SELECTED] = 2;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (index === this.rowCount - 1) {
|
|
116
|
+
this.data.length = internalIndex + 1;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
getAtIndex(index) {
|
|
121
|
+
return this.range.isWithin(index) && this.data[index - this.range.from] != null ? this.data[index - this.range.from] : void 0;
|
|
122
|
+
}
|
|
123
|
+
isWithinRange(index) {
|
|
124
|
+
return this.range.isWithin(index);
|
|
125
|
+
}
|
|
126
|
+
setRange(from, to) {
|
|
127
|
+
if (from !== this.range.from || to !== this.range.to) {
|
|
128
|
+
const [overlapFrom, overlapTo] = this.range.overlap(from, to);
|
|
129
|
+
const newData = new Array(to - from);
|
|
130
|
+
for (let i = overlapFrom; i < overlapTo; i++) {
|
|
131
|
+
const data = this.getAtIndex(i);
|
|
132
|
+
if (data) {
|
|
133
|
+
const index = i - from;
|
|
134
|
+
newData[index] = data;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
this.data = newData;
|
|
138
|
+
this.range.from = from;
|
|
139
|
+
this.range.to = to;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// src/hooks/useLookupValues.ts
|
|
145
|
+
import { VuuDataSource } from "@vuu-ui/vuu-data-remote";
|
|
146
|
+
import { useShellContext } from "@vuu-ui/vuu-shell";
|
|
147
|
+
import {
|
|
148
|
+
buildColumnMap,
|
|
149
|
+
isLookupRenderer,
|
|
150
|
+
isTypeDescriptor,
|
|
151
|
+
isValueListRenderer
|
|
152
|
+
} from "@vuu-ui/vuu-utils";
|
|
153
|
+
import { useMemo as useMemo2, useState as useState2 } from "react";
|
|
154
|
+
var NO_VALUES = [];
|
|
155
|
+
var toListOption = (value) => ({
|
|
156
|
+
label: value,
|
|
157
|
+
value
|
|
158
|
+
});
|
|
159
|
+
var lookupValueMap = /* @__PURE__ */ new Map();
|
|
160
|
+
var loadLookupValues = ({
|
|
161
|
+
labelColumn,
|
|
162
|
+
table,
|
|
163
|
+
valueColumn
|
|
164
|
+
}) => {
|
|
165
|
+
const tableKey = `${table.module}:${table.table}`;
|
|
166
|
+
const lookupValues = lookupValueMap.get(tableKey);
|
|
167
|
+
if (lookupValues) {
|
|
168
|
+
return lookupValues;
|
|
169
|
+
} else {
|
|
170
|
+
const promise = new Promise((resolve) => {
|
|
171
|
+
const columns = [valueColumn, labelColumn];
|
|
172
|
+
const columnMap = buildColumnMap(columns);
|
|
173
|
+
const dataSource = new VuuDataSource({
|
|
174
|
+
bufferSize: 0,
|
|
175
|
+
table
|
|
176
|
+
});
|
|
177
|
+
dataSource.subscribe(
|
|
178
|
+
{
|
|
179
|
+
columns,
|
|
180
|
+
range: { from: 0, to: 100 }
|
|
181
|
+
},
|
|
182
|
+
(message) => {
|
|
183
|
+
if (message.type === "viewport-update") {
|
|
184
|
+
if (message.rows) {
|
|
185
|
+
const listOptions = message.rows.map((row) => ({
|
|
186
|
+
value: row[columnMap[valueColumn]],
|
|
187
|
+
label: row[columnMap[labelColumn]]
|
|
188
|
+
}));
|
|
189
|
+
resolve(listOptions);
|
|
190
|
+
dataSource.unsubscribe();
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
);
|
|
195
|
+
});
|
|
196
|
+
lookupValueMap.set(tableKey, promise);
|
|
197
|
+
return promise;
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
var getSelectedOption = (values, selectedValue) => {
|
|
201
|
+
var _a;
|
|
202
|
+
if (selectedValue === void 0) {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
return (_a = values.find((option) => option.value === selectedValue)) != null ? _a : null;
|
|
206
|
+
};
|
|
207
|
+
var getLookupDetails = ({ name, type }) => {
|
|
208
|
+
if (isTypeDescriptor(type) && isLookupRenderer(type.renderer)) {
|
|
209
|
+
return type.renderer.lookup;
|
|
210
|
+
} else {
|
|
211
|
+
throw Error(
|
|
212
|
+
`useLookupValues column ${name} is not configured to use lookup values`
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
var useLookupValues = (column, initialValueProp) => {
|
|
217
|
+
const { type: columnType } = column;
|
|
218
|
+
const { getLookupValues } = useShellContext();
|
|
219
|
+
const initialState = useMemo2(() => {
|
|
220
|
+
var _a;
|
|
221
|
+
if (isTypeDescriptor(columnType) && isValueListRenderer(columnType == null ? void 0 : columnType.renderer)) {
|
|
222
|
+
const values2 = columnType.renderer.values.map(toListOption);
|
|
223
|
+
return {
|
|
224
|
+
initialValue: getSelectedOption(values2, initialValueProp),
|
|
225
|
+
values: values2
|
|
226
|
+
};
|
|
227
|
+
} else {
|
|
228
|
+
const lookupDetails = getLookupDetails(column);
|
|
229
|
+
const values2 = (_a = getLookupValues == null ? void 0 : getLookupValues(lookupDetails.table)) != null ? _a : NO_VALUES;
|
|
230
|
+
return {
|
|
231
|
+
initialValue: getSelectedOption(values2, initialValueProp),
|
|
232
|
+
values: values2
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
}, [column, columnType, getLookupValues, initialValueProp]);
|
|
236
|
+
const [{ initialValue, values }, setLookupState] = useState2(initialState);
|
|
237
|
+
useMemo2(() => {
|
|
238
|
+
if (values === NO_VALUES) {
|
|
239
|
+
const lookupDetails = getLookupDetails(column);
|
|
240
|
+
loadLookupValues(lookupDetails).then(
|
|
241
|
+
(values2) => setLookupState({
|
|
242
|
+
initialValue: getSelectedOption(values2, initialValueProp),
|
|
243
|
+
values: values2
|
|
244
|
+
})
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
}, [values, column, initialValueProp]);
|
|
248
|
+
return {
|
|
249
|
+
initialValue,
|
|
250
|
+
values
|
|
251
|
+
};
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
// src/hooks/useServerConnectionStatus.ts
|
|
255
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useState as useState3 } from "react";
|
|
256
|
+
import { ConnectionManager } from "@vuu-ui/vuu-data-remote";
|
|
257
|
+
var useServerConnectionStatus = () => {
|
|
258
|
+
const [connectionStatus, setConnectionStatus] = useState3("disconnected");
|
|
259
|
+
const handleStatusChange = useCallback2(
|
|
260
|
+
({ status }) => {
|
|
261
|
+
setConnectionStatus(status);
|
|
262
|
+
},
|
|
263
|
+
[]
|
|
264
|
+
);
|
|
265
|
+
useEffect2(() => {
|
|
266
|
+
ConnectionManager.on("connection-status", handleStatusChange);
|
|
267
|
+
return () => {
|
|
268
|
+
ConnectionManager.removeListener("connection-status", handleStatusChange);
|
|
269
|
+
};
|
|
270
|
+
}, [handleStatusChange]);
|
|
271
|
+
return connectionStatus;
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
// src/hooks/useServerConnectionQuality.ts
|
|
275
|
+
import { useCallback as useCallback3, useEffect as useEffect3, useState as useState4 } from "react";
|
|
276
|
+
import { ConnectionManager as ConnectionManager2 } from "@vuu-ui/vuu-data-remote";
|
|
277
|
+
var useServerConnectionQuality = () => {
|
|
278
|
+
const [messagesPerSecond, setMessagesPerSecond] = useState4(0);
|
|
279
|
+
const handleConnectivityMessage = useCallback3(({ messages }) => {
|
|
280
|
+
setMessagesPerSecond(messages.messagesLength);
|
|
281
|
+
}, []);
|
|
282
|
+
useEffect3(() => {
|
|
283
|
+
ConnectionManager2.on("connection-metrics", handleConnectivityMessage);
|
|
284
|
+
return () => {
|
|
285
|
+
ConnectionManager2.removeListener(
|
|
286
|
+
"connection-metrics",
|
|
287
|
+
handleConnectivityMessage
|
|
288
|
+
);
|
|
289
|
+
};
|
|
290
|
+
}, [handleConnectivityMessage]);
|
|
291
|
+
return messagesPerSecond;
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
// src/hooks/useTypeaheadSuggestions.ts
|
|
295
|
+
import { makeRpcCall } from "@vuu-ui/vuu-data-remote";
|
|
296
|
+
import { useCallback as useCallback4 } from "react";
|
|
297
|
+
var TYPEAHEAD_MESSAGE_CONSTANTS = {
|
|
298
|
+
type: "RPC_CALL",
|
|
299
|
+
service: "TypeAheadRpcHandler"
|
|
300
|
+
};
|
|
301
|
+
var getTypeaheadParams = (table, column, text = "", selectedValues = []) => {
|
|
302
|
+
if (text !== "" && !selectedValues.includes(text.toLowerCase())) {
|
|
303
|
+
return [table, column, text];
|
|
304
|
+
}
|
|
305
|
+
return [table, column];
|
|
306
|
+
};
|
|
307
|
+
var useTypeaheadSuggestions = () => useCallback4(async (params) => {
|
|
308
|
+
const rpcMessage = params.length === 2 ? {
|
|
309
|
+
method: "getUniqueFieldValues",
|
|
310
|
+
params,
|
|
311
|
+
...TYPEAHEAD_MESSAGE_CONSTANTS
|
|
312
|
+
} : {
|
|
313
|
+
method: "getUniqueFieldValuesStartingWith",
|
|
314
|
+
params,
|
|
315
|
+
...TYPEAHEAD_MESSAGE_CONSTANTS
|
|
316
|
+
};
|
|
317
|
+
return makeRpcCall(rpcMessage);
|
|
318
|
+
}, []);
|
|
319
|
+
|
|
320
|
+
// src/hooks/useVuuMenuActions.ts
|
|
321
|
+
import { getFilterPredicate } from "@vuu-ui/vuu-filter-parser";
|
|
322
|
+
import {
|
|
323
|
+
getRowRecord,
|
|
324
|
+
isGroupMenuItemDescriptor,
|
|
325
|
+
metadataKeys as metadataKeys2
|
|
326
|
+
} from "@vuu-ui/vuu-utils";
|
|
327
|
+
import { useCallback as useCallback5 } from "react";
|
|
328
|
+
var addRowsFromInstruments = "addRowsFromInstruments";
|
|
329
|
+
var { KEY } = metadataKeys2;
|
|
330
|
+
var NO_CONFIG = {};
|
|
331
|
+
var isMenuItem = (menu) => "rpcName" in menu;
|
|
332
|
+
var isGroupMenuItem = (menu) => "menus" in menu;
|
|
333
|
+
var isRoot = (menu) => menu.name === "ROOT";
|
|
334
|
+
var isCellMenu = (options) => options.context === "cell";
|
|
335
|
+
var isRowMenu = (options) => options.context === "row";
|
|
336
|
+
var isSelectionMenu = (options) => options.context === "selected-rows";
|
|
337
|
+
var vuuContextCompatibleWithTableLocation = (uiLocation, vuuContext, selectedRowCount = 0) => {
|
|
338
|
+
switch (uiLocation) {
|
|
339
|
+
case "grid":
|
|
340
|
+
if (vuuContext === "selected-rows") {
|
|
341
|
+
return selectedRowCount > 0;
|
|
342
|
+
} else {
|
|
343
|
+
return true;
|
|
344
|
+
}
|
|
345
|
+
case "header":
|
|
346
|
+
return vuuContext === "grid";
|
|
347
|
+
default:
|
|
348
|
+
return false;
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
var gridRowMeetsFilterCriteria = (context, row, selectedRows, filter, columnMap) => {
|
|
352
|
+
if (context === "cell" || context === "row") {
|
|
353
|
+
const filterPredicate = getFilterPredicate(columnMap, filter);
|
|
354
|
+
return filterPredicate(row);
|
|
355
|
+
} else if (context === "selected-rows") {
|
|
356
|
+
if (selectedRows.length === 0) {
|
|
357
|
+
return false;
|
|
358
|
+
} else {
|
|
359
|
+
const filterPredicate = getFilterPredicate(columnMap, filter);
|
|
360
|
+
return selectedRows.every(filterPredicate);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
return true;
|
|
364
|
+
};
|
|
365
|
+
var getMenuRpcRequest = (options) => {
|
|
366
|
+
const { rpcName } = options;
|
|
367
|
+
if (isCellMenu(options)) {
|
|
368
|
+
return {
|
|
369
|
+
field: options.field,
|
|
370
|
+
rowKey: options.rowKey,
|
|
371
|
+
rpcName,
|
|
372
|
+
value: options.value,
|
|
373
|
+
type: "VIEW_PORT_MENU_CELL_RPC"
|
|
374
|
+
};
|
|
375
|
+
} else if (isRowMenu(options)) {
|
|
376
|
+
return {
|
|
377
|
+
rowKey: options.rowKey,
|
|
378
|
+
row: options.row,
|
|
379
|
+
rpcName,
|
|
380
|
+
type: "VIEW_PORT_MENU_ROW_RPC"
|
|
381
|
+
};
|
|
382
|
+
} else if (isSelectionMenu(options)) {
|
|
383
|
+
return {
|
|
384
|
+
rpcName,
|
|
385
|
+
type: "VIEW_PORT_MENUS_SELECT_RPC"
|
|
386
|
+
};
|
|
387
|
+
} else {
|
|
388
|
+
return {
|
|
389
|
+
rpcName,
|
|
390
|
+
type: "VIEW_PORT_MENU_TABLE_RPC"
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
var isTableLocation = (location) => ["grid", "header", "filter"].includes(location);
|
|
395
|
+
var hasFilter = ({ filter }) => typeof filter === "string" && filter.length > 0;
|
|
396
|
+
var getMenuItemOptions = (menu, options) => {
|
|
397
|
+
switch (menu.context) {
|
|
398
|
+
case "cell":
|
|
399
|
+
return {
|
|
400
|
+
...menu,
|
|
401
|
+
field: options.columnName,
|
|
402
|
+
rowKey: options.row[KEY],
|
|
403
|
+
value: options.row[options.columnMap[options.columnName]]
|
|
404
|
+
};
|
|
405
|
+
case "row":
|
|
406
|
+
return {
|
|
407
|
+
...menu,
|
|
408
|
+
row: getRowRecord(options.row, options.columnMap),
|
|
409
|
+
rowKey: options.row[KEY]
|
|
410
|
+
};
|
|
411
|
+
default:
|
|
412
|
+
return menu;
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
var menuShouldBeRenderedInThisContext = (menuItem, tableLocation, options) => {
|
|
416
|
+
var _a;
|
|
417
|
+
if (isGroupMenuItem(menuItem)) {
|
|
418
|
+
return menuItem.menus.some(
|
|
419
|
+
(childMenu) => menuShouldBeRenderedInThisContext(childMenu, tableLocation, options)
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
if (!vuuContextCompatibleWithTableLocation(
|
|
423
|
+
tableLocation,
|
|
424
|
+
menuItem.context,
|
|
425
|
+
(_a = options.selectedRows) == null ? void 0 : _a.length
|
|
426
|
+
)) {
|
|
427
|
+
return false;
|
|
428
|
+
}
|
|
429
|
+
if (tableLocation === "grid" && hasFilter(menuItem)) {
|
|
430
|
+
return gridRowMeetsFilterCriteria(
|
|
431
|
+
menuItem.context,
|
|
432
|
+
options.row,
|
|
433
|
+
options.selectedRows,
|
|
434
|
+
menuItem.filter,
|
|
435
|
+
options.columnMap
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
if (isCellMenu(menuItem) && menuItem.field !== "*") {
|
|
439
|
+
return menuItem.field === options.columnName;
|
|
440
|
+
}
|
|
441
|
+
return true;
|
|
442
|
+
};
|
|
443
|
+
var buildMenuDescriptor = (menu, tableLocation, options) => {
|
|
444
|
+
if (menuShouldBeRenderedInThisContext(menu, tableLocation, options)) {
|
|
445
|
+
if (isMenuItem(menu)) {
|
|
446
|
+
return {
|
|
447
|
+
label: menu.name,
|
|
448
|
+
action: "MENU_RPC_CALL",
|
|
449
|
+
options: getMenuItemOptions(menu, options)
|
|
450
|
+
};
|
|
451
|
+
} else {
|
|
452
|
+
const children = menu.menus.map(
|
|
453
|
+
(childMenu) => buildMenuDescriptor(childMenu, tableLocation, options)
|
|
454
|
+
).filter(
|
|
455
|
+
(childMenu) => childMenu !== void 0
|
|
456
|
+
);
|
|
457
|
+
if (children.length > 0) {
|
|
458
|
+
return {
|
|
459
|
+
label: menu.name,
|
|
460
|
+
children
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
};
|
|
466
|
+
var useVuuMenuActions = ({
|
|
467
|
+
clientSideMenuActionHandler,
|
|
468
|
+
dataSource,
|
|
469
|
+
menuActionConfig = NO_CONFIG,
|
|
470
|
+
onRpcResponse
|
|
471
|
+
}) => {
|
|
472
|
+
const buildViewserverMenuOptions = useCallback5(
|
|
473
|
+
(location, options) => {
|
|
474
|
+
const { links, menu } = dataSource;
|
|
475
|
+
const { visualLink } = menuActionConfig;
|
|
476
|
+
const descriptors = [];
|
|
477
|
+
if (location === "grid" && links && !visualLink) {
|
|
478
|
+
links.forEach((linkDescriptor) => {
|
|
479
|
+
const { link, label: linkLabel } = linkDescriptor;
|
|
480
|
+
const label = linkLabel ? linkLabel : link.toTable;
|
|
481
|
+
descriptors.push({
|
|
482
|
+
label: `Link to ${label}`,
|
|
483
|
+
action: "link-table",
|
|
484
|
+
options: linkDescriptor
|
|
485
|
+
});
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
if (menu && isTableLocation(location)) {
|
|
489
|
+
const menuDescriptor = buildMenuDescriptor(
|
|
490
|
+
menu,
|
|
491
|
+
location,
|
|
492
|
+
options
|
|
493
|
+
);
|
|
494
|
+
if (isRoot(menu) && isGroupMenuItemDescriptor(menuDescriptor)) {
|
|
495
|
+
descriptors.push(...menuDescriptor.children);
|
|
496
|
+
} else if (menuDescriptor) {
|
|
497
|
+
descriptors.push(menuDescriptor);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
return descriptors;
|
|
501
|
+
},
|
|
502
|
+
[dataSource, menuActionConfig]
|
|
503
|
+
);
|
|
504
|
+
const handleMenuAction = useCallback5(
|
|
505
|
+
({ menuId, options }) => {
|
|
506
|
+
if (clientSideMenuActionHandler == null ? void 0 : clientSideMenuActionHandler(menuId, options)) {
|
|
507
|
+
return true;
|
|
508
|
+
} else if (menuId === "MENU_RPC_CALL") {
|
|
509
|
+
const rpcRequest = getMenuRpcRequest(options);
|
|
510
|
+
dataSource.menuRpcCall(rpcRequest).then((rpcResponse) => {
|
|
511
|
+
if (onRpcResponse && rpcResponse) {
|
|
512
|
+
onRpcResponse && onRpcResponse(rpcResponse);
|
|
513
|
+
}
|
|
514
|
+
});
|
|
515
|
+
return true;
|
|
516
|
+
} else if (menuId === "link-table") {
|
|
517
|
+
return dataSource.visualLink = options, true;
|
|
518
|
+
} else {
|
|
519
|
+
console.log(
|
|
520
|
+
`useViewServer handleMenuAction, can't handle action type ${menuId}`
|
|
521
|
+
);
|
|
522
|
+
}
|
|
523
|
+
return false;
|
|
524
|
+
},
|
|
525
|
+
[clientSideMenuActionHandler, dataSource, onRpcResponse]
|
|
526
|
+
);
|
|
527
|
+
return {
|
|
528
|
+
buildViewserverMenuOptions,
|
|
529
|
+
handleMenuAction
|
|
530
|
+
};
|
|
531
|
+
};
|
|
532
|
+
|
|
533
|
+
// src/hooks/useVuuTables.ts
|
|
534
|
+
import { getServerAPI } from "@vuu-ui/vuu-data-remote";
|
|
535
|
+
import { useCallback as useCallback6, useEffect as useEffect4, useState as useState5 } from "react";
|
|
536
|
+
var useVuuTables = () => {
|
|
537
|
+
const [tables, setTables] = useState5();
|
|
538
|
+
const buildTables = useCallback6((schemas) => {
|
|
539
|
+
const vuuTables = /* @__PURE__ */ new Map();
|
|
540
|
+
schemas.forEach((schema) => {
|
|
541
|
+
vuuTables.set(schema.table.table, schema);
|
|
542
|
+
});
|
|
543
|
+
return vuuTables;
|
|
544
|
+
}, []);
|
|
545
|
+
useEffect4(() => {
|
|
546
|
+
async function fetchTableMetadata() {
|
|
547
|
+
try {
|
|
548
|
+
const server = await getServerAPI();
|
|
549
|
+
const { tables: tables2 } = await server.getTableList();
|
|
550
|
+
const tableSchemas = buildTables(
|
|
551
|
+
await Promise.all(
|
|
552
|
+
tables2.map((vuuTable) => server.getTableSchema(vuuTable))
|
|
553
|
+
)
|
|
554
|
+
);
|
|
555
|
+
setTables(tableSchemas);
|
|
556
|
+
} catch (err) {
|
|
557
|
+
console.warn(
|
|
558
|
+
`useVuuTables: unable to connect to Vuu server ${String(err)}`
|
|
559
|
+
);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
fetchTableMetadata();
|
|
563
|
+
}, [buildTables]);
|
|
564
|
+
return tables;
|
|
565
|
+
};
|
|
566
|
+
var getVuuTableSchema = (table) => getServerAPI().then((server) => server.getTableSchema(table));
|
|
567
|
+
export {
|
|
568
|
+
MovingWindow,
|
|
569
|
+
addRowsFromInstruments,
|
|
570
|
+
getSelectedOption,
|
|
571
|
+
getTypeaheadParams,
|
|
572
|
+
getVuuTableSchema,
|
|
573
|
+
useDataSource,
|
|
574
|
+
useLookupValues,
|
|
575
|
+
useServerConnectionQuality,
|
|
576
|
+
useServerConnectionStatus,
|
|
577
|
+
useTypeaheadSuggestions,
|
|
578
|
+
useVuuMenuActions,
|
|
579
|
+
useVuuTables
|
|
580
|
+
};
|
|
2
581
|
//# sourceMappingURL=index.js.map
|