@platforma-sdk/ui-vue 1.7.16 → 1.7.18

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platforma-sdk/ui-vue",
3
- "version": "1.7.16",
3
+ "version": "1.7.18",
4
4
  "type": "module",
5
5
  "main": "dist/lib.umd.cjs",
6
6
  "module": "dist/lib.js",
@@ -24,6 +24,7 @@
24
24
  "@ag-grid-community/core": "^32.3.0",
25
25
  "@ag-grid-community/client-side-row-model": "^32.3.0",
26
26
  "@ag-grid-community/infinite-row-model": "^32.3.0",
27
+ "@ag-grid-enterprise/server-side-row-model": "^32.3.0",
27
28
  "@ag-grid-community/styles": "^32.3.0",
28
29
  "@ag-grid-community/vue3": "^32.3.0",
29
30
  "@ag-grid-community/csv-export": "^32.3.0",
@@ -33,13 +34,13 @@
33
34
  "@ag-grid-enterprise/rich-select": "^32.3.0",
34
35
  "@ag-grid-enterprise/menu": "^32.3.0",
35
36
  "@ag-grid-enterprise/excel-export": "^32.3.0",
36
- "@platforma-sdk/model": "^1.7.16",
37
- "@milaboratories/uikit": "^1.2.26"
37
+ "@milaboratories/uikit": "^1.2.26",
38
+ "@platforma-sdk/model": "^1.7.16"
38
39
  },
