@vuu-ui/vuu-datatable 0.13.6 → 0.13.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/cjs/index.js +741 -10
  2. package/cjs/index.js.map +1 -1
  3. package/esm/index.js +740 -5
  4. package/esm/index.js.map +1 -1
  5. package/package.json +11 -11
  6. package/cjs/filter-table/FilterTable.css.js +0 -6
  7. package/cjs/filter-table/FilterTable.css.js.map +0 -1
  8. package/cjs/filter-table/FilterTable.js +0 -44
  9. package/cjs/filter-table/FilterTable.js.map +0 -1
  10. package/cjs/filter-table/useFilterTable.js +0 -29
  11. package/cjs/filter-table/useFilterTable.js.map +0 -1
  12. package/cjs/filter-table/usePersistFilterState.js +0 -156
  13. package/cjs/filter-table/usePersistFilterState.js.map +0 -1
  14. package/cjs/json-table/JsonCell.css.js +0 -6
  15. package/cjs/json-table/JsonCell.css.js.map +0 -1
  16. package/cjs/json-table/JsonCell.js +0 -45
  17. package/cjs/json-table/JsonCell.js.map +0 -1
  18. package/cjs/json-table/JsonTable.js +0 -52
  19. package/cjs/json-table/JsonTable.js.map +0 -1
  20. package/cjs/linked-table-view/LinkedTableView.css.js +0 -6
  21. package/cjs/linked-table-view/LinkedTableView.css.js.map +0 -1
  22. package/cjs/linked-table-view/LinkedTableView.js +0 -168
  23. package/cjs/linked-table-view/LinkedTableView.js.map +0 -1
  24. package/cjs/linked-table-view/TableLayoutToggleButton.js +0 -31
  25. package/cjs/linked-table-view/TableLayoutToggleButton.js.map +0 -1
  26. package/cjs/linked-table-view/useLinkedTableView.js +0 -210
  27. package/cjs/linked-table-view/useLinkedTableView.js.map +0 -1
  28. package/cjs/tree-table/TreeTable.js +0 -73
  29. package/cjs/tree-table/TreeTable.js.map +0 -1
  30. package/esm/filter-table/FilterTable.css.js +0 -4
  31. package/esm/filter-table/FilterTable.css.js.map +0 -1
  32. package/esm/filter-table/FilterTable.js +0 -42
  33. package/esm/filter-table/FilterTable.js.map +0 -1
  34. package/esm/filter-table/useFilterTable.js +0 -27
  35. package/esm/filter-table/useFilterTable.js.map +0 -1
  36. package/esm/filter-table/usePersistFilterState.js +0 -154
  37. package/esm/filter-table/usePersistFilterState.js.map +0 -1
  38. package/esm/json-table/JsonCell.css.js +0 -4
  39. package/esm/json-table/JsonCell.css.js.map +0 -1
  40. package/esm/json-table/JsonCell.js +0 -43
  41. package/esm/json-table/JsonCell.js.map +0 -1
  42. package/esm/json-table/JsonTable.js +0 -50
  43. package/esm/json-table/JsonTable.js.map +0 -1
  44. package/esm/linked-table-view/LinkedTableView.css.js +0 -4
  45. package/esm/linked-table-view/LinkedTableView.css.js.map +0 -1
  46. package/esm/linked-table-view/LinkedTableView.js +0 -166
  47. package/esm/linked-table-view/LinkedTableView.js.map +0 -1
  48. package/esm/linked-table-view/TableLayoutToggleButton.js +0 -29
  49. package/esm/linked-table-view/TableLayoutToggleButton.js.map +0 -1
  50. package/esm/linked-table-view/useLinkedTableView.js +0 -208
  51. package/esm/linked-table-view/useLinkedTableView.js.map +0 -1
  52. package/esm/tree-table/TreeTable.js +0 -71
  53. package/esm/tree-table/TreeTable.js.map +0 -1
