Skip to content

Commit 2edcaff

Browse files
os-zhuangclaude
andauthored
chore: drop compactLayout fallback reads (alias retired by framework#2536) (#2187)
framework#2539 removed the deprecated spelling from the spec (create() rejects, parse strips, no mirror) — served metadata carries highlightFields only, so these 6 fallback reads can never fire again. deriveHighlightFields tests flipped: the retired spelling is now IGNORED (heuristic applies) instead of read. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 9aec681 commit 2edcaff

7 files changed

Lines changed: 30 additions & 50 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@object-ui/plugin-grid': patch
3+
'@object-ui/plugin-detail': patch
4+
'@object-ui/app-shell': patch
5+
---
6+
7+
Drop the `compactLayout` fallback reads (6 sites: ObjectGrid default columns, deriveHighlightFields, RecordDetailView highlight strip + child preview, ObjectView ×2, InterfaceListPage). The deprecated spelling was retired from the spec by framework#2539 (framework#2536) — served metadata carries `highlightFields` only, so the fallbacks could never fire again; keeping them would teach the retired key to the next reader.

packages/app-shell/src/views/InterfaceListPage.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,18 +70,16 @@ function resolveSourceView(objectDef: any, sourceView?: string): any | undefined
7070
* Default column set when the resolved view carries none — mirrors
7171
* ObjectView's data-mode fallback so an interface page never renders a
7272
* column-less grid. Priority: the `highlightFields` semantic role
73-
* (ADR-0085; deprecated `compactLayout` read as fallback), else the first
74-
* business fields (system/audit columns excluded).
73+
* (ADR-0085), else the first business fields (system/audit columns
74+
* excluded).
7575
*/
7676
const SYSTEM_FIELDS = new Set([
7777
'id', 'created_at', 'createdAt', 'updated_at', 'updatedAt',
7878
'deleted_at', 'deletedAt', 'created_by', 'createdBy',
7979
'updated_by', 'updatedBy', '_version', '_rev',
8080
]);
8181
function defaultColumnsFromObject(objectDef: any): string[] {
82-
const curated = Array.isArray(objectDef?.highlightFields) && objectDef.highlightFields.length > 0
83-
? objectDef.highlightFields
84-
: objectDef?.compactLayout;
82+
const curated = objectDef?.highlightFields;
8583
if (Array.isArray(curated) && curated.length > 0) {
8684
return curated.filter((n: string) => objectDef.fields?.[n]);
8785
}

packages/app-shell/src/views/ObjectView.tsx

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,7 @@ function ObjectViewInner({ dataSource, objects, onEdit, externalRefreshKey }: an
236236
'updated_by', 'updatedBy', '_version', '_rev',
237237
]);
238238
let defaultColumns: string[] = [];
239-
const curated = Array.isArray(objectDef?.highlightFields) && objectDef.highlightFields.length > 0
240-
? objectDef.highlightFields
241-
: objectDef?.compactLayout;
239+
const curated = objectDef?.highlightFields;
242240
if (Array.isArray(curated) && curated.length > 0) {
243241
defaultColumns = curated.filter((n: string) => objectDef.fields?.[n]);
244242
} else if (objectDef?.fields) {
@@ -489,8 +487,7 @@ function ObjectViewInner({ dataSource, objects, onEdit, externalRefreshKey }: an
489487
// Resolve Views from objectDef.listViews (camelCase per @objectstack/spec)
490488
const views = useMemo(() => {
491489
// Default column resolution priority:
492-
// 1. The `highlightFields` semantic role (ADR-0085; deprecated
493-
// `compactLayout` read as fallback).
490+
// 1. The `highlightFields` semantic role (ADR-0085).
494491
// 2. Business fields only — exclude system-managed identifiers/audit
495492
// columns (id, created_at, updated_at, …) and fields explicitly
496493
// marked hidden/readonly on the schema. First 5 kept for compactness.
@@ -500,9 +497,7 @@ function ObjectViewInner({ dataSource, objects, onEdit, externalRefreshKey }: an
500497
'updated_by', 'updatedBy', '_version', '_rev',
501498
]);
502499
const resolveDefaultColumns = (): string[] => {
503-
const curated = Array.isArray(objectDef.highlightFields) && objectDef.highlightFields.length > 0
504-
? objectDef.highlightFields
505-
: objectDef.compactLayout;
500+
const curated = objectDef.highlightFields;
506501
if (Array.isArray(curated) && curated.length > 0) {
507502
return curated.filter((n: string) => objectDef.fields?.[n]);
508503
}

packages/app-shell/src/views/RecordDetailView.tsx

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,12 +1379,9 @@ export function RecordDetailView({ dataSource, objects, onEdit, objectNameOverri
13791379
return base;
13801380
})();
13811381

1382-
// Build highlightFields from the object's semantic role (ADR-0085):
1383-
// top-level `highlightFields`, with the deprecated `compactLayout`
1384-
// spelling as fallback for pre-11.7 metadata that reaches consumers
1385-
// un-normalized. Bare field names resolve label/type from the field def.
1386-
const rawHighlightFields =
1387-
(objectDef as any).highlightFields ?? (objectDef as any).compactLayout ?? [];
1382+
// Build highlightFields from the object's semantic role (ADR-0085).
1383+
// Bare field names resolve label/type from the field def.
1384+
const rawHighlightFields = (objectDef as any).highlightFields ?? [];
13881385
const highlightFields: HighlightField[] = (Array.isArray(rawHighlightFields) ? rawHighlightFields : [])
13891386
.map((f: any): HighlightField | null => {
13901387
const name = typeof f === 'string' ? f : f?.name;
@@ -1494,9 +1491,7 @@ export function RecordDetailView({ dataSource, objects, onEdit, objectNameOverri
14941491
childObjectDef?.displayNameField ||
14951492
(Array.isArray(childObjectDef?.highlightFields)
14961493
? childObjectDef.highlightFields[0]
1497-
: Array.isArray(childObjectDef?.compactLayout)
1498-
? childObjectDef.compactLayout[0]
1499-
: undefined),
1494+
: undefined),
15001495
onNew,
15011496
onViewAll,
15021497
onRowClick,

packages/plugin-detail/src/synth/__tests__/buildDefaultPageSchema.test.ts

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -698,23 +698,15 @@ describe('semantic-role hints (ADR-0085 / #2065)', () => {
698698
});
699699

700700
describe('deriveHighlightFields', () => {
701-
it('highlightFields wins over the deprecated compactLayout spelling', () => {
701+
it('reads the highlightFields semantic role', () => {
702702
expect(
703-
deriveHighlightFields(
704-
{
705-
...leadDef,
706-
highlightFields: ['phone', 'rating'],
707-
compactLayout: ['email'],
708-
},
709-
'status',
710-
),
703+
deriveHighlightFields({ ...leadDef, highlightFields: ['phone', 'rating'] }, 'status'),
711704
).toEqual(['phone', 'rating']);
712705
});
713706

714-
it('reads the deprecated compactLayout when highlightFields is absent', () => {
715-
expect(
716-
deriveHighlightFields({ ...leadDef, compactLayout: ['email', 'phone'] }, 'status'),
717-
).toEqual(['email', 'phone']);
707+
it('ignores the retired compactLayout spelling (framework#2536) — heuristic applies instead', () => {
708+
const derived = deriveHighlightFields({ ...leadDef, compactLayout: ['email', 'phone'] }, 'status');
709+
expect(derived).not.toEqual(['email', 'phone']);
718710
});
719711

720712
it('drops non-string entries and caps the declared list at max', () => {

packages/plugin-detail/src/synth/buildDefaultPageSchema.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,6 @@ export interface ObjectDefLike {
4040
/** Semantic role (ADR-0085): the object's most important fields —
4141
* drives the highlight strip (first 4). */
4242
highlightFields?: string[];
43-
/** @deprecated Renamed to `highlightFields` (ADR-0085). Read as a
44-
* fallback for pre-11.7 metadata that reaches consumers un-normalized. */
45-
compactLayout?: string[];
4643
/** Name of the field that holds the record's display title (e.g. `name`,
4744
* `subject`). When present we exclude it from the auto-derived highlight
4845
* list to avoid duplicating the page H1. */
@@ -266,14 +263,12 @@ export function deriveHighlightFields(
266263
max = 4,
267264
): string[] {
268265
if (!def) return [];
269-
// Semantic role first (ADR-0085): top-level `highlightFields`, with the
270-
// deprecated `compactLayout` spelling as a fallback for pre-11.7 metadata
271-
// that reaches consumers un-normalized (the spec mirrors the two on parse).
266+
// Semantic role first (ADR-0085): top-level `highlightFields`. (The
267+
// deprecated `compactLayout` fallback was retired with the alias —
268+
// framework#2536.)
272269
const declared = Array.isArray(def.highlightFields) && def.highlightFields.length > 0
273270
? def.highlightFields
274-
: Array.isArray(def.compactLayout) && def.compactLayout.length > 0
275-
? def.compactLayout
276-
: null;
271+
: null;
277272
if (declared) {
278273
return declared
279274
.filter((n): n is string => typeof n === 'string' && n.length > 0)

packages/plugin-grid/src/ObjectGrid.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,8 +1201,7 @@ export const ObjectGrid: React.FC<ObjectGridProps> = ({
12011201

12021202
const generatedColumns: any[] = [];
12031203
// Default columns priority (when schema doesn't specify columns):
1204-
// 1. The object's `highlightFields` semantic role (ADR-0085; deprecated
1205-
// `compactLayout` spelling read as fallback for pre-11.7 metadata).
1204+
// 1. The object's `highlightFields` semantic role (ADR-0085).
12061205
// 2. Otherwise, all schema fields with system-managed fields pushed to the end.
12071206
//
12081207
// Also drop fields that are platform-managed identifiers/audit columns or
@@ -1214,14 +1213,13 @@ export const ObjectGrid: React.FC<ObjectGridProps> = ({
12141213
'deleted_at', 'deletedAt', 'created_by', 'createdBy',
12151214
'updated_by', 'updatedBy', '_version', '_rev',
12161215
]);
1217-
const compactLayout: string[] | undefined =
1218-
(objectSchema as any)?.highlightFields ?? (objectSchema as any)?.compactLayout;
1216+
const highlightFields: string[] | undefined = (objectSchema as any)?.highlightFields;
12191217
const allFieldNames = Object.keys(objectSchema.fields || {});
12201218
let fieldsToShow: string[];
12211219
if (schemaFields) {
12221220
fieldsToShow = schemaFields;
1223-
} else if (compactLayout?.length) {
1224-
fieldsToShow = compactLayout.filter((n) => objectSchema.fields?.[n]);
1221+
} else if (highlightFields?.length) {
1222+
fieldsToShow = highlightFields.filter((n) => objectSchema.fields?.[n]);
12251223
} else {
12261224
// Drop hidden + readonly system-managed fields, then push remaining
12271225
// system identifier/audit fields to the end as a fallback.

0 commit comments

Comments
 (0)