@platforma-sdk/model 1.59.3 → 1.60.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_storage.cjs.map +1 -1
- package/dist/block_storage.d.ts +1 -11
- package/dist/block_storage.js.map +1 -1
- package/dist/block_storage_callbacks.cjs.map +1 -1
- package/dist/block_storage_callbacks.js.map +1 -1
- package/dist/columns/column_collection_builder.cjs +215 -0
- package/dist/columns/column_collection_builder.cjs.map +1 -0
- package/dist/columns/column_collection_builder.d.ts +112 -0
- package/dist/columns/column_collection_builder.js +214 -0
- package/dist/columns/column_collection_builder.js.map +1 -0
- package/dist/columns/column_selector.cjs +122 -0
- package/dist/columns/column_selector.cjs.map +1 -0
- package/dist/columns/column_selector.d.ts +41 -0
- package/dist/columns/column_selector.js +118 -0
- package/dist/columns/column_selector.js.map +1 -0
- package/dist/columns/column_snapshot.cjs +20 -0
- package/dist/columns/column_snapshot.cjs.map +1 -0
- package/dist/columns/column_snapshot.d.ts +39 -0
- package/dist/columns/column_snapshot.js +18 -0
- package/dist/columns/column_snapshot.js.map +1 -0
- package/dist/columns/column_snapshot_provider.cjs +112 -0
- package/dist/columns/column_snapshot_provider.cjs.map +1 -0
- package/dist/columns/column_snapshot_provider.d.ts +73 -0
- package/dist/columns/column_snapshot_provider.js +107 -0
- package/dist/columns/column_snapshot_provider.js.map +1 -0
- package/dist/columns/ctx_column_sources.cjs +84 -0
- package/dist/columns/ctx_column_sources.cjs.map +1 -0
- package/dist/columns/ctx_column_sources.d.ts +33 -0
- package/dist/columns/ctx_column_sources.js +82 -0
- package/dist/columns/ctx_column_sources.js.map +1 -0
- package/dist/columns/index.cjs +5 -0
- package/dist/columns/index.d.ts +5 -0
- package/dist/columns/index.js +5 -0
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.cjs +111 -0
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.cjs.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.d.ts +25 -0
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.js +110 -0
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.js.map +1 -0
- package/dist/components/PlDataTable/{table.cjs → createPlDataTable/createPlDataTableV3.cjs} +54 -54
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts +39 -0
- package/dist/components/PlDataTable/{table.js → createPlDataTable/createPlDataTableV3.js} +53 -53
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/index.cjs +12 -0
- package/dist/components/PlDataTable/createPlDataTable/index.cjs.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/index.d.ts +15 -0
- package/dist/components/PlDataTable/createPlDataTable/index.js +12 -0
- package/dist/components/PlDataTable/createPlDataTable/index.js.map +1 -0
- package/dist/components/PlDataTable/createPlDataTableSheet.cjs +18 -0
- package/dist/components/PlDataTable/createPlDataTableSheet.cjs.map +1 -0
- package/dist/components/PlDataTable/createPlDataTableSheet.d.ts +11 -0
- package/dist/components/PlDataTable/createPlDataTableSheet.js +17 -0
- package/dist/components/PlDataTable/createPlDataTableSheet.js.map +1 -0
- package/dist/components/PlDataTable/index.cjs +4 -1
- package/dist/components/PlDataTable/index.d.ts +5 -2
- package/dist/components/PlDataTable/index.js +4 -1
- package/dist/components/PlDataTable/state-migration.cjs.map +1 -1
- package/dist/components/PlDataTable/state-migration.d.ts +2 -2
- package/dist/components/PlDataTable/state-migration.js.map +1 -1
- package/dist/components/PlDataTable/{v4.d.ts → typesV4.d.ts} +2 -2
- package/dist/components/PlDataTable/{v5.d.ts → typesV5.d.ts} +2 -2
- package/dist/components/index.cjs +4 -1
- package/dist/components/index.d.ts +5 -2
- package/dist/components/index.js +4 -1
- package/dist/index.cjs +44 -16
- package/dist/index.d.ts +17 -5
- package/dist/index.js +15 -3
- package/dist/labels/derive_distinct_labels.cjs +156 -0
- package/dist/labels/derive_distinct_labels.cjs.map +1 -0
- package/dist/labels/derive_distinct_labels.d.ts +29 -0
- package/dist/labels/derive_distinct_labels.js +155 -0
- package/dist/labels/derive_distinct_labels.js.map +1 -0
- package/dist/labels/index.cjs +2 -0
- package/dist/labels/index.d.ts +2 -0
- package/dist/labels/index.js +2 -0
- package/dist/labels/write_labels_to_specs.cjs +15 -0
- package/dist/labels/write_labels_to_specs.cjs.map +1 -0
- package/dist/labels/write_labels_to_specs.d.ts +9 -0
- package/dist/labels/write_labels_to_specs.js +14 -0
- package/dist/labels/write_labels_to_specs.js.map +1 -0
- package/dist/package.cjs +1 -1
- package/dist/package.js +1 -1
- package/dist/render/api.cjs +11 -2
- package/dist/render/api.cjs.map +1 -1
- package/dist/render/api.d.ts +9 -5
- package/dist/render/api.js +12 -3
- package/dist/render/api.js.map +1 -1
- package/dist/render/index.d.ts +2 -1
- package/dist/render/index.js +1 -1
- package/dist/render/internal.cjs.map +1 -1
- package/dist/render/internal.d.ts +5 -2
- package/dist/render/internal.js.map +1 -1
- package/dist/render/util/column_collection.cjs +3 -3
- package/dist/render/util/column_collection.cjs.map +1 -1
- package/dist/render/util/column_collection.d.ts +3 -2
- package/dist/render/util/column_collection.js +4 -4
- package/dist/render/util/column_collection.js.map +1 -1
- package/dist/render/util/index.d.ts +2 -1
- package/dist/render/util/index.js +1 -1
- package/dist/render/util/label.cjs +7 -134
- package/dist/render/util/label.cjs.map +1 -1
- package/dist/render/util/label.d.ts +5 -50
- package/dist/render/util/label.js +8 -132
- package/dist/render/util/label.js.map +1 -1
- package/dist/render/util/split_selectors.d.ts +2 -2
- package/package.json +9 -7
- package/src/block_storage.ts +0 -11
- package/src/block_storage_callbacks.ts +1 -1
- package/src/columns/column_collection_builder.test.ts +427 -0
- package/src/columns/column_collection_builder.ts +455 -0
- package/src/columns/column_selector.test.ts +472 -0
- package/src/columns/column_selector.ts +212 -0
- package/src/columns/column_snapshot.ts +55 -0
- package/src/columns/column_snapshot_provider.ts +177 -0
- package/src/columns/ctx_column_sources.ts +107 -0
- package/src/columns/expand_by_partition.test.ts +289 -0
- package/src/columns/expand_by_partition.ts +187 -0
- package/src/columns/index.ts +5 -0
- package/src/components/PlDataTable/createPlDataTable/createPlDataTableV2.ts +193 -0
- package/src/components/PlDataTable/{table.ts → createPlDataTable/createPlDataTableV3.ts} +134 -70
- package/src/components/PlDataTable/createPlDataTable/index.ts +27 -0
- package/src/components/PlDataTable/createPlDataTableSheet.ts +20 -0
- package/src/components/PlDataTable/index.ts +6 -4
- package/src/components/PlDataTable/state-migration.ts +2 -2
- package/src/index.ts +2 -1
- package/src/labels/derive_distinct_labels.test.ts +461 -0
- package/src/labels/derive_distinct_labels.ts +289 -0
- package/src/labels/index.ts +2 -0
- package/src/labels/write_labels_to_specs.ts +12 -0
- package/src/render/api.ts +25 -3
- package/src/render/internal.ts +20 -1
- package/src/render/util/column_collection.ts +9 -6
- package/src/render/util/label.test.ts +1 -1
- package/src/render/util/label.ts +19 -235
- package/src/render/util/split_selectors.ts +3 -3
- package/dist/components/PlDataTable/table.cjs.map +0 -1
- package/dist/components/PlDataTable/table.d.ts +0 -30
- package/dist/components/PlDataTable/table.js.map +0 -1
- /package/src/components/PlDataTable/{v4.ts → typesV4.ts} +0 -0
- /package/src/components/PlDataTable/{v5.ts → typesV5.ts} +0 -0
package/src/render/util/label.ts
CHANGED
|
@@ -1,241 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
} from "@milaboratories/pl-model-common";
|
|
7
|
-
import { z } from "zod";
|
|
8
|
-
|
|
9
|
-
export type RecordsWithLabel<T> = {
|
|
10
|
-
value: T;
|
|
11
|
-
label: string;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export type LabelDerivationOps = {
|
|
15
|
-
/** Force inclusion of native column label */
|
|
16
|
-
includeNativeLabel?: boolean;
|
|
17
|
-
/** Separator to use between label parts (" / " by default) */
|
|
18
|
-
separator?: string;
|
|
19
|
-
/** If true, label will be added as suffix (at the end of the generated label). By default label added as a prefix. */
|
|
20
|
-
addLabelAsSuffix?: boolean;
|
|
21
|
-
/** Trace elements list that will be forced to be included in the label. */
|
|
22
|
-
forceTraceElements?: string[];
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export const TraceEntry = z.object({
|
|
26
|
-
type: z.string(),
|
|
27
|
-
importance: z.number().optional(),
|
|
28
|
-
id: z.string().optional(),
|
|
29
|
-
label: z.string(),
|
|
30
|
-
});
|
|
31
|
-
export type TraceEntry = z.infer<typeof TraceEntry>;
|
|
32
|
-
type FullTraceEntry = TraceEntry & { fullType: string; occurrenceIndex: number };
|
|
1
|
+
export {
|
|
2
|
+
type Trace,
|
|
3
|
+
type DeriveLabelsOptions as LabelDerivationOps,
|
|
4
|
+
type Entry as SpecExtractorResult,
|
|
5
|
+
} from "../../labels/derive_distinct_labels";
|
|
33
6
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
| PObjectSpec
|
|
41
|
-
| {
|
|
42
|
-
spec: PObjectSpec;
|
|
43
|
-
prefixTrace?: TraceEntry[];
|
|
44
|
-
suffixTrace?: TraceEntry[];
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
const DistancePenalty = 0.001;
|
|
7
|
+
// Backward-compatible wrapper: old API accepted a getSpec callback
|
|
8
|
+
import {
|
|
9
|
+
deriveDistinctLabels,
|
|
10
|
+
type DeriveLabelsOptions,
|
|
11
|
+
type Entry,
|
|
12
|
+
} from "../../labels/derive_distinct_labels";
|
|
48
13
|
|
|
49
|
-
|
|
50
|
-
const LabelTypeFull = "__LABEL__@1";
|
|
14
|
+
type WithLabel<T> = { value: T; label: string };
|
|
51
15
|
|
|
16
|
+
/** @deprecated Use deriveDistinctLabels */
|
|
52
17
|
export function deriveLabels<T>(
|
|
53
18
|
values: T[],
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
):
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
ops.forceTraceElements !== undefined && ops.forceTraceElements.length > 0
|
|
61
|
-
? new Set(ops.forceTraceElements)
|
|
62
|
-
: undefined;
|
|
63
|
-
|
|
64
|
-
// number of times certain type occurred among all of the
|
|
65
|
-
const numberOfRecordsWithType = new Map<string, number>();
|
|
66
|
-
|
|
67
|
-
const enrichedRecords = values.map((value) => {
|
|
68
|
-
const extractorResult = specExtractor(value);
|
|
69
|
-
let spec: PObjectSpec;
|
|
70
|
-
let prefixTrace: TraceEntry[] | undefined;
|
|
71
|
-
let suffixTrace: TraceEntry[] | undefined;
|
|
72
|
-
|
|
73
|
-
// Check if the result is the new structure or just PObjectSpec
|
|
74
|
-
if ("spec" in extractorResult && typeof extractorResult.spec === "object") {
|
|
75
|
-
// It's the new structure { spec, prefixTrace?, suffixTrace? }
|
|
76
|
-
spec = extractorResult.spec;
|
|
77
|
-
prefixTrace = extractorResult.prefixTrace;
|
|
78
|
-
suffixTrace = extractorResult.suffixTrace;
|
|
79
|
-
} else {
|
|
80
|
-
// It's just PObjectSpec
|
|
81
|
-
spec = extractorResult as PObjectSpec;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const label = readAnnotation(spec, Annotation.Label);
|
|
85
|
-
const traceStr = readAnnotation(spec, Annotation.Trace);
|
|
86
|
-
const baseTrace = (traceStr ? Trace.safeParse(parseJson(traceStr)).data : undefined) ?? [];
|
|
87
|
-
|
|
88
|
-
const trace = [...(prefixTrace ?? []), ...baseTrace, ...(suffixTrace ?? [])];
|
|
89
|
-
|
|
90
|
-
if (label !== undefined) {
|
|
91
|
-
const labelEntry = { label, type: LabelType, importance: -2 };
|
|
92
|
-
if (ops.addLabelAsSuffix) trace.push(labelEntry);
|
|
93
|
-
else trace.splice(0, 0, labelEntry);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const fullTrace: FullTrace = [];
|
|
97
|
-
|
|
98
|
-
const occurrences = new Map<string, number>();
|
|
99
|
-
for (let i = trace.length - 1; i >= 0; --i) {
|
|
100
|
-
const { type: typeName } = trace[i];
|
|
101
|
-
const importance = trace[i].importance ?? 0;
|
|
102
|
-
const occurrenceIndex = (occurrences.get(typeName) ?? 0) + 1;
|
|
103
|
-
occurrences.set(typeName, occurrenceIndex);
|
|
104
|
-
const fullType = `${typeName}@${occurrenceIndex}`;
|
|
105
|
-
numberOfRecordsWithType.set(fullType, (numberOfRecordsWithType.get(fullType) ?? 0) + 1);
|
|
106
|
-
importances.set(
|
|
107
|
-
fullType,
|
|
108
|
-
Math.max(
|
|
109
|
-
importances.get(fullType) ?? Number.NEGATIVE_INFINITY,
|
|
110
|
-
importance - (trace.length - i) * DistancePenalty,
|
|
111
|
-
),
|
|
112
|
-
);
|
|
113
|
-
fullTrace.push({ ...trace[i], fullType, occurrenceIndex: occurrenceIndex });
|
|
114
|
-
}
|
|
115
|
-
fullTrace.reverse();
|
|
116
|
-
return {
|
|
117
|
-
value,
|
|
118
|
-
spec,
|
|
119
|
-
label,
|
|
120
|
-
fullTrace,
|
|
121
|
-
};
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
// excluding repeated types (i.e. ..@2, ..@3, etc.) not found in some records
|
|
125
|
-
const mainTypes: string[] = [];
|
|
126
|
-
// repeated types (i.e. ..@2, ..@3, etc.) not found in some records
|
|
127
|
-
const secondaryTypes: string[] = [];
|
|
128
|
-
|
|
129
|
-
const allTypeRecords = [...importances];
|
|
130
|
-
// sorting: most important types go first
|
|
131
|
-
allTypeRecords.sort(([, i1], [, i2]) => i2 - i1);
|
|
132
|
-
|
|
133
|
-
for (const [typeName] of allTypeRecords) {
|
|
134
|
-
if (typeName.endsWith("@1") || numberOfRecordsWithType.get(typeName) === values.length)
|
|
135
|
-
mainTypes.push(typeName);
|
|
136
|
-
else secondaryTypes.push(typeName);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const calculate = (includedTypes: Set<string>, force: boolean = false) => {
|
|
140
|
-
const result: RecordsWithLabel<T>[] = [];
|
|
141
|
-
for (let i = 0; i < enrichedRecords.length; i++) {
|
|
142
|
-
const r = enrichedRecords[i];
|
|
143
|
-
const includedTrace = r.fullTrace.filter(
|
|
144
|
-
(fm) =>
|
|
145
|
-
includedTypes.has(fm.fullType) || (forceTraceElements && forceTraceElements.has(fm.type)),
|
|
146
|
-
);
|
|
147
|
-
if (includedTrace.length === 0) {
|
|
148
|
-
if (force)
|
|
149
|
-
result.push({
|
|
150
|
-
label: "Unlabeled",
|
|
151
|
-
value: r.value,
|
|
152
|
-
} satisfies RecordsWithLabel<T>);
|
|
153
|
-
else return undefined;
|
|
154
|
-
}
|
|
155
|
-
const labelSet = includedTrace.map((fm) => fm.label);
|
|
156
|
-
const sep = ops.separator ?? " / ";
|
|
157
|
-
result.push({
|
|
158
|
-
label: labelSet.join(sep),
|
|
159
|
-
value: r.value,
|
|
160
|
-
} satisfies RecordsWithLabel<T>);
|
|
161
|
-
}
|
|
162
|
-
return result;
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
const countUniqueLabels = (result: RecordsWithLabel<T>[] | undefined): number =>
|
|
166
|
-
result === undefined ? 0 : new Set(result.map((c) => c.label)).size;
|
|
167
|
-
|
|
168
|
-
// Post-processing: try removing types one by one (lowest importance first) to minimize the label set
|
|
169
|
-
// Accepts removal if it doesn't decrease the number of unique labels (cardinality)
|
|
170
|
-
const minimizeTypeSet = (typeSet: Set<string>): Set<string> => {
|
|
171
|
-
const initialResult = calculate(typeSet);
|
|
172
|
-
if (initialResult === undefined) {
|
|
173
|
-
return typeSet;
|
|
174
|
-
}
|
|
175
|
-
const currentCardinality = countUniqueLabels(initialResult);
|
|
176
|
-
|
|
177
|
-
// Get types sorted by importance ascending (lowest first), excluding forced elements
|
|
178
|
-
const removableSorted = [...typeSet]
|
|
179
|
-
.filter(
|
|
180
|
-
(t) =>
|
|
181
|
-
!forceTraceElements?.has(t.split("@")[0]) &&
|
|
182
|
-
!(ops.includeNativeLabel && t === LabelTypeFull),
|
|
183
|
-
)
|
|
184
|
-
.sort((a, b) => (importances.get(a) ?? 0) - (importances.get(b) ?? 0));
|
|
185
|
-
|
|
186
|
-
for (const typeToRemove of removableSorted) {
|
|
187
|
-
const reducedSet = new Set(typeSet);
|
|
188
|
-
reducedSet.delete(typeToRemove);
|
|
189
|
-
const candidateResult = calculate(reducedSet);
|
|
190
|
-
if (
|
|
191
|
-
candidateResult !== undefined &&
|
|
192
|
-
countUniqueLabels(candidateResult) >= currentCardinality
|
|
193
|
-
) {
|
|
194
|
-
typeSet.delete(typeToRemove);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
return typeSet;
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
if (mainTypes.length === 0) {
|
|
201
|
-
if (secondaryTypes.length !== 0)
|
|
202
|
-
throw new Error("Non-empty secondary types list while main types list is empty.");
|
|
203
|
-
return calculate(new Set(LabelTypeFull), true)!;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
//
|
|
207
|
-
// includedTypes = 2
|
|
208
|
-
// * *
|
|
209
|
-
// T0 T1 T2 T3 T4 T5
|
|
210
|
-
// *
|
|
211
|
-
// additionalType = 3
|
|
212
|
-
//
|
|
213
|
-
// Resulting set: T0, T1, T3
|
|
214
|
-
//
|
|
215
|
-
let includedTypes = 0;
|
|
216
|
-
let additionalType = -1;
|
|
217
|
-
while (includedTypes < mainTypes.length) {
|
|
218
|
-
const currentSet = new Set<string>();
|
|
219
|
-
if (ops.includeNativeLabel) currentSet.add(LabelTypeFull);
|
|
220
|
-
for (let i = 0; i < includedTypes; ++i) currentSet.add(mainTypes[i]);
|
|
221
|
-
if (additionalType >= 0) currentSet.add(mainTypes[additionalType]);
|
|
222
|
-
|
|
223
|
-
const candidateResult = calculate(currentSet);
|
|
224
|
-
|
|
225
|
-
if (candidateResult !== undefined && countUniqueLabels(candidateResult) === values.length) {
|
|
226
|
-
minimizeTypeSet(currentSet);
|
|
227
|
-
return calculate(currentSet)!;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
additionalType++;
|
|
231
|
-
if (additionalType >= mainTypes.length) {
|
|
232
|
-
includedTypes++;
|
|
233
|
-
additionalType = includedTypes;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// Fallback: include all types, then try to minimize
|
|
238
|
-
const fallbackSet = new Set([...mainTypes, ...secondaryTypes]);
|
|
239
|
-
minimizeTypeSet(fallbackSet);
|
|
240
|
-
return calculate(fallbackSet, true)!;
|
|
19
|
+
getSpec: (obj: T) => Entry,
|
|
20
|
+
options: DeriveLabelsOptions = {},
|
|
21
|
+
): WithLabel<T>[] {
|
|
22
|
+
const specs = values.map(getSpec);
|
|
23
|
+
const labeled = deriveDistinctLabels(specs, options);
|
|
24
|
+
return labeled.map((l, i) => ({ value: values[i], label: l.label }));
|
|
241
25
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
AAxisSelector,
|
|
3
|
-
AnchoredPColumnSelector,
|
|
4
|
-
AxisSelector,
|
|
5
3
|
PColumnSelector,
|
|
4
|
+
AnchoredPColumnSelector,
|
|
5
|
+
LegacyAxisSelector,
|
|
6
6
|
} from "@milaboratories/pl-model-common";
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -22,7 +22,7 @@ export type APColumnSelectorWithSplit = AnchoredPColumnSelector & {
|
|
|
22
22
|
/**
|
|
23
23
|
* AxisSelector with an optional split flag
|
|
24
24
|
*/
|
|
25
|
-
export type AxisSelectorWithSplit =
|
|
25
|
+
export type AxisSelectorWithSplit = LegacyAxisSelector & {
|
|
26
26
|
split?: boolean;
|
|
27
27
|
};
|
|
28
28
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"table.cjs","names":["distillFilterSpec","filterSpecToSpecQueryExpr","Annotation","upgradePlDataTableStateV2","getAllLabelColumns","getMatchingLabelColumns","getColumnIdAndSpec","deriveLabels","identity","collectFilterSpecColumns","allPColumnsReady"],"sources":["../../../src/components/PlDataTable/table.ts"],"sourcesContent":["import type {\n AxisId,\n AxisSpec,\n DataInfo,\n PColumn,\n PColumnIdAndSpec,\n PColumnValues,\n PObjectId,\n PTableColumnId,\n PTableColumnIdAxis,\n PTableColumnIdColumn,\n PTableDefV2,\n PTableSorting,\n SpecQuery,\n SingleAxisSelector,\n SpecQueryExpression,\n SpecQueryJoinEntry,\n CanonicalizedJson,\n} from \"@milaboratories/pl-model-common\";\nimport {\n Annotation,\n canonicalizeJson,\n getAxisId,\n getColumnIdAndSpec,\n isLinkerColumn,\n readAnnotation,\n uniqueBy,\n isBooleanExpression,\n parseJson,\n} from \"@milaboratories/pl-model-common\";\nimport { filterSpecToSpecQueryExpr } from \"../../filters\";\nimport type { RenderCtxBase, TreeNodeAccessor, PColumnDataUniversal } from \"../../render\";\nimport { allPColumnsReady, deriveLabels } from \"../../render\";\nimport { identity, isFunction, isNil } from \"es-toolkit\";\nimport { distillFilterSpec } from \"../../filters/distill\";\nimport type { CreatePlDataTableOps, PlDataTableFilters, PlDataTableModel } from \"./v5\";\nimport { upgradePlDataTableStateV2 } from \"./state-migration\";\nimport type { PlDataTableStateV2 } from \"./state-migration\";\nimport type { PlDataTableSheet } from \"./v5\";\nimport { getAllLabelColumns, getMatchingLabelColumns } from \"./labels\";\nimport { collectFilterSpecColumns } from \"../../filters/traverse\";\nimport { isEmpty } from \"es-toolkit/compat\";\n\n/** Convert a PTableColumnId to a SpecQueryExpression reference. */\nfunction columnIdToExpr(col: PTableColumnId): SpecQueryExpression {\n if (col.type === \"axis\") {\n return { type: \"axisRef\", value: col.id as SingleAxisSelector };\n }\n return { type: \"columnRef\", value: col.id };\n}\n\n/** Wrap a SpecQuery as a SpecQueryJoinEntry with empty qualifications. */\nfunction joinEntry<C>(input: SpecQuery<C>): SpecQueryJoinEntry<C> {\n return { entry: input, qualifications: [] };\n}\n\nfunction createPTableDef(params: {\n columns: PColumn<PColumnDataUniversal>[];\n labelColumns: PColumn<PColumnDataUniversal>[];\n coreJoinType: \"inner\" | \"full\";\n filters: null | PlDataTableFilters;\n sorting: PTableSorting[];\n coreColumnPredicate?: (spec: PColumnIdAndSpec) => boolean;\n}): PTableDefV2<PColumn<TreeNodeAccessor | PColumnValues | DataInfo<TreeNodeAccessor>>> {\n let coreColumns = params.columns;\n const secondaryColumns: typeof params.columns = [];\n\n if (isFunction(params.coreColumnPredicate)) {\n coreColumns = [];\n for (const c of params.columns)\n if (params.coreColumnPredicate(getColumnIdAndSpec(c))) coreColumns.push(c);\n else secondaryColumns.push(c);\n }\n\n secondaryColumns.push(...params.labelColumns);\n\n // Build SpecQuery directly from columns\n const coreJoinQuery: SpecQuery<\n PColumn<TreeNodeAccessor | PColumnValues | DataInfo<TreeNodeAccessor>>\n > = {\n type: params.coreJoinType === \"inner\" ? \"innerJoin\" : \"fullJoin\",\n entries: coreColumns.map((c) => joinEntry({ type: \"column\", column: c })),\n };\n\n let query: SpecQuery<PColumn<TreeNodeAccessor | PColumnValues | DataInfo<TreeNodeAccessor>>> = {\n type: \"outerJoin\",\n primary: joinEntry(coreJoinQuery),\n secondary: secondaryColumns.map((c) => joinEntry({ type: \"column\", column: c })),\n };\n\n // Apply filters\n if (params.filters !== null) {\n const nonEmpty = distillFilterSpec(params.filters);\n\n if (!isNil(nonEmpty)) {\n const pridicate = filterSpecToSpecQueryExpr(nonEmpty);\n if (!isBooleanExpression(pridicate)) {\n throw new Error(\n `Filter conversion produced a non-boolean expression (got type \"${pridicate.type}\"), expected a boolean predicate for query filtering`,\n );\n }\n query = {\n type: \"filter\",\n input: query,\n predicate: pridicate,\n };\n }\n }\n\n // Apply sorting\n if (params.sorting.length > 0) {\n query = {\n type: \"sort\",\n input: query,\n sortBy: params.sorting.map((s) => ({\n expression: columnIdToExpr(s.column),\n ascending: s.ascending,\n nullsFirst: !s.naAndAbsentAreLeastValues,\n })),\n };\n }\n\n return { query };\n}\n\n/** Check if column should be omitted from the table */\nexport function isColumnHidden(spec: { annotations?: Annotation }): boolean {\n return readAnnotation(spec, Annotation.Table.Visibility) === \"hidden\";\n}\n\n/** Check if column is hidden by default */\nexport function isColumnOptional(spec: { annotations?: Annotation }): boolean {\n return readAnnotation(spec, Annotation.Table.Visibility) === \"optional\";\n}\n\n/**\n * Create p-table spec and handle given ui table state\n *\n * @param ctx context\n * @param columns column list\n * @param tableState table ui state\n * @returns PlAgDataTableV2 table source\n */\nexport function createPlDataTableV2<A, U>(\n ctx: RenderCtxBase<A, U>,\n columns: PColumn<PColumnDataUniversal>[],\n tableState: PlDataTableStateV2 | undefined,\n ops?: CreatePlDataTableOps,\n): PlDataTableModel | undefined {\n if (columns.length === 0) return undefined;\n\n const tableStateNormalized = upgradePlDataTableStateV2(tableState);\n\n const allLabelColumns = getAllLabelColumns(ctx.resultPool);\n if (!allLabelColumns) return undefined;\n\n let fullLabelColumns = getMatchingLabelColumns(columns.map(getColumnIdAndSpec), allLabelColumns);\n fullLabelColumns = deriveLabels(fullLabelColumns, identity, { includeNativeLabel: true }).map(\n (v) => {\n return {\n ...v.value,\n spec: {\n ...v.value.spec,\n annotations: {\n ...v.value.spec.annotations,\n [Annotation.Label]: v.label,\n },\n },\n };\n },\n );\n\n const fullColumns = [...columns, ...fullLabelColumns];\n\n const fullColumnsAxes = uniqueBy(\n fullColumns.flatMap((c) => c.spec.axesSpec.map((a) => getAxisId(a))),\n (a) => canonicalizeJson<AxisId>(a),\n );\n const fullColumnsIds: PTableColumnId[] = [\n ...fullColumnsAxes.map((a) => ({ type: \"axis\", id: a }) satisfies PTableColumnIdAxis),\n ...fullColumns.map((c) => ({ type: \"column\", id: c.id }) satisfies PTableColumnIdColumn),\n ];\n const fullColumnsIdsSet = new Set(fullColumnsIds.map((c) => canonicalizeJson<PTableColumnId>(c)));\n const isValidColumnId = (id: string): boolean =>\n fullColumnsIdsSet.has(id as CanonicalizedJson<PTableColumnId>);\n\n // -- Filtering validation --\n const stateFilters = tableStateNormalized.pTableParams.filters;\n const opsFilters = ops?.filters ?? null;\n const filters: null | PlDataTableFilters =\n stateFilters != null && opsFilters != null\n ? { type: \"and\", filters: [stateFilters, opsFilters] }\n : (stateFilters ?? opsFilters);\n const filterColumns = filters ? collectFilterSpecColumns(filters) : [];\n const firstInvalidFilterColumn = filterColumns.find((col) => !isValidColumnId(col));\n if (firstInvalidFilterColumn)\n throw new Error(\n `Invalid filter column ${firstInvalidFilterColumn}: column reference does not match the table columns`,\n );\n\n // -- Sorting validation --\n const userSorting = tableStateNormalized.pTableParams.sorting;\n const sorting = (isEmpty(userSorting) ? ops?.sorting : userSorting) ?? [];\n const firstInvalidSortingColumn = sorting.find(\n (s) => !isValidColumnId(canonicalizeJson<PTableColumnId>(s.column)),\n );\n if (firstInvalidSortingColumn)\n throw new Error(\n `Invalid sorting column ${JSON.stringify(firstInvalidSortingColumn.column)}: column reference does not match the table columns`,\n );\n\n const coreJoinType = ops?.coreJoinType ?? \"full\";\n const fullDef = createPTableDef({\n columns,\n labelColumns: fullLabelColumns,\n coreJoinType,\n filters,\n sorting,\n coreColumnPredicate: ops?.coreColumnPredicate,\n });\n\n const fullHandle = ctx.createPTableV2(fullDef);\n const pframeHandle = ctx.createPFrame(fullColumns);\n if (!fullHandle || !pframeHandle) return undefined;\n\n const hiddenColumns = new Set<PObjectId>(\n ((): PObjectId[] => {\n // Inner join works as a filter - all columns must be present\n if (coreJoinType === \"inner\") return [];\n\n const hiddenColIds = tableStateNormalized.pTableParams.hiddenColIds;\n if (hiddenColIds) return hiddenColIds;\n\n return columns.filter((c) => isColumnOptional(c.spec)).map((c) => c.id);\n })(),\n );\n\n // Preserve linker columns\n columns.filter((c) => isLinkerColumn(c.spec)).forEach((c) => hiddenColumns.delete(c.id));\n\n // Preserve core columns as they change the shape of join.\n const coreColumnPredicate = ops?.coreColumnPredicate;\n if (coreColumnPredicate) {\n const coreColumns = columns.flatMap((c) =>\n coreColumnPredicate(getColumnIdAndSpec(c)) ? [c.id] : [],\n );\n coreColumns.forEach((c) => hiddenColumns.delete(c));\n }\n\n // Preserve sorted columns from being hidden\n sorting\n .map((s) => s.column)\n .filter((c): c is PTableColumnIdColumn => c.type === \"column\")\n .forEach((c) => hiddenColumns.delete(c.id));\n\n // Preserve filter columns from being hidden\n if (filters) {\n collectFilterSpecColumns(filters)\n .flatMap((c) => {\n const obj = parseJson(c);\n return obj.type === \"column\" ? [obj.id] : [];\n })\n .forEach((c) => hiddenColumns.delete(c));\n }\n\n const visibleColumns = columns.filter((c) => !hiddenColumns.has(c.id));\n const visibleLabelColumns = getMatchingLabelColumns(\n visibleColumns.map(getColumnIdAndSpec),\n allLabelColumns,\n );\n\n // if at least one column is not yet computed, we can't show the table\n if (!allPColumnsReady([...visibleColumns, ...visibleLabelColumns])) return undefined;\n\n const visibleDef = createPTableDef({\n columns: visibleColumns,\n labelColumns: visibleLabelColumns,\n coreJoinType,\n filters,\n sorting,\n coreColumnPredicate,\n });\n const visibleHandle = ctx.createPTableV2(visibleDef);\n\n if (!visibleHandle) return undefined;\n\n return {\n sourceId: tableStateNormalized.pTableParams.sourceId,\n fullTableHandle: fullHandle,\n fullPframeHandle: pframeHandle,\n visibleTableHandle: visibleHandle,\n } satisfies PlDataTableModel;\n}\n\n/** Create sheet entries for PlDataTable */\nexport function createPlDataTableSheet<A, U>(\n ctx: RenderCtxBase<A, U>,\n axis: AxisSpec,\n values: (string | number)[],\n): PlDataTableSheet {\n const labels = ctx.resultPool.findLabels(axis);\n return {\n axis,\n options: values.map((v) => ({\n value: v,\n label: labels?.[v] ?? v.toString(),\n })),\n defaultValue: values[0],\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { PColumnDataUniversal } from "../../render/internal.js";
|
|
2
|
-
import { RenderCtxBase } from "../../render/api.js";
|
|
3
|
-
import "../../render/index.js";
|
|
4
|
-
import { CreatePlDataTableOps, PlDataTableModel, PlDataTableSheet } from "./v5.js";
|
|
5
|
-
import { PlDataTableStateV2 } from "./state-migration.js";
|
|
6
|
-
import { Annotation, AxisSpec, PColumn } from "@milaboratories/pl-model-common";
|
|
7
|
-
|
|
8
|
-
//#region src/components/PlDataTable/table.d.ts
|
|
9
|
-
/** Check if column should be omitted from the table */
|
|
10
|
-
declare function isColumnHidden(spec: {
|
|
11
|
-
annotations?: Annotation;
|
|
12
|
-
}): boolean;
|
|
13
|
-
/** Check if column is hidden by default */
|
|
14
|
-
declare function isColumnOptional(spec: {
|
|
15
|
-
annotations?: Annotation;
|
|
16
|
-
}): boolean;
|
|
17
|
-
/**
|
|
18
|
-
* Create p-table spec and handle given ui table state
|
|
19
|
-
*
|
|
20
|
-
* @param ctx context
|
|
21
|
-
* @param columns column list
|
|
22
|
-
* @param tableState table ui state
|
|
23
|
-
* @returns PlAgDataTableV2 table source
|
|
24
|
-
*/
|
|
25
|
-
declare function createPlDataTableV2<A, U>(ctx: RenderCtxBase<A, U>, columns: PColumn<PColumnDataUniversal>[], tableState: PlDataTableStateV2 | undefined, ops?: CreatePlDataTableOps): PlDataTableModel | undefined;
|
|
26
|
-
/** Create sheet entries for PlDataTable */
|
|
27
|
-
declare function createPlDataTableSheet<A, U>(ctx: RenderCtxBase<A, U>, axis: AxisSpec, values: (string | number)[]): PlDataTableSheet;
|
|
28
|
-
//#endregion
|
|
29
|
-
export { createPlDataTableSheet, createPlDataTableV2, isColumnHidden, isColumnOptional };
|
|
30
|
-
//# sourceMappingURL=table.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"table.js","names":[],"sources":["../../../src/components/PlDataTable/table.ts"],"sourcesContent":["import type {\n AxisId,\n AxisSpec,\n DataInfo,\n PColumn,\n PColumnIdAndSpec,\n PColumnValues,\n PObjectId,\n PTableColumnId,\n PTableColumnIdAxis,\n PTableColumnIdColumn,\n PTableDefV2,\n PTableSorting,\n SpecQuery,\n SingleAxisSelector,\n SpecQueryExpression,\n SpecQueryJoinEntry,\n CanonicalizedJson,\n} from \"@milaboratories/pl-model-common\";\nimport {\n Annotation,\n canonicalizeJson,\n getAxisId,\n getColumnIdAndSpec,\n isLinkerColumn,\n readAnnotation,\n uniqueBy,\n isBooleanExpression,\n parseJson,\n} from \"@milaboratories/pl-model-common\";\nimport { filterSpecToSpecQueryExpr } from \"../../filters\";\nimport type { RenderCtxBase, TreeNodeAccessor, PColumnDataUniversal } from \"../../render\";\nimport { allPColumnsReady, deriveLabels } from \"../../render\";\nimport { identity, isFunction, isNil } from \"es-toolkit\";\nimport { distillFilterSpec } from \"../../filters/distill\";\nimport type { CreatePlDataTableOps, PlDataTableFilters, PlDataTableModel } from \"./v5\";\nimport { upgradePlDataTableStateV2 } from \"./state-migration\";\nimport type { PlDataTableStateV2 } from \"./state-migration\";\nimport type { PlDataTableSheet } from \"./v5\";\nimport { getAllLabelColumns, getMatchingLabelColumns } from \"./labels\";\nimport { collectFilterSpecColumns } from \"../../filters/traverse\";\nimport { isEmpty } from \"es-toolkit/compat\";\n\n/** Convert a PTableColumnId to a SpecQueryExpression reference. */\nfunction columnIdToExpr(col: PTableColumnId): SpecQueryExpression {\n if (col.type === \"axis\") {\n return { type: \"axisRef\", value: col.id as SingleAxisSelector };\n }\n return { type: \"columnRef\", value: col.id };\n}\n\n/** Wrap a SpecQuery as a SpecQueryJoinEntry with empty qualifications. */\nfunction joinEntry<C>(input: SpecQuery<C>): SpecQueryJoinEntry<C> {\n return { entry: input, qualifications: [] };\n}\n\nfunction createPTableDef(params: {\n columns: PColumn<PColumnDataUniversal>[];\n labelColumns: PColumn<PColumnDataUniversal>[];\n coreJoinType: \"inner\" | \"full\";\n filters: null | PlDataTableFilters;\n sorting: PTableSorting[];\n coreColumnPredicate?: (spec: PColumnIdAndSpec) => boolean;\n}): PTableDefV2<PColumn<TreeNodeAccessor | PColumnValues | DataInfo<TreeNodeAccessor>>> {\n let coreColumns = params.columns;\n const secondaryColumns: typeof params.columns = [];\n\n if (isFunction(params.coreColumnPredicate)) {\n coreColumns = [];\n for (const c of params.columns)\n if (params.coreColumnPredicate(getColumnIdAndSpec(c))) coreColumns.push(c);\n else secondaryColumns.push(c);\n }\n\n secondaryColumns.push(...params.labelColumns);\n\n // Build SpecQuery directly from columns\n const coreJoinQuery: SpecQuery<\n PColumn<TreeNodeAccessor | PColumnValues | DataInfo<TreeNodeAccessor>>\n > = {\n type: params.coreJoinType === \"inner\" ? \"innerJoin\" : \"fullJoin\",\n entries: coreColumns.map((c) => joinEntry({ type: \"column\", column: c })),\n };\n\n let query: SpecQuery<PColumn<TreeNodeAccessor | PColumnValues | DataInfo<TreeNodeAccessor>>> = {\n type: \"outerJoin\",\n primary: joinEntry(coreJoinQuery),\n secondary: secondaryColumns.map((c) => joinEntry({ type: \"column\", column: c })),\n };\n\n // Apply filters\n if (params.filters !== null) {\n const nonEmpty = distillFilterSpec(params.filters);\n\n if (!isNil(nonEmpty)) {\n const pridicate = filterSpecToSpecQueryExpr(nonEmpty);\n if (!isBooleanExpression(pridicate)) {\n throw new Error(\n `Filter conversion produced a non-boolean expression (got type \"${pridicate.type}\"), expected a boolean predicate for query filtering`,\n );\n }\n query = {\n type: \"filter\",\n input: query,\n predicate: pridicate,\n };\n }\n }\n\n // Apply sorting\n if (params.sorting.length > 0) {\n query = {\n type: \"sort\",\n input: query,\n sortBy: params.sorting.map((s) => ({\n expression: columnIdToExpr(s.column),\n ascending: s.ascending,\n nullsFirst: !s.naAndAbsentAreLeastValues,\n })),\n };\n }\n\n return { query };\n}\n\n/** Check if column should be omitted from the table */\nexport function isColumnHidden(spec: { annotations?: Annotation }): boolean {\n return readAnnotation(spec, Annotation.Table.Visibility) === \"hidden\";\n}\n\n/** Check if column is hidden by default */\nexport function isColumnOptional(spec: { annotations?: Annotation }): boolean {\n return readAnnotation(spec, Annotation.Table.Visibility) === \"optional\";\n}\n\n/**\n * Create p-table spec and handle given ui table state\n *\n * @param ctx context\n * @param columns column list\n * @param tableState table ui state\n * @returns PlAgDataTableV2 table source\n */\nexport function createPlDataTableV2<A, U>(\n ctx: RenderCtxBase<A, U>,\n columns: PColumn<PColumnDataUniversal>[],\n tableState: PlDataTableStateV2 | undefined,\n ops?: CreatePlDataTableOps,\n): PlDataTableModel | undefined {\n if (columns.length === 0) return undefined;\n\n const tableStateNormalized = upgradePlDataTableStateV2(tableState);\n\n const allLabelColumns = getAllLabelColumns(ctx.resultPool);\n if (!allLabelColumns) return undefined;\n\n let fullLabelColumns = getMatchingLabelColumns(columns.map(getColumnIdAndSpec), allLabelColumns);\n fullLabelColumns = deriveLabels(fullLabelColumns, identity, { includeNativeLabel: true }).map(\n (v) => {\n return {\n ...v.value,\n spec: {\n ...v.value.spec,\n annotations: {\n ...v.value.spec.annotations,\n [Annotation.Label]: v.label,\n },\n },\n };\n },\n );\n\n const fullColumns = [...columns, ...fullLabelColumns];\n\n const fullColumnsAxes = uniqueBy(\n fullColumns.flatMap((c) => c.spec.axesSpec.map((a) => getAxisId(a))),\n (a) => canonicalizeJson<AxisId>(a),\n );\n const fullColumnsIds: PTableColumnId[] = [\n ...fullColumnsAxes.map((a) => ({ type: \"axis\", id: a }) satisfies PTableColumnIdAxis),\n ...fullColumns.map((c) => ({ type: \"column\", id: c.id }) satisfies PTableColumnIdColumn),\n ];\n const fullColumnsIdsSet = new Set(fullColumnsIds.map((c) => canonicalizeJson<PTableColumnId>(c)));\n const isValidColumnId = (id: string): boolean =>\n fullColumnsIdsSet.has(id as CanonicalizedJson<PTableColumnId>);\n\n // -- Filtering validation --\n const stateFilters = tableStateNormalized.pTableParams.filters;\n const opsFilters = ops?.filters ?? null;\n const filters: null | PlDataTableFilters =\n stateFilters != null && opsFilters != null\n ? { type: \"and\", filters: [stateFilters, opsFilters] }\n : (stateFilters ?? opsFilters);\n const filterColumns = filters ? collectFilterSpecColumns(filters) : [];\n const firstInvalidFilterColumn = filterColumns.find((col) => !isValidColumnId(col));\n if (firstInvalidFilterColumn)\n throw new Error(\n `Invalid filter column ${firstInvalidFilterColumn}: column reference does not match the table columns`,\n );\n\n // -- Sorting validation --\n const userSorting = tableStateNormalized.pTableParams.sorting;\n const sorting = (isEmpty(userSorting) ? ops?.sorting : userSorting) ?? [];\n const firstInvalidSortingColumn = sorting.find(\n (s) => !isValidColumnId(canonicalizeJson<PTableColumnId>(s.column)),\n );\n if (firstInvalidSortingColumn)\n throw new Error(\n `Invalid sorting column ${JSON.stringify(firstInvalidSortingColumn.column)}: column reference does not match the table columns`,\n );\n\n const coreJoinType = ops?.coreJoinType ?? \"full\";\n const fullDef = createPTableDef({\n columns,\n labelColumns: fullLabelColumns,\n coreJoinType,\n filters,\n sorting,\n coreColumnPredicate: ops?.coreColumnPredicate,\n });\n\n const fullHandle = ctx.createPTableV2(fullDef);\n const pframeHandle = ctx.createPFrame(fullColumns);\n if (!fullHandle || !pframeHandle) return undefined;\n\n const hiddenColumns = new Set<PObjectId>(\n ((): PObjectId[] => {\n // Inner join works as a filter - all columns must be present\n if (coreJoinType === \"inner\") return [];\n\n const hiddenColIds = tableStateNormalized.pTableParams.hiddenColIds;\n if (hiddenColIds) return hiddenColIds;\n\n return columns.filter((c) => isColumnOptional(c.spec)).map((c) => c.id);\n })(),\n );\n\n // Preserve linker columns\n columns.filter((c) => isLinkerColumn(c.spec)).forEach((c) => hiddenColumns.delete(c.id));\n\n // Preserve core columns as they change the shape of join.\n const coreColumnPredicate = ops?.coreColumnPredicate;\n if (coreColumnPredicate) {\n const coreColumns = columns.flatMap((c) =>\n coreColumnPredicate(getColumnIdAndSpec(c)) ? [c.id] : [],\n );\n coreColumns.forEach((c) => hiddenColumns.delete(c));\n }\n\n // Preserve sorted columns from being hidden\n sorting\n .map((s) => s.column)\n .filter((c): c is PTableColumnIdColumn => c.type === \"column\")\n .forEach((c) => hiddenColumns.delete(c.id));\n\n // Preserve filter columns from being hidden\n if (filters) {\n collectFilterSpecColumns(filters)\n .flatMap((c) => {\n const obj = parseJson(c);\n return obj.type === \"column\" ? [obj.id] : [];\n })\n .forEach((c) => hiddenColumns.delete(c));\n }\n\n const visibleColumns = columns.filter((c) => !hiddenColumns.has(c.id));\n const visibleLabelColumns = getMatchingLabelColumns(\n visibleColumns.map(getColumnIdAndSpec),\n allLabelColumns,\n );\n\n // if at least one column is not yet computed, we can't show the table\n if (!allPColumnsReady([...visibleColumns, ...visibleLabelColumns])) return undefined;\n\n const visibleDef = createPTableDef({\n columns: visibleColumns,\n labelColumns: visibleLabelColumns,\n coreJoinType,\n filters,\n sorting,\n coreColumnPredicate,\n });\n const visibleHandle = ctx.createPTableV2(visibleDef);\n\n if (!visibleHandle) return undefined;\n\n return {\n sourceId: tableStateNormalized.pTableParams.sourceId,\n fullTableHandle: fullHandle,\n fullPframeHandle: pframeHandle,\n visibleTableHandle: visibleHandle,\n } satisfies PlDataTableModel;\n}\n\n/** Create sheet entries for PlDataTable */\nexport function createPlDataTableSheet<A, U>(\n ctx: RenderCtxBase<A, U>,\n axis: AxisSpec,\n values: (string | number)[],\n): PlDataTableSheet {\n const labels = ctx.resultPool.findLabels(axis);\n return {\n axis,\n options: values.map((v) => ({\n value: v,\n label: labels?.[v] ?? v.toString(),\n })),\n defaultValue: values[0],\n };\n}\n"],"mappings":"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"}
|
|
File without changes
|
|
File without changes
|