@platforma-sdk/ui-vue 1.30.38 → 1.31.1

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.30.38",
3
+ "version": "1.31.1",
4
4
  "type": "module",
5
5
  "main": "dist/lib.umd.cjs",
6
6
  "module": "dist/lib.js",
@@ -25,8 +25,8 @@
25
25
  "comlink": "~4.4.2",
26
26
  "lru-cache": "^11.1.0",
27
27
  "vue": "^3.5.13",
28
- "@platforma-sdk/model": "^1.30.37",
29
- "@milaboratories/uikit": "^2.2.75"
28
+ "@milaboratories/uikit": "^2.2.75",
29
+ "@platforma-sdk/model": "^1.30.37"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@faker-js/faker": "^9.2.0",
@@ -47,8 +47,8 @@
47
47
  "vue-tsc": "^2.1.10",
48
48
  "yarpm": "^1.2.0",
49
49
  "zod": "~3.23.8",
50
- "@milaboratories/eslint-config": "^1.0.4",
51
- "@milaboratories/helpers": "^1.6.11"
50
+ "@milaboratories/helpers": "^1.6.11",
51
+ "@milaboratories/eslint-config": "^1.0.4"
52
52
  },
53
53
  "scripts": {
54
54
  "test": "vitest run --passWithNoTests",
@@ -1,10 +1,3 @@
1
- import type {
2
- ColDef,
3
- ICellRendererParams,
4
- IServerSideDatasource,
5
- IServerSideGetRowsParams,
6
- RowModelType,
7
- } from 'ag-grid-enterprise';
8
1
  import type {
9
2
  AxisId,
10
3
  PlDataTableGridStateWithoutSheets,
@@ -24,21 +17,28 @@ import {
24
17
  type PlDataTableSheet,
25
18
  type PTableVector,
26
19
  } from '@platforma-sdk/model';
20
+ import type {
21
+ ColDef,
22
+ ICellRendererParams,
23
+ IServerSideDatasource,
24
+ IServerSideGetRowsParams,
25
+ RowModelType,
26
+ } from 'ag-grid-enterprise';
27
+ import canonicalize from 'canonicalize';
27
28
  import * as lodash from 'lodash';
28
- import type { PlAgDataTableV2Row, PTableKeyJson } from '../types';
29
- import { makeRowNumberColDef, PlAgDataTableRowNumberColId } from './row-number';
30
- import { objectHash } from '../../../objectHash';
31
29
  import type { Ref } from 'vue';
30
+ import { objectHash } from '../../../objectHash';
31
+ import type { PlAgHeaderComponentParams, PlAgHeaderComponentType } from '../../PlAgColumnHeader';
32
+ import { PlAgColumnHeader } from '../../PlAgColumnHeader';
33
+ import { PlAgTextAndButtonCell } from '../../PlAgTextAndButtonCell';
34
+ import type { PlAgDataTableV2Row, PTableKeyJson } from '../types';
32
35
  import {
33
36
  defaultValueFormatter,
34
37
  isLabelColumn,
35
38
  PTableHidden,
36
39
  } from './common';
37
- import canonicalize from 'canonicalize';
38
- import type { PlAgHeaderComponentType, PlAgHeaderComponentParams } from '../../PlAgColumnHeader';
39
- import { PlAgColumnHeader } from '../../PlAgColumnHeader';
40
- import { PlAgTextAndButtonCell } from '../../PlAgTextAndButtonCell';
41
40
  import { defaultMainMenuItems } from './menu-items';
41
+ import { makeRowNumberColDef, PlAgDataTableRowNumberColId } from './row-number';
42
42
 
43
43
  /** Convert columnar data from the driver to rows, used by ag-grid */
44
44
  function columns2rows(
@@ -192,13 +192,23 @@ export async function updatePFrameGridOptions(
192
192
  }
193
193
  }
194
194
 
195
- // indices of axes in allIndices array
196
- const axes: number[] = [];
197
- for (let i = 0; i < numberOfAxes; ++i) {
198
- const fieldIdx = axisToFieldIdx.get(i);
199
- if (fieldIdx === undefined || fieldIdx === -1) throw new Error('assertion exception');
200
- axes.push(fieldIdx);
201
- }
195
+ // Construct the `axes` array for key generation in `columns2rows`.
196
+ // The key components should be ordered according to the display order of axis columns from the `fields` array.
197
+ const axes: number[] = fields.filter((idx) => specs[idx].type === 'axis').map((idx) => {
198
+ const r = allIndices.indexOf(idx);
199
+ if (r === -1) {
200
+ console.error(
201
+ 'Key construction error: Original axis spec index from `fields` not found in `allIndices`.',
202
+ {
203
+ originalAxisSpecIdx: idx,
204
+ },
205
+ );
206
+ throw new Error(
207
+ `Assertion failed: Original axis spec index ${idx} (from fields) for key construction not found in allIndices.`,
208
+ );
209
+ }
210
+ return r;
211
+ });
202
212
 
203
213
  const requestIndices: number[] = [];
204
214
  const resultMapping: number[] = [];
@@ -3,8 +3,6 @@ import type {
3
3
  AxisId,
4
4
  CalculateTableDataRequest,
5
5
  CanonicalizedJson,
6
- ColumnJoinEntry,
7
- InlineColumnJoinEntry,
8
6
  PColumnIdAndSpec,
9
7
  PColumnPredicate,
10
8
  PFrameHandle,
@@ -13,7 +11,6 @@ import type {
13
11
  PTableColumnIdAxis,
14
12
  PTableColumnIdColumn,
15
13
  PTableColumnIdJson,
16
- PTableSorting,
17
14
  } from '@platforma-sdk/model';
18
15
  import {
19
16
  canonicalizeJson,
@@ -280,7 +277,7 @@ async function getSequenceRows(
280
277
  rowSelectionModel,
281
278
  );
282
279
 
283
- const predef = {
280
+ const predef: CalculateTableDataRequest<PObjectId> = {
284
281
  src: {
285
282
  type: 'outer',
286
283
  primary: {
@@ -288,40 +285,32 @@ async function getSequenceRows(
288
285
  entries: [
289
286
  ...(filterColumn && filterColumn.data.length > 0
290
287
  ? [
291
- {
292
- type: 'inlineColumn',
293
- column: filterColumn,
294
- } satisfies InlineColumnJoinEntry,
288
+ {
289
+ type: 'inlineColumn' as const,
290
+ column: filterColumn,
291
+ },
295
292
  ]
296
293
  : []),
297
- ...linkerColumns.map((c) => ({
298
- type: 'column',
299
- column: c.columnId,
300
- } satisfies ColumnJoinEntry<PObjectId>)),
301
294
  ...sequenceColumnIds.map((c) => ({
302
- type: 'column',
295
+ type: 'column' as const,
303
296
  column: c,
304
- } satisfies ColumnJoinEntry<PObjectId>)),
305
- ].filter((e): e is ColumnJoinEntry<PObjectId> => e !== undefined),
297
+ })),
298
+ ],
306
299
  },
307
- secondary: labelColumnIds
308
- .map((c) => parseJson(c))
309
- .filter((c) => c.type === 'column')
310
- .map((c) => ({
311
- type: 'column',
312
- column: c.id,
313
- } satisfies ColumnJoinEntry<PObjectId>)),
300
+ secondary: [
301
+ ...linkerColumns.map((c) => c.columnId),
302
+ ...labelColumnIds.map((c) => parseJson(c))
303
+ .filter((c) => c.type === 'column')
304
+ .map((c) => c.id),
305
+ ].map((c) => ({
306
+ type: 'column' as const,
307
+ column: c,
308
+ })),
314
309
  },
315
310
  filters: [],
316
- sorting: sequenceColumnIds.map((c) => ({
317
- column: {
318
- type: 'column',
319
- id: c,
320
- },
321
- ascending: true,
322
- naAndAbsentAreLeastValues: true,
323
- } satisfies PTableSorting)),
324
- } satisfies CalculateTableDataRequest<PObjectId>;
311
+
312
+ sorting: [], // @TODO: may be add sorting ?
313
+ };
325
314
 
326
315
  const def = JSON.parse(JSON.stringify(predef));
327
316
  const table = await pFrameDriver.calculateTableData(pframe, def);
@@ -1,20 +1,21 @@
1
1
  <script lang="ts" setup>
2
2
  import type { ListOption } from '@milaboratories/uikit';
3
- import { PlBtnGhost, PlIcon24, PlSlideModal, PlMaskIcon16, PlMaskIcon24 } from '@milaboratories/uikit';
4
- import { computed, onBeforeUnmount, onMounted, reactive, ref, toRefs, watch } from 'vue';
3
+ import { PlBtnGhost, PlBtnSecondary, PlIcon24, PlMaskIcon16, PlMaskIcon24, PlSlideModal } from '@milaboratories/uikit';
5
4
  import type {
6
- PlTableFiltersModel,
7
- PlTableFilterType,
8
5
  PlTableFilter,
9
- PTableColumnSpec,
6
+ PlTableFilterColumnId,
7
+ PlTableFiltersModel,
10
8
  PlTableFiltersState,
11
9
  PlTableFiltersStateEntry,
12
- PlTableFilterColumnId,
10
+ PlTableFilterType,
11
+ PTableColumnSpec,
13
12
  } from '@platforma-sdk/model';
14
13
  import * as lodash from 'lodash';
15
- import type { PlTableFiltersDefault, PlTableFiltersRestriction } from '../PlAgDataTable/types';
16
- import PlTableFilterEntry from './PlTableFilterEntry.vue';
14
+ import { computed, onBeforeUnmount, onMounted, reactive, ref, toRefs, watch } from 'vue';
15
+ import type { PlTableFiltersRestriction } from '../PlAgDataTable/types';
16
+ import { useDataTableToolsPanelTarget } from '../PlAgDataTableToolsPanel';
17
17
  import PlTableAddFilter from './PlTableAddFilter.vue';
18
+ import PlTableFilterEntry from './PlTableFilterEntry.vue';
18
19
  import {
19
20
  filterTypesNumber,
20
21
  filterTypesString,
@@ -25,13 +26,14 @@ import {
25
26
  makePredicate,
26
27
  } from './filters_logic';
27
28
  import './pl-table-filters.scss';
28
- import { useDataTableToolsPanelTarget } from '../PlAgDataTableToolsPanel';
29
+
30
+ type DefaultFilters = (spec: PTableColumnSpec) => (PlTableFilter | undefined);
29
31
 
30
32
  const model = defineModel<PlTableFiltersModel>({ required: true });
31
33
  const props = defineProps<{
32
34
  columns: Readonly<PTableColumnSpec[]>;
33
35
  restrictions?: Readonly<PlTableFiltersRestriction[]>;
34
- defaults?: Readonly<PlTableFiltersDefault[]>;
36
+ defaults?: DefaultFilters;
35
37
  }>();
36
38
  const { columns, restrictions, defaults } = toRefs(props);
37
39
 
@@ -53,6 +55,27 @@ const columnsById = computed<Record<PlTableFilterColumnId, PTableColumnSpec>>(()
53
55
  }
54
56
  return result;
55
57
  });
