@platforma-sdk/ui-vue 1.29.9 → 1.29.13

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 (32) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/lib.js +9477 -9003
  3. package/dist/lib.js.map +1 -1
  4. package/dist/lib.umd.cjs +27 -27
  5. package/dist/lib.umd.cjs.map +1 -1
  6. package/dist/src/components/PlAgDataTable/PlAgDataTable.vue.d.ts.map +1 -1
  7. package/dist/src/components/PlAgDataTable/PlAgDataTableV2.vue.d.ts +78 -0
  8. package/dist/src/components/PlAgDataTable/PlAgDataTableV2.vue.d.ts.map +1 -0
  9. package/dist/src/components/PlAgDataTable/index.d.ts +1 -0
  10. package/dist/src/components/PlAgDataTable/index.d.ts.map +1 -1
  11. package/dist/src/components/PlAgDataTable/sources/common.d.ts +21 -0
  12. package/dist/src/components/PlAgDataTable/sources/common.d.ts.map +1 -0
  13. package/dist/src/components/PlAgDataTable/sources/table-source-v2.d.ts +16 -0
  14. package/dist/src/components/PlAgDataTable/sources/table-source-v2.d.ts.map +1 -0
  15. package/dist/src/components/PlAgDataTable/sources/table-source.d.ts +4 -15
  16. package/dist/src/components/PlAgDataTable/sources/table-source.d.ts.map +1 -1
  17. package/dist/src/components/PlAgDataTable/types.d.ts +14 -2
  18. package/dist/src/components/PlAgDataTable/types.d.ts.map +1 -1
  19. package/dist/src/lib.d.ts +2 -1
  20. package/dist/src/lib.d.ts.map +1 -1
  21. package/dist/style.css +1 -1
  22. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  23. package/package.json +3 -3
  24. package/src/components/PlAgDataTable/PlAgDataTable.vue +10 -6
  25. package/src/components/PlAgDataTable/PlAgDataTableV2.vue +539 -0
  26. package/src/components/PlAgDataTable/index.ts +1 -0
  27. package/src/components/PlAgDataTable/sources/common.ts +127 -0
  28. package/src/components/PlAgDataTable/sources/table-source-heterogeneous.ts +2 -2
  29. package/src/components/PlAgDataTable/sources/table-source-v2.ts +260 -0
  30. package/src/components/PlAgDataTable/sources/table-source.ts +2 -115
  31. package/src/components/PlAgDataTable/types.ts +19 -1
  32. package/src/lib.ts +2 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platforma-sdk/ui-vue",
3
- "version": "1.29.9",
3
+ "version": "1.29.13",
4
4
  "type": "module",
5
5
  "main": "dist/lib.umd.cjs",
6
6
  "module": "dist/lib.js",
@@ -23,8 +23,8 @@
23
23
  "canonicalize": "~2.1.0",
24
24
  "ag-grid-enterprise": "^33.0.4",
25
25
  "ag-grid-vue3": "^33.0.4",
26
- "@platforma-sdk/model": "^1.29.2",
27
- "@milaboratories/uikit": "^2.2.67"
26
+ "@milaboratories/uikit": "^2.2.67",
27
+ "@platforma-sdk/model": "^1.29.13"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@faker-js/faker": "^9.2.0",
@@ -19,6 +19,8 @@ import {
19
19
  } from 'ag-grid-enterprise';
20
20
  import { AgGridVue } from 'ag-grid-vue3';
21
21
  import { PlDropdownLine } from '@milaboratories/uikit';
