@object-ui/core 17.5.0 → 17.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7404 -0
- package/README.md +127 -26
- package/dist/actions/ActionEngine.d.ts +5 -3
- package/dist/actions/ActionEngine.js +14 -10
- package/dist/actions/ActionRunner.d.ts +363 -30
- package/dist/actions/ActionRunner.js +544 -58
- package/dist/actions/TransactionManager.d.ts +7 -2
- package/dist/actions/actionKeys.d.ts +75 -13
- package/dist/actions/actionKeys.js +131 -16
- package/dist/actions/actionResponse.js +3 -3
- package/dist/actions/index.d.ts +2 -0
- package/dist/actions/index.js +2 -0
- package/dist/actions/recordDelete.d.ts +118 -0
- package/dist/actions/recordDelete.js +112 -0
- package/dist/actions/recordIdParam.d.ts +77 -0
- package/dist/actions/recordIdParam.js +37 -0
- package/dist/actions/serverActionHandler.d.ts +1 -1
- package/dist/actions/serverActionHandler.js +1 -1
- package/dist/adapters/ValueDataSource.d.ts +6 -1
- package/dist/adapters/ValueDataSource.js +1090 -98
- package/dist/adapters/batchTransaction.d.ts +1 -1
- package/dist/adapters/batchTransaction.js +1 -1
- package/dist/builder/schema-builder.d.ts +38 -81
- package/dist/builder/schema-builder.js +33 -152
- package/dist/data-scope/ViewDataProvider.d.ts +1 -1
- package/dist/data-scope/ViewDataProvider.js +21 -1
- package/dist/data-scope/element-data-source.d.ts +261 -7
- package/dist/data-scope/element-data-source.js +342 -52
- package/dist/data-scope/index.d.ts +9 -4
- package/dist/data-scope/index.js +9 -4
- package/dist/evaluator/ExpressionEvaluator.d.ts +128 -1
- package/dist/evaluator/ExpressionEvaluator.js +226 -13
- package/dist/evaluator/FormulaFunctions.d.ts +0 -10
- package/dist/evaluator/FormulaFunctions.js +166 -27
- package/dist/evaluator/SafeExpressionParser.js +0 -4
- package/dist/evaluator/declaredPredicate.d.ts +93 -9
- package/dist/evaluator/declaredPredicate.js +118 -17
- package/dist/evaluator/fieldRules.d.ts +107 -4
- package/dist/evaluator/fieldRules.js +231 -35
- package/dist/evaluator/index.d.ts +2 -0
- package/dist/evaluator/index.js +2 -0
- package/dist/evaluator/listConditional.d.ts +125 -9
- package/dist/evaluator/listConditional.js +167 -26
- package/dist/evaluator/optionRules.d.ts +126 -0
- package/dist/evaluator/optionRules.js +141 -4
- package/dist/evaluator/predicateInput.d.ts +15 -4
- package/dist/evaluator/predicateInput.js +35 -2
- package/dist/evaluator/rowPredicateCanon.d.ts +56 -0
- package/dist/evaluator/rowPredicateCanon.js +158 -0
- package/dist/evaluator/subjectPermissions.d.ts +76 -0
- package/dist/evaluator/subjectPermissions.js +44 -0
- package/dist/evaluator/unevaluablePredicate.d.ts +57 -0
- package/dist/evaluator/unevaluablePredicate.js +70 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +97 -2
- package/dist/protocols/index.d.ts +0 -1
- package/dist/protocols/index.js +9 -1
- package/dist/registry/Registry.d.ts +397 -48
- package/dist/registry/Registry.js +263 -11
- package/dist/registry/WidgetRegistry.js +7 -3
- package/dist/registry/html-tier-intrinsics.d.ts +90 -0
- package/dist/registry/html-tier-intrinsics.js +110 -0
- package/dist/registry/public-blocks.d.ts +8 -0
- package/dist/registry/public-blocks.js +57 -0
- package/dist/theme/ThemeEngine.js +1 -1
- package/dist/theme/index.d.ts +1 -1
- package/dist/theme/index.js +1 -1
- package/dist/types/index.d.ts +92 -13
- package/dist/utils/chart-category-key.d.ts +82 -0
- package/dist/utils/chart-category-key.js +84 -0
- package/dist/utils/chart-measure-key.d.ts +64 -0
- package/dist/utils/chart-measure-key.js +65 -0
- package/dist/utils/chart-presentation.d.ts +188 -0
- package/dist/utils/chart-presentation.js +345 -0
- package/dist/utils/chart-series.d.ts +271 -31
- package/dist/utils/chart-series.js +478 -55
- package/dist/utils/column-identity.d.ts +43 -0
- package/dist/utils/column-identity.js +47 -1
- package/dist/utils/column-sortability.d.ts +157 -0
- package/dist/utils/column-sortability.js +217 -0
- package/dist/utils/dashboard-filters.d.ts +38 -6
- package/dist/utils/dashboard-filters.js +107 -61
- package/dist/utils/dataset-format.d.ts +211 -30
- package/dist/utils/dataset-format.js +407 -52
- package/dist/utils/date-display.d.ts +354 -0
- package/dist/utils/date-display.js +463 -0
- package/dist/utils/date-macros.js +7 -0
- package/dist/utils/debug.js +7 -0
- package/dist/utils/drill-down.d.ts +78 -0
- package/dist/utils/drill-down.js +93 -0
- package/dist/utils/emptiness.d.ts +96 -0
- package/dist/utils/emptiness.js +101 -0
- package/dist/utils/expand-fields.d.ts +171 -11
- package/dist/utils/expand-fields.js +171 -11
- package/dist/utils/extract-records.d.ts +65 -5
- package/dist/utils/extract-records.js +65 -8
- package/dist/utils/filter-converter.d.ts +152 -4
- package/dist/utils/filter-converter.js +1092 -22
- package/dist/utils/filter-tokens.d.ts +49 -5
- package/dist/utils/filter-tokens.js +105 -34
- package/dist/utils/freeze-schema.d.ts +38 -1
- package/dist/utils/freeze-schema.js +10 -0
- package/dist/utils/grouping-fields.d.ts +61 -0
- package/dist/utils/grouping-fields.js +84 -0
- package/dist/utils/humanize-label.d.ts +60 -0
- package/dist/utils/humanize-label.js +62 -0
- package/dist/utils/managedBy.d.ts +30 -5
- package/dist/utils/managedBy.js +5 -5
- package/dist/utils/native-date-value.d.ts +48 -0
- package/dist/utils/native-date-value.js +167 -0
- package/dist/utils/non-grid-row-ceiling.d.ts +143 -0
- package/dist/utils/non-grid-row-ceiling.js +141 -0
- package/dist/utils/normalize-list-view.d.ts +131 -1
- package/dist/utils/normalize-list-view.js +248 -6
- package/dist/utils/number-display.d.ts +70 -17
- package/dist/utils/number-display.js +34 -12
- package/dist/utils/object-aggregate-query.d.ts +113 -0
- package/dist/utils/object-aggregate-query.js +50 -0
- package/dist/utils/parent-scope.d.ts +123 -0
- package/dist/utils/parent-scope.js +140 -0
- package/dist/utils/predicate-fields.d.ts +62 -4
- package/dist/utils/predicate-fields.js +169 -4
- package/dist/utils/record-color.d.ts +75 -0
- package/dist/utils/record-color.js +65 -0
- package/dist/utils/record-source.d.ts +298 -0
- package/dist/utils/record-source.js +331 -0
- package/dist/utils/record-title.d.ts +148 -8
- package/dist/utils/record-title.js +220 -26
- package/dist/utils/reference-keys.d.ts +21 -22
- package/dist/utils/reference-keys.js +532 -29
- package/dist/utils/retired-field-types.d.ts +90 -0
- package/dist/utils/retired-field-types.js +124 -0
- package/dist/utils/sort-query.d.ts +128 -26
- package/dist/utils/sort-query.js +240 -13
- package/dist/utils/text-comparand.d.ts +92 -0
- package/dist/utils/text-comparand.js +99 -0
- package/dist/utils/unmaterialized-fields.d.ts +52 -0
- package/dist/utils/unmaterialized-fields.js +57 -0
- package/dist/utils/without-denied-fields.d.ts +49 -0
- package/dist/utils/without-denied-fields.js +52 -0
- package/dist/validation/index.d.ts +9 -4
- package/dist/validation/index.js +9 -4
- package/dist/validation/schema-validator.d.ts +1 -1
- package/dist/validation/schema-validator.js +305 -82
- package/dist/validation/server-owned-value.d.ts +62 -0
- package/dist/validation/server-owned-value.js +99 -0
- package/dist/validation/validators/object-validation-engine.d.ts +1 -1
- package/dist/validation/validators/object-validation-engine.js +14 -5
- package/package.json +8 -9
- package/dist/__benchmarks__/core.bench.d.ts +0 -8
- package/dist/__benchmarks__/core.bench.js +0 -53
- package/dist/data-scope/DataScopeManager.d.ts +0 -127
- package/dist/data-scope/DataScopeManager.js +0 -229
- package/dist/protocols/ResponsiveProtocol.d.ts +0 -73
- package/dist/protocols/ResponsiveProtocol.js +0 -158
- package/dist/validation/validation-engine.d.ts +0 -88
- package/dist/validation/validation-engine.js +0 -434
|
@@ -5,32 +5,42 @@
|
|
|
5
5
|
* This source code is licensed under the MIT license found in the
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
|
-
/**
|
|
9
|
-
* chart-series — shape a semantic-layer `queryDataset` result into the
|
|
10
|
-
* `{ data, xAxisKey, series }` triple a chart renderer consumes (ADR-0021, #1759).
|
|
11
|
-
*
|
|
12
|
-
* Shared by `ObjectChart` (plugin-charts) and `DatasetWidget` (plugin-dashboard)
|
|
13
|
-
* so multi-dimension charts visualise identically across surfaces.
|
|
14
|
-
*
|
|
15
|
-
* Rules:
|
|
16
|
-
* - **2+ dimensions, single measure** → pivot the SECOND dimension into one
|
|
17
|
-
* series per distinct value (grouped/coloured bars). `xAxisKey` = first
|
|
18
|
-
* dimension; each output row is one first-dimension bucket with a column per
|
|
19
|
-
* second-dimension value holding the measure. This makes the second dimension
|
|
20
|
-
* visible instead of just repeating the x-axis label.
|
|
21
|
-
* - **otherwise** (single dimension, or multiple measures) → first dimension is
|
|
22
|
-
* the x-axis and each measure is its own series (long format passes through).
|
|
23
|
-
*
|
|
24
|
-
* BOTH branches map a NULL first-dimension VALUE to an explicit bucket label
|
|
25
|
-
* ({@link NULL_CATEGORY_LABEL}) so the group renders instead of vanishing —
|
|
26
|
-
* objectui#4466 for the single-dimension branch, objectui#4497 for the pivot.
|
|
27
|
-
* One doctrine, one predicate (`isNullCategory`), two call sites.
|
|
28
|
-
*/
|
|
29
8
|
export interface ChartResultField {
|
|
30
9
|
name: string;
|
|
31
10
|
label?: string;
|
|
32
11
|
format?: string;
|
|
33
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* The OPTIONAL wire discriminator naming which server-side BUILT-IN default
|
|
15
|
+
* measure a result column is (objectui#7258; producer half objectstack#14492).
|
|
16
|
+
* The analytics service sets it ONLY on the measures it minted itself with a
|
|
17
|
+
* hard-coded English default label (`count` → `'Count'`, …); an author-declared
|
|
18
|
+
* measure never carries it, so its `label` stays the author's verbatim text
|
|
19
|
+
* (objectui#4106). {@link resolveMeasureLabel} is the one reader.
|
|
20
|
+
*
|
|
21
|
+
* Declared BESIDE {@link ChartResultField} rather than on it, deliberately:
|
|
22
|
+
* `dataset-result-field-spec-parity` pins every key of `ChartResultField` as a
|
|
23
|
+
* key of the spec's `AnalyticsResult.fields[]`, and the `@objectstack/spec`
|
|
24
|
+
* this package is built against does not carry `builtinAggregate` yet. The
|
|
25
|
+
* intersection {@link ChartMeasureField} is what the helpers accept, so a
|
|
26
|
+
* spec-typed field flows in unchanged today and carries the key the moment
|
|
27
|
+
* the spec does — structurally, with no cast at the call sites.
|
|
28
|
+
*
|
|
29
|
+
* Typed as `string` rather than the closed {@link BuiltinAggregate} union on
|
|
30
|
+
* purpose: a JSON response is handed here as-is, so the value is validated at
|
|
31
|
+
* the lookup ({@link isBuiltinAggregate}) instead of trusted at the type.
|
|
32
|
+
*
|
|
33
|
+
* TODO(objectstack#14492): once the spec dependency is bumped past the release
|
|
34
|
+
* that adds `AnalyticsResult.fields[].builtinAggregate`, fold this key into
|
|
35
|
+
* `ChartResultField` as `DatasetResultField['builtinAggregate']` (pinning the
|
|
36
|
+
* two closed vocabularies to each other in the parity suite) and retire the
|
|
37
|
+
* carrier.
|
|
38
|
+
*/
|
|
39
|
+
export interface BuiltinAggregateCarrier {
|
|
40
|
+
builtinAggregate?: string;
|
|
41
|
+
}
|
|
42
|
+
/** A result field as the series helpers read it: the renderer shape plus the optional discriminator. */
|
|
43
|
+
export type ChartMeasureField = ChartResultField & BuiltinAggregateCarrier;
|
|
34
44
|
/**
|
|
35
45
|
* One renderer-internal series binding produced by {@link buildChartSeries}:
|
|
36
46
|
* WHICH result-set column to draw and what to call it.
|
|
@@ -52,6 +62,47 @@ export interface ChartSeriesResult {
|
|
|
52
62
|
xAxisKey: string | undefined;
|
|
53
63
|
series: ChartSeriesBinding[];
|
|
54
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* The closed vocabulary of server-side built-in default measures a result field
|
|
67
|
+
* can declare itself as (objectui#7258 / objectstack#14492) — the spec's own
|
|
68
|
+
* measure-aggregate enum spelling (`count_distinct`, not `countDistinct`), so
|
|
69
|
+
* there is exactly ONE spelling on the wire and this list never grows on its
|
|
70
|
+
* own: a value outside it is not "a new aggregate", it is an unrecognised one,
|
|
71
|
+
* and {@link resolveMeasureLabel} treats it as absent.
|
|
72
|
+
*/
|
|
73
|
+
export declare const BUILTIN_AGGREGATES: readonly ["count", "sum", "avg", "min", "max", "count_distinct"];
|
|
74
|
+
/** One member of {@link BUILTIN_AGGREGATES}. */
|
|
75
|
+
export type BuiltinAggregate = (typeof BUILTIN_AGGREGATES)[number];
|
|
76
|
+
/** Runtime membership test for {@link BUILTIN_AGGREGATES}, over an untrusted wire value. */
|
|
77
|
+
export declare function isBuiltinAggregate(value: unknown): value is BuiltinAggregate;
|
|
78
|
+
/**
|
|
79
|
+
* The LOCALIZED display label per built-in aggregate, as the layer that holds
|
|
80
|
+
* the i18n provider resolved them (`@object-ui/i18n`'s
|
|
81
|
+
* `builtinAggregateLabels(tt)`). Partial on purpose: an aggregate the caller
|
|
82
|
+
* did not resolve falls back to the wire `label`, exactly as if the field had
|
|
83
|
+
* carried no discriminator.
|
|
84
|
+
*/
|
|
85
|
+
export type BuiltinAggregateLabels = Partial<Record<BuiltinAggregate, string>>;
|
|
86
|
+
/**
|
|
87
|
+
* The display label of ONE result field, for a legend / axis / tooltip.
|
|
88
|
+
*
|
|
89
|
+
* Resolution order (objectui#7258, maintainer ruling B of 2026-09-02):
|
|
90
|
+
* 1. the field declares itself a built-in default measure
|
|
91
|
+
* (`builtinAggregate` ∈ {@link BUILTIN_AGGREGATES}) AND the caller resolved
|
|
92
|
+
* a locale label for it → that label. This is the only path that can
|
|
93
|
+
* replace a wire `label`, and it is keyed by a STRUCTURAL discriminator —
|
|
94
|
+
* never by matching the label's text or the field's name, both of which
|
|
95
|
+
* the ruling rejected (a real author measure literally named `count`, or
|
|
96
|
+
* labelled `Count`, must keep its own label);
|
|
97
|
+
* 2. otherwise the wire `label` verbatim — the objectui#4106 contract for an
|
|
98
|
+
* author-declared measure (`'Tasks'` reaches the legend untouched);
|
|
99
|
+
* 3. otherwise the field's `name`.
|
|
100
|
+
*
|
|
101
|
+
* So a discriminator the caller has no label for (a provider-less host, or a
|
|
102
|
+
* value outside the closed vocabulary) costs nothing: the field renders exactly
|
|
103
|
+
* what it rendered before the discriminator existed.
|
|
104
|
+
*/
|
|
105
|
+
export declare function resolveMeasureLabel(field: ChartMeasureField, labels?: BuiltinAggregateLabels): string;
|
|
55
106
|
/**
|
|
56
107
|
* The bucket a NULL/undefined category VALUE renders under, when the caller
|
|
57
108
|
* supplies no localized label of its own (objectui#4466).
|
|
@@ -69,6 +120,57 @@ export interface ChartSeriesResult {
|
|
|
69
120
|
* clicked bucket bar resolve back to its (raw null) dataset row.
|
|
70
121
|
*/
|
|
71
122
|
export declare const NULL_CATEGORY_LABEL = "(None)";
|
|
123
|
+
/**
|
|
124
|
+
* The IDENTITY of the chart bucket a first-dimension raw value falls in —
|
|
125
|
+
* distinct from the string that bucket DISPLAYS (objectui#4508).
|
|
126
|
+
*
|
|
127
|
+
* Deliberately the SAME encoder the pivot TABLE already keys its buckets with
|
|
128
|
+
* (`pivotBucketId` over a `pivotDimensionValue`-normalized value), because the
|
|
129
|
+
* two surfaces answer the same question about the same dataset rows and were
|
|
130
|
+
* answering it differently: `buildPivot` gives a null dimension value a bucket
|
|
131
|
+
* id no string can spell, while the chart used the display label as its own
|
|
132
|
+
* key. That gap is the whole of objectui#4508 — see `dataset-pivot.ts` for why
|
|
133
|
+
* the encoding is JSON rather than a delimiter or a placeholder character.
|
|
134
|
+
*
|
|
135
|
+
* Two collisions follow from a label-as-key, and one encoder closes both:
|
|
136
|
+
* - `null` and `''` are different groups. `String(x ?? '')` made them one
|
|
137
|
+
* bucket, so two groups drew ONE bar and one of them lost its drill.
|
|
138
|
+
* `[null]` and `[""]` are different ids.
|
|
139
|
+
* - a stored value that literally spells the bucket label (`'(None)'`, or any
|
|
140
|
+
* localized `nullCategoryLabel` — `'(未指定)'` and the other nine packs) is
|
|
141
|
+
* not the null group. `["(None)"]` and `[null]` are different ids, so the
|
|
142
|
+
* click resolves to the rows its own bar was drawn from.
|
|
143
|
+
*/
|
|
144
|
+
export declare function chartBucketId(rawValue: unknown): string;
|
|
145
|
+
/**
|
|
146
|
+
* The key an emitted chart row carries its {@link chartBucketId} under, when it
|
|
147
|
+
* carries one — the "alongside the display label" half of objectui#4508.
|
|
148
|
+
*
|
|
149
|
+
* **Written exactly when the display string does not name one bucket**, i.e.
|
|
150
|
+
* when two or more DISTINCT buckets render the same axis text. That is not a
|
|
151
|
+
* cost-saving heuristic, it is the complete condition: with the reader's
|
|
152
|
+
* matching made exact (see {@link findChartSeriesRow}), a display string that
|
|
153
|
+
* one bucket alone produces already identifies it, and the rows a chart is
|
|
154
|
+
* drawn from are also an authoring-visible surface (`data` on a `chart`
|
|
155
|
+
* schema) that renderer-internal metadata should not appear in for every
|
|
156
|
+
* ordinary chart. Rows that do not carry the category key at all never get one
|
|
157
|
+
* — they have no bucket, and that shape belongs to `hasNoCategoryKey`
|
|
158
|
+
* (framework#4033), not here.
|
|
159
|
+
*
|
|
160
|
+
* Read it with {@link chartRowBucketId} rather than the literal key.
|
|
161
|
+
*/
|
|
162
|
+
export declare const CHART_BUCKET_ID_KEY = "__bucketId";
|
|
163
|
+
/**
|
|
164
|
+
* Read the bucket identity off a row a chart was drawn from, or `undefined`
|
|
165
|
+
* when the row carries none (an unambiguous bucket, or rows a caller built
|
|
166
|
+
* itself rather than through {@link buildChartSeries}).
|
|
167
|
+
*
|
|
168
|
+
* Takes `unknown` because its callers hold a click payload, not a typed row:
|
|
169
|
+
* recharts hands a pie/funnel click a SPREAD COPY of the data item, which is
|
|
170
|
+
* why the identity is an ordinary enumerable property and not a symbol or a
|
|
171
|
+
* non-enumerable one — either of those would silently not survive the copy.
|
|
172
|
+
*/
|
|
173
|
+
export declare function chartRowBucketId(row: unknown): string | undefined;
|
|
72
174
|
/** Per-call knobs shared by {@link buildChartSeries} / {@link findChartSeriesRow}. */
|
|
73
175
|
export interface ChartSeriesOptions {
|
|
74
176
|
/**
|
|
@@ -80,8 +182,81 @@ export interface ChartSeriesOptions {
|
|
|
80
182
|
* it, so a mismatch costs the null bucket its drill-through.
|
|
81
183
|
*/
|
|
82
184
|
nullCategoryLabel?: string;
|
|
185
|
+
/**
|
|
186
|
+
* Locale labels for the server's BUILT-IN default measures, keyed by the
|
|
187
|
+
* wire discriminator a result field carries as `builtinAggregate`
|
|
188
|
+
* (objectui#7258). Same division of labour as `nullCategoryLabel`: this
|
|
189
|
+
* package is React-free and i18n-free, so the renderer that holds the
|
|
190
|
+
* provider resolves the strings (`builtinAggregateLabels(tt)` in
|
|
191
|
+
* `@object-ui/i18n`) and passes them in. Absent ⇒ every measure keeps its
|
|
192
|
+
* wire `label`, which for a built-in default is the server's English.
|
|
193
|
+
*/
|
|
194
|
+
builtinAggregateLabels?: BuiltinAggregateLabels;
|
|
195
|
+
}
|
|
196
|
+
/** Per-CLICK knobs for {@link findChartSeriesRow}, on top of the shared ones. */
|
|
197
|
+
export interface ChartDrillLookupOptions extends ChartSeriesOptions {
|
|
198
|
+
/**
|
|
199
|
+
* The clicked bucket's {@link chartBucketId}, when the renderer could read one
|
|
200
|
+
* off the row the segment was drawn from ({@link chartRowBucketId} over
|
|
201
|
+
* {@link CHART_BUCKET_ID_KEY}) — objectui#4508.
|
|
202
|
+
*
|
|
203
|
+
* Supplied ⇒ AUTHORITATIVE: the lookup matches on identity and ignores
|
|
204
|
+
* `category` entirely, which is what lets two bars painting the same axis
|
|
205
|
+
* text drill to their own rows instead of both resolving to the first.
|
|
206
|
+
* Absent ⇒ the bucket's display string identified it on its own (that is
|
|
207
|
+
* exactly when `buildChartSeries` writes no id), or the rows were not built
|
|
208
|
+
* by `buildChartSeries` at all, and the display match answers.
|
|
209
|
+
*/
|
|
210
|
+
bucketId?: string;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* What a chart renderer hands a drill handler when a segment is clicked.
|
|
214
|
+
*
|
|
215
|
+
* Declared HERE, beside the two helpers that write and read a bucket, rather
|
|
216
|
+
* than re-spelled inline in each of the three packages that pass it along
|
|
217
|
+
* (`AdvancedChartImpl` builds it, `ChartRenderer` and `ObjectChart` forward it,
|
|
218
|
+
* `DatasetWidget` consumes it). It was three inline literals when
|
|
219
|
+
* {@link ChartDrillLookupOptions.bucketId} needed a carrier, and a field added
|
|
220
|
+
* to one of three copies reaches the consumer as `undefined` with nothing red.
|
|
221
|
+
*/
|
|
222
|
+
export interface ChartSegmentClickEvent {
|
|
223
|
+
/** The clicked bucket's axis TEXT — what the user sees on the tick. */
|
|
224
|
+
category?: string;
|
|
225
|
+
/**
|
|
226
|
+
* The clicked bucket's IDENTITY, when its row carried one (objectui#4508).
|
|
227
|
+
* Feed it straight to {@link ChartDrillLookupOptions.bucketId}; it is the
|
|
228
|
+
* only field that survives two buckets painting the same `category`.
|
|
229
|
+
*/
|
|
230
|
+
categoryId?: string;
|
|
231
|
+
/** The clicked series' key — a measure, or a pivoted second-dimension value. */
|
|
232
|
+
series?: string;
|
|
233
|
+
/**
|
|
234
|
+
* The clicked series' DISPLAY LABEL, when the renderer knew one
|
|
235
|
+
* (objectui#4682) — `series[].label` as {@link buildChartSeries} assigned it.
|
|
236
|
+
*
|
|
237
|
+
* {@link ChartSegmentClickEvent.series} stays the LOOKUP key and this never
|
|
238
|
+
* substitutes for it: {@link findChartSeriesRow} resolves a key through the
|
|
239
|
+
* same assignment `buildChartSeries` made, and a label cannot be resolved
|
|
240
|
+
* that way — it is not unique (that is precisely why the colliding groups key
|
|
241
|
+
* by identity instead). This field exists for what a key cannot do: be SHOWN.
|
|
242
|
+
*
|
|
243
|
+
* The two strings are equal for every ordinary group, which is why reading
|
|
244
|
+
* the key as a title went unnoticed. They part company when a group's label
|
|
245
|
+
* cannot name it — objectui#4508's collision on the series axis — and the key
|
|
246
|
+
* becomes an opaque `chartBucketId`. A drawer titled `Backlog / [null]` over
|
|
247
|
+
* a segment the user saw labelled `(None)` reads as broken DATA rather than
|
|
248
|
+
* as a broken title, which is why the label travels with the click rather
|
|
249
|
+
* than being re-derived by the consumer.
|
|
250
|
+
*
|
|
251
|
+
* Absent when the renderer resolved no series, or when the series carries no
|
|
252
|
+
* label distinct from its key; a consumer titles itself from
|
|
253
|
+
* `seriesLabel ?? series` and so is unchanged wherever it is absent.
|
|
254
|
+
*/
|
|
255
|
+
seriesLabel?: string;
|
|
256
|
+
/** The measure value at the click point. */
|
|
257
|
+
value?: number;
|
|
83
258
|
}
|
|
84
|
-
export declare function buildChartSeries(rows: Array<Record<string, unknown>> | null | undefined, dimensions: string[] | null | undefined, values: string[] | null | undefined, fields?:
|
|
259
|
+
export declare function buildChartSeries(rows: Array<Record<string, unknown>> | null | undefined, dimensions: string[] | null | undefined, values: string[] | null | undefined, fields?: ChartMeasureField[] | null, options?: ChartSeriesOptions): ChartSeriesResult;
|
|
85
260
|
/**
|
|
86
261
|
* Resolve select/enum dimension VALUES to display LABELS in chart rows.
|
|
87
262
|
*
|
|
@@ -117,16 +292,37 @@ export declare function relabelDimensions(rows: Array<Record<string, unknown>> |
|
|
|
117
292
|
* BOTH the x-axis dimension (`category`) and the series dimension (`seriesKey`).
|
|
118
293
|
* - **otherwise** → match the x-axis (first) dimension only.
|
|
119
294
|
*
|
|
120
|
-
*
|
|
121
|
-
* surfaces as `category`
|
|
295
|
+
* The x-axis comparison is string-wise on the rows' display values (which is
|
|
296
|
+
* what the chart surfaces as `category`), unless the click carried a bucket
|
|
297
|
+
* IDENTITY — {@link ChartDrillLookupOptions.bucketId} — in which case that is
|
|
298
|
+
* authoritative and the display string is not consulted at all. Returns `-1`
|
|
299
|
+
* when nothing matches.
|
|
300
|
+
*
|
|
301
|
+
* The SERIES comparison is not string-wise at all as of objectui#4673: a series
|
|
302
|
+
* key is a `dataKey` {@link buildChartSeries} assigned, so it is resolved back
|
|
303
|
+
* through the same {@link pivotSeriesBuckets} assignment (same rows, same
|
|
304
|
+
* `nullCategoryLabel`) to the group IDENTITY it names, and rows are matched on
|
|
305
|
+
* that. A null-valued second dimension had no series at all before, so its
|
|
306
|
+
* segment could not be clicked; now it can, and `String(r[gDim] ?? '')` would
|
|
307
|
+
* have answered that click with an empty-string group's rows — the same
|
|
308
|
+
* conflation objectui#4508 removed on the x-axis.
|
|
122
309
|
*
|
|
123
310
|
* The NULL-category bucket {@link buildChartSeries} renders (objectui#4466) is
|
|
124
311
|
* matched back to its row here, and it has to be: the caller passes the rows it
|
|
125
312
|
* charted FROM (still carrying the raw null) while the click event carries the
|
|
126
313
|
* bucket LABEL, so without this the one bar the fix made visible would resolve
|
|
127
314
|
* to `-1` and its drill-through would silently no-op. Pass the same
|
|
128
|
-
* `nullCategoryLabel` both helpers were given.
|
|
129
|
-
*
|
|
315
|
+
* `nullCategoryLabel` both helpers were given.
|
|
316
|
+
*
|
|
317
|
+
* **A null category reads as its bucket LABEL and nothing else** (objectui#4508).
|
|
318
|
+
* It used to read as the label OR the empty string, on the stated grounds that
|
|
319
|
+
* `''` is the drill layer's own spelling of "no group value" — but no producer
|
|
320
|
+
* of this function's `category` argument writes that spelling (the one
|
|
321
|
+
* production caller feeds it a chart click's category, and `computeDrillFilter`
|
|
322
|
+
* is downstream of the drill, not upstream of this lookup), while `''` IS what
|
|
323
|
+
* a genuine empty-string group paints. So the tolerance cost that group its own
|
|
324
|
+
* drill and gave it a null group's records instead — a WRONG click, not a dead
|
|
325
|
+
* one. `''` now means the empty-string group, which is what it says.
|
|
130
326
|
*
|
|
131
327
|
* **`xOf` covers BOTH arms, which is what let objectui#4497 bucket the pivot
|
|
132
328
|
* branch without touching this function.** Worth stating because the reverse
|
|
@@ -140,7 +336,7 @@ export declare function relabelDimensions(rows: Array<Record<string, unknown>> |
|
|
|
140
336
|
* searches still carry their null either way, and `xOf` reads the label back to
|
|
141
337
|
* them in the multi-dimension arm exactly as in the single-dimension one.
|
|
142
338
|
*/
|
|
143
|
-
export declare function findChartSeriesRow(rows: Array<Record<string, unknown>> | null | undefined, dimensions: string[] | null | undefined, values: string[] | null | undefined, category: string | undefined, seriesKey?: string, options?:
|
|
339
|
+
export declare function findChartSeriesRow(rows: Array<Record<string, unknown>> | null | undefined, dimensions: string[] | null | undefined, values: string[] | null | undefined, category: string | undefined, seriesKey?: string, options?: ChartDrillLookupOptions): number;
|
|
144
340
|
/**
|
|
145
341
|
* Build a per-category colour map from a select/lookup field's `options`.
|
|
146
342
|
*
|
|
@@ -248,10 +444,54 @@ export declare function buildDimensionLabelMap(options: unknown, translate?: Opt
|
|
|
248
444
|
* The object a relationship field points at, or `undefined` when the field is
|
|
249
445
|
* not a relationship (or names no target).
|
|
250
446
|
*
|
|
251
|
-
* The target lives under `reference`
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
447
|
+
* The target lives under `reference` — the ONLY spelling read here, and the same
|
|
448
|
+
* canonicalization as the dataset designer's `resolveReferenceTo`, which is
|
|
449
|
+
* narrowed to match in the same pass (objectui#6528). As of objectui#6648 the
|
|
450
|
+
* CARRIER matches too: a bare string and nothing else. The two helpers are one
|
|
451
|
+
* doctrine in two files and must never drift — a divergence recreates the
|
|
452
|
+
* defect one file over.
|
|
453
|
+
*
|
|
454
|
+
* The three legacy spellings this dropped (`reference_to` / `referenceTo` /
|
|
455
|
+
* `reference_to_object`) were censused against every producer, with `reference`
|
|
456
|
+
* itself as the positive control (445 of 565 lookup / master_detail defs in the
|
|
457
|
+
* framework tree; ACCEPTED by `ObjectSchema.safeParse` on spec 17.2.0, which
|
|
458
|
+
* REFUSES all three others BY NAME). No producer emits any of them onto an
|
|
459
|
+
* object metadata document: `reference_to` was then live only on ObjectUI's own
|
|
460
|
+
* view/field schema (a different contract, translated INTO from `reference`;
|
|
461
|
+
* objectui#11070 round 4 moved that contract to `reference` as well),
|
|
462
|
+
* `referenceTo`'s two producers were retired by objectui#6041, and
|
|
463
|
+
* `reference_to_object` occurs nowhere in either tree outside this chain and the
|
|
464
|
+
* test that called it.
|
|
465
|
+
*
|
|
466
|
+
* ⚠ Unlike `resolveReferenceTo`, this helper reads the `GET /meta/object/:name`
|
|
467
|
+
* document DIRECTLY — no `readFields` door strips retired keys on this path. So
|
|
468
|
+
* the narrowing is load-bearing rather than cosmetic: a stored pre-objectui#6041
|
|
469
|
+
* row spelling the target `referenceTo` now resolves to `undefined` here, the
|
|
470
|
+
* walk yields no entry, and the caller keeps the raw value (best-effort by
|
|
471
|
+
* construction — see {@link resolveDimensionFieldMeta}). That is the intended
|
|
472
|
+
* outcome: per AGENTS.md #0.1 such a row is a PRODUCER-side defect, and a
|
|
473
|
+
* lenient consumer here is exactly where it would have stayed hidden. Note
|
|
474
|
+
* `reference` was already HEAD of the old chain, so any doc carrying both is
|
|
475
|
+
* unaffected.
|
|
476
|
+
*
|
|
477
|
+
* The array and `{ object }` CARRIERS this used to accept were censused on the
|
|
478
|
+
* same standard and removed with the same reasoning (objectui#6648).
|
|
479
|
+
* `FieldSchema.reference` is a plain `z.string()`; `ObjectSchema.safeParse`
|
|
480
|
+
* (spec 17.2.0) ACCEPTS `reference: 'crm_account'` and REFUSES both
|
|
481
|
+
* `['crm_account']` and `{ object: 'crm_account' }` as `invalid_type`. A
|
|
482
|
+
* structure-walking, key-position-aware census of both trees found 587
|
|
483
|
+
* bare-string carriers at the field-def key position and ZERO array or
|
|
484
|
+
* `{ object }` carriers from any producer — the only ones in either tree were
|
|
485
|
+
* the green pins asserting this very tolerance. See `resolveReferenceTo` for
|
|
486
|
+
* the full census, including why a multi-target lookup is NOT what the array
|
|
487
|
+
* branch was serving: it returned `raw[0]` and discarded the rest, and
|
|
488
|
+
* polymorphic lookup remains an undeclared, open spec gap.
|
|
489
|
+
*
|
|
490
|
+
* This path matters MORE than the designer's for the same reason the spelling
|
|
491
|
+
* narrowing did: it reads the metadata document directly, with no `readFields`
|
|
492
|
+
* door in between, so a non-string carrier now degrades visibly (the walk
|
|
493
|
+
* yields no entry and the caller keeps the raw value) instead of being absorbed
|
|
494
|
+
* here.
|
|
255
495
|
*
|
|
256
496
|
* The **type gate is deliberate**: only a declared relationship is walked, so a
|
|
257
497
|
* path segment naming a plain field can never be turned into an object name and
|