58
+
59
+ const defaultsMap = computed<Record<PlTableFilterColumnId, PlTableFiltersStateEntry>>(() => {
60
+ const cols = columns.value;
61
+ const defFn = defaults.value;
62
+
63
+ if (!cols || !defFn) return {};
64
+
65
+ const result: Record<PlTableFilterColumnId, PlTableFiltersStateEntry> = {};
66
+ for (const column of cols) {
67
+ const f = defFn(column);
68
+ if (!f) continue;
69
+ const id = makeColumnId(column);
70
+ result[id] = {
71
+ columnId: id,
72
+ filter: f,
73
+ disabled: false,
74
+ };
75
+ }
76
+ return result;
77
+ });
78
+
56
79
  const restrictionsMap = computed<Record<PlTableFilterColumnId, PlTableFilterType[]>>(() => {
57
80
  const restrictionsValue = restrictions.value ?? [];
58
81
  const map: Record<PlTableFilterColumnId, PlTableFilterType[]> = {};
@@ -65,21 +88,6 @@ const restrictionsMap = computed<Record<PlTableFilterColumnId, PlTableFilterType
65
88
  }
66
89
  return map;
67
90
  });
68
- const defaultsMap = computed<Record<PlTableFilterColumnId, PlTableFiltersStateEntry>>(() => {
69
- const defaultsValue = defaults.value ?? [];
70
- const map: Record<PlTableFilterColumnId, PlTableFiltersStateEntry> = {};
71
- for (const [id, column] of Object.entries(columnsById.value)) {
72
- const entry = lodash.find(defaultsValue, (entry) => lodash.isEqual(entry.column.id, column.id));
73
- if (entry) {
74
- map[id] = {
75
- columnId: id,
76
- filter: entry.default,
77
- disabled: false,
78
- };
79
- }
80
- }
81
- return map;
82
- });
83
91
 
