@object-ui/core 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 +2018 -0
- package/README.md +38 -34
- package/dist/actions/ActionEngine.d.ts +43 -26
- package/dist/actions/ActionEngine.js +67 -54
- package/dist/actions/ActionRunner.d.ts +281 -31
- package/dist/actions/ActionRunner.js +458 -36
- package/dist/actions/actionKeys.d.ts +163 -27
- package/dist/actions/actionKeys.js +238 -27
- package/dist/actions/actionResponse.js +1 -1
- package/dist/actions/index.d.ts +1 -0
- package/dist/actions/index.js +1 -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/data-scope/ViewDataProvider.d.ts +37 -12
- package/dist/data-scope/ViewDataProvider.js +83 -5
- package/dist/data-scope/element-data-source.d.ts +113 -0
- package/dist/data-scope/element-data-source.js +216 -0
- package/dist/data-scope/index.d.ts +2 -1
- package/dist/data-scope/index.js +1 -0
- package/dist/evaluator/ExpressionEvaluator.d.ts +42 -1
- package/dist/evaluator/ExpressionEvaluator.js +42 -1
- package/dist/evaluator/SafeExpressionParser.js +0 -4
- package/dist/evaluator/declaredPredicate.d.ts +119 -0
- package/dist/evaluator/declaredPredicate.js +152 -0
- package/dist/evaluator/fieldRules.d.ts +35 -0
- package/dist/evaluator/fieldRules.js +79 -20
- package/dist/evaluator/index.d.ts +2 -0
- package/dist/evaluator/index.js +2 -0
- package/dist/evaluator/listConditional.d.ts +54 -4
- package/dist/evaluator/listConditional.js +125 -19
- package/dist/evaluator/optionRules.d.ts +55 -0
- package/dist/evaluator/optionRules.js +60 -0
- package/dist/evaluator/predicateInput.d.ts +51 -3
- package/dist/evaluator/predicateInput.js +62 -5
- package/dist/evaluator/rowPredicateCanon.d.ts +67 -0
- package/dist/evaluator/rowPredicateCanon.js +208 -0
- package/dist/index.d.ts +8 -1
- package/dist/index.js +31 -1
- package/dist/protocols/DndProtocol.d.ts +42 -1
- package/dist/protocols/KeyboardProtocol.d.ts +31 -1
- package/dist/protocols/SharingProtocol.d.ts +11 -1
- package/dist/registry/Registry.d.ts +62 -16
- package/dist/theme/ThemeEngine.d.ts +0 -8
- package/dist/theme/ThemeEngine.js +22 -103
- package/dist/theme/index.d.ts +1 -1
- package/dist/theme/index.js +7 -1
- package/dist/types/index.d.ts +125 -12
- package/dist/utils/chart-presentation.d.ts +205 -0
- package/dist/utils/chart-presentation.js +280 -0
- package/dist/utils/chart-series.d.ts +390 -23
- package/dist/utils/chart-series.js +776 -32
- package/dist/utils/column-identity.d.ts +43 -0
- package/dist/utils/column-identity.js +47 -1
- package/dist/utils/compare-to.d.ts +40 -13
- package/dist/utils/compare-to.js +4 -32
- package/dist/utils/dashboard-filters.d.ts +54 -8
- package/dist/utils/dashboard-filters.js +261 -12
- package/dist/utils/dataset-format.d.ts +73 -14
- package/dist/utils/dataset-format.js +142 -9
- package/dist/utils/dataset-pivot.d.ts +28 -7
- package/dist/utils/dataset-pivot.js +27 -6
- package/dist/utils/debug.js +7 -0
- package/dist/utils/dom-props.d.ts +137 -0
- package/dist/utils/dom-props.js +153 -0
- package/dist/utils/expand-fields.d.ts +97 -7
- package/dist/utils/expand-fields.js +97 -7
- package/dist/utils/filter-tokens.js +0 -1
- package/dist/utils/freeze-schema.d.ts +38 -1
- package/dist/utils/freeze-schema.js +10 -0
- package/dist/utils/humanize-label.d.ts +60 -0
- package/dist/utils/humanize-label.js +62 -0
- package/dist/utils/managedBy.d.ts +27 -2
- package/dist/utils/normalize-list-view.d.ts +36 -6
- package/dist/utils/normalize-list-view.js +93 -9
- package/dist/utils/number-display.d.ts +155 -0
- package/dist/utils/number-display.js +71 -0
- package/dist/utils/predicate-fields.d.ts +29 -4
- package/dist/utils/predicate-fields.js +44 -4
- package/dist/utils/resolve-view-id.d.ts +31 -0
- package/dist/utils/resolve-view-id.js +45 -0
- 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 +57 -0
- package/dist/utils/sort-query.js +35 -0
- package/dist/utils/unmaterialized-fields.d.ts +52 -0
- package/dist/utils/unmaterialized-fields.js +57 -0
- package/dist/validation/index.d.ts +1 -0
- package/dist/validation/index.js +1 -0
- package/dist/validation/schema-validator.js +105 -0
- 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.js +0 -2
- package/package.json +5 -5
- package/dist/__benchmarks__/core.bench.d.ts +0 -8
- package/dist/__benchmarks__/core.bench.js +0 -53
- package/dist/utils/merge-views-into-objects.d.ts +0 -19
- package/dist/utils/merge-views-into-objects.js +0 -39
|
@@ -108,3 +108,46 @@ export declare function normalizeColumnIdentity<T>(entry: T): T;
|
|
|
108
108
|
* every consumer already special-cases it.
|
|
109
109
|
*/
|
|
110
110
|
export declare function normalizeColumnIdentities<T>(columns: T): T;
|
|
111
|
+
/**
|
|
112
|
+
* The spec's canonical key for "what this column is CALLED on screen".
|
|
113
|
+
*
|
|
114
|
+
* `ListColumnSchema` (`@objectstack/spec/view`) spells a column's display text
|
|
115
|
+
* `label`, next to its `field`. It is metadata vocabulary, exactly like
|
|
116
|
+
* {@link CANONICAL_COLUMN_IDENTITY_KEY} — not an objectui legacy spelling, and
|
|
117
|
+
* not something to amputate.
|
|
118
|
+
*/
|
|
119
|
+
export declare const CANONICAL_COLUMN_LABEL_KEY = "label";
|
|
120
|
+
/**
|
|
121
|
+
* NOT metadata — the display half of the same boundary
|
|
122
|
+
* {@link TABLE_ADAPTER_COLUMN_KEY} draws for identity.
|
|
123
|
+
*
|
|
124
|
+
* `header` is `TableColumn.header` (`packages/types/src/data-display.ts`), the
|
|
125
|
+
* data-table ADAPTER's own key for a column's rendered title. The adapter
|
|
126
|
+
* declares `header` and does not declare `label`; the spec declares `label` and
|
|
127
|
+
* does not declare `header`. Those are two vocabularies, and the translation
|
|
128
|
+
* between them belongs at the producer — one translation, one place
|
|
129
|
+
* (objectui#5068) — never as a tolerated `col.header || col.label` alias inside
|
|
130
|
+
* the adapter (objectui#5351).
|
|
131
|
+
*/
|
|
132
|
+
export declare const TABLE_ADAPTER_HEADER_KEY = "header";
|
|
133
|
+
/**
|
|
134
|
+
* Read a column entry's display text on its way INTO the data-table adapter —
|
|
135
|
+
* the header counterpart of {@link columnIdentity} (objectui#5351).
|
|
136
|
+
*
|
|
137
|
+
* Adapter-first, which is the opposite order from {@link columnIdentity} and is
|
|
138
|
+
* deliberate. `columnIdentity` folds several METADATA spellings of one metadata
|
|
139
|
+
* concept, so the canonical metadata key wins. This reader crosses a boundary
|
|
140
|
+
* between two vocabularies instead: an author who wrote the adapter's own
|
|
141
|
+
* `header` addressed the table directly, and a producer must not overwrite that
|
|
142
|
+
* — the same rule `RelatedList` and `ObjectDataTable` already state for an
|
|
143
|
+
* author-supplied `accessorKey` (objectui#5022).
|
|
144
|
+
*
|
|
145
|
+
* Returns `undefined` — not `''` — when neither key carries text, so a caller
|
|
146
|
+
* can tell "no header authored" from "the header is deliberately blank" and
|
|
147
|
+
* stamp nothing rather than stamping an empty string.
|
|
148
|
+
*
|
|
149
|
+
* A bare-string column entry has no display text of its own; producers derive
|
|
150
|
+
* one from the field key (`humanizeFieldKey`) or the object schema's label, and
|
|
151
|
+
* that derivation is theirs, not this reader's.
|
|
152
|
+
*/
|
|
153
|
+
export declare function columnHeader(entry: unknown): string | undefined;
|
|
@@ -125,7 +125,6 @@ function warnOnConflictingIdentity(entry, identity, losing) {
|
|
|
125
125
|
if (warnedConflicts.has(memo))
|
|
126
126
|
continue;
|
|
127
127
|
warnedConflicts.add(memo);
|
|
128
|
-
// eslint-disable-next-line no-console
|
|
129
128
|
console.warn(`[ObjectUI] Column carries two identities: \`${CANONICAL_COLUMN_IDENTITY_KEY}: ` +
|
|
130
129
|
`'${identity}'\` and \`${key}: '${String(entry[key])}'\`. ` +
|
|
131
130
|
`\`${CANONICAL_COLUMN_IDENTITY_KEY}\` wins — it is the only key ` +
|
|
@@ -208,3 +207,50 @@ export function normalizeColumnIdentities(columns) {
|
|
|
208
207
|
});
|
|
209
208
|
return (changed ? next : columns);
|
|
210
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* The spec's canonical key for "what this column is CALLED on screen".
|
|
212
|
+
*
|
|
213
|
+
* `ListColumnSchema` (`@objectstack/spec/view`) spells a column's display text
|
|
214
|
+
* `label`, next to its `field`. It is metadata vocabulary, exactly like
|
|
215
|
+
* {@link CANONICAL_COLUMN_IDENTITY_KEY} — not an objectui legacy spelling, and
|
|
216
|
+
* not something to amputate.
|
|
217
|
+
*/
|
|
218
|
+
export const CANONICAL_COLUMN_LABEL_KEY = 'label';
|
|
219
|
+
/**
|
|
220
|
+
* NOT metadata — the display half of the same boundary
|
|
221
|
+
* {@link TABLE_ADAPTER_COLUMN_KEY} draws for identity.
|
|
222
|
+
*
|
|
223
|
+
* `header` is `TableColumn.header` (`packages/types/src/data-display.ts`), the
|
|
224
|
+
* data-table ADAPTER's own key for a column's rendered title. The adapter
|
|
225
|
+
* declares `header` and does not declare `label`; the spec declares `label` and
|
|
226
|
+
* does not declare `header`. Those are two vocabularies, and the translation
|
|
227
|
+
* between them belongs at the producer — one translation, one place
|
|
228
|
+
* (objectui#5068) — never as a tolerated `col.header || col.label` alias inside
|
|
229
|
+
* the adapter (objectui#5351).
|
|
230
|
+
*/
|
|
231
|
+
export const TABLE_ADAPTER_HEADER_KEY = 'header';
|
|
232
|
+
/**
|
|
233
|
+
* Read a column entry's display text on its way INTO the data-table adapter —
|
|
234
|
+
* the header counterpart of {@link columnIdentity} (objectui#5351).
|
|
235
|
+
*
|
|
236
|
+
* Adapter-first, which is the opposite order from {@link columnIdentity} and is
|
|
237
|
+
* deliberate. `columnIdentity` folds several METADATA spellings of one metadata
|
|
238
|
+
* concept, so the canonical metadata key wins. This reader crosses a boundary
|
|
239
|
+
* between two vocabularies instead: an author who wrote the adapter's own
|
|
240
|
+
* `header` addressed the table directly, and a producer must not overwrite that
|
|
241
|
+
* — the same rule `RelatedList` and `ObjectDataTable` already state for an
|
|
242
|
+
* author-supplied `accessorKey` (objectui#5022).
|
|
243
|
+
*
|
|
244
|
+
* Returns `undefined` — not `''` — when neither key carries text, so a caller
|
|
245
|
+
* can tell "no header authored" from "the header is deliberately blank" and
|
|
246
|
+
* stamp nothing rather than stamping an empty string.
|
|
247
|
+
*
|
|
248
|
+
* A bare-string column entry has no display text of its own; producers derive
|
|
249
|
+
* one from the field key (`humanizeFieldKey`) or the object schema's label, and
|
|
250
|
+
* that derivation is theirs, not this reader's.
|
|
251
|
+
*/
|
|
252
|
+
export function columnHeader(entry) {
|
|
253
|
+
if (!isRecord(entry))
|
|
254
|
+
return undefined;
|
|
255
|
+
return (asIdentity(entry[TABLE_ADAPTER_HEADER_KEY]) ?? asIdentity(entry[CANONICAL_COLUMN_LABEL_KEY]));
|
|
256
|
+
}
|
|
@@ -8,23 +8,50 @@
|
|
|
8
8
|
/**
|
|
9
9
|
* Period-over-period comparison config for dashboard widgets.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
11
|
+
* Converged (objectstack#5011) onto the contract the analytics executor
|
|
12
|
+
* already implements — `DatasetSelection.compareTo`, i.e. `DatasetCompareTo`
|
|
13
|
+
* in `@objectstack/spec` (`contracts/analytics-service.ts`). This type is that
|
|
14
|
+
* contract's thin projection, so the same widget key means the same thing on
|
|
15
|
+
* the ADR-0021 dataset path and on this legacy inline object-provider path.
|
|
16
|
+
*
|
|
17
|
+
* - `kind: 'previousPeriod'` — the equal-length window immediately before the
|
|
18
|
+
* current one. On the inline path that is done by substituting `current_*` /
|
|
19
|
+
* `today` date macro tokens with their `last_*` / `yesterday` counterparts
|
|
20
|
+
* (`current_quarter_start` → `last_quarter_start`), so it works best when the
|
|
21
|
+
* filter is written with date macros.
|
|
22
|
+
* - `kind: 'previousYear'` — re-resolve the filter's date macros against a
|
|
23
|
+
* `now` shifted back one calendar year (same week / month / quarter, one year
|
|
24
|
+
* earlier).
|
|
25
|
+
* - `dimension` — OPTIONAL, and deliberately never read on this path. It names
|
|
26
|
+
* the dataset time dimension whose `dateRange` the EXECUTOR shifts. That
|
|
27
|
+
* resolution lives at the producer of the comparison so that every caller
|
|
28
|
+
* gets the same answer or the same loud error; a renderer that guessed a
|
|
29
|
+
* dimension would trade "loud error" for "quietly wrong window" — precisely
|
|
30
|
+
* the failure class this convergence exists to end.
|
|
31
|
+
*
|
|
32
|
+
* **Design note — a plain strict object, NOT a union** (objectstack#5011,
|
|
33
|
+
* framework#5014). The retired shape was a three-branch union
|
|
34
|
+
* (`'previousPeriod' | 'previousYear' | { offset }`); zod collapses a failed
|
|
35
|
+
* union into a bare `Invalid input`, so the prescriptions written inside each
|
|
36
|
+
* arm never reached the author. One strict object keeps the rejection specific.
|
|
37
|
+
* It also leaves this renderer with exactly one contract to read — no second
|
|
38
|
+
* de-facto dialect to be tolerant about (AGENTS.md #0.1).
|
|
39
|
+
*
|
|
40
|
+
* The `{ offset: '7d' | '1M' | '1y' }` arm went with the union: `{ offset: '1y' }`
|
|
41
|
+
* IS `kind: 'previousYear'` (rewritten deterministically upstream), while
|
|
42
|
+
* `'7d'` / `'1M'` have no faithful target — an author restates that window on
|
|
43
|
+
* the widget's own `filter` and asks for `kind: 'previousPeriod'` (registered
|
|
44
|
+
* semantic migration `dashboard-widget-compareto-offset`).
|
|
19
45
|
*/
|
|
20
|
-
export
|
|
21
|
-
|
|
22
|
-
|
|
46
|
+
export interface CompareToConfig {
|
|
47
|
+
kind: 'previousPeriod' | 'previousYear';
|
|
48
|
+
dimension?: string;
|
|
49
|
+
}
|
|
23
50
|
/**
|
|
24
|
-
* Resolve a filter for a period-over-period comparison query.
|
|
51
|
+
* Resolve a filter for a period-over-period comparison query. Dispatches on
|
|
52
|
+
* `compareTo.kind` — the only discriminator the converged shape has:
|
|
25
53
|
*
|
|
26
54
|
* - `previousYear` — re-resolve date macros against a `now` shifted back by one year.
|
|
27
|
-
* - `{ offset }` — re-resolve date macros against a `now` shifted by the given duration.
|
|
28
55
|
* - `previousPeriod` — substitute `current_*` / `today` tokens with `last_*` / `yesterday`
|
|
29
56
|
* before resolving.
|
|
30
57
|
*/
|
package/dist/utils/compare-to.js
CHANGED
|
@@ -44,44 +44,19 @@ function substituteTokens(value, map) {
|
|
|
44
44
|
}
|
|
45
45
|
return value;
|
|
46
46
|
}
|
|
47
|
-
function shiftNow(now, offset) {
|
|
48
|
-
const m = offset.match(/^(\d+)([dwMy])$/);
|
|
49
|
-
if (!m)
|
|
50
|
-
return null;
|
|
51
|
-
const n = parseInt(m[1], 10);
|
|
52
|
-
const unit = m[2];
|
|
53
|
-
const x = new Date(now);
|
|
54
|
-
if (unit === 'd')
|
|
55
|
-
x.setDate(x.getDate() - n);
|
|
56
|
-
else if (unit === 'w')
|
|
57
|
-
x.setDate(x.getDate() - n * 7);
|
|
58
|
-
else if (unit === 'M')
|
|
59
|
-
x.setMonth(x.getMonth() - n);
|
|
60
|
-
else if (unit === 'y')
|
|
61
|
-
x.setFullYear(x.getFullYear() - n);
|
|
62
|
-
else
|
|
63
|
-
return null;
|
|
64
|
-
return x;
|
|
65
|
-
}
|
|
66
47
|
/**
|
|
67
|
-
* Resolve a filter for a period-over-period comparison query.
|
|
48
|
+
* Resolve a filter for a period-over-period comparison query. Dispatches on
|
|
49
|
+
* `compareTo.kind` — the only discriminator the converged shape has:
|
|
68
50
|
*
|
|
69
51
|
* - `previousYear` — re-resolve date macros against a `now` shifted back by one year.
|
|
70
|
-
* - `{ offset }` — re-resolve date macros against a `now` shifted by the given duration.
|
|
71
52
|
* - `previousPeriod` — substitute `current_*` / `today` tokens with `last_*` / `yesterday`
|
|
72
53
|
* before resolving.
|
|
73
54
|
*/
|
|
74
55
|
export function shiftFilterByCompareTo(filter, compareTo, now = new Date()) {
|
|
75
|
-
if (compareTo === 'previousYear') {
|
|
56
|
+
if (compareTo.kind === 'previousYear') {
|
|
76
57
|
const shifted = new Date(now.getFullYear() - 1, now.getMonth(), now.getDate(), now.getHours(), now.getMinutes(), now.getSeconds());
|
|
77
58
|
return resolveDateMacros(filter, shifted);
|
|
78
59
|
}
|
|
79
|
-
if (typeof compareTo === 'object' && compareTo && 'offset' in compareTo) {
|
|
80
|
-
const shifted = shiftNow(now, compareTo.offset);
|
|
81
|
-
if (!shifted)
|
|
82
|
-
return resolveDateMacros(filter, now);
|
|
83
|
-
return resolveDateMacros(filter, shifted);
|
|
84
|
-
}
|
|
85
60
|
// previousPeriod
|
|
86
61
|
const substituted = substituteTokens(filter, CURRENT_TO_LAST_TOKENS);
|
|
87
62
|
return resolveDateMacros(substituted, now);
|
|
@@ -91,11 +66,8 @@ export function shiftFilterByCompareTo(filter, compareTo, now = new Date()) {
|
|
|
91
66
|
* comparison window. Used by metric widgets to label the trend delta.
|
|
92
67
|
*/
|
|
93
68
|
export function compareToTrendLabelKey(compareTo, filter) {
|
|
94
|
-
if (compareTo === 'previousYear')
|
|
69
|
+
if (compareTo.kind === 'previousYear')
|
|
95
70
|
return 'vsLastYear';
|
|
96
|
-
if (typeof compareTo === 'object' && compareTo && 'offset' in compareTo) {
|
|
97
|
-
return 'vsPreviousPeriod';
|
|
98
|
-
}
|
|
99
71
|
// previousPeriod — sniff the dominant token in the filter
|
|
100
72
|
const json = filter ? JSON.stringify(filter) : '';
|
|
101
73
|
if (/current_year_|year_start|year_end/.test(json))
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
* Everything in this module is pure and synchronous so the binding rules
|
|
19
19
|
* are unit-testable in isolation from React and the data layer.
|
|
20
20
|
*/
|
|
21
|
-
import type { DashboardComponentSchema, DashboardWidgetSchema, PageVariable } from '@object-ui/types';
|
|
21
|
+
import type { DashboardComponentSchema, DashboardWidgetSchema, I18nLabel, PageVariable } from '@object-ui/types';
|
|
22
|
+
import { DATE_RANGE_PRESETS } from '@objectstack/spec/ui';
|
|
22
23
|
/** Reserved filter name for the dashboard's built-in date range. */
|
|
23
24
|
export declare const DATE_RANGE_FILTER_NAME = "dateRange";
|
|
24
25
|
export interface DashboardFilterDef {
|
|
@@ -26,17 +27,41 @@ export interface DashboardFilterDef {
|
|
|
26
27
|
name: string;
|
|
27
28
|
/** Default target field when a widget declares no explicit binding. */
|
|
28
29
|
field: string;
|
|
29
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Display label, in @objectstack/spec's `I18nLabel` vocabulary — a plain
|
|
32
|
+
* string, or an inline per-locale map (`{ en: 'Owner', 'zh-CN': '负责人' }`).
|
|
33
|
+
*
|
|
34
|
+
* Widened from `string` under the objectstack#5428 ruling of 2026-08-06
|
|
35
|
+
* (option A): `GlobalFilterSchema.label` has been `I18nLabel` on the spec
|
|
36
|
+
* side since 17.0.0-rc.6, so declaring it `string` here made this module
|
|
37
|
+
* NARROWER than the contract it implements — which is exactly why the filter
|
|
38
|
+
* bar's map reads were invisible to `tsc` (objectui#4163).
|
|
39
|
+
*
|
|
40
|
+
* This module is locale-free BY DESIGN (`@object-ui/core` is logic-only), so
|
|
41
|
+
* it carries the authored vocabulary through unresolved and the RENDER side
|
|
42
|
+
* collapses it to the active language. Resolving here would need a locale
|
|
43
|
+
* this layer has no business knowing.
|
|
44
|
+
*/
|
|
45
|
+
label?: string | I18nLabel;
|
|
30
46
|
type: 'text' | 'select' | 'date' | 'number' | 'lookup' | 'dateRange';
|
|
31
47
|
/**
|
|
32
48
|
* Static options, NORMALIZED to `{ value, label }` pairs by
|
|
33
|
-
* `resolveDashboardFilterDefs` —
|
|
34
|
-
*
|
|
35
|
-
*
|
|
49
|
+
* `resolveDashboardFilterDefs` — consumers always see the object form.
|
|
50
|
+
*
|
|
51
|
+
* The canonical authoring form is @objectstack/spec's `{ value, label }`
|
|
52
|
+
* pair, and it is the ONLY one the platform accepts at publish. A bare-string
|
|
53
|
+
* shorthand in a STORED document is still lifted here, with a deprecation
|
|
54
|
+
* warning, on the objectstack#7917 retirement schedule — see
|
|
55
|
+
* `normalizeFilterOptions`. Do not author a new one.
|
|
56
|
+
*
|
|
57
|
+
* The PAIR SHAPE is normalized; the label's own vocabulary is not. `label`
|
|
58
|
+
* is `I18nLabel` in `GlobalFilterSchema.options[]` too, and it reaches the
|
|
59
|
+
* renderer as authored — see `normalizeFilterOptions` for why collapsing it
|
|
60
|
+
* here was data loss rather than normalization.
|
|
36
61
|
*/
|
|
37
62
|
options?: Array<{
|
|
38
63
|
value: string;
|
|
39
|
-
label: string;
|
|
64
|
+
label: string | I18nLabel;
|
|
40
65
|
}>;
|
|
41
66
|
optionsFrom?: {
|
|
42
67
|
object: string;
|
|
@@ -58,8 +83,29 @@ export interface DateRangeValue {
|
|
|
58
83
|
from?: string;
|
|
59
84
|
to?: string;
|
|
60
85
|
}
|
|
61
|
-
/**
|
|
62
|
-
|
|
86
|
+
/**
|
|
87
|
+
* Preset keys the filter bar offers, in display order — the spec's list,
|
|
88
|
+
* RE-EXPORTED since objectui#4167 rather than derived from the local bounds
|
|
89
|
+
* table (objectstack#4115).
|
|
90
|
+
*
|
|
91
|
+
* `@objectstack/spec` 17.0.0-rc.6 publishes `DATE_RANGE_PRESETS`, and its own
|
|
92
|
+
* doc comment names this module as one of the three copies the extraction
|
|
93
|
+
* (objectstack#4614) existed to collapse: "it used to exist three times —
|
|
94
|
+
* inline in `dateRange.defaultRange`, as `PRESET_RANGES` in objectui's
|
|
95
|
+
* `dashboard-filters`, and as a hand-written table in
|
|
96
|
+
* `content/docs/ui/dashboards.mdx`". So the burn-down direction here is not a
|
|
97
|
+
* judgement call, it is upstream's stated intent, and the two lists were
|
|
98
|
+
* already identical in content AND display order — the copy had nothing to
|
|
99
|
+
* protect.
|
|
100
|
+
*
|
|
101
|
+
* What stays local is the BOUNDS table above, which is the other half of
|
|
102
|
+
* #4614's design ("the two vocabularies live one import apart and neither
|
|
103
|
+
* restates the other's grammar"): the spec owns which presets exist, this
|
|
104
|
+
* module owns what each one resolves to in date-macro tokens.
|
|
105
|
+
*/
|
|
106
|
+
export { DATE_RANGE_PRESETS };
|
|
107
|
+
/** Reset the shorthand-options warn-once memo. Exported for tests. */
|
|
108
|
+
export declare function resetDashboardFilterWarnings(): void;
|
|
63
109
|
/**
|
|
64
110
|
* Normalize a dashboard schema's filter declarations into a flat list of
|
|
65
111
|
* filter definitions. The built-in `dateRange` (when declared) comes first
|