Skip to content
This repository was archived by the owner on Oct 26, 2026. It is now read-only.

Commit 551e5ae

Browse files
committed
Merge origin/main into claude/issue-11913-import-time-identity-email
Claude-Session: https://claude.ai/code/session_01CGZy1BGCjdN5cXqL9cnvB8 Co-authored-by: Claude <noreply@anthropic.com>
2 parents 603ad4e + 0bbb67b commit 551e5ae

100 files changed

Lines changed: 5709 additions & 673 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
'@object-ui/types': minor
3+
---
4+
5+
A form field declares `scale` and `currencyConfig` on both faces, by reference to `@objectstack/spec`'s `FieldSchema`, so the strict authoring face accepts the decimal places and the fixed currency the field widgets read (objectui#11070).
6+
7+
A hand-authored `form` hands each field widget the `fields[]` entry itself as its metadata carrier. The `number`, `percent`, `formula` and `summary` widgets read `scale` off it, and the `currency` widget reads `currencyConfig` through `resolveFieldCurrency`. Both keys always drew; only the declarations were missing. Each is now the spec member itself, value checks included.
8+
9+
- **TypeScript.** `FormField` gains `scale?: SpecField['scale']` and `currencyConfig?: SpecField['currencyConfig']`. Both used to fall to the index signature's `any`. A typed literal with a value of the wrong type (a string `scale`, a `currencyMode` outside `fixed` / `dynamic`) is now a compile error.
10+
- **zod (`@object-ui/types/zod`).** WIDENS on the strict authoring face (`StrictAnyComponentSchema`): `fields[].scale` and `fields[].currencyConfig` used to be refused with `unrecognized_keys`, and now parse. NARROWS on the tolerant face (`safeValidateSchema`), where both keys used to be stripped unjudged: a `scale` that is not a whole number from 0 to 100 is now refused, and so is a `currencyConfig` the spec refuses (a `currencyMode` outside `fixed` / `dynamic`, a `defaultCurrency` that is not three characters, or a member the spec's config does not declare, such as the removed `precision`). The values are now kept. No spec default (`dynamic`, `CNY`) is written into the document.
11+
- **`scale` on a `currency` field is refused, on both faces.** The spec's `FieldSchema` refuses it there (objectstack-ai/objectstack#19629): an amount's decimal places are its currency's ISO 4217 minor unit. The `currency` widget never read it. The rule is keyed on `type`, as the spec keys it, and the refusal is the spec's own text. This is the only one of the spec's cross-key rules this face carries. The others (`rows`, `minLength` / `maxLength`, `multiple`) key on the spec's field-type sets, and a form field's `type` is a widget id (`input`, `select`, …) those sets do not hold.
12+
- **Not declared: `currency` on a form field.** The spec's `FieldSchema` refuses it as a field key, so the strict face still refuses it. `resolveFieldCurrency` still reads it at runtime. Declare a fixed currency as `currencyConfig: { currencyMode: 'fixed', defaultCurrency: 'EUR' }`.
13+
14+
BREAKING (`@object-ui/types`), for a document whose form field carries a `scale` or a `currencyConfig` the spec refuses, or a `scale` on a `currency` field: it no longer validates on the tolerant face. Fix the value, or delete `scale` from the `currency` field. (The bump is `minor` by this repo's release model: objectui's major follows the `@objectstack` family major, and its own breaking changes ship as `minor` with the breaking semantics stated here.)
15+
16+
**Clause-②: yes (widening)**: both keys widen the strict face, and their spec value checks, plus the spec's `currency` rule on `scale`, narrow the tolerant face.

‎.changeset/11861-action-presets.md‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
'@object-ui/app-shell': patch
3+
---
4+
5+
Studio's action "New" menu opens on common actions in plain words, with the blank action under "Advanced" (part of objectui#11861: the actions entry).
6+
7+
"New" in an object's Actions view used to add one action, "New action": an update of this record with no field values yet (objectui#11820). It now opens on four starting points, each an action of a shape the spec already has:
8+
9+
- **Change a picklist field** — asks for a new value of the object's first picklist (its own: never a system, hidden or read-only one), then saves it. It is the declarative record update with that field as its one input (`operation: 'update'`, `params: [{ field }]`), labelled "Change Status" for a Status field, and written at once.
10+
- **Run a flow**, **Open a web page**, **Open a page in a dialog** — a `flow`, `url` or `modal` action. The spec refuses each of these without a `target`, and only the author knows which one they mean. So, like a new validation rule waiting for its condition (objectui#11820), the action is listed as not saved and kept in the panel until the action editor's own Flow name, URL or page input is filled in. The first value given writes it. Delete drops it unsent, and leaving the view before then drops it too.
11+
12+
The menu row for "Change a picklist field" names the field it will ask about. When the object has no picklist the author can change, the row is listed disabled, saying what it needs.
13+
14+
The blank action, still named "New action", is unchanged, one click away under "Advanced". No starting point writes a script.
15+
16+
Nothing is added to the package entry: no export, prop, type member or language-pack key. The new copy lives in the metadata-admin designer's own string tables (en and zh).
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
'@object-ui/app-shell': patch
3+
---
4+
5+
Studio's *Explain access* panel picks the object and the operation with the shared `Select`, the control Studio's validation rule editor already picks with (objectui#11865, the *Explain access* part of that card).
6+
7+
The two pickers were browser-native selects, so they looked and behaved differently from Studio's other dropdowns. They now use the shared Radix `Select`: the same trigger, dropdown and keyboard behaviour. In the object list, typing an object's leading letters jumps to it.
8+
9+
What they set is unchanged. Each option makes Explain send the same request as before: an object sends its name, an operation sends its name, and "Select an object…" leaves Explain disabled until an object is picked. Re-picking the current option changes nothing. Each picker keeps the accessible name its label gave the native select.
10+
11+
One display change: when the object the panel holds is not one of the package's objects, the object picker now shows that object. The native select showed "Select an object…" instead, while Explain still asked about the held object.
12+
13+
Unchanged: without a package's object list the object is still a free-text input, and the user picker, the record selector and the explain request itself are untouched.
14+
15+
**Clause-②: no.** No published face moves: `AccessExplainPanel` takes the same props, the package entry exports the same names, and no i18n key is added. What moves is the panel's own markup, described above.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
'@object-ui/app-shell': patch
3+
---
4+
5+
Studio's validation rule editor picks a rule's type, field, built-in format and severity with the shared `Select`, the control the condition builder beside them already uses (objectui#11865, the validation editor's part of that card).
6+
7+
The four pickers were browser-native selects, so they looked and behaved differently from the condition builder's dropdowns in the same editor. They now use the shared Radix `Select`: the same trigger, dropdown and keyboard behaviour.
8+
9+
What they write is unchanged. Each option writes the same rule as before, key for key: a type switch still reseeds the rule, "pick a field" still writes an empty `field`, and the format's "none" still clears `format`. Re-picking the current option writes nothing. Each picker keeps the accessible name its caption gave the native select.
10+
11+
On a read-only package each picker is disabled and wears the shared control's own disabled look (objectui#11781).
12+
13+
One display change: a rule whose stored value is not among a picker's options now shows that value. This happens, for example, when a rule's field has been removed from the object. The native select showed its first option instead ("pick a field", "none", or "error"), which is not what the rule says.
14+
15+
**Clause-②: no.** No published face moves: `ObjectValidationsPanel` takes the same props, the package entry exports the same names, and no i18n key is added. What moves is the editor's own markup, described above.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
'@object-ui/components': patch
3+
'@object-ui/app-shell': patch
4+
'@object-ui/i18n': patch
5+
---
6+
7+
`element:record_picker` and `element:number` bind data through the node-level `dataSource` only (objectui#11880, part of the objectui half of objectstack#11509, ruled A-narrow).
8+
9+
- Neither element reads the flat `properties.object` / `filter` / `sort` / `limit` beside the binding any more: the `composed?.x ?? props.x` fallbacks are gone, and `element:number`'s filter is the binding's alone (the AND with `properties.filter` is gone). An element whose node names no `dataSource.object` issues no query. The flat keys stay published until `@objectstack/spec` retires them in v18; each input's description now says it is not read and names the binding member that is.
10+
- The Studio page designer writes `element:number`'s object to `dataSource.object` at node level, and its measure picker reads the object from there. A stored `properties.object` stays visible in the inspector's Advanced section.
11+
- `element.number.noObject` now names only `dataSource.object`, in all ten language packs.
12+
13+
Breaking for an author who wrote the flat keys on these two elements: move them into `dataSource`. `element:repeater` is unchanged.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
'@object-ui/app-shell': patch
3+
---
4+
5+
The console header no longer shows a "Search ⌘K" trigger where it would open nothing (objectui#11912).
6+
7+
On `/home`, `/ai`, `/organizations` and an organization's own pages, the header showed the search trigger, but no command palette is mounted in those frames: a click did nothing, and neither did `Ctrl+K`. `AppHeader` now draws the trigger (desktop and compact) only under a `CommandPaletteProvider`. Inside an app, where `ConsoleLayout` mounts the provider and `AppContent` mounts the palette, the trigger is unchanged and opens the palette as before.
8+
9+
Nothing is added to the package entry: no export, prop, type member or language-pack key. `useCommandPalette()` keeps its return shape and its no-op fallback outside a provider.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
'@object-ui/app-shell': patch
3+
---
4+
5+
A refused package publish names each refused item with the server's reason, on the package sheet and on Home's *Publish all* and the draft-preview bar (objectui#11922).
6+
7+
`POST /packages/:id/publish-drafts` answers a refusal (`outcome: 'refused'`) on a 200, with the batch's own `success: false` and every item that did not publish, with its reason, in `failed[]`. Both doors read `success` first and stopped there: the package sheet showed "Action failed", and Home's *Publish all* and the draft-preview bar toasted "Publish failed: publish-drafts did not publish this package". Both now read `failed[]` first, as Studio's publish does (objectui#11807).
8+
9+
- **The package sheet.** A rolled-back batch (ADR-0067 D2) keeps its "Nothing was published — the batch rolled back" row and names the causal item with its reason. The drafts rolled back with it are not listed as causes. A refusal with no rolled-back item (the runtime's pre-flight checks) keeps its "Published N; M failed" row and now names every refused item with its reason after it.
10+
- **Home's *Publish all* and the draft-preview bar.** The "Publish failed" toast names the refused items with their reasons, leaving out the rolled-back ones, in place of "publish-drafts did not publish this package".
11+
12+
A published batch, and a batch that carries an envelope `error` with an empty `failed[]`, read as before. Nothing is added to the package entry: no export, prop, type member or language-pack key.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
'@object-ui/components': minor
3+
'@object-ui/plugin-list': patch
4+
---
5+
6+
The list's Sort picker lists a field it keeps only for the current sort as removable, never as a new choice (objectui#11943).
7+
8+
`SortBuilder`'s `fields` entries take an optional `disabled`. A disabled entry is drawn as an unavailable option in every row's dropdown and cannot be chosen by click or keyboard. A row whose field it already is still shows its label, and can be changed to another field or removed. "Add sort" seeds the first entry that is not disabled, and is disabled when every entry is. An entry without the flag behaves as before.
9+
10+
`ListView` sets the flag on each field its Sort picker keeps only because the current sort names it: a field the user may not read, a field the platform refuses to order by, and a relational field listed as ordering by ID. Before this, a stored or URL sort on such a field left it choosable in the picker's other rows, and "Add sort" seeded it when it came first.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
'@object-ui/app-shell': patch
3+
---
4+
5+
Studio Interfaces: a leaf save that goes through now clears the red "Changes not saved" strip an earlier refused save showed (objectui#11950).
6+
7+
A dashboard, report or page leaf whose draft the server refused showed the refusal strip, and the strip stayed after the next edit was saved. It kept saying the draft was refused until the author left the leaf. Each leaf save now starts clear, as the Data and Automations pillars' saves do: the strip goes when the next save is sent, and a save that is refused again shows its own refusal. The notice for a dashboard widget held unsent until it is bound is separate, and a save does not clear it.
8+
9+
Nothing is added to the package entry: no export, prop, type member or language-pack key.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
'@object-ui/app-shell': patch
3+
---
4+
5+
Studio keeps a dashboard widget as an unsaved edit while the author changes its measure, instead of showing a red error the moment the last measure is removed (objectui#11951).
6+
7+
- **Interfaces page, a dashboard in Design mode.** Removing a widget's last measure in the widget inspector no longer sends the widget with an empty measure list, so it no longer draws a 422 and a red "Changes not saved" strip. The widget is held as a new, unbound widget is held: a neutral line names what it needs ("Not saved yet: Values (measures) on the widget “Pipeline” needs a value."), the inspector says "Required" under the measures, and Publish refuses while it is held. Picking another measure saves the dashboard as usual.
8+
- **Every binding input, in every unset state.** A dataset cleared to an empty name is held like an absent one. A dimension list emptied of its last dimension is saved at once wherever the spec accepts that, which is every widget type with one measure. Where the spec refuses it, a scatter with two measures and no dimension, the widget is held and the inspector says "Required" under the dimensions.
9+
10+
A widget the spec refuses for anything else, such as a dataset name that is wrong or two measures on a metric or a pie, is still sent, and its refusal shows the red strip as before. Nothing is added to the package entry: no export, prop, type member or language-pack key.

0 commit comments

Comments
 (0)