package/esm/index.js CHANGED
@@ -1,6 +1,741 @@
1
- export { FilterTable } from './filter-table/FilterTable.js';
2
- export { usePersistFilterState } from './filter-table/usePersistFilterState.js';
3
- export { JsonTable } from './json-table/JsonTable.js';
4
- export { TreeTable } from './tree-table/TreeTable.js';
5
- export { LinkedTableView } from './linked-table-view/LinkedTableView.js';
1
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
+ import { FilterBar } from '@vuu-ui/vuu-filters';
3
+ import { Table } from '@vuu-ui/vuu-table';
4
+ import { useComponentCssInjection } from '@salt-ds/styles';
5
+ import { useWindow } from '@salt-ds/window';
6
+ import cx from 'clsx';
7
+ import { useCallback, useMemo, useState, useRef, useEffect } from 'react';
8
+ import { useViewContext, View, Flexbox, Stack } from '@vuu-ui/vuu-layout';
9
+ import { useWorkspace } from '@vuu-ui/vuu-shell';
10
+ import { metadataKeys, registerComponent, isRowSelected, useData } from '@vuu-ui/vuu-utils';
11
+ import { JsonDataSource, TreeDataSource } from '@vuu-ui/vuu-data-local';
12
+ import { ToggleIconButton, Icon, Tabstrip, Tab } from '@vuu-ui/vuu-ui-controls';
13
+ import { ToggleButtonGroup, ToggleButton } from '@salt-ds/core';
14
+
15
+ const useFilterTable = ({
16
+ FilterBarProps: FilterBarProps2,
17
+ TableProps: {
18
+ config: { columns },
19
+ dataSource
20
+ }
21
+ }) => {
22
+ const handleApplyFilter = useCallback(
23
+ (filter) => {
24
+ dataSource.filter = filter;
25
+ },
26
+ [dataSource]
27
+ );
28
+ const filterBarProps = {
29
+ ...FilterBarProps2,
30
+ columnDescriptors: FilterBarProps2?.columnDescriptors ?? columns,
31
+ onApplyFilter: handleApplyFilter
32
+ };
33
+ return {
34
+ filterBarProps
35
+ };
36
+ };
37
+
38
+ var filterTableCss = ".vuuFilterTable {\n --vuuMeasuredContainer-flex: 1 1 auto;\n --vuuMeasuredContainer-height: auto;\n display: flex;\n flex-direction: column;\n\n .vuuFilterBar {\n flex: 0 0 auto;\n }\n}\n";
39
+
40
+ const classBase$1 = "vuuFilterTable";
41
+ const FilterTable = ({
42
+ FilterBarProps: FilterBarProps2,
43
+ TableProps: TableProps2,
44
+ style: styleProps,
45
+ ...htmlAttributes
46
+ }) => {
47
+ const targetWindow = useWindow();
48
+ useComponentCssInjection({
49
+ testId: "vuu-filter-table",
50
+ css: filterTableCss,
51
+ window: targetWindow
52
+ });
53
+ const { filterBarProps } = useFilterTable({
54
+ TableProps: TableProps2,
55
+ FilterBarProps: FilterBarProps2
56
+ });
57
+ return /* @__PURE__ */ jsxs(
58
+ "div",
59
+ {
60
+ ...htmlAttributes,
61
+ className: cx(classBase$1),
62
+ style: { ...styleProps },
63
+ children: [
64
+ /* @__PURE__ */ jsx(FilterBar, { ...filterBarProps }),
65
+ /* @__PURE__ */ jsx(Table, { ...TableProps2, height: "auto", width: "auto" })
66
+ ]
67
+ }
68
+ );
69
+ };
70
+
71
+ const NO_CONFIG = {};
72
+ const hasFilterWithName = (filters, name) => filters.findIndex((f) => f.name === name) !== -1;
73
+ const usePersistFilterState = ({
74
+ tableSchema
75
+ }) => {
76
+ const { load, save } = useViewContext();
77
+ const { getApplicationSettings, saveApplicationSettings } = useWorkspace();
78
+ const { "filterbar-config": filterbarConfigFromState } = useMemo(() => load?.() ?? NO_CONFIG, [load]);
79
+ const [filterState, setFilterState] = useState({
80
+ filters: filterbarConfigFromState?.filterState?.filters ?? [],
81
+ activeIndices: filterbarConfigFromState?.filterState?.activeIndices ?? []
82
+ });
83
+ const savedFilters = useMemo(() => {
84
+ const {
85
+ table: { module, table }
86
+ } = tableSchema;
87
+ const savedFilters2 = getApplicationSettings("filters");
88
+ const key = `${module}:${table}`;
89
+ return savedFilters2?.[key] ?? [];
90
+ }, [getApplicationSettings, tableSchema]);
91
+ const removeFilterFromSettings = useCallback(
92
+ (filter) => {
93
+ if (!tableSchema || !filter.name) return;
94
+ const savedFilters2 = getApplicationSettings("filters");
95
+ if (!savedFilters2) return;
96
+ const { module, table } = tableSchema.table;
97
+ const key = `${module}:${table}`;
98
+ if (hasFilterWithName(savedFilters2[key], filter.name)) {
99
+ const newSavedFilters = {
100
+ ...savedFilters2,
101
+ [key]: savedFilters2[key].filter((f) => f.name !== filter.name)
102
+ };
103
+ saveApplicationSettings(newSavedFilters, "filters");
104
+ }
105
+ },
106
+ [getApplicationSettings, saveApplicationSettings, tableSchema]
107
+ );
108
+ const saveFilterToSettings = useCallback(
109
+ (filter, name) => {
110
+ if (tableSchema && name) {
111
+ const savedFilters2 = getApplicationSettings(
112
+ "filters"
113
+ );
114
+ let newFilters = savedFilters2;
115
+ const { module, table } = tableSchema.table;
116
+ const key = `${module}:${table}`;
117
+ if (savedFilters2) {
118
+ if (savedFilters2[key]) {
119
+ if (hasFilterWithName(savedFilters2[key], name)) {
120
+ newFilters = {
121
+ ...savedFilters2,
122
+ [key]: savedFilters2[key].map(
123
+ (f) => f.name === name ? { ...filter, name } : f
124
+ )
125
+ };
126
+ } else if (filter?.name && filter?.name !== name && hasFilterWithName(savedFilters2[key], filter.name)) {
127
+ newFilters = {
128
+ ...savedFilters2,
129
+ [key]: savedFilters2[key].map(
130
+ (f) => f.name === filter.name ? { ...filter, name } : f
131
+ )
132
+ };
133
+ } else {
134
+ newFilters = {
135
+ ...savedFilters2,
136
+ [key]: savedFilters2[key].concat({ ...filter, name })
137
+ };
138
+ }
139
+ } else {
140
+ newFilters = {
141
+ ...savedFilters2,
142
+ [key]: [{ ...filter, name }]
143
+ };
144
+ }
145
+ } else {
146
+ newFilters = {
147
+ [key]: [{ ...filter, name }]
148
+ };
149
+ }
150
+ if (newFilters !== savedFilters2) {
151
+ saveApplicationSettings(newFilters, "filters");
152
+ }
153
+ }
154
+ },
155
+ [getApplicationSettings, saveApplicationSettings, tableSchema]
156
+ );
157
+ const handleFilterStateChanged = useCallback(
158
+ (filterState2) => {
159
+ save?.({ filterState: filterState2 }, "filterbar-config");
160
+ setFilterState(filterState2);
161
+ },
162
+ [save]
163
+ );
164
+ const handleFilterDeleted = useCallback(
165
+ (filter) => {
166
+ removeFilterFromSettings(filter);
167
+ },
168
+ [removeFilterFromSettings]
169
+ );
170
+ const handleFilterRenamed = useCallback(
171
+ (filter, name) => {
172
+ saveFilterToSettings(filter, name);
173
+ },
174
+ [saveFilterToSettings]
175
+ );
176
+ const buildFilterTableMenuOptions = useCallback(
177
+ (location) => {
178
+ if (location === "filter-bar-menu") {
179
+ if (savedFilters.length > 0) {
180
+ return savedFilters.map((filter) => ({
181
+ id: "add-filter",
182
+ label: filter.name,
183
+ options: { filter }
184
+ }));
185
+ } else {
186
+ return [
187
+ {
188
+ label: `You have no saved filters for this table`,
189
+ id: `no-action`
190
+ }
191
+ ];
192
+ }
193
+ } else {
194
+ return [];
195
+ }
196
+ },
197
+ [savedFilters]
198
+ );
199
+ const handleFilterTableMenuAction = useCallback(
200
+ (menuItemId) => {
201
+ if (menuItemId === "add-filter") {
202
+ return true;
203
+ } else {
204
+ return false;
205
+ }
206
+ },
207
+ []
208
+ );
209
+ return {
210
+ buildFilterTableMenuOptions,
211
+ filterState,
212
+ handleFilterTableMenuAction,
213
+ onFilterStateChanged: handleFilterStateChanged,
214
+ onFilterDeleted: handleFilterDeleted,
215
+ onFilterRenamed: handleFilterRenamed
216
+ };
217
+ };
218
+
219
+ var arrayCellCss = ".vuuJsonCell {\n --group-cell-spacer-width: 20px;\n align-items: center;\n border-right-style: solid;\n border-right-width: 1px;\n cursor: pointer;\n display: inline-flex;\n height: var(--row-height);\n padding-left: 20px;\n line-height: 16px;\n position: relative;\n\n .vuuToggleIconButton {\n position: absolute;\n }\n}\n";
220
+
221
+ const { IS_EXPANDED, IS_LEAF: IS_LEAF$1 } = metadataKeys;
222
+ const JsonCell = ({ column, columnMap, row }) => {
223
+ const targetWindow = useWindow();
224
+ useComponentCssInjection({
225
+ testId: "vuu-array-cell",
226
+ css: arrayCellCss,
227
+ window: targetWindow
228
+ });
229
+ const { name } = column;
230
+ const dataIdx = columnMap[name];
231
+ let { [IS_EXPANDED]: isExpanded, [IS_LEAF$1]: isLeaf, [dataIdx]: value } = row;
232
+ const getDisplayValue = () => {
233
+ if (isLeaf) {
234
+ return value;
235
+ } else if (typeof value === "string" && value.endsWith("{")) {
236
+ value = value.slice(0, -1);
237
+ if (!isNaN(parseInt(value))) {
238
+ return `${value}: {...}`;
239
+ } else {
240
+ return `value {...}`;
241
+ }
242
+ } else if (typeof value === "string" && value.endsWith("[")) {
243
+ value = value.slice(0, -1);
244
+ return `${value} [...]`;
245
+ }
246
+ };
247
+ const displayValue = getDisplayValue();
248
+ const isEmpty = displayValue === "" || displayValue === void 0;
249
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
250
+ isLeaf || isEmpty ? null : /* @__PURE__ */ jsx(ToggleIconButton, { isExpanded }),
251
+ /* @__PURE__ */ jsx("span", { children: displayValue })
252
+ ] });
253
+ };
254
+
255
+ registerComponent("json", JsonCell, "cell-renderer");
256
+ const JsonTable = ({
257
+ config,
258
+ source: sourceProp,
259
+ ...tableProps
260
+ }) => {
261
+ const sourceRef = useRef(sourceProp);
262
+ const dataSourceRef = useRef(void 0);
263
+ useMemo(() => {
264
+ dataSourceRef.current = new JsonDataSource({
265
+ data: sourceRef.current
266
+ });
267
+ }, []);
268
+ const tableConfig = useMemo(() => {
269
+ return {
270
+ ...config,
271
+ columns: dataSourceRef.current?.columnDescriptors ?? [],
272
+ columnSeparators: true,
273
+ rowSeparators: true
274
+ };
275
+ }, [config]);
276
+ useEffect(() => {
277
+ if (dataSourceRef.current) {
278
+ dataSourceRef.current.data = sourceProp;
279
+ }
280
+ }, [sourceProp]);
281
+ if (dataSourceRef.current === void 0) {
282
+ return null;
283
+ }
284
+ return /* @__PURE__ */ jsx(
285
+ Table,
286
+ {
287
+ ...tableProps,
288
+ config: tableConfig,
289
+ dataSource: dataSourceRef.current,
290
+ showColumnHeaderMenus: false,
291
+ selectionModel: "none"
292
+ }
293
+ );
294
+ };
295
+
296
+ const { DEPTH, IS_LEAF, KEY, IDX } = metadataKeys;
297
+ const rowToTreeNodeObject = (row, columnMap) => {
298
+ const { [IS_LEAF]: isLeaf, [KEY]: key, [IDX]: index, [DEPTH]: depth } = row;
299
+ const firstColIdx = columnMap.nodeData;
300
+ const labelColIdx = firstColIdx + depth;
301
+ return {
302
+ key,
303
+ index,
304
+ isGroupRow: !isLeaf,
305
+ isSelected: isRowSelected(row),
306
+ data: {
307
+ label: row[labelColIdx],
308
+ nodeData: row[firstColIdx]
309
+ }
310
+ };
311
+ };
312
+ const TreeTable = ({
313
+ config,
314
+ dataSource,
315
+ source,
316
+ ...tableProps
317
+ }) => {
318
+ const dataSourceRef = useRef(void 0);
319
+ useMemo(() => {
320
+ if (dataSource) {
321
+ dataSourceRef.current = dataSource;
322
+ } else if (source) {
323
+ dataSourceRef.current = new TreeDataSource({
324
+ data: source
325
+ });
326
+ } else {
327
+ throw Error(`TreeTable either source or dataSource must be provided`);
328
+ }
329
+ }, [dataSource, source]);
330
+ const tableConfig = useMemo(() => {
331
+ return {
332
+ ...config,
333
+ columns: dataSourceRef.current?.columnDescriptors ?? [],
334
+ columnSeparators: false,
335
+ rowSeparators: false
336
+ };
337
+ }, [config]);
338
+ console.log({ tableConfig, dataSource: dataSourceRef.current });
339
+ if (dataSourceRef.current === void 0) {
340
+ return null;
341
+ }
342
+ return /* @__PURE__ */ jsx(
343
+ Table,
344
+ {
345
+ ...tableProps,
346
+ className: "vuuTreeTable",
347
+ config: tableConfig,
348
+ dataSource: dataSourceRef.current,
349
+ groupToggleTarget: "toggle-icon",
350
+ navigationStyle: "tree",
351
+ rowToObject: rowToTreeNodeObject,
352
+ showColumnHeaderMenus: false,
353
+ selectionModel: "single",
354
+ selectionBookendWidth: 0
355
+ }
356
+ );
357
+ };
358
+
359
+ const getSchema = (schemas, { module, table }) => {
360
+ const schema = schemas.find(
361
+ ({ table: t }) => t.module === module && t.table === table
362
+ );
363
+ if (schema) {
364
+ return schema;
365
+ } else {
366
+ throw Error(`No schema for table ${module} ${table}`);
367
+ }
368
+ };
369
+ const getTable = (ds) => {
370
+ if (ds.table) {
371
+ return ds.table;
372
+ } else {
373
+ throw Error("No datasource table specified");
374
+ }
375
+ };
376
+ const getTables = (linkedDataSources) => {
377
+ const { "1": linked1, "2": linked2, "3": linked3 } = linkedDataSources;
378
+ const tables = [];
379
+ tables.push(getTable(linked1.dataSource));
380
+ if (Array.isArray(linked2)) {
381
+ linked2.forEach(({ dataSource }) => {
382
+ tables.push(getTable(dataSource));
383
+ });
384
+ } else {
385
+ tables.push(getTable(linked2.dataSource));
386
+ }
387
+ if (Array.isArray(linked3)) {
388
+ linked3.forEach(({ dataSource }) => {
389
+ tables.push(getTable(dataSource));
390
+ });
391
+ } else if (linked3) {
392
+ tables.push(getTable(linked3.dataSource));
393
+ }
394
+ return tables;
395
+ };
396
+ const useLinkedTableView = ({
397
+ linkedDataSources
398
+ }) => {
399
+ const { VuuDataSource, getServerAPI } = useData();
400
+ const [tableConfig, setTableConfig] = useState();
401
+ const [activeTabs, setActiveTab] = useState([
402
+ 0,
403
+ 0,
404
+ 0
405
+ ]);
406
+ const [collapsed, setCollapsed] = useState([
407
+ false,
408
+ false
409
+ ]);
410
+ const [tabbedView, setTabbedView] = useState([1, 1]);
411
+ useMemo(async () => {
412
+ const tables = getTables(linkedDataSources);
413
+ const serverAPI = await getServerAPI();
414
+ const schemas = await Promise.all(tables.map(serverAPI.getTableSchema));
415
+ const isDataSource = (ds) => typeof ds === typeof VuuDataSource;
416
+ const getDataSource = (ds) => {
417
+ if (isDataSource(ds)) {
418
+ return ds;
419
+ } else {
420
+ return new VuuDataSource(ds);
421
+ }
422
+ };
423
+ const createVisualLink = (vuuLink, parentDs) => {
424
+ if (parentDs && parentDs.table) {
425
+ const parentVpId = parentDs.viewport;
426
+ const toTable = vuuLink.toTable ?? parentDs.table?.table;
427
+ return {
428
+ link: {
429
+ ...vuuLink,
430
+ toTable
431
+ },
432
+ parentClientVpId: parentVpId,
433
+ parentVpId
434
+ };
435
+ } else {
436
+ throw Error("visual link cannot be created without parent vp id");
437
+ }
438
+ };
439
+ const getLinkedDataSource = (ds, vuuLink, parentDs) => {
440
+ if (isDataSource(ds)) {
441
+ return ds;
442
+ } else {
443
+ return new VuuDataSource({
444
+ ...ds,
445
+ visualLink: createVisualLink(vuuLink, parentDs)
446
+ });
447
+ }
448
+ };
449
+ const getTableConfig = (ds) => {
450
+ const schema = getSchema(schemas, getTable(ds));
451
+ return {
452
+ columns: schema.columns
453
+ };
454
+ };
455
+ const getRootConfig = ({
456
+ dataSource: ds,
457
+ title
458
+ }) => ({
459
+ config: getTableConfig(ds),
460
+ dataSource: getDataSource(ds),
461
+ title
462
+ });
463
+ const getLinkedConfig = ({ dataSource: ds, vuuLink, title }, parentDataSource) => ({
464
+ config: getTableConfig(ds),
465
+ dataSource: getLinkedDataSource(ds, vuuLink, parentDataSource),
466
+ title
467
+ });
468
+ const getLinkedConfigs = (linkedTableConfig, parentDataSource) => {
469
+ if (Array.isArray(linkedTableConfig)) {
470
+ return linkedTableConfig.map(
471
+ (config) => getLinkedConfig(config, parentDataSource)
472
+ );
473
+ } else {
474
+ return getLinkedConfig(linkedTableConfig, parentDataSource);
475
+ }
476
+ };
477
+ const { "1": level1, "2": level2, "3": level3 } = linkedDataSources;
478
+ const configLevel1 = getRootConfig(level1);
479
+ const configLevel2 = getLinkedConfigs(level2, configLevel1.dataSource);
480
+ const dsLevel2 = Array.isArray(configLevel2) ? void 0 : configLevel2.dataSource;
481
+ const configLevel3 = level3 ? getLinkedConfigs(level3, dsLevel2) : void 0;
482
+ const results = {
483
+ "1": configLevel1,
484
+ "2": configLevel2,
485
+ "3": configLevel3
486
+ };
487
+ setTableConfig(results);
488
+ }, [VuuDataSource, getServerAPI, linkedDataSources]);
489
+ const handleTabChangeLevel1 = useCallback((tabIndex) => {
490
+ setActiveTab(([, v2, v3]) => [tabIndex, v2, v3]);
491
+ }, []);
492
+ const handleTabChangeLevel2 = useCallback((tabIndex) => {
493
+ setActiveTab(([v1, , v3]) => [v1, tabIndex, v3]);
494
+ }, []);
495
+ const handleTabChangeLevel3 = useCallback((tabIndex) => {
496
+ setActiveTab(([v1, v2]) => [v1, v2, tabIndex]);
497
+ }, []);
498
+ const handleCollapseLevel2 = useCallback(() => {
499
+ setCollapsed(([, val]) => [true, val]);
500
+ }, []);
501
+ const handleExpandLevel2 = useCallback(() => {
502
+ setCollapsed(([, val]) => [false, val]);
503
+ }, []);
504
+ const handleCollapseLevel3 = useCallback(() => {
505
+ setCollapsed(([val]) => [val, true]);
506
+ }, []);
507
+ const handleExpandLevel3 = useCallback(() => {
508
+ setCollapsed(([val]) => [val, false]);
509
+ }, []);
510
+ const handleChangeTabbedView2 = useCallback(
511
+ (evt) => {
512
+ const target = evt.target;
513
+ const button = target?.closest("button");
514
+ if (button) {
515
+ const value = parseInt(button.value);
516
+ setTabbedView(([, val]) => [value, val]);
517
+ }
518
+ },
519
+ []
520
+ );
521
+ const handleChangeTabbedView3 = useCallback(
522
+ (evt) => {
523
+ const target = evt.target;
524
+ const button = target?.closest("button");
525
+ if (button) {
526
+ const value = parseInt(button.value);
527
+ setTabbedView(([val]) => [val, value]);
528
+ }
529
+ },
530
+ []
531
+ );
532
+ return {
533
+ level1: {
534
+ activeTab: activeTabs[0],
535
+ key: "level1",
536
+ onTabChange: handleTabChangeLevel1
537
+ },
538
+ level2: {
539
+ activeTab: activeTabs[1],
540
+ collapsed: collapsed[0],
541
+ key: "level2",
542
+ onChangeTabbedView: handleChangeTabbedView2,
543
+ onCollapse: handleCollapseLevel2,
544
+ onExpand: handleExpandLevel2,
545
+ onTabChange: handleTabChangeLevel2,
546
+ tabbedView: tabbedView[0]
547
+ },
548
+ level3: {
549
+ activeTab: activeTabs[2],
550
+ collapsed: collapsed[1],
551
+ key: "level3",
552
+ onChangeTabbedView: handleChangeTabbedView3,
553
+ onCollapse: handleCollapseLevel3,
554
+ onExpand: handleExpandLevel3,
555
+ onTabChange: handleTabChangeLevel3,
556
+ tabbedView: tabbedView[1]
557
+ },
558
+ tableConfig
559
+ };
560
+ };
561
+
562
+ var css = ".vuuLinkedTableView {\n \n}\n\n.vuuLinkedTableView-header {\n align-items: center;\n \n display: flex;\n flex-basis: 28px;\n flex-grow: 0;\n flex-shrink: 0;\n padding-right: var(--salt-spacing-100);\n\n .vuuTabstrip {\n width: fit-content;\n }\n\n .vuuLinkedTableView-toolTray {\n margin-left: auto;\n }\n\n}\n\n.vuuLinkedTableView-view {\n overflow: hidden;\n padding: var(--salt-spacing-100);\n}";
563
+
564
+ const TableLayoutToggleButton = (props) => {
565
+ return /* @__PURE__ */ jsxs(ToggleButtonGroup, { ...props, children: [
566
+ /* @__PURE__ */ jsx(
567
+ ToggleButton,
568
+ {
569
+ className: "vuuIconToggleButton",
570
+ value: 0,
571
+ "aria-label": "Tabbed View",
572
+ children: /* @__PURE__ */ jsx(Icon, { name: "split-v", size: 18 })
573
+ }
574
+ ),
575
+ /* @__PURE__ */ jsx(
576
+ ToggleButton,
577
+ {
578
+ className: "vuuIconToggleButton",
579
+ value: 1,
580
+ "aria-label": "Side by side view",
581
+ children: /* @__PURE__ */ jsx(Icon, { name: "tabs", size: 18 })
582
+ }
583
+ )
584
+ ] });
585
+ };
586
+
587
+ const classBase = "vuuLinkedTableView";
588
+ const LinkedTables = ({
589
+ className,
590
+ linkedDataSources,
591
+ ...htmlAttributes
592
+ }) => {
593
+ const targetWindow = useWindow();
594
+ useComponentCssInjection({
595
+ testId: "vuu-linked-table-view",
596
+ css,
597
+ window: targetWindow
598
+ });
599
+ const { tableConfig, ...config } = useLinkedTableView({
600
+ linkedDataSources
601
+ });
602
+ const getLinkedTables = (tdsConfig, {
603
+ activeTab,
604
+ onChangeTabbedView,
605
+ onTabChange,
606
+ tabbedView,
607
+ ...levelConfig
608
+ }) => Array.isArray(tdsConfig) === false ? /* @__PURE__ */ jsx(
609
+ View,
610
+ {
611
+ ...levelConfig,
612
+ header: true,
613
+ resizeable: true,
614
+ style: { flexBasis: 0, flexGrow: 1, flexShrink: 1 },
615
+ title: tdsConfig.title,
616
+ children: /* @__PURE__ */ jsx(Table, { config: tdsConfig.config, dataSource: tdsConfig.dataSource })
617
+ }
618
+ ) : tabbedView === 1 ? /* @__PURE__ */ jsxs(
619
+ "div",
620
+ {
621
+ style: {
622
+ display: "flex",
623
+ flexDirection: "column",
624
+ flexBasis: 0,
625
+ flexGrow: 1,
626
+ flexShrink: 1
627
+ },
628
+ children: [
629
+ /* @__PURE__ */ jsxs("div", { className: `${classBase}-header`, children: [
630
+ /* @__PURE__ */ jsx(Tabstrip, { activeTabIndex: activeTab, onActiveChange: onTabChange, children: tdsConfig.map(({ title }, i) => /* @__PURE__ */ jsx(Tab, { label: title }, i)) }),
631
+ /* @__PURE__ */ jsx("div", { className: `${classBase}-toolTray`, children: /* @__PURE__ */ jsx(
632
+ TableLayoutToggleButton,
633
+ {
634
+ onChange: onChangeTabbedView,
635
+ value: tabbedView
636
+ }
637
+ ) })
638
+ ] }),
639
+ /* @__PURE__ */ jsx(
640
+ Stack,
641
+ {
642
+ active: activeTab,
643
+ "data-resizeable": true,
644
+ showTabs: false,
645
+ style: { flexBasis: 0, flexGrow: 1, flexShrink: 1 },
646
+ children: tdsConfig.map(({ config: config2, dataSource, title }, i) => /* @__PURE__ */ jsx(
647
+ "div",
648
+ {
649
+ className: `${classBase}-view`,
650
+ style: { flexBasis: 0, flexGrow: 1, flexShrink: 1 },
651
+ title,
652
+ children: /* @__PURE__ */ jsx(Table, { config: config2, dataSource })
653
+ },
654
+ i
655
+ ))
656
+ },
657
+ levelConfig.key
658
+ )
659
+ ]
660
+ }
661
+ ) : /* @__PURE__ */ jsxs(
662
+ "div",
663
+ {
664
+ style: {
665
+ display: "flex",
666
+ flexDirection: "column",
667
+ flexBasis: 0,
668
+ flexGrow: 1,
669
+ flexShrink: 1
670
+ },
671
+ children: [
672
+ /* @__PURE__ */ jsxs("div", { className: `${classBase}-header`, children: [
673
+ /* @__PURE__ */ jsx("div", { className: `${classBase}-flexHeaders`, children: tdsConfig.map(({ title }, i) => /* @__PURE__ */ jsx("span", { children: title }, i)) }),
674
+ /* @__PURE__ */ jsx("div", { className: `${classBase}-toolTray`, children: /* @__PURE__ */ jsx(
675
+ TableLayoutToggleButton,
676
+ {
677
+ onChange: onChangeTabbedView,
678
+ value: tabbedView
679
+ }
680
+ ) })
681
+ ] }),
682
+ /* @__PURE__ */ jsx(
683
+ Flexbox,
684
+ {
685
+ style: {
686
+ flexDirection: "row",
687
+ flexBasis: 0,
688
+ flexGrow: 1,
689
+ flexShrink: 1
690
+ },
691
+ children: tdsConfig.map(({ config: config2, dataSource, title }, i) => /* @__PURE__ */ jsx(
692
+ "div",
693
+ {
694
+ className: `${classBase}-view`,
695
+ "data-resizeable": true,
696
+ style: { flexBasis: 0, flexGrow: 1, flexShrink: 1 },
697
+ title,
698
+ children: /* @__PURE__ */ jsx(Table, { config: config2, dataSource })
699
+ },
700
+ i
701
+ ))
702
+ }
703
+ )
704
+ ]
705
+ }
706
+ );
707
+ const getAllLinkedTables = (level2, level3, config2) => {
708
+ const results = [getLinkedTables(level2, config2.level2)];
709
+ if (level3) {
710
+ results.push(getLinkedTables(level3, config2.level3));
711
+ }
712
+ return results;
713
+ };
714
+ if (tableConfig) {
715
+ const { "1": level1, "2": level2, "3": level3 } = tableConfig;
716
+ return /* @__PURE__ */ jsx("div", { ...htmlAttributes, className: cx(classBase, className), children: /* @__PURE__ */ jsxs(Flexbox, { style: { flexDirection: "column", height: "100%" }, children: [
717
+ /* @__PURE__ */ jsx(
718
+ View,
719
+ {
720
+ className: `${classBase}-view`,
721
+ header: true,
722
+ resizeable: true,
723
+ style: { flexBasis: 0, flexGrow: 1, flexShrink: 1 },
724
+ title: level1.title,
725
+ children: /* @__PURE__ */ jsx(Table, { config: level1.config, dataSource: level1.dataSource })
726
+ }
727
+ ),
728
+ ...getAllLinkedTables(level2, level3, config)
729
+ ] }) });
730
+ } else {
731
+ return null;
732
+ }
733
+ };
734
+ const LinkedTableView = ({
735
+ className,
736
+ linkedDataSources,
737
+ ...htmlAttributes
738
+ }) => /* @__PURE__ */ jsx(View, { ...htmlAttributes, className, children: /* @__PURE__ */ jsx(LinkedTables, { linkedDataSources }) });
739
+
740
+ export { FilterTable, JsonTable, LinkedTableView, TreeTable, usePersistFilterState };
6
741
  //# sourceMappingURL=index.js.map