@object-ui/core 17.6.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 +6610 -0
- package/README.md +101 -14
- package/dist/actions/ActionEngine.d.ts +4 -2
- package/dist/actions/ActionEngine.js +13 -8
- package/dist/actions/ActionRunner.d.ts +288 -27
- package/dist/actions/ActionRunner.js +443 -63
- package/dist/actions/TransactionManager.d.ts +7 -2
- package/dist/actions/actionKeys.d.ts +9 -7
- package/dist/actions/actionKeys.js +57 -14
- package/dist/actions/actionResponse.js +2 -2
- package/dist/actions/index.d.ts +1 -0
- package/dist/actions/index.js +1 -0
- package/dist/actions/recordDelete.d.ts +118 -0
- package/dist/actions/recordDelete.js +112 -0
- 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 +86 -0
- package/dist/evaluator/ExpressionEvaluator.js +184 -12
- package/dist/evaluator/FormulaFunctions.d.ts +0 -10
- package/dist/evaluator/FormulaFunctions.js +166 -27
- package/dist/evaluator/declaredPredicate.d.ts +93 -9
- package/dist/evaluator/declaredPredicate.js +117 -16
- package/dist/evaluator/fieldRules.d.ts +88 -4
- package/dist/evaluator/fieldRules.js +203 -31
- package/dist/evaluator/index.d.ts +1 -0
- package/dist/evaluator/index.js +1 -0
- package/dist/evaluator/listConditional.d.ts +103 -34
- package/dist/evaluator/listConditional.js +127 -50
- package/dist/evaluator/optionRules.d.ts +77 -6
- package/dist/evaluator/optionRules.js +87 -10
- package/dist/evaluator/predicateInput.d.ts +15 -4
- package/dist/evaluator/predicateInput.js +35 -2
- package/dist/evaluator/rowPredicateCanon.d.ts +7 -18
- package/dist/evaluator/rowPredicateCanon.js +65 -115
- 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 +14 -0
- package/dist/index.js +80 -2
- package/dist/protocols/index.d.ts +0 -1
- package/dist/protocols/index.js +9 -1
- package/dist/registry/Registry.d.ts +358 -31
- 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/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 +95 -112
- package/dist/utils/chart-presentation.js +169 -104
- package/dist/utils/chart-series.d.ts +131 -5
- package/dist/utils/chart-series.js +98 -16
- 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 +389 -46
- 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/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 +76 -6
- package/dist/utils/expand-fields.js +76 -6
- 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 -33
- package/dist/utils/grouping-fields.d.ts +61 -0
- package/dist/utils/grouping-fields.js +84 -0
- package/dist/utils/managedBy.d.ts +3 -3
- 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 +121 -1
- package/dist/utils/normalize-list-view.js +186 -6
- package/dist/utils/number-display.d.ts +63 -14
- 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 +45 -12
- package/dist/utils/predicate-fields.js +137 -12
- 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/sort-query.d.ts +115 -15
- 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/without-denied-fields.d.ts +49 -0
- package/dist/utils/without-denied-fields.js +52 -0
- package/dist/validation/index.d.ts +8 -4
- package/dist/validation/index.js +8 -4
- package/dist/validation/schema-validator.d.ts +1 -1
- package/dist/validation/schema-validator.js +200 -82
- package/dist/validation/validators/object-validation-engine.d.ts +1 -1
- package/dist/validation/validators/object-validation-engine.js +14 -3
- package/package.json +8 -9
- 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
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* date-display - the ONE date/datetime display path behind every field cell,
|
|
10
|
+
* grid card, gantt tooltip and dataset measure in the console.
|
|
11
|
+
*
|
|
12
|
+
* These functions are unchanged; what changed is where they live. They were
|
|
13
|
+
* written in `@object-ui/fields`' barrel (`packages/fields/src/index.tsx`),
|
|
14
|
+
* which is a React package, so `@object-ui/core` could not reach them - and
|
|
15
|
+
* `core`'s `utils/dataset-format.ts` is exactly the caller that needed them:
|
|
16
|
+
* `formatMeasure` returned `String(v)` for any non-numeric value, so a `min` /
|
|
17
|
+
* `max` measure over a date field rendered its raw 24-character ISO string on
|
|
18
|
+
* the metric tile, in chart values, in dataset table cells and in the
|
|
19
|
+
* metadata-admin dataset preview (objectui#7178).
|
|
20
|
+
*
|
|
21
|
+
* The fix is the move, NOT a second formatter here. That choice is the whole
|
|
22
|
+
* point, and it is the lesson of objectui#4576: when the percent convention
|
|
23
|
+
* was duplicated across this same package boundary, a list cell and a
|
|
24
|
+
* dashboard measure drifted apart (`1.234,5 %` beside `1.234,5%` in a German
|
|
25
|
+
* session) while both were "correct". `dataset-format.ts`'s own header records
|
|
26
|
+
* that history, and `number-display.ts` next door is the same remedy applied
|
|
27
|
+
* to numbers: the pure function moves DOWN into the React-free engine and the
|
|
28
|
+
* upper package re-exports it, so there is one home and nothing to drift.
|
|
29
|
+
*
|
|
30
|
+
* `@object-ui/fields` re-exports the formatting symbols below under their
|
|
31
|
+
* original names, so `formatDate` / `formatDateTime` /
|
|
32
|
+
* `formatDateTimeCompactParts` / `formatRelativeDate` / `DateDisplayOptions`
|
|
33
|
+
* keep working unchanged for `ObjectGrid`, `ObjectGantt`,
|
|
34
|
+
* `plugin-dashboard`'s `recordFields` and the `date` cell renderer.
|
|
35
|
+
* `toDisplayDate` is exported from `@object-ui/core` alone (objectui#10183),
|
|
36
|
+
* and so are `toDisplayEndDate` / `toInclusiveEndDay`, the end read and its
|
|
37
|
+
* inverse both gantt surfaces share (objectui#11141).
|
|
38
|
+
*
|
|
39
|
+
* The `datetime` CELL face joined this file in objectui#7443. It used to be a
|
|
40
|
+
* second convention inlined in `DateTimeCellRenderer`: two `Intl` option bags
|
|
41
|
+
* for one field type, kept in step by nothing, while `date` had exactly one.
|
|
42
|
+
* It is `formatDateTime`'s `'compact'` style now, byte-identical to what the
|
|
43
|
+
* cell rendered before.
|
|
44
|
+
*
|
|
45
|
+
* Pure by construction (no React, no i18n): the only ambient inputs are `Intl`
|
|
46
|
+
* and the clock, and the one phrase `Intl` cannot produce ("Overdue Nd") comes
|
|
47
|
+
* in through the INJECTED `options.t`, the same way `buildDatasetFieldHelpers`
|
|
48
|
+
* in `dataset-format.ts` takes `fieldLabel`.
|
|
49
|
+
*
|
|
50
|
+
* ⚠️ There is a third ambient input, and it is the one this module has to
|
|
51
|
+
* decide about rather than pass on: the VIEWER's timezone. A value carrying a
|
|
52
|
+
* time is an instant and renders in that zone; a DATE-ONLY value names a
|
|
53
|
+
* calendar day, carries no instant, and must render as that day everywhere.
|
|
54
|
+
* `toDisplayDate` below is the single parse step that tells the two apart —
|
|
55
|
+
* every function here goes through it (objectui#10110), and so does every
|
|
56
|
+
* caller elsewhere that needs a face or a day comparison none of these
|
|
57
|
+
* functions produce (objectui#10183).
|
|
58
|
+
*/
|
|
59
|
+
/**
|
|
60
|
+
* Options shared by {@link formatDate} / {@link formatRelativeDate} /
|
|
61
|
+
* {@link formatDateTime}. One bag, and each function reads the keys it needs:
|
|
62
|
+
* `dueLike` and `t` only matter on the relative path, `style` is read by
|
|
63
|
+
* `formatDateTime` and by `formatDate` (see below).
|
|
64
|
+
*/
|
|
65
|
+
export interface DateDisplayOptions {
|
|
66
|
+
dueLike?: boolean;
|
|
67
|
+
/** BCP-47 display locale (ADR-0053 tenant default); falls back to the runtime locale. */
|
|
68
|
+
locale?: string;
|
|
69
|
+
/** i18n translate fn for phrases `Intl` can't produce (the "Overdue Nd" wording). */
|
|
70
|
+
t?: (key: string, params?: Record<string, unknown>) => string;
|
|
71
|
+
/**
|
|
72
|
+
* Named face, read by {@link formatDateTime} and {@link formatDate}. Each
|
|
73
|
+
* reads its own vocabulary: `'compact'` is `formatDateTime`'s dense grid
|
|
74
|
+
* cell face (objectui#7443), `'short'` and `'relative'` are `formatDate`'s;
|
|
75
|
+
* anything else, or absent, is that function's default face.
|
|
76
|
+
*
|
|
77
|
+
* It rides here rather than in a second positional parameter because
|
|
78
|
+
* `formatDateTime(value, options?)` is a PUBLISHED signature with `options`
|
|
79
|
+
* in position two (objectui#4272). A positional `style` would have displaced
|
|
80
|
+
* it: TypeScript would reject the old call, but a JavaScript caller would
|
|
81
|
+
* silently hand its options bag to the style slot and lose its locale —
|
|
82
|
+
* the #4272 defect again.
|
|
83
|
+
*
|
|
84
|
+
* ⚠️ On {@link formatDate} this key COLLIDES with a positional parameter of
|
|
85
|
+
* the same name, so the precedence is PINNED, not left to implementation
|
|
86
|
+
* order: **the positional argument wins**, and this key is consulted only
|
|
87
|
+
* when the positional slot is `undefined` (objectui#7745). See
|
|
88
|
+
* {@link formatDate}'s own note for why that direction and not the other.
|
|
89
|
+
*
|
|
90
|
+
* ⚠️ {@link formatRelativeDate} still does NOT read this key — the
|
|
91
|
+
* maintainer's long-run ruling on objectui#7443 names `formatDate` only, and
|
|
92
|
+
* whether the relative path's out-of-window fallback should honour it is a
|
|
93
|
+
* separate, deliberate call (objectui#7745's report).
|
|
94
|
+
*/
|
|
95
|
+
style?: string;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* A date that exists — the pattern alone would accept `2024-02-31`.
|
|
99
|
+
*
|
|
100
|
+
* `true` only for a date-only ISO string (`YYYY-MM-DD`, the shape
|
|
101
|
+
* {@link ISO_DATE_ONLY_RE} names) whose year, month and day read back
|
|
102
|
+
* unchanged from the calendar. Anything else — another shape, a time part, an
|
|
103
|
+
* out-of-range month, or a day its month does not have — is `false`.
|
|
104
|
+
*
|
|
105
|
+
* ## Why this lives here (objectui#10026)
|
|
106
|
+
*
|
|
107
|
+
* It used to be module-private in `@object-ui/components`' filter builder,
|
|
108
|
+
* which refused `2026-02-30` at the AUTHORING boundary, while this module — a
|
|
109
|
+
* package below it, unable to import it — ROLLED the same value into March 2nd
|
|
110
|
+
* on every display face. One concept, two answers. It moved down, exactly as
|
|
111
|
+
* `formatDate` itself moved into this package (see the header), so the filter
|
|
112
|
+
* builder and {@link toDisplayDate} now ask the one function. ⛔ A move, not a
|
|
113
|
+
* copy: `@object-ui/components` imports it from here.
|
|
114
|
+
*
|
|
115
|
+
* ## Why the engine cannot answer this on its own
|
|
116
|
+
*
|
|
117
|
+
* ECMAScript's date-string parse accepts a DAY of `01`-`31` for every month
|
|
118
|
+
* and rolls the surplus forward: `Date.parse('2026-02-30')` is March 2nd, not
|
|
119
|
+
* `NaN`. It rejects an out-of-range MONTH (`2026-13-01`), which is why a
|
|
120
|
+
* bad month was always a dash on the display path and a bad day never was.
|
|
121
|
+
* So the day is read back instead: build the date in UTC (no zone, so no DST
|
|
122
|
+
* gap can move it) and require all three parts to survive.
|
|
123
|
+
*
|
|
124
|
+
* `setUTCFullYear` rather than `Date.UTC(year, …)`: the latter maps years
|
|
125
|
+
* 0-99 onto 1900+y, so it answered `false` for `0026-08-01` — a real day,
|
|
126
|
+
* and one {@link toDisplayDate} renders (it undoes the same legacy mapping for
|
|
127
|
+
* the same reason). The move had to fix that, or refusing through this
|
|
128
|
+
* function would have dashed every year below 100.
|
|
129
|
+
*/
|
|
130
|
+
export declare function isRealCalendarDate(dateOnly: string): boolean;
|
|
131
|
+
/**
|
|
132
|
+
* The ONE `value -> Date` step behind every function below.
|
|
133
|
+
*
|
|
134
|
+
* ## The defect (objectui#10110)
|
|
135
|
+
*
|
|
136
|
+
* ECMAScript parses the two ISO shapes into two different zones: a DATE-ONLY
|
|
137
|
+
* form is UTC, while a date-TIME form without an offset is local. So
|
|
138
|
+
* `new Date('2026-08-01')` is UTC midnight, and every getter this module then
|
|
139
|
+
* uses — `getFullYear`, `getMonth`, `getDate`, and `toLocaleDateString`'s own
|
|
140
|
+
* internal ones — reads it back in the VIEWER's zone. West of UTC that lands
|
|
141
|
+
* on the previous calendar day: `2026-08-01` rendered `Jul 31` for a UTC-7
|
|
142
|
+
* viewer while the stored value, the API response and a UTC+8 viewer all said
|
|
143
|
+
* August 1st. The relative branch shifted with it, one day per day
|
|
144
|
+
* (`2026-08-31` read `4 days ago` on the 3rd instead of `3 days ago`),
|
|
145
|
+
* because it compares two LOCAL start-of-days.
|
|
146
|
+
*
|
|
147
|
+
* ## The repair, and why it is not an offset
|
|
148
|
+
*
|
|
149
|
+
* A date-only value names a CALENDAR DAY and carries no instant, so there is
|
|
150
|
+
* no conversion to perform: this rebuilds it at LOCAL midnight of the day it
|
|
151
|
+
* names, and every local getter downstream then reports that same day in
|
|
152
|
+
* every zone. ⛔ Nothing here adds or subtracts hours. An offset that
|
|
153
|
+
* cancels the shift would be wrong again at the next DST boundary and wrong
|
|
154
|
+
* in the opposite direction for a viewer EAST of UTC, where the UTC-midnight
|
|
155
|
+
* parse already lands on the right day — the co-located suite drives both.
|
|
156
|
+
* `GridField`'s sub-grid cell already parsed its own date-only values this
|
|
157
|
+
* way before reaching `formatDate`; this is that treatment, moved to the one
|
|
158
|
+
* place every caller passes through (the sub-grid reads it from here since
|
|
159
|
+
* objectui#10301).
|
|
160
|
+
*
|
|
161
|
+
* A value with a time part is not rebuilt, in both spellings: it HAS an
|
|
162
|
+
* instant, and rendering an instant in the viewer's zone is the whole point
|
|
163
|
+
* of a `datetime`. The regex is what separates them, so the split is the
|
|
164
|
+
* VALUE's shape and never the field's declared type, which this module (pure,
|
|
165
|
+
* no schema) cannot see.
|
|
166
|
+
*
|
|
167
|
+
* ## What it refuses (objectui#10026)
|
|
168
|
+
*
|
|
169
|
+
* The engine's own parse still decides what is a date at all (`2026-13-01`
|
|
170
|
+
* is an Invalid Date, and so every face below renders `—`), with ONE
|
|
171
|
+
* addition: a date-only value naming a day its month does not have. The
|
|
172
|
+
* engine accepts `2026-02-30` and rolls it into March 2nd, so before this
|
|
173
|
+
* card every date face showed a real day nobody wrote, with nothing to say
|
|
174
|
+
* so. This step hands back an Invalid Date for it instead — the same answer
|
|
175
|
+
* the engine gives a bad month — so every caller renders the face it already
|
|
176
|
+
* renders for an unparsable value: `—` from the functions below, `EmptyValue`
|
|
177
|
+
* from the field carriers that read validity here, the raw stored string from
|
|
178
|
+
* a caller whose unparsable face is the raw string. ⛔ No new marker.
|
|
179
|
+
*
|
|
180
|
+
* The maintainer's ruling on objectui#10026 (option A) placed the refusal on
|
|
181
|
+
* the SHARED path, in this step and not in any one consumer: refusing in a
|
|
182
|
+
* single face would re-create the list-cell-versus-measure split
|
|
183
|
+
* objectui#4576 recorded. {@link isRealCalendarDate} is the one judgement,
|
|
184
|
+
* shared with the filter builder's authoring boundary.
|
|
185
|
+
*
|
|
186
|
+
* A value that carries a TIME is refused the same way when the day it is
|
|
187
|
+
* written on does not exist (objectui#10301): `2026-02-30T10:00:00Z` parses
|
|
188
|
+
* too, and rendered `Mar 2, 2026, 10:00 AM` on every datetime face. Triage
|
|
189
|
+
* graded that an inherited branch of the same ruling. The judgement reads the
|
|
190
|
+
* value's leading `YYYY-MM-DD` AS WRITTEN, never the day its instant lands on
|
|
191
|
+
* in some zone: a parsed `Date` always names a real day, so a check made after
|
|
192
|
+
* any conversion could only miss the refusal, and a real day written with an
|
|
193
|
+
* offset (`2026-02-28T23:30:00-05:00`, March 1st in UTC) is kept. A real
|
|
194
|
+
* date-time is otherwise untouched — no rebuild, the engine's instant.
|
|
195
|
+
*
|
|
196
|
+
* ## Why it is exported (objectui#10183)
|
|
197
|
+
*
|
|
198
|
+
* A caller that formats with its own `Intl` options — a face none of the
|
|
199
|
+
* functions below produce, such as the record summary chip's
|
|
200
|
+
* `dateStyle: 'medium'` — or that compares a value against "today" needs the
|
|
201
|
+
* `Date` itself, not a string. Such callers used to parse the value on their
|
|
202
|
+
* own (`new Date(value)`, or `Date.parse` and then a `Date` handed to
|
|
203
|
+
* `formatDate`, which this step then leaves alone), so the objectui#10110
|
|
204
|
+
* repair never reached them and each still read a date-only value one day
|
|
205
|
+
* early west of UTC. They take the `Date` from here instead.
|
|
206
|
+
*
|
|
207
|
+
* ⛔ Read the result with LOCAL getters or local-zone `Intl` formatting only.
|
|
208
|
+
* For a date-only value it is local midnight of the named day, so its
|
|
209
|
+
* `toISOString()` / UTC getters name the previous day east of UTC — hand
|
|
210
|
+
* those the stored value, never this.
|
|
211
|
+
*/
|
|
212
|
+
export declare function toDisplayDate(value: string | Date | number): Date;
|
|
213
|
+
/**
|
|
214
|
+
* THE ONE READ of a stored END, where a bar or span is drawn to
|
|
215
|
+
* (objectui#11141): {@link toDisplayDate}'s read, and then, for a date-only
|
|
216
|
+
* value only, the next day's local midnight.
|
|
217
|
+
*
|
|
218
|
+
* ## The rule (objectui#11112's ruling, one home since objectui#11141)
|
|
219
|
+
*
|
|
220
|
+
* A date-only end is INCLUSIVE: `2024-01-01` to `2024-01-15` runs through
|
|
221
|
+
* January 15th, so the span is drawn to the start of the 16th, and a
|
|
222
|
+
* successor starting `2024-01-16` begins exactly where it ends. A span whose
|
|
223
|
+
* date-only start and end name the same day is one day long, across a DST
|
|
224
|
+
* change too: the step is a calendar day (`setDate`), never 24 hours, so it
|
|
225
|
+
* lands on the next local midnight, or on that day's first hour where its
|
|
226
|
+
* midnight does not exist. That is how a project plan and the schema
|
|
227
|
+
* catalog's gantt plans author an end.
|
|
228
|
+
*
|
|
229
|
+
* The result is the EXCLUSIVE end instant of a half-open span `[start, end)`,
|
|
230
|
+
* the form every gantt surface draws and schedules with. Date-only is decided
|
|
231
|
+
* by the value's own shape, with {@link isRealCalendarDate}, exactly as
|
|
232
|
+
* {@link toDisplayDate} decides it, so an end reads its day as a start does and
|
|
233
|
+
* then runs to that day's end. A value with a time part, a number or a `Date`
|
|
234
|
+
* is an instant: the span ends at it, and it is handed back as
|
|
235
|
+
* {@link toDisplayDate} hands it back.
|
|
236
|
+
*
|
|
237
|
+
* {@link toInclusiveEndDay} is the exact inverse: it names the day a span
|
|
238
|
+
* ending here runs through, so a read and a write of a date-only end agree.
|
|
239
|
+
*
|
|
240
|
+
* ⛔ One rule, one place: `plugin-timeline`'s gantt variant and
|
|
241
|
+
* `plugin-gantt` both read their ends here. A second copy of the step in a
|
|
242
|
+
* consumer is how the two gantt surfaces came to draw one plan a day apart.
|
|
243
|
+
* ⛔ Read the result with LOCAL getters only, as {@link toDisplayDate}'s is.
|
|
244
|
+
*/
|
|
245
|
+
export declare function toDisplayEndDate(value: string | Date | number): Date;
|
|
246
|
+
/**
|
|
247
|
+
* The day a span ending at `end` runs through: local midnight of the day that
|
|
248
|
+
* holds the last instant before `end` (objectui#11141).
|
|
249
|
+
*
|
|
250
|
+
* This is the exact inverse of {@link toDisplayEndDate} on a date-only end:
|
|
251
|
+
* the instant it reads `2024-01-15` as, local midnight of the 16th, names the
|
|
252
|
+
* 15th here, so a read, a drag and a write of a stored date-only end leave it
|
|
253
|
+
* the day it was, and a bar dragged to end at a day's local midnight names the
|
|
254
|
+
* day BEFORE it. An end inside a day (a `datetime` end, or a shift band's
|
|
255
|
+
* edge) names that day, the last one the span reaches into.
|
|
256
|
+
*
|
|
257
|
+
* It names a day for display and for a date-only write. ⛔ It is not a read of
|
|
258
|
+
* a stored value, and a `datetime` end still keeps its own instant: hand this
|
|
259
|
+
* only to a face that names a day, or to a field that stores one. Read the
|
|
260
|
+
* result with LOCAL getters only; an Invalid Date stays invalid.
|
|
261
|
+
*/
|
|
262
|
+
export declare function toInclusiveEndDay(end: Date): Date;
|
|
263
|
+
/**
|
|
264
|
+
* Format date as relative time (e.g., "3 days ago", "Today", "Overdue 3d"),
|
|
265
|
+
* localized via `Intl.RelativeTimeFormat` (objectstack-ai/objectstack#3040).
|
|
266
|
+
*
|
|
267
|
+
* `dueLike` gates the "Overdue" wording — a past `start_date`/`created_at`
|
|
268
|
+
* isn't overdue, only a past due/deadline-semantic field is. Non-due-like
|
|
269
|
+
* past dates render as plain "N days ago" instead. The overdue phrase has no
|
|
270
|
+
* `Intl` equivalent, so it resolves through `options.t` (key
|
|
271
|
+
* `fields.relativeDate.overdue`) with an English fallback.
|
|
272
|
+
*/
|
|
273
|
+
export declare function formatRelativeDate(value: string | Date | number, options?: DateDisplayOptions): string;
|
|
274
|
+
/**
|
|
275
|
+
* Format date value.
|
|
276
|
+
*
|
|
277
|
+
* The named face comes from EITHER spelling — the positional `style`
|
|
278
|
+
* parameter or `options.style` — and the precedence between them is pinned
|
|
279
|
+
* (objectui#7745):
|
|
280
|
+
*
|
|
281
|
+
* > **The positional argument wins. `options.style` is consulted only when the
|
|
282
|
+
* > positional slot is `undefined`.**
|
|
283
|
+
*
|
|
284
|
+
* Before #7745 only the positional spelling was read here, while
|
|
285
|
+
* {@link formatDateTime} read only the `options` one — one shared bag, two
|
|
286
|
+
* spellings for one concept, and on THIS function the options spelling did
|
|
287
|
+
* nothing at all: `formatDate(v, undefined, { style: 'short' })` silently
|
|
288
|
+
* rendered the default face with no diagnostic. Reading the key is the
|
|
289
|
+
* additive half of the maintainer's long-run ruling on objectui#7443.
|
|
290
|
+
*
|
|
291
|
+
* Why the positional wins, and not the newer key:
|
|
292
|
+
*
|
|
293
|
+
* - It is the ONLY direction that is purely additive. It fires exactly on
|
|
294
|
+
* the input that is a silent no-op today (positional absent, key present);
|
|
295
|
+
* every call that renders a face today renders the same face after.
|
|
296
|
+
* - The bag is SHARED across three functions, so it can legitimately carry a
|
|
297
|
+
* key meant for a sibling — that is this module's convention (`dueLike`
|
|
298
|
+
* and `t` are read by `formatRelativeDate` alone). A caller that built
|
|
299
|
+
* `{ style: 'compact', locale }` for `formatDateTime` and reused the bag
|
|
300
|
+
* for `formatDate(v, 'short', bag)` must keep its short face. A key aimed
|
|
301
|
+
* at a sibling function must not outrank an argument written for THIS
|
|
302
|
+
* call — that is objectui#7694's shape (an alias overwriting the canonical
|
|
303
|
+
* key), and the silent-override half of objectui#4272.
|
|
304
|
+
*
|
|
305
|
+
* `??`, not `||`, is what "absent" means here: `formatDate(v, '', bag)`
|
|
306
|
+
* renders the default face today and must keep doing so, so an empty string
|
|
307
|
+
* counts as GIVEN and does not fall through to the key.
|
|
308
|
+
*/
|
|
309
|
+
export declare function formatDate(value: string | Date | number, style?: string, options?: DateDisplayOptions): string;
|
|
310
|
+
/**
|
|
311
|
+
* The `'compact'` datetime face as the two halves a grid cell paints
|
|
312
|
+
* separately — `7/4/2024` and `7:00 am` for `2024-07-04T07:00:00Z` in `en-US`.
|
|
313
|
+
*
|
|
314
|
+
* `formatDateTime(value, { style: 'compact', ...options })` is exactly
|
|
315
|
+
* `date + ' ' + time` of what this returns, so a caller that wants the face
|
|
316
|
+
* as ONE string and a caller that wants to style the halves differently
|
|
317
|
+
* cannot drift apart. That drift is what objectui#7443 recorded:
|
|
318
|
+
* `DateTimeCellRenderer` inlined these two option bags and never called this
|
|
319
|
+
* module, so `datetime` had two display conventions while `date` had one —
|
|
320
|
+
* the same shape as objectui#4576, which this repo has already paid for once.
|
|
321
|
+
*
|
|
322
|
+
* `null` for a value this module renders as `'—'`; the cell renders its own
|
|
323
|
+
* empty state for those, so it never sees the dash.
|
|
324
|
+
*/
|
|
325
|
+
export declare function formatDateTimeCompactParts(value: string | Date | number, options?: DateDisplayOptions): {
|
|
326
|
+
date: string;
|
|
327
|
+
time: string;
|
|
328
|
+
} | null;
|
|
329
|
+
/**
|
|
330
|
+
* Format datetime value.
|
|
331
|
+
*
|
|
332
|
+
* `options.style` selects a named face:
|
|
333
|
+
*
|
|
334
|
+
* - `'compact'` — the dense grid face, `7/4/2024 7:00 am` in `en-US`. It is
|
|
335
|
+
* what every `datetime` CELL renders, and what `DateTimeCellRenderer`
|
|
336
|
+
* used to build from its own inlined `Intl` bags (objectui#7443).
|
|
337
|
+
* - anything else, including absent — the verbose default,
|
|
338
|
+
* `Jul 4, 2024, 07:00 AM` in `en-US`. Unchanged, and still what a
|
|
339
|
+
* non-cell caller (dataset measure, gantt tooltip, data-table) gets.
|
|
340
|
+
*
|
|
341
|
+
* The signature is `(value, options?)`, unchanged: `style` is a key of
|
|
342
|
+
* `options`, not a positional parameter, so every existing call —
|
|
343
|
+
* `formatDateTime(v, { locale })` included — keeps meaning exactly what it
|
|
344
|
+
* meant (see the note on `DateDisplayOptions.style` for why the positional
|
|
345
|
+
* shape `formatDate` uses was refused here).
|
|
346
|
+
*
|
|
347
|
+
* `options` is optional, so a caller that passes nothing keeps the exact
|
|
348
|
+
* runtime-default behavior it had. Before objectui#4272 the parameter did not
|
|
349
|
+
* exist at all, which meant no caller could localize this function however
|
|
350
|
+
* hard it tried — it always handed `Intl` an `undefined` tag, i.e. the
|
|
351
|
+
* MACHINE's locale, which is neither of the repo's two locale channels.
|
|
352
|
+
* Callers should pass the tag from `useDisplayLocale()`.
|
|
353
|
+
*/
|
|
354
|
+
export declare function formatDateTime(value: string | Date | number, options?: DateDisplayOptions): string;
|