@platforma-sdk/ui-vue 1.40.0 → 1.40.2
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/.turbo/turbo-build.log +27 -30
- package/.turbo/turbo-type-check.log +1 -1
- package/CHANGELOG.md +15 -0
- package/dist/AgGridVue/selection.d.ts.map +1 -1
- package/dist/AgGridVue/selection.js +11 -10
- package/dist/AgGridVue/selection.js.map +1 -1
- package/dist/AgGridVue/useAgGridOptions.js +53 -54
- package/dist/AgGridVue/useAgGridOptions.js.map +1 -1
- package/dist/_virtual/_commonjsHelpers.js +3 -5
- package/dist/_virtual/_commonjsHelpers.js.map +1 -1
- package/dist/components/PlAgDataTable/PlAgDataTableV2.vue.d.ts +4 -1
- package/dist/components/PlAgDataTable/PlAgDataTableV2.vue.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/PlAgDataTableV2.vue2.js +184 -155
- package/dist/components/PlAgDataTable/PlAgDataTableV2.vue2.js.map +1 -1
- package/dist/components/PlAgDataTable/PlAgRowCount.vue.js +6 -7
- package/dist/components/PlAgDataTable/PlAgRowCount.vue.js.map +1 -1
- package/dist/components/PlAgDataTable/sources/focus-row.d.ts +5 -6
- package/dist/components/PlAgDataTable/sources/focus-row.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/sources/focus-row.js +23 -27
- package/dist/components/PlAgDataTable/sources/focus-row.js.map +1 -1
- package/dist/components/PlAgDataTable/sources/menu-items.js +1 -1
- package/dist/components/PlAgDataTable/sources/menu-items.js.map +1 -1
- package/dist/components/PlAgDataTable/sources/table-source-v2.d.ts +13 -6
- package/dist/components/PlAgDataTable/sources/table-source-v2.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/sources/table-source-v2.js +121 -113
- package/dist/components/PlAgDataTable/sources/table-source-v2.js.map +1 -1
- package/dist/components/PlAgDataTable/sources/table-state-v2.d.ts +1 -1
- package/dist/components/PlAgDataTable/sources/table-state-v2.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/sources/table-state-v2.js +48 -49
- package/dist/components/PlAgDataTable/sources/table-state-v2.js.map +1 -1
- package/dist/components/PlAgDataTable/types.d.ts +18 -5
- package/dist/components/PlAgDataTable/types.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/types.js +26 -25
- package/dist/components/PlAgDataTable/types.js.map +1 -1
- package/dist/components/PlAgRowNumCheckbox/PlAgRowNumCheckbox.vue.js +9 -10
- package/dist/components/PlAgRowNumCheckbox/PlAgRowNumCheckbox.vue.js.map +1 -1
- package/dist/components/PlAgRowNumHeader.vue.js +2 -3
- package/dist/components/PlAgRowNumHeader.vue.js.map +1 -1
- package/dist/lib/ui/uikit/dist/components/PlAutocomplete/PlAutocomplete.vue.js +1 -1
- package/dist/lib/ui/uikit/dist/components/PlDropdown/PlDropdown.vue.js +1 -1
- package/dist/lib/ui/uikit/dist/components/PlDropdownLegacy/PlDropdownLegacy.vue.js +1 -1
- package/dist/lib/ui/uikit/dist/components/PlDropdownMulti/PlDropdownMulti.vue.js +1 -1
- package/dist/lib/ui/uikit/dist/components/PlFileInput/PlFileInput.vue.js +1 -1
- package/dist/lib/ui/uikit/dist/components/PlTextArea/PlTextArea.vue.js +1 -1
- package/dist/lib/ui/uikit/dist/components/PlTextField/PlTextField.vue.js +1 -1
- package/dist/lib/ui/uikit/dist/composition/computedCached.js +13 -14
- package/dist/lib/ui/uikit/dist/composition/computedCached.js.map +1 -1
- package/dist/lib/ui/uikit/dist/composition/watchCached.js +15 -15
- package/dist/lib/ui/uikit/dist/composition/watchCached.js.map +1 -1
- package/dist/lib/ui/uikit/dist/generated/components/svg/images/{SvgRequired.vue.js → SvgRequired.vue2.js} +1 -1
- package/dist/lib/ui/uikit/dist/generated/components/svg/images/SvgRequired.vue2.js.map +1 -0
- package/dist/lib/ui/uikit/dist/sdk/model/dist/index.js +1 -1
- package/dist/lib/ui/uikit/dist/sdk/model/dist/index.js.map +1 -1
- package/dist/lib.js +256 -257
- package/dist/sdk/model/dist/index.js +111 -111
- package/dist/sdk/model/dist/index.js.map +1 -1
- package/package.json +5 -7
- package/src/AgGridVue/selection.ts +12 -10
- package/src/components/PlAgDataTable/PlAgDataTableV2.vue +66 -27
- package/src/components/PlAgDataTable/sources/focus-row.ts +26 -33
- package/src/components/PlAgDataTable/sources/menu-items.ts +1 -1
- package/src/components/PlAgDataTable/sources/table-source-v2.ts +75 -47
- package/src/components/PlAgDataTable/sources/table-state-v2.ts +30 -33
- package/src/components/PlAgDataTable/types.ts +23 -7
- package/dist/_virtual/lodash.js +0 -6
- package/dist/_virtual/lodash.js.map +0 -1
- package/dist/_virtual/lodash2.js +0 -5
- package/dist/_virtual/lodash2.js.map +0 -1
- package/dist/components/PlAgDataTable/sources/file-source.d.ts +0 -7
- package/dist/components/PlAgDataTable/sources/file-source.d.ts.map +0 -1
- package/dist/lib/ui/uikit/dist/generated/components/svg/images/SvgRequired.vue.js.map +0 -1
- package/dist/node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/lodash.js +0 -3678
- package/dist/node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/lodash.js.map +0 -1
- package/src/components/PlAgDataTable/sources/file-source.ts +0 -23
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platforma-sdk/ui-vue",
|
|
3
|
-
"version": "1.40.
|
|
3
|
+
"version": "1.40.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/lib.js",
|
|
6
6
|
"styles": "dist/lib.js",
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
"./styles": "./dist/lib.js"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@types/lodash": "^4.17.16",
|
|
16
15
|
"@types/node": "~20.16.15",
|
|
17
16
|
"@types/semver": "^7.7.0",
|
|
18
17
|
"@types/sortablejs": "^1.15.6",
|
|
@@ -27,11 +26,10 @@
|
|
|
27
26
|
"@vueuse/integrations": "^13.3.0",
|
|
28
27
|
"sortablejs": "^1.15.6",
|
|
29
28
|
"d3-format": "^3.1.0",
|
|
30
|
-
"lodash": "^4.17.17",
|
|
31
29
|
"zod": "~3.23.8",
|
|
30
|
+
"@platforma-sdk/model": "~1.40.1",
|
|
32
31
|
"@milaboratories/biowasm-tools": "^1.1.0",
|
|
33
|
-
"@milaboratories/uikit": "2.3.
|
|
34
|
-
"@platforma-sdk/model": "~1.40.0"
|
|
32
|
+
"@milaboratories/uikit": "2.3.11"
|
|
35
33
|
},
|
|
36
34
|
"devDependencies": {
|
|
37
35
|
"happy-dom": "^15.11.7",
|
|
@@ -44,9 +42,9 @@
|
|
|
44
42
|
"vitest": "^2.1.9",
|
|
45
43
|
"vue-tsc": "^2.2.10",
|
|
46
44
|
"yarpm": "^1.2.0",
|
|
47
|
-
"@milaboratories/ts-configs": "1.0.4",
|
|
48
|
-
"@milaboratories/build-configs": "1.0.4",
|
|
49
45
|
"@milaboratories/eslint-config": "^1.0.4",
|
|
46
|
+
"@milaboratories/build-configs": "1.0.4",
|
|
47
|
+
"@milaboratories/ts-configs": "1.0.4",
|
|
50
48
|
"@milaboratories/helpers": "^1.6.17"
|
|
51
49
|
},
|
|
52
50
|
"scripts": {
|
|
@@ -6,15 +6,17 @@ import type { GridApi } from 'ag-grid-enterprise';
|
|
|
6
6
|
* @returns The number of selected rows.
|
|
7
7
|
*/
|
|
8
8
|
export function getSelectedRowsCount(gridApi: GridApi) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
if (!gridApi.getGridOption('loading')) {
|
|
10
|
+
const rowModel = gridApi.getGridOption('rowModelType');
|
|
11
|
+
switch (rowModel) {
|
|
12
|
+
case 'clientSide': {
|
|
13
|
+
return gridApi.getSelectedRows().length;
|
|
14
|
+
}
|
|
15
|
+
case 'serverSide': {
|
|
16
|
+
const state = gridApi.getServerSideSelectionState();
|
|
17
|
+
// `state.selectAll` flag is ignored as we assume `selectAll` was used to select all rows
|
|
18
|
+
return state?.toggledNodes?.length ?? 0;
|
|
19
|
+
}
|
|
18
20
|
}
|
|
19
21
|
}
|
|
20
22
|
return 0;
|
|
@@ -69,7 +71,7 @@ export function deselectAll(gridApi: GridApi) {
|
|
|
69
71
|
* @returns The total number of rows.
|
|
70
72
|
*/
|
|
71
73
|
export function getTotalRowsCount(gridApi: GridApi) {
|
|
72
|
-
return gridApi.getDisplayedRowCount();
|
|
74
|
+
return gridApi.getGridOption('loading') ? 0 : gridApi.getDisplayedRowCount();
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
/**
|
|
@@ -4,11 +4,12 @@ import {
|
|
|
4
4
|
} from '@milaboratories/helpers';
|
|
5
5
|
import type {
|
|
6
6
|
AxisId,
|
|
7
|
+
AxisSpec,
|
|
7
8
|
PlDataTableGridStateCore,
|
|
8
9
|
PlDataTableStateV2,
|
|
9
10
|
PlSelectionModel,
|
|
11
|
+
PlTableColumnIdJson,
|
|
10
12
|
PTableColumnSpec,
|
|
11
|
-
PTableColumnSpecJson,
|
|
12
13
|
PTableKey,
|
|
13
14
|
} from '@platforma-sdk/model';
|
|
14
15
|
import {
|
|
@@ -49,7 +50,6 @@ import PlAgDataTableSheets from './PlAgDataTableSheets.vue';
|
|
|
49
50
|
import {
|
|
50
51
|
focusRow,
|
|
51
52
|
makeOnceTracker,
|
|
52
|
-
trackFirstDataRendered,
|
|
53
53
|
} from './sources/focus-row';
|
|
54
54
|
import {
|
|
55
55
|
autoSizeRowNumberColumn,
|
|
@@ -59,7 +59,6 @@ import type {
|
|
|
59
59
|
PlAgCellButtonAxisParams,
|
|
60
60
|
} from './sources/table-source-v2';
|
|
61
61
|
import {
|
|
62
|
-
makeRowId,
|
|
63
62
|
calculateGridOptions,
|
|
64
63
|
} from './sources/table-source-v2';
|
|
65
64
|
import type {
|
|
@@ -69,7 +68,8 @@ import type {
|
|
|
69
68
|
PlAgOverlayNoRowsParams,
|
|
70
69
|
PlDataTableSettingsV2,
|
|
71
70
|
PlDataTableSheetsSettings,
|
|
72
|
-
|
|
71
|
+
PlTableLabeledSelectionModel,
|
|
72
|
+
PlTableRowIdJson,
|
|
73
73
|
} from './types';
|
|
74
74
|
import {
|
|
75
75
|
useTableState,
|
|
@@ -82,6 +82,7 @@ const tableState = defineModel<PlDataTableStateV2>({
|
|
|
82
82
|
required: true,
|
|
83
83
|
});
|
|
84
84
|
const selection = defineModel<PlSelectionModel>('selection');
|
|
85
|
+
const selectionLabeled = defineModel<PlTableLabeledSelectionModel>('selectionLabeled');
|
|
85
86
|
const props = defineProps<{
|
|
86
87
|
/** Required component settings */
|
|
87
88
|
settings: Readonly<PlDataTableSettingsV2>;
|
|
@@ -183,10 +184,10 @@ const firstDataRenderedTracker = makeOnceTracker<GridApi<PlAgDataTableV2Row>>();
|
|
|
183
184
|
const gridOptions = shallowRef<GridOptions<PlAgDataTableV2Row>>({
|
|
184
185
|
animateRows: false,
|
|
185
186
|
suppressColumnMoveAnimation: true,
|
|
186
|
-
cellSelection: selection.value
|
|
187
|
+
cellSelection: !selection.value && !selectionLabeled.value,
|
|
187
188
|
initialState: gridState.value,
|
|
188
189
|
autoSizeStrategy: { type: 'fitCellContents' },
|
|
189
|
-
rowSelection: selection.value
|
|
190
|
+
rowSelection: selection.value || selectionLabeled.value
|
|
190
191
|
? {
|
|
191
192
|
mode: 'multiRow',
|
|
192
193
|
selectAll: 'all',
|
|
@@ -197,14 +198,18 @@ const gridOptions = shallowRef<GridOptions<PlAgDataTableV2Row>>({
|
|
|
197
198
|
}
|
|
198
199
|
: undefined,
|
|
199
200
|
onSelectionChanged: (event) => {
|
|
201
|
+
const state = event.api.getServerSideSelectionState();
|
|
200
202
|
if (selection.value) {
|
|
201
|
-
const
|
|
202
|
-
const selectedKeys = state?.toggledNodes?.map((nodeId) => parseJson(nodeId as PTableKeyJson)) ?? [];
|
|
203
|
+
const selectedKeys = state?.toggledNodes?.map((nodeId) => parseJson(nodeId as PlTableRowIdJson).axesKey) ?? [];
|
|
203
204
|
selection.value = { ...selection.value, selectedKeys };
|
|
204
205
|
}
|
|
206
|
+
if (selectionLabeled.value) {
|
|
207
|
+
const selectedLabeledKeys = state?.toggledNodes?.map((nodeId) => parseJson(nodeId as PlTableRowIdJson).labeled) ?? [];
|
|
208
|
+
selectionLabeled.value = { ...selectionLabeled.value, selectedLabeledKeys };
|
|
209
|
+
}
|
|
205
210
|
},
|
|
206
211
|
onRowDoubleClicked: (event) => {
|
|
207
|
-
if (event.data && event.data.
|
|
212
|
+
if (event.data && event.data.axesKey) emit('rowDoubleClicked', event.data.axesKey);
|
|
208
213
|
},
|
|
209
214
|
defaultColDef: {
|
|
210
215
|
suppressHeaderMenuButton: true,
|
|
@@ -247,7 +252,6 @@ const gridOptions = shallowRef<GridOptions<PlAgDataTableV2Row>>({
|
|
|
247
252
|
},
|
|
248
253
|
onGridReady: (event) => {
|
|
249
254
|
const api = event.api;
|
|
250
|
-
trackFirstDataRendered(api, firstDataRenderedTracker);
|
|
251
255
|
autoSizeRowNumberColumn(api);
|
|
252
256
|
const setGridOption = (
|
|
253
257
|
key: ManagedGridOptionKey,
|
|
@@ -300,16 +304,16 @@ const gridOptions = shallowRef<GridOptions<PlAgDataTableV2Row>>({
|
|
|
300
304
|
function makePartialState(state: GridState): PlDataTableGridStateCore {
|
|
301
305
|
return {
|
|
302
306
|
columnOrder: state.columnOrder as {
|
|
303
|
-
orderedColIds:
|
|
307
|
+
orderedColIds: PlTableColumnIdJson[];
|
|
304
308
|
} | undefined,
|
|
305
309
|
sort: state.sort as {
|
|
306
310
|
sortModel: {
|
|
307
|
-
colId:
|
|
311
|
+
colId: PlTableColumnIdJson;
|
|
308
312
|
sort: 'asc' | 'desc';
|
|
309
313
|
}[];
|
|
310
314
|
} | undefined,
|
|
311
315
|
columnVisibility: state.columnVisibility as {
|
|
312
|
-
hiddenColIds:
|
|
316
|
+
hiddenColIds: PlTableColumnIdJson[];
|
|
313
317
|
} | undefined,
|
|
314
318
|
};
|
|
315
319
|
};
|
|
@@ -362,7 +366,10 @@ watch(
|
|
|
362
366
|
);
|
|
363
367
|
|
|
364
368
|
defineExpose<PlAgDataTableV2Controller>({
|
|
365
|
-
focusRow: (rowKey) => focusRow(
|
|
369
|
+
focusRow: (rowKey) => focusRow(
|
|
370
|
+
(row) => isJsonEqual(row.data?.axesKey, rowKey),
|
|
371
|
+
firstDataRenderedTracker,
|
|
372
|
+
),
|
|
366
373
|
});
|
|
367
374
|
|
|
368
375
|
// Propagate columns for filter component
|
|
@@ -378,6 +385,12 @@ watchCached(
|
|
|
378
385
|
selectedKeys: [],
|
|
379
386
|
};
|
|
380
387
|
}
|
|
388
|
+
if (selectionLabeled.value) {
|
|
389
|
+
selectionLabeled.value = {
|
|
390
|
+
spec: [],
|
|
391
|
+
selectedLabeledKeys: [],
|
|
392
|
+
};
|
|
393
|
+
}
|
|
381
394
|
} else {
|
|
382
395
|
const isColDef = (def: ColDef | ColGroupDef): def is ColDef =>
|
|
383
396
|
!('children' in def);
|
|
@@ -386,18 +399,35 @@ watchCached(
|
|
|
386
399
|
.map((def) => def.colId)
|
|
387
400
|
.filter((colId) => colId !== undefined)
|
|
388
401
|
.filter((colId) => colId !== PlAgDataTableRowNumberColId)
|
|
389
|
-
.map((colId) => parseJson(colId as
|
|
402
|
+
.map((colId) => parseJson(colId as PlTableColumnIdJson))
|
|
390
403
|
?? [];
|
|
391
|
-
filterableColumns.value = columns;
|
|
404
|
+
filterableColumns.value = columns.map((column) => column.labeled);
|
|
392
405
|
if (selection.value) {
|
|
393
406
|
const axesSpec = columns
|
|
394
|
-
.
|
|
395
|
-
|
|
407
|
+
.reduce((acc, column) => {
|
|
408
|
+
if (column.source.type === 'axis') {
|
|
409
|
+
acc.push(column.source.spec);
|
|
410
|
+
}
|
|
411
|
+
return acc;
|
|
412
|
+
}, [] as AxisSpec[]);
|
|
396
413
|
selection.value = {
|
|
397
414
|
...selection.value,
|
|
398
415
|
axesSpec,
|
|
399
416
|
};
|
|
400
417
|
}
|
|
418
|
+
if (selectionLabeled.value) {
|
|
419
|
+
const spec = columns
|
|
420
|
+
.reduce((acc, column) => {
|
|
421
|
+
if (column.source.type === 'axis') {
|
|
422
|
+
acc.push(column.labeled);
|
|
423
|
+
}
|
|
424
|
+
return acc;
|
|
425
|
+
}, [] as PTableColumnSpec[]);
|
|
426
|
+
selectionLabeled.value = {
|
|
427
|
+
...selectionLabeled.value,
|
|
428
|
+
spec,
|
|
429
|
+
};
|
|
430
|
+
}
|
|
401
431
|
}
|
|
402
432
|
},
|
|
403
433
|
{ immediate: true },
|
|
@@ -417,10 +447,11 @@ watch(
|
|
|
417
447
|
try {
|
|
418
448
|
// Hide no rows overlay if it is shown, or else loading overlay will not be shown
|
|
419
449
|
gridApi.hideOverlay();
|
|
450
|
+
firstDataRenderedTracker.reset();
|
|
420
451
|
|
|
421
452
|
// No data source selected -> reset state to default
|
|
422
453
|
if (!settings.sourceId) {
|
|
423
|
-
|
|
454
|
+
gridApi.updateGridOptions({
|
|
424
455
|
loading: true,
|
|
425
456
|
loadingOverlayComponentParams: {
|
|
426
457
|
...gridOptions.value.loadingOverlayComponentParams,
|
|
@@ -429,6 +460,13 @@ watch(
|
|
|
429
460
|
columnDefs: undefined,
|
|
430
461
|
serverSideDatasource: undefined,
|
|
431
462
|
});
|
|
463
|
+
if (selection.value || selectionLabeled.value) {
|
|
464
|
+
gridApi.setServerSideSelectionState({
|
|
465
|
+
selectAll: false,
|
|
466
|
+
toggledNodes: [],
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
return;
|
|
432
470
|
}
|
|
433
471
|
|
|
434
472
|
// Data source changed -> show full page loader, clear selection
|
|
@@ -440,7 +478,7 @@ watch(
|
|
|
440
478
|
notReady: false,
|
|
441
479
|
} satisfies PlAgOverlayLoadingParams,
|
|
442
480
|
});
|
|
443
|
-
if (selection.value) {
|
|
481
|
+
if (selection.value || selectionLabeled.value) {
|
|
444
482
|
gridApi.setServerSideSelectionState({
|
|
445
483
|
selectAll: false,
|
|
446
484
|
toggledNodes: [],
|
|
@@ -466,19 +504,20 @@ watch(
|
|
|
466
504
|
|
|
467
505
|
// Model ready -> calculate new state
|
|
468
506
|
const stateGeneration = generation.value;
|
|
469
|
-
calculateGridOptions(
|
|
507
|
+
calculateGridOptions({
|
|
470
508
|
generation,
|
|
471
|
-
getRawPlatformaInstance().pFrameDriver,
|
|
472
|
-
settings.model,
|
|
473
|
-
settings.sheets ?? [],
|
|
474
|
-
|
|
475
|
-
|
|
509
|
+
pfDriver: getRawPlatformaInstance().pFrameDriver,
|
|
510
|
+
model: settings.model,
|
|
511
|
+
sheets: settings.sheets ?? [],
|
|
512
|
+
track: firstDataRenderedTracker.track,
|
|
513
|
+
hiddenColIds: gridState.value.columnVisibility?.hiddenColIds,
|
|
514
|
+
cellButtonAxisParams: {
|
|
476
515
|
showCellButtonForAxisId: props.showCellButtonForAxisId,
|
|
477
516
|
cellButtonInvokeRowsOnDoubleClick:
|
|
478
517
|
props.cellButtonInvokeRowsOnDoubleClick,
|
|
479
518
|
trigger: (key?: PTableKey) => emit('cellButtonClicked', key),
|
|
480
519
|
} satisfies PlAgCellButtonAxisParams,
|
|
481
|
-
).then((options) => {
|
|
520
|
+
}).then((options) => {
|
|
482
521
|
if (gridApi.isDestroyed() || stateGeneration !== generation.value) return;
|
|
483
522
|
return gridApi.updateGridOptions({
|
|
484
523
|
...options,
|
|
@@ -1,45 +1,35 @@
|
|
|
1
1
|
import type { GridApi, IRowNode } from 'ag-grid-enterprise';
|
|
2
|
-
import { nextTick, shallowRef,
|
|
2
|
+
import { nextTick, shallowRef, watch } from 'vue';
|
|
3
3
|
|
|
4
4
|
export function makeOnceTracker<TContext = undefined>() {
|
|
5
5
|
const state = shallowRef<[false, undefined] | [true, TContext]>([false, undefined]);
|
|
6
|
-
const track = (ctx: TContext) =>
|
|
7
|
-
|
|
6
|
+
const track = (ctx: TContext): void => {
|
|
7
|
+
state.value = [true, ctx];
|
|
8
|
+
};
|
|
9
|
+
const reset = (): void => {
|
|
10
|
+
state.value = [false, undefined];
|
|
11
|
+
};
|
|
8
12
|
const onceTracked = (callback: (ctx: TContext) => void) => {
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
const handle = watch(
|
|
14
|
+
state,
|
|
15
|
+
([tracked, context]) => {
|
|
16
|
+
if (tracked) {
|
|
17
|
+
callback(context);
|
|
18
|
+
nextTick(() => handle.stop());
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
{ immediate: true },
|
|
22
|
+
);
|
|
23
|
+
return handle;
|
|
17
24
|
};
|
|
18
25
|
return { track, reset, onceTracked };
|
|
19
26
|
}
|
|
20
27
|
export type OnceTracker<TContext = undefined> = ReturnType<typeof makeOnceTracker<TContext>>;
|
|
21
28
|
|
|
22
|
-
|
|
23
|
-
gridApi.addEventListener('firstDataRendered', (event) => {
|
|
24
|
-
if (event.api.getGridOption('rowModelType') === 'clientSide') {
|
|
25
|
-
tracker.track(event.api);
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
gridApi.addEventListener('modelUpdated', (event) => {
|
|
29
|
-
if (event.api.getGridOption('rowModelType') === 'serverSide') {
|
|
30
|
-
const groupState = event.api.getServerSideGroupLevelState();
|
|
31
|
-
if (groupState && groupState.length > 0 && groupState[0].lastRowIndexKnown) {
|
|
32
|
-
tracker.track(event.api);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
gridApi.addEventListener('gridPreDestroyed', () => tracker.reset());
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function ensureNodeVisible(api: GridApi, rowId: string): void {
|
|
29
|
+
function ensureNodeVisible<TData>(api: GridApi<TData>, selector: (row: IRowNode<TData>) => boolean): void {
|
|
40
30
|
let rowIndex: number | null = null;
|
|
41
|
-
const nodeSelector = (row: IRowNode): boolean => {
|
|
42
|
-
if (row
|
|
31
|
+
const nodeSelector = (row: IRowNode<TData>): boolean => {
|
|
32
|
+
if (selector(row)) {
|
|
43
33
|
rowIndex = row.rowIndex;
|
|
44
34
|
return true;
|
|
45
35
|
}
|
|
@@ -55,10 +45,13 @@ function ensureNodeVisible(api: GridApi, rowId: string): void {
|
|
|
55
45
|
}
|
|
56
46
|
};
|
|
57
47
|
|
|
58
|
-
export async function focusRow
|
|
48
|
+
export async function focusRow<TData>(
|
|
49
|
+
selector: (row: IRowNode<TData>) => boolean,
|
|
50
|
+
tracker: OnceTracker<GridApi<TData>>,
|
|
51
|
+
): Promise<void> {
|
|
59
52
|
return new Promise((resolve) => {
|
|
60
53
|
nextTick(() => tracker.onceTracked((gridApi) => {
|
|
61
|
-
ensureNodeVisible(gridApi,
|
|
54
|
+
ensureNodeVisible(gridApi, selector);
|
|
62
55
|
resolve();
|
|
63
56
|
}));
|
|
64
57
|
});
|
|
@@ -12,22 +12,24 @@ import {
|
|
|
12
12
|
type PlDataTableModel,
|
|
13
13
|
type PTableColumnSpec,
|
|
14
14
|
type PTableKey,
|
|
15
|
+
type PlTableColumnId,
|
|
16
|
+
type PlTableColumnIdJson,
|
|
15
17
|
isLabelColumn as isLabelColumnSpec,
|
|
16
18
|
} from '@platforma-sdk/model';
|
|
17
19
|
import type {
|
|
18
20
|
CellStyle,
|
|
19
21
|
ColDef,
|
|
22
|
+
GridApi,
|
|
20
23
|
ICellRendererParams,
|
|
21
24
|
IServerSideDatasource,
|
|
22
25
|
IServerSideGetRowsParams,
|
|
23
26
|
ManagedGridOptions,
|
|
24
27
|
} from 'ag-grid-enterprise';
|
|
25
28
|
import canonicalize from 'canonicalize';
|
|
26
|
-
import * as lodash from 'lodash';
|
|
27
29
|
import type { PlAgHeaderComponentParams, PlAgHeaderComponentType } from '../../PlAgColumnHeader';
|
|
28
30
|
import { PlAgColumnHeader } from '../../PlAgColumnHeader';
|
|
29
31
|
import { PlAgTextAndButtonCell } from '../../PlAgTextAndButtonCell';
|
|
30
|
-
import type { PlAgDataTableV2Row,
|
|
32
|
+
import type { PlAgDataTableV2Row, PlTableRowId } from '../types';
|
|
31
33
|
import {
|
|
32
34
|
PTableHidden,
|
|
33
35
|
} from './common';
|
|
@@ -35,6 +37,7 @@ import { defaultMainMenuItems } from './menu-items';
|
|
|
35
37
|
import { makeRowNumberColDef, PlAgDataTableRowNumberColId } from './row-number';
|
|
36
38
|
import { getColumnRenderingSpec } from './value-rendering';
|
|
37
39
|
import type { Ref } from 'vue';
|
|
40
|
+
import { isJsonEqual } from '@milaboratories/helpers';
|
|
38
41
|
|
|
39
42
|
export function isLabelColumn(column: PTableColumnSpec) {
|
|
40
43
|
return column.type === 'column' && isLabelColumnSpec(column.spec);
|
|
@@ -45,16 +48,26 @@ function columns2rows(
|
|
|
45
48
|
fields: number[],
|
|
46
49
|
columns: PTableVector[],
|
|
47
50
|
axes: number[],
|
|
51
|
+
labeledAxes: number[],
|
|
48
52
|
resultMapping: number[],
|
|
49
53
|
): PlAgDataTableV2Row[] {
|
|
50
54
|
const rowData: PlAgDataTableV2Row[] = [];
|
|
51
55
|
for (let iRow = 0; iRow < columns[0].data.length; ++iRow) {
|
|
52
|
-
const
|
|
56
|
+
const axesKey = axes.map((iAxis) => {
|
|
53
57
|
return mapPTableValueToAxisKey(
|
|
54
58
|
pTableValue(columns[resultMapping[iAxis]], iRow),
|
|
55
59
|
);
|
|
56
60
|
});
|
|
57
|
-
const
|
|
61
|
+
const labeled = labeledAxes.map((iAxis) => {
|
|
62
|
+
return mapPTableValueToAxisKey(
|
|
63
|
+
pTableValue(columns[resultMapping[iAxis]], iRow),
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
const id = canonicalizeJson<PlTableRowId>({
|
|
67
|
+
axesKey,
|
|
68
|
+
labeled,
|
|
69
|
+
});
|
|
70
|
+
const row: PlAgDataTableV2Row = { id, axesKey };
|
|
58
71
|
fields.forEach((field, iCol) => {
|
|
59
72
|
row[field.toString() as `${number}`] = resultMapping[iCol] === -1
|
|
60
73
|
? PTableHidden
|
|
@@ -66,14 +79,23 @@ function columns2rows(
|
|
|
66
79
|
}
|
|
67
80
|
|
|
68
81
|
/** Calculate GridOptions for selected p-table data source */
|
|
69
|
-
export async function calculateGridOptions(
|
|
70
|
-
generation
|
|
71
|
-
pfDriver
|
|
72
|
-
model
|
|
73
|
-
sheets
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
82
|
+
export async function calculateGridOptions({
|
|
83
|
+
generation,
|
|
84
|
+
pfDriver,
|
|
85
|
+
model,
|
|
86
|
+
sheets,
|
|
87
|
+
track,
|
|
88
|
+
hiddenColIds,
|
|
89
|
+
cellButtonAxisParams,
|
|
90
|
+
}: {
|
|
91
|
+
generation: Ref<number>;
|
|
92
|
+
pfDriver: PFrameDriver;
|
|
93
|
+
model: PlDataTableModel;
|
|
94
|
+
sheets: PlDataTableSheet[];
|
|
95
|
+
track: (ctx: GridApi<PlAgDataTableV2Row>) => void;
|
|
96
|
+
hiddenColIds?: PlTableColumnIdJson[];
|
|
97
|
+
cellButtonAxisParams?: PlAgCellButtonAxisParams;
|
|
98
|
+
}): Promise<Pick<ManagedGridOptions<PlAgDataTableV2Row>, 'columnDefs' | 'serverSideDatasource'>> {
|
|
77
99
|
const pt = model.visibleTableHandle;
|
|
78
100
|
const specs = await pfDriver.getSpec(model.fullTableHandle);
|
|
79
101
|
type SpecId = string;
|
|
@@ -99,14 +121,13 @@ export async function calculateGridOptions(
|
|
|
99
121
|
const indices = [...specs.keys()]
|
|
100
122
|
.filter(
|
|
101
123
|
(i) =>
|
|
102
|
-
!
|
|
103
|
-
sheets,
|
|
124
|
+
!sheets.some(
|
|
104
125
|
(sheet) =>
|
|
105
|
-
|
|
126
|
+
isJsonEqual(getAxisId(sheet.axis), specs[i].id)
|
|
106
127
|
|| (specs[i].type === 'column'
|
|
107
128
|
&& specs[i].spec.name === 'pl7.app/label'
|
|
108
129
|
&& specs[i].spec.axesSpec.length === 1
|
|
109
|
-
&&
|
|
130
|
+
&& isJsonEqual(getAxisId(sheet.axis), getAxisId(specs[i].spec.axesSpec[0]))),
|
|
110
131
|
),
|
|
111
132
|
)
|
|
112
133
|
.sort((a, b) => {
|
|
@@ -130,7 +151,7 @@ export async function calculateGridOptions(
|
|
|
130
151
|
|
|
131
152
|
// axis of labels
|
|
132
153
|
const axisId = getAxisId((specs[idx].spec as PColumnSpec).axesSpec[0]);
|
|
133
|
-
const axisIdx = indices.findIndex((idx) =>
|
|
154
|
+
const axisIdx = indices.findIndex((idx) => isJsonEqual(specs[idx].id, axisId));
|
|
134
155
|
if (axisIdx !== -1) {
|
|
135
156
|
indices[axisIdx] = idx;
|
|
136
157
|
} else {
|
|
@@ -144,7 +165,7 @@ export async function calculateGridOptions(
|
|
|
144
165
|
|
|
145
166
|
const columnDefs: ColDef<PlAgDataTableV2Row>[] = [
|
|
146
167
|
makeRowNumberColDef(),
|
|
147
|
-
...fields.map((
|
|
168
|
+
...fields.map((field, index) => makeColDef(field, specs[field], specs[indices[index]], hiddenColIds, cellButtonAxisParams)),
|
|
148
169
|
];
|
|
149
170
|
|
|
150
171
|
// mixing in axis indices
|
|
@@ -170,21 +191,24 @@ export async function calculateGridOptions(
|
|
|
170
191
|
|
|
171
192
|
// Construct the `axes` array for key generation in `columns2rows`.
|
|
172
193
|
// The key components should be ordered according to the display order of axis columns from the `fields` array.
|
|
173
|
-
const axes: number[] = fields
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
194
|
+
const axes: number[] = fields
|
|
195
|
+
.filter((field) => specs[field].type === 'axis')
|
|
196
|
+
.map((field) => {
|
|
197
|
+
const r = allIndices.indexOf(field);
|
|
198
|
+
if (r === -1) {
|
|
199
|
+
throw new Error(
|
|
200
|
+
`Assertion failed: Original axis spec index ${field} (from fields) for key construction not found in allIndices.`,
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
return r;
|
|
204
|
+
});
|
|
205
|
+
const labeledAxes: number[] = fields
|
|
206
|
+
.reduce((acc, field, index) => {
|
|
207
|
+
if (specs[field].type === 'axis') {
|
|
208
|
+
acc.push(allIndices.indexOf(indices[index]));
|
|
209
|
+
}
|
|
210
|
+
return acc;
|
|
211
|
+
}, [] as number[]);
|
|
188
212
|
|
|
189
213
|
const requestIndices: number[] = [];
|
|
190
214
|
const resultMapping: number[] = [];
|
|
@@ -207,7 +231,7 @@ export async function calculateGridOptions(
|
|
|
207
231
|
try {
|
|
208
232
|
if (rowCount === -1) {
|
|
209
233
|
const ptShape = await pfDriver.getShape(pt);
|
|
210
|
-
if (stateGeneration !== generation.value) return params.fail();
|
|
234
|
+
if (stateGeneration !== generation.value || params.api.isDestroyed()) return params.fail();
|
|
211
235
|
rowCount = ptShape.rows;
|
|
212
236
|
}
|
|
213
237
|
|
|
@@ -221,7 +245,7 @@ export async function calculateGridOptions(
|
|
|
221
245
|
}
|
|
222
246
|
|
|
223
247
|
// If sort has changed - show skeletons instead of data
|
|
224
|
-
if (lastParams && !
|
|
248
|
+
if (lastParams && !isJsonEqual(lastParams.request.sortModel, params.request.sortModel)) {
|
|
225
249
|
return params.success({ rowData: [], rowCount });
|
|
226
250
|
}
|
|
227
251
|
lastParams = params;
|
|
@@ -235,8 +259,8 @@ export async function calculateGridOptions(
|
|
|
235
259
|
offset: params.request.startRow,
|
|
236
260
|
length,
|
|
237
261
|
});
|
|
238
|
-
if (stateGeneration !== generation.value) return params.fail();
|
|
239
|
-
rowData = columns2rows(fields, data, axes, resultMapping);
|
|
262
|
+
if (stateGeneration !== generation.value || params.api.isDestroyed()) return params.fail();
|
|
263
|
+
rowData = columns2rows(fields, data, axes, labeledAxes, resultMapping);
|
|
240
264
|
}
|
|
241
265
|
}
|
|
242
266
|
|
|
@@ -247,10 +271,14 @@ export async function calculateGridOptions(
|
|
|
247
271
|
);
|
|
248
272
|
params.api.setGridOption('loading', false);
|
|
249
273
|
} catch (error: unknown) {
|
|
250
|
-
if (stateGeneration !== generation.value) return params.fail();
|
|
274
|
+
if (stateGeneration !== generation.value || params.api.isDestroyed()) return params.fail();
|
|
251
275
|
params.api.setGridOption('loading', true);
|
|
252
276
|
params.fail();
|
|
253
277
|
console.trace(error);
|
|
278
|
+
} finally {
|
|
279
|
+
if (!params.api.isDestroyed()) {
|
|
280
|
+
track(params.api);
|
|
281
|
+
}
|
|
254
282
|
}
|
|
255
283
|
},
|
|
256
284
|
};
|
|
@@ -273,10 +301,14 @@ export type PlAgCellButtonAxisParams = {
|
|
|
273
301
|
export function makeColDef(
|
|
274
302
|
iCol: number,
|
|
275
303
|
spec: PTableColumnSpec,
|
|
276
|
-
|
|
304
|
+
labeledSpec: PTableColumnSpec,
|
|
305
|
+
hiddenColIds: PlTableColumnIdJson[] | undefined,
|
|
277
306
|
cellButtonAxisParams?: PlAgCellButtonAxisParams,
|
|
278
307
|
): ColDef {
|
|
279
|
-
const colId = canonicalizeJson<
|
|
308
|
+
const colId = canonicalizeJson<PlTableColumnId>({
|
|
309
|
+
source: spec,
|
|
310
|
+
labeled: labeledSpec,
|
|
311
|
+
});
|
|
280
312
|
const valueType = spec.type === 'axis' ? spec.spec.type : spec.spec.valueType;
|
|
281
313
|
const columnRenderingSpec = getColumnRenderingSpec(spec);
|
|
282
314
|
const cellStyle: CellStyle = {};
|
|
@@ -293,7 +325,7 @@ export function makeColDef(
|
|
|
293
325
|
mainMenuItems: defaultMainMenuItems,
|
|
294
326
|
context: spec,
|
|
295
327
|
field: iCol.toString(),
|
|
296
|
-
headerName:
|
|
328
|
+
headerName: labeledSpec.spec.annotations?.['pl7.app/label']?.trim() ?? 'Unlabeled ' + spec.type + ' ' + iCol.toString(),
|
|
297
329
|
lockPosition: spec.type === 'axis',
|
|
298
330
|
hide: hiddenColIds?.includes(colId) ?? isColumnOptional(spec.spec),
|
|
299
331
|
valueFormatter: columnRenderingSpec.valueFormatter,
|
|
@@ -303,13 +335,13 @@ export function makeColDef(
|
|
|
303
335
|
if (spec.type !== 'axis') return;
|
|
304
336
|
|
|
305
337
|
const axisId = (params.colDef?.context as PTableColumnSpec)?.id as AxisId;
|
|
306
|
-
if (
|
|
338
|
+
if (isJsonEqual(axisId, cellButtonAxisParams.showCellButtonForAxisId)) {
|
|
307
339
|
return {
|
|
308
340
|
component: PlAgTextAndButtonCell,
|
|
309
341
|
params: {
|
|
310
342
|
invokeRowsOnDoubleClick: cellButtonAxisParams.cellButtonInvokeRowsOnDoubleClick,
|
|
311
343
|
onClick: (params: ICellRendererParams<PlAgDataTableV2Row>) => {
|
|
312
|
-
cellButtonAxisParams.trigger(params.data?.
|
|
344
|
+
cellButtonAxisParams.trigger(params.data?.axesKey);
|
|
313
345
|
},
|
|
314
346
|
},
|
|
315
347
|
};
|
|
@@ -349,7 +381,3 @@ export function makeColDef(
|
|
|
349
381
|
})(),
|
|
350
382
|
};
|
|
351
383
|
}
|
|
352
|
-
|
|
353
|
-
export function makeRowId(rowKey: PTableKey): PTableKeyJson {
|
|
354
|
-
return canonicalizeJson(rowKey);
|
|
355
|
-
}
|