84
92
  /* State upgrader */ (() => {
85
93
  const state = model.value.state;
@@ -93,10 +101,30 @@ const defaultsMap = computed<Record<PlTableFilterColumnId, PlTableFiltersStateEn
93
101
  }));
94
102
  }
95
103
  })();
104
+
105
+ const defaultState = () => lodash.cloneDeep(Object.values(defaultsMap.value));
106
+
96
107
  const makeState = (state?: PlTableFiltersState): PlTableFiltersState => {
97
- return state ?? Object.values(defaultsMap.value);
108
+ return state ?? [];
98
109
  };
99
110
  const reactiveModel = reactive({ state: makeState(model.value.state) });
111
+
112
+ const resetToDefaults = () => {
113
+ reactiveModel.state = defaultState();
114
+ };
115
+
116
+ watch(
117
+ () => columns.value,
118
+ (columns, previousColumns) => {
119
+ // @TODO: we need to somehow store that user modified defaults
120
+ // rn we will e.g. reset to defaults on page refresh if user removed all filters at all
121
+ if (defaults.value && model.value.state?.length === 0 && (!previousColumns || previousColumns.length === 0) && columns.length > 0) {
122
+ resetToDefaults();
123
+ }
124
+ },
125
+ { immediate: true },
126
+ );
127
+
100
128
  watch(
101
129
  () => model.value,
102
130
  (model) => {
@@ -178,6 +206,7 @@ const makeFilter = (columnId: string): PlTableFiltersStateEntry =>
178
206
  filter: getFilterDefault(filterOptions.value[columnId][0].value),
179
207
  disabled: false,
180
208
  };
209
+
181
210
  const resetFilter = (index: number) => {
182
211
  reactiveModel.state[index] = makeFilter(reactiveModel.state[index].columnId);
183
212
  };
@@ -306,6 +335,7 @@ const teleportTarget = useDataTableToolsPanelTarget();
306
335
 
307
336
  <div v-if="!filterOptionsPresent">No filters applicable</div>
308
337
  </div>
338
+ <PlBtnSecondary v-if="defaults" @click.stop="resetToDefaults">Reset to defaults</PlBtnSecondary>
309
339
  </PlSlideModal>
310
340
 
311
341
  <PlTableAddFilter