@platforma-sdk/model 1.74.0 → 1.75.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/dist/columns/column_collection_builder.cjs +4 -3
- package/dist/columns/column_collection_builder.cjs.map +1 -1
- package/dist/columns/column_collection_builder.d.ts +5 -5
- package/dist/columns/column_collection_builder.d.ts.map +1 -1
- package/dist/columns/column_collection_builder.js +4 -3
- package/dist/columns/column_collection_builder.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.d.ts +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs +14 -14
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts +3 -2
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js +16 -16
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs +50 -4
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js +51 -6
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/index.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/index.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.cjs +7 -4
- package/dist/components/PlDataTable/createPlDataTable/utils.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.js +16 -13
- package/dist/components/PlDataTable/createPlDataTable/utils.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTableSheet.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTableSheet.d.ts +1 -1
- package/dist/components/PlDataTable/createPlDataTableSheet.js.map +1 -1
- package/dist/components/PlDataTable/index.d.ts +1 -1
- package/dist/components/PlDataTable/state-migration.cjs +31 -5
- package/dist/components/PlDataTable/state-migration.cjs.map +1 -1
- package/dist/components/PlDataTable/state-migration.d.ts +13 -1
- package/dist/components/PlDataTable/state-migration.d.ts.map +1 -1
- package/dist/components/PlDataTable/state-migration.js +32 -6
- package/dist/components/PlDataTable/state-migration.js.map +1 -1
- package/dist/components/PlDataTable/typesV5.d.ts +19 -90
- package/dist/components/PlDataTable/typesV5.d.ts.map +1 -1
- package/dist/components/PlDataTable/typesV6.d.ts +98 -0
- package/dist/components/PlDataTable/typesV6.d.ts.map +1 -0
- package/dist/components/PlDatasetSelector/enrichment_discovery.cjs +5 -5
- package/dist/components/PlDatasetSelector/enrichment_discovery.cjs.map +1 -1
- package/dist/components/PlDatasetSelector/enrichment_discovery.js +5 -5
- package/dist/components/PlDatasetSelector/enrichment_discovery.js.map +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/labels/derive_distinct_labels.cjs +2 -2
- package/dist/labels/derive_distinct_labels.cjs.map +1 -1
- package/dist/labels/derive_distinct_labels.js +2 -2
- package/dist/labels/derive_distinct_labels.js.map +1 -1
- package/dist/labels/derive_distinct_tooltips.cjs +2 -1
- package/dist/labels/derive_distinct_tooltips.cjs.map +1 -1
- package/dist/labels/derive_distinct_tooltips.js +2 -1
- package/dist/labels/derive_distinct_tooltips.js.map +1 -1
- package/dist/package.cjs +1 -1
- package/dist/package.js +1 -1
- package/package.json +8 -8
- package/src/columns/column_collection_builder.test.ts +3 -7
- package/src/columns/column_collection_builder.ts +14 -35
- package/src/components/PlDataTable/createPlDataTable/createPTableDefV2.ts +1 -1
- package/src/components/PlDataTable/createPlDataTable/createPTableDefV3.ts +1 -1
- package/src/components/PlDataTable/createPlDataTable/createPlDataTableV2.ts +1 -1
- package/src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts +36 -21
- package/src/components/PlDataTable/createPlDataTable/discoverColumns.ts +57 -8
- package/src/components/PlDataTable/createPlDataTable/index.ts +1 -1
- package/src/components/PlDataTable/createPlDataTable/utils.test.ts +1 -1
- package/src/components/PlDataTable/createPlDataTable/utils.ts +9 -8
- package/src/components/PlDataTable/createPlDataTableSheet.ts +1 -1
- package/src/components/PlDataTable/index.ts +1 -2
- package/src/components/PlDataTable/state-migration.ts +71 -8
- package/src/components/PlDataTable/typesV5.ts +14 -153
- package/src/components/PlDataTable/typesV6.ts +152 -0
- package/src/components/PlDatasetSelector/enrichment_discovery.ts +5 -5
- package/src/labels/derive_distinct_labels.ts +2 -2
- package/src/labels/derive_distinct_tooltips.ts +2 -1
|
@@ -17,7 +17,7 @@ import { canonicalizeJson, getAxisId, parseJson, uniqueBy } from "@milaboratorie
|
|
|
17
17
|
import { collectFilterSpecColumns, traverseFilterSpec } from "../../../filters/traverse";
|
|
18
18
|
import type { RenderCtxBase, PColumnDataUniversal } from "../../../render";
|
|
19
19
|
import { isEmpty } from "es-toolkit/compat";
|
|
20
|
-
import type { PlDataTableFilters, PlDataTableFilterSpecLeaf, PlDataTableModel } from "../
|
|
20
|
+
import type { PlDataTableFilters, PlDataTableFilterSpecLeaf, PlDataTableModel } from "../typesV6";
|
|
21
21
|
import { upgradePlDataTableStateV2 } from "../state-migration";
|
|
22
22
|
import type { PlDataTableStateV2 } from "../state-migration";
|
|
23
23
|
import type { ColumnSelector, ColumnSnapshot, ColumnVariant, MatchingMode } from "../../../columns";
|
|
@@ -36,8 +36,12 @@ import {
|
|
|
36
36
|
} from "./utils";
|
|
37
37
|
import type { PrimaryEntry, SecondaryGroup } from "./createPTableDefV3";
|
|
38
38
|
import { createPTableDefV3 } from "./createPTableDefV3";
|
|
39
|
-
import {
|
|
40
|
-
|
|
39
|
+
import {
|
|
40
|
+
discoverLabelColumnVariants,
|
|
41
|
+
discoverTableColumnSnaphots,
|
|
42
|
+
type DiscoverTableColumnOptions,
|
|
43
|
+
} from "./discoverColumns";
|
|
44
|
+
import { getField, isNil, isPlainObject, throwError, type Nil } from "@milaboratories/helpers";
|
|
41
45
|
import { flow } from "es-toolkit";
|
|
42
46
|
|
|
43
47
|
export type createPlDataTableOptionsV3 = {
|
|
@@ -90,7 +94,12 @@ export function createPlDataTableV3<A, U>(
|
|
|
90
94
|
|
|
91
95
|
const discovered = isPlainObject(options.columns)
|
|
92
96
|
? discoverTableColumnSnaphots(ctx, options.columns)
|
|
93
|
-
: options.columns
|
|
97
|
+
: isNil(options.columns)
|
|
98
|
+
? options.columns
|
|
99
|
+
: uniqueBy(
|
|
100
|
+
[...options.columns, ...discoverLabelColumnVariants(ctx, options.columns)],
|
|
101
|
+
(c) => c.column.id,
|
|
102
|
+
);
|
|
94
103
|
if (isNil(discovered) || discovered.length === 0) return undefined;
|
|
95
104
|
|
|
96
105
|
const splited = splitDiscoveredColumns(discovered);
|
|
@@ -111,7 +120,7 @@ export function createPlDataTableV3<A, U>(
|
|
|
111
120
|
const derivedTooltips = deriveAllTooltips({
|
|
112
121
|
columns: discovered.map((dc) => ({
|
|
113
122
|
id: dc.column.id,
|
|
114
|
-
originalId: dc
|
|
123
|
+
originalId: getField(dc, "originalId"),
|
|
115
124
|
spec: dc.column.spec,
|
|
116
125
|
linkerPath: dc.path,
|
|
117
126
|
qualifications: dc.qualifications,
|
|
@@ -133,7 +142,7 @@ export function createPlDataTableV3<A, U>(
|
|
|
133
142
|
|
|
134
143
|
const columnIsAvailable = createColumnValidationById([
|
|
135
144
|
...annotated.direct.map((v) => v.column),
|
|
136
|
-
...annotated.linked.flatMap((lc) => [...lc.path.map((s) => s.linker), lc.column]),
|
|
145
|
+
...annotated.linked.flatMap((lc) => [...(lc.path ?? []).map((s) => s.linker), lc.column]),
|
|
137
146
|
]);
|
|
138
147
|
|
|
139
148
|
const remapedDefaultFilters = remapFilterColumnIds(options.filters, discovered);
|
|
@@ -204,8 +213,10 @@ export function createPlDataTableV3<A, U>(
|
|
|
204
213
|
} satisfies PlDataTableModel;
|
|
205
214
|
}
|
|
206
215
|
|
|
207
|
-
export type TableColumnVariant =
|
|
208
|
-
|
|
216
|
+
export type TableColumnVariant = (
|
|
217
|
+
| ColumnVariant<PObjectId>
|
|
218
|
+
| (ColumnVariant<DiscoveredPColumnId> & { readonly originalId: PObjectId })
|
|
219
|
+
) & {
|
|
209
220
|
readonly isPrimary?: boolean;
|
|
210
221
|
};
|
|
211
222
|
|
|
@@ -226,15 +237,15 @@ type VisibleColumns = {
|
|
|
226
237
|
|
|
227
238
|
/** Split discovered columns into direct (no linker path) and linked (with linker path). */
|
|
228
239
|
function splitDiscoveredColumns(columns: TableColumnVariant[]): SplitDiscoveredColumns {
|
|
229
|
-
const direct = columns.filter((dc) => dc.path
|
|
230
|
-
const linked = columns.filter((dc) => dc.path
|
|
240
|
+
const direct = columns.filter((dc) => (dc.path?.length ?? 0) === 0);
|
|
241
|
+
const linked = columns.filter((dc) => (dc.path?.length ?? 0) > 0);
|
|
231
242
|
return { direct, linked };
|
|
232
243
|
}
|
|
233
244
|
|
|
234
245
|
/** All linker snapshots across the given linked columns, deduped by id. */
|
|
235
246
|
function collectLinkerSnapshots(linked: TableColumnVariant[]): ColumnSnapshot<PObjectId>[] {
|
|
236
247
|
return uniqueBy(
|
|
237
|
-
linked.flatMap((lc) => lc.path.map((s) => s.linker)),
|
|
248
|
+
linked.flatMap((lc) => (lc.path ?? []).map((s) => s.linker)),
|
|
238
249
|
(c) => c.id,
|
|
239
250
|
);
|
|
240
251
|
}
|
|
@@ -299,9 +310,13 @@ function annotateColumnGroups(params: {
|
|
|
299
310
|
}
|
|
300
311
|
|
|
301
312
|
/** Lift a snapshot-array transform so it runs on the inner `column` of each variant. */
|
|
302
|
-
function liftToVariantColumns<
|
|
313
|
+
function liftToVariantColumns<
|
|
314
|
+
V extends { readonly column: ColumnSnapshot<PObjectId | DiscoveredPColumnId> },
|
|
315
|
+
>(
|
|
303
316
|
variants: V[],
|
|
304
|
-
fn: (
|
|
317
|
+
fn: (
|
|
318
|
+
cols: ColumnSnapshot<PObjectId | DiscoveredPColumnId>[],
|
|
319
|
+
) => ColumnSnapshot<PObjectId | DiscoveredPColumnId>[],
|
|
305
320
|
): V[] {
|
|
306
321
|
const cols = fn(variants.map((v) => v.column));
|
|
307
322
|
if (cols.length !== variants.length)
|
|
@@ -315,7 +330,7 @@ function annotateLinkerPath(
|
|
|
315
330
|
derivedLabels: Record<string, string>,
|
|
316
331
|
path: TableColumnVariant["path"],
|
|
317
332
|
): TableColumnVariant["path"] {
|
|
318
|
-
if (path.length === 0) return path;
|
|
333
|
+
if (isNil(path) || path.length === 0) return path;
|
|
319
334
|
const annotatedLinkers = withHidenAxesAnnotations(
|
|
320
335
|
withLabelAnnotations(
|
|
321
336
|
derivedLabels,
|
|
@@ -410,8 +425,8 @@ function buildSecondaryGroups(
|
|
|
410
425
|
return [
|
|
411
426
|
...direct.map(
|
|
412
427
|
(c): SecondaryGroup<undefined | PColumnDataUniversal> => ({
|
|
413
|
-
entries: [{ column: resolveSnapshot(c.column), qualifications: c.qualifications
|
|
414
|
-
primaryQualifications: c.qualifications
|
|
428
|
+
entries: [{ column: resolveSnapshot(c.column), qualifications: c.qualifications?.forHit }],
|
|
429
|
+
primaryQualifications: c.qualifications?.forQueries,
|
|
415
430
|
}),
|
|
416
431
|
),
|
|
417
432
|
...linked.map(
|
|
@@ -419,11 +434,11 @@ function buildSecondaryGroups(
|
|
|
419
434
|
entries: [
|
|
420
435
|
{
|
|
421
436
|
column: resolveSnapshot(lc.column),
|
|
422
|
-
|
|
423
|
-
|
|
437
|
+
linkers: lc.path?.map((s) => resolveSnapshot(s.linker)),
|
|
438
|
+
qualifications: lc.qualifications?.forHit,
|
|
424
439
|
},
|
|
425
440
|
],
|
|
426
|
-
primaryQualifications: lc.qualifications
|
|
441
|
+
primaryQualifications: lc.qualifications?.forQueries,
|
|
427
442
|
}),
|
|
428
443
|
),
|
|
429
444
|
];
|
|
@@ -492,7 +507,7 @@ function remapSortingColumnIds(
|
|
|
492
507
|
if (s.column.type === "axis") return [s]; // Axis references are unaffected by column ID remapping
|
|
493
508
|
|
|
494
509
|
const id = s.column.id;
|
|
495
|
-
const column = columns.find((c) => (c
|
|
510
|
+
const column = columns.find((c) => (getField(c, "originalId") ?? c.column.id) === id);
|
|
496
511
|
if (column === undefined) return [];
|
|
497
512
|
|
|
498
513
|
return [
|
|
@@ -524,7 +539,7 @@ function remapFilterColumnIds(
|
|
|
524
539
|
|
|
525
540
|
const originalId = parsed.id;
|
|
526
541
|
const column =
|
|
527
|
-
columns.find((c) => (c
|
|
542
|
+
columns.find((c) => (getField(c, "originalId") ?? c.column.id) === originalId) ??
|
|
528
543
|
throwError(`Column ID "${parsed.id}" in filters does not match any discovered column`);
|
|
529
544
|
|
|
530
545
|
return canonicalizeJson<PTableColumnId>({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PColumnSpec, PlRef, PObjectId } from "@milaboratories/pl-model-common";
|
|
2
|
-
import { createDiscoveredPColumnId, isPlRef } from "@milaboratories/pl-model-common";
|
|
2
|
+
import { createDiscoveredPColumnId, isPlRef, PColumnName } from "@milaboratories/pl-model-common";
|
|
3
3
|
import type { RenderCtxBase } from "../../../render";
|
|
4
4
|
import type {
|
|
5
5
|
ColumnSource,
|
|
@@ -42,9 +42,7 @@ export function discoverTableColumnSnaphots(
|
|
|
42
42
|
if (collection === undefined) return undefined;
|
|
43
43
|
|
|
44
44
|
try {
|
|
45
|
-
const variants = collection.findColumnVariants(
|
|
46
|
-
...(resolvedOptions.selector ?? {}),
|
|
47
|
-
});
|
|
45
|
+
const variants = collection.findColumnVariants(resolvedOptions.selector);
|
|
48
46
|
const anchors = collection.getAnchors();
|
|
49
47
|
return mapToTableColumnVariants(variants, anchors);
|
|
50
48
|
} finally {
|
|
@@ -52,7 +50,58 @@ export function discoverTableColumnSnaphots(
|
|
|
52
50
|
}
|
|
53
51
|
}
|
|
54
52
|
|
|
55
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Discover label columns matching the axes of the given value columns from
|
|
55
|
+
* ctx providers. Returns label snapshots wrapped as direct TableColumnVariants
|
|
56
|
+
* (path: [], empty qualifications, isPrimary: false).
|
|
57
|
+
*/
|
|
58
|
+
export function discoverLabelColumnVariants<A, U>(
|
|
59
|
+
ctx: RenderCtxBase<A, U>,
|
|
60
|
+
columns: TableColumnVariant[],
|
|
61
|
+
): TableColumnVariant[] {
|
|
62
|
+
if (columns.length === 0) return [];
|
|
63
|
+
const collection = new ColumnCollectionBuilder(ctx.getService("pframeSpec"))
|
|
64
|
+
.addSources(collectCtxColumnSnapshotProviders(ctx))
|
|
65
|
+
.addSource(columns.map((c) => c.column))
|
|
66
|
+
.build({
|
|
67
|
+
allowPartialColumnList: true,
|
|
68
|
+
anchors: Object.fromEntries(
|
|
69
|
+
columns
|
|
70
|
+
.filter((col) => (col.path?.length ?? 0) === 0 && col.isPrimary)
|
|
71
|
+
.map((col, i) => [`anchor_${i}`, col.column.spec]),
|
|
72
|
+
),
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
const axes = columns.flatMap((col) => col.column.spec.axesSpec);
|
|
77
|
+
return collection
|
|
78
|
+
.findColumnVariants({
|
|
79
|
+
include: axes.map((a) => ({
|
|
80
|
+
name: { type: "exact", value: PColumnName.Label },
|
|
81
|
+
axes: [{ name: { type: "exact", value: a.name } }],
|
|
82
|
+
})),
|
|
83
|
+
maxHops: columns.reduce((acc, c) => Math.max(acc, c.path?.length ?? 0), 0),
|
|
84
|
+
})
|
|
85
|
+
.map((variant) => ({
|
|
86
|
+
...variant,
|
|
87
|
+
column: {
|
|
88
|
+
...variant.column,
|
|
89
|
+
id: createDiscoveredPColumnId({
|
|
90
|
+
column: variant.column.id,
|
|
91
|
+
path: variant.path?.map((p) => ({
|
|
92
|
+
type: "linker",
|
|
93
|
+
column: p.linker.id,
|
|
94
|
+
})),
|
|
95
|
+
columnQualifications: variant.qualifications?.forHit,
|
|
96
|
+
queriesQualifications: variant.qualifications?.forQueries,
|
|
97
|
+
}),
|
|
98
|
+
originalId: variant.column.id,
|
|
99
|
+
},
|
|
100
|
+
}));
|
|
101
|
+
} finally {
|
|
102
|
+
collection.dispose();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
56
105
|
|
|
57
106
|
/** Resolve PlRef values in anchors to PColumnSpec via the result pool. */
|
|
58
107
|
function resolveAnchors(
|
|
@@ -99,12 +148,12 @@ function mapToTableColumnVariants(
|
|
|
99
148
|
|
|
100
149
|
const discoveredId = createDiscoveredPColumnId({
|
|
101
150
|
column: snap.id,
|
|
102
|
-
path: variant.path
|
|
151
|
+
path: variant.path?.map((p) => ({
|
|
103
152
|
type: "linker",
|
|
104
153
|
column: p.linker.id,
|
|
105
154
|
})),
|
|
106
|
-
columnQualifications: variant.qualifications
|
|
107
|
-
queriesQualifications: variant.qualifications
|
|
155
|
+
columnQualifications: variant.qualifications?.forHit,
|
|
156
|
+
queriesQualifications: variant.qualifications?.forQueries,
|
|
108
157
|
});
|
|
109
158
|
return {
|
|
110
159
|
column: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { RenderCtxBase } from "../../../render";
|
|
2
|
-
import type { PlDataTableModel } from "../
|
|
2
|
+
import type { PlDataTableModel } from "../typesV6";
|
|
3
3
|
import { createPlDataTableOptionsV2, createPlDataTableV2 } from "./createPlDataTableV2";
|
|
4
4
|
import { createPlDataTableV3 } from "./createPlDataTableV3";
|
|
5
5
|
import type { createPlDataTableOptionsV3 } from "./createPlDataTableV3";
|
|
@@ -114,7 +114,7 @@ describe("deriveAllLabels", () => {
|
|
|
114
114
|
makeLabelableColumn(
|
|
115
115
|
"c1",
|
|
116
116
|
{ name: "shared", annotations: { [Annotation.Label]: "Cluster size" } },
|
|
117
|
-
[{ linker: { id: "lk" as PObjectId, spec: linkerSpec } as never
|
|
117
|
+
[{ linker: { id: "lk" as PObjectId, spec: linkerSpec } as never }],
|
|
118
118
|
),
|
|
119
119
|
makeLabelableColumn("c2", {
|
|
120
120
|
name: "shared",
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
canonicalizeAxisId,
|
|
8
8
|
DiscoveredPColumnId,
|
|
9
9
|
readAnnotation,
|
|
10
|
-
readAnnotationJson,
|
|
11
10
|
} from "@milaboratories/pl-model-common";
|
|
12
11
|
import {
|
|
13
12
|
deriveDistinctLabels,
|
|
@@ -22,6 +21,7 @@ import type { ColumnMatcher, ColumnOrderRule, ColumnVisibilityRule } from "./cre
|
|
|
22
21
|
import type { ColumnSelector } from "../../../columns";
|
|
23
22
|
import { ArrayColumnProvider, ColumnCollectionBuilder } from "../../../columns";
|
|
24
23
|
import { isNil } from "es-toolkit";
|
|
24
|
+
import { getField } from "@milaboratories/helpers";
|
|
25
25
|
|
|
26
26
|
/** Check if column should be omitted from the table */
|
|
27
27
|
export function isColumnHidden(spec: { annotations?: Annotation }): boolean {
|
|
@@ -55,7 +55,8 @@ export function getOrderPriority(
|
|
|
55
55
|
): undefined | number {
|
|
56
56
|
const rule = orderByColId?.get(col.id);
|
|
57
57
|
if (rule !== undefined) return rule.priority;
|
|
58
|
-
|
|
58
|
+
const annotation = Number(readAnnotation(col.spec, Annotation.Table.OrderPriority));
|
|
59
|
+
return isNaN(annotation) ? undefined : annotation;
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
/**
|
|
@@ -276,9 +277,9 @@ export function deriveAllLabels(options: {
|
|
|
276
277
|
|
|
277
278
|
/** Column shape required by tooltip derivation. */
|
|
278
279
|
export type TooltipableColumn = {
|
|
279
|
-
readonly id: DiscoveredPColumnId;
|
|
280
|
+
readonly id: PObjectId | DiscoveredPColumnId;
|
|
280
281
|
readonly spec: PColumnSpec;
|
|
281
|
-
readonly originalId
|
|
282
|
+
readonly originalId?: PObjectId;
|
|
282
283
|
readonly linkerPath?: MatchVariant["path"];
|
|
283
284
|
readonly qualifications?: MatchQualifications;
|
|
284
285
|
};
|
|
@@ -290,15 +291,15 @@ export function deriveAllTooltips(options: {
|
|
|
290
291
|
const { columns } = options;
|
|
291
292
|
|
|
292
293
|
const variantCountByOriginal = columns.reduce<Map<PObjectId, number>>((acc, c) => {
|
|
293
|
-
return acc.set(c.
|
|
294
|
+
return acc.set(getField(c, "originalId") ?? c.id, (acc.get(c.originalId ?? c.id) ?? 0) + 1);
|
|
294
295
|
}, new Map());
|
|
295
296
|
|
|
296
297
|
const { entries } = columns.reduce(
|
|
297
298
|
({ entries, variantSeen }, c) => {
|
|
298
|
-
const
|
|
299
|
+
const id = getField(c, "originalId") ?? c.id;
|
|
300
|
+
const variantCount = variantCountByOriginal.get(id);
|
|
299
301
|
const variantIndex =
|
|
300
|
-
(variantSeen.set(
|
|
301
|
-
variantSeen.get(c.originalId));
|
|
302
|
+
(variantSeen.set(id, (variantSeen.get(id) ?? 0) + 1), variantSeen.get(id));
|
|
302
303
|
|
|
303
304
|
entries.push({
|
|
304
305
|
spec: c.spec,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AxisSpec } from "@milaboratories/pl-model-common";
|
|
2
2
|
import type { RenderCtxBase } from "../../render";
|
|
3
|
-
import type { PlDataTableSheet } from "./
|
|
3
|
+
import type { PlDataTableSheet } from "./typesV6";
|
|
4
4
|
|
|
5
5
|
/** Create sheet entries for PlDataTable */
|
|
6
6
|
export function createPlDataTableSheet<A, U>(
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// If you need to export something from previous versions,
|
|
2
2
|
// that mean you don't forget update deps to the latest version of the package.
|
|
3
3
|
export type {
|
|
4
|
-
PlTableColumnId,
|
|
5
4
|
PlTableColumnIdJson,
|
|
6
5
|
PlDataTableGridStateCore,
|
|
7
6
|
PlDataTableSheet,
|
|
@@ -14,7 +13,7 @@ export type {
|
|
|
14
13
|
PlDataTableFilterMeta,
|
|
15
14
|
PlDataTableFilters,
|
|
16
15
|
PlDataTableFiltersWithMeta,
|
|
17
|
-
} from "./
|
|
16
|
+
} from "./typesV6";
|
|
18
17
|
|
|
19
18
|
export type { PlDataTableStateV2 } from "./state-migration";
|
|
20
19
|
export {
|
|
@@ -7,7 +7,7 @@ import type {
|
|
|
7
7
|
PTableRecordFilter,
|
|
8
8
|
PTableSorting,
|
|
9
9
|
} from "@milaboratories/pl-model-common";
|
|
10
|
-
import { canonicalizeJson } from "@milaboratories/pl-model-common";
|
|
10
|
+
import { canonicalizeJson, parseJson } from "@milaboratories/pl-model-common";
|
|
11
11
|
import { distillFilterSpec } from "../../filters";
|
|
12
12
|
import type { PlDataTableFilterState, PlTableFilter } from "./typesV4";
|
|
13
13
|
import type {
|
|
@@ -17,7 +17,8 @@ import type {
|
|
|
17
17
|
PlDataTableStateV2CacheEntry,
|
|
18
18
|
PlDataTableStateV2Normalized,
|
|
19
19
|
PTableParamsV2,
|
|
20
|
-
} from "./
|
|
20
|
+
} from "./typesV6";
|
|
21
|
+
import type { PlDataTableGridStateV5, PlDataTableV5ColIdJson } from "./typesV5";
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* PlDataTableV2 persisted state
|
|
@@ -111,6 +112,19 @@ export type PlDataTableStateV2 =
|
|
|
111
112
|
sorting: PTableSorting[];
|
|
112
113
|
};
|
|
113
114
|
}
|
|
115
|
+
// v5 stored colIds as `{source, labeled}` wrappers; only the gridState shape differs.
|
|
116
|
+
| {
|
|
117
|
+
version: 5;
|
|
118
|
+
stateCache: {
|
|
119
|
+
sourceId: string;
|
|
120
|
+
gridState: PlDataTableGridStateV5;
|
|
121
|
+
sheetsState: PlDataTableSheetState[];
|
|
122
|
+
filtersState: null | PlDataTableFiltersWithMeta;
|
|
123
|
+
defaultFiltersState: null | PlDataTableFiltersWithMeta;
|
|
124
|
+
searchString?: string;
|
|
125
|
+
}[];
|
|
126
|
+
pTableParams: PTableParamsV2;
|
|
127
|
+
}
|
|
114
128
|
// Normalized state
|
|
115
129
|
| PlDataTableStateV2Normalized;
|
|
116
130
|
|
|
@@ -143,15 +157,64 @@ export function upgradePlDataTableStateV2(
|
|
|
143
157
|
// Non upgradeable as column ids calculation algorithm has changed, resetting state to default
|
|
144
158
|
state = createPlDataTableStateV2();
|
|
145
159
|
}
|
|
146
|
-
// v4 ->
|
|
160
|
+
// v4 -> v6: migrate per-column filters to tree-based format (skips v5).
|
|
161
|
+
// v4 gridState already used bare PTableColumnSpec colIds, so we jump
|
|
162
|
+
// straight to v6 without going through the v5 wrapper format.
|
|
147
163
|
if (state.version === 4) {
|
|
148
|
-
state =
|
|
164
|
+
state = migrateV4toV6(state);
|
|
165
|
+
}
|
|
166
|
+
// v5 -> v6: unwrap `{source, labeled}` colIds in gridState back to bare PTableColumnSpec.
|
|
167
|
+
if (state.version === 5) {
|
|
168
|
+
state = migrateV5toV6(state);
|
|
149
169
|
}
|
|
150
170
|
return state;
|
|
151
171
|
}
|
|
152
172
|
|
|
153
|
-
/** Migrate
|
|
154
|
-
function
|
|
173
|
+
/** Migrate v5 to v6: unwrap `{source, labeled}` colIds in gridState. */
|
|
174
|
+
function migrateV5toV6(
|
|
175
|
+
state: Extract<PlDataTableStateV2, { version: 5 }>,
|
|
176
|
+
): PlDataTableStateV2Normalized {
|
|
177
|
+
// pTableParams reset: v5 stored DiscoveredPColumnId-based hiddenColIds with
|
|
178
|
+
// empty-array fields (e.g. `{column, path: [], columnQualifications: [], ...}`).
|
|
179
|
+
// v6 distills empty fields, so the same logical column serialises differently
|
|
180
|
+
// and lookups would silently miss every previously-hidden discovered column.
|
|
181
|
+
// gridState colIds are derived from PTableColumnSpec and unaffected.
|
|
182
|
+
return {
|
|
183
|
+
version: 6,
|
|
184
|
+
stateCache: state.stateCache.map((entry) => ({
|
|
185
|
+
...entry,
|
|
186
|
+
gridState: unwrapV5GridState(entry.gridState),
|
|
187
|
+
})),
|
|
188
|
+
pTableParams: createDefaultPTableParams(),
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** Convert v5 wrapped colId JSON to bare PTableColumnSpec JSON, taking `.source`. */
|
|
193
|
+
function unwrapV5ColId(json: PlDataTableV5ColIdJson): CanonicalizedJson<PTableColumnSpec> {
|
|
194
|
+
return canonicalizeJson(parseJson(json).source);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function unwrapV5GridState(gridState: PlDataTableGridStateV5): PlDataTableGridStateCore {
|
|
198
|
+
return {
|
|
199
|
+
columnOrder: gridState.columnOrder
|
|
200
|
+
? { orderedColIds: gridState.columnOrder.orderedColIds.map(unwrapV5ColId) }
|
|
201
|
+
: undefined,
|
|
202
|
+
sort: gridState.sort
|
|
203
|
+
? {
|
|
204
|
+
sortModel: gridState.sort.sortModel.map((s) => ({
|
|
205
|
+
colId: unwrapV5ColId(s.colId),
|
|
206
|
+
sort: s.sort,
|
|
207
|
+
})),
|
|
208
|
+
}
|
|
209
|
+
: undefined,
|
|
210
|
+
columnVisibility: gridState.columnVisibility
|
|
211
|
+
? { hiddenColIds: gridState.columnVisibility.hiddenColIds.map(unwrapV5ColId) }
|
|
212
|
+
: undefined,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/** Migrate v4 state to v6: convert per-column filters to tree-based format (skips v5). */
|
|
217
|
+
function migrateV4toV6(
|
|
155
218
|
state: Extract<PlDataTableStateV2, { version: 4 }>,
|
|
156
219
|
): PlDataTableStateV2Normalized {
|
|
157
220
|
let idCounter = 0;
|
|
@@ -183,7 +246,7 @@ function migrateV4toV5(
|
|
|
183
246
|
: undefined;
|
|
184
247
|
|
|
185
248
|
return {
|
|
186
|
-
version:
|
|
249
|
+
version: 6,
|
|
187
250
|
stateCache: migratedCache,
|
|
188
251
|
pTableParams:
|
|
189
252
|
currentCache && oldSourceId
|
|
@@ -283,7 +346,7 @@ export function createDefaultPTableParams(): PTableParamsV2 {
|
|
|
283
346
|
|
|
284
347
|
export function createPlDataTableStateV2(): PlDataTableStateV2Normalized {
|
|
285
348
|
return {
|
|
286
|
-
version:
|
|
349
|
+
version: 6,
|
|
287
350
|
stateCache: [],
|
|
288
351
|
pTableParams: createDefaultPTableParams(),
|
|
289
352
|
};
|
|
@@ -1,159 +1,20 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
RootFilterSpec,
|
|
11
|
-
PTableColumnId,
|
|
12
|
-
PFrameHandle,
|
|
13
|
-
} from "@milaboratories/pl-model-common";
|
|
14
|
-
import type { FilterSpecLeaf } from "../../filters";
|
|
15
|
-
import { Nil } from "@milaboratories/helpers";
|
|
16
|
-
|
|
17
|
-
export type PlTableColumnId = {
|
|
18
|
-
/** Original column spec */
|
|
1
|
+
import type { CanonicalizedJson, PTableColumnSpec } from "@milaboratories/pl-model-common";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* v5 colId wrapper. v5 stored every grid colId as `{ source, labeled }` —
|
|
5
|
+
* `source` was the original column spec, `labeled` was the spec with
|
|
6
|
+
* labeled axes substituted by their label columns. v6 dropped the wrapper
|
|
7
|
+
* and stores bare `PTableColumnSpec`. Kept here for the v5→v6 migration.
|
|
8
|
+
*/
|
|
9
|
+
export type PlDataTableV5ColIdWrapper = {
|
|
19
10
|
source: PTableColumnSpec;
|
|
20
|
-
/** Column spec with labeled axes replaced by label columns */
|
|
21
11
|
labeled: PTableColumnSpec;
|
|
22
12
|
};
|
|
23
13
|
|
|
24
|
-
export type
|
|
25
|
-
|
|
26
|
-
export type PlDataTableGridStateCore = {
|
|
27
|
-
/** Includes column ordering */
|
|
28
|
-
columnOrder?: {
|
|
29
|
-
/** All colIds in order */
|
|
30
|
-
orderedColIds: PlTableColumnIdJson[];
|
|
31
|
-
};
|
|
32
|
-
/** Includes current sort columns and direction */
|
|
33
|
-
sort?: {
|
|
34
|
-
/** Sorted columns and directions in order */
|
|
35
|
-
sortModel: {
|
|
36
|
-
/** Column Id to apply the sort to. */
|
|
37
|
-
colId: PlTableColumnIdJson;
|
|
38
|
-
/** Sort direction */
|
|
39
|
-
sort: "asc" | "desc";
|
|
40
|
-
}[];
|
|
41
|
-
};
|
|
42
|
-
/** Includes column visibility */
|
|
43
|
-
columnVisibility?: {
|
|
44
|
-
/** All colIds which were hidden */
|
|
45
|
-
hiddenColIds: PlTableColumnIdJson[];
|
|
46
|
-
};
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
export type PlDataTableSheet = {
|
|
50
|
-
/** spec of the axis to use */
|
|
51
|
-
axis: AxisSpec;
|
|
52
|
-
/** options to show in the filter dropdown */
|
|
53
|
-
options: ListOptionBase<string | number>[];
|
|
54
|
-
/** default (selected) value */
|
|
55
|
-
defaultValue?: string | number;
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
export type PlDataTableSheetState = {
|
|
59
|
-
/** id of the axis */
|
|
60
|
-
axisId: AxisId;
|
|
61
|
-
/** selected value */
|
|
62
|
-
value: string | number;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
/** Tree-based filter state compatible with PlAdvancedFilter's RootFilter */
|
|
66
|
-
export type PlDataTableFilterMeta = {
|
|
67
|
-
id: number;
|
|
68
|
-
source?: "table-filter" | "table-search";
|
|
69
|
-
isExpanded?: boolean;
|
|
70
|
-
isSuppressed?: boolean;
|
|
71
|
-
};
|
|
72
|
-
export type PlDataTableFilterSpecLeaf = FilterSpecLeaf<CanonicalizedJson<PTableColumnId>>;
|
|
73
|
-
export type PlDataTableFilters = RootFilterSpec<PlDataTableFilterSpecLeaf>;
|
|
74
|
-
export type PlDataTableFiltersWithMeta = RootFilterSpec<
|
|
75
|
-
PlDataTableFilterSpecLeaf,
|
|
76
|
-
PlDataTableFilterMeta
|
|
77
|
-
>;
|
|
78
|
-
|
|
79
|
-
export type PlDataTableStateV2CacheEntry = {
|
|
80
|
-
/** DataSource identifier for state management */
|
|
81
|
-
sourceId: string;
|
|
82
|
-
/** Internal ag-grid state */
|
|
83
|
-
gridState: PlDataTableGridStateCore;
|
|
84
|
-
/** Sheets state */
|
|
85
|
-
sheetsState: PlDataTableSheetState[];
|
|
86
|
-
/** User filters state (tree-based, compatible with PlAdvancedFilter) */
|
|
87
|
-
filtersState: null | PlDataTableFiltersWithMeta;
|
|
88
|
-
/** Default filters state from model (snapshot of defaults) */
|
|
89
|
-
defaultFiltersState: null | PlDataTableFiltersWithMeta;
|
|
90
|
-
/** Fast search string */
|
|
91
|
-
searchString?: string;
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
export type PTableParamsV2 =
|
|
95
|
-
| {
|
|
96
|
-
sourceId: null;
|
|
97
|
-
hiddenColIds: null;
|
|
98
|
-
sorting: [];
|
|
99
|
-
filters: null;
|
|
100
|
-
defaultFilters: null;
|
|
101
|
-
}
|
|
102
|
-
| {
|
|
103
|
-
sourceId: string;
|
|
104
|
-
hiddenColIds: null | PTableColumnId[];
|
|
105
|
-
sorting: PTableSorting[];
|
|
106
|
-
filters: null | PlDataTableFilters;
|
|
107
|
-
defaultFilters: null | PlDataTableFilters;
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
export type PlDataTableStateV2Normalized = {
|
|
111
|
-
/** Version for upgrades */
|
|
112
|
-
version: 5;
|
|
113
|
-
/** Internal states, LRU cache for 5 sourceId-s */
|
|
114
|
-
stateCache: PlDataTableStateV2CacheEntry[];
|
|
115
|
-
/** PTable params derived from the cache state for the current sourceId */
|
|
116
|
-
pTableParams: PTableParamsV2;
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
/** PlAgDataTable model */
|
|
120
|
-
export type PlDataTableModel = {
|
|
121
|
-
/** DataSource identifier for state management */
|
|
122
|
-
sourceId: null | string;
|
|
123
|
-
/** p-table including all columns, used to show the full specification of the table */
|
|
124
|
-
fullTableHandle?: PTableHandle;
|
|
125
|
-
/** p-frame handle */
|
|
126
|
-
fullPframeHandle?: PFrameHandle;
|
|
127
|
-
/** p-table including only visible columns, used to get the data */
|
|
128
|
-
visibleTableHandle?: PTableHandle;
|
|
129
|
-
/** Default filters from model options, surfaced for UI display */
|
|
130
|
-
defaultFilters?: Nil | PlDataTableFilters;
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
export type CreatePlDataTableOps = {
|
|
134
|
-
/** Filters for columns and non-partitioned axes */
|
|
135
|
-
filters?: PlDataTableFilters;
|
|
136
|
-
|
|
137
|
-
/** Sorting to columns hidden from user */
|
|
138
|
-
sorting?: PTableSorting[];
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Selects columns for which will be inner-joined to the table.
|
|
142
|
-
*
|
|
143
|
-
* Default behaviour: all columns are considered to be core
|
|
144
|
-
*/
|
|
145
|
-
coreColumnPredicate?: (spec: PColumnIdAndSpec) => boolean;
|
|
14
|
+
export type PlDataTableV5ColIdJson = CanonicalizedJson<PlDataTableV5ColIdWrapper>;
|
|
146
15
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
*
|
|
152
|
-
* All non-core columns will be left joined to the table produced by the core
|
|
153
|
-
* columns, in other words records form the pool of non-core columns will only
|
|
154
|
-
* make their way into the final table if core table contains corresponding key.
|
|
155
|
-
*
|
|
156
|
-
* Default: 'full'
|
|
157
|
-
*/
|
|
158
|
-
coreJoinType?: "inner" | "full";
|
|
16
|
+
export type PlDataTableGridStateV5 = {
|
|
17
|
+
columnOrder?: { orderedColIds: PlDataTableV5ColIdJson[] };
|
|
18
|
+
sort?: { sortModel: { colId: PlDataTableV5ColIdJson; sort: "asc" | "desc" }[] };
|
|
19
|
+
columnVisibility?: { hiddenColIds: PlDataTableV5ColIdJson[] };
|
|
159
20
|
};
|