Repository navigation
fix(plugin-view): the New button opens a create form under a split or popover navigation (objectui#10975) - #11014
Conversation
… / popover Under a `split` or `popover` navigation mode, the node's own or the active named view's, `ObjectView` draws a form only beside a selected record, and `handleCreate` clears that record, so the New button set state that nothing rendered. The create form now opens on the surface `formLayout` falls back to with no `navigation`: the modal for `layout: 'modal'`, the drawer otherwise. A record opened to view or edit still opens beside the list. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
…opover Adds the plugin-view patch changeset, a dated note on the pending objectui#10885 member-4 changeset whose "the New button opens no form" sentence this change makes false (front matter untouched), and the README / docs-page prose: under `split` or `popover` the create form opens on the `layout` surface. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
|
changeset-claim-re-read
|
❌ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. Which half objected:
📦 Bundle Size Report
Size Limits
|
|
|
Contract reviewServed-tier: This is an in-seat review. The diff is one render helper, two call sites, a pin file, a changeset, a dated note, and the README and docs pages (6 files, +190 −2), ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS |
Fixes #10975
Clause-②: no
Under a
splitorpopovernavigation mode,ObjectView's New button now opens a create form. Implemented by thedomain:uiseat 2 dispatch (PM claim5874519919), sessionhttps://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN.What changed
packages/plugin-view/src/ObjectView.tsx: arenderCreateSurfacehelper draws the create form on the drawer or the modal whenformModeiscreate. Thesplitbranch renders it, and so does the default branch whenformLayoutispopover.formLayout,handleCreate,handleEdit,handleRowClickand bothNavigationOverlaybranches are unchanged. A record opened to view or edit still opens beside the list undersplit, and in the popover underpopover.navigation, and the active named view's (read first since PR objectui#10967).ObjectView.splitPopoverCreate-10975.test.tsx: 3 fix rows and 3 controls..changeset/10975-split-popover-create-surface.md:'@object-ui/plugin-view': patch..changeset/10885-object-view-route2-named-view-rest.md, in the objectui#10533 form. Its sentence "the New button opens no form" is now false.packages/plugin-view/README.mdandcontent/docs/plugins/plugin-view.mdx, the same two edits in each:splitorpopoverthe create form opens on thelayoutsurface.split/popoverexception.The chosen surface and why
The create form opens where the node's own non-split create path would open it. That is the surface
formLayoutfalls back to with nonavigation:layout, meaningschema.layout, orderiveRecordSurfacewhen it is unset.layout: 'modal': the modal (renderModalForm).layout: 'drawer': the drawer (renderDrawerForm).layout: 'page'withonNavigate: the form is never reached.handleCreatehandsonNavigate('new', 'edit')to the router first, as before.layout: 'page'withoutonNavigate: here the code has no single answer, because the non-split path has no surface for a page inside this component either. This case takes the drawer: it is whatderiveRecordSurfaceanswers for a light desktop object, and it is the registered renderer'sdefaultProps.layout.A named view's
navigationreplaces the node's as a whole (objectui#10885 member 4). So under a namedsplit, the node's ownnavigationdoes not choose the create surface;layoutdoes. The README's Create section already says "the new-record form opens on thelayoutsurface".edit, decided explicitly: unchanged.handleEditsets the record, so the split panel and the popover already draw the edit form beside it. The edit control below measures this, green on base and head.Pins: red on base, green on head
ObjectFormis a sink that shows the mode its schema was built for. The drawer is found by vaul'sdata-vaul-drawerattribute, and the modal byrole="dialog"with no drawer ancestor.2049b03df7split, New gives a create form in the drawerpopoverwithlayout: 'modal', New gives a create form in the modalsplitover the node'smodalnavigation, New gives a create form in the drawerdrawernavigation's New gives a create form in the drawersplit, a row click opens the existing record beside the list (grid still mounted,Tasks Detailheading, not in a dialog)split, Edit opens the existing record beside the list2049b03df7with the pin file copied in gaveTests 3 failed | 3 passed (6). The three failures are exactly the fix rows, eachUnable to find an element by: [data-testid="object-form"].Tests 6 passed (6).ablation-replace.mjs, anchor must hit, WRAP mode): therenderCreateSurfacebody was replaced bynull. Anchor x1 to x0, blobdb64424727to16ecc8ecf0. ResultTests 3 failed | 3 passed (6), exactly the three fix rows. Restore proven: blob equals HEAD andgit diff HEADis empty.layout === 'modal' ? renderModalForm() : renderDrawerForm()was replaced byrenderDrawerForm(). ResultTests 1 failed | 5 passed (6): only the modal row went red. Restored and proven the same way.../ObjectViewfrom source, so nodistsits between a mutation and the run.Gates
These ran at head
0d122bf345under the verify lock.VERDICT command-exitlines are quoted as the lock printed them.pnpm --filter @object-ui/plugin-view type-check, after building the 15-task dependency closure:VERDICT command-exit 0.tsc -p tsconfig.test.json --listFilesOnlycounts the new pin (1 hit) among 51 plugin-view test files.packages/plugin-view/plus the 11 out-of-package tests that readObjectView.tsxoff disk (found withgit grep):Test Files 68 passed (68),Tests 1611 passed (1611).Test Files 21 passed (21),Tests 810 passed (810).eslint .inpackages/plugin-view(the package's own lint script): 72 files, 0 errors. The new pin is among them.check-changeset-presence: pass.check-changeset-no-major: pass.check-changeset-fixed: pass.check-changeset-overwrite(report-only) names the modified 10885 file. Its declaration is@object-ui/plugin-view: patchboth at base and now: the dated-note case.check:changeset-claims(report-only) lists 6 pending changesets that name a touched file. Each paragraph was read, and none is made false. They cover the non-grid fetch,generateViewSchema, the retired sort key, thetitlerelay and the objectui#7779 measurement. The self-contradiction reading passes.check:pending-changeset-literals: pass.check:new-line-citations:VERDICT new-cross-file-line-citations: 0 new citation(s).check:control-bytes: pass.check-doc-links: "Links are valid across 17 scan roots".check:doc-types,check:doc-fencesandcheck:doc-example-ids: pass.check:vi-mock-specifiers,check:vi-mock-inherit,check:vi-mock-override-shapeandcheck:test-path-roots: pass.check:readme-exports: pass. Its first run exited 1 only because thecliandplugin-aidists were missing, a prerequisite and not a finding; it passed once those were built.check:handler-key-reads,check:icon-record-names,check:unreferenced-sourcesandcheck:i18n-keys: pass.scripts/__tests__/markdown-test-inputs.test.tsis not owed: the new pin reads no markdown.check-governed-queue-guard --teston the 6 paths: NOT GOVERNED.git merge-tree --write-treeagainst a freshmain(ad0310fb57) is clean, treefbba809560.mainis one commit past the base (objectui#11010, app-shell only), with no file overlap.Eager closure (console build, base against head)
turbo run build --filter=@object-ui/consolewas run twice in the same worktree. The two trees differ only inObjectView.tsx, which was swapped to its base blob with a trap-guarded restore proven by hash.plugin-viewchunk grew by 75 raw and 32 gzip bytes.indexandCreateViewDialoggrew by 1 and 2 gzip bytes, from renamed chunk hashes.check:eager-closureis red on base, 18 bytes over the 3,179,000 ceiling (objectui#10996). Head is 53 bytes over.Bundle Analysiswill be red for that pre-existing reason; this change adds 35 gzip bytes.Acceptance notes
splitorpopover, the create form's surface now comes fromlayout, though its width still follows the namednavigation. That sentence is amended, and "Opening a record" now documents the node's own case.layout: 'page'with noonNavigate, outsidesplit/popover:formLayoutis'page', which has no render branch, so New opens nothing there either.layout: 'page'withoutonNavigate.layoutsurface. Under adrawerormodalnavigation it opens on that navigation's surface instead. This wording drift predates the change and is not made false by it.split, because the initialformModeiscreate. That keeps the create drawer's exit animation, as on the drawer path. A closed drawer renders nothing into the DOM, and the row-click control is unchanged.Generated by Claude Code