|
| 1 | +--- |
| 2 | +"@objectstack/spec": minor |
| 3 | +"@objectstack/rest": patch |
| 4 | +"@objectstack/platform-objects": patch |
| 5 | +--- |
| 6 | + |
| 7 | +feat(spec): a metadata-form repeater's row properties have a name — `DashboardHeaderAction` fields carry a JSON Schema `title`, and `resolveMetadataFormSchemaTitles` overlays a bundle's `metadataForms.<type>.fields.<path>.label` onto a derived JSON Schema (#16458) |
| 8 | + |
| 9 | +## What was wrong |
| 10 | + |
| 11 | +The Studio property panel renders `dashboard.header.actions[]` as a table whose |
| 12 | +column headers read `items.properties[k].title ?? k` from the JSON Schema |
| 13 | +derived by `z.toJSONSchema(DashboardSchema)`. None of the four item fields |
| 14 | +(`label`, `actionUrl`, `actionType`, `icon`) carried a `title`, so the fallback |
| 15 | +arm ran for every locale, English included, and the maker saw machine keys. |
| 16 | +Nothing could localise them either: the only channel, `resolveMetadataFormLabels`, |
| 17 | +decorates the `FormFieldSpec` tree, which the table never reads. And the platform |
| 18 | +catalogs carried `dashboard.fields.header` alone — `dashboard.form.ts` declared |
| 19 | +no children under the composite, so `os i18n extract` emitted no |
| 20 | +`header.showTitle` / `header.showDescription` / `header.actions` key and the |
| 21 | +console shipped a private overlay for exactly those three. |
| 22 | + |
| 23 | +## What changed |
| 24 | + |
| 25 | +- **`@objectstack/spec`** — `DashboardHeaderActionSchema`'s four fields author |
| 26 | + `.meta({ title })` (`Label`, `Action URL`, `Action Type`, `Icon`), so the |
| 27 | + derived JSON Schema names each column. New export |
| 28 | + `resolveMetadataFormSchemaTitles(schema, type, bundle, opts)` in |
| 29 | + `@objectstack/spec/system`: every `metadataForms.<type>.fields.<path>.label` |
| 30 | + at any locale of the chain becomes the `title` of the node the path addresses, |
| 31 | + stepping through an array's `items` so a repeater ROW property is addressed |
| 32 | + as `<repeater>.<property>` (`header.actions.label`) — the same path the |
| 33 | + extractor emits. Pure; returns the input object itself when nothing applies. |
| 34 | + `dashboardForm` enumerates the `header` composite's children |
| 35 | + (`showTitle`, `showDescription`, `actions` with its four row properties) with |
| 36 | + labels equal to the schema titles, pinned equal in `dashboard.test.ts`. |
| 37 | + The mechanism is written down in `content/docs/protocol/kernel/i18n-standard.mdx` |
| 38 | + → "Metadata authoring forms". |
| 39 | +- **`@objectstack/rest`** — `GET /api/v1/meta` localises each entry's derived |
| 40 | + `schema` beside its `form`, through that overlay. |
| 41 | +- **`@objectstack/platform-objects`** — the four generated `metadata-forms` |
| 42 | + catalogs carry the seven new `dashboard.fields` keys, translated in `zh-CN`, |
| 43 | + `ja-JP` and `es-ES`. |
| 44 | + |
| 45 | +Additive: no key removed, no accept set changed, no parsed output moved. |
| 46 | + |
| 47 | +`DashboardSchema.columns` deliberately still declares no `.default(12)`, and |
| 48 | +the reason is stronger than the one #16458 assumed. The card reasoned that the |
| 49 | +renderer already falls back to 12, which would make `.default(12)` |
| 50 | +behaviour-preserving. Measured at objectui `origin/main` |
| 51 | +(`packages/plugin-dashboard/src/DashboardRenderer.tsx`), it does not: a |
| 52 | +`columns`-less dashboard is INFERRED from the widget spans — `maxSpan > 4` |
| 53 | +yields 12 and everything else yields **4** — and the next line switches the |
| 54 | +whole layout on that value (`hasExplicitColumns = schema.columns != null || |
| 55 | +inferredColumns !== 4`, positioned grid vs responsive auto-flow). Declaring the |
| 56 | +default would therefore both retire the inference and flip every auto-flow |
| 57 | +dashboard into the positioned grid. A default that silently materialises a key |
| 58 | +is expensive to take back, so the round stopped at the declared condition and |
| 59 | +left the key alone; see #16458. |
0 commit comments