@platforma-sdk/model 1.68.4 → 1.68.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/dist/columns/column_collection_builder.cjs +8 -2
- package/dist/columns/column_collection_builder.cjs.map +1 -1
- package/dist/columns/column_collection_builder.d.ts +14 -3
- package/dist/columns/column_collection_builder.d.ts.map +1 -1
- package/dist/columns/column_collection_builder.js +8 -2
- package/dist/columns/column_collection_builder.js.map +1 -1
- package/dist/columns/ctx_column_sources.d.ts +1 -1
- package/dist/columns/index.d.ts +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs +3 -5
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js +3 -5
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs +48 -49
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts +5 -10
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js +48 -49
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs +16 -17
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts +4 -4
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js +16 -17
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.cjs +8 -2
- package/dist/components/PlDataTable/createPlDataTable/utils.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.js +8 -2
- package/dist/components/PlDataTable/createPlDataTable/utils.js.map +1 -1
- package/dist/components/PlDatasetSelector/filter_discovery.d.ts +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/labels/derive_distinct_labels.cjs +121 -50
- package/dist/labels/derive_distinct_labels.cjs.map +1 -1
- package/dist/labels/derive_distinct_labels.d.ts +30 -14
- package/dist/labels/derive_distinct_labels.d.ts.map +1 -1
- package/dist/labels/derive_distinct_labels.js +121 -50
- package/dist/labels/derive_distinct_labels.js.map +1 -1
- package/dist/labels/derive_distinct_tooltips.cjs +0 -10
- package/dist/labels/derive_distinct_tooltips.cjs.map +1 -1
- package/dist/labels/derive_distinct_tooltips.d.ts +2 -3
- package/dist/labels/derive_distinct_tooltips.d.ts.map +1 -1
- package/dist/labels/derive_distinct_tooltips.js +0 -10
- package/dist/labels/derive_distinct_tooltips.js.map +1 -1
- package/dist/labels/index.d.ts +1 -1
- package/dist/package.cjs +1 -1
- package/dist/package.js +1 -1
- package/package.json +5 -5
- package/src/columns/column_collection_builder.test.ts +0 -2
- package/src/columns/column_collection_builder.ts +26 -3
- package/src/components/PlDataTable/createPlDataTable/createPTableDefV3.ts +7 -5
- package/src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts +91 -76
- package/src/components/PlDataTable/createPlDataTable/discoverColumns.ts +31 -34
- package/src/components/PlDataTable/createPlDataTable/utils.test.ts +1 -1
- package/src/components/PlDataTable/createPlDataTable/utils.ts +11 -4
- package/src/labels/derive_distinct_labels.test.ts +396 -52
- package/src/labels/derive_distinct_labels.ts +205 -103
- package/src/labels/derive_distinct_tooltips.test.ts +1 -22
- package/src/labels/derive_distinct_tooltips.ts +1 -18
|
@@ -16,12 +16,13 @@ function createPlDataTableV3(ctx, options) {
|
|
|
16
16
|
const discovered = (0, _milaboratories_helpers.isPlainObject)(options.columns) ? require_discoverColumns.discoverTableColumnSnaphots(ctx, options.columns) : options.columns;
|
|
17
17
|
if ((0, _milaboratories_helpers.isNil)(discovered) || discovered.length === 0) return void 0;
|
|
18
18
|
const splited = splitDiscoveredColumns(discovered);
|
|
19
|
-
const labelColumns = require_labels.getMatchingLabelColumns([...splited.direct, ...splited.linked], require_labels.getAllLabelColumns(ctx));
|
|
19
|
+
const labelColumns = require_labels.getMatchingLabelColumns([...splited.direct, ...splited.linked].map((v) => v.column), require_labels.getAllLabelColumns(ctx));
|
|
20
20
|
const derivedLabels = require_utils.deriveAllLabels({
|
|
21
21
|
columns: discovered.map((dc) => ({
|
|
22
|
-
id: dc.id,
|
|
23
|
-
spec: dc.spec,
|
|
24
|
-
linkerPath: dc.
|
|
22
|
+
id: dc.column.id,
|
|
23
|
+
spec: dc.column.spec,
|
|
24
|
+
linkerPath: dc.path,
|
|
25
|
+
qualifications: dc.qualifications
|
|
25
26
|
})),
|
|
26
27
|
labelColumns,
|
|
27
28
|
deriveLabelsOptions: {
|
|
@@ -30,12 +31,11 @@ function createPlDataTableV3(ctx, options) {
|
|
|
30
31
|
}
|
|
31
32
|
});
|
|
32
33
|
const derivedTooltips = require_utils.deriveAllTooltips({ columns: discovered.map((dc) => ({
|
|
33
|
-
id: dc.id,
|
|
34
|
+
id: dc.column.id,
|
|
34
35
|
originalId: dc.originalId,
|
|
35
|
-
spec: dc.spec,
|
|
36
|
-
linkerPath: dc.
|
|
37
|
-
qualifications: dc.qualifications
|
|
38
|
-
distinctiveQualifications: dc.distinctiveQualifications
|
|
36
|
+
spec: dc.column.spec,
|
|
37
|
+
linkerPath: dc.path,
|
|
38
|
+
qualifications: dc.qualifications
|
|
39
39
|
})) });
|
|
40
40
|
const annotated = annotateColumnGroups({
|
|
41
41
|
pframeSpec,
|
|
@@ -49,8 +49,8 @@ function createPlDataTableV3(ctx, options) {
|
|
|
49
49
|
const secondarySnapshots = annotated.direct.filter((c) => !c.isPrimary);
|
|
50
50
|
if (primarySnapshots.length === 0) return void 0;
|
|
51
51
|
const columnIsAvailable = createColumnValidationById([
|
|
52
|
-
...annotated.direct,
|
|
53
|
-
...annotated.linked.flatMap((lc) => [...
|
|
52
|
+
...annotated.direct.map((v) => v.column),
|
|
53
|
+
...annotated.linked.flatMap((lc) => [...lc.path.map((s) => s.linker), lc.column]),
|
|
54
54
|
...annotated.labels
|
|
55
55
|
]);
|
|
56
56
|
const remapedDefaultFilters = remapFilterColumnIds(options.filters, discovered);
|
|
@@ -58,7 +58,7 @@ function createPlDataTableV3(ctx, options) {
|
|
|
58
58
|
validateFilters(filters, columnIsAvailable);
|
|
59
59
|
const sorting = resolveSorting(state.pTableParams.sorting, remapSortingColumnIds(options.sorting, discovered));
|
|
60
60
|
validateSorting(sorting, columnIsAvailable);
|
|
61
|
-
const primaryEntries = primarySnapshots.map((
|
|
61
|
+
const primaryEntries = primarySnapshots.map((v) => ({ column: resolveSnapshot(v.column) }));
|
|
62
62
|
const fullDef = require_createPTableDefV3.createPTableDefV3({
|
|
63
63
|
primaryJoinType,
|
|
64
64
|
primary: primaryEntries,
|
|
@@ -68,13 +68,13 @@ function createPlDataTableV3(ctx, options) {
|
|
|
68
68
|
});
|
|
69
69
|
const fullHandle = ctx.createPTableV2(fullDef);
|
|
70
70
|
const pframeHandle = ctx.createPFrame([
|
|
71
|
-
...annotated.direct.map(resolveSnapshot),
|
|
72
|
-
...annotated.linked.map(resolveSnapshot),
|
|
71
|
+
...annotated.direct.map((v) => resolveSnapshot(v.column)),
|
|
72
|
+
...annotated.linked.map((v) => resolveSnapshot(v.column)),
|
|
73
73
|
...annotated.labels,
|
|
74
74
|
...collectLinkerSnapshots(annotated.linked).map(resolveSnapshot)
|
|
75
75
|
]);
|
|
76
76
|
const hiddenSpecs = state.pTableParams.hiddenColIds;
|
|
77
|
-
const visible = buildVisibleColumns(annotated, computeHiddenColumns([...annotated.direct, ...annotated.linked], sorting, filters, hiddenSpecs), labelColumns);
|
|
77
|
+
const visible = buildVisibleColumns(annotated, computeHiddenColumns([...annotated.direct, ...annotated.linked].map((v) => v.column), sorting, filters, hiddenSpecs), labelColumns);
|
|
78
78
|
const visibleDef = require_createPTableDefV3.createPTableDefV3({
|
|
79
79
|
primaryJoinType,
|
|
80
80
|
primary: primaryEntries,
|
|
@@ -94,13 +94,13 @@ function createPlDataTableV3(ctx, options) {
|
|
|
94
94
|
/** Split discovered columns into direct (no linker path) and linked (with linker path). */
|
|
95
95
|
function splitDiscoveredColumns(columns) {
|
|
96
96
|
return {
|
|
97
|
-
direct: columns.filter((dc) =>
|
|
98
|
-
linked: columns.filter((dc) =>
|
|
97
|
+
direct: columns.filter((dc) => dc.path.length === 0),
|
|
98
|
+
linked: columns.filter((dc) => dc.path.length > 0)
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
101
|
/** All linker snapshots across the given linked columns, deduped by id. */
|
|
102
102
|
function collectLinkerSnapshots(linked) {
|
|
103
|
-
return (0, _milaboratories_pl_model_common.uniqueBy)(linked.flatMap((lc) =>
|
|
103
|
+
return (0, _milaboratories_pl_model_common.uniqueBy)(linked.flatMap((lc) => lc.path.map((s) => s.linker)), (c) => c.id);
|
|
104
104
|
}
|
|
105
105
|
/**
|
|
106
106
|
* Annotate all column groups with derived labels and display-rule annotations.
|
|
@@ -111,34 +111,33 @@ function collectLinkerSnapshots(linked) {
|
|
|
111
111
|
function annotateColumnGroups(params) {
|
|
112
112
|
const { direct, linked, labelColumns, derivedLabels, derivedTooltips, displayOptions, pframeSpec } = params;
|
|
113
113
|
const allColumnsForRules = [
|
|
114
|
-
...direct,
|
|
115
|
-
...linked,
|
|
114
|
+
...direct.map((v) => v.column),
|
|
115
|
+
...linked.map((v) => v.column),
|
|
116
116
|
...labelColumns,
|
|
117
117
|
...collectLinkerSnapshots(linked)
|
|
118
118
|
];
|
|
119
119
|
const visibilityByColId = require_utils.evaluateRules(displayOptions?.visibility ?? [], allColumnsForRules, pframeSpec);
|
|
120
120
|
const orderByColId = require_utils.evaluateRules(displayOptions?.ordering ?? [], allColumnsForRules, pframeSpec);
|
|
121
121
|
return {
|
|
122
|
-
direct:
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
linked: [
|
|
128
|
-
require_utils.withLabelAnnotations.bind(null, derivedLabels),
|
|
129
|
-
require_utils.withInfoAnnotations.bind(null, derivedTooltips),
|
|
130
|
-
require_utils.withHidenAxesAnnotations.bind(null),
|
|
131
|
-
require_utils.withTableVisualAnnotations.bind(null, visibilityByColId, orderByColId),
|
|
132
|
-
(cols) => cols.map((lc) => ({
|
|
133
|
-
...lc,
|
|
134
|
-
linkerPath: annotateLinkerPath(derivedLabels, lc.linkerPath)
|
|
135
|
-
}))
|
|
136
|
-
].reduce((cols, fn) => fn(cols), linked),
|
|
122
|
+
direct: withVariantColumns(direct, (cols) => require_utils.withTableVisualAnnotations(visibilityByColId, orderByColId, require_utils.withInfoAnnotations(derivedTooltips, require_utils.withLabelAnnotations(derivedLabels, cols)))),
|
|
123
|
+
linked: withVariantColumns(linked, (cols) => require_utils.withTableVisualAnnotations(visibilityByColId, orderByColId, require_utils.withHidenAxesAnnotations(require_utils.withInfoAnnotations(derivedTooltips, require_utils.withLabelAnnotations(derivedLabels, cols))))).map((lc) => ({
|
|
124
|
+
...lc,
|
|
125
|
+
path: annotateLinkerPath(derivedLabels, lc.path)
|
|
126
|
+
})),
|
|
137
127
|
labels: require_utils.withLabelAnnotations(derivedLabels, labelColumns)
|
|
138
128
|
};
|
|
139
129
|
}
|
|
130
|
+
/** Apply a snapshot-array transformation to the inner `column` of each variant. */
|
|
131
|
+
function withVariantColumns(variants, fn) {
|
|
132
|
+
const cols = fn(variants.map((v) => v.column));
|
|
133
|
+
if (cols.length !== variants.length) throw new Error(`withVariantColumns: fn must preserve array length (got ${cols.length}, expected ${variants.length})`);
|
|
134
|
+
return variants.map((v, i) => ({
|
|
135
|
+
...v,
|
|
136
|
+
column: cols[i]
|
|
137
|
+
}));
|
|
138
|
+
}
|
|
140
139
|
function annotateLinkerPath(derivedLabels, path) {
|
|
141
|
-
if (
|
|
140
|
+
if (path.length === 0) return path;
|
|
142
141
|
const annotatedLinkers = require_utils.withHidenAxesAnnotations(require_utils.withLabelAnnotations(derivedLabels, path.map((s) => s.linker)));
|
|
143
142
|
return path.map((s, i) => ({
|
|
144
143
|
...s,
|
|
@@ -187,20 +186,20 @@ function buildSecondaryGroups(direct, linked, labels) {
|
|
|
187
186
|
return [
|
|
188
187
|
...direct.map((c) => ({
|
|
189
188
|
entries: [{
|
|
190
|
-
column: resolveSnapshot(c),
|
|
191
|
-
qualifications: c.qualifications
|
|
189
|
+
column: resolveSnapshot(c.column),
|
|
190
|
+
qualifications: c.qualifications.forHit
|
|
192
191
|
}],
|
|
193
|
-
primaryQualifications: c.qualifications
|
|
192
|
+
primaryQualifications: c.qualifications.forQueries
|
|
194
193
|
})),
|
|
195
194
|
...linked.map((lc) => ({
|
|
196
|
-
entries: [...
|
|
195
|
+
entries: [...lc.path.map((s) => ({
|
|
197
196
|
column: resolveSnapshot(s.linker),
|
|
198
197
|
qualifications: s.qualifications
|
|
199
198
|
})), {
|
|
200
|
-
column: resolveSnapshot(lc),
|
|
201
|
-
qualifications: lc.qualifications
|
|
199
|
+
column: resolveSnapshot(lc.column),
|
|
200
|
+
qualifications: lc.qualifications.forHit
|
|
202
201
|
}],
|
|
203
|
-
primaryQualifications: lc.qualifications
|
|
202
|
+
primaryQualifications: lc.qualifications.forQueries
|
|
204
203
|
})),
|
|
205
204
|
...labels.map((c) => ({ entries: [{ column: c }] }))
|
|
206
205
|
];
|
|
@@ -224,12 +223,12 @@ function collectPreservedColumnIds(sorting, filters) {
|
|
|
224
223
|
}
|
|
225
224
|
/** Filter annotated columns to only visible ones, re-matching label columns for the visible subset. */
|
|
226
225
|
function buildVisibleColumns(annotated, hiddenColumns, originalLabelColumns) {
|
|
227
|
-
const direct = annotated.direct.filter((c) => !hiddenColumns.has(c.id));
|
|
228
|
-
const linked = annotated.linked.filter((c) => !hiddenColumns.has(c.id));
|
|
226
|
+
const direct = annotated.direct.filter((c) => !hiddenColumns.has(c.column.id));
|
|
227
|
+
const linked = annotated.linked.filter((c) => !hiddenColumns.has(c.column.id));
|
|
229
228
|
return {
|
|
230
229
|
direct,
|
|
231
230
|
linked,
|
|
232
|
-
labels: require_labels.getMatchingLabelColumns([...direct, ...linked], originalLabelColumns)
|
|
231
|
+
labels: require_labels.getMatchingLabelColumns([...direct, ...linked].map((v) => v.column), originalLabelColumns)
|
|
233
232
|
};
|
|
234
233
|
}
|
|
235
234
|
/** Resolve a ColumnSnapshot to a PColumn with lazily-evaluated data. */
|
|
@@ -245,12 +244,12 @@ function remapSortingColumnIds(sorting, columns) {
|
|
|
245
244
|
return sorting?.map((s) => {
|
|
246
245
|
if (s.column.type === "axis") return s;
|
|
247
246
|
const id = s.column.id;
|
|
248
|
-
const column = columns.find((c) => (c.originalId ?? c.id) === id) ?? (0, _milaboratories_helpers.throwError)(`Column ID "${id}" in sorting does not match any discovered column`);
|
|
247
|
+
const column = columns.find((c) => (c.originalId ?? c.column.id) === id) ?? (0, _milaboratories_helpers.throwError)(`Column ID "${id}" in sorting does not match any discovered column`);
|
|
249
248
|
return {
|
|
250
249
|
...s,
|
|
251
250
|
column: {
|
|
252
251
|
type: "column",
|
|
253
|
-
id: column.id
|
|
252
|
+
id: column.column.id
|
|
254
253
|
}
|
|
255
254
|
};
|
|
256
255
|
});
|
|
@@ -264,7 +263,7 @@ function remapFilterColumnIds(filters, columns) {
|
|
|
264
263
|
const originalId = parsed.id;
|
|
265
264
|
return (0, _milaboratories_pl_model_common.canonicalizeJson)({
|
|
266
265
|
type: "column",
|
|
267
|
-
id: (columns.find((c) => (c.originalId ?? c.id) === originalId) ?? (0, _milaboratories_helpers.throwError)(`Column ID "${parsed.id}" in filters does not match any discovered column`)).id
|
|
266
|
+
id: (columns.find((c) => (c.originalId ?? c.column.id) === originalId) ?? (0, _milaboratories_helpers.throwError)(`Column ID "${parsed.id}" in filters does not match any discovered column`)).column.id
|
|
268
267
|
});
|
|
269
268
|
};
|
|
270
269
|
return require_traverse.traverseFilterSpec(filters, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createPlDataTableV3.cjs","names":["upgradePlDataTableStateV2","discoverTableColumnSnaphots","getMatchingLabelColumns","getAllLabelColumns","deriveAllLabels","deriveAllTooltips","createPTableDefV3","evaluateRules","withLabelAnnotations","withInfoAnnotations","withTableVisualAnnotations","withHidenAxesAnnotations","getAxisId","collectFilterSpecColumns","isColumnHidden","isColumnOptional","traverseFilterSpec"],"sources":["../../../../src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts"],"sourcesContent":["import type {\n AxisId,\n CanonicalizedJson,\n FilterSpecNode,\n PColumn,\n PObjectId,\n PTableColumnId,\n PTableColumnIdAxis,\n PTableColumnIdColumn,\n PTableSorting,\n PColumnSpec,\n MultiColumnSelector,\n PFrameSpecDriver,\n DiscoveredPColumnId,\n} from \"@milaboratories/pl-model-common\";\nimport { canonicalizeJson, getAxisId, parseJson, uniqueBy } from \"@milaboratories/pl-model-common\";\nimport { collectFilterSpecColumns, traverseFilterSpec } from \"../../../filters/traverse\";\nimport type { RenderCtxBase, PColumnDataUniversal } from \"../../../render\";\nimport { isEmpty } from \"es-toolkit/compat\";\nimport type { PlDataTableFilters, PlDataTableFilterSpecLeaf, PlDataTableModel } from \"../typesV5\";\nimport { upgradePlDataTableStateV2 } from \"../state-migration\";\nimport type { PlDataTableStateV2 } from \"../state-migration\";\nimport type {\n ColumnSelector,\n ColumnSnapshot,\n MatchingMode,\n MatchQualifications,\n MatchVariant,\n} from \"../../../columns\";\nimport { getAllLabelColumns, getMatchingLabelColumns } from \"../labels\";\nimport type { DeriveLabelsOptions } from \"../../../labels/derive_distinct_labels\";\nimport {\n deriveAllLabels,\n deriveAllTooltips,\n evaluateRules,\n isColumnHidden,\n isColumnOptional,\n withHidenAxesAnnotations,\n withLabelAnnotations,\n withTableVisualAnnotations,\n withInfoAnnotations,\n} from \"./utils\";\nimport type { PrimaryEntry, SecondaryGroup } from \"./createPTableDefV3\";\nimport { createPTableDefV3 } from \"./createPTableDefV3\";\nimport { discoverTableColumnSnaphots, type DiscoverTableColumnOptions } from \"./discoverColumns\";\nimport { isNil, isPlainObject, throwError, type Nil } from \"@milaboratories/helpers\";\n\nexport type createPlDataTableOptionsV3 = {\n tableState?: PlDataTableStateV2;\n\n columns: Nil | DiscoverTableColumnOptions | TableColumnSnapshot[];\n filters?: PlDataTableFilters;\n sorting?: PTableSorting[];\n primaryJoinType?: \"inner\" | \"full\";\n\n labelsOptions?: DeriveLabelsOptions;\n displayOptions?: ColumnsDisplayOptions;\n};\n\n/** Structured source config — selectors/anchors instead of raw ColumnSource. */\nexport type ColumnsSelectorConfig = {\n include?: MultiColumnSelector | MultiColumnSelector[];\n exclude?: MultiColumnSelector | MultiColumnSelector[];\n mode?: MatchingMode;\n maxHops?: number;\n};\n\nexport type ColumnsDisplayOptions = {\n /** Column ordering rules. Higher priority = further left. First matching rule wins. */\n ordering?: ColumnOrderRule[];\n /** Column visibility rules. First matching rule wins. Unmatched columns use default visibility. */\n visibility?: ColumnVisibilityRule[];\n};\n\nexport type ColumnOrderRule = {\n match: ColumnMatcher | ColumnSelector;\n /** Higher number = further left in table */\n priority: number;\n};\n\nexport type ColumnVisibilityRule = {\n match: ColumnMatcher | ColumnSelector;\n visibility: \"default\" | \"optional\" | \"hidden\";\n};\n\nexport type ColumnMatcher = (spec: PColumnSpec) => boolean;\n\n// Main Function\n\nexport function createPlDataTableV3<A, U>(\n ctx: RenderCtxBase<A, U>,\n options: createPlDataTableOptionsV3,\n): PlDataTableModel | undefined {\n const pframeSpec = ctx.getService(\"pframeSpec\");\n const state = upgradePlDataTableStateV2(options.tableState);\n const primaryJoinType = options.primaryJoinType ?? \"full\";\n\n const discovered = isPlainObject(options.columns)\n ? discoverTableColumnSnaphots(ctx, options.columns)\n : options.columns;\n if (isNil(discovered) || discovered.length === 0) return undefined;\n\n const splited = splitDiscoveredColumns(discovered);\n\n const labelColumns = getMatchingLabelColumns(\n [...splited.direct, ...splited.linked],\n getAllLabelColumns(ctx),\n );\n\n const derivedLabels = deriveAllLabels({\n columns: discovered.map((dc) => ({\n id: dc.id,\n spec: dc.spec,\n linkerPath: dc.linkerPath?.map((lp) => ({ spec: lp.linker.spec })),\n })),\n labelColumns,\n deriveLabelsOptions: {\n includeNativeLabel: true,\n ...options.labelsOptions,\n },\n });\n\n const derivedTooltips = deriveAllTooltips({\n columns: discovered.map((dc) => ({\n id: dc.id,\n originalId: dc.originalId,\n spec: dc.spec,\n linkerPath: dc.linkerPath,\n qualifications: dc.qualifications,\n distinctiveQualifications: dc.distinctiveQualifications,\n })),\n });\n\n const annotated = annotateColumnGroups({\n pframeSpec,\n ...splited,\n labelColumns,\n derivedLabels,\n derivedTooltips,\n displayOptions: options.displayOptions,\n });\n\n const primarySnapshots = annotated.direct.filter((c) => c.isPrimary);\n const secondarySnapshots = annotated.direct.filter((c) => !c.isPrimary);\n\n if (primarySnapshots.length === 0) return undefined;\n\n const columnIsAvailable = createColumnValidationById([\n ...annotated.direct,\n ...annotated.linked.flatMap((lc) => [...(lc.linkerPath ?? []).map((s) => s.linker), lc]),\n ...annotated.labels,\n ]);\n\n const remapedDefaultFilters = remapFilterColumnIds(options.filters, discovered);\n const filters = concatFilters(\n state.pTableParams.filters,\n state.pTableParams.defaultFilters ?? remapedDefaultFilters,\n );\n validateFilters(filters, columnIsAvailable);\n\n const sorting = resolveSorting(\n state.pTableParams.sorting,\n remapSortingColumnIds(options.sorting, discovered),\n );\n validateSorting(sorting, columnIsAvailable);\n\n const primaryEntries: PrimaryEntry<undefined | PColumnDataUniversal>[] = primarySnapshots.map(\n (snap) => ({ column: resolveSnapshot(snap) }),\n );\n const fullDef = createPTableDefV3({\n primaryJoinType,\n primary: primaryEntries,\n secondary: buildSecondaryGroups(secondarySnapshots, annotated.linked, annotated.labels),\n filters,\n sorting,\n });\n\n const fullHandle = ctx.createPTableV2(fullDef);\n // TODO: is workaround for dropdown suggestions.\n // Pframe have not equivalent data for columns relativly to Ptable\n const pframeHandle = ctx.createPFrame([\n ...annotated.direct.map(resolveSnapshot),\n ...annotated.linked.map(resolveSnapshot),\n ...annotated.labels,\n ...collectLinkerSnapshots(annotated.linked).map(resolveSnapshot),\n ]);\n\n const hiddenSpecs = state.pTableParams.hiddenColIds;\n const hiddenColumnIds = computeHiddenColumns(\n [...annotated.direct, ...annotated.linked],\n sorting,\n filters,\n hiddenSpecs,\n );\n\n const visible = buildVisibleColumns(annotated, hiddenColumnIds, labelColumns);\n const visibleDef = createPTableDefV3({\n primaryJoinType,\n primary: primaryEntries,\n secondary: buildSecondaryGroups(\n visible.direct.filter((c) => !c.isPrimary),\n visible.linked,\n visible.labels,\n ),\n filters,\n sorting,\n });\n const visibleHandle = ctx.createPTableV2(visibleDef);\n\n return {\n sourceId: state.pTableParams.sourceId,\n fullTableHandle: fullHandle,\n fullPframeHandle: pframeHandle,\n visibleTableHandle: visibleHandle,\n defaultFilters: remapedDefaultFilters,\n } satisfies PlDataTableModel;\n}\n\n/** A single column discovered from sources — normalized from raw ColumnSnapshot/ColumnMatch. */\nexport type TableColumnSnapshot = ColumnSnapshot<DiscoveredPColumnId> & {\n readonly originalId: PObjectId;\n readonly isPrimary?: boolean;\n readonly linkerPath?: MatchVariant[\"path\"];\n readonly qualifications?: MatchQualifications;\n readonly distinctiveQualifications?: MatchQualifications;\n};\n\ntype SplitDiscoveredColumns = {\n readonly direct: TableColumnSnapshot[];\n readonly linked: TableColumnSnapshot[];\n};\n\ntype AnnotatedColumnGroups = {\n readonly direct: TableColumnSnapshot[];\n readonly linked: TableColumnSnapshot[];\n readonly labels: PColumn<PColumnDataUniversal>[];\n};\n\ntype VisibleColumns = {\n readonly direct: TableColumnSnapshot[];\n readonly linked: TableColumnSnapshot[];\n readonly labels: PColumn<PColumnDataUniversal>[];\n};\n\n/** Split discovered columns into direct (no linker path) and linked (with linker path). */\nfunction splitDiscoveredColumns(columns: TableColumnSnapshot[]): SplitDiscoveredColumns {\n const direct = columns.filter((dc) => isNil(dc.linkerPath) || dc.linkerPath.length === 0);\n const linked = columns.filter((dc) => !isNil(dc.linkerPath) && dc.linkerPath.length > 0);\n return { direct, linked };\n}\n\n/** All linker snapshots across the given linked columns, deduped by id. */\nfunction collectLinkerSnapshots(linked: TableColumnSnapshot[]): ColumnSnapshot<PObjectId>[] {\n return uniqueBy(\n linked.flatMap((lc) => (lc.linkerPath ?? []).map((s) => s.linker)),\n (c) => c.id,\n );\n}\n\n/**\n * Annotate all column groups with derived labels and display-rule annotations.\n * Evaluates `displayOptions` rules against all discovered columns (direct,\n * linked, labels, linkers) and writes the winning visibility/priority into\n * column annotations via `withTableVisualAnnotations`.\n */\nfunction annotateColumnGroups(params: {\n direct: TableColumnSnapshot[];\n linked: TableColumnSnapshot[];\n labelColumns: PColumn<PColumnDataUniversal>[];\n derivedLabels: Record<string, string>;\n derivedTooltips: Record<string, string>;\n displayOptions?: ColumnsDisplayOptions;\n pframeSpec: PFrameSpecDriver;\n}): AnnotatedColumnGroups {\n const {\n direct,\n linked,\n labelColumns,\n derivedLabels,\n derivedTooltips,\n displayOptions,\n pframeSpec,\n } = params;\n\n const allColumnsForRules = [\n ...direct,\n ...linked,\n ...labelColumns,\n ...collectLinkerSnapshots(linked),\n ];\n const visibilityByColId = evaluateRules(\n displayOptions?.visibility ?? [],\n allColumnsForRules,\n pframeSpec,\n );\n const orderByColId = evaluateRules(\n displayOptions?.ordering ?? [],\n allColumnsForRules,\n pframeSpec,\n );\n\n const directAnnotated = [\n withLabelAnnotations.bind(null, derivedLabels),\n withInfoAnnotations.bind(null, derivedTooltips),\n withTableVisualAnnotations.bind(null, visibilityByColId, orderByColId),\n ].reduce((cols, fn) => fn(cols) as TableColumnSnapshot[], direct);\n\n const linkedAnnotated = [\n withLabelAnnotations.bind(null, derivedLabels),\n withInfoAnnotations.bind(null, derivedTooltips),\n withHidenAxesAnnotations.bind(null),\n withTableVisualAnnotations.bind(null, visibilityByColId, orderByColId),\n (cols: TableColumnSnapshot[]) =>\n cols.map((lc) => ({ ...lc, linkerPath: annotateLinkerPath(derivedLabels, lc.linkerPath) })),\n ].reduce((cols, fn) => fn(cols) as TableColumnSnapshot[], linked);\n\n const labelColumnsAnnotated = withLabelAnnotations(derivedLabels, labelColumns);\n\n return {\n direct: directAnnotated,\n linked: linkedAnnotated,\n labels: labelColumnsAnnotated,\n };\n}\nfunction annotateLinkerPath(\n derivedLabels: Record<string, string>,\n path: TableColumnSnapshot[\"linkerPath\"],\n): TableColumnSnapshot[\"linkerPath\"] {\n if (isNil(path) || path.length === 0) return path;\n const annotatedLinkers = withHidenAxesAnnotations(\n withLabelAnnotations(\n derivedLabels,\n path.map((s) => s.linker),\n ),\n );\n return path.map((s, i) => ({ ...s, linker: annotatedLinkers[i] }));\n}\n\n/** Build an index of all valid column IDs (axes + columns) for filter/sorting validation. */\nfunction createColumnValidationById(\n fullColumns: { readonly id: PObjectId; readonly spec: PColumnSpec }[],\n) {\n const axisIds = uniqueBy(\n fullColumns.flatMap((c) => c.spec.axesSpec.map(getAxisId)),\n (a) => canonicalizeJson<AxisId>(a),\n );\n\n const allIds: PTableColumnId[] = [\n ...axisIds.map((a) => ({ type: \"axis\", id: a }) satisfies PTableColumnIdAxis),\n ...fullColumns.map((c) => ({ type: \"column\", id: c.id }) satisfies PTableColumnIdColumn),\n ];\n\n const validIdSet = new Set(allIds.map((c) => canonicalizeJson<PTableColumnId>(c)));\n\n return (id: string): boolean => {\n return validIdSet.has(id as CanonicalizedJson<PTableColumnId>);\n };\n}\n\n/** Validate that all column references in filters exist in the table. */\nfunction validateFilters(\n filters: Nil | PlDataTableFilters,\n isValidColumnId: (id: string) => boolean,\n): void {\n if (filters == null) return;\n const filterColumns = collectFilterSpecColumns(filters);\n const firstInvalid = filterColumns.find((col) => !isValidColumnId(col));\n if (firstInvalid !== undefined) {\n throw new Error(\n `Invalid filter column ${firstInvalid}: column reference does not match the table columns`,\n );\n }\n}\n\n/** Merge two filter trees into one AND-combined tree. Returns the non-nil one if the other is nil. */\nfunction concatFilters(\n a: Nil | PlDataTableFilters,\n b: Nil | PlDataTableFilters,\n): Nil | PlDataTableFilters {\n if (isNil(a)) return b;\n if (isNil(b)) return a;\n return { ...a, filters: [...a.filters, ...b.filters] };\n}\n\n/** Pick user sorting from state if non-empty, otherwise fall back to options default. */\nfunction resolveSorting(\n userSorting: PTableSorting[],\n defaultSorting: Nil | PTableSorting[],\n): PTableSorting[] {\n return (isEmpty(userSorting) ? defaultSorting : userSorting) ?? [];\n}\n\n/** Validate that all column references in sorting exist in the table. */\nfunction validateSorting(sorting: PTableSorting[], isValidColumnId: (id: string) => boolean): void {\n const firstInvalid = sorting.find(\n (s) => !isValidColumnId(canonicalizeJson<PTableColumnId>(s.column)),\n );\n if (firstInvalid !== undefined) {\n throw new Error(\n `Invalid sorting column ${JSON.stringify(firstInvalid.column)}: column reference does not match the table columns`,\n );\n }\n}\n\nfunction buildSecondaryGroups(\n direct: TableColumnSnapshot[],\n linked: TableColumnSnapshot[],\n labels: PColumn<PColumnDataUniversal>[],\n): SecondaryGroup<undefined | PColumnDataUniversal>[] {\n return [\n ...direct.map(\n (c): SecondaryGroup<undefined | PColumnDataUniversal> => ({\n entries: [{ column: resolveSnapshot(c), qualifications: c.qualifications?.forHit }],\n primaryQualifications: c.qualifications?.forQueries,\n }),\n ),\n ...linked.map(\n (lc): SecondaryGroup<undefined | PColumnDataUniversal> => ({\n entries: [\n ...(lc.linkerPath ?? []).map((s) => ({\n column: resolveSnapshot(s.linker),\n qualifications: s.qualifications,\n })),\n { column: resolveSnapshot(lc), qualifications: lc.qualifications?.forHit },\n ],\n primaryQualifications: lc.qualifications?.forQueries,\n }),\n ),\n ...labels.map(\n (c): SecondaryGroup<undefined | PColumnDataUniversal> => ({ entries: [{ column: c }] }),\n ),\n ];\n}\n\n/** Determine which columns should be hidden based on state or optional-column defaults. */\nfunction computeHiddenColumns(\n columns: { readonly id: PObjectId; readonly spec: PColumnSpec }[],\n sorting: Nil | PTableSorting[],\n filters: Nil | PlDataTableFilters,\n hiddenSpecs: Nil | PTableColumnId[],\n): Set<PObjectId> {\n const alwaysHidden = columns.filter((c) => isColumnHidden(c.spec)).map((c) => c.id);\n const optionalHidden = !isNil(hiddenSpecs)\n ? hiddenSpecs.filter((s): s is PTableColumnIdColumn => s.type === \"column\").map((s) => s.id)\n : columns.filter((c) => isColumnOptional(c.spec)).map((c) => c.id);\n const initial = [...alwaysHidden, ...optionalHidden];\n const preserved = collectPreservedColumnIds(sorting, filters);\n\n return new Set(initial.filter((id) => !preserved.has(id)));\n}\n\n/** Collect IDs of columns that must remain visible (sorted, filtered). */\nfunction collectPreservedColumnIds(\n sorting: Nil | PTableSorting[],\n filters: Nil | PlDataTableFilters,\n): Set<PObjectId> {\n const sortedIds = (sorting ?? [])\n .map((s) => s.column)\n .filter((c): c is PTableColumnIdColumn => c.type === \"column\")\n .map((c) => c.id);\n\n const filterIds = !isNil(filters)\n ? collectFilterSpecColumns(filters).flatMap((c) => {\n const obj = parseJson(c);\n return obj.type === \"column\" ? [obj.id] : [];\n })\n : [];\n\n return new Set<PObjectId>([...sortedIds, ...filterIds]);\n}\n\n/** Filter annotated columns to only visible ones, re-matching label columns for the visible subset. */\nfunction buildVisibleColumns(\n annotated: AnnotatedColumnGroups,\n hiddenColumns: Set<PObjectId>,\n originalLabelColumns: PColumn<PColumnDataUniversal>[],\n): VisibleColumns {\n const direct = annotated.direct.filter((c) => !hiddenColumns.has(c.id));\n const linked = annotated.linked.filter((c) => !hiddenColumns.has(c.id));\n const labels = getMatchingLabelColumns([...direct, ...linked], originalLabelColumns);\n return { direct, linked, labels };\n}\n\n/** Resolve a ColumnSnapshot to a PColumn with lazily-evaluated data. */\nfunction resolveSnapshot(\n snap: ColumnSnapshot<PObjectId>,\n): PColumn<undefined | PColumnDataUniversal> {\n return { id: snap.id, spec: snap.spec, data: snap.data?.get() };\n}\n\n/** Remap column references in sorting entries. */\nfunction remapSortingColumnIds(\n sorting: Nil | PTableSorting[],\n columns: TableColumnSnapshot[],\n): Nil | PTableSorting[] {\n return sorting?.map((s) => {\n if (s.column.type === \"axis\") return s; // Axis references are unaffected by column ID remapping\n\n const id = s.column.id;\n const column =\n columns.find((c) => (c.originalId ?? c.id) === id) ??\n throwError(`Column ID \"${id}\" in sorting does not match any discovered column`);\n\n return {\n ...s,\n column: {\n type: \"column\",\n id: column.id,\n },\n };\n });\n}\n\ntype PlDataTableFilterNode = FilterSpecNode<PlDataTableFilterSpecLeaf>;\n\n/** Remap column references in a filter tree. */\nfunction remapFilterColumnIds(\n filters: Nil | PlDataTableFilters,\n columns: TableColumnSnapshot[],\n): Nil | PlDataTableFilters {\n if (isNil(filters)) return filters;\n\n const map = (\n tableColumnId: CanonicalizedJson<PTableColumnId>,\n ): CanonicalizedJson<PTableColumnId> => {\n const parsed = parseJson<PTableColumnId>(tableColumnId);\n if (parsed.type === \"axis\") return tableColumnId; // Axis references are unaffected by column ID remapping\n\n const originalId = parsed.id;\n const column =\n columns.find((c) => (c.originalId ?? c.id) === originalId) ??\n throwError(`Column ID \"${parsed.id}\" in filters does not match any discovered column`);\n\n return canonicalizeJson<PTableColumnId>({\n type: \"column\",\n id: column.id,\n });\n };\n\n return traverseFilterSpec(filters, {\n leaf: (leaf): PlDataTableFilterNode => {\n if (leaf.type === undefined) return leaf;\n const result = { ...leaf };\n if (\"column\" in result) result.column = map(result.column);\n if (\"rhs\" in result) result.rhs = map(result.rhs);\n return result;\n },\n and: (results): PlDataTableFilterNode => ({ type: \"and\", filters: results }),\n or: (results): PlDataTableFilterNode => ({ type: \"or\", filters: results }),\n not: (result): PlDataTableFilterNode => ({ type: \"not\", filter: result }),\n }) as PlDataTableFilters;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"createPlDataTableV3.cjs","names":["upgradePlDataTableStateV2","discoverTableColumnSnaphots","getMatchingLabelColumns","getAllLabelColumns","deriveAllLabels","deriveAllTooltips","createPTableDefV3","evaluateRules","withTableVisualAnnotations","withInfoAnnotations","withLabelAnnotations","withHidenAxesAnnotations","getAxisId","collectFilterSpecColumns","isColumnHidden","isColumnOptional","traverseFilterSpec"],"sources":["../../../../src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts"],"sourcesContent":["import type {\n AxisId,\n CanonicalizedJson,\n FilterSpecNode,\n PColumn,\n PObjectId,\n PTableColumnId,\n PTableColumnIdAxis,\n PTableColumnIdColumn,\n PTableSorting,\n PColumnSpec,\n MultiColumnSelector,\n PFrameSpecDriver,\n DiscoveredPColumnId,\n} from \"@milaboratories/pl-model-common\";\nimport { canonicalizeJson, getAxisId, parseJson, uniqueBy } from \"@milaboratories/pl-model-common\";\nimport { collectFilterSpecColumns, traverseFilterSpec } from \"../../../filters/traverse\";\nimport type { RenderCtxBase, PColumnDataUniversal } from \"../../../render\";\nimport { isEmpty } from \"es-toolkit/compat\";\nimport type { PlDataTableFilters, PlDataTableFilterSpecLeaf, PlDataTableModel } from \"../typesV5\";\nimport { upgradePlDataTableStateV2 } from \"../state-migration\";\nimport type { PlDataTableStateV2 } from \"../state-migration\";\nimport type { ColumnSelector, ColumnSnapshot, ColumnVariant, MatchingMode } from \"../../../columns\";\nimport { getAllLabelColumns, getMatchingLabelColumns } from \"../labels\";\nimport type { DeriveLabelsOptions } from \"../../../labels/derive_distinct_labels\";\nimport {\n deriveAllLabels,\n deriveAllTooltips,\n evaluateRules,\n isColumnHidden,\n isColumnOptional,\n withHidenAxesAnnotations,\n withLabelAnnotations,\n withTableVisualAnnotations,\n withInfoAnnotations,\n} from \"./utils\";\nimport type { PrimaryEntry, SecondaryGroup } from \"./createPTableDefV3\";\nimport { createPTableDefV3 } from \"./createPTableDefV3\";\nimport { discoverTableColumnSnaphots, type DiscoverTableColumnOptions } from \"./discoverColumns\";\nimport { isNil, isPlainObject, throwError, type Nil } from \"@milaboratories/helpers\";\n\nexport type createPlDataTableOptionsV3 = {\n tableState?: PlDataTableStateV2;\n\n columns: Nil | DiscoverTableColumnOptions | TableColumnVariant[];\n filters?: PlDataTableFilters;\n sorting?: PTableSorting[];\n primaryJoinType?: \"inner\" | \"full\";\n\n labelsOptions?: DeriveLabelsOptions;\n displayOptions?: ColumnsDisplayOptions;\n};\n\n/** Structured source config — selectors/anchors instead of raw ColumnSource. */\nexport type ColumnsSelectorConfig = {\n include?: MultiColumnSelector | MultiColumnSelector[];\n exclude?: MultiColumnSelector | MultiColumnSelector[];\n mode?: MatchingMode;\n maxHops?: number;\n};\n\nexport type ColumnsDisplayOptions = {\n /** Column ordering rules. Higher priority = further left. First matching rule wins. */\n ordering?: ColumnOrderRule[];\n /** Column visibility rules. First matching rule wins. Unmatched columns use default visibility. */\n visibility?: ColumnVisibilityRule[];\n};\n\nexport type ColumnOrderRule = {\n match: ColumnMatcher | ColumnSelector;\n /** Higher number = further left in table */\n priority: number;\n};\n\nexport type ColumnVisibilityRule = {\n match: ColumnMatcher | ColumnSelector;\n visibility: \"default\" | \"optional\" | \"hidden\";\n};\n\nexport type ColumnMatcher = (spec: PColumnSpec) => boolean;\n\n// Main Function\n\nexport function createPlDataTableV3<A, U>(\n ctx: RenderCtxBase<A, U>,\n options: createPlDataTableOptionsV3,\n): PlDataTableModel | undefined {\n const pframeSpec = ctx.getService(\"pframeSpec\");\n const state = upgradePlDataTableStateV2(options.tableState);\n const primaryJoinType = options.primaryJoinType ?? \"full\";\n\n const discovered = isPlainObject(options.columns)\n ? discoverTableColumnSnaphots(ctx, options.columns)\n : options.columns;\n if (isNil(discovered) || discovered.length === 0) return undefined;\n\n const splited = splitDiscoveredColumns(discovered);\n\n const labelColumns = getMatchingLabelColumns(\n [...splited.direct, ...splited.linked].map((v) => v.column),\n getAllLabelColumns(ctx),\n );\n\n const derivedLabels = deriveAllLabels({\n columns: discovered.map((dc) => ({\n id: dc.column.id,\n spec: dc.column.spec,\n linkerPath: dc.path,\n qualifications: dc.qualifications,\n })),\n labelColumns,\n deriveLabelsOptions: {\n includeNativeLabel: true,\n ...options.labelsOptions,\n },\n });\n\n const derivedTooltips = deriveAllTooltips({\n columns: discovered.map((dc) => ({\n id: dc.column.id,\n originalId: dc.originalId,\n spec: dc.column.spec,\n linkerPath: dc.path,\n qualifications: dc.qualifications,\n })),\n });\n\n const annotated = annotateColumnGroups({\n pframeSpec,\n ...splited,\n labelColumns,\n derivedLabels,\n derivedTooltips,\n displayOptions: options.displayOptions,\n });\n\n const primarySnapshots = annotated.direct.filter((c) => c.isPrimary);\n const secondarySnapshots = annotated.direct.filter((c) => !c.isPrimary);\n\n if (primarySnapshots.length === 0) return undefined;\n\n const columnIsAvailable = createColumnValidationById([\n ...annotated.direct.map((v) => v.column),\n ...annotated.linked.flatMap((lc) => [...lc.path.map((s) => s.linker), lc.column]),\n ...annotated.labels,\n ]);\n\n const remapedDefaultFilters = remapFilterColumnIds(options.filters, discovered);\n const filters = concatFilters(\n state.pTableParams.filters,\n state.pTableParams.defaultFilters ?? remapedDefaultFilters,\n );\n validateFilters(filters, columnIsAvailable);\n\n const sorting = resolveSorting(\n state.pTableParams.sorting,\n remapSortingColumnIds(options.sorting, discovered),\n );\n validateSorting(sorting, columnIsAvailable);\n\n const primaryEntries: PrimaryEntry<undefined | PColumnDataUniversal>[] = primarySnapshots.map(\n (v) => ({ column: resolveSnapshot(v.column) }),\n );\n const secondaryGroups: SecondaryGroup<undefined | PColumnDataUniversal>[] = buildSecondaryGroups(\n secondarySnapshots,\n annotated.linked,\n annotated.labels,\n );\n const fullDef = createPTableDefV3({\n primaryJoinType,\n primary: primaryEntries,\n secondary: secondaryGroups,\n filters,\n sorting,\n });\n\n const fullHandle = ctx.createPTableV2(fullDef);\n // TODO: is workaround for dropdown suggestions.\n // Pframe have not equivalent data for columns relativly to Ptable\n const pframeHandle = ctx.createPFrame([\n ...annotated.direct.map((v) => resolveSnapshot(v.column)),\n ...annotated.linked.map((v) => resolveSnapshot(v.column)),\n ...annotated.labels,\n ...collectLinkerSnapshots(annotated.linked).map(resolveSnapshot),\n ]);\n\n const hiddenSpecs = state.pTableParams.hiddenColIds;\n const hiddenColumnIds = computeHiddenColumns(\n [...annotated.direct, ...annotated.linked].map((v) => v.column),\n sorting,\n filters,\n hiddenSpecs,\n );\n\n const visible = buildVisibleColumns(annotated, hiddenColumnIds, labelColumns);\n const visibleDef = createPTableDefV3({\n primaryJoinType,\n primary: primaryEntries,\n secondary: buildSecondaryGroups(\n visible.direct.filter((c) => !c.isPrimary),\n visible.linked,\n visible.labels,\n ),\n filters,\n sorting,\n });\n const visibleHandle = ctx.createPTableV2(visibleDef);\n\n return {\n sourceId: state.pTableParams.sourceId,\n fullTableHandle: fullHandle,\n fullPframeHandle: pframeHandle,\n visibleTableHandle: visibleHandle,\n defaultFilters: remapedDefaultFilters,\n } satisfies PlDataTableModel;\n}\n\nexport type TableColumnVariant = ColumnVariant<DiscoveredPColumnId> & {\n readonly originalId: PObjectId;\n readonly isPrimary?: boolean;\n};\n\ntype SplitDiscoveredColumns = {\n readonly direct: TableColumnVariant[];\n readonly linked: TableColumnVariant[];\n};\n\ntype AnnotatedColumnGroups = {\n readonly direct: TableColumnVariant[];\n readonly linked: TableColumnVariant[];\n readonly labels: PColumn<PColumnDataUniversal>[];\n};\n\ntype VisibleColumns = {\n readonly direct: TableColumnVariant[];\n readonly linked: TableColumnVariant[];\n readonly labels: PColumn<PColumnDataUniversal>[];\n};\n\n/** Split discovered columns into direct (no linker path) and linked (with linker path). */\nfunction splitDiscoveredColumns(columns: TableColumnVariant[]): SplitDiscoveredColumns {\n const direct = columns.filter((dc) => dc.path.length === 0);\n const linked = columns.filter((dc) => dc.path.length > 0);\n return { direct, linked };\n}\n\n/** All linker snapshots across the given linked columns, deduped by id. */\nfunction collectLinkerSnapshots(linked: TableColumnVariant[]): ColumnSnapshot<PObjectId>[] {\n return uniqueBy(\n linked.flatMap((lc) => lc.path.map((s) => s.linker)),\n (c) => c.id,\n );\n}\n\n/**\n * Annotate all column groups with derived labels and display-rule annotations.\n * Evaluates `displayOptions` rules against all discovered columns (direct,\n * linked, labels, linkers) and writes the winning visibility/priority into\n * column annotations via `withTableVisualAnnotations`.\n */\nfunction annotateColumnGroups(params: {\n direct: TableColumnVariant[];\n linked: TableColumnVariant[];\n labelColumns: PColumn<PColumnDataUniversal>[];\n derivedLabels: Record<string, string>;\n derivedTooltips: Record<string, string>;\n displayOptions?: ColumnsDisplayOptions;\n pframeSpec: PFrameSpecDriver;\n}): AnnotatedColumnGroups {\n const {\n direct,\n linked,\n labelColumns,\n derivedLabels,\n derivedTooltips,\n displayOptions,\n pframeSpec,\n } = params;\n\n const allColumnsForRules = [\n ...direct.map((v) => v.column),\n ...linked.map((v) => v.column),\n ...labelColumns,\n ...collectLinkerSnapshots(linked),\n ];\n const visibilityByColId = evaluateRules(\n displayOptions?.visibility ?? [],\n allColumnsForRules,\n pframeSpec,\n );\n const orderByColId = evaluateRules(\n displayOptions?.ordering ?? [],\n allColumnsForRules,\n pframeSpec,\n );\n\n const directAnnotated = withVariantColumns(direct, (cols) =>\n withTableVisualAnnotations(\n visibilityByColId,\n orderByColId,\n withInfoAnnotations(derivedTooltips, withLabelAnnotations(derivedLabels, cols)),\n ),\n );\n\n const linkedAnnotated = withVariantColumns(linked, (cols) =>\n withTableVisualAnnotations(\n visibilityByColId,\n orderByColId,\n withHidenAxesAnnotations(\n withInfoAnnotations(derivedTooltips, withLabelAnnotations(derivedLabels, cols)),\n ),\n ),\n ).map((lc) => ({ ...lc, path: annotateLinkerPath(derivedLabels, lc.path) }));\n\n const labelColumnsAnnotated = withLabelAnnotations(derivedLabels, labelColumns);\n\n return {\n direct: directAnnotated,\n linked: linkedAnnotated,\n labels: labelColumnsAnnotated,\n };\n}\n\n/** Apply a snapshot-array transformation to the inner `column` of each variant. */\nfunction withVariantColumns<V extends { readonly column: ColumnSnapshot<DiscoveredPColumnId> }>(\n variants: V[],\n fn: (cols: ColumnSnapshot<DiscoveredPColumnId>[]) => ColumnSnapshot<DiscoveredPColumnId>[],\n): V[] {\n const cols = fn(variants.map((v) => v.column));\n if (cols.length !== variants.length)\n throw new Error(\n `withVariantColumns: fn must preserve array length (got ${cols.length}, expected ${variants.length})`,\n );\n return variants.map((v, i) => ({ ...v, column: cols[i] }));\n}\n\nfunction annotateLinkerPath(\n derivedLabels: Record<string, string>,\n path: TableColumnVariant[\"path\"],\n): TableColumnVariant[\"path\"] {\n if (path.length === 0) return path;\n const annotatedLinkers = withHidenAxesAnnotations(\n withLabelAnnotations(\n derivedLabels,\n path.map((s) => s.linker),\n ),\n );\n return path.map((s, i) => ({ ...s, linker: annotatedLinkers[i] }));\n}\n\n/** Build an index of all valid column IDs (axes + columns) for filter/sorting validation. */\nfunction createColumnValidationById(\n fullColumns: { readonly id: PObjectId; readonly spec: PColumnSpec }[],\n) {\n const axisIds = uniqueBy(\n fullColumns.flatMap((c) => c.spec.axesSpec.map(getAxisId)),\n (a) => canonicalizeJson<AxisId>(a),\n );\n\n const allIds: PTableColumnId[] = [\n ...axisIds.map((a) => ({ type: \"axis\", id: a }) satisfies PTableColumnIdAxis),\n ...fullColumns.map((c) => ({ type: \"column\", id: c.id }) satisfies PTableColumnIdColumn),\n ];\n\n const validIdSet = new Set(allIds.map((c) => canonicalizeJson<PTableColumnId>(c)));\n\n return (id: string): boolean => {\n return validIdSet.has(id as CanonicalizedJson<PTableColumnId>);\n };\n}\n\n/** Validate that all column references in filters exist in the table. */\nfunction validateFilters(\n filters: Nil | PlDataTableFilters,\n isValidColumnId: (id: string) => boolean,\n): void {\n if (filters == null) return;\n const filterColumns = collectFilterSpecColumns(filters);\n const firstInvalid = filterColumns.find((col) => !isValidColumnId(col));\n if (firstInvalid !== undefined) {\n throw new Error(\n `Invalid filter column ${firstInvalid}: column reference does not match the table columns`,\n );\n }\n}\n\n/** Merge two filter trees into one AND-combined tree. Returns the non-nil one if the other is nil. */\nfunction concatFilters(\n a: Nil | PlDataTableFilters,\n b: Nil | PlDataTableFilters,\n): Nil | PlDataTableFilters {\n if (isNil(a)) return b;\n if (isNil(b)) return a;\n return { ...a, filters: [...a.filters, ...b.filters] };\n}\n\n/** Pick user sorting from state if non-empty, otherwise fall back to options default. */\nfunction resolveSorting(\n userSorting: PTableSorting[],\n defaultSorting: Nil | PTableSorting[],\n): PTableSorting[] {\n return (isEmpty(userSorting) ? defaultSorting : userSorting) ?? [];\n}\n\n/** Validate that all column references in sorting exist in the table. */\nfunction validateSorting(sorting: PTableSorting[], isValidColumnId: (id: string) => boolean): void {\n const firstInvalid = sorting.find(\n (s) => !isValidColumnId(canonicalizeJson<PTableColumnId>(s.column)),\n );\n if (firstInvalid !== undefined) {\n throw new Error(\n `Invalid sorting column ${JSON.stringify(firstInvalid.column)}: column reference does not match the table columns`,\n );\n }\n}\n\nfunction buildSecondaryGroups(\n direct: TableColumnVariant[],\n linked: TableColumnVariant[],\n labels: PColumn<PColumnDataUniversal>[],\n): SecondaryGroup<undefined | PColumnDataUniversal>[] {\n return [\n ...direct.map(\n (c): SecondaryGroup<undefined | PColumnDataUniversal> => ({\n entries: [{ column: resolveSnapshot(c.column), qualifications: c.qualifications.forHit }],\n primaryQualifications: c.qualifications.forQueries,\n }),\n ),\n ...linked.map(\n (lc): SecondaryGroup<undefined | PColumnDataUniversal> => ({\n entries: [\n ...lc.path.map((s) => ({\n column: resolveSnapshot(s.linker),\n qualifications: s.qualifications,\n })),\n { column: resolveSnapshot(lc.column), qualifications: lc.qualifications.forHit },\n ],\n primaryQualifications: lc.qualifications.forQueries,\n }),\n ),\n ...labels.map(\n (c): SecondaryGroup<undefined | PColumnDataUniversal> => ({ entries: [{ column: c }] }),\n ),\n ];\n}\n\n/** Determine which columns should be hidden based on state or optional-column defaults. */\nfunction computeHiddenColumns(\n columns: { readonly id: PObjectId; readonly spec: PColumnSpec }[],\n sorting: Nil | PTableSorting[],\n filters: Nil | PlDataTableFilters,\n hiddenSpecs: Nil | PTableColumnId[],\n): Set<PObjectId> {\n const alwaysHidden = columns.filter((c) => isColumnHidden(c.spec)).map((c) => c.id);\n const optionalHidden = !isNil(hiddenSpecs)\n ? hiddenSpecs.filter((s): s is PTableColumnIdColumn => s.type === \"column\").map((s) => s.id)\n : columns.filter((c) => isColumnOptional(c.spec)).map((c) => c.id);\n const initial = [...alwaysHidden, ...optionalHidden];\n const preserved = collectPreservedColumnIds(sorting, filters);\n\n return new Set(initial.filter((id) => !preserved.has(id)));\n}\n\n/** Collect IDs of columns that must remain visible (sorted, filtered). */\nfunction collectPreservedColumnIds(\n sorting: Nil | PTableSorting[],\n filters: Nil | PlDataTableFilters,\n): Set<PObjectId> {\n const sortedIds = (sorting ?? [])\n .map((s) => s.column)\n .filter((c): c is PTableColumnIdColumn => c.type === \"column\")\n .map((c) => c.id);\n\n const filterIds = !isNil(filters)\n ? collectFilterSpecColumns(filters).flatMap((c) => {\n const obj = parseJson(c);\n return obj.type === \"column\" ? [obj.id] : [];\n })\n : [];\n\n return new Set<PObjectId>([...sortedIds, ...filterIds]);\n}\n\n/** Filter annotated columns to only visible ones, re-matching label columns for the visible subset. */\nfunction buildVisibleColumns(\n annotated: AnnotatedColumnGroups,\n hiddenColumns: Set<PObjectId>,\n originalLabelColumns: PColumn<PColumnDataUniversal>[],\n): VisibleColumns {\n const direct = annotated.direct.filter((c) => !hiddenColumns.has(c.column.id));\n const linked = annotated.linked.filter((c) => !hiddenColumns.has(c.column.id));\n const labels = getMatchingLabelColumns(\n [...direct, ...linked].map((v) => v.column),\n originalLabelColumns,\n );\n return { direct, linked, labels };\n}\n\n/** Resolve a ColumnSnapshot to a PColumn with lazily-evaluated data. */\nfunction resolveSnapshot(\n snap: ColumnSnapshot<PObjectId>,\n): PColumn<undefined | PColumnDataUniversal> {\n return { id: snap.id, spec: snap.spec, data: snap.data?.get() };\n}\n\n/** Remap column references in sorting entries. */\nfunction remapSortingColumnIds(\n sorting: Nil | PTableSorting[],\n columns: TableColumnVariant[],\n): Nil | PTableSorting[] {\n return sorting?.map((s) => {\n if (s.column.type === \"axis\") return s; // Axis references are unaffected by column ID remapping\n\n const id = s.column.id;\n const column =\n columns.find((c) => (c.originalId ?? c.column.id) === id) ??\n throwError(`Column ID \"${id}\" in sorting does not match any discovered column`);\n\n return {\n ...s,\n column: {\n type: \"column\",\n id: column.column.id,\n },\n };\n });\n}\n\ntype PlDataTableFilterNode = FilterSpecNode<PlDataTableFilterSpecLeaf>;\n\n/** Remap column references in a filter tree. */\nfunction remapFilterColumnIds(\n filters: Nil | PlDataTableFilters,\n columns: TableColumnVariant[],\n): Nil | PlDataTableFilters {\n if (isNil(filters)) return filters;\n\n const map = (\n tableColumnId: CanonicalizedJson<PTableColumnId>,\n ): CanonicalizedJson<PTableColumnId> => {\n const parsed = parseJson<PTableColumnId>(tableColumnId);\n if (parsed.type === \"axis\") return tableColumnId; // Axis references are unaffected by column ID remapping\n\n const originalId = parsed.id;\n const column =\n columns.find((c) => (c.originalId ?? c.column.id) === originalId) ??\n throwError(`Column ID \"${parsed.id}\" in filters does not match any discovered column`);\n\n return canonicalizeJson<PTableColumnId>({\n type: \"column\",\n id: column.column.id,\n });\n };\n\n return traverseFilterSpec(filters, {\n leaf: (leaf): PlDataTableFilterNode => {\n if (leaf.type === undefined) return leaf;\n const result = { ...leaf };\n if (\"column\" in result) result.column = map(result.column);\n if (\"rhs\" in result) result.rhs = map(result.rhs);\n return result;\n },\n and: (results): PlDataTableFilterNode => ({ type: \"and\", filters: results }),\n or: (results): PlDataTableFilterNode => ({ type: \"or\", filters: results }),\n not: (result): PlDataTableFilterNode => ({ type: \"not\", filter: result }),\n }) as PlDataTableFilters;\n}\n"],"mappings":"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"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
+
import { ColumnSelector } from "../../../columns/column_selector.js";
|
|
2
|
+
import { ColumnVariant, MatchingMode } from "../../../columns/column_collection_builder.js";
|
|
1
3
|
import { DeriveLabelsOptions } from "../../../labels/derive_distinct_labels.js";
|
|
2
4
|
import { RenderCtxBase } from "../../../render/api.js";
|
|
3
|
-
import { ColumnSelector } from "../../../columns/column_selector.js";
|
|
4
|
-
import { ColumnSnapshot } from "../../../columns/column_snapshot.js";
|
|
5
|
-
import { MatchQualifications, MatchVariant, MatchingMode } from "../../../columns/column_collection_builder.js";
|
|
6
5
|
import { PlDataTableFilters, PlDataTableModel } from "../typesV5.js";
|
|
7
6
|
import { PlDataTableStateV2 } from "../state-migration.js";
|
|
8
7
|
import { DiscoverTableColumnOptions } from "./discoverColumns.js";
|
|
@@ -12,7 +11,7 @@ import { Nil } from "@milaboratories/helpers";
|
|
|
12
11
|
//#region src/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts
|
|
13
12
|
type createPlDataTableOptionsV3 = {
|
|
14
13
|
tableState?: PlDataTableStateV2;
|
|
15
|
-
columns: Nil | DiscoverTableColumnOptions |
|
|
14
|
+
columns: Nil | DiscoverTableColumnOptions | TableColumnVariant[];
|
|
16
15
|
filters?: PlDataTableFilters;
|
|
17
16
|
sorting?: PTableSorting[];
|
|
18
17
|
primaryJoinType?: "inner" | "full";
|
|
@@ -40,14 +39,10 @@ type ColumnVisibilityRule = {
|
|
|
40
39
|
};
|
|
41
40
|
type ColumnMatcher = (spec: PColumnSpec) => boolean;
|
|
42
41
|
declare function createPlDataTableV3<A, U>(ctx: RenderCtxBase<A, U>, options: createPlDataTableOptionsV3): PlDataTableModel | undefined;
|
|
43
|
-
|
|
44
|
-
type TableColumnSnapshot = ColumnSnapshot<DiscoveredPColumnId> & {
|
|
42
|
+
type TableColumnVariant = ColumnVariant<DiscoveredPColumnId> & {
|
|
45
43
|
readonly originalId: PObjectId;
|
|
46
44
|
readonly isPrimary?: boolean;
|
|
47
|
-
readonly linkerPath?: MatchVariant["path"];
|
|
48
|
-
readonly qualifications?: MatchQualifications;
|
|
49
|
-
readonly distinctiveQualifications?: MatchQualifications;
|
|
50
45
|
};
|
|
51
46
|
//#endregion
|
|
52
|
-
export { ColumnMatcher, ColumnOrderRule, ColumnVisibilityRule, ColumnsDisplayOptions, ColumnsSelectorConfig,
|
|
47
|
+
export { ColumnMatcher, ColumnOrderRule, ColumnVisibilityRule, ColumnsDisplayOptions, ColumnsSelectorConfig, TableColumnVariant, createPlDataTableOptionsV3, createPlDataTableV3 };
|
|
53
48
|
//# sourceMappingURL=createPlDataTableV3.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createPlDataTableV3.d.ts","names":[],"sources":["../../../../src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"createPlDataTableV3.d.ts","names":[],"sources":["../../../../src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts"],"mappings":";;;;;;;;;;;KAyCY,0BAAA;EACV,UAAA,GAAa,kBAAA;EAEb,OAAA,EAAS,GAAA,GAAM,0BAAA,GAA6B,kBAAA;EAC5C,OAAA,GAAU,kBAAA;EACV,OAAA,GAAU,aAAA;EACV,eAAA;EAEA,aAAA,GAAgB,mBAAA;EAChB,cAAA,GAAiB,qBAAA;AAAA;;KAIP,qBAAA;EACV,OAAA,GAAU,mBAAA,GAAsB,mBAAA;EAChC,OAAA,GAAU,mBAAA,GAAsB,mBAAA;EAChC,IAAA,GAAO,YAAA;EACP,OAAA;AAAA;AAAA,KAGU,qBAAA;EAX4B,uFAatC,QAAA,GAAW,eAAA,IArBE;EAuBb,UAAA,GAAa,oBAAA;AAAA;AAAA,KAGH,eAAA;EACV,KAAA,EAAO,aAAA,GAAgB,cAAA,EAxBvB;EA0BA,QAAA;AAAA;AAAA,KAGU,oBAAA;EACV,KAAA,EAAO,aAAA,GAAgB,cAAA;EACvB,UAAA;AAAA;AAAA,KAGU,aAAA,IAAiB,IAAA,EAAM,WAAA;AAAA,iBAInB,mBAAA,MAAA,CACd,GAAA,EAAK,aAAA,CAAc,CAAA,EAAG,CAAA,GACtB,OAAA,EAAS,0BAAA,GACR,gBAAA;AAAA,KAmIS,kBAAA,GAAqB,aAAA,CAAc,mBAAA;EAAA,SACpC,UAAA,EAAY,SAAA;EAAA,SACZ,SAAA;AAAA"}
|
|
@@ -15,12 +15,13 @@ function createPlDataTableV3(ctx, options) {
|
|
|
15
15
|
const discovered = isPlainObject(options.columns) ? discoverTableColumnSnaphots(ctx, options.columns) : options.columns;
|
|
16
16
|
if (isNil(discovered) || discovered.length === 0) return void 0;
|
|
17
17
|
const splited = splitDiscoveredColumns(discovered);
|
|
18
|
-
const labelColumns = getMatchingLabelColumns([...splited.direct, ...splited.linked], getAllLabelColumns(ctx));
|
|
18
|
+
const labelColumns = getMatchingLabelColumns([...splited.direct, ...splited.linked].map((v) => v.column), getAllLabelColumns(ctx));
|
|
19
19
|
const derivedLabels = deriveAllLabels({
|
|
20
20
|
columns: discovered.map((dc) => ({
|
|
21
|
-
id: dc.id,
|
|
22
|
-
spec: dc.spec,
|
|
23
|
-
linkerPath: dc.
|
|
21
|
+
id: dc.column.id,
|
|
22
|
+
spec: dc.column.spec,
|
|
23
|
+
linkerPath: dc.path,
|
|
24
|
+
qualifications: dc.qualifications
|
|
24
25
|
})),
|
|
25
26
|
labelColumns,
|
|
26
27
|
deriveLabelsOptions: {
|
|
@@ -29,12 +30,11 @@ function createPlDataTableV3(ctx, options) {
|
|
|
29
30
|
}
|
|
30
31
|
});
|
|
31
32
|
const derivedTooltips = deriveAllTooltips({ columns: discovered.map((dc) => ({
|
|
32
|
-
id: dc.id,
|
|
33
|
+
id: dc.column.id,
|
|
33
34
|
originalId: dc.originalId,
|
|
34
|
-
spec: dc.spec,
|
|
35
|
-
linkerPath: dc.
|
|
36
|
-
qualifications: dc.qualifications
|
|
37
|
-
distinctiveQualifications: dc.distinctiveQualifications
|
|
35
|
+
spec: dc.column.spec,
|
|
36
|
+
linkerPath: dc.path,
|
|
37
|
+
qualifications: dc.qualifications
|
|
38
38
|
})) });
|
|
39
39
|
const annotated = annotateColumnGroups({
|
|
40
40
|
pframeSpec,
|
|
@@ -48,8 +48,8 @@ function createPlDataTableV3(ctx, options) {
|
|
|
48
48
|
const secondarySnapshots = annotated.direct.filter((c) => !c.isPrimary);
|
|
49
49
|
if (primarySnapshots.length === 0) return void 0;
|
|
50
50
|
const columnIsAvailable = createColumnValidationById([
|
|
51
|
-
...annotated.direct,
|
|
52
|
-
...annotated.linked.flatMap((lc) => [...
|
|
51
|
+
...annotated.direct.map((v) => v.column),
|
|
52
|
+
...annotated.linked.flatMap((lc) => [...lc.path.map((s) => s.linker), lc.column]),
|
|
53
53
|
...annotated.labels
|
|
54
54
|
]);
|
|
55
55
|
const remapedDefaultFilters = remapFilterColumnIds(options.filters, discovered);
|
|
@@ -57,7 +57,7 @@ function createPlDataTableV3(ctx, options) {
|
|
|
57
57
|
validateFilters(filters, columnIsAvailable);
|
|
58
58
|
const sorting = resolveSorting(state.pTableParams.sorting, remapSortingColumnIds(options.sorting, discovered));
|
|
59
59
|
validateSorting(sorting, columnIsAvailable);
|
|
60
|
-
const primaryEntries = primarySnapshots.map((
|
|
60
|
+
const primaryEntries = primarySnapshots.map((v) => ({ column: resolveSnapshot(v.column) }));
|
|
61
61
|
const fullDef = createPTableDefV3({
|
|
62
62
|
primaryJoinType,
|
|
63
63
|
primary: primaryEntries,
|
|
@@ -67,13 +67,13 @@ function createPlDataTableV3(ctx, options) {
|
|
|
67
67
|
});
|
|
68
68
|
const fullHandle = ctx.createPTableV2(fullDef);
|
|
69
69
|
const pframeHandle = ctx.createPFrame([
|
|
70
|
-
...annotated.direct.map(resolveSnapshot),
|
|
71
|
-
...annotated.linked.map(resolveSnapshot),
|
|
70
|
+
...annotated.direct.map((v) => resolveSnapshot(v.column)),
|
|
71
|
+
...annotated.linked.map((v) => resolveSnapshot(v.column)),
|
|
72
72
|
...annotated.labels,
|
|
73
73
|
...collectLinkerSnapshots(annotated.linked).map(resolveSnapshot)
|
|
74
74
|
]);
|
|
75
75
|
const hiddenSpecs = state.pTableParams.hiddenColIds;
|
|
76
|
-
const visible = buildVisibleColumns(annotated, computeHiddenColumns([...annotated.direct, ...annotated.linked], sorting, filters, hiddenSpecs), labelColumns);
|
|
76
|
+
const visible = buildVisibleColumns(annotated, computeHiddenColumns([...annotated.direct, ...annotated.linked].map((v) => v.column), sorting, filters, hiddenSpecs), labelColumns);
|
|
77
77
|
const visibleDef = createPTableDefV3({
|
|
78
78
|
primaryJoinType,
|
|
79
79
|
primary: primaryEntries,
|
|
@@ -93,13 +93,13 @@ function createPlDataTableV3(ctx, options) {
|
|
|
93
93
|
/** Split discovered columns into direct (no linker path) and linked (with linker path). */
|
|
94
94
|
function splitDiscoveredColumns(columns) {
|
|
95
95
|
return {
|
|
96
|
-
direct: columns.filter((dc) =>
|
|
97
|
-
linked: columns.filter((dc) =>
|
|
96
|
+
direct: columns.filter((dc) => dc.path.length === 0),
|
|
97
|
+
linked: columns.filter((dc) => dc.path.length > 0)
|
|
98
98
|
};
|
|
99
99
|
}
|
|
100
100
|
/** All linker snapshots across the given linked columns, deduped by id. */
|
|
101
101
|
function collectLinkerSnapshots(linked) {
|
|
102
|
-
return uniqueBy(linked.flatMap((lc) =>
|
|
102
|
+
return uniqueBy(linked.flatMap((lc) => lc.path.map((s) => s.linker)), (c) => c.id);
|
|
103
103
|
}
|
|
104
104
|
/**
|
|
105
105
|
* Annotate all column groups with derived labels and display-rule annotations.
|
|
@@ -110,34 +110,33 @@ function collectLinkerSnapshots(linked) {
|
|
|
110
110
|
function annotateColumnGroups(params) {
|
|
111
111
|
const { direct, linked, labelColumns, derivedLabels, derivedTooltips, displayOptions, pframeSpec } = params;
|
|
112
112
|
const allColumnsForRules = [
|
|
113
|
-
...direct,
|
|
114
|
-
...linked,
|
|
113
|
+
...direct.map((v) => v.column),
|
|
114
|
+
...linked.map((v) => v.column),
|
|
115
115
|
...labelColumns,
|
|
116
116
|
...collectLinkerSnapshots(linked)
|
|
117
117
|
];
|
|
118
118
|
const visibilityByColId = evaluateRules(displayOptions?.visibility ?? [], allColumnsForRules, pframeSpec);
|
|
119
119
|
const orderByColId = evaluateRules(displayOptions?.ordering ?? [], allColumnsForRules, pframeSpec);
|
|
120
120
|
return {
|
|
121
|
-
direct:
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
linked: [
|
|
127
|
-
withLabelAnnotations.bind(null, derivedLabels),
|
|
128
|
-
withInfoAnnotations.bind(null, derivedTooltips),
|
|
129
|
-
withHidenAxesAnnotations.bind(null),
|
|
130
|
-
withTableVisualAnnotations.bind(null, visibilityByColId, orderByColId),
|
|
131
|
-
(cols) => cols.map((lc) => ({
|
|
132
|
-
...lc,
|
|
133
|
-
linkerPath: annotateLinkerPath(derivedLabels, lc.linkerPath)
|
|
134
|
-
}))
|
|
135
|
-
].reduce((cols, fn) => fn(cols), linked),
|
|
121
|
+
direct: withVariantColumns(direct, (cols) => withTableVisualAnnotations(visibilityByColId, orderByColId, withInfoAnnotations(derivedTooltips, withLabelAnnotations(derivedLabels, cols)))),
|
|
122
|
+
linked: withVariantColumns(linked, (cols) => withTableVisualAnnotations(visibilityByColId, orderByColId, withHidenAxesAnnotations(withInfoAnnotations(derivedTooltips, withLabelAnnotations(derivedLabels, cols))))).map((lc) => ({
|
|
123
|
+
...lc,
|
|
124
|
+
path: annotateLinkerPath(derivedLabels, lc.path)
|
|
125
|
+
})),
|
|
136
126
|
labels: withLabelAnnotations(derivedLabels, labelColumns)
|
|
137
127
|
};
|
|
138
128
|
}
|
|
129
|
+
/** Apply a snapshot-array transformation to the inner `column` of each variant. */
|
|
130
|
+
function withVariantColumns(variants, fn) {
|
|
131
|
+
const cols = fn(variants.map((v) => v.column));
|
|
132
|
+
if (cols.length !== variants.length) throw new Error(`withVariantColumns: fn must preserve array length (got ${cols.length}, expected ${variants.length})`);
|
|
133
|
+
return variants.map((v, i) => ({
|
|
134
|
+
...v,
|
|
135
|
+
column: cols[i]
|
|
136
|
+
}));
|
|
137
|
+
}
|
|
139
138
|
function annotateLinkerPath(derivedLabels, path) {
|
|
140
|
-
if (
|
|
139
|
+
if (path.length === 0) return path;
|
|
141
140
|
const annotatedLinkers = withHidenAxesAnnotations(withLabelAnnotations(derivedLabels, path.map((s) => s.linker)));
|
|
142
141
|
return path.map((s, i) => ({
|
|
143
142
|
...s,
|
|
@@ -186,20 +185,20 @@ function buildSecondaryGroups(direct, linked, labels) {
|
|
|
186
185
|
return [
|
|
187
186
|
...direct.map((c) => ({
|
|
188
187
|
entries: [{
|
|
189
|
-
column: resolveSnapshot(c),
|
|
190
|
-
qualifications: c.qualifications
|
|
188
|
+
column: resolveSnapshot(c.column),
|
|
189
|
+
qualifications: c.qualifications.forHit
|
|
191
190
|
}],
|
|
192
|
-
primaryQualifications: c.qualifications
|
|
191
|
+
primaryQualifications: c.qualifications.forQueries
|
|
193
192
|
})),
|
|
194
193
|
...linked.map((lc) => ({
|
|
195
|
-
entries: [...
|
|
194
|
+
entries: [...lc.path.map((s) => ({
|
|
196
195
|
column: resolveSnapshot(s.linker),
|
|
197
196
|
qualifications: s.qualifications
|
|
198
197
|
})), {
|
|
199
|
-
column: resolveSnapshot(lc),
|
|
200
|
-
qualifications: lc.qualifications
|
|
198
|
+
column: resolveSnapshot(lc.column),
|
|
199
|
+
qualifications: lc.qualifications.forHit
|
|
201
200
|
}],
|
|
202
|
-
primaryQualifications: lc.qualifications
|
|
201
|
+
primaryQualifications: lc.qualifications.forQueries
|
|
203
202
|
})),
|
|
204
203
|
...labels.map((c) => ({ entries: [{ column: c }] }))
|
|
205
204
|
];
|
|
@@ -223,12 +222,12 @@ function collectPreservedColumnIds(sorting, filters) {
|
|
|
223
222
|
}
|
|
224
223
|
/** Filter annotated columns to only visible ones, re-matching label columns for the visible subset. */
|
|
225
224
|
function buildVisibleColumns(annotated, hiddenColumns, originalLabelColumns) {
|
|
226
|
-
const direct = annotated.direct.filter((c) => !hiddenColumns.has(c.id));
|
|
227
|
-
const linked = annotated.linked.filter((c) => !hiddenColumns.has(c.id));
|
|
225
|
+
const direct = annotated.direct.filter((c) => !hiddenColumns.has(c.column.id));
|
|
226
|
+
const linked = annotated.linked.filter((c) => !hiddenColumns.has(c.column.id));
|
|
228
227
|
return {
|
|
229
228
|
direct,
|
|
230
229
|
linked,
|
|
231
|
-
labels: getMatchingLabelColumns([...direct, ...linked], originalLabelColumns)
|
|
230
|
+
labels: getMatchingLabelColumns([...direct, ...linked].map((v) => v.column), originalLabelColumns)
|
|
232
231
|
};
|
|
233
232
|
}
|
|
234
233
|
/** Resolve a ColumnSnapshot to a PColumn with lazily-evaluated data. */
|
|
@@ -244,12 +243,12 @@ function remapSortingColumnIds(sorting, columns) {
|
|
|
244
243
|
return sorting?.map((s) => {
|
|
245
244
|
if (s.column.type === "axis") return s;
|
|
246
245
|
const id = s.column.id;
|
|
247
|
-
const column = columns.find((c) => (c.originalId ?? c.id) === id) ?? throwError(`Column ID "${id}" in sorting does not match any discovered column`);
|
|
246
|
+
const column = columns.find((c) => (c.originalId ?? c.column.id) === id) ?? throwError(`Column ID "${id}" in sorting does not match any discovered column`);
|
|
248
247
|
return {
|
|
249
248
|
...s,
|
|
250
249
|
column: {
|
|
251
250
|
type: "column",
|
|
252
|
-
id: column.id
|
|
251
|
+
id: column.column.id
|
|
253
252
|
}
|
|
254
253
|
};
|
|
255
254
|
});
|
|
@@ -263,7 +262,7 @@ function remapFilterColumnIds(filters, columns) {
|
|
|
263
262
|
const originalId = parsed.id;
|
|
264
263
|
return canonicalizeJson({
|
|
265
264
|
type: "column",
|
|
266
|
-
id: (columns.find((c) => (c.originalId ?? c.id) === originalId) ?? throwError(`Column ID "${parsed.id}" in filters does not match any discovered column`)).id
|
|
265
|
+
id: (columns.find((c) => (c.originalId ?? c.column.id) === originalId) ?? throwError(`Column ID "${parsed.id}" in filters does not match any discovered column`)).column.id
|
|
267
266
|
});
|
|
268
267
|
};
|
|
269
268
|
return traverseFilterSpec(filters, {
|