@platforma-sdk/ui-vue 1.5.0 → 1.5.40
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/CHANGELOG.md +16 -0
- package/dist/lib.js +9039 -8852
- package/dist/lib.umd.cjs +64 -64
- package/dist/src/components/PlAgDataTable/PlAgDataTable.vue.d.ts.map +1 -1
- package/dist/src/components/PlAgDataTable/sources/table-source.d.ts +3 -1
- package/dist/src/components/PlAgDataTable/sources/table-source.d.ts.map +1 -1
- package/dist/src/components/PlAgDataTable/types.d.ts +19 -15
- package/dist/src/components/PlAgDataTable/types.d.ts.map +1 -1
- package/dist/style.css +1 -1
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +13 -11
- package/src/components/PlAgDataTable/PlAgDataTable.vue +118 -31
- package/src/components/PlAgDataTable/sources/table-source.ts +155 -51
- package/src/components/PlAgDataTable/types.ts +20 -15
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platforma-sdk/ui-vue",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.40",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/lib.umd.cjs",
|
|
6
6
|
"module": "dist/lib.js",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"lru-cache": "^11.0.1",
|
|
22
22
|
"vue": "^3.5.11",
|
|
23
23
|
"canonicalize": "^2.0.0",
|
|
24
|
-
"@milaboratories/uikit": "^1.2.
|
|
25
|
-
"@platforma-sdk/model": "^1.
|
|
24
|
+
"@milaboratories/uikit": "^1.2.17",
|
|
25
|
+
"@platforma-sdk/model": "^1.5.40"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@ag-grid-community/client-side-row-model": "^32.2.2",
|
|
@@ -33,18 +33,20 @@
|
|
|
33
33
|
"@ag-grid-enterprise/core": "^32.2.2",
|
|
34
34
|
"@ag-grid-enterprise/clipboard": "^32.2.2",
|
|
35
35
|
"@ag-grid-enterprise/range-selection": "^32.2.2",
|
|
36
|
-
"@faker-js/faker": "^8.4.
|
|
37
|
-
"@types/lodash": "^4.17.
|
|
38
|
-
"@types/node": "~20.16.
|
|
39
|
-
"@typescript-eslint/eslint-plugin": "^7.
|
|
36
|
+
"@faker-js/faker": "^8.4.1",
|
|
37
|
+
"@types/lodash": "^4.17.10",
|
|
38
|
+
"@types/node": "~20.16.10",
|
|
39
|
+
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
40
40
|
"@vitejs/plugin-vue": "^5.1.4",
|
|
41
|
+
"@vueuse/core": "^11.1.0",
|
|
42
|
+
"canonicalize": "^2.0.0",
|
|
41
43
|
"eslint": "^8.57.1",
|
|
42
44
|
"eslint-config-prettier": "^9.1.0",
|
|
43
|
-
"eslint-plugin-prettier": "^5.1
|
|
44
|
-
"eslint-plugin-vue": "^9.
|
|
45
|
+
"eslint-plugin-prettier": "^5.2.1",
|
|
46
|
+
"eslint-plugin-vue": "^9.28.0",
|
|
45
47
|
"happy-dom": "^14.12.3",
|
|
46
|
-
"lodash": "4.17.21",
|
|
47
|
-
"sass": "~1.77.
|
|
48
|
+
"lodash": "^4.17.21",
|
|
49
|
+
"sass": "~1.77.8",
|
|
48
50
|
"typescript": "~5.5.4",
|
|
49
51
|
"vite": "^5.4.8",
|
|
50
52
|
"vitest": "^2.1.2",
|
|
@@ -14,12 +14,15 @@ import { computed, ref, watch, shallowRef, toRefs } from 'vue';
|
|
|
14
14
|
import OverlayLoading from './OverlayLoading.vue';
|
|
15
15
|
import OverlayNoRows from './OverlayNoRows.vue';
|
|
16
16
|
import { updateXsvGridOptions } from './sources/file-source';
|
|
17
|
-
import {
|
|
18
|
-
|
|
17
|
+
import {
|
|
18
|
+
parseColId,
|
|
19
|
+
makeSheets,
|
|
20
|
+
updatePFrameGridOptions,
|
|
21
|
+
enrichJoinWithLabelColumns
|
|
22
|
+
} from './sources/table-source';
|
|
23
|
+
import type { PlDataTableSheet, PlDataTableSettings } from './types';
|
|
19
24
|
import * as lodash from 'lodash';
|
|
20
|
-
|
|
21
|
-
// @todo add license to AgGrid
|
|
22
|
-
// const license = window.getEnvironmentValue('VITE_PLATFORMA_AG_GRID_LICENSE_KEY');
|
|
25
|
+
import { computedAsync } from '@vueuse/core';
|
|
23
26
|
|
|
24
27
|
ModuleRegistry.registerModules([ClientSideRowModelModule, ClipboardModule, InfiniteRowModelModule, RangeSelectionModule]);
|
|
25
28
|
|
|
@@ -29,8 +32,78 @@ const props = defineProps<{
|
|
|
29
32
|
}>();
|
|
30
33
|
const { settings } = toRefs(props);
|
|
31
34
|
|
|
35
|
+
watch(
|
|
36
|
+
() => settings.value,
|
|
37
|
+
async (settings, oldSettings) => {
|
|
38
|
+
if (
|
|
39
|
+
settings.sourceType !== 'pframe' ||
|
|
40
|
+
!settings.pFrame?.ok ||
|
|
41
|
+
!settings.pFrame.value ||
|
|
42
|
+
!settings.join
|
|
43
|
+
) return;
|
|
44
|
+
|
|
45
|
+
if (
|
|
46
|
+
oldSettings &&
|
|
47
|
+
oldSettings.sourceType === 'pframe' &&
|
|
48
|
+
lodash.isEqual(settings.pFrame, oldSettings.pFrame) &&
|
|
49
|
+
lodash.isEqual(settings.join, oldSettings.join)
|
|
50
|
+
) return;
|
|
51
|
+
|
|
52
|
+
const platforma = window.platforma;
|
|
53
|
+
if (!platforma) throw Error('platforma not set');
|
|
54
|
+
|
|
55
|
+
const pfDriver = platforma.pFrameDriver;
|
|
56
|
+
if (!pfDriver) throw Error('platforma.pFrameDriver not set');
|
|
57
|
+
|
|
58
|
+
const enrichedJoin = await enrichJoinWithLabelColumns(pfDriver, settings.pFrame.value, settings.join);
|
|
59
|
+
|
|
60
|
+
const state = tableState.value;
|
|
61
|
+
|
|
62
|
+
if (!state.pTableParams) {
|
|
63
|
+
state.pTableParams = {
|
|
64
|
+
sorting: [],
|
|
65
|
+
filters: [],
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
state.pTableParams.join = enrichedJoin;
|
|
69
|
+
|
|
70
|
+
tableState.value = state;
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const sheets = computedAsync<PlDataTableSheet[]>(
|
|
75
|
+
async () => {
|
|
76
|
+
const sourceType = settings.value.sourceType;
|
|
77
|
+
switch(sourceType) {
|
|
78
|
+
case 'pframe': {
|
|
79
|
+
const platforma = window.platforma;
|
|
80
|
+
if (!platforma) throw Error('platforma not set');
|
|
81
|
+
|
|
82
|
+
const pfDriver = platforma.pFrameDriver;
|
|
83
|
+
if (!pfDriver) throw Error('platforma.pFrameDriver not set');
|
|
84
|
+
|
|
85
|
+
if (!settings.value.pFrame?.ok || !settings.value.pFrame.value) return [];
|
|
86
|
+
const pFrame = settings.value.pFrame.value;
|
|
87
|
+
|
|
88
|
+
const join = tableState.value.pTableParams?.join;
|
|
89
|
+
if (!join) return [];
|
|
90
|
+
|
|
91
|
+
return await makeSheets(pfDriver, pFrame, settings.value.sheetAxes, join);
|
|
92
|
+
}
|
|
93
|
+
case 'ptable': {
|
|
94
|
+
return settings.value.sheets ?? [];
|
|
95
|
+
}
|
|
96
|
+
case 'xsv': {
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
default: throw Error(`unsupported source type: ${sourceType satisfies never}`);
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
[]
|
|
103
|
+
);
|
|
104
|
+
|
|
32
105
|
function makeSorting(state?: SortState): PTableSorting[] | undefined {
|
|
33
|
-
if (settings.value.sourceType !== 'ptable') return undefined;
|
|
106
|
+
if (settings.value.sourceType !== 'ptable' && settings.value.sourceType !== 'pframe') return undefined;
|
|
34
107
|
return (
|
|
35
108
|
state?.sortModel.map(
|
|
36
109
|
(item) =>
|
|
@@ -59,7 +132,7 @@ const gridState = computed({
|
|
|
59
132
|
state.gridState.columnOrder = gridState.columnOrder;
|
|
60
133
|
state.gridState.sort = gridState.sort;
|
|
61
134
|
|
|
62
|
-
if (settings.value.sourceType === 'ptable') {
|
|
135
|
+
if (settings.value.sourceType === 'ptable' || settings.value.sourceType === 'pframe') {
|
|
63
136
|
if (!state.pTableParams) {
|
|
64
137
|
state.pTableParams = {
|
|
65
138
|
sorting: [],
|
|
@@ -76,9 +149,9 @@ const gridState = computed({
|
|
|
76
149
|
const makeSheetId = (axis: AxisId) => canonicalize(axis)!;
|
|
77
150
|
|
|
78
151
|
function makeFilters(sheetsState: Record<string, string | number>): PTableRecordFilter[] | undefined {
|
|
79
|
-
if (settings.value.sourceType !== 'ptable') return undefined;
|
|
152
|
+
if (settings.value.sourceType !== 'ptable' && settings.value.sourceType !== 'pframe') return undefined;
|
|
80
153
|
return (
|
|
81
|
-
|
|
154
|
+
sheets.value.map((sheet) => ({
|
|
82
155
|
type: 'bySingleColumn',
|
|
83
156
|
column: sheet.column
|
|
84
157
|
? {
|
|
@@ -106,7 +179,7 @@ const sheetsState = computed({
|
|
|
106
179
|
|
|
107
180
|
state.gridState.sheets = sheetsState;
|
|
108
181
|
|
|
109
|
-
if (settings.value.sourceType === 'ptable') {
|
|
182
|
+
if (settings.value.sourceType === 'ptable' || settings.value.sourceType === 'pframe') {
|
|
110
183
|
if (!state.pTableParams) {
|
|
111
184
|
state.pTableParams = {
|
|
112
185
|
sorting: [],
|
|
@@ -121,24 +194,27 @@ const sheetsState = computed({
|
|
|
121
194
|
});
|
|
122
195
|
|
|
123
196
|
watch(
|
|
124
|
-
() => settings.value,
|
|
125
|
-
(
|
|
126
|
-
|
|
197
|
+
() => [settings.value, sheets.value] as const,
|
|
198
|
+
(state, oldState) => {
|
|
199
|
+
const [settings, sheets] = state;
|
|
200
|
+
if (oldState) {
|
|
201
|
+
const [oldSettings, oldSheets] = oldState;
|
|
202
|
+
if ((settings.sourceType === 'ptable' || settings.sourceType === 'pframe') && settings.sourceType === oldSettings?.sourceType && lodash.isEqual(sheets, oldSheets)) return;
|
|
203
|
+
}
|
|
127
204
|
|
|
128
|
-
if (settings.sourceType !== 'ptable') {
|
|
205
|
+
if (settings.sourceType !== 'ptable' && settings.sourceType !== 'pframe') {
|
|
129
206
|
sheetsState.value = {};
|
|
130
207
|
return;
|
|
131
208
|
}
|
|
132
209
|
|
|
133
|
-
const
|
|
134
|
-
const sheets = settings.sheets ?? [];
|
|
210
|
+
const newSheetsState = sheetsState.value;
|
|
135
211
|
for (const sheet of sheets) {
|
|
136
212
|
const sheetId = makeSheetId(sheet.axis);
|
|
137
|
-
if (!
|
|
138
|
-
|
|
213
|
+
if (!newSheetsState[sheetId]) {
|
|
214
|
+
newSheetsState[sheetId] = sheet.defaultValue ?? sheet.options[0].value;
|
|
139
215
|
}
|
|
140
216
|
}
|
|
141
|
-
sheetsState.value =
|
|
217
|
+
sheetsState.value = newSheetsState;
|
|
142
218
|
},
|
|
143
219
|
{ immediate: true },
|
|
144
220
|
);
|
|
@@ -197,11 +273,11 @@ const onSheetChanged = (sheetId: string, newValue: string | number) => {
|
|
|
197
273
|
};
|
|
198
274
|
|
|
199
275
|
watch(
|
|
200
|
-
() => [gridApi.value, settings.value] as const,
|
|
276
|
+
() => [gridApi.value, settings.value, sheets.value] as const,
|
|
201
277
|
async (state, oldState) => {
|
|
202
278
|
if (lodash.isEqual(state, oldState)) return;
|
|
203
279
|
|
|
204
|
-
const [gridApi, settings] = state;
|
|
280
|
+
const [gridApi, settings, sheets] = state;
|
|
205
281
|
if (!gridApi) return;
|
|
206
282
|
|
|
207
283
|
const platforma = window.platforma;
|
|
@@ -209,6 +285,7 @@ watch(
|
|
|
209
285
|
|
|
210
286
|
const sourceType = settings.sourceType;
|
|
211
287
|
switch (sourceType) {
|
|
288
|
+
case 'pframe':
|
|
212
289
|
case 'ptable': {
|
|
213
290
|
const pfDriver = platforma.pFrameDriver;
|
|
214
291
|
if (!pfDriver) throw Error('platforma.pFrameDriver not set');
|
|
@@ -223,7 +300,7 @@ watch(
|
|
|
223
300
|
});
|
|
224
301
|
}
|
|
225
302
|
|
|
226
|
-
const options = await updatePFrameGridOptions(gridApi, pfDriver, pTable.value,
|
|
303
|
+
const options = await updatePFrameGridOptions(gridApi, pfDriver, pTable.value, sheets);
|
|
227
304
|
return gridApi.updateGridOptions({
|
|
228
305
|
loading: true,
|
|
229
306
|
loadingOverlayComponentParams: { notReady: false },
|
|
@@ -262,15 +339,17 @@ watch(
|
|
|
262
339
|
|
|
263
340
|
<template>
|
|
264
341
|
<div class="ap-ag-data-table-container">
|
|
265
|
-
<
|
|
266
|
-
<
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
342
|
+
<Transition name="ap-ag-data-table-sheets-transition">
|
|
343
|
+
<div v-if="sheets.length > 0" class="ap-ag-data-table-sheets">
|
|
344
|
+
<PlDropdownLine
|
|
345
|
+
v-for="(sheet, i) in sheets"
|
|
346
|
+
:key="i"
|
|
347
|
+
:model-value="sheetsState[makeSheetId(sheet.axis)]"
|
|
348
|
+
:options="sheet.options"
|
|
349
|
+
@update:model-value="(newValue) => onSheetChanged(makeSheetId(sheet.axis), newValue)"
|
|
350
|
+
/>
|
|
351
|
+
</div>
|
|
352
|
+
</Transition>
|
|
274
353
|
<AgGridVue class="ap-ag-data-table-grid" :grid-options="gridOptions" />
|
|
275
354
|
</div>
|
|
276
355
|
</template>
|
|
@@ -282,6 +361,14 @@ watch(
|
|
|
282
361
|
height: 100%;
|
|
283
362
|
gap: 12px;
|
|
284
363
|
}
|
|
364
|
+
.ap-ag-data-table-sheets-transition-enter-active,
|
|
365
|
+
.ap-ag-data-table-sheets-transition-leave-active {
|
|
366
|
+
transition: all 0.2s ease-in-out;
|
|
367
|
+
}
|
|
368
|
+
.ap-ag-data-table-sheets-transition-enter-from,
|
|
369
|
+
.ap-ag-data-table-sheets-transition-leave-to {
|
|
370
|
+
margin-top: -52px;
|
|
371
|
+
}
|
|
285
372
|
.ap-ag-data-table-sheets {
|
|
286
373
|
display: flex;
|
|
287
374
|
flex-direction: row;
|
|
@@ -1,17 +1,7 @@
|
|
|
1
1
|
import type { ColDef, GridApi, IDatasource, IGetRowsParams } from '@ag-grid-community/core';
|
|
2
2
|
import {
|
|
3
3
|
type ValueType,
|
|
4
|
-
type
|
|
5
|
-
PValueIntNA,
|
|
6
|
-
PValueLongNA,
|
|
7
|
-
type PValueFloat,
|
|
8
|
-
PValueFloatNA,
|
|
9
|
-
type PValueDouble,
|
|
10
|
-
PValueDoubleNA,
|
|
11
|
-
type PValueString,
|
|
12
|
-
PValueStringNA,
|
|
13
|
-
type PValueBytes,
|
|
14
|
-
PValueBytesNA,
|
|
4
|
+
type PValue,
|
|
15
5
|
type PFrameDriver,
|
|
16
6
|
type PTableColumnId,
|
|
17
7
|
type PTableColumnSpec,
|
|
@@ -19,6 +9,14 @@ import {
|
|
|
19
9
|
type PTableVector,
|
|
20
10
|
type PColumnSpec,
|
|
21
11
|
getAxesId,
|
|
12
|
+
isValueNA,
|
|
13
|
+
isValueAbsent,
|
|
14
|
+
PFrameHandle,
|
|
15
|
+
AxisId,
|
|
16
|
+
PColumnIdAndSpec,
|
|
17
|
+
JoinEntry,
|
|
18
|
+
mapJoinEntry,
|
|
19
|
+
PObjectId
|
|
22
20
|
} from '@platforma-sdk/model';
|
|
23
21
|
import * as lodash from 'lodash';
|
|
24
22
|
import canonicalize from 'canonicalize';
|
|
@@ -78,46 +76,15 @@ function getColDef(iCol: number, spec: PTableColumnSpec): ColDef {
|
|
|
78
76
|
};
|
|
79
77
|
}
|
|
80
78
|
|
|
81
|
-
/**
|
|
82
|
-
* Check if value is NA
|
|
83
|
-
*/
|
|
84
|
-
function isValueNA(value: unknown, valueType: ValueType): boolean {
|
|
85
|
-
switch (valueType) {
|
|
86
|
-
case 'Int':
|
|
87
|
-
return (value as PValueInt) === PValueIntNA;
|
|
88
|
-
case 'Long':
|
|
89
|
-
return (value as bigint) === PValueLongNA;
|
|
90
|
-
case 'Float':
|
|
91
|
-
return (value as PValueFloat) === PValueFloatNA;
|
|
92
|
-
case 'Double':
|
|
93
|
-
return (value as PValueDouble) === PValueDoubleNA;
|
|
94
|
-
case 'String':
|
|
95
|
-
return (value as PValueString) === PValueStringNA;
|
|
96
|
-
case 'Bytes':
|
|
97
|
-
return (value as PValueBytes) === PValueBytesNA;
|
|
98
|
-
default:
|
|
99
|
-
throw Error(`unsupported data type: ${valueType satisfies never}`);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Check if value is absent
|
|
105
|
-
*/
|
|
106
|
-
function isValueAbsent(array: Uint8Array, index: number): boolean {
|
|
107
|
-
const chunkIndex = Math.floor(index / 8);
|
|
108
|
-
const mask = 1 << (7 - (index % 8));
|
|
109
|
-
return (array[chunkIndex] & mask) > 0;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
79
|
/**
|
|
113
80
|
* Convert value to displayable form
|
|
114
81
|
*/
|
|
115
|
-
function toDisplayValue(value:
|
|
82
|
+
function toDisplayValue(value: Exclude<PValue, null>, valueType: ValueType): string | number {
|
|
116
83
|
switch (valueType) {
|
|
117
84
|
case 'Int':
|
|
118
85
|
return value as number;
|
|
119
86
|
case 'Long':
|
|
120
|
-
return Number(value as bigint);
|
|
87
|
+
return typeof value === 'bigint' ? Number(value as bigint) : value as number;
|
|
121
88
|
case 'Float':
|
|
122
89
|
return value as number;
|
|
123
90
|
case 'Double':
|
|
@@ -129,6 +96,144 @@ function toDisplayValue(value: string | number | bigint | Uint8Array, valueType:
|
|
|
129
96
|
default:
|
|
130
97
|
throw Error(`unsupported data type: ${valueType satisfies never}`);
|
|
131
98
|
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
function getColumnsFromJoin(join: JoinEntry<PColumnIdAndSpec>): PColumnIdAndSpec[] {
|
|
102
|
+
const columns: PColumnIdAndSpec[] = [];
|
|
103
|
+
mapJoinEntry(join, (idAndSpec) => {
|
|
104
|
+
columns.push(idAndSpec);
|
|
105
|
+
return idAndSpec;
|
|
106
|
+
});
|
|
107
|
+
return columns;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async function getLabelColumns(
|
|
111
|
+
pfDriver: PFrameDriver,
|
|
112
|
+
pFrame: PFrameHandle,
|
|
113
|
+
idsAndSpecs: PColumnIdAndSpec[]
|
|
114
|
+
): Promise<PColumnIdAndSpec[]> {
|
|
115
|
+
if (!idsAndSpecs.length) return [];
|
|
116
|
+
|
|
117
|
+
const response = await pfDriver.findColumns(pFrame, {
|
|
118
|
+
columnFilter: {
|
|
119
|
+
name: ['pl7.app/label']
|
|
120
|
+
},
|
|
121
|
+
compatibleWith: lodash.uniqWith(
|
|
122
|
+
idsAndSpecs.map((column) => getAxesId(column.spec.axesSpec).map(lodash.cloneDeep)).flat(),
|
|
123
|
+
lodash.isEqual
|
|
124
|
+
),
|
|
125
|
+
strictlyCompatible: true
|
|
126
|
+
});
|
|
127
|
+
return response.hits.filter((idAndSpec) => idAndSpec.spec.axesSpec.length === 1);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export async function enrichJoinWithLabelColumns(
|
|
131
|
+
pfDriver: PFrameDriver,
|
|
132
|
+
pFrame: PFrameHandle,
|
|
133
|
+
join: JoinEntry<PColumnIdAndSpec>
|
|
134
|
+
): Promise<JoinEntry<PColumnIdAndSpec>> {
|
|
135
|
+
const columns = getColumnsFromJoin(join);
|
|
136
|
+
const labelColumns = await getLabelColumns(pfDriver, pFrame, columns);
|
|
137
|
+
const missingLabelColumns = labelColumns.filter((column) => !lodash.find(columns, (c) => column.columnId === c.columnId));
|
|
138
|
+
if (missingLabelColumns.length === 0) return join;
|
|
139
|
+
return {
|
|
140
|
+
type: 'outer',
|
|
141
|
+
primary: join,
|
|
142
|
+
secondary: missingLabelColumns.map((column) => ({
|
|
143
|
+
type: 'column',
|
|
144
|
+
column,
|
|
145
|
+
}))
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export async function makeSheets(
|
|
150
|
+
pfDriver: PFrameDriver,
|
|
151
|
+
pFrameHandle: PFrameHandle,
|
|
152
|
+
sheetAxes: AxisId[],
|
|
153
|
+
join: JoinEntry<PColumnIdAndSpec>
|
|
154
|
+
): Promise<PlDataTableSheet[]> {
|
|
155
|
+
const axes = sheetAxes.filter((spec) => spec.type !== 'Bytes');
|
|
156
|
+
|
|
157
|
+
const columns = getColumnsFromJoin(join);
|
|
158
|
+
|
|
159
|
+
const mapping: [number, number][][] = axes.map((_) => []);
|
|
160
|
+
const labelCol: (PObjectId | null)[] = axes.map((_) => null);
|
|
161
|
+
for (let i = 0; i < columns.length; ++i) {
|
|
162
|
+
const axesId = getAxesId(columns[i].spec.axesSpec);
|
|
163
|
+
for (let j = 0; j < axesId.length; ++j) {
|
|
164
|
+
const k = lodash.findIndex(axes, (axis) => lodash.isEqual(axis, axesId[j]));
|
|
165
|
+
if (k === -1 || labelCol[k]) continue;
|
|
166
|
+
|
|
167
|
+
if (axesId.length === 1 && columns[i].spec.name === 'pl7.app/label') {
|
|
168
|
+
mapping[k] = [[i, j]];
|
|
169
|
+
labelCol[k] = columns[i].columnId;
|
|
170
|
+
} else {
|
|
171
|
+
mapping[k].push([i, j]);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
for (let i = axes.length - 1; i >= 0; --i) {
|
|
177
|
+
if (!mapping[i].length) {
|
|
178
|
+
labelCol.splice(i, 1);
|
|
179
|
+
mapping.splice(i, 1);
|
|
180
|
+
axes.splice(i, 1);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const limit = 100;
|
|
185
|
+
const possibleValues: Set<string | number>[] = axes.map((_) => new Set());
|
|
186
|
+
|
|
187
|
+
loop1: for (let i = axes.length - 1; i >= 0; --i) {
|
|
188
|
+
for (const [column, _] of mapping[i]) {
|
|
189
|
+
const response = await pfDriver.getUniqueValues(pFrameHandle, {
|
|
190
|
+
columnId: columns[column].columnId,
|
|
191
|
+
...(!labelCol[i] && { axis: lodash.cloneDeep(axes[i]) }),
|
|
192
|
+
filters: [],
|
|
193
|
+
limit
|
|
194
|
+
});
|
|
195
|
+
if (response.overflow) {
|
|
196
|
+
labelCol.splice(i, 1);
|
|
197
|
+
mapping.splice(i, 1);
|
|
198
|
+
axes.splice(i, 1);
|
|
199
|
+
continue loop1;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const valueType = response.values.type;
|
|
203
|
+
for (const value of response.values.data) {
|
|
204
|
+
if (isValueNA(value, valueType) || value === null) continue;
|
|
205
|
+
possibleValues[i].add(toDisplayValue(value, valueType));
|
|
206
|
+
|
|
207
|
+
if (possibleValues[i].size === limit) {
|
|
208
|
+
labelCol.splice(i, 1);
|
|
209
|
+
mapping.splice(i, 1);
|
|
210
|
+
axes.splice(i, 1);
|
|
211
|
+
continue loop1;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (!possibleValues[i].size) {
|
|
217
|
+
labelCol.splice(i, 1);
|
|
218
|
+
mapping.splice(i, 1);
|
|
219
|
+
axes.splice(i, 1);
|
|
220
|
+
continue loop1;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return axes.map((axis, i) => {
|
|
225
|
+
const options = [...possibleValues[i]].map((value) => ({
|
|
226
|
+
value: value,
|
|
227
|
+
text: value.toString()
|
|
228
|
+
}));
|
|
229
|
+
const defaultValue = options[0].value;
|
|
230
|
+
return {
|
|
231
|
+
axis: lodash.cloneDeep(axis),
|
|
232
|
+
...(labelCol[i] && { column: labelCol[i] }),
|
|
233
|
+
options,
|
|
234
|
+
defaultValue
|
|
235
|
+
} as PlDataTableSheet;
|
|
236
|
+
});
|
|
132
237
|
}
|
|
133
238
|
|
|
134
239
|
/**
|
|
@@ -182,22 +287,21 @@ export async function updatePFrameGridOptions(
|
|
|
182
287
|
datasource: IDatasource;
|
|
183
288
|
}> {
|
|
184
289
|
const specs = await pfDriver.getSpec(pt);
|
|
185
|
-
const indices = specs
|
|
186
|
-
.
|
|
187
|
-
.filter((entry) => entry !== null);
|
|
290
|
+
const indices = [...specs.keys()]
|
|
291
|
+
.filter((i) => !lodash.find(sheets, (sheet) => lodash.isEqual(sheet.axis, specs[i].id) || lodash.isEqual(sheet.column, specs[i].id)));
|
|
188
292
|
const fields = lodash.cloneDeep(indices);
|
|
189
293
|
|
|
190
294
|
for (let i = indices.length - 1; i >= 0; --i) {
|
|
191
295
|
const idx = indices[i];
|
|
192
|
-
if (specs[idx].type
|
|
296
|
+
if (!(specs[idx].type === 'column' && specs[idx].spec.axesSpec.length === 1 && specs[idx].spec.name === 'pl7.app/label')) continue;
|
|
193
297
|
|
|
194
|
-
const axisId = getAxesId((specs[idx].spec as PColumnSpec).axesSpec)
|
|
298
|
+
const axisId = getAxesId((specs[idx].spec as PColumnSpec).axesSpec)[0];
|
|
195
299
|
const axisIdx = lodash.findIndex(indices, (idx) => lodash.isEqual(specs[idx].id, axisId));
|
|
196
300
|
if (axisIdx === -1) continue;
|
|
197
301
|
|
|
198
302
|
indices[axisIdx] = idx;
|
|
199
|
-
indices.splice(
|
|
200
|
-
fields.splice(
|
|
303
|
+
indices.splice(i, 1);
|
|
304
|
+
fields.splice(i, 1);
|
|
201
305
|
}
|
|
202
306
|
|
|
203
307
|
const columnDefs = fields.map((i) => getColDef(i, specs[i]));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AxisId, LocalBlobHandleAndSize, PObjectId, PTableHandle, RemoteBlobHandleAndSize, ValueOrErrors } from '@platforma-sdk/model';
|
|
1
|
+
import type { AxisId, JoinEntry, LocalBlobHandleAndSize, PColumnIdAndSpec, PFrameHandle, PObjectId, PTableHandle, RemoteBlobHandleAndSize, ValueOrErrors } from '@platforma-sdk/model';
|
|
2
2
|
|
|
3
3
|
export type PlDataTableSheet = {
|
|
4
4
|
/** id of the axis to use */
|
|
@@ -16,25 +16,30 @@ export type PlDataTableSheet = {
|
|
|
16
16
|
defaultValue?: string | number;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
/**
|
|
20
|
-
* Data table settings
|
|
21
|
-
*/
|
|
19
|
+
/** Data table settings */
|
|
22
20
|
export type PlDataTableSettings =
|
|
23
21
|
| {
|
|
24
|
-
/**
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
/** The type of the source to feed the data into the table */
|
|
23
|
+
sourceType: 'pframe';
|
|
24
|
+
/** PFrame handle output */
|
|
25
|
+
pFrame: ValueOrErrors<PFrameHandle | undefined> | undefined;
|
|
26
|
+
/** Join used to construct pTable, will be enriched with label-columns */
|
|
27
|
+
join: JoinEntry<PColumnIdAndSpec> | undefined;
|
|
28
|
+
/** Partitioning axes to make sheets */
|
|
29
|
+
sheetAxes: AxisId[];
|
|
30
|
+
/** PTable handle output */
|
|
31
|
+
pTable: ValueOrErrors<PTableHandle | undefined> | undefined;
|
|
32
|
+
}
|
|
33
|
+
| {
|
|
34
|
+
/** The type of the source to feed the data into the table */
|
|
27
35
|
sourceType: 'ptable';
|
|
28
|
-
/**
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
pTable?: ValueOrErrors<PTableHandle | undefined> | undefined;
|
|
32
|
-
/**
|
|
33
|
-
* Sheets that we want to show in our table
|
|
34
|
-
*/
|
|
36
|
+
/** PTable handle output */
|
|
37
|
+
pTable: ValueOrErrors<PTableHandle | undefined> | undefined;
|
|
38
|
+
/** Sheets that we want to show in our table */
|
|
35
39
|
sheets?: PlDataTableSheet[];
|
|
36
40
|
}
|
|
37
41
|
| {
|
|
42
|
+
/** The type of the source to feed the data into the table */
|
|
38
43
|
sourceType: 'xsv';
|
|
39
|
-
xsvFile
|
|
44
|
+
xsvFile: ValueOrErrors<RemoteBlobHandleAndSize | undefined> | ValueOrErrors<LocalBlobHandleAndSize | undefined> | undefined;
|
|
40
45
|
};
|