Repository navigation
feat(app-shell): Studio authors relatedList, the related-list block's columns/sort/filter, ordered highlight fields, and slotted-by-default record pages - #27163
Conversation
…converting it to a full page is an explicit action Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4EjjRbbbwV5u1Vx4Ge7TT
…den / primary) and relatedListFilter with the shared filter builder Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4EjjRbbbwV5u1Vx4Ge7TT
…, filter, limit, showViewAll and add Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4EjjRbbbwV5u1Vx4Ge7TT
…, drag-to-reorder list of up to six with a strip preview Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4EjjRbbbwV5u1Vx4Ge7TT
…-record-page controls Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4EjjRbbbwV5u1Vx4Ge7TT
Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4EjjRbbbwV5u1Vx4Ge7TT
… from the field's own Hidden checkbox Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4EjjRbbbwV5u1Vx4Ge7TT
…hape, so the converted page passes the spec Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4EjjRbbbwV5u1Vx4Ge7TT
…pec props row Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4EjjRbbbwV5u1Vx4Ge7TT
…udio-related-list-controls
席位核对 · PR #27163 ← #27054 · epic PM
|
…udio-related-list-controls
…icit-full path
A record page is now created kind slotted with no regions, so the
seed-and-runtime agreement holds on the copy an explicit full makes: the
seeded record:details still carries the runtime's sections in the persisted
shape, and the fieldGroups CONTROL still seeds group references. One new case
pins the default half: a draft with no kind, or slotted, seeds
{ kind: 'slotted' } and no record:details at all.
Claude-Session: https://claude.ai/code/session_cdb7a717-def7-4e71-9988-f089fbaa18ff
Co-authored-by: Claude <noreply@anthropic.com>
席位核对 · PR #27163 ← #27054 · epic PM
|
Part of #27054. This PR lands four of the card's five Studio items. The card's
relatedListsdrag-to-order editor stays open on the card: it waits for #27069 to ship the key, as the card and the dispatch both say.Clause-②: no
Metadata-protocol: none
维护者速读
ui/packages/app-shell/src/views/metadata-admin/inspectors/ObjectFieldInspector.tsx(RelatedListFields);ui/packages/app-shell/src/views/metadata-admin/previews/PagePreview.tsx(convertToFull,写回的是 spec 认可的落盘形状);ui/packages/app-shell/src/views/metadata-admin/anchors.ts(新建页 seed)。claude/issue-27054-evidence。What changes
lookupormaster_detailfield, a new section edits the two keys that describe the child collection on the parent's record page.relatedList. "Don't show" writesfalseand "Primary (in body)" writes'primary'. "Show" leaves the key absent, the spec's own "true or absent = shown"; a storedtruereads as Show.relatedListFilteris edited with the same builder the dataset designer uses over the list toolbar'sFilterBuilder. That field is now one shared component,FilterConditionField, moved out of the dataset inspector rather than copied. A stored filter the flat builder cannot hold (nested, OR) is kept as stored and named.treefields, which the spec gives no related list.record:related_listblock inspector. The block now curatescolumns,sort,filter,limit,showViewAllandadd, besideobjectName,relationshipFieldandtitle. Every one is a propRecordRelatedListPropsalready declares.columns,sortandfilterread the child object named byobjectName.filteruses the list toolbar's builder (thefilter-builderform widget's own field, now exported), so it writes specViewFilterRule[].showViewAllshows the spec default (on) when unset.addis a JSON box with a shape sample, the only door that can add that nested key.sort, orcolumnsgiven as saved-view column objects.highlightFieldsas an ordered list. Rows can be dragged or moved with up and down buttons (the keyboard path). Fields are appended up to six, and a longer stored list is shown whole. A strip preview below draws the picked order. Removing the last field removes the key. The editor isHighlightFieldsEditorinstudio-design.recordgivesslotted, everything elsefull. This is a newpage-kindcreate-derive transform.kind: 'slotted'with no slots, which renders as the synthesized default and keeps following the object.fullat create, or with the designer's new "Convert to full page" action.fulland dropsslots.Why
The record-page v3 epic makes the record page read these keys, and the spec already declares all of them, but Studio had no control for most of them. Authors had to hand-write JSON, or had no door at all:
relatedListhad no control, and the block's column, sort and filter props were absent. A new record page was seeded with a copy of the synthesized page, so every authored page forked from the default on the day it was created. The maintainer's rulings on the card fix the shape of each control.Tests
All test runs are on head
23a697c2(after mergingmain), run from the repository root.ObjectFieldInspector.relatedList-27054.test.tsx: 「主要」 on the task → lead FK writes'primary', and the lead page built by the realderiveRelatedListsandbuildDefaultPageSchemachain lists tasks first. Before the click, the control order is notes first.PageBlockInspector.relatedListProps-27054.test.tsx: columns, filter and limit round-trip, and every written block passesComponentPropsMap['record:related_list'].ObjectSettingsPanel.highlightOrder-27054.test.tsx: order is preserved through buttons, drag and add, plus the cap of six.PagePreview.slottedDefault-27054.test.tsxandanchors.page-seed.test.ts: a new record page iskind: 'slotted'with empty slots and passesPageSchema. Convert-to-full and full-create both write blocks that pass their spec props rows.7731242e37):recordDetailSections.agreement-12442.test.ts— the seed-and-runtime agreement now holds on the explicit-fullpath (fullSeedFor), and a new case pins that a record page created with no kind orslottedseeds exactly{ kind: 'slotted' }with norecord:detailsnode; the three-call-sites block is unchanged.block-config-i18n.test.ts: one more add button, one more literal placeholder, and the limit literal is now 5.block-config.test.ts: the newfilter-ruleskind.block-config-schema-parity-8216.test.ts: the census now judges the row editor's element through the single array arm of astring | arrayunion, which is more coverage, not less.Test and type-check readings
Ablations (one-shot, restored by blob hash)
Acceptance notes
relatedLists: ['task', 'event', …], an ordered list of child relationships likehighlightFieldsis of fields; unlisted ones follow the derived order; a name that matches no inbound relationship is refused #27069's half; until it lands, the runtime still promotes a primary list to its own tab. The dispatch asked the help text to cite spec: an object declares the business order of its related lists —relatedLists: ['task', 'event', …], an ordered list of child relationships likehighlightFieldsis of fields; unlisted ones follow the derived order; a name that matches no inbound relationship is refused #27069, but runtime strings carry no tracker number in this repo, so the reference sits in the code comment onRelatedListFields.relatedListabsent rather than writingtrue. The spec reads both the same, and the inspector's convention is that unset deletes the key.relatedListFilterrow is still a JSON box. The spec's field form (field.form.ts) renders there throughSchemaForm, which has no object-field context in that drawer. Plumbing one would also re-bind every*Fieldrow of the field form to the wrong object:displayFieldnames a field of the referenced object. The filter builder is in the Studio field inspector, where the three-state control lives, sofield.form.tsandpage.form.tsare unchanged.block-config.tsandPageBlockInspector.tsxlive undermetadata-admin/(previews and inspectors), andObjectSettingsPanel.tsxunderstudio-design/. The fix also touchesPagePreview.tsx,PageBlockCanvas.tsx,createDerive.ts,registry.ts,widgets.tsx(one export) andDatasetDefaultInspector.tsx(the shared filter field moved out). New files areFilterConditionField.tsxandHighlightFieldsEditor.tsx.record:detailsthat names its fields draws a location field as "[Object]" and a select value raw. This is the same output the existing full-create seed already produces onmain. Another is thatPageBlockInspector's JSON fields render aLabelthat is not associated with their textarea.Verification
claude/issue-27054-evidence. They come from a local showcase app (--freshdatabase) running this branch.showcase_invoice.accountwith 「Primary (in body)」 selected.slottedfor a record page.23a697c2), the patch round's in 6466884994 (head7731242e37; 34 / 34 derived, thevitest run scripts/red is the macOS host gap). CI on7731242e37: all nine required contexts success, Test UI 16 / 16 shards.7731242e37(the cloud head23a697c2merged withmainb8615afabaplus the re-pin).Human Minimum
packages/specholds no runtime logic. (No spec change.)main, one pull request.packages/spectouched: not touched.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_01Q4EjjRbbbwV5u1Vx4Ge7TT
Generated by Claude Code