@platforma-sdk/ui-vue 1.41.3 → 1.41.6
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 +21 -31
- package/.turbo/turbo-type-check.log +1 -1
- package/CHANGELOG.md +18 -0
- package/dist/aggrid.js +4 -4
- package/dist/components/PlAgDataTable/PlAgDataTableV2.vue.d.ts +14 -3
- package/dist/components/PlAgDataTable/PlAgDataTableV2.vue.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/PlAgDataTableV2.vue2.js +252 -179
- package/dist/components/PlAgDataTable/PlAgDataTableV2.vue2.js.map +1 -1
- package/dist/components/PlAgDataTable/PlAgRowCount.vue.js +1 -1
- package/dist/components/PlAgDataTable/sources/focus-row.d.ts +8 -7
- package/dist/components/PlAgDataTable/sources/focus-row.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/sources/focus-row.js +46 -31
- package/dist/components/PlAgDataTable/sources/focus-row.js.map +1 -1
- package/dist/components/PlAgDataTable/sources/table-source-v2.d.ts +10 -5
- package/dist/components/PlAgDataTable/sources/table-source-v2.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/sources/table-source-v2.js +144 -141
- package/dist/components/PlAgDataTable/sources/table-source-v2.js.map +1 -1
- package/dist/components/PlAgDataTable/types.d.ts +27 -1
- package/dist/components/PlAgDataTable/types.d.ts.map +1 -1
- package/dist/components/PlAgDataTable/types.js.map +1 -1
- package/dist/components/PlAgRowNumCheckbox/PlAgRowNumCheckbox.vue.js +1 -1
- package/dist/components/PlAgRowNumHeader.vue.js +1 -1
- package/dist/components/PlAnnotations/components/DynamicForm.vue2.js +24 -24
- package/dist/components/PlAnnotations/components/FilterSidebar.vue2.js +2 -2
- package/dist/internal/test-helpers/BlockMock.d.ts +1 -0
- package/dist/internal/test-helpers/BlockMock.d.ts.map +1 -1
- package/dist/lib/ui/uikit/dist/components/PlAccordion/{ExpandTransition.vue.js → ExpandTransition.vue2.js} +1 -1
- package/dist/lib/ui/uikit/dist/components/PlAccordion/ExpandTransition.vue2.js.map +1 -0
- package/dist/lib/ui/uikit/dist/components/PlAccordion/PlAccordionSection.vue2.js +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/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/util/helpers/dist/index.js +88 -73
- package/dist/lib/util/helpers/dist/index.js.map +1 -1
- package/dist/lib.js +73 -73
- package/dist/sdk/model/dist/index.js +82 -75
- package/dist/sdk/model/dist/index.js.map +1 -1
- package/package.json +10 -10
- package/src/components/PlAgDataTable/PlAgDataTableV2.vue +172 -45
- package/src/components/PlAgDataTable/sources/focus-row.ts +38 -37
- package/src/components/PlAgDataTable/sources/table-source-v2.ts +113 -110
- package/src/components/PlAgDataTable/types.ts +30 -1
- package/src/internal/test-helpers/BlockMock.ts +5 -0
- package/dist/lib/ui/uikit/dist/components/PlAccordion/ExpandTransition.vue.js.map +0 -1
- package/dist/lib/ui/uikit/dist/generated/components/svg/images/SvgRequired.vue.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platforma-sdk/ui-vue",
|
|
3
|
-
"version": "1.41.
|
|
3
|
+
"version": "1.41.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/lib.js",
|
|
6
6
|
"styles": "dist/lib.js",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": {
|
|
9
|
-
"
|
|
9
|
+
"sources": "./src/lib.ts",
|
|
10
10
|
"default": "./dist/lib.js"
|
|
11
11
|
},
|
|
12
12
|
"./styles": "./dist/lib.js"
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
"@types/semver": "^7.7.0",
|
|
17
17
|
"@types/d3-format": "^3.0.4",
|
|
18
18
|
"@milaboratories/miplots4": "^1.0.123",
|
|
19
|
-
"ag-grid-enterprise": "^
|
|
20
|
-
"ag-grid-vue3": "^
|
|
19
|
+
"ag-grid-enterprise": "^34.0.2",
|
|
20
|
+
"ag-grid-vue3": "^34.0.2",
|
|
21
21
|
"canonicalize": "~2.1.0",
|
|
22
22
|
"lru-cache": "^11.1.0",
|
|
23
23
|
"vue": "^3.5.13",
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"@vueuse/integrations": "^13.3.0",
|
|
26
26
|
"d3-format": "^3.1.0",
|
|
27
27
|
"zod": "~3.23.8",
|
|
28
|
+
"@milaboratories/uikit": "2.3.21",
|
|
28
29
|
"@milaboratories/biowasm-tools": "^1.1.0",
|
|
29
|
-
"@
|
|
30
|
-
"@platforma-sdk/model": "~1.41.3"
|
|
30
|
+
"@platforma-sdk/model": "~1.41.6"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"happy-dom": "^15.11.7",
|
|
@@ -43,10 +43,10 @@
|
|
|
43
43
|
"yarpm": "^1.2.0",
|
|
44
44
|
"fast-json-patch": "^3.1.1",
|
|
45
45
|
"@faker-js/faker": "^9.2.0",
|
|
46
|
-
"@milaboratories/
|
|
47
|
-
"@milaboratories/
|
|
48
|
-
"@milaboratories/
|
|
49
|
-
"@milaboratories/
|
|
46
|
+
"@milaboratories/helpers": "^1.6.19",
|
|
47
|
+
"@milaboratories/ts-configs": "1.0.5",
|
|
48
|
+
"@milaboratories/eslint-config": "^1.0.4",
|
|
49
|
+
"@milaboratories/build-configs": "1.0.5"
|
|
50
50
|
},
|
|
51
51
|
"scripts": {
|
|
52
52
|
"test": "vitest run --passWithNoTests",
|
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
-
import { isJsonEqual } from '@milaboratories/helpers';
|
|
2
|
+
import { promiseTimeout, isJsonEqual } from '@milaboratories/helpers';
|
|
3
3
|
import type {
|
|
4
4
|
AxisId,
|
|
5
|
-
AxisSpec,
|
|
6
5
|
PlDataTableGridStateCore,
|
|
7
6
|
PlDataTableStateV2,
|
|
8
7
|
PlSelectionModel,
|
|
9
8
|
PlTableColumnIdJson,
|
|
10
9
|
PTableColumnSpec,
|
|
11
10
|
PTableKey,
|
|
11
|
+
PTableValue,
|
|
12
|
+
} from '@platforma-sdk/model';
|
|
13
|
+
import {
|
|
14
|
+
getRawPlatformaInstance,
|
|
15
|
+
parseJson,
|
|
16
|
+
createPlSelectionModel,
|
|
17
|
+
matchAxisId,
|
|
18
|
+
getAxisId,
|
|
19
|
+
canonicalizeJson,
|
|
12
20
|
} from '@platforma-sdk/model';
|
|
13
|
-
import { getRawPlatformaInstance, parseJson } from '@platforma-sdk/model';
|
|
14
21
|
import type {
|
|
15
22
|
CellRendererSelectorFunc,
|
|
16
23
|
ColDef,
|
|
@@ -22,7 +29,7 @@ import type {
|
|
|
22
29
|
ManagedGridOptions,
|
|
23
30
|
} from 'ag-grid-enterprise';
|
|
24
31
|
import { AgGridVue } from 'ag-grid-vue3';
|
|
25
|
-
import { computed, ref, shallowRef, toRefs, watch } from 'vue';
|
|
32
|
+
import { computed, effectScope, ref, shallowRef, toRefs, watch } from 'vue';
|
|
26
33
|
import { AgGridTheme } from '../../aggrid';
|
|
27
34
|
import PlAgCsvExporter from '../PlAgCsvExporter/PlAgCsvExporter.vue';
|
|
28
35
|
import { PlAgGridColumnManager } from '../PlAgGridColumnManager';
|
|
@@ -32,7 +39,7 @@ import PlAgDataTableSheets from './PlAgDataTableSheets.vue';
|
|
|
32
39
|
import PlOverlayLoading from './PlAgOverlayLoading.vue';
|
|
33
40
|
import PlOverlayNoRows from './PlAgOverlayNoRows.vue';
|
|
34
41
|
import PlAgRowCount from './PlAgRowCount.vue';
|
|
35
|
-
import {
|
|
42
|
+
import { DeferredCircular, ensureNodeVisible } from './sources/focus-row';
|
|
36
43
|
import { autoSizeRowNumberColumn, PlAgDataTableRowNumberColId } from './sources/row-number';
|
|
37
44
|
import type { PlAgCellButtonAxisParams } from './sources/table-source-v2';
|
|
38
45
|
import { calculateGridOptions } from './sources/table-source-v2';
|
|
@@ -44,13 +51,16 @@ import type {
|
|
|
44
51
|
PlAgOverlayNoRowsParams,
|
|
45
52
|
PlDataTableSettingsV2,
|
|
46
53
|
PlDataTableSheetsSettings,
|
|
54
|
+
PlTableRowId,
|
|
47
55
|
PlTableRowIdJson,
|
|
48
56
|
} from './types';
|
|
49
57
|
import { watchCached } from '@milaboratories/uikit';
|
|
58
|
+
import { isPTableHidden, type PTableHidden } from './sources/common';
|
|
50
59
|
|
|
51
60
|
const tableState = defineModel<PlDataTableStateV2>({
|
|
52
61
|
required: true,
|
|
53
62
|
});
|
|
63
|
+
/** Warning: selection model value updates are ignored, use updateSelection instead */
|
|
54
64
|
const selection = defineModel<PlSelectionModel>('selection');
|
|
55
65
|
const props = defineProps<{
|
|
56
66
|
/** Required component settings */
|
|
@@ -113,6 +123,7 @@ const { settings } = toRefs(props);
|
|
|
113
123
|
const emit = defineEmits<{
|
|
114
124
|
rowDoubleClicked: [key?: PTableKey];
|
|
115
125
|
cellButtonClicked: [key?: PTableKey];
|
|
126
|
+
newDataRendered: [];
|
|
116
127
|
}>();
|
|
117
128
|
|
|
118
129
|
const { gridState, sheetsState, filtersState } = useTableState(tableState, settings);
|
|
@@ -149,7 +160,7 @@ const filtersSettings = computed<PlDataTableFiltersSettings>(() => {
|
|
|
149
160
|
});
|
|
150
161
|
|
|
151
162
|
const gridApi = shallowRef<GridApi<PlAgDataTableV2Row> | null>(null);
|
|
152
|
-
const
|
|
163
|
+
const dataRenderedTracker = new DeferredCircular<GridApi<PlAgDataTableV2Row>>();
|
|
153
164
|
const gridOptions = shallowRef<GridOptions<PlAgDataTableV2Row>>({
|
|
154
165
|
animateRows: false,
|
|
155
166
|
suppressColumnMoveAnimation: true,
|
|
@@ -170,7 +181,9 @@ const gridOptions = shallowRef<GridOptions<PlAgDataTableV2Row>>({
|
|
|
170
181
|
if (selection.value) {
|
|
171
182
|
const state = event.api.getServerSideSelectionState();
|
|
172
183
|
const selectedKeys = state?.toggledNodes?.map((nodeId) => parseJson(nodeId as PlTableRowIdJson)) ?? [];
|
|
173
|
-
selection.value
|
|
184
|
+
if (!isJsonEqual(selection.value.selectedKeys, selectedKeys)) {
|
|
185
|
+
selection.value = { ...selection.value, selectedKeys };
|
|
186
|
+
}
|
|
174
187
|
}
|
|
175
188
|
},
|
|
176
189
|
onRowDoubleClicked: (event) => {
|
|
@@ -331,12 +344,101 @@ watch(
|
|
|
331
344
|
);
|
|
332
345
|
|
|
333
346
|
defineExpose<PlAgDataTableV2Controller>({
|
|
334
|
-
focusRow: (rowKey) =>
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
347
|
+
focusRow: async (rowKey) => {
|
|
348
|
+
const gridApi = await dataRenderedTracker.promise;
|
|
349
|
+
if (gridApi.isDestroyed()) return false;
|
|
350
|
+
|
|
351
|
+
return ensureNodeVisible(gridApi, (row) => isJsonEqual(row.data?.axesKey, rowKey));
|
|
352
|
+
},
|
|
353
|
+
updateSelection: async ({ axesSpec, selectedKeys }) => {
|
|
354
|
+
const gridApi = await dataRenderedTracker.promise;
|
|
355
|
+
if (gridApi.isDestroyed()) return false;
|
|
356
|
+
|
|
357
|
+
const axes = selection.value?.axesSpec;
|
|
358
|
+
if (!axes || axes.length !== axesSpec.length) return false;
|
|
359
|
+
|
|
360
|
+
const mapping = axesSpec
|
|
361
|
+
.map((spec) => {
|
|
362
|
+
const id = getAxisId(spec);
|
|
363
|
+
return axes.findIndex((axis) => matchAxisId(axis, id));
|
|
364
|
+
});
|
|
365
|
+
const mappingSet = new Set(mapping);
|
|
366
|
+
if (mappingSet.has(-1) || mappingSet.size !== axesSpec.length) return false;
|
|
367
|
+
|
|
368
|
+
const selectedNodes = selectedKeys
|
|
369
|
+
.map((key) => canonicalizeJson<PlTableRowId>(mapping.map((index) => key[index])));
|
|
370
|
+
const oldSelectedKeys = gridApi.getServerSideSelectionState()?.toggledNodes ?? [];
|
|
371
|
+
if (!isJsonEqual(oldSelectedKeys, selectedNodes)) {
|
|
372
|
+
gridApi.setServerSideSelectionState({
|
|
373
|
+
selectAll: false,
|
|
374
|
+
toggledNodes: selectedNodes,
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
// wait for `onSelectionChanged` to update `selection` model
|
|
378
|
+
const scope = effectScope();
|
|
379
|
+
const { resolve, promise } = Promise.withResolvers();
|
|
380
|
+
scope.run(() => watch(selection, resolve, { once: true }));
|
|
381
|
+
try {
|
|
382
|
+
await promiseTimeout(promise, 500);
|
|
383
|
+
} catch {
|
|
384
|
+
return false;
|
|
385
|
+
} finally {
|
|
386
|
+
scope.stop();
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
return true;
|
|
390
|
+
},
|
|
391
|
+
getRowCount: async () => {
|
|
392
|
+
const gridApi = await dataRenderedTracker.promise;
|
|
393
|
+
if (gridApi.isDestroyed()) return;
|
|
394
|
+
|
|
395
|
+
return gridApi.getDisplayedRowCount();
|
|
396
|
+
},
|
|
397
|
+
getRow: async (index) => {
|
|
398
|
+
const gridApi = await dataRenderedTracker.promise;
|
|
399
|
+
if (gridApi.isDestroyed()) return;
|
|
400
|
+
|
|
401
|
+
const visibleColumns: {
|
|
402
|
+
spec: PTableColumnSpec;
|
|
403
|
+
field: `${number}`;
|
|
404
|
+
}[] = getDataColDefs(gridApi.getColumnDefs())
|
|
405
|
+
.filter((def) => !def.hide)
|
|
406
|
+
.map((def) => ({
|
|
407
|
+
spec: parseJson(def.colId! satisfies string as PlTableColumnIdJson).labeled,
|
|
408
|
+
field: def.field! as `${number}`,
|
|
409
|
+
}));
|
|
410
|
+
|
|
411
|
+
const row = Array.isArray(index)
|
|
412
|
+
? gridApi.getRowNode(canonicalizeJson<PlTableRowId>(index))
|
|
413
|
+
: gridApi.getDisplayedRowAtIndex(index);
|
|
414
|
+
if (!row) return;
|
|
415
|
+
|
|
416
|
+
const rowData = row.data;
|
|
417
|
+
if (!rowData) return;
|
|
418
|
+
|
|
419
|
+
const getTableValue = (value: PTableValue | PTableHidden): PTableValue => {
|
|
420
|
+
if (isPTableHidden(value)) throw new Error('hidden value was not filtered out');
|
|
421
|
+
return value;
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
const spec: PTableColumnSpec[] = visibleColumns.map((column) => column.spec);
|
|
425
|
+
const data: PTableValue[] = visibleColumns.map((column) => getTableValue(rowData[column.field]));
|
|
426
|
+
return { spec, data };
|
|
427
|
+
},
|
|
338
428
|
});
|
|
339
429
|
|
|
430
|
+
function getDataColDefs(
|
|
431
|
+
columnDefs: ColDef<PlAgDataTableV2Row, PTableValue | PTableHidden>[] | null | undefined,
|
|
432
|
+
): ColDef<PlAgDataTableV2Row, PTableValue | PTableHidden>[] {
|
|
433
|
+
const isColDef = <TData, TValue>(
|
|
434
|
+
def: ColDef<TData, TValue> | ColGroupDef<TData>,
|
|
435
|
+
): def is ColDef<TData, TValue> => !('children' in def);
|
|
436
|
+
if (!columnDefs) return [];
|
|
437
|
+
return columnDefs
|
|
438
|
+
.filter(isColDef)
|
|
439
|
+
.filter((def) => def.colId && def.colId !== PlAgDataTableRowNumberColId);
|
|
440
|
+
}
|
|
441
|
+
|
|
340
442
|
// Propagate columns for filter component
|
|
341
443
|
watchCached(
|
|
342
444
|
() => gridOptions.value.columnDefs,
|
|
@@ -344,42 +446,17 @@ watchCached(
|
|
|
344
446
|
const sourceId = settings.value.sourceId;
|
|
345
447
|
if (sourceId === null) {
|
|
346
448
|
filterableColumns.value = [];
|
|
347
|
-
if (selection.value) {
|
|
348
|
-
selection.value = {
|
|
349
|
-
axesSpec: [],
|
|
350
|
-
selectedKeys: [],
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
449
|
} else {
|
|
354
|
-
const
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
const columns = colDefs
|
|
358
|
-
.map((def) => def.colId)
|
|
359
|
-
.filter((colId) => colId !== undefined)
|
|
360
|
-
.filter((colId) => colId !== PlAgDataTableRowNumberColId)
|
|
361
|
-
.map((colId) => parseJson(colId as PlTableColumnIdJson))
|
|
362
|
-
?? [];
|
|
363
|
-
filterableColumns.value = columns.map((column) => column.labeled);
|
|
364
|
-
if (selection.value) {
|
|
365
|
-
const axesSpec = columns
|
|
366
|
-
.reduce((acc, column) => {
|
|
367
|
-
if (column.source.type === 'axis') {
|
|
368
|
-
acc.push(column.source.spec);
|
|
369
|
-
}
|
|
370
|
-
return acc;
|
|
371
|
-
}, [] as AxisSpec[]);
|
|
372
|
-
selection.value = {
|
|
373
|
-
...selection.value,
|
|
374
|
-
axesSpec,
|
|
375
|
-
};
|
|
376
|
-
}
|
|
450
|
+
const dataColumns = getDataColDefs(columnDefs);
|
|
451
|
+
filterableColumns.value = dataColumns
|
|
452
|
+
.map((def) => parseJson(def.colId! satisfies string as PlTableColumnIdJson).labeled);
|
|
377
453
|
}
|
|
378
454
|
},
|
|
379
455
|
{ immediate: true },
|
|
380
456
|
);
|
|
381
457
|
|
|
382
458
|
// Update AgGrid when settings change
|
|
459
|
+
const defaultSelection = createPlSelectionModel();
|
|
383
460
|
let oldSettings: PlDataTableSettingsV2 | null = null;
|
|
384
461
|
const generation = ref(0);
|
|
385
462
|
watch(
|
|
@@ -393,7 +470,7 @@ watch(
|
|
|
393
470
|
try {
|
|
394
471
|
// Hide no rows overlay if it is shown, or else loading overlay will not be shown
|
|
395
472
|
gridApi.hideOverlay();
|
|
396
|
-
|
|
473
|
+
dataRenderedTracker.reset();
|
|
397
474
|
|
|
398
475
|
// No data source selected -> reset state to default
|
|
399
476
|
if (!settings.sourceId) {
|
|
@@ -407,6 +484,9 @@ watch(
|
|
|
407
484
|
serverSideDatasource: undefined,
|
|
408
485
|
});
|
|
409
486
|
if (selection.value) {
|
|
487
|
+
if (selection.value && !isJsonEqual(selection.value, defaultSelection)) {
|
|
488
|
+
selection.value = createPlSelectionModel();
|
|
489
|
+
}
|
|
410
490
|
gridApi.setServerSideSelectionState({
|
|
411
491
|
selectAll: false,
|
|
412
492
|
toggledNodes: [],
|
|
@@ -424,7 +504,10 @@ watch(
|
|
|
424
504
|
notReady: false,
|
|
425
505
|
} satisfies PlAgOverlayLoadingParams,
|
|
426
506
|
});
|
|
427
|
-
if (selection.value) {
|
|
507
|
+
if (selection.value && oldSettings?.sourceId) {
|
|
508
|
+
if (selection.value && !isJsonEqual(selection.value, defaultSelection)) {
|
|
509
|
+
selection.value = createPlSelectionModel();
|
|
510
|
+
}
|
|
428
511
|
gridApi.setServerSideSelectionState({
|
|
429
512
|
selectAll: false,
|
|
430
513
|
toggledNodes: [],
|
|
@@ -455,7 +538,7 @@ watch(
|
|
|
455
538
|
pfDriver: getRawPlatformaInstance().pFrameDriver,
|
|
456
539
|
model: settings.model,
|
|
457
540
|
sheets: settings.sheets ?? [],
|
|
458
|
-
|
|
541
|
+
dataRenderedTracker,
|
|
459
542
|
hiddenColIds: gridState.value.columnVisibility?.hiddenColIds,
|
|
460
543
|
cellButtonAxisParams: {
|
|
461
544
|
showCellButtonForAxisId: props.showCellButtonForAxisId,
|
|
@@ -463,11 +546,54 @@ watch(
|
|
|
463
546
|
props.cellButtonInvokeRowsOnDoubleClick,
|
|
464
547
|
trigger: (key?: PTableKey) => emit('cellButtonClicked', key),
|
|
465
548
|
} satisfies PlAgCellButtonAxisParams,
|
|
466
|
-
}).then((
|
|
549
|
+
}).then((result) => {
|
|
467
550
|
if (gridApi.isDestroyed() || stateGeneration !== generation.value) return;
|
|
468
|
-
|
|
551
|
+
const { axesSpec, ...options } = result;
|
|
552
|
+
gridApi.updateGridOptions({
|
|
469
553
|
...options,
|
|
470
554
|
});
|
|
555
|
+
if (selection.value) {
|
|
556
|
+
// Update selection if axesSpec changed, as order of axes may have changed and so we need to remap selected keys
|
|
557
|
+
const { axesSpec: oldAxesSpec, selectedKeys: oldSelectedKeys } = selection.value;
|
|
558
|
+
if (!isJsonEqual(oldAxesSpec, axesSpec)) {
|
|
559
|
+
if (!oldAxesSpec || axesSpec.length !== oldAxesSpec.length) {
|
|
560
|
+
const newSelection: PlSelectionModel = { axesSpec, selectedKeys: [] };
|
|
561
|
+
if (!isJsonEqual(selection.value, newSelection)) {
|
|
562
|
+
selection.value = newSelection;
|
|
563
|
+
}
|
|
564
|
+
return gridApi.setServerSideSelectionState({
|
|
565
|
+
selectAll: false,
|
|
566
|
+
toggledNodes: [],
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
const mapping = oldAxesSpec
|
|
571
|
+
.map(getAxisId)
|
|
572
|
+
.map((id) => axesSpec.findIndex((axis) => matchAxisId(axis, id)));
|
|
573
|
+
const mappingSet = new Set(mapping);
|
|
574
|
+
if (mappingSet.has(-1) || mappingSet.size !== axesSpec.length) {
|
|
575
|
+
const newSelection: PlSelectionModel = { axesSpec, selectedKeys: [] };
|
|
576
|
+
if (!isJsonEqual(selection.value, newSelection)) {
|
|
577
|
+
selection.value = newSelection;
|
|
578
|
+
}
|
|
579
|
+
return gridApi.setServerSideSelectionState({
|
|
580
|
+
selectAll: false,
|
|
581
|
+
toggledNodes: [],
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
const selectedNodes = oldSelectedKeys
|
|
586
|
+
.map((key) => mapping.map((index) => key[index]));
|
|
587
|
+
const newSelection: PlSelectionModel = { axesSpec, selectedKeys: selectedNodes };
|
|
588
|
+
if (!isJsonEqual(selection.value, newSelection)) {
|
|
589
|
+
selection.value = newSelection;
|
|
590
|
+
}
|
|
591
|
+
return gridApi.setServerSideSelectionState({
|
|
592
|
+
selectAll: false,
|
|
593
|
+
toggledNodes: selectedNodes.map((key) => canonicalizeJson<PlTableRowId>(key)),
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
}
|
|
471
597
|
}).catch((error: unknown) => {
|
|
472
598
|
if (gridApi.isDestroyed() || stateGeneration !== generation.value) return;
|
|
473
599
|
console.trace(error);
|
|
@@ -477,6 +603,7 @@ watch(
|
|
|
477
603
|
loading: false,
|
|
478
604
|
});
|
|
479
605
|
});
|
|
606
|
+
dataRenderedTracker.promise.then(() => emit('newDataRendered'));
|
|
480
607
|
} catch (error: unknown) {
|
|
481
608
|
console.trace(error);
|
|
482
609
|
} finally {
|
|
@@ -1,32 +1,44 @@
|
|
|
1
1
|
import type { GridApi, IRowNode } from 'ag-grid-enterprise';
|
|
2
|
-
import {
|
|
2
|
+
import { Deferred } from '@milaboratories/helpers';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return
|
|
24
|
-
}
|
|
25
|
-
|
|
4
|
+
class DeferredTracked<T> extends Deferred<T> {
|
|
5
|
+
#resolved = false;
|
|
6
|
+
|
|
7
|
+
constructor() {
|
|
8
|
+
super();
|
|
9
|
+
this.promise.finally(() => {
|
|
10
|
+
this.#resolved = true;
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public get resolved(): boolean {
|
|
15
|
+
return this.#resolved;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class DeferredCircular<T> {
|
|
20
|
+
private deferred = new DeferredTracked<T>();
|
|
21
|
+
|
|
22
|
+
public get promise(): Promise<T> {
|
|
23
|
+
return this.deferred.promise;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public resolve(ctx: T): void {
|
|
27
|
+
this.deferred.resolve(ctx);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public get resolved(): boolean {
|
|
31
|
+
return this.deferred.resolved;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public reset(): void {
|
|
35
|
+
if (this.resolved) {
|
|
36
|
+
this.deferred = new DeferredTracked<T>();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
26
39
|
}
|
|
27
|
-
export type OnceTracker<TContext = undefined> = ReturnType<typeof makeOnceTracker<TContext>>;
|
|
28
40
|
|
|
29
|
-
function ensureNodeVisible<TData>(api: GridApi<TData>, selector: (row: IRowNode<TData>) => boolean):
|
|
41
|
+
export function ensureNodeVisible<TData>(api: GridApi<TData>, selector: (row: IRowNode<TData>) => boolean): boolean {
|
|
30
42
|
let rowIndex: number | null = null;
|
|
31
43
|
const nodeSelector = (row: IRowNode<TData>): boolean => {
|
|
32
44
|
if (selector(row)) {
|
|
@@ -43,16 +55,5 @@ function ensureNodeVisible<TData>(api: GridApi<TData>, selector: (row: IRowNode<
|
|
|
43
55
|
api.setFocusedCell(rowIndex, columns[0]);
|
|
44
56
|
}
|
|
45
57
|
}
|
|
58
|
+
return rowIndex !== null;
|
|
46
59
|
};
|
|
47
|
-
|
|
48
|
-
export async function focusRow<TData>(
|
|
49
|
-
selector: (row: IRowNode<TData>) => boolean,
|
|
50
|
-
tracker: OnceTracker<GridApi<TData>>,
|
|
51
|
-
): Promise<void> {
|
|
52
|
-
return new Promise((resolve) => {
|
|
53
|
-
nextTick(() => tracker.onceTracked((gridApi) => {
|
|
54
|
-
ensureNodeVisible(gridApi, selector);
|
|
55
|
-
resolve();
|
|
56
|
-
}));
|
|
57
|
-
});
|
|
58
|
-
}
|