39
40
  "devDependencies": {
40
41
  "@faker-js/faker": "^8.4.1",
41
- "@types/lodash": "^4.17.10",
42
- "@types/node": "~20.16.10",
42
+ "@types/lodash": "^4.17.12",
43
+ "@types/node": "~20.16.15",
43
44
  "@typescript-eslint/eslint-plugin": "^7.18.0",
44
45
  "@vitejs/plugin-vue": "^5.1.4",
45
46
  "@vueuse/core": "^11.1.0",
@@ -47,7 +48,7 @@
47
48
  "eslint": "^8.57.1",
48
49
  "eslint-config-prettier": "^9.1.0",
49
50
  "eslint-plugin-prettier": "^5.2.1",
50
- "eslint-plugin-vue": "^9.28.0",
51
+ "eslint-plugin-vue": "^9.29.1",
51
52
  "happy-dom": "^14.12.3",
52
53
  "lodash": "^4.17.21",
53
54
  "sass": "~1.77.8",
package/src/aggrid.ts CHANGED
@@ -4,6 +4,7 @@ import { getEnvironmentValue } from '@platforma-sdk/model';
4
4
  import { ModuleRegistry } from '@ag-grid-community/core';
5
5
  import { ClientSideRowModelModule } from '@ag-grid-community/client-side-row-model';
6
6
  import { InfiniteRowModelModule } from '@ag-grid-community/infinite-row-model';
7
+ import { ServerSideRowModelModule } from '@ag-grid-enterprise/server-side-row-model';
7
8
  import { CsvExportModule } from '@ag-grid-community/csv-export';
8
9
  import { ClipboardModule } from '@ag-grid-enterprise/clipboard';
9
10
  import { RangeSelectionModule } from '@ag-grid-enterprise/range-selection';
@@ -15,6 +16,7 @@ export function activateAgGrid() {
15
16
  ModuleRegistry.registerModules([
16
17
  ClientSideRowModelModule,
17
18
  InfiniteRowModelModule,
19
+ ServerSideRowModelModule,
18
20
  CsvExportModule,
19
21
  ClipboardModule,
20
22
  RangeSelectionModule,
@@ -1,9 +1,17 @@
1
1
  <script lang="ts" setup>
2
2
  import './ag-theme.css';
3
3
  import { ClientSideRowModelModule } from '@ag-grid-community/client-side-row-model';
4
- import type { GridApi, GridOptions, SortState } from '@ag-grid-community/core';
4
+ import type {
5
+ GridApi,
6
+ GridOptions,
7
+ GridReadyEvent,
8
+ ManagedGridOptionKey,
9
+ ManagedGridOptions,
10
+ SortState,
11
+ StateUpdatedEvent,
12
+ } from '@ag-grid-community/core';
5
13
  import { ModuleRegistry } from '@ag-grid-community/core';
6
- import { InfiniteRowModelModule } from '@ag-grid-community/infinite-row-model';
14
+ import { ServerSideRowModelModule } from '@ag-grid-enterprise/server-side-row-model';
7
15
  import { AgGridVue } from '@ag-grid-community/vue3';
8
16
  import { ClipboardModule } from '@ag-grid-enterprise/clipboard';
9
17
  import { RangeSelectionModule } from '@ag-grid-enterprise/range-selection';
@@ -19,7 +27,7 @@ import { updateXsvGridOptions } from './sources/file-source';
19
27
  import { enrichJoinWithLabelColumns, makeSheets, parseColId, updatePFrameGridOptions } from './sources/table-source';
20
28
  import type { PlDataTableSettings, PlDataTableSheet } from './types';
21
29
 
22
- ModuleRegistry.registerModules([ClientSideRowModelModule, ClipboardModule, InfiniteRowModelModule, RangeSelectionModule]);
30
+ ModuleRegistry.registerModules([ClientSideRowModelModule, ClipboardModule, ServerSideRowModelModule, RangeSelectionModule]);
23
31
 
24
32
  const tableState = defineModel<PlDataTableState>({ default: { gridState: {} } });
25
33
  const props = defineProps<{
@@ -120,7 +128,7 @@ const gridState = computed({
120
128
  const state = tableState.value;
121
129
 
122
130
  // do not apply driver sorting for client side rendering
123
- const sorting = gridOptions.rowModelType === 'clientSide' ? undefined : makeSorting(gridState.sort);
131
+ const sorting = gridOptions.value.rowModelType === 'clientSide' ? undefined : makeSorting(gridState.sort);
124
132
 
125
133
  state.gridState.columnOrder = gridState.columnOrder;
126
134
  state.gridState.sort = gridState.sort;
@@ -221,32 +229,67 @@ watch(
221
229
  );
222
230
 
223
231
  const gridApi = shallowRef<GridApi>();
224
- const gridOptions: GridOptions = {
232
+ const gridOptions = ref<GridOptions>({
225
233
  animateRows: false,
226
234
  suppressColumnMoveAnimation: true,
227
235
  cellSelection: true,
228
- initialState: tableState.value.gridState,
229
- onGridReady: (event) => {
230
- gridApi.value = event.api;
231
- },
232
- onStateUpdated: (event) => {
233
- gridState.value = {
234
- columnOrder: event.state.columnOrder,
235
- sort: event.state.sort,
236
- };
237
- },
236
+ initialState: gridState.value,
238
237
  autoSizeStrategy: { type: 'fitCellContents' },
239
238
  onRowDataUpdated: (event) => {
240
239
  event.api.autoSizeAllColumns();
241
240
  },
242
- // rowModelType: 'infinite', // will be set with the first data set
241
+ rowModelType: 'clientSide',
243
242
  maxBlocksInCache: 10000,
244
243
  cacheBlockSize: 100,
244
+ serverSideSortAllLevels: true,
245
+ suppressServerSideFullWidthLoadingRow: true,
245
246
  getRowId: (params) => params.data.id,
246
247
  loading: true,
247
248
  loadingOverlayComponentParams: { notReady: true },
248
249
  loadingOverlayComponent: PlOverlayLoading,
249
250
  noRowsOverlayComponent: PlOverlayNoRows,
251
+ });
252
+ const onGridReady = (event: GridReadyEvent) => {
253
+ const api = event.api;
254
+ gridApi.value = new Proxy(api, {
255
+ get(target, prop, receiver) {
256
+ switch (prop) {
257
+ case 'setGridOption':
258
+ return (key: ManagedGridOptionKey, value: GridOptions[ManagedGridOptionKey]) => {
259
+ const options = gridOptions.value;
260
+ options[key] = value;
261
+ gridOptions.value = options;
262
+ api.updateGridOptions(options);
263
+ };
264
+ case 'updateGridOptions':
265
+ return (options: ManagedGridOptions) => {
266
+ gridOptions.value = {
267
+ ...gridOptions.value,
268
+ ...options,
269
+ };
270
+ api.updateGridOptions(options);
271
+ };
272
+ default:
273
+ return Reflect.get(target, prop, receiver);
274
+ }
275
+ },
276
+ });
277
+ };
278
+ const onStateUpdated = (event: StateUpdatedEvent) => {
279
+ gridState.value = {
280
+ columnOrder: event.state.columnOrder,
281
+ sort: event.state.sort,
282
+ };
283
+ gridOptions.value.initialState = gridState.value;
284
+ };
285
+ const onGridPreDestroyed = () => {
286
+ const state = gridApi.value!.getState();
287
+ gridState.value = {
288
+ columnOrder: state.columnOrder,
289
+ sort: state.sort,
290
+ };
291
+ gridOptions.value.initialState = gridState.value;
292
+ gridApi.value = undefined;
250
293
  };
251
294
 
252
295
  const reloadKey = ref(0);
@@ -258,13 +301,32 @@ watch(
258
301
  const [gridApi, gridState] = state;
259
302
  if (!gridApi) return;
260
303
 
261
- const selfState = gridApi.getState();
262
- if (lodash.isEqual(gridState.columnOrder, selfState.columnOrder) && lodash.isEqual(gridState.sort, selfState.sort)) return;
263
-
264
- gridOptions.initialState = gridState;
304
+ const selfFullState = gridApi.getState();
305
+ const selfState = {
306
+ columnOrder: selfFullState.columnOrder,
307
+ sort: selfFullState.sort,
308
+ };
309
+ if (lodash.isEqual(gridState, selfState)) return;
310
+
311
+ console.log(
312
+ 'reloading; columnOrder changed',
313
+ !lodash.isEqual(gridState.columnOrder, selfState.columnOrder),
314
+ 'saved',
315
+ gridState.columnOrder,
316
+ 'current',
317
+ selfState.columnOrder,
318
+ );
319
+ gridOptions.value.initialState = gridState;
265
320
  ++reloadKey.value;
266
321
  },
267
322
  );
323
+ watch(
324
+ () => gridOptions.value,
325
+ (options, oldOptions) => {
326
+ if (!oldOptions) return;
327
+ if (options.rowModelType != oldOptions.rowModelType) ++reloadKey.value;
328
+ },
329
+ );
268
330
 
269
331
  const onSheetChanged = (sheetId: string, newValue: string | number) => {
270
332
  const state = sheetsState.value;
@@ -290,20 +352,17 @@ watch(
290
352
  case 'ptable': {
291
353
  const pfDriver = platforma.pFrameDriver;
292
354
  if (!pfDriver) throw Error('platforma.pFrameDriver not set');
293
-
294
355
  const pTable = settings.pTable;
295
356
  if (!pTable || !sheets) {
296
357
  return gridApi.updateGridOptions({
297
358
  loading: true,
298
359
  loadingOverlayComponentParams: { notReady: true },
299
360
  columnDefs: [],
300
- rowData: [],
301
361
  });
302
362
  }
303
-
304
- const options = await updatePFrameGridOptions(gridApi, pfDriver, pTable, sheets);
363
+ const options = await updatePFrameGridOptions(pfDriver, pTable, sheets);
305
364
  return gridApi.updateGridOptions({
306
- loading: options.rowModelType === 'infinite',
365
+ loading: options.rowModelType !== 'clientSide',
307
366
  loadingOverlayComponentParams: { notReady: false },
308
367
  ...options,
309
368
  });
@@ -319,11 +378,10 @@ watch(
319
378
  loading: true,
320
379
  loadingOverlayComponentParams: { notReady: true },
321
380
  columnDefs: [],
322
- rowData: [],
323
381
  });
324
382
  }
325
383
 
326
- const options = await updateXsvGridOptions(gridApi, blobDriver, xsvFile.value);
384
+ const options = await updateXsvGridOptions(blobDriver, xsvFile.value);
327
385
  return gridApi.updateGridOptions({
328
386
  loading: true,
329
387
  loadingOverlayComponentParams: { notReady: false },
@@ -351,7 +409,14 @@ watch(
351
409
  />
352
410
  </div>
353
411
  </Transition>
354
- <AgGridVue class="ap-ag-data-table-grid" :grid-options="gridOptions" />
412
+ <AgGridVue
413
+ class="ap-ag-data-table-grid"
414
+ :grid-options="gridOptions"
415
+ :key="reloadKey"
416
+ @grid-ready="onGridReady"
417
+ @state-updated="onStateUpdated"
418
+ @grid-pre-destroyed="onGridPreDestroyed"
419
+ />
355
420
  </div>
356
421
  </template>
357
422
 
@@ -1,15 +1,13 @@
1
- import type { ColDef, GridApi, IDatasource } from '@ag-grid-community/core';
1
+ import type { ColDef, IDatasource } from '@ag-grid-community/core';
2
2
  import type { BlobDriver, LocalBlobHandleAndSize, RemoteBlobHandleAndSize } from '@platforma-sdk/model';
3
3
 
4
4
  export async function updateXsvGridOptions(
5
- gridApi: GridApi,
6
5
  blobDriver: BlobDriver,
7
6
  file: LocalBlobHandleAndSize | RemoteBlobHandleAndSize,
8
7
  ): Promise<{
9
8
  columnDefs: ColDef[];
10
9
  datasource: IDatasource;
11
10
  }> {
12
- gridApi;
13
11
  blobDriver;
14
12
  file;
15
13
  //blobDriver.getContent(file.handle!)
@@ -1,4 +1,4 @@
1
- import type { ColDef, IDatasource, RowModelType } from '@ag-grid-community/core';
1
+ import type { ColDef, IServerSideDatasource, RowModelType } from '@ag-grid-community/core';
2
2
  import type { AxisSpec, PColumnSpec, PTableColumnSpec, PTableShape, PTableVector, PVectorDataString } from '@platforma-sdk/model';
3
3
  import { getAxisId } from '@platforma-sdk/model';
4
4
  import canonicalize from 'canonicalize';
@@ -78,7 +78,7 @@ export function updatePFrameGridOptionsHeterogeneousAxes(
78
78
  indices: number[],
79
79
  ): {
80
80
  columnDefs: ColDef[];
81
- datasource?: IDatasource;
81
+ serverSideDatasource?: IServerSideDatasource;
82
82
  rowModelType: RowModelType;
83
83
  rowData?: unknown[];
84
84
  } {
@@ -1,4 +1,4 @@
1
- import type { ColDef, GridApi, IDatasource, IGetRowsParams, RowModelType } from '@ag-grid-community/core';
1
+ import type { ColDef, IServerSideDatasource, IServerSideGetRowsParams, RowModelType } from '@ag-grid-community/core';
2
2
  import type { AxisId, JoinEntry, PColumnIdAndSpec, PFrameHandle, PObjectId } from '@platforma-sdk/model';
3
3
  import {
4
4
  type PColumnSpec,
@@ -16,7 +16,7 @@ import {
16
16
  } from '@platforma-sdk/model';
17
17
  import canonicalize from 'canonicalize';
18
18
  import * as lodash from 'lodash';
19
- import { type PlDataTableSheet } from '../types';
19
+ import type { PlDataTableSheet } from '../types';
20
20
  import { getHeterogeneousColumns, updatePFrameGridOptionsHeterogeneousAxes } from './table-source-heterogeneous';
21
21
 
22
22
  /**
@@ -273,13 +273,12 @@ const isLabelColumn = (col: PTableColumnSpec) => col.type === 'column' && col.sp
273
273
  * Calculate GridOptions for p-table data source type
274
274
  */
275
275
  export async function updatePFrameGridOptions(
276
- gridApi: GridApi,
277
276
  pfDriver: PFrameDriver,
278
277
  pt: PTableHandle,
279
278
  sheets: PlDataTableSheet[],
280
279
  ): Promise<{
281
280
  columnDefs: ColDef[];
282
- datasource?: IDatasource;
281
+ serverSideDatasource?: IServerSideDatasource;
283
282
  rowModelType: RowModelType;
284
283
  rowData?: unknown[];
285
284
  }> {
@@ -329,49 +328,52 @@ export async function updatePFrameGridOptions(
329
328
  return updatePFrameGridOptionsHeterogeneousAxes(hColumns, ptShape, columnDefs, await pfDriver.getData(pt, indices), fields, indices);
330
329
  }
331
330
 
332
- let lastParams: IGetRowsParams | undefined = undefined;
333
- const datasource = {
334
- rowCount,
335
- getRows: async (params) => {
336
- gridApi.setGridOption('loading', true);
331
+ let lastParams: IServerSideGetRowsParams | undefined = undefined;
332
+ const serverSideDatasource = {
333
+ getRows: async (params: IServerSideGetRowsParams) => {
337
334
  try {
338
335
  if (rowCount == 0) {
339
- params.successCallback([], rowCount);
340
- gridApi.setGridOption('loading', false);
341
- gridApi.showNoRowsOverlay();
336
+ params.success({ rowData: [], rowCount });
337
+ params.api.showNoRowsOverlay();
338
+ params.api.setGridOption('loading', false);
342
339
  return;
343
340
  }
344
341
 
345
342
  // this is to avoid double flickering when underlying table is changed
346
- if (lastParams && !lodash.isEqual(lastParams.sortModel, params.sortModel)) {
343
+ if (lastParams && !lodash.isEqual(lastParams.request.sortModel, params.request.sortModel)) {
347
344
  lastParams = undefined;
348
- params.failCallback();
345
+ params.fail();
346
+ params.api.setGridOption('loading', true);
349
347
  return;
350
348
  }
351
349
  lastParams = params;
352
350
 
353
- const length = params.endRow - params.startRow;
351
+ let length = 0;
354
352
  let rowData: unknown[] = [];
355
- if (length > 0) {
356
- const data = await pfDriver.getData(pt, indices, {
357
- offset: params.startRow,
358
- length,
359
- });
360
- rowData = columns2rows(fields, data);
353
+ if (rowCount > 0 && params.request.startRow !== undefined && params.request.endRow !== undefined) {
354
+ length = Math.min(rowCount, params.request.endRow) - params.request.startRow;
355
+ if (length > 0) {
356
+ const data = await pfDriver.getData(pt, indices, {
357
+ offset: params.request.startRow,
358
+ length,
359
+ });
360
+ rowData = columns2rows(fields, data);
361
+ }
361
362
  }
362
363
 
363
- params.successCallback(rowData, ptShape.rows);
364
- gridApi.setGridOption('loading', false);
365
- gridApi.autoSizeAllColumns();
364
+ params.success({ rowData, rowCount });
365
+ params.api.autoSizeAllColumns();
366
+ params.api.setGridOption('loading', false);
366
367
  } catch (error: unknown) {
367
- params.failCallback();
368
+ params.fail();
369
+ params.api.setGridOption('loading', true);
368
370
  }
369
371
  },
370
- } satisfies IDatasource;
372
+ } satisfies IServerSideDatasource;
371
373
 
372
374
  return {
373
- rowModelType: 'infinite',
375
+ rowModelType: 'serverSide',
374
376
  columnDefs,
375
- datasource,
377
+ serverSideDatasource,
376
378
  };
377
379
  }
package/vite.config.ts CHANGED
@@ -20,6 +20,7 @@ export default defineConfig({
20
20
  '@ag-grid-community/core',
21
21
  '@ag-grid-community/client-side-row-model',
22
22
  '@ag-grid-community/infinite-row-model',
23
+ '@ag-grid-enterprise/server-side-row-model',
23
24
  '@ag-grid-community/styles',
24
25
  '@ag-grid-community/vue3',
25
26
  '@ag-grid-community/csv-export',