Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .changeset/naming-drift-dashboard-label-field-length.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
"@object-ui/plugin-dashboard": patch
"@object-ui/fields": patch
---

fix: read spec-canonical keys for dashboard header title and field length rules

Two naming-drift closeouts (framework#1878 / framework#1891):

- `DashboardRenderer` header now falls back to the spec-canonical `label` when
the legacy `title` is absent (mirrors the `DashboardGridLayout` fallback from
#2666) — a spec-compliant dashboard gets its header title.
- Field validation rules now read the spec-canonical camelCase
`minLength`/`maxLength` (what the server record-validator enforces) with the
legacy snake_case `min_length`/`max_length` kept as fallback — authored
length constraints reach the client form.
15 changes: 10 additions & 5 deletions packages/fields/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1966,18 +1966,23 @@ export function buildValidationRules(field: any): any {
// vars); a field-authored `*_message` is a string and passes through as-is,
// still winning over the localized default. See form.tsx `localizeRule`.

// Length validation for text fields
if (field.min_length) {
// Length validation for text fields. The spec-canonical keys are camelCase
// (`minLength`/`maxLength`, @objectstack/spec FieldSchema — what the server
// record-validator enforces); the snake_case pair is the legacy objectui
// spelling, kept as fallback (framework#1878/#1891 naming-drift closeout).
const minLength = (field as any).minLength ?? field.min_length;
if (minLength) {
rules.minLength = {
value: field.min_length,
value: minLength,
message: typeof field.min_length_message === 'string' ? field.min_length_message : undefined,
messageKey: 'validation.minLength',
};
}

if (field.max_length) {
const maxLength = (field as any).maxLength ?? field.max_length;
if (maxLength) {
rules.maxLength = {
value: field.max_length,
value: maxLength,
message: typeof field.max_length_message === 'string' ? field.max_length_message : undefined,
messageKey: 'validation.maxLength',
};
Expand Down
11 changes: 8 additions & 3 deletions packages/plugin-dashboard/src/DashboardRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -775,13 +775,18 @@ const DashboardRendererInner = forwardRef<HTMLDivElement, DashboardRendererProps
return <Fragment key={widgetKey}>{renderedNode}</Fragment>;
};

// The spec-canonical dashboard display name is `label` (@objectstack/spec
// DashboardSchema); `title` is the legacy objectui spelling. Read both so
// spec-compliant dashboards get their header title (framework#1878/#1891;
// mirrors the DashboardGridLayout fallback from #2666).
const headerTitle = schema.title || schema.label;
const headerSection = schema.header && (
<div className="col-span-full mb-4">
{!hideHeaderText && schema.header.showTitle !== false && schema.title && (
{!hideHeaderText && schema.header.showTitle !== false && headerTitle && (
<h2 className="text-lg font-semibold tracking-tight">
{dashName
? dashboardLabel({ name: dashName, label: resolveLabel(schema.title) })
: resolveLabel(schema.title)}
? dashboardLabel({ name: dashName, label: resolveLabel(headerTitle) })
: resolveLabel(headerTitle)}
</h2>
)}
{!hideHeaderText && schema.header.showDescription !== false && schema.description && (
Expand Down
Loading