Repository navigation
fix(app-shell): one shared object picker for Studio's object-name inputs, resolving only the chosen name (objectui#11783) - #11840
Merged
Conversation
…uts, resolving only the chosen name (objectui#11783) The Lookup's Related object, the summary's child object and every flow reference of kind `object` now render one module-private ObjectPicker. - Typing stays in the input; the name is committed on a choice, Enter or blur, so nothing that resolves it (useObjectFields, useFlowScope, the entry-condition builder) refetches per keystroke. Escape abandons. - Enter and blur commit exactly what was typed, so a flow value that is an expression is accepted as before. - One catalog read per mount, the draft-overlaid object list: this package's objects first, then the others, with label and name; served isSystem objects sit in a collapsed System group a search still reaches. A draft-only object is offered with its draft's label. - The trigger's Object field drops its crm_lead placeholder. Claude-Session: https://claude.ai/code/session_01DrKzdPdyLLBW3qpZ4vtk7z Co-authored-by: Claude <noreply@anthropic.com>
… lines
In the inspector's narrow column the two shared one line and both were cut
short ("Field Tec…", "Repair …"). The label now takes the first line, with
the draft marker; the name sits under it.
Claude-Session: https://claude.ai/code/session_01DrKzdPdyLLBW3qpZ4vtk7z
Co-authored-by: Claude <noreply@anthropic.com>
The hook has no caller outside the picker, and exporting it beside the component defeats fast refresh. The not-yet-answered catalog is one stable empty list rather than a fresh array each render, which the memoised groups depended on. Claude-Session: https://claude.ai/code/session_01DrKzdPdyLLBW3qpZ4vtk7z Co-authored-by: Claude <noreply@anthropic.com>
Contributor
✅ 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. 📦 Bundle Size Report
Size Limits
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #11783
Clause-②: no
What this changes
Studio's object-name inputs now share one module-private picker,
inspectors/ObjectPicker.tsx.Who renders it. In
ObjectFieldInspector: the Lookup's Related object and the summary's Child object. InFlowReferenceField: every flow reference of kindobject, through one branch inReferenceCombobox. That covers the trigger's Object, the time-relative Sweep object, the map node's Item object, the Object of the four record nodes and the legacy action node, and the screen's Object form. The trigger field reaches the picker throughFlowNodeConfigFieldandFlowReferenceField.FlowNodeInspector.tsxis untouched.When a name leaves it. Typing stays in the input.
onCommitruns once, when the author chooses an option, presses Enter, or leaves the input after typing. Escape abandons the typing. Enter and blur commit exactly what was typed, matched or not, so a flow value that is an expression is accepted as before.What it offers. One read per picker mount:
GET /api/v1/meta/object?preview=draft. The groups come in this order::packageIdroute parameter, else the editor URL's?package=;isSystem, in a collapsed System group. A search reaches that group without opening it, sosys_userstays choosable for a Lookup.Each option shows its label and its name. An entry served with
_draftcarries the existingengine.inspector.draftSuffixmarker. "System" is read from the servedisSystemonly: no name prefix and no list.crm_lead. The placeholder is removed from the trigger Object field, with no replacement and no locale key.i18n. Six new
engine.inspector.objectPicker.*rows, EN and ZH, inmetadata-admin/i18n.ts. Loading and load failure reuseengine.form.loadingOptionsandengine.form.optionsLoadFailedTitle.Nothing is added to the package's entry: no export, published prop,
@object-ui/typesmember orpackages/i18nkey. One module-internal optional prop,ariaLabelonReferenceCombobox, is added. It carries the flow field's label to the picker, so the input has an accessible name (the old datalist input had none).ReferenceComboboxis not exported from the package.Why the preview list, and not the list the inputs read before
This departs from the suggested route on measurement:
GET /meta/_drafts?type=objectanswers header rows with no label. Labelling a draft-only object from it would take one more read per draft.?preview=draftserves the draft-only object in the same single answer, with its own label, its_packageIdand_draft: true.mayReadPendingDraftsin objectstack's runtime meta domain); this run did not measure it._draft: truewith its draft label, so it also carries the draft marker.Measurements
Setup. Real Chromium at 1440×900, with this branch's console on a dev-only Vite harness that is not committed. The backend is
examples/app-showcasefrom objectstackbafb58bb, run withobjectstack dev --seed-admin --fresh. The data is a writable packagecom.example.repairsholding a draft-only objectrepairs_repair_ticketand a draft flow. The author typesrepairs_repair_ticketone key at a time into each input. Both runs start from the same drafts.16cda0bGET /meta/object/PREFIXwhile typingGET /meta/object/PREFIXwhile typingsys_*, the draft as a bare namecrm_leadAll 3 reads on the flow commit are for the committed name. The inspector holds more than one reader of the trigger object:
useFlowScopeinFlowNodeInspectorand the entry-conditionConditionBuilderare two of them, and the third was not identified. All of them are outside this card's files.H2, the served list.
GET /api/v1/meta/objectreturned 107 entries. All 107 carryisSystem(80true) and alabel, and every entry carries_packageId. A runtime-authored object carries noisSystemkey, published or draft. Its absence is the spec's declared default,false. Three platform objects are servedisSystem: false:sys_inbox_message,sys_fileandsys_upload_session. They are offered up front, because the mark decides, not the prefix.H3, the object-name inputs in the Studio inspectors.
Moved onto the picker: the Lookup and summary inputs above, and every flow reference of kind
object. Each was a free-text datalist that committed per keystroke.Left as they are, because they are not the same kind:
InspectorComboFieldpopovers that commit on choice.None of these fetches per keystroke. All of them still list
isSystemobjects without grouping (see Acceptance notes).H4, the draft object.
repairs_repair_ticketis offered in This package, labelled Repair Ticket from its draft and marked as a draft. It is choosable from both inputs.Tests
New pins:
ObjectPicker.test.tsxchecks what the picker offers and in which order. It checks that the servedisSystemdecides membership in System:sys_fileis offered up front andaudit_trailis collapsed. It checks that opening System or searching reaches those objects, and that the draft is labelled and marked. It checks that typing commits nothing, that Enter and blur commit what was typed (an expression included), that Escape abandons, and that the catalog is read once.ObjectFieldInspector.objectPicker-11783.test.tsxruns the real inspector with the realuseObjectFields. Typing the name makes 0 object reads, and the commit makes 1, for that name.sys_useris choosable.FlowReferenceField.objectPicker-11783.test.tsxruns the realFlowNodeInspector, with the realuseFlowScopeanduseObjectFields. Typing makes 0 object reads, and the commit reads only the committed name. An expression value is accepted as before (a control). The field has nocrm_leadplaceholder.Updated:
ObjectFieldInspector.draft-locale.test.tsxreads the localized draft marker on the picker.ObjectFieldInspector.test.tsx's summary case commits by leaving the input.Gates, run locally on HEAD
8b94ce9:pnpm exec vitest run: exit 0,Test Files 102 passed (102),Tests 1206 passed | 1 skipped (1207)pnpm --filter @object-ui/app-shell type-check, which runstsc --noEmit && tsc -p tsconfig.test.json(--listFilesOnlyconfirms the new test files are in that project): exit 0check:control-bytes·check:new-line-citations·check:changeset-claims·check:pending-changeset-literals: exit 0check:i18n-designer-parityandcheck:i18n-dead-keys(designer-table leg), pluscheck:i18n-keys: exit 0vi.mockdoubles, a new source file, a newreact-router-domimport):check:vi-mock-specifiers·check:vi-mock-inherit·check:vi-mock-override-shape·check:unreferenced-sources·check:phantom-deps·check:test-path-roots·check-changeset-presence.mjs: exit 0eslint --no-inline-configover the changed files: 0 errors.ObjectPicker.tsxhas no warnings, andFlowReferenceField.tsxcarries the same 10 warnings it had at16cda0b.The repo-wide
pnpm lintand the full test farm are left to CI.Reverse check. This ran on the committed fix,
3389363. The three source files were reverted to16cda0b, the two inspector-level pin files were run, and the files were restored fromHEAD. The restore was proven by blob hashes equal toHEADand an emptygit diff HEAD. Predicted and observed, 4 red and 2 green:sys_userpin and the placeholder pin went red;Acceptance notes
Noted here, not filed:
contract(the four record nodes and the legacy action node),contracts(sweep object) andcrm_account(screen object form) name objects the showcase does not serve.showcase_task(map item object) exists only in the showcase. The view inspector'sengine.inspector.view.objectPlaceholderreadse.g. crm_lead. This is the same class ascrm_lead, but outside this claim's lines.isSystemobjects first-class and ungrouped. The action's and page block's empty-list text-field fallback commits per keystroke, which reachesuseObjectFields.sys_inbox_message,sys_fileandsys_upload_sessionare servedisSystem: false. Whether they should carry the mark is the platform's decision.Generated by Claude Code