@object-ui/plugin-charts 17.3.0 → 17.6.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 +646 -0
- package/README.md +0 -11
- package/dist/AdvancedChartImpl.d.ts +28 -7
- package/dist/ChartContainerImpl.d.ts +1 -1
- package/dist/ChartRenderer.d.ts +2 -5
- package/dist/ObjectChart.d.ts +25 -2
- package/dist/index.d.ts +3 -1
- package/dist/index.js +734 -624
- package/dist/index.umd.cjs +2 -2
- package/package.json +9 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,645 @@
|
|
|
1
1
|
# @object-ui/plugin-charts
|
|
2
2
|
|
|
3
|
+
## 17.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 9ce096f: Give a chart bucket an identity distinct from its display label
|
|
8
|
+
|
|
9
|
+
objectui#4508. `buildChartSeries` used the bucket's DISPLAY string as the
|
|
10
|
+
bucket's own key, so two pairs of genuinely different groups were conflated —
|
|
11
|
+
and the segment click that drills a bar back to its records inherited both
|
|
12
|
+
conflations. The maintainer ruling (2026-08-14) approved the sentinel-identity
|
|
13
|
+
direction, aligning the chart branch with the distinct-bucket-id form the pivot
|
|
14
|
+
TABLE (`buildPivot`) already uses over the same dataset rows.
|
|
15
|
+
|
|
16
|
+
Two collisions, one cause:
|
|
17
|
+
|
|
18
|
+
- **A null group and an empty-string group drew ONE bar.** The pivot branch
|
|
19
|
+
keyed buckets by `String(xRaw ?? '')`, which spells `null` and `''`
|
|
20
|
+
identically. The bar took its label from whichever row created the bucket, and
|
|
21
|
+
the other group's segment then resolved to no row at all — a visible bar whose
|
|
22
|
+
click did nothing.
|
|
23
|
+
- **A record whose stored value spells the bucket label stole the null bucket's
|
|
24
|
+
drill.** A row storing the literal text `(None)` (or any localized
|
|
25
|
+
`chart.nullCategory` — `(未指定)` and the other nine packs) kept its own
|
|
26
|
+
bucket, so two bars carried the same axis text and BOTH resolved to the first.
|
|
27
|
+
That one is a wrong drill, not a dead one: clicking the null bucket's bar
|
|
28
|
+
opened the drawer on another group's records.
|
|
29
|
+
|
|
30
|
+
What changed:
|
|
31
|
+
|
|
32
|
+
- **`chartBucketId`** (`@object-ui/core`) is the bucket identity — the SAME
|
|
33
|
+
encoder `buildPivot` keys its buckets with (`pivotBucketId` over
|
|
34
|
+
`pivotDimensionValue`), so the two surfaces stop answering one question two
|
|
35
|
+
ways. The pivot branch now buckets by it, which is what makes null and `''`
|
|
36
|
+
two groups again.
|
|
37
|
+
- **`CHART_BUCKET_ID_KEY`** carries that identity on an emitted row, written
|
|
38
|
+
exactly where two DISTINCT buckets paint the same axis text — the complete set
|
|
39
|
+
of cases where the display string cannot name what was clicked. An ordinary
|
|
40
|
+
chart's rows are returned untouched (by identity), so no renderer-internal key
|
|
41
|
+
reaches an authoring surface.
|
|
42
|
+
- **`findChartSeriesRow`** takes that identity back as `options.bucketId` and
|
|
43
|
+
treats it as authoritative. The renderers forward it: the drill event gains
|
|
44
|
+
`categoryId` (`ChartSegmentClickEvent`, now declared once in
|
|
45
|
+
`@object-ui/core` instead of inline in three packages), `AdvancedChartImpl`
|
|
46
|
+
reads it off the clicked row on the cartesian, pie and funnel paths, and
|
|
47
|
+
`DatasetWidget.handleChartDrill` hands it to the lookup.
|
|
48
|
+
|
|
49
|
+
Behaviour change worth noting: an empty-string category no longer resolves to a
|
|
50
|
+
null-valued row. That tolerance was justified as the drill layer's own spelling
|
|
51
|
+
of "no group value", but no producer of this lookup's `category` writes it,
|
|
52
|
+
while `''` IS the axis text a genuine empty-string group paints — so the
|
|
53
|
+
tolerance was giving that group's bar a different group's records. A host that
|
|
54
|
+
forwards no `categoryId` keeps its existing drill unchanged.
|
|
55
|
+
|
|
56
|
+
### Patch Changes
|
|
57
|
+
|
|
58
|
+
- e132433: A grouped chart whose SECOND dimension was never projected says so instead of
|
|
59
|
+
drawing an empty frame.
|
|
60
|
+
|
|
61
|
+
"Cannot know refuses loudly" was answered on the first dimension only.
|
|
62
|
+
`AdvancedChartImpl`'s `hasNoCategoryKey` (framework#4033) names an unprojected
|
|
63
|
+
x-axis dimension rather than drawing a bare axis; the series axis had no
|
|
64
|
+
counterpart, so a pivot whose second dimension was absent from the result rows
|
|
65
|
+
produced `series: []` and rendered axes, grid, tooltip and legend around zero
|
|
66
|
+
marks — indistinguishable, to the author, from "no data matched".
|
|
67
|
+
|
|
68
|
+
Such a chart now renders the same explanatory placeholder
|
|
69
|
+
(`data-chart-error="no-plottable-series"`) and logs the same diagnostic pair the
|
|
70
|
+
category-axis guard logs: the axis it did plot, and the keys its rows actually
|
|
71
|
+
carry.
|
|
72
|
+
|
|
73
|
+
The three-way distinction is unchanged and pinned: null / empty-string group
|
|
74
|
+
values still DRAW (they are real groups with real buckets), a partially
|
|
75
|
+
projected group key still draws what projects — mirroring the category axis,
|
|
76
|
+
which refuses only when NOT ONE row carries the key — and an ordinary pivot
|
|
77
|
+
renders unchanged. The refusal is limited to the families whose marks come from
|
|
78
|
+
`series` and nothing else (bar, horizontal-bar, line, area, combo); pie, donut,
|
|
79
|
+
funnel, radar and scatter draw from a `value` column with no series declared, so
|
|
80
|
+
they are untouched. A caller that computed no series binding at all
|
|
81
|
+
(`series === undefined`) is also untouched.
|
|
82
|
+
- f95434b: Combo charts drill from their marks
|
|
83
|
+
|
|
84
|
+
objectui#4692, ruled Option B. `AdvancedChartImpl` built `cartesianClickProps` once and
|
|
85
|
+
applied it to exactly one element — the final cartesian `ChartComponent`. The `combo`
|
|
86
|
+
branch returns earlier, from its own `ComposedChart`, which was rendered with `data` and
|
|
87
|
+
no click props at all, so a combo chart fired `onChartClick` never: not on a mark, not on
|
|
88
|
+
the axis. Its marks are the same `Bar` / `Line` / `Area` components the drillable branch
|
|
89
|
+
renders.
|
|
90
|
+
|
|
91
|
+
The trap that made this worth fixing rather than documenting is that the family is
|
|
92
|
+
**derived**, not only authored: `effectiveChartFamily` resolves a chart to `combo`
|
|
93
|
+
whenever its series declare different families (objectui#2945), so adding `type: 'line'`
|
|
94
|
+
to one series of a drillable bar chart silently turned that chart's drill-through off —
|
|
95
|
+
nothing in the authored spec said drill had been touched, and nothing errored.
|
|
96
|
+
|
|
97
|
+
A combo's `Bar` / `Line` / `Area` marks now emit `{ category, categoryId, series, value }`
|
|
98
|
+
with the same semantics the plain cartesian branch gives, reusing the item-level
|
|
99
|
+
series-identity machinery from objectui#4672 / objectui#4682: the mark handler records the
|
|
100
|
+
series it was rendered with, the chart-level handler composes the one event, so a gesture
|
|
101
|
+
still produces exactly one `onChartClick`. Retyping one series now changes that series'
|
|
102
|
+
mark and nothing else.
|
|
103
|
+
|
|
104
|
+
**Only the marks drill.** A click on a combo's plot surface or axis stays silent, where
|
|
105
|
+
the plain cartesian branch falls back to its axis-level answer. A combo plots several
|
|
106
|
+
measures on one plot, so a surface click there has no single series to report and the
|
|
107
|
+
fallback would have to invent one — the same reasoning objectui#4672's ruling gave the
|
|
108
|
+
pivoted case. Combo also carries no chart-wide pointer cursor for that reason; the
|
|
109
|
+
affordance sits on the marks that answer.
|
|
110
|
+
|
|
111
|
+
Radar is now the one cartesian-adjacent family with no click wiring. The `onChartClick`
|
|
112
|
+
doc comment, corrected in objectui#4705 to say combo was a no-op, states the new rule and
|
|
113
|
+
its one deliberate exception.
|
|
114
|
+
- e05db88: A clicked cartesian mark names its own series, and the drill title reads its label
|
|
115
|
+
|
|
116
|
+
objectui#4672, objectui#4682.
|
|
117
|
+
|
|
118
|
+
**The dead pivoted drill.** objectui#4680 fixed what a cartesian click could
|
|
119
|
+
read out of recharts 3's `MouseHandlerDataParam`, and measured the wall it could
|
|
120
|
+
not get past: a chart-level click is an AXIS interaction, and recharts
|
|
121
|
+
dispatches those with `activeDataKey` hard-coded `undefined`, because the shared
|
|
122
|
+
cursor spans every series at that tick. A pivoted dataset chart — 2 dimensions,
|
|
123
|
+
1 measure, the shape ADR-0021 introduced — needs the series to resolve its drill
|
|
124
|
+
row, so every segment of every such dashboard chart stayed a dead click. The
|
|
125
|
+
series was left unresolved rather than guessed, and the card carried the rest.
|
|
126
|
+
|
|
127
|
+
The answer is the mark itself. This renderer draws the `Bar` / `Line` / `Area`,
|
|
128
|
+
so an item-level `onClick` closes over the very `dataKey` it was rendered with —
|
|
129
|
+
the series is statically known, not inferred from tooltip state.
|
|
130
|
+
|
|
131
|
+
Both handlers fire for one gesture (measured: item first, chart second, sharing
|
|
132
|
+
one `nativeEvent` object), so the item handler does not emit. It RECORDS its
|
|
133
|
+
series, stamped with that gesture, and the chart-level handler composes the one
|
|
134
|
+
event. That is the double-fire answer and the additive property together:
|
|
135
|
+
|
|
136
|
+
- **one click, one drill event**, because there is one emit site — not a second
|
|
137
|
+
event suppressed after the fact;
|
|
138
|
+
- **a click that lands on no mark is untouched**: it records nothing and falls
|
|
139
|
+
through to the objectui#4680 axis answer exactly as shipped — category, bucket
|
|
140
|
+
identity, and the series only where one series is plotted. Empty plot area
|
|
141
|
+
stays category-only, and "drill the whole category" was rejected as a
|
|
142
|
+
different product question. Nothing that resolved before stops resolving; a
|
|
143
|
+
line's `dot={false}` stroke simply GAINS the exact series where it is hit;
|
|
144
|
+
- pairing on the shared DOM event rather than on a flag means a record left by
|
|
145
|
+
one gesture can never be adopted by a later click.
|
|
146
|
+
|
|
147
|
+
The clicked key is forwarded exactly as rendered, `''` included: the
|
|
148
|
+
empty-string second-dimension group draws its own bar since objectui#4673, and
|
|
149
|
+
`''` is falsy, so a truthiness test on the way out would send no series at all
|
|
150
|
+
and leave that bar's drill standing on the reader's coercion instead of on what
|
|
151
|
+
was clicked.
|
|
152
|
+
|
|
153
|
+
**The opaque drill title.** `ChartSegmentClickEvent` gains `seriesLabel`, and
|
|
154
|
+
`DatasetWidget`'s drill drawer titles itself from `seriesLabel ?? series`.
|
|
155
|
+
`ev.series` stays the LOOKUP key — `findChartSeriesRow` resolves it through the
|
|
156
|
+
same assignment `buildChartSeries` made — and only the title reads the label.
|
|
157
|
+
|
|
158
|
+
The two strings are equal for every ordinary group, which is why reading the key
|
|
159
|
+
as a title went unnoticed. They part company when a group's label cannot name
|
|
160
|
+
it: the null bucket beside a record whose stored value literally spells
|
|
161
|
+
`(None)`, which is objectui#4508's collision on the series axis, reachable since
|
|
162
|
+
objectui#4673. Both groups then key by `chartBucketId`, and the drawer opened on
|
|
163
|
+
the right records under the title `Backlog / [null]`. An internal id where a
|
|
164
|
+
label belongs reads as broken DATA rather than as a broken title.
|
|
165
|
+
|
|
166
|
+
Neither string can do the other's job, which is why this is a second field
|
|
167
|
+
rather than a change to the first: the label is not resolvable (it is exactly
|
|
168
|
+
what the colliding groups share) and the key is not showable. `seriesLabel` is
|
|
169
|
+
optional and absent wherever a renderer resolved no label, so every other
|
|
170
|
+
chart's title is byte-identical.
|
|
171
|
+
- d298be8: Cartesian chart clicks report the clicked series and value again
|
|
172
|
+
|
|
173
|
+
objectui#4672. `AdvancedChartImpl`'s chart-level click handler built its drill
|
|
174
|
+
event from `payload.activePayload[0]` — a **recharts 2** field. This package is
|
|
175
|
+
on recharts 3, which hands a chart-level `onClick` a `MouseHandlerDataParam`:
|
|
176
|
+
`{ activeCoordinate, activeDataKey, activeIndex, activeLabel, activeTooltipIndex,
|
|
177
|
+
isTooltipActive }`, and nothing else. `activePayload` appears nowhere in the
|
|
178
|
+
shipped library, so the read was `undefined` on **every** cartesian click and
|
|
179
|
+
every bar / line / area drill event carried `series: undefined, value: undefined`.
|
|
180
|
+
Nothing went red: the payload is typed `any` at the call site, and every existing
|
|
181
|
+
drill test either calls the pure lookup directly or stubs the chart.
|
|
182
|
+
|
|
183
|
+
The handler now works from the payload recharts 3 actually sends:
|
|
184
|
+
|
|
185
|
+
- **The value** is read off the clicked row — `data[activeTooltipIndex]`, the
|
|
186
|
+
array this component was given — for the resolved measure, the same way the
|
|
187
|
+
bucket identity has been read since objectui#4508.
|
|
188
|
+
- **The series** comes from `activeDataKey` when the payload carries one, and
|
|
189
|
+
otherwise from the chart's own series list when it plots exactly one series,
|
|
190
|
+
where the clicked column can belong to nothing else.
|
|
191
|
+
- **A click with no active tick** (the plot margins, an axis label) resolves to
|
|
192
|
+
no row instead of to bucket zero. recharts reports a **null** index there, not
|
|
193
|
+
an absent one, and `Number(null)` is `0` — so such a click used to drill the
|
|
194
|
+
first bucket's records. That is a wrong drill, not a dead one.
|
|
195
|
+
|
|
196
|
+
A drill on a single-measure chart therefore names its measure and carries its
|
|
197
|
+
value again — `resolveDrillTitle` composes the drawer title from them, and an
|
|
198
|
+
authored drill filter can reference `${event.value}`.
|
|
199
|
+
|
|
200
|
+
**Still open, deliberately:** a chart plotting several series under the default
|
|
201
|
+
SHARED cursor. Measured against recharts 3.10.1, an axis interaction is
|
|
202
|
+
dispatched with `activeDataKey` hard-coded `undefined` (bar, line and area
|
|
203
|
+
alike, on the mark and on empty plot area), so the payload names no series at
|
|
204
|
+
all — and a pivoted dataset chart's drill lookup requires one. The series is
|
|
205
|
+
left unresolved rather than guessed: naming a series the user did not click
|
|
206
|
+
drills to another group's records, which is worse than the dead click. Resolving
|
|
207
|
+
it needs the clicked mark rather than this payload; objectui#4672 carries that
|
|
208
|
+
half.
|
|
209
|
+
- Updated dependencies [88085e3]
|
|
210
|
+
- Updated dependencies [69251bf]
|
|
211
|
+
- Updated dependencies [57e668f]
|
|
212
|
+
- Updated dependencies [516663d]
|
|
213
|
+
- Updated dependencies [41ac1b7]
|
|
214
|
+
- Updated dependencies [1eaf0a1]
|
|
215
|
+
- Updated dependencies [460c4d0]
|
|
216
|
+
- Updated dependencies [0ae27f7]
|
|
217
|
+
- Updated dependencies [2533ec5]
|
|
218
|
+
- Updated dependencies [78c0f9a]
|
|
219
|
+
- Updated dependencies [bbe8b86]
|
|
220
|
+
- Updated dependencies [8477be5]
|
|
221
|
+
- Updated dependencies [279fb13]
|
|
222
|
+
- Updated dependencies [2e82ab2]
|
|
223
|
+
- Updated dependencies [ad07b65]
|
|
224
|
+
- Updated dependencies [41f498b]
|
|
225
|
+
- Updated dependencies [ef0d150]
|
|
226
|
+
- Updated dependencies [f34226e]
|
|
227
|
+
- Updated dependencies [564b605]
|
|
228
|
+
- Updated dependencies [e1d4251]
|
|
229
|
+
- Updated dependencies [40d3a33]
|
|
230
|
+
- Updated dependencies [8b9dc62]
|
|
231
|
+
- Updated dependencies [1184192]
|
|
232
|
+
- Updated dependencies [a2a9747]
|
|
233
|
+
- Updated dependencies [a1609a6]
|
|
234
|
+
- Updated dependencies [53f23bc]
|
|
235
|
+
- Updated dependencies [c4533dc]
|
|
236
|
+
- Updated dependencies [be60815]
|
|
237
|
+
- Updated dependencies [37f6844]
|
|
238
|
+
- Updated dependencies [93de4f6]
|
|
239
|
+
- Updated dependencies [2b50261]
|
|
240
|
+
- Updated dependencies [384f30d]
|
|
241
|
+
- Updated dependencies [ac600e5]
|
|
242
|
+
- Updated dependencies [97fba31]
|
|
243
|
+
- Updated dependencies [232f61a]
|
|
244
|
+
- Updated dependencies [d374caf]
|
|
245
|
+
- Updated dependencies [5673576]
|
|
246
|
+
- Updated dependencies [c1ef923]
|
|
247
|
+
- Updated dependencies [911ceaa]
|
|
248
|
+
- Updated dependencies [98eab36]
|
|
249
|
+
- Updated dependencies [af5e292]
|
|
250
|
+
- Updated dependencies [3fbbea1]
|
|
251
|
+
- Updated dependencies [7f96b10]
|
|
252
|
+
- Updated dependencies [167ec42]
|
|
253
|
+
- Updated dependencies [616a2a5]
|
|
254
|
+
- Updated dependencies [0046d8f]
|
|
255
|
+
- Updated dependencies [f1d4748]
|
|
256
|
+
- Updated dependencies [bea374e]
|
|
257
|
+
- Updated dependencies [b1119ec]
|
|
258
|
+
- Updated dependencies [9f23d2b]
|
|
259
|
+
- Updated dependencies [578e025]
|
|
260
|
+
- Updated dependencies [af025ee]
|
|
261
|
+
- Updated dependencies [d109a4d]
|
|
262
|
+
- Updated dependencies [598c89a]
|
|
263
|
+
- Updated dependencies [4a0bd17]
|
|
264
|
+
- Updated dependencies [b8b9af4]
|
|
265
|
+
- Updated dependencies [31676be]
|
|
266
|
+
- Updated dependencies [8c0d52e]
|
|
267
|
+
- Updated dependencies [aff10e2]
|
|
268
|
+
- Updated dependencies [70a774b]
|
|
269
|
+
- Updated dependencies [9ce096f]
|
|
270
|
+
- Updated dependencies [e05db88]
|
|
271
|
+
- Updated dependencies [7458a41]
|
|
272
|
+
- Updated dependencies [ad13d63]
|
|
273
|
+
- Updated dependencies [5ffcc14]
|
|
274
|
+
- Updated dependencies [d971e51]
|
|
275
|
+
- Updated dependencies [97abb24]
|
|
276
|
+
- Updated dependencies [deb157a]
|
|
277
|
+
- Updated dependencies [9c60144]
|
|
278
|
+
- Updated dependencies [d2ce342]
|
|
279
|
+
- Updated dependencies [9695da7]
|
|
280
|
+
- Updated dependencies [75444e3]
|
|
281
|
+
- Updated dependencies [58b8346]
|
|
282
|
+
- Updated dependencies [2d0bd16]
|
|
283
|
+
- Updated dependencies [a9e17b4]
|
|
284
|
+
- Updated dependencies [b8ce7dc]
|
|
285
|
+
- Updated dependencies [dad51e5]
|
|
286
|
+
- Updated dependencies [1c9c342]
|
|
287
|
+
- Updated dependencies [787c738]
|
|
288
|
+
- Updated dependencies [8396656]
|
|
289
|
+
- Updated dependencies [dbbd38a]
|
|
290
|
+
- Updated dependencies [8871c14]
|
|
291
|
+
- Updated dependencies [93fe362]
|
|
292
|
+
- Updated dependencies [dfc6975]
|
|
293
|
+
- Updated dependencies [3cf4de0]
|
|
294
|
+
- Updated dependencies [c9dc811]
|
|
295
|
+
- Updated dependencies [144ef9b]
|
|
296
|
+
- Updated dependencies [138ab04]
|
|
297
|
+
- Updated dependencies [a0b9e91]
|
|
298
|
+
- Updated dependencies [99bd015]
|
|
299
|
+
- Updated dependencies [21e4585]
|
|
300
|
+
- @object-ui/types@17.6.0
|
|
301
|
+
- @object-ui/i18n@17.6.0
|
|
302
|
+
- @object-ui/react@17.6.0
|
|
303
|
+
- @object-ui/components@17.6.0
|
|
304
|
+
- @object-ui/core@17.6.0
|
|
305
|
+
|
|
306
|
+
## 17.5.0
|
|
307
|
+
|
|
308
|
+
### Minor Changes
|
|
309
|
+
|
|
310
|
+
- 5fac011: Publish `normalizeChartSchema` from the package entry.
|
|
311
|
+
|
|
312
|
+
`normalizeChartSchema` is the single place the author-facing chart schema is translated into the renderer's internal pipeline contract, and `ChartRenderer` calls it on every render. It was not reachable from the package's only entry point, so a consumer that wanted to assert what `AdvancedChartImpl` is actually handed had to restate the translation rather than run it. It is now exported from the entry, along with the `NormalizedChartSchema` type it returns.
|
|
313
|
+
|
|
314
|
+
Additive only: nothing is removed or renamed, and the module was already in the entry's eager import graph via `ChartRenderer`, so this publishes a name rather than shipping new bytes.
|
|
315
|
+
|
|
316
|
+
### Patch Changes
|
|
317
|
+
|
|
318
|
+
- 5900ac5: Analytics surfaces now run resolved select-option labels through the locale bundle — the chart legend and the related list on one page stop disagreeing
|
|
319
|
+
|
|
320
|
+
A dashboard widget grouped by a `select` field rendered the option's authored English label while the related list beside it rendered the translation. The decisive evidence in objectui#4030 is the stored value `orion`: the chart read `Orion Engineered Carbons`, a string with no resemblance to the value and matching the object's `label` byte for byte. So the analytics path had already RESOLVED the option label — it simply never ran the result through the i18n bundle before display. (`domestic → Domestic` differs from its value by case alone, which is why the first diagnosis, "the report groups by stored value", was wrong.)
|
|
321
|
+
|
|
322
|
+
There is exactly one resolution channel and this change reuses it rather than adding a chart-side dialect: `fieldOptionLabel` from `useObjectLabel`, i.e. `{ns}.fieldOptions.<object>.<field>.<value>` — the convention `@objectstack/spec` names objectui as the reader of, and the one list, form, kanban and record-picker surfaces already translate select options through. The bundle is applied ONCE, at the output of the label net that landed in objectui#4053/#4263, on the shared option list every consumer reads: chart axis and legend, the table/pivot cells of a dotted dimension, that table's CSV export, per-category colours and the declared category order. `@object-ui/core` gains `localizeFieldOptions` (the pure mirror of `translateOptions`), an optional translator on `buildDimensionLabelMap`, and `resolveDimensionFieldMeta` — the same single relationship walk `resolveDimensionFieldOptions` performs, now keeping the object that OWNS the terminal field, because for `crm_account.industry` the bundle key is `crm_account`, not the dataset's base object.
|
|
323
|
+
|
|
324
|
+
Two properties the fix is shaped around. The rows reach this net keyed either way — by stored value when the server did not resolve the dimension, by the English label when it did (ADR-0021) — and the reported screen is the second case, so the map answers to both keys and lands on the same translated display. And identity is untouched: `relabelDimensions` still rewrites display only, so a drilled chart segment clicked as `欧励隆` filters by `orion`, bucket ids and pivot totals keep their raw keys, and an option with no bundle entry (or an `en` console) renders exactly the authored label it renders today.
|
|
325
|
+
|
|
326
|
+
The per-locale work moved from the metadata fetch into the render, so switching language now re-labels in place instead of waiting for a refetch.
|
|
327
|
+
|
|
328
|
+
Not covered, and unchanged here: a LOCAL select dimension on a table/pivot, whose label the server resolves and whose client-side net is deliberately off (objectui#4263), and a dashboard global filter's own field label, which has no object name in its metadata to key a bundle lookup with — tracked on objectui#4030.
|
|
329
|
+
|
|
330
|
+
- 3fc2971: A null-keyed group renders as an explicit bucket instead of silently vanishing from a chart (objectui#4466)
|
|
331
|
+
|
|
332
|
+
`buildChartSeries`' single-dimension branch passed rows through verbatim, so a row whose category VALUE is `null` reached recharts with a null category and drew no mark. The visible outcome was not an empty chart but a quietly wrong one: rows `[{user_id: null, event_count: 51}, {user_id: 'Dev Admin', event_count: 2}]` drew exactly ONE bar — the dominant group, 51 of 53 events, dropped while the y-axis scale still accommodated it, so the chart understated its own data and the axis proved the data had been there. With every group null it drew axes, gridlines and an axis title with zero marks and no empty state, which is the shipped first-boot state of the built-in System Overview board's "Events by User" (every seeded `sys_audit_log` row is written with `user_id = NULL`).
|
|
333
|
+
|
|
334
|
+
The mapping lives in the shared series layer, so dashboard widgets and standalone `ObjectChart` get one answer rather than a per-chart patch in the recharts wrapper. It resolves the two-answers disagreement the card names as well: an empty result set keeps the designed empty state, a non-empty result always draws bars — the null bucket included.
|
|
335
|
+
|
|
336
|
+
`@object-ui/core` gains `NULL_CATEGORY_LABEL` and `ChartSeriesOptions`; `buildChartSeries` and `findChartSeriesRow` each take an optional trailing `options`. Both additive — every existing call site compiles and behaves identically, and a result with no null category is still returned by array identity. The two helpers are a pair on purpose: the caller matches a clicked segment against rows that still carry the raw `null`, so `findChartSeriesRow` reads the bucket label back to that row and the newly-visible bar keeps its drill-through instead of resolving to `-1`.
|
|
337
|
+
|
|
338
|
+
The label goes through the i18n channel (`chart.nullCategory`, en `(None)` / zh `(未指定)`, all ten packs), passed down by the renderer: `@object-ui/core` is React-free and cannot read the locale bundle, so it takes the resolved string the same way `dimensionOptionTranslator` takes a resolver. Its English constant is the floor for a provider-less host, not the mechanism.
|
|
339
|
+
|
|
340
|
+
`hasNoCategoryKey` (framework#4033) is untouched and now documented against this: a row that does not carry the category key AT ALL is a different defect — a dimension grouped by but never projected — and keeps its explanatory placeholder. The bucket deliberately never ADDS the key to such a row, which is what keeps that guard's signal alive. Key absent → the placeholder; key present with a null value → the bucket.
|
|
341
|
+
|
|
342
|
+
- aca27fa: The multi-dimension pivot branch buckets a null first-dimension value instead of dropping its bar (objectui#4497)
|
|
343
|
+
|
|
344
|
+
`buildChartSeries`' pivot branch (2+ dimensions, single measure) bucketed rows by `String(xRaw ?? '')` but wrote the RAW value into the emitted row, so a null first-dimension value produced `{status: null, Low: 3}` and reached recharts with a null category — which draws no mark. Measured at the DOM: a two-group pivot drew ONE bar, and an all-null pivot drew axes and gridlines with zero bar rectangles and no empty state. That is the same mechanism objectui#4466 fixed one branch below, on the branch that card deliberately left pinned as-is until the pivot's own bucketing had been measured.
|
|
345
|
+
|
|
346
|
+
The pivot now maps a null/undefined first-dimension VALUE to the same bucket label the single-dimension branch uses — `ChartSeriesOptions.nullCategoryLabel`, defaulting to `NULL_CATEGORY_LABEL`. One doctrine, one predicate, two call sites; no new export, and every existing call site compiles and behaves identically.
|
|
347
|
+
|
|
348
|
+
The bucket KEY is untouched, which is what keeps this a display fix: `String(xRaw ?? '')` still decides which rows share a bar, so every existing grouping is byte-identical and only the label the bucket carries changes. Rows that lack the category key entirely are still not bucketed — that shape is a dimension grouped by but never projected (framework#4033), a different defect with a different answer.
|
|
349
|
+
|
|
350
|
+
Drill-through needed no change, which was measured rather than assumed: the pivot's emitted rows are AGGREGATED, so they are not index-aligned with `drillRawRows` and the one production caller (`DatasetWidget.handleChartDrill`) already drills by SEARCHING the raw rows through `findChartSeriesRow`. Those raw rows still carry their null, and objectui#4466's label-matching covers the multi-dimension arm as well as the single-dimension one, so the newly-visible bar resolves to the right record. Pinned at both levels so a regression in either half surfaces as the dead click it would be.
|
|
351
|
+
|
|
352
|
+
- 613b167: A dataset dimension on a dotted relationship path now renders its option labels instead of the raw stored enum
|
|
353
|
+
|
|
354
|
+
A `DatasetDimension` whose `field` is a relationship path (`crm_account.industry`) got no select-option resolution at all: the chart plotted `education`, `finance`, `manufacturing` — the database column, unresolved — while the **same underlying field** reached as a **local** dimension rendered `Education`, `Finance`, `Manufacturing` beside it on the same dashboard. Nothing errored, so the widget just quietly showed database enum values to end users; on a non-English deployment those are words that appear nowhere else in the UI, since every form and list shows the translated label.
|
|
355
|
+
|
|
356
|
+
The label lookup read options as `baseObject.fields[<path>]`, which only ever matches the local spelling. For a dotted path the options live on the **related** object, so the lookup missed and the renderer fell through to the stored value.
|
|
357
|
+
|
|
358
|
+
The object-resolution step of that one lookup now walks the path: each segment before the last must be a declared relationship (`lookup` / `master_detail`, target read from `reference` / `reference_to` / `referenceTo` / `reference_to_object`), and the terminal field's options are read off the object that actually owns it. This is the same lookup for both spellings rather than a dotted-path variant beside it — a single-segment path never enters the walk and resolves exactly as before, so the local and joined paths cannot drift apart. Multi-hop paths (`crm_account.owner.department`) resolve too, which is the shape the dataset designer already emits.
|
|
359
|
+
|
|
360
|
+
Hops ride the caller's existing `GET /meta/object/:name` channel — the same authenticated read that fetched the base object — so no new fetch layer is introduced, and objects are fetched once per resolution even when several dimensions share a prefix. Every failure stays best-effort: a segment that is not a relationship, a target that cannot be loaded, or a terminal field with no options yields no mapping and the raw value survives, exactly as it does today.
|
|
361
|
+
|
|
362
|
+
Applies to both surfaces that carried this lookup: dashboard dataset widgets (`DatasetWidget`) and the chart view's dataset path (`ObjectChart`).
|
|
363
|
+
|
|
364
|
+
Scope: this ends at "the label is in hand". Whether that label then passes through the i18n bundle is a separate gap tracked upstream as objectstack#5076.
|
|
365
|
+
|
|
366
|
+
- 0b49d60: Analytics: `ObjectChart` consumes the shared label-net helpers instead of a third copy
|
|
367
|
+
|
|
368
|
+
objectui#4389 (PR #4404) named two copies of the analytics label-net glue — the dashboard's `DatasetWidget` and plugin-report's dataset block — and retired both into `@object-ui/core` + `@object-ui/react`. There was a THIRD, which that card did not name and its PR deliberately left out of scope: `packages/plugin-charts/src/ObjectChart.tsx` carried its own `translatorFor` closure, its own `buildDimensionLabelMap` loop, and its own base-object-read-then-walk composition. The `translatorFor` copy was logically identical to the two that were deleted, down to the comment explaining the binding.
|
|
369
|
+
|
|
370
|
+
`ObjectChart` now calls core's `dimensionOptionTranslator`, `deriveDimensionLabelMaps` and `loadDimensionFieldMeta` directly. Nothing about what a label IS changes — those helpers are the same code the two retired copies were rewritten onto, so the part that was genuinely duplicated three times is now written once.
|
|
371
|
+
|
|
372
|
+
Behaviour is unchanged by construction: same two metadata reads in the same order on the dataset path, same one read on the aggregate path, same best-effort fallback (an unresolvable path yields no entry and the raw value survives), same locale-applying memo boundary. `plugin-charts`' 22 test files / 170 assertions pass unchanged and their files are byte-identical to before, which is the acceptance evidence for a pure swap.
|
|
373
|
+
|
|
374
|
+
The card's second, optional step — moving the DATASET path's metadata read onto `@object-ui/react`'s `useDatasetDimensionMeta` — was attempted and declined on measurement; the shape blocker is recorded on objectui#4405 and in the PR. The two bug-fix properties the family exists to state (the read rides the host's authenticated `apiFetch`, objectui#4121; the fetched metadata stays locale-free, objectui#4030 / PR #4324) therefore remain stated locally in this file, exactly as before, and are undisturbed by this change.
|
|
375
|
+
|
|
376
|
+
- bcd3e02: `ObjectChart`'s category option-color / dimension-label probe now rides the host's
|
|
377
|
+
authenticated fetch (`SchemaRendererContext.apiFetch`) instead of the bare global
|
|
378
|
+
`fetch`.
|
|
379
|
+
|
|
380
|
+
Both metadata reads the effect makes — `GET /api/v1/meta/dataset/{dataset}` and
|
|
381
|
+
`GET /api/v1/meta/object/{object}` — went out on the global `fetch`, so in a hosted
|
|
382
|
+
console they skipped whatever the host supplies on that channel (Authorization /
|
|
383
|
+
tenant headers, base-URL rewrite, draft-preview params). A bearer-token session
|
|
384
|
+
carries its credential in a header rather than a cookie, so `credentials: 'include'`
|
|
385
|
+
alone left these two reads unauthenticated. The effect is best-effort and swallows
|
|
386
|
+
every failure, which made the symptom silent: semantic option colors and dataset
|
|
387
|
+
dimension labels simply never applied, and the chart fell back to the positional
|
|
388
|
+
theme palette and raw stored values.
|
|
389
|
+
|
|
390
|
+
Standalone embeds are unaffected — with no provider (or a provider that supplies no
|
|
391
|
+
`apiFetch`) the probe still uses the global `fetch`, the same documented fallback
|
|
392
|
+
`useRecordEditable` and `provider: 'api'` view sources use.
|
|
393
|
+
|
|
394
|
+
- Updated dependencies [0e67b53]
|
|
395
|
+
- Updated dependencies [ceccdcf]
|
|
396
|
+
- Updated dependencies [d6e5124]
|
|
397
|
+
- Updated dependencies [debad27]
|
|
398
|
+
- Updated dependencies [dc2aa3e]
|
|
399
|
+
- Updated dependencies [ee66e2e]
|
|
400
|
+
- Updated dependencies [ee26e65]
|
|
401
|
+
- Updated dependencies [5900ac5]
|
|
402
|
+
- Updated dependencies [932cbcd]
|
|
403
|
+
- Updated dependencies [734d186]
|
|
404
|
+
- Updated dependencies [f650253]
|
|
405
|
+
- Updated dependencies [3d9769a]
|
|
406
|
+
- Updated dependencies [8f85f8b]
|
|
407
|
+
- Updated dependencies [d0c3b26]
|
|
408
|
+
- Updated dependencies [3fc2971]
|
|
409
|
+
- Updated dependencies [aca27fa]
|
|
410
|
+
- Updated dependencies [dde7283]
|
|
411
|
+
- Updated dependencies [f7c6430]
|
|
412
|
+
- Updated dependencies [4dadf0d]
|
|
413
|
+
- Updated dependencies [ae10a01]
|
|
414
|
+
- Updated dependencies [92876f0]
|
|
415
|
+
- Updated dependencies [f279deb]
|
|
416
|
+
- Updated dependencies [4b70d28]
|
|
417
|
+
- Updated dependencies [eb7f586]
|
|
418
|
+
- Updated dependencies [e901131]
|
|
419
|
+
- Updated dependencies [d9d3463]
|
|
420
|
+
- Updated dependencies [2a40f69]
|
|
421
|
+
- Updated dependencies [bec3e14]
|
|
422
|
+
- Updated dependencies [613b167]
|
|
423
|
+
- Updated dependencies [b4d3c22]
|
|
424
|
+
- Updated dependencies [1f9b905]
|
|
425
|
+
- Updated dependencies [cb13400]
|
|
426
|
+
- Updated dependencies [828549a]
|
|
427
|
+
- Updated dependencies [e1ade8f]
|
|
428
|
+
- Updated dependencies [bc64bfe]
|
|
429
|
+
- Updated dependencies [abb0f81]
|
|
430
|
+
- Updated dependencies [38ab505]
|
|
431
|
+
- Updated dependencies [3e19fe7]
|
|
432
|
+
- Updated dependencies [bb58d1d]
|
|
433
|
+
- Updated dependencies [5cc847c]
|
|
434
|
+
- Updated dependencies [fa21254]
|
|
435
|
+
- Updated dependencies [33c32bf]
|
|
436
|
+
- Updated dependencies [66fb4fa]
|
|
437
|
+
- Updated dependencies [b953a97]
|
|
438
|
+
- Updated dependencies [d7f3e30]
|
|
439
|
+
- Updated dependencies [6d641c9]
|
|
440
|
+
- Updated dependencies [7e4f0e5]
|
|
441
|
+
- Updated dependencies [a84385b]
|
|
442
|
+
- Updated dependencies [45e1949]
|
|
443
|
+
- Updated dependencies [92250d6]
|
|
444
|
+
- Updated dependencies [c1d939f]
|
|
445
|
+
- Updated dependencies [58bebf6]
|
|
446
|
+
- Updated dependencies [405e808]
|
|
447
|
+
- Updated dependencies [49ae9f4]
|
|
448
|
+
- Updated dependencies [a3ae404]
|
|
449
|
+
- Updated dependencies [bfdf3d4]
|
|
450
|
+
- Updated dependencies [bb68488]
|
|
451
|
+
- Updated dependencies [c0f9a4b]
|
|
452
|
+
- Updated dependencies [b1e42d0]
|
|
453
|
+
- Updated dependencies [2459a3e]
|
|
454
|
+
- Updated dependencies [ac853ce]
|
|
455
|
+
- Updated dependencies [fa51109]
|
|
456
|
+
- Updated dependencies [d6aa172]
|
|
457
|
+
- Updated dependencies [fe52a04]
|
|
458
|
+
- Updated dependencies [d46f9b8]
|
|
459
|
+
- Updated dependencies [3f5f87c]
|
|
460
|
+
- Updated dependencies [2fea4d2]
|
|
461
|
+
- Updated dependencies [f5e1143]
|
|
462
|
+
- Updated dependencies [7f1cb33]
|
|
463
|
+
- Updated dependencies [f148a64]
|
|
464
|
+
- Updated dependencies [bb68488]
|
|
465
|
+
- Updated dependencies [2e3b0c0]
|
|
466
|
+
- Updated dependencies [9461dd3]
|
|
467
|
+
- Updated dependencies [78fa331]
|
|
468
|
+
- Updated dependencies [47f551b]
|
|
469
|
+
- Updated dependencies [31ab1ac]
|
|
470
|
+
- Updated dependencies [0082db8]
|
|
471
|
+
- Updated dependencies [ab04728]
|
|
472
|
+
- Updated dependencies [5bf09fd]
|
|
473
|
+
- Updated dependencies [06915b0]
|
|
474
|
+
- Updated dependencies [ff84b05]
|
|
475
|
+
- @object-ui/i18n@17.5.0
|
|
476
|
+
- @object-ui/react@17.5.0
|
|
477
|
+
- @object-ui/components@17.5.0
|
|
478
|
+
- @object-ui/core@17.5.0
|
|
479
|
+
- @object-ui/types@17.5.0
|
|
480
|
+
|
|
481
|
+
## 17.4.0
|
|
482
|
+
|
|
483
|
+
### Patch Changes
|
|
484
|
+
|
|
485
|
+
- a7e39a8: `ChartContainer`'s min-size fallback survives a consumer-supplied `style` (objectstack#7026)
|
|
486
|
+
|
|
487
|
+
The container wrote `style={{ minHeight: 280, minWidth: 0, ...props.style }}` and
|
|
488
|
+
then spread `{...props}` on the line BELOW it. `props` is the rest of
|
|
489
|
+
`ComponentProps< "div" >` — only `id`, `className`, `children`, `config` and
|
|
490
|
+
`disableSettleRemount` are destructured out of it — so it still carried the
|
|
491
|
+
consumer's `style`, and a later JSX attribute of the same name replaces an earlier
|
|
492
|
+
one outright. Any caller that passed a `style` therefore replaced the whole object:
|
|
493
|
+
both `minHeight` and `minWidth` vanished, and the `...props.style` merge written
|
|
494
|
+
inside it never executed even once. It was dead code that read, to anyone auditing
|
|
495
|
+
the file, as if the fallback were guaranteed.
|
|
496
|
+
|
|
497
|
+
That fallback is not decorative. It exists so Recharts' `ResponsiveContainer`
|
|
498
|
+
always has a non-zero box to measure: a dashboard widget that overrides the
|
|
499
|
+
container's `h-[350px]` class and wraps the chart in flex/grid without an explicit
|
|
500
|
+
child height leaves the box at 0, Recharts measures `width/height = -1`, and the
|
|
501
|
+
chart renders invisibly — the exact failure the guard was added for.
|
|
502
|
+
|
|
503
|
+
`style` is now destructured out of the rest props and merged explicitly, so which
|
|
504
|
+
side wins is stated in code instead of being decided by JSX attribute order, and
|
|
505
|
+
`{...props}` can no longer reach `style` at all.
|
|
506
|
+
|
|
507
|
+
Precedence: **an author's explicit size wins.** Simply spreading `{...props}`
|
|
508
|
+
first and merging unconditionally would have traded this bug for its mirror image
|
|
509
|
+
— `minHeight: 280` injected next to an authored `height: 100` floors that 100 to
|
|
510
|
+
280, silently overriding the author. So each half of the fallback applies only
|
|
511
|
+
when the consumer style declares neither of its own keys: `height`/`minHeight`
|
|
512
|
+
gate the height half, `width`/`minWidth` gate the width half, and a key present
|
|
513
|
+
but set to `undefined`/`null` counts as not declared. Every other consumer style
|
|
514
|
+
key passes through untouched.
|
|
515
|
+
|
|
516
|
+
Behaviour change surface, deliberately narrow. A caller that supplies no `style`
|
|
517
|
+
is byte-for-byte unchanged. A caller whose `style` declares a height — which today
|
|
518
|
+
is the only shape in the tree, `AdvancedChartImpl`'s `containerProps` forwarding
|
|
519
|
+
`ChartConfig.height` — keeps exactly the height it authored, also unchanged, and
|
|
520
|
+
additionally regains the `minWidth: 0` half. What changes is the case the issue
|
|
521
|
+
was filed for: a `style` carrying no size key (a margin, a padding, an
|
|
522
|
+
aspect-ratio, any future container-level presentation prop routed through the same
|
|
523
|
+
`containerProps` path) now keeps the min-size fallback instead of silently
|
|
524
|
+
stripping it.
|
|
525
|
+
|
|
526
|
+
Pinned in both directions, since a one-sided pin would have been satisfied by the
|
|
527
|
+
mirror-image fix: a non-size `style` keeps `min-height: 280` / `min-width: 0`
|
|
528
|
+
(red before this change), and an explicit `height: 100` renders as 100 with no
|
|
529
|
+
`min-height` floor (red under the unconditional-merge alternative).
|
|
530
|
+
|
|
531
|
+
- 4bc6c23: Converge dashboard widget `compareTo` on the executor's `{ kind, dimension? }` contract, and make the dataset path actually render a comparison
|
|
532
|
+
|
|
533
|
+
`CompareToConfig` was a three-branch union (`'previousPeriod' | 'previousYear' | { offset }`). `@objectstack/spec` collapsed it to the shape the analytics executor already implements — `DatasetCompareTo`, a plain strict object `{ kind: 'previousPeriod' | 'previousYear'; dimension?: string }` (objectstack#5011) — so this renderer now reads that one shape:
|
|
534
|
+
|
|
535
|
+
- `shiftFilterByCompareTo` / `compareToTrendLabelKey` dispatch on `compareTo.kind`. The `{ offset }` duration shift is gone: `{ offset: '1y' }` is `kind: 'previousYear'`, while `'7d'` / `'1M'` have no faithful target and are restated by the author on the widget's own `filter` plus `kind: 'previousPeriod'`. No trend label key is retired — the offset arm resolved to `vsPreviousPeriod`, which survives as the `previousPeriod` fallback.
|
|
536
|
+
- `DatasetWidget` no longer discards part of `compareTo`. It used to forward only the object form because the two string forms had no meaning downstream; with one shape there is nothing to discard, and a stale string is now invalid metadata rejected where it is authored rather than silently reinterpreted here.
|
|
537
|
+
- **The comparison now actually runs on the dataset path.** A widget states its window in its own `filter` (a date macro, or the dashboard date-range filter merged in), but the executor shifts a `timeDimensions` entry carrying a `dateRange` — so a dataset widget asking for a comparison got "compareTo needs a dated window to shift" and rendered none. When (and only when) a comparison is requested, the resolved filter's bounded date windows are lowered into `selection.timeDimensions[].dateRange` and moved out of `runtimeFilter` (a copy left behind would intersect the shifted window with the current one and empty every comparison column). Which dimension gets shifted stays the executor's decision: every window found is lowered under the name the author wrote, and zero or two candidates surfaces the executor's own error, listing them.
|
|
538
|
+
- The `<measure>__compare` columns that come back are now shown: a delta + window label on KPI widgets, a comparison column on tables, and a `variant: 'comparison'` overlay series on charts — the same treatment and the same `dashboard.trend.*` labels the inline object-provider widgets already use.
|
|
539
|
+
|
|
540
|
+
- 5bfaabd: `PageComponentSchema.dataSource` now reaches every object-bound block, not just
|
|
541
|
+
`list-view` — and `element:record_picker` stops discarding `view`
|
|
542
|
+
(objectstack#6953).
|
|
543
|
+
|
|
544
|
+
objectstack#5576 wired the spec's per-element data binding
|
|
545
|
+
(`dataSource: { object, view?, filter?, sort?, limit? }`) to `list-view` and left
|
|
546
|
+
the same declaration inert on every other page component. Two gaps remained, and
|
|
547
|
+
both were silent:
|
|
548
|
+
|
|
549
|
+
- **`element:record_picker` read four of the five keys and dropped `view`.** So
|
|
550
|
+
`dataSource: { object: 'account', view: 'hot' }` — the spec's own example —
|
|
551
|
+
built a picker over EVERY account instead of the rows the saved view selects.
|
|
552
|
+
Nothing threw and nothing rendered an error; the option list was simply wider
|
|
553
|
+
than what was authored, which also means a user could select a record the page
|
|
554
|
+
said was out of scope.
|
|
555
|
+
- **`object-grid` / `object-form` / `object-kanban` / `object-calendar` /
|
|
556
|
+
`object-chart` / `object-metric` / `record:related_list` read none of it.**
|
|
557
|
+
Each gates its fetch on its own `objectName`, and nothing mapped
|
|
558
|
+
`dataSource.object` onto it, so a page written the way the spec documents
|
|
559
|
+
rendered an empty grid / a field-less form / a board with no cards / an empty
|
|
560
|
+
month / an empty chart / a static metric number — with no request and no
|
|
561
|
+
diagnostic anywhere. Spec-valid metadata rendering nothing is the
|
|
562
|
+
objectstack#4413 shape.
|
|
563
|
+
|
|
564
|
+
Composition follows objectstack#5576's landed semantics unchanged on every block:
|
|
565
|
+
a named saved view supplies the baseline, a key written on the component itself
|
|
566
|
+
overrides it, an explicit binding key overrides both, `filter` AND-combines
|
|
567
|
+
("additional filter criteria" — a binding can narrow a view, never widen it), and
|
|
568
|
+
a `view` name that does not resolve renders a configuration error instead of
|
|
569
|
+
degrading to the object's full scope.
|
|
570
|
+
|
|
571
|
+
- `@object-ui/react` — new `useElementDataSourceSchema(schema, mapping, dataSource?)`
|
|
572
|
+
and `ElementDataSourceGate` apply a resolved binding to the schema keys a given
|
|
573
|
+
block reads, plus `ElementDataSourceErrorPanel` / `ElementDataSourceLoadingPanel`
|
|
574
|
+
for the two non-final states. One precedence table for all blocks rather than
|
|
575
|
+
one copy per block — that copy is how "additional filter criteria" would have
|
|
576
|
+
become two dialects.
|
|
577
|
+
- A mapping names **only** keys its block genuinely reads. A composed value
|
|
578
|
+
written onto a key the block ignores would be accepted and dropped, which is
|
|
579
|
+
the defect being removed, one layer deeper — so a kanban's swimlane `columns`
|
|
580
|
+
never receive a view's field list, and a block with no row cap leaves `limit`
|
|
581
|
+
unmapped. The per-block coverage table, including two residual gaps that are
|
|
582
|
+
named rather than papered over, is in `content/docs/guide/data-source.md`.
|
|
583
|
+
|
|
584
|
+
No behaviour changes for a block that carries no `dataSource`: the binding-free
|
|
585
|
+
path returns the schema by reference, so nothing remounts and nothing refetches.
|
|
586
|
+
|
|
587
|
+
- Updated dependencies [794c497]
|
|
588
|
+
- Updated dependencies [993336f]
|
|
589
|
+
- Updated dependencies [f0a625a]
|
|
590
|
+
- Updated dependencies [b5980f4]
|
|
591
|
+
- Updated dependencies [8aad9fd]
|
|
592
|
+
- Updated dependencies [6719877]
|
|
593
|
+
- Updated dependencies [56ff091]
|
|
594
|
+
- Updated dependencies [7864f03]
|
|
595
|
+
- Updated dependencies [0cbdca8]
|
|
596
|
+
- Updated dependencies [d229dfa]
|
|
597
|
+
- Updated dependencies [ecae400]
|
|
598
|
+
- Updated dependencies [4bc6c23]
|
|
599
|
+
- Updated dependencies [d3e738a]
|
|
600
|
+
- Updated dependencies [c3b01a7]
|
|
601
|
+
- Updated dependencies [f5f8744]
|
|
602
|
+
- Updated dependencies [7ed3360]
|
|
603
|
+
- Updated dependencies [69becd2]
|
|
604
|
+
- Updated dependencies [5e52495]
|
|
605
|
+
- Updated dependencies [0fa5e4d]
|
|
606
|
+
- Updated dependencies [b750823]
|
|
607
|
+
- Updated dependencies [5bfaabd]
|
|
608
|
+
- Updated dependencies [e06810e]
|
|
609
|
+
- Updated dependencies [ab3ad4f]
|
|
610
|
+
- Updated dependencies [c2fd122]
|
|
611
|
+
- Updated dependencies [ac2139c]
|
|
612
|
+
- Updated dependencies [b14ab3a]
|
|
613
|
+
- Updated dependencies [e24d767]
|
|
614
|
+
- Updated dependencies [8c60819]
|
|
615
|
+
- Updated dependencies [aca561a]
|
|
616
|
+
- Updated dependencies [e64a52e]
|
|
617
|
+
- Updated dependencies [844d17f]
|
|
618
|
+
- Updated dependencies [48132f7]
|
|
619
|
+
- Updated dependencies [4dcd52a]
|
|
620
|
+
- Updated dependencies [42ae5c6]
|
|
621
|
+
- Updated dependencies [0ef9dfd]
|
|
622
|
+
- Updated dependencies [1d723e3]
|
|
623
|
+
- Updated dependencies [0109f54]
|
|
624
|
+
- Updated dependencies [7e5bb5d]
|
|
625
|
+
- Updated dependencies [fbc23e0]
|
|
626
|
+
- Updated dependencies [6d762da]
|
|
627
|
+
- Updated dependencies [e6fdbdc]
|
|
628
|
+
- Updated dependencies [54233b1]
|
|
629
|
+
- Updated dependencies [f9faa7d]
|
|
630
|
+
- Updated dependencies [97b63d7]
|
|
631
|
+
- Updated dependencies [6bb454a]
|
|
632
|
+
- Updated dependencies [523be48]
|
|
633
|
+
- Updated dependencies [7e2b7e9]
|
|
634
|
+
- Updated dependencies [33526fd]
|
|
635
|
+
- Updated dependencies [32413ec]
|
|
636
|
+
- Updated dependencies [c1e1e6b]
|
|
637
|
+
- @object-ui/components@17.4.0
|
|
638
|
+
- @object-ui/react@17.4.0
|
|
639
|
+
- @object-ui/core@17.4.0
|
|
640
|
+
- @object-ui/i18n@17.4.0
|
|
641
|
+
- @object-ui/types@17.4.0
|
|
642
|
+
|
|
3
643
|
## 17.3.0
|
|
4
644
|
|
|
5
645
|
### Minor Changes
|
|
@@ -872,6 +1512,7 @@
|
|
|
872
1512
|
project `health`) painted its categories from the generic `--chart-1..5`
|
|
873
1513
|
palette — the same gap the chart view (`object-chart`) had before #1932. It now
|
|
874
1514
|
resolves the dimension field's option colors (using the dataset's base `object`
|
|
1515
|
+
|
|
875
1516
|
- dimension→field map the query already returns) and threads them to the
|
|
876
1517
|
renderer as a per-category `categoryColors` map, so health green/red/yellow
|
|
877
1518
|
paints semantically.
|
|
@@ -1078,6 +1719,7 @@
|
|
|
1078
1719
|
- 991b62d: Add `compareTo` field to dashboard widgets for period-over-period
|
|
1079
1720
|
comparison. Supports `'previousPeriod'`, `'previousYear'`, and
|
|
1080
1721
|
`{ offset: '7d' | '4w' | '1M' | '1y' }`.
|
|
1722
|
+
|
|
1081
1723
|
- **Metric / gauge widgets** now compute a delta percentage when `compareTo`
|
|
1082
1724
|
is set and surface it as a derived `trend` (auto-labelled via
|
|
1083
1725
|
`dashboard.trend.vsLast*` i18n keys sniffed from the filter macros).
|
|
@@ -1562,6 +2204,7 @@
|
|
|
1562
2204
|
Library builds (vite lib mode) now externalize every non-relative import instead of bundling third-party CJS dependencies into the published dist. This avoids inlined `require("react")` / `require("react-dom")` calls that cause `Calling \`require\` for "react" in an environment that doesn't expose the \`require\` function` runtime errors when consumer apps re-bundle the published dist.
|
|
1563
2205
|
|
|
1564
2206
|
Specifically fixes:
|
|
2207
|
+
|
|
1565
2208
|
- `@object-ui/plugin-dashboard` no longer inlines `react-grid-layout` (and its transitive `react-draggable` / `react-resizable` CJS bundles). `react-grid-layout` is now declared as a peer dependency so consumers install a single ESM-friendly copy.
|
|
1566
2209
|
- `@object-ui/components`, `@object-ui/plugin-calendar`, `@object-ui/plugin-charts`, `@object-ui/plugin-designer` no longer inline `react-i18next` / `i18next` / `use-sync-external-store` CJS shims.
|
|
1567
2210
|
- All plugin packages now use a unified `external: (id) => !/^[./]/.test(id) && !id.startsWith(__dirname)` rule, ensuring future additions of CJS deps are automatically externalized.
|
|
@@ -1795,6 +2438,7 @@
|
|
|
1795
2438
|
- New plugin-object and ObjectQL SDK updates
|
|
1796
2439
|
|
|
1797
2440
|
**Added:**
|
|
2441
|
+
|
|
1798
2442
|
- New Plugin: @object-ui/plugin-object - ObjectQL plugin for automatic table and form generation
|
|
1799
2443
|
- ObjectTable: Auto-generates tables from ObjectQL object schemas
|
|
1800
2444
|
- ObjectForm: Auto-generates forms from ObjectQL object schemas with create/edit/view modes
|
|
@@ -1803,6 +2447,7 @@
|
|
|
1803
2447
|
- ObjectQL Integration: Enhanced ObjectQLDataSource with getObjectSchema() method using MetadataApiClient
|
|
1804
2448
|
|
|
1805
2449
|
**Changed:**
|
|
2450
|
+
|
|
1806
2451
|
- Updated @objectql/sdk from ^1.8.3 to ^1.9.1
|
|
1807
2452
|
- Updated @objectql/types from ^1.8.3 to ^1.9.1
|
|
1808
2453
|
|
|
@@ -1819,6 +2464,7 @@
|
|
|
1819
2464
|
- Patch release: Add automated changeset workflow and CI/CD improvements
|
|
1820
2465
|
|
|
1821
2466
|
This release includes infrastructure improvements:
|
|
2467
|
+
|
|
1822
2468
|
- Added changeset-based version management
|
|
1823
2469
|
- Enhanced CI/CD workflows with GitHub Actions
|
|
1824
2470
|
- Improved documentation for contributing and releasing
|