22
+ import type {
23
+ PTableColumnSpecJson } from '@platforma-sdk/model';
22
24
  import {
23
25
  getAxisId,
24
26
  getRawPlatformaInstance,
@@ -28,6 +30,7 @@ import {
28
30
  type PTableColumnSpec,
29
31
  type PTableRecordFilter,
30
32
  type PTableSorting,
33
+ parsePTableColumnId,
31
34
  } from '@platforma-sdk/model';
32
35
  import canonicalize from 'canonicalize';
33
36
  import * as lodash from 'lodash';
@@ -36,7 +39,8 @@ import { AgGridTheme } from '../../lib';
36
39
  import PlOverlayLoading from './PlAgOverlayLoading.vue';
37
40
  import PlOverlayNoRows from './PlAgOverlayNoRows.vue';
38
41
  import { updateXsvGridOptions } from './sources/file-source';
39
- import { makeRowId, parseColId, updatePFrameGridOptions } from './sources/table-source';
42
+ import { type PlAgCellButtonAxisParams, makeRowId } from './sources/common';
43
+ import { updatePFrameGridOptions } from './sources/table-source';
40
44
  import type { PlAgDataTableController, PlDataTableSettings, PlAgDataTableRow, PTableRowKey, PlDataTableSettingsPTable } from './types';
41
45
  import { PlAgGridColumnManager } from '../PlAgGridColumnManager';
42
46
  import { autoSizeRowNumberColumn, PlAgDataTableRowNumberColId } from './sources/row-number';
@@ -108,12 +112,12 @@ const emit = defineEmits<{
108
112
  function makeSorting(state?: SortState): PTableSorting[] {
109
113
  return (
110
114
  state?.sortModel.map((item) => {
111
- const { spec, ...column } = parseColId(item.colId);
115
+ const { spec, ...column } = parsePTableColumnId(item.colId as PTableColumnSpecJson);
112
116
  const _ = spec;
113
117
  return {
114
118
  column,
115
119
  ascending: item.sort === 'asc',
116
- naAndAbsentAreLeastValues: true,
120
+ naAndAbsentAreLeastValues: item.sort === 'asc',
117
121
  };
118
122
  }) ?? []
119
123
  );
@@ -321,7 +325,7 @@ const makePartialState = (state: GridState) => {
321
325
  sourceId: gridState.value.sourceId,
322
326
  columnOrder: state.columnOrder,
323
327
  sort: state.sort,
324
- columnVisibility: state.columnVisibility,
328
+ columnVisibility: state.columnVisibility as { hiddenColIds: PTableColumnSpecJson[] } | undefined,
325
329
  };
326
330
  };
327
331
 
@@ -370,7 +374,7 @@ watch(
370
374
  .filter((colId) => colId !== undefined)
371
375
  .filter((colId) => colId !== PlAgDataTableRowNumberColId)
372
376
  .filter((colId) => !isColumnSelectionCol(colId))
373
- .map((colId) => parseColId(colId)) ?? [];
377
+ .map((colId) => parsePTableColumnId(colId as PTableColumnSpecJson)) ?? [];
374
378
  emit('columnsChanged', columns);
375
379
  }
376
380
  if (!lodash.isEqual(options.loadingOverlayComponentParams, oldOptions.loadingOverlayComponentParams) && options.loading) {
@@ -451,7 +455,7 @@ watch(
451
455
  showCellButtonForAxisId: props.showCellButtonForAxisId,
452
456
  cellButtonInvokeRowsOnDoubleClick: props.cellButtonInvokeRowsOnDoubleClick,
453
457
  trigger: (key?: PTableRowKey) => emit('cellButtonClicked', key),
454
- },
458
+ } satisfies PlAgCellButtonAxisParams,
455
459
  ).catch((err) => {
456
460
  gridApi.updateGridOptions({
457
461
  loading: false,
@@ -0,0 +1,539 @@
1
+ <script lang="ts" setup>
2
+ import {
3
+ type ColDef,
4
+ type ColGroupDef,
5
+ type GridApi,
6
+ type GridOptions,
7
+ type GridReadyEvent,
8
+ type GridState,
9
+ type ManagedGridOptionKey,
10
+ type ManagedGridOptions,
11
+ type SortState,
12
+ type StateUpdatedEvent,
13
+ ModuleRegistry,
14
+ ClientSideRowModelModule,
15
+ ClipboardModule,
16
+ CellSelectionModule,
17
+ ServerSideRowModelModule,
18
+ isColumnSelectionCol,
19
+ } from 'ag-grid-enterprise';
20
+ import { AgGridVue } from 'ag-grid-vue3';
21
+ import { PlDropdownLine } from '@milaboratories/uikit';
22
+ import type {
23
+ PTableColumnSpecJson } from '@platforma-sdk/model';
24
+ import {
25
+ getAxisId,
26
+ getRawPlatformaInstance,
27
+ type PlDataTableGridStateWithoutSheets,
28
+ type AxisId,
29
+ type PlDataTableState,
30
+ type PTableColumnSpec,
31
+ type PTableRecordFilter,
32
+ type PTableSorting,
33
+ parsePTableColumnId,
34
+ } from '@platforma-sdk/model';
35
+ import canonicalize from 'canonicalize';
36
+ import * as lodash from 'lodash';
37
+ import { computed, nextTick, ref, shallowRef, toRefs, watch } from 'vue';
38
+ import { AgGridTheme } from '../../lib';
39
+ import PlOverlayLoading from './PlAgOverlayLoading.vue';
40
+ import PlOverlayNoRows from './PlAgOverlayNoRows.vue';
41
+ import { type PlAgCellButtonAxisParams, makeRowId } from './sources/common';
42
+ import { updatePFrameGridOptions } from './sources/table-source-v2';
43
+ import type { PlAgDataTableController, PlAgDataTableSettings, PlAgDataTableRow, PTableRowKey, PlAgDataTableSettingsPTable } from './types';
44
+ import { PlAgGridColumnManager } from '../PlAgGridColumnManager';
45
+ import { autoSizeRowNumberColumn, PlAgDataTableRowNumberColId } from './sources/row-number';
46
+ import { focusRow, makeOnceTracker, trackFirstDataRendered } from './sources/focus-row';
47
+ import PlAgCsvExporter from '../PlAgCsvExporter/PlAgCsvExporter.vue';
48
+ import { Deferred, isJsonEqual } from '@milaboratories/helpers';
49
+
50
+ ModuleRegistry.registerModules([
51
+ ClientSideRowModelModule,
52
+ ClipboardModule,
53
+ ServerSideRowModelModule,
54
+ CellSelectionModule,
55
+ ]);
56
+
57
+ const tableState = defineModel<PlDataTableState>({ default: { gridState: {} } });
58
+ const selectedRows = defineModel<PTableRowKey[]>('selectedRows');
59
+ const props = defineProps<{
60
+ settings?: Readonly<PlAgDataTableSettings>;
61
+ /**
62
+ * The showColumnsPanel prop controls the display of a button that activates
63
+ * the columns management panel in the table. To make the button functional
64
+ * and visible, you must also include the PlAgDataTableToolsPanel component in your layout.
65
+ * This component serves as the target for teleporting the button.
66
+ */
67
+ showColumnsPanel?: boolean;
68
+ /**
69
+ * Css width of the Column Manager (Panel) modal (default value is `368px`)
70
+ */
71
+ columnsPanelWidth?: string;
72
+ /**
73
+ * The showExportButton prop controls the display of a button that allows
74
+ * to export table data in CSV format. To make the button functional
75
+ * and visible, you must also include the PlAgDataTableToolsPanel component in your layout.
76
+ * This component serves as the target for teleporting the button.
77
+ */
78
+ showExportButton?: boolean;
79
+ /**
80
+ * Force use of client-side row model.
81
+ * Required for reliable work of focusRow.
82
+ * Auto-enabled when selectedRows provided.
83
+ */
84
+ clientSideModel?: boolean;
85
+
86
+ /**
87
+ * The AxisId property is used to configure and display the PlAgTextAndButtonCell component
88
+ */
89
+ showCellButtonForAxisId?: AxisId;
90
+
91
+ /**
92
+ * If cellButtonInvokeRowsOnDoubleClick = true, clicking a button inside the row
93
+ * triggers the doubleClick event for the entire row.
94
+ *
95
+ * If cellButtonInvokeRowsOnDoubleClick = false, the doubleClick event for the row
96
+ * is not triggered, but will triggered cellButtonClicked event with (key: PTableRowKey) argument.
97
+ */
98
+ cellButtonInvokeRowsOnDoubleClick?: boolean;
99
+ }>();
100
+ const { settings } = toRefs(props);
101
+ const emit = defineEmits<{
102
+ rowDoubleClicked: [key?: PTableRowKey];
103
+ columnsChanged: [columns: PTableColumnSpec[]];
104
+ cellButtonClicked: [key?: PTableRowKey];
105
+ }>();
106
+
107
+ /** State upgrader */ (() => {
108
+ if (!tableState.value.pTableParams) tableState.value.pTableParams = {};
109
+ })();
110
+
111
+ function makeSorting(state?: SortState): PTableSorting[] {
112
+ return (
113
+ state?.sortModel.map((item) => {
114
+ const { spec, ...column } = parsePTableColumnId(item.colId as PTableColumnSpecJson);
115
+ const _ = spec;
116
+ return {
117
+ column,
118
+ ascending: item.sort === 'asc',
119
+ naAndAbsentAreLeastValues: item.sort === 'asc',
120
+ };
121
+ }) ?? []
122
+ );
123
+ }
124
+
125
+ const gridState = computed<PlDataTableGridStateWithoutSheets>({
126
+ get: () => {
127
+ const state = tableState.value;
128
+ return {
129
+ sourceId: state.gridState.sourceId,
130
+ columnOrder: state.gridState.columnOrder,
131
+ sort: state.gridState.sort,
132
+ columnVisibility: state.gridState.columnVisibility,
133
+ };
134
+ },
135
+ set: (gridState) => {
136
+ // do not apply driver sorting for client side rendering
137
+ const sorting
138
+ = settings.value?.sourceType !== 'ptable' || gridOptions.value.rowModelType === 'clientSide' ? undefined : makeSorting(gridState.sort);
139
+
140
+ const oldState = tableState.value;
141
+
142
+ const newState = {
143
+ ...oldState,
144
+ gridState: { ...oldState.gridState, ...gridState },
145
+ pTableParams: { ...oldState.pTableParams, sorting },
146
+ };
147
+
148
+ // Note: the table constantly emits an unchanged state, so I added this
149
+ if (!isJsonEqual(oldState, newState)) {
150
+ tableState.value = newState;
151
+ }
152
+ },
153
+ });
154
+
155
+ const makeSheetId = (axis: AxisId) => canonicalize(getAxisId(axis))!;
156
+
157
+ function makeFilters(sheetsState: Record<string, string | number>): PTableRecordFilter[] | undefined {
158
+ if (settings.value?.sourceType !== 'ptable') return undefined;
159
+ return (
160
+ settings.value.sheets?.map((sheet) => ({
161
+ type: 'bySingleColumnV2',
162
+ column: {
163
+ type: 'axis',
164
+ id: sheet.axis,
165
+ },
166
+ predicate: {
167
+ operator: 'Equal',
168
+ reference: sheetsState[makeSheetId(sheet.axis)],
169
+ },
170
+ })) ?? []
171
+ );
172
+ }
173
+
174
+ const sheetsState = computed({
175
+ get: () => tableState.value.gridState.sheets ?? {},
176
+ set: (sheetsState) => {
177
+ const filters = makeFilters(sheetsState);
178
+
179
+ const oldState = tableState.value;
180
+ tableState.value = {
181
+ ...oldState,
182
+ gridState: { ...oldState.gridState, sheets: sheetsState },
183
+ pTableParams: { ...oldState.pTableParams, filters },
184
+ };
185
+ },
186
+ });
187
+
188
+ const hasSheets = (
189
+ settings?: Readonly<PlAgDataTableSettings>,
190
+ ): settings is PlAgDataTableSettingsPTable => {
191
+ return settings?.sourceType === 'ptable'
192
+ && !!settings.sheets
193
+ && settings.sheets.length > 0;
194
+ };
195
+
196
+ watch(
197
+ () => settings.value,
198
+ (settings, oldSettings) => {
199
+ if (settings?.sourceType !== 'ptable' || !settings.sheets) {
200
+ sheetsState.value = {};
201
+ return;
202
+ }
203
+
204
+ if (oldSettings && oldSettings.sourceType === 'ptable' && lodash.isEqual(settings.sheets, oldSettings.sheets)) return;
205
+
206
+ const oldSheetsState = sheetsState.value;
207
+ const newSheetsState: Record<string, string | number> = {};
208
+ for (const sheet of settings.sheets) {
209
+ const sheetId = makeSheetId(sheet.axis);
210
+ newSheetsState[sheetId] = oldSheetsState[sheetId] ?? sheet.defaultValue ?? sheet.options[0]?.value;
211
+ }
212
+ sheetsState.value = newSheetsState;
213
+ },
214
+ { immediate: true },
215
+ );
216
+
217
+ const gridApi = shallowRef<GridApi>();
218
+
219
+ const gridApiDef = shallowRef(new Deferred<GridApi>());
220
+
221
+ const firstDataRenderedTracker = makeOnceTracker<GridApi<PlAgDataTableRow>>();
222
+ const gridOptions = shallowRef<GridOptions<PlAgDataTableRow>>({
223
+ animateRows: false,
224
+ suppressColumnMoveAnimation: true,
225
+ cellSelection: selectedRows.value === undefined,
226
+ initialState: gridState.value,
227
+ autoSizeStrategy: { type: 'fitCellContents' },
228
+ rowSelection: selectedRows.value !== undefined
229
+ ? {
230
+ mode: 'multiRow',
231
+ checkboxes: false,
232
+ headerCheckbox: false,
233
+ enableClickSelection: false,
234
+ }
235
+ : undefined,
236
+ selectionColumnDef: {
237
+ mainMenuItems: [],
238
+ contextMenuItems: [],
239
+ pinned: 'left',
240
+ lockPinned: true,
241
+ suppressSizeToFit: true,
242
+ suppressAutoSize: true,
243
+ sortable: false,
244
+ resizable: false,
245
+ },
246
+ onRowDataUpdated: (event) => {
247
+ const selectedRowsValue = selectedRows.value;
248
+ if (selectedRowsValue) {
249
+ const nodes = selectedRowsValue
250
+ .map((rowKey) => event.api.getRowNode(makeRowId(rowKey)))
251
+ .filter((node) => !!node);
252
+ event.api.setNodesSelected({ nodes, newValue: true });
253
+ }
254
+ },
255
+ onSelectionChanged: (event) => {
256
+ if (selectedRows.value) {
257
+ selectedRows.value = event.api.getSelectedNodes()
258
+ .map((rowNode) => rowNode.data?.key)
259
+ .filter((rowKey) => !!rowKey);
260
+ }
261
+ },
262
+ onRowDoubleClicked: (event) => {
263
+ if (event.data && event.data.key) emit('rowDoubleClicked', event.data.key);
264
+ },
265
+ defaultColDef: {
266
+ suppressHeaderMenuButton: true,
267
+ sortingOrder: ['desc', 'asc', null],
268
+ },
269
+ maintainColumnOrder: true,
270
+ localeText: {
271
+ loadingError: '...',
272
+ },
273
+ rowModelType: 'clientSide',
274
+ maxBlocksInCache: 1000,
275
+ // cacheBlockSize: 100,
276
+ blockLoadDebounceMillis: 500,
277
+ serverSideSortAllLevels: true,
278
+ suppressServerSideFullWidthLoadingRow: true,
279
+ getRowId: (params) => params.data.id,
280
+ loading: true,
281
+ loadingOverlayComponentParams: { notReady: true },
282
+ loadingOverlayComponent: PlOverlayLoading,
283
+ noRowsOverlayComponent: PlOverlayNoRows,
284
+ defaultCsvExportParams: {
285
+ allColumns: true,
286
+ suppressQuotes: true,
287
+ fileName: 'table.csv',
288
+ },
289
+ });
290
+
291
+ const onGridReady = (event: GridReadyEvent) => {
292
+ const api = event.api;
293
+ trackFirstDataRendered(api, firstDataRenderedTracker);
294
+ autoSizeRowNumberColumn(api);
295
+ gridApi.value = new Proxy(api, {
296
+ get(target, prop, receiver) {
297
+ switch (prop) {
298
+ case 'setGridOption':
299
+ return (key: ManagedGridOptionKey, value: GridOptions[ManagedGridOptionKey]) => {
300
+ const options = gridOptions.value;
301
+ options[key] = value;
302
+ gridOptions.value = options;
303
+ api.setGridOption(key, value);
304
+ };
305
+ case 'updateGridOptions':
306
+ return (options: ManagedGridOptions) => {
307
+ gridOptions.value = {
308
+ ...gridOptions.value,
309
+ ...options,
310
+ };
311
+ api.updateGridOptions(options);
312
+ };
313
+ default:
314
+ return Reflect.get(target, prop, receiver);
315
+ }
316
+ },
317
+ });
318
+
319
+ gridApiDef.value.resolve(gridApi.value);
320
+ };
321
+
322
+ const makePartialState = (state: GridState) => {
323
+ return {
324
+ sourceId: gridState.value.sourceId,
325
+ columnOrder: state.columnOrder,
326
+ sort: state.sort,
327
+ columnVisibility: state.columnVisibility as { hiddenColIds: PTableColumnSpecJson[] } | undefined,
328
+ };
329
+ };
330
+
331
+ const onStateUpdated = (event: StateUpdatedEvent) => {
332
+ gridOptions.value.initialState = gridState.value = makePartialState(event.state);
333
+ event.api.autoSizeColumns(event.api.getAllDisplayedColumns().filter((column) => column.getColId() !== PlAgDataTableRowNumberColId));
334
+ };
335
+
336
+ const onGridPreDestroyed = () => {
337
+ gridOptions.value.initialState = gridState.value = makePartialState(gridApi.value!.getState());
338
+ gridApi.value = undefined;
339
+ gridApiDef.value = new Deferred<GridApi>();
340
+ };
341
+
342
+ defineExpose<PlAgDataTableController>({
343
+ focusRow: (rowKey) => focusRow(makeRowId(rowKey), firstDataRenderedTracker),
344
+ });
345
+
346
+ const reloadKey = ref(0);
347
+ watch(
348
+ () => [gridApi.value, gridState.value] as const,
349
+ (state, oldState) => {
350
+ if (lodash.isEqual(state, oldState)) return;
351
+
352
+ const [gridApi, gridState] = state;
353
+ if (!gridApi) return;
354
+
355
+ const selfState = makePartialState(gridApi.getState());
356
+ if (lodash.isEqual(gridState, selfState)) return;
357
+
358
+ gridOptions.value.initialState = gridState;
359
+ ++reloadKey.value;
360
+ },
361
+ );
362
+ watch(
363
+ () => gridOptions.value,
364
+ (options, oldOptions) => {
365
+ if (!oldOptions) return;
366
+ if (options.rowModelType != oldOptions.rowModelType) ++reloadKey.value;
367
+ if (options.columnDefs && !lodash.isEqual(options.columnDefs, oldOptions.columnDefs)) {
368
+ const isColDef = (def: ColDef | ColGroupDef): def is ColDef => !('children' in def);
369
+ const colDefs = options.columnDefs?.filter(isColDef) ?? [];
370
+ const columns
371
+ = colDefs
372
+ .map((def) => def.colId)
373
+ .filter((colId) => colId !== undefined)
374
+ .filter((colId) => colId !== PlAgDataTableRowNumberColId)
375
+ .filter((colId) => !isColumnSelectionCol(colId))
376
+ .map((colId) => parsePTableColumnId(colId as PTableColumnSpecJson)) ?? [];
377
+ emit('columnsChanged', columns);
378
+ }
379
+ if (!lodash.isEqual(options.loadingOverlayComponentParams, oldOptions.loadingOverlayComponentParams) && options.loading) {
380
+ gridApi.value?.setGridOption('loading', false);
381
+ nextTick(() => gridApi.value?.setGridOption('loading', true));
382
+ }
383
+ },
384
+ { immediate: true },
385
+ );
386
+
387
+ const onSheetChanged = (sheetId: string, newValue: string | number) => {
388
+ const state = sheetsState.value;
389
+ if (state[sheetId] === newValue) return;
390
+ state[sheetId] = newValue;
391
+ sheetsState.value = state;
392
+ return gridApi.value?.updateGridOptions({
393
+ loading: true,
394
+ loadingOverlayComponentParams: { notReady: false },
395
+ });
396
+ };
397
+
398
+ let oldSettings: PlAgDataTableSettings | undefined = undefined;
399
+
400
+ watch(
401
+ () => [settings.value] as const,
402
+ async (state) => {
403
+ try {
404
+ const [settings] = state;
405
+
406
+ const gridApi = await gridApiDef.value.promise;
407
+
408
+ if (gridApi.isDestroyed()) {
409
+ console.warn('gridApi is destroyed');
410
+ return;
411
+ }
412
+
413
+ if (lodash.isEqual(settings, oldSettings)) {
414
+ return;
415
+ };
416
+
417
+ oldSettings = settings;
418
+
419
+ const sourceType = settings?.sourceType;
420
+
421
+ switch (sourceType) {
422
+ case undefined:
423
+ return gridApi.updateGridOptions({
424
+ loading: true,
425
+ loadingOverlayComponentParams: { notReady: true },
426
+ columnDefs: [],
427
+ rowData: undefined,
428
+ datasource: undefined,
429
+ });
430
+
431
+ case 'ptable': {
432
+ if (!settings?.model) {
433
+ return gridApi.updateGridOptions({
434
+ loading: true,
435
+ loadingOverlayComponentParams: { notReady: false },
436
+ columnDefs: [],
437
+ rowData: undefined,
438
+ datasource: undefined,
439
+ });
440
+ }
441
+
442
+ gridApi.updateGridOptions({
443
+ loading: true,
444
+ loadingOverlayComponentParams: { notReady: false },
445
+ });
446
+
447
+ const options = await updatePFrameGridOptions(
448
+ getRawPlatformaInstance().pFrameDriver,
449
+ settings.model,
450
+ settings.sheets ?? [],
451
+ !!props.clientSideModel || !!selectedRows.value,
452
+ gridState,
453
+ {
454
+ showCellButtonForAxisId: props.showCellButtonForAxisId,
455
+ cellButtonInvokeRowsOnDoubleClick: props.cellButtonInvokeRowsOnDoubleClick,
456
+ trigger: (key?: PTableRowKey) => emit('cellButtonClicked', key),
457
+ } satisfies PlAgCellButtonAxisParams,
458
+ ).catch((err) => {
459
+ gridApi.updateGridOptions({
460
+ loading: false,
461
+ loadingOverlayComponentParams: { notReady: false },
462
+ });
463
+ throw err;
464
+ });
465
+
466
+ return gridApi.updateGridOptions({
467
+ loading: false,
468
+ loadingOverlayComponentParams: { notReady: false },
469
+ ...options,
470
+ });
471
+ }
472
+
473
+ default:
474
+ throw Error(`unsupported source type: ${sourceType satisfies never}`);
475
+ }
476
+ } catch (error: unknown) {
477
+ // How should we handle possible errors?
478
+ console.trace(error);
479
+ }
480
+ },
481
+ { immediate: true, deep: true },
482
+ );
483
+ </script>
484
+
485
+ <template>
486
+ <div class="ap-ag-data-table-container">
487
+ <PlAgGridColumnManager v-if="gridApi && showColumnsPanel" :api="gridApi" :width="columnsPanelWidth" />
488
+ <PlAgCsvExporter v-if="gridApi && showExportButton" :api="gridApi" />
489
+ <div
490
+ v-if="hasSheets(settings) || $slots['before-sheets'] || $slots['after-sheets']"
491
+ class="ap-ag-data-table-sheets"
492
+ >
493
+ <slot name="before-sheets" />
494
+ <template
495
+ v-if="hasSheets(settings)"
496
+ >
497
+ <PlDropdownLine
498
+ v-for="(sheet, i) in settings.sheets"
499
+ :key="i"
500
+ :model-value="sheetsState[makeSheetId(sheet.axis)]"
501
+ :options="sheet.options"
502
+ :prefix="(sheet.axis.annotations?.['pl7.app/label']?.trim() ?? `Unlabeled axis ${i}`) + ':'"
503
+ @update:model-value="(newValue) => onSheetChanged(makeSheetId(sheet.axis), newValue)"
504
+ />
505
+ </template>
506
+ <slot name="after-sheets" />
507
+ </div>
508
+ <AgGridVue
509
+ :key="reloadKey"
510
+ :theme="AgGridTheme"
511
+ class="ap-ag-data-table-grid"
512
+ :grid-options="gridOptions"
513
+ @grid-ready="onGridReady"
514
+ @state-updated="onStateUpdated"
515
+ @grid-pre-destroyed="onGridPreDestroyed"
516
+ />
517
+ </div>
518
+ </template>
519
+
520
+ <style lang="css" scoped>
521
+ .ap-ag-data-table-container {
522
+ display: flex;
523
+ flex-direction: column;
524
+ height: 100%;
525
+ gap: 12px;
526
+ }
527
+
528
+ .ap-ag-data-table-sheets {
529
+ display: flex;
530
+ flex-direction: row;
531
+ gap: 12px;
532
+ flex-wrap: wrap;
533
+ z-index: 3;
534
+ }
535
+
536
+ .ap-ag-data-table-grid {
537
+ flex: 1;
538
+ }
539
+ </style>
@@ -1,4 +1,5 @@
1
1
  export { default as PlDataTable } from './PlAgDataTable.vue';
2
+ export { default as PlDataTableV2 } from './PlAgDataTableV2.vue';
2
3
  export { default as PlAgOverlayLoading } from './PlAgOverlayLoading.vue';
3
4
  export { default as PlAgOverlayNoRows } from './PlAgOverlayNoRows.vue';
4
5