@platforma-sdk/model 1.65.9 → 1.66.2
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/block_model.cjs +8 -11
- package/dist/block_model.cjs.map +1 -1
- package/dist/block_model.d.ts.map +1 -1
- package/dist/block_model.js +8 -10
- package/dist/block_model.js.map +1 -1
- package/dist/columns/column_collection_builder.cjs +61 -74
- package/dist/columns/column_collection_builder.cjs.map +1 -1
- package/dist/columns/column_collection_builder.d.ts +16 -22
- package/dist/columns/column_collection_builder.d.ts.map +1 -1
- package/dist/columns/column_collection_builder.js +62 -75
- package/dist/columns/column_collection_builder.js.map +1 -1
- package/dist/columns/column_selector.cjs.map +1 -1
- package/dist/columns/column_selector.d.ts +1 -1
- package/dist/columns/column_selector.js.map +1 -1
- package/dist/columns/column_snapshot.cjs.map +1 -1
- package/dist/columns/column_snapshot.d.ts +4 -4
- package/dist/columns/column_snapshot.d.ts.map +1 -1
- package/dist/columns/column_snapshot.js.map +1 -1
- package/dist/columns/ctx_column_sources.cjs.map +1 -1
- package/dist/columns/ctx_column_sources.d.ts +1 -1
- package/dist/columns/ctx_column_sources.d.ts.map +1 -1
- package/dist/columns/ctx_column_sources.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs +2 -2
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js +2 -2
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs +17 -18
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js +17 -18
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs +99 -91
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts +16 -16
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js +102 -94
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs +32 -23
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts +5 -5
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js +33 -24
- 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.d.ts +2 -3
- package/dist/components/PlDataTable/createPlDataTable/index.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/index.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.cjs +133 -16
- package/dist/components/PlDataTable/createPlDataTable/utils.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.d.ts +8 -6
- package/dist/components/PlDataTable/createPlDataTable/utils.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.js +130 -17
- package/dist/components/PlDataTable/createPlDataTable/utils.js.map +1 -1
- package/dist/components/PlDataTable/labels.cjs +1 -2
- package/dist/components/PlDataTable/labels.cjs.map +1 -1
- package/dist/components/PlDataTable/labels.js +1 -2
- package/dist/components/PlDataTable/labels.js.map +1 -1
- package/dist/filters/distill.cjs +73 -30
- package/dist/filters/distill.cjs.map +1 -1
- package/dist/filters/distill.d.ts.map +1 -1
- package/dist/filters/distill.js +73 -30
- package/dist/filters/distill.js.map +1 -1
- package/dist/index.cjs +19 -15
- package/dist/index.d.ts +4 -2
- package/dist/index.js +6 -4
- package/dist/labels/derive_distinct_tooltips.cjs +85 -0
- package/dist/labels/derive_distinct_tooltips.cjs.map +1 -0
- package/dist/labels/derive_distinct_tooltips.d.ts +17 -0
- package/dist/labels/derive_distinct_tooltips.d.ts.map +1 -0
- package/dist/labels/derive_distinct_tooltips.js +84 -0
- package/dist/labels/derive_distinct_tooltips.js.map +1 -0
- package/dist/labels/index.cjs +1 -0
- package/dist/labels/index.d.ts +2 -1
- package/dist/labels/index.js +1 -0
- package/dist/package.cjs +1 -1
- package/dist/package.js +1 -1
- package/dist/render/api.cjs +8 -13
- package/dist/render/api.cjs.map +1 -1
- package/dist/render/api.d.ts +8 -11
- package/dist/render/api.d.ts.map +1 -1
- package/dist/render/api.js +8 -13
- package/dist/render/api.js.map +1 -1
- package/dist/services/get_services.cjs +19 -0
- package/dist/services/get_services.cjs.map +1 -0
- package/dist/services/get_services.d.ts +7 -0
- package/dist/services/get_services.d.ts.map +1 -0
- package/dist/services/get_services.js +19 -0
- package/dist/services/get_services.js.map +1 -0
- package/dist/services/index.cjs +1 -0
- package/dist/services/index.d.ts +2 -1
- package/dist/services/index.js +1 -0
- package/dist/services/service_bridge.cjs +4 -4
- package/dist/services/service_bridge.cjs.map +1 -1
- package/dist/services/service_bridge.d.ts +4 -4
- package/dist/services/service_bridge.d.ts.map +1 -1
- package/dist/services/service_bridge.js +4 -4
- package/dist/services/service_bridge.js.map +1 -1
- package/package.json +6 -6
- package/src/block_model.ts +8 -11
- package/src/columns/column_collection_builder.test.ts +75 -30
- package/src/columns/column_collection_builder.ts +96 -133
- package/src/columns/column_selector.ts +1 -1
- package/src/columns/column_snapshot.ts +7 -4
- package/src/columns/ctx_column_sources.ts +1 -3
- package/src/components/PFrameForGraphs.test.ts +4 -4
- package/src/components/PlDataTable/createPlDataTable/createPTableDefV2.ts +2 -2
- package/src/components/PlDataTable/createPlDataTable/createPTableDefV3.ts +44 -21
- package/src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts +202 -218
- package/src/components/PlDataTable/createPlDataTable/discoverColumns.ts +69 -56
- package/src/components/PlDataTable/createPlDataTable/index.ts +6 -7
- package/src/components/PlDataTable/createPlDataTable/utils.test.ts +97 -1
- package/src/components/PlDataTable/createPlDataTable/utils.ts +190 -35
- package/src/components/PlDataTable/labels.ts +3 -7
- package/src/filters/distill.test.ts +91 -0
- package/src/filters/distill.ts +102 -46
- package/src/labels/derive_distinct_tooltips.test.ts +233 -0
- package/src/labels/derive_distinct_tooltips.ts +130 -0
- package/src/labels/index.ts +1 -0
- package/src/render/api.ts +15 -50
- package/src/services/get_services.ts +28 -0
- package/src/services/index.ts +1 -0
- package/src/services/service_bridge.ts +5 -5
|
@@ -10,51 +10,51 @@ import type {
|
|
|
10
10
|
PTableSorting,
|
|
11
11
|
PColumnSpec,
|
|
12
12
|
MultiColumnSelector,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
import {
|
|
16
|
-
canonicalizeJson,
|
|
17
|
-
getAxisId,
|
|
18
|
-
getColumnIdAndSpec,
|
|
19
|
-
parseJson,
|
|
20
|
-
uniqueBy,
|
|
13
|
+
PFrameSpecDriver,
|
|
14
|
+
DiscoveredPColumnId,
|
|
21
15
|
} from "@milaboratories/pl-model-common";
|
|
16
|
+
import { canonicalizeJson, getAxisId, parseJson, uniqueBy } from "@milaboratories/pl-model-common";
|
|
22
17
|
import { collectFilterSpecColumns, traverseFilterSpec } from "../../../filters/traverse";
|
|
23
18
|
import type { RenderCtxBase, PColumnDataUniversal } from "../../../render";
|
|
24
19
|
import { isEmpty } from "es-toolkit/compat";
|
|
25
20
|
import type { PlDataTableFilters, PlDataTableFilterSpecLeaf, PlDataTableModel } from "../typesV5";
|
|
26
21
|
import { upgradePlDataTableStateV2 } from "../state-migration";
|
|
27
22
|
import type { PlDataTableStateV2 } from "../state-migration";
|
|
28
|
-
import type {
|
|
29
|
-
|
|
23
|
+
import type {
|
|
24
|
+
ColumnSelector,
|
|
25
|
+
ColumnSnapshot,
|
|
26
|
+
MatchingMode,
|
|
27
|
+
MatchQualifications,
|
|
28
|
+
MatchVariant,
|
|
29
|
+
} from "../../../columns";
|
|
30
30
|
import { getAllLabelColumns, getMatchingLabelColumns } from "../labels";
|
|
31
31
|
import type { DeriveLabelsOptions } from "../../../labels/derive_distinct_labels";
|
|
32
32
|
import {
|
|
33
33
|
deriveAllLabels,
|
|
34
|
+
deriveAllTooltips,
|
|
35
|
+
evaluateRules,
|
|
34
36
|
isColumnHidden,
|
|
35
37
|
isColumnOptional,
|
|
38
|
+
withHidenAxesAnnotations,
|
|
36
39
|
withLabelAnnotations,
|
|
37
40
|
withTableVisualAnnotations,
|
|
41
|
+
withInfoAnnotations,
|
|
38
42
|
} from "./utils";
|
|
43
|
+
import type { PrimaryEntry, SecondaryGroup } from "./createPTableDefV3";
|
|
39
44
|
import { createPTableDefV3 } from "./createPTableDefV3";
|
|
40
|
-
import { discoverTableColumnSnaphots, type
|
|
41
|
-
import { isNil,
|
|
42
|
-
|
|
43
|
-
export type createPlDataTableOptionsV3 =
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
| {
|
|
48
|
-
columns: Nil | TableColumnSnapshot<SUniversalPColumnId>[];
|
|
49
|
-
}
|
|
50
|
-
) & {
|
|
45
|
+
import { discoverTableColumnSnaphots, type DiscoverTableColumnOptions } from "./discoverColumns";
|
|
46
|
+
import { isNil, isPlainObject, throwError, type Nil } from "@milaboratories/helpers";
|
|
47
|
+
|
|
48
|
+
export type createPlDataTableOptionsV3 = {
|
|
49
|
+
tableState?: PlDataTableStateV2;
|
|
50
|
+
|
|
51
|
+
columns: Nil | DiscoverTableColumnOptions | TableColumnSnapshot[];
|
|
51
52
|
filters?: PlDataTableFilters;
|
|
52
53
|
sorting?: PTableSorting[];
|
|
53
54
|
primaryJoinType?: "inner" | "full";
|
|
54
55
|
|
|
55
|
-
tableState?: PlDataTableStateV2;
|
|
56
56
|
labelsOptions?: DeriveLabelsOptions;
|
|
57
|
-
|
|
57
|
+
displayOptions?: ColumnsDisplayOptions;
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
/** Structured source config — selectors/anchors instead of raw ColumnSource. */
|
|
@@ -73,13 +73,13 @@ export type ColumnsDisplayOptions = {
|
|
|
73
73
|
};
|
|
74
74
|
|
|
75
75
|
export type ColumnOrderRule = {
|
|
76
|
-
match: ColumnMatcher;
|
|
76
|
+
match: ColumnMatcher | ColumnSelector;
|
|
77
77
|
/** Higher number = further left in table */
|
|
78
78
|
priority: number;
|
|
79
79
|
};
|
|
80
80
|
|
|
81
81
|
export type ColumnVisibilityRule = {
|
|
82
|
-
match: ColumnMatcher;
|
|
82
|
+
match: ColumnMatcher | ColumnSelector;
|
|
83
83
|
visibility: "default" | "optional" | "hidden";
|
|
84
84
|
};
|
|
85
85
|
|
|
@@ -87,23 +87,25 @@ export type ColumnMatcher = (spec: PColumnSpec) => boolean;
|
|
|
87
87
|
|
|
88
88
|
// Main Function
|
|
89
89
|
|
|
90
|
-
export function createPlDataTableV3<A, U
|
|
91
|
-
ctx: RenderCtxBase<A, U
|
|
90
|
+
export function createPlDataTableV3<A, U>(
|
|
91
|
+
ctx: RenderCtxBase<A, U>,
|
|
92
92
|
options: createPlDataTableOptionsV3,
|
|
93
93
|
): PlDataTableModel | undefined {
|
|
94
|
+
const pframeSpec = ctx.getService("pframeSpec");
|
|
94
95
|
const state = upgradePlDataTableStateV2(options.tableState);
|
|
95
96
|
const primaryJoinType = options.primaryJoinType ?? "full";
|
|
96
97
|
|
|
97
|
-
const discovered =
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
: options.columns;
|
|
98
|
+
const discovered = isPlainObject(options.columns)
|
|
99
|
+
? discoverTableColumnSnaphots(ctx, options.columns)
|
|
100
|
+
: options.columns;
|
|
101
101
|
if (isNil(discovered) || discovered.length === 0) return undefined;
|
|
102
102
|
|
|
103
103
|
const splited = splitDiscoveredColumns(discovered);
|
|
104
|
-
const resolved = resolveDiscoveredColumns(splited, discovered);
|
|
105
104
|
|
|
106
|
-
const labelColumns = getMatchingLabelColumns(
|
|
105
|
+
const labelColumns = getMatchingLabelColumns(
|
|
106
|
+
[...splited.direct, ...splited.linked],
|
|
107
|
+
getAllLabelColumns(ctx),
|
|
108
|
+
);
|
|
107
109
|
|
|
108
110
|
const derivedLabels = deriveAllLabels({
|
|
109
111
|
columns: discovered.map((dc) => ({
|
|
@@ -118,24 +120,34 @@ export function createPlDataTableV3<A, U, S extends RequireServices<typeof Servi
|
|
|
118
120
|
},
|
|
119
121
|
});
|
|
120
122
|
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
+
const derivedTooltips = deriveAllTooltips({
|
|
124
|
+
columns: discovered.map((dc) => ({
|
|
125
|
+
id: dc.id,
|
|
126
|
+
originalId: dc.originalId,
|
|
127
|
+
spec: dc.spec,
|
|
128
|
+
linkerPath: dc.linkerPath,
|
|
129
|
+
qualifications: dc.qualifications,
|
|
130
|
+
distinctiveQualifications: dc.distinctiveQualifications,
|
|
131
|
+
})),
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
const annotated = annotateColumnGroups({
|
|
135
|
+
pframeSpec,
|
|
136
|
+
...splited,
|
|
123
137
|
labelColumns,
|
|
124
138
|
derivedLabels,
|
|
125
|
-
|
|
126
|
-
|
|
139
|
+
derivedTooltips,
|
|
140
|
+
displayOptions: options.displayOptions,
|
|
141
|
+
});
|
|
127
142
|
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
);
|
|
131
|
-
const primaryColumns = annotated.direct.filter((c) => primaryColumnIds.has(c.id));
|
|
132
|
-
const secondaryColumns = annotated.direct.filter((c) => !primaryColumnIds.has(c.id));
|
|
143
|
+
const primarySnapshots = annotated.direct.filter((c) => c.isPrimary);
|
|
144
|
+
const secondarySnapshots = annotated.direct.filter((c) => !c.isPrimary);
|
|
133
145
|
|
|
134
|
-
if (
|
|
146
|
+
if (primarySnapshots.length === 0) return undefined;
|
|
135
147
|
|
|
136
148
|
const columnIsAvailable = createColumnValidationById([
|
|
137
149
|
...annotated.direct,
|
|
138
|
-
...annotated.linked.flatMap((lc) => [...(
|
|
150
|
+
...annotated.linked.flatMap((lc) => [...(lc.linkerPath ?? []).map((s) => s.linker), lc]),
|
|
139
151
|
...annotated.labels,
|
|
140
152
|
]);
|
|
141
153
|
|
|
@@ -152,24 +164,25 @@ export function createPlDataTableV3<A, U, S extends RequireServices<typeof Servi
|
|
|
152
164
|
);
|
|
153
165
|
validateSorting(sorting, columnIsAvailable);
|
|
154
166
|
|
|
167
|
+
const primaryEntries: PrimaryEntry<undefined | PColumnDataUniversal>[] = primarySnapshots.map(
|
|
168
|
+
(snap) => ({ column: resolveSnapshot(snap) }),
|
|
169
|
+
);
|
|
155
170
|
const fullDef = createPTableDefV3({
|
|
156
171
|
primaryJoinType,
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
...secondaryColumns.map((c) => [c]),
|
|
160
|
-
...annotated.linked.map((lc) => [...(annotated.linkers.get(lc.id) ?? []), lc]),
|
|
161
|
-
...annotated.labels.map((c) => [c]),
|
|
162
|
-
],
|
|
172
|
+
primary: primaryEntries,
|
|
173
|
+
secondary: buildSecondaryGroups(secondarySnapshots, annotated.linked, annotated.labels),
|
|
163
174
|
filters,
|
|
164
175
|
sorting,
|
|
165
176
|
});
|
|
166
177
|
|
|
167
178
|
const fullHandle = ctx.createPTableV2(fullDef);
|
|
179
|
+
// TODO: is workaround for dropdown suggestions.
|
|
180
|
+
// Pframe have not equivalent data for columns relativly to Ptable
|
|
168
181
|
const pframeHandle = ctx.createPFrame([
|
|
169
|
-
...annotated.direct,
|
|
170
|
-
...annotated.linked,
|
|
182
|
+
...annotated.direct.map(resolveSnapshot),
|
|
183
|
+
...annotated.linked.map(resolveSnapshot),
|
|
171
184
|
...annotated.labels,
|
|
172
|
-
...
|
|
185
|
+
...collectLinkerSnapshots(annotated.linked).map(resolveSnapshot),
|
|
173
186
|
]);
|
|
174
187
|
|
|
175
188
|
const hiddenSpecs = state.pTableParams.hiddenColIds;
|
|
@@ -181,22 +194,14 @@ export function createPlDataTableV3<A, U, S extends RequireServices<typeof Servi
|
|
|
181
194
|
);
|
|
182
195
|
|
|
183
196
|
const visible = buildVisibleColumns(annotated, hiddenColumnIds, labelColumns);
|
|
184
|
-
const visibleNonCoreDirect = secondaryColumns.filter((c) => !hiddenColumnIds.has(c.id));
|
|
185
|
-
const visibleLinkedGroups = buildVisibleLinkedGroups(
|
|
186
|
-
visible.direct,
|
|
187
|
-
visible.linked,
|
|
188
|
-
annotated.linkers,
|
|
189
|
-
hiddenSpecs,
|
|
190
|
-
);
|
|
191
|
-
|
|
192
197
|
const visibleDef = createPTableDefV3({
|
|
193
198
|
primaryJoinType,
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
199
|
+
primary: primaryEntries,
|
|
200
|
+
secondary: buildSecondaryGroups(
|
|
201
|
+
visible.direct.filter((c) => !c.isPrimary),
|
|
202
|
+
visible.linked,
|
|
203
|
+
visible.labels,
|
|
204
|
+
),
|
|
200
205
|
filters,
|
|
201
206
|
sorting,
|
|
202
207
|
});
|
|
@@ -212,97 +217,128 @@ export function createPlDataTableV3<A, U, S extends RequireServices<typeof Servi
|
|
|
212
217
|
}
|
|
213
218
|
|
|
214
219
|
/** A single column discovered from sources — normalized from raw ColumnSnapshot/ColumnMatch. */
|
|
215
|
-
export type TableColumnSnapshot
|
|
220
|
+
export type TableColumnSnapshot = ColumnSnapshot<DiscoveredPColumnId> & {
|
|
221
|
+
readonly originalId: PObjectId;
|
|
216
222
|
readonly isPrimary?: boolean;
|
|
217
|
-
readonly
|
|
218
|
-
readonly
|
|
223
|
+
readonly linkerPath?: MatchVariant["path"];
|
|
224
|
+
readonly qualifications?: MatchQualifications;
|
|
225
|
+
readonly distinctiveQualifications?: MatchQualifications;
|
|
219
226
|
};
|
|
220
227
|
|
|
221
|
-
type TableColumn = PColumn<undefined | PColumnDataUniversal>;
|
|
222
|
-
|
|
223
228
|
type SplitDiscoveredColumns = {
|
|
224
|
-
readonly direct: TableColumnSnapshot
|
|
225
|
-
readonly linked: TableColumnSnapshot
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
type ResolvedColumns = {
|
|
229
|
-
readonly direct: TableColumn[];
|
|
230
|
-
readonly linked: TableColumn[];
|
|
231
|
-
readonly linkers: Map<PObjectId, TableColumn[]>;
|
|
232
|
-
readonly all: TableColumn[];
|
|
229
|
+
readonly direct: TableColumnSnapshot[];
|
|
230
|
+
readonly linked: TableColumnSnapshot[];
|
|
233
231
|
};
|
|
234
232
|
|
|
235
233
|
type AnnotatedColumnGroups = {
|
|
236
|
-
readonly direct:
|
|
237
|
-
readonly linked:
|
|
238
|
-
readonly
|
|
239
|
-
readonly labels: TableColumn[];
|
|
234
|
+
readonly direct: TableColumnSnapshot[];
|
|
235
|
+
readonly linked: TableColumnSnapshot[];
|
|
236
|
+
readonly labels: PColumn<PColumnDataUniversal>[];
|
|
240
237
|
};
|
|
241
238
|
|
|
242
239
|
type VisibleColumns = {
|
|
243
|
-
readonly direct:
|
|
244
|
-
readonly linked:
|
|
240
|
+
readonly direct: TableColumnSnapshot[];
|
|
241
|
+
readonly linked: TableColumnSnapshot[];
|
|
245
242
|
readonly labels: PColumn<PColumnDataUniversal>[];
|
|
246
243
|
};
|
|
247
244
|
|
|
248
245
|
/** Split discovered columns into direct (no linker path) and linked (with linker path). */
|
|
249
|
-
function splitDiscoveredColumns(
|
|
250
|
-
columns
|
|
251
|
-
)
|
|
252
|
-
return {
|
|
253
|
-
direct: columns.filter((dc) => isNil(dc.linkerPath) || dc.linkerPath.length === 0),
|
|
254
|
-
linked: columns.filter((dc) => !isNil(dc.linkerPath) && dc.linkerPath.length > 0),
|
|
255
|
-
};
|
|
246
|
+
function splitDiscoveredColumns(columns: TableColumnSnapshot[]): SplitDiscoveredColumns {
|
|
247
|
+
const direct = columns.filter((dc) => isNil(dc.linkerPath) || dc.linkerPath.length === 0);
|
|
248
|
+
const linked = columns.filter((dc) => !isNil(dc.linkerPath) && dc.linkerPath.length > 0);
|
|
249
|
+
return { direct, linked };
|
|
256
250
|
}
|
|
257
251
|
|
|
258
|
-
/**
|
|
259
|
-
function
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
)
|
|
263
|
-
const linked = split.linked.map(resolveSnapshot);
|
|
264
|
-
const linkers = new Map<PObjectId, TableColumn[]>(
|
|
265
|
-
split.linked
|
|
266
|
-
.filter(
|
|
267
|
-
(dc): dc is RequiredBy<TableColumnSnapshot<SUniversalPColumnId>, "linkerPath"> =>
|
|
268
|
-
!isNil(dc.linkerPath),
|
|
269
|
-
)
|
|
270
|
-
.map((dc, i) => [linked[i].id, dc.linkerPath.map((s) => resolveSnapshot(s.linker))]),
|
|
252
|
+
/** All linker snapshots across the given linked columns, deduped by id. */
|
|
253
|
+
function collectLinkerSnapshots(linked: TableColumnSnapshot[]): ColumnSnapshot<PObjectId>[] {
|
|
254
|
+
return uniqueBy(
|
|
255
|
+
linked.flatMap((lc) => (lc.linkerPath ?? []).map((s) => s.linker)),
|
|
256
|
+
(c) => c.id,
|
|
271
257
|
);
|
|
272
|
-
|
|
273
|
-
return {
|
|
274
|
-
all: allDiscovered.map(resolveSnapshot),
|
|
275
|
-
direct: split.direct.map(resolveSnapshot),
|
|
276
|
-
linked,
|
|
277
|
-
linkers,
|
|
278
|
-
};
|
|
279
258
|
}
|
|
280
259
|
|
|
281
|
-
/**
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
260
|
+
/**
|
|
261
|
+
* Annotate all column groups with derived labels and display-rule annotations.
|
|
262
|
+
* Evaluates `displayOptions` rules against all discovered columns (direct,
|
|
263
|
+
* linked, labels, linkers) and writes the winning visibility/priority into
|
|
264
|
+
* column annotations via `withTableVisualAnnotations`.
|
|
265
|
+
*/
|
|
266
|
+
function annotateColumnGroups(params: {
|
|
267
|
+
direct: TableColumnSnapshot[];
|
|
268
|
+
linked: TableColumnSnapshot[];
|
|
269
|
+
labelColumns: PColumn<PColumnDataUniversal>[];
|
|
270
|
+
derivedLabels: Record<string, string>;
|
|
271
|
+
derivedTooltips: Record<string, string>;
|
|
272
|
+
displayOptions?: ColumnsDisplayOptions;
|
|
273
|
+
pframeSpec: PFrameSpecDriver;
|
|
274
|
+
}): AnnotatedColumnGroups {
|
|
275
|
+
const {
|
|
276
|
+
direct,
|
|
277
|
+
linked,
|
|
278
|
+
labelColumns,
|
|
279
|
+
derivedLabels,
|
|
280
|
+
derivedTooltips,
|
|
293
281
|
displayOptions,
|
|
294
|
-
|
|
282
|
+
pframeSpec,
|
|
283
|
+
} = params;
|
|
284
|
+
|
|
285
|
+
const allColumnsForRules = [
|
|
286
|
+
...direct,
|
|
287
|
+
...linked,
|
|
288
|
+
...labelColumns,
|
|
289
|
+
...collectLinkerSnapshots(linked),
|
|
290
|
+
];
|
|
291
|
+
const visibilityByColId = evaluateRules(
|
|
292
|
+
displayOptions?.visibility ?? [],
|
|
293
|
+
allColumnsForRules,
|
|
294
|
+
pframeSpec,
|
|
295
295
|
);
|
|
296
|
-
const
|
|
297
|
-
|
|
296
|
+
const orderByColId = evaluateRules(
|
|
297
|
+
displayOptions?.ordering ?? [],
|
|
298
|
+
allColumnsForRules,
|
|
299
|
+
pframeSpec,
|
|
298
300
|
);
|
|
299
|
-
const labels = withLabelAnnotations(derivedLabels, labelColumns);
|
|
300
301
|
|
|
301
|
-
|
|
302
|
+
const directAnnotated = [
|
|
303
|
+
withLabelAnnotations.bind(null, derivedLabels),
|
|
304
|
+
withInfoAnnotations.bind(null, derivedTooltips),
|
|
305
|
+
withTableVisualAnnotations.bind(null, visibilityByColId, orderByColId),
|
|
306
|
+
].reduce((cols, fn) => fn(cols) as TableColumnSnapshot[], direct);
|
|
307
|
+
|
|
308
|
+
const linkedAnnotated = [
|
|
309
|
+
withLabelAnnotations.bind(null, derivedLabels),
|
|
310
|
+
withInfoAnnotations.bind(null, derivedTooltips),
|
|
311
|
+
withTableVisualAnnotations.bind(null, visibilityByColId, orderByColId),
|
|
312
|
+
(cols: TableColumnSnapshot[]) =>
|
|
313
|
+
cols.map((lc) => ({ ...lc, linkerPath: annotateLinkerPath(derivedLabels, lc.linkerPath) })),
|
|
314
|
+
].reduce((cols, fn) => fn(cols) as TableColumnSnapshot[], linked);
|
|
315
|
+
|
|
316
|
+
const labelColumnsAnnotated = withLabelAnnotations(derivedLabels, labelColumns);
|
|
317
|
+
|
|
318
|
+
return {
|
|
319
|
+
direct: directAnnotated,
|
|
320
|
+
linked: linkedAnnotated,
|
|
321
|
+
labels: labelColumnsAnnotated,
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
function annotateLinkerPath(
|
|
325
|
+
derivedLabels: Record<string, string>,
|
|
326
|
+
path: TableColumnSnapshot["linkerPath"],
|
|
327
|
+
): TableColumnSnapshot["linkerPath"] {
|
|
328
|
+
if (isNil(path) || path.length === 0) return path;
|
|
329
|
+
const annotatedLinkers = withHidenAxesAnnotations(
|
|
330
|
+
withLabelAnnotations(
|
|
331
|
+
derivedLabels,
|
|
332
|
+
path.map((s) => s.linker),
|
|
333
|
+
),
|
|
334
|
+
);
|
|
335
|
+
return path.map((s, i) => ({ ...s, linker: annotatedLinkers[i] }));
|
|
302
336
|
}
|
|
303
337
|
|
|
304
338
|
/** Build an index of all valid column IDs (axes + columns) for filter/sorting validation. */
|
|
305
|
-
function createColumnValidationById(
|
|
339
|
+
function createColumnValidationById(
|
|
340
|
+
fullColumns: { readonly id: PObjectId; readonly spec: PColumnSpec }[],
|
|
341
|
+
) {
|
|
306
342
|
const axisIds = uniqueBy(
|
|
307
343
|
fullColumns.flatMap((c) => c.spec.axesSpec.map(getAxisId)),
|
|
308
344
|
(a) => canonicalizeJson<AxisId>(a),
|
|
@@ -365,9 +401,39 @@ function validateSorting(sorting: PTableSorting[], isValidColumnId: (id: string)
|
|
|
365
401
|
}
|
|
366
402
|
}
|
|
367
403
|
|
|
404
|
+
function buildSecondaryGroups(
|
|
405
|
+
direct: TableColumnSnapshot[],
|
|
406
|
+
linked: TableColumnSnapshot[],
|
|
407
|
+
labels: PColumn<PColumnDataUniversal>[],
|
|
408
|
+
): SecondaryGroup<undefined | PColumnDataUniversal>[] {
|
|
409
|
+
return [
|
|
410
|
+
...direct.map(
|
|
411
|
+
(c): SecondaryGroup<undefined | PColumnDataUniversal> => ({
|
|
412
|
+
entries: [{ column: resolveSnapshot(c), qualifications: c.qualifications?.forHit }],
|
|
413
|
+
primaryQualifications: c.qualifications?.forQueries,
|
|
414
|
+
}),
|
|
415
|
+
),
|
|
416
|
+
...linked.map(
|
|
417
|
+
(lc): SecondaryGroup<undefined | PColumnDataUniversal> => ({
|
|
418
|
+
entries: [
|
|
419
|
+
...(lc.linkerPath ?? []).map((s) => ({
|
|
420
|
+
column: resolveSnapshot(s.linker),
|
|
421
|
+
qualifications: s.qualifications,
|
|
422
|
+
})),
|
|
423
|
+
{ column: resolveSnapshot(lc), qualifications: lc.qualifications?.forHit },
|
|
424
|
+
],
|
|
425
|
+
primaryQualifications: lc.qualifications?.forQueries,
|
|
426
|
+
}),
|
|
427
|
+
),
|
|
428
|
+
...labels.map(
|
|
429
|
+
(c): SecondaryGroup<undefined | PColumnDataUniversal> => ({ entries: [{ column: c }] }),
|
|
430
|
+
),
|
|
431
|
+
];
|
|
432
|
+
}
|
|
433
|
+
|
|
368
434
|
/** Determine which columns should be hidden based on state or optional-column defaults. */
|
|
369
435
|
function computeHiddenColumns(
|
|
370
|
-
columns:
|
|
436
|
+
columns: { readonly id: PObjectId; readonly spec: PColumnSpec }[],
|
|
371
437
|
sorting: Nil | PTableSorting[],
|
|
372
438
|
filters: Nil | PlDataTableFilters,
|
|
373
439
|
hiddenSpecs: Nil | PTableColumnId[],
|
|
@@ -382,85 +448,6 @@ function computeHiddenColumns(
|
|
|
382
448
|
return new Set(initial.filter((id) => !preserved.has(id)));
|
|
383
449
|
}
|
|
384
450
|
|
|
385
|
-
/**
|
|
386
|
-
* Build visible linked column groups. Non-hidden groups are included fully;
|
|
387
|
-
* hidden groups are trimmed to only the prefix that brings axes not yet
|
|
388
|
-
* covered by earlier groups (visible or previously trimmed).
|
|
389
|
-
*/
|
|
390
|
-
function buildVisibleLinkedGroups(
|
|
391
|
-
direct: TableColumn[],
|
|
392
|
-
linked: TableColumn[],
|
|
393
|
-
linkers: Map<PObjectId, TableColumn[]>,
|
|
394
|
-
hiddenSpecs: PTableColumnId[] | null,
|
|
395
|
-
): TableColumn[][] {
|
|
396
|
-
const result: TableColumn[][] = [];
|
|
397
|
-
const coveredAxisIds = new Set<CanonicalizedJson<AxisId>>();
|
|
398
|
-
|
|
399
|
-
const collectAxes = (group: TableColumn[]) => {
|
|
400
|
-
for (const col of group) {
|
|
401
|
-
for (const as of col.spec.axesSpec) {
|
|
402
|
-
coveredAxisIds.add(canonicalizeJson(getAxisId(as)));
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
};
|
|
406
|
-
|
|
407
|
-
collectAxes(direct);
|
|
408
|
-
|
|
409
|
-
for (const lc of linked) {
|
|
410
|
-
const group = [...(linkers.get(lc.id) ?? []), lc];
|
|
411
|
-
result.push(group);
|
|
412
|
-
collectAxes(group);
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
for (const group of linkers.values()) {
|
|
416
|
-
const trimmed = trimGroupByVisibleAxes(group, hiddenSpecs, coveredAxisIds);
|
|
417
|
-
if (trimmed.length > 0) {
|
|
418
|
-
result.push(trimmed);
|
|
419
|
-
collectAxes(trimmed);
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
return result;
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
/**
|
|
427
|
-
* For a linked column group [linker1, ..., linkerN, column], find the rightmost
|
|
428
|
-
* element that has at least one non-hidden and not-yet-covered axis.
|
|
429
|
-
* Return the prefix up to and including that element.
|
|
430
|
-
* If no element has such an axis, return empty array.
|
|
431
|
-
*/
|
|
432
|
-
function trimGroupByVisibleAxes(
|
|
433
|
-
group: TableColumn[],
|
|
434
|
-
hiddenSpecs: PTableColumnId[] | null,
|
|
435
|
-
coveredAxisIds: Set<CanonicalizedJson<AxisId>>,
|
|
436
|
-
): TableColumn[] {
|
|
437
|
-
if (hiddenSpecs === null) return group;
|
|
438
|
-
|
|
439
|
-
const hiddenAxisIds = new Set(
|
|
440
|
-
hiddenSpecs
|
|
441
|
-
.filter((s): s is PTableColumnIdAxis => s.type === "axis")
|
|
442
|
-
.map((s) => canonicalizeJson(s.id)),
|
|
443
|
-
);
|
|
444
|
-
|
|
445
|
-
const uncoveredAxisIds = new Set(
|
|
446
|
-
group
|
|
447
|
-
.flatMap((c) => c.spec.axesSpec.map((as) => canonicalizeJson(getAxisId(as))))
|
|
448
|
-
.filter((id) => !hiddenAxisIds.has(id) && !coveredAxisIds.has(id)),
|
|
449
|
-
);
|
|
450
|
-
|
|
451
|
-
let lastNeeded = -1;
|
|
452
|
-
for (let i = 0; i < group.length; i++) {
|
|
453
|
-
const newAxes = group[i].spec.axesSpec
|
|
454
|
-
.map((as) => canonicalizeJson(getAxisId(as)))
|
|
455
|
-
.filter((id) => uncoveredAxisIds.has(id));
|
|
456
|
-
if (newAxes.length > 0) {
|
|
457
|
-
for (const id of newAxes) uncoveredAxisIds.delete(id);
|
|
458
|
-
lastNeeded = i;
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
return lastNeeded === -1 ? [] : group.slice(0, lastNeeded + 1);
|
|
462
|
-
}
|
|
463
|
-
|
|
464
451
|
/** Collect IDs of columns that must remain visible (sorted, filtered). */
|
|
465
452
|
function collectPreservedColumnIds(
|
|
466
453
|
sorting: Nil | PTableSorting[],
|
|
@@ -489,10 +476,7 @@ function buildVisibleColumns(
|
|
|
489
476
|
): VisibleColumns {
|
|
490
477
|
const direct = annotated.direct.filter((c) => !hiddenColumns.has(c.id));
|
|
491
478
|
const linked = annotated.linked.filter((c) => !hiddenColumns.has(c.id));
|
|
492
|
-
const labels = getMatchingLabelColumns(
|
|
493
|
-
[...direct, ...linked].map(getColumnIdAndSpec),
|
|
494
|
-
originalLabelColumns,
|
|
495
|
-
);
|
|
479
|
+
const labels = getMatchingLabelColumns([...direct, ...linked], originalLabelColumns);
|
|
496
480
|
return { direct, linked, labels };
|
|
497
481
|
}
|
|
498
482
|
|
|
@@ -506,7 +490,7 @@ function resolveSnapshot(
|
|
|
506
490
|
/** Remap column references in sorting entries. */
|
|
507
491
|
function remapSortingColumnIds(
|
|
508
492
|
sorting: Nil | PTableSorting[],
|
|
509
|
-
columns: TableColumnSnapshot
|
|
493
|
+
columns: TableColumnSnapshot[],
|
|
510
494
|
): Nil | PTableSorting[] {
|
|
511
495
|
return sorting?.map((s) => {
|
|
512
496
|
if (s.column.type === "axis") return s; // Axis references are unaffected by column ID remapping
|
|
@@ -531,7 +515,7 @@ type PlDataTableFilterNode = FilterSpecNode<PlDataTableFilterSpecLeaf>;
|
|
|
531
515
|
/** Remap column references in a filter tree. */
|
|
532
516
|
function remapFilterColumnIds(
|
|
533
517
|
filters: Nil | PlDataTableFilters,
|
|
534
|
-
columns: TableColumnSnapshot
|
|
518
|
+
columns: TableColumnSnapshot[],
|
|
535
519
|
): Nil | PlDataTableFilters {
|
|
536
520
|
if (isNil(filters)) return filters;
|
|
537
521
|
|