Repository navigation
feat(console): Public Forms, Flow Runs and Profile pick with the shared Select - #12012
Merged
objectstack-fleet[bot] merged 4 commits intoOct 8, 2026
Merged
Conversation
…ed Select
The Public Forms dialogs (the FormView to publish, "After submit"), the
Flow Runs flow picker and the Profile page's preferred language were
browser-native selects beside the shared Radix Select the rest of the
console uses. Each now picks through a module-private picker on the
shared primitive: items carry their option's index, so the '' options
("— Select a FormView —", "Use the deployment default") need no empty
SelectItem, and a value no option carries is shown as itself rather than
as the first option. Every pick hands the caller the same string the
native change carried, each trigger keeps its label (id on the trigger),
and the Profile picker's read-only state is the primitive's disabled
trigger.
Part of objectui#11865.
Claude-Session: https://claude.ai/code/session_01MgfduSkFrfM3eorB3UGfAU
Co-authored-by: Claude <noreply@anthropic.com>
… the shared Select One pin per page: each picker is the primitive's trigger and no visible native select is left; each keeps the accessible name it had; every option leads to the same saveItem / execute+listRuns / update call the native control led to (literals read on the pre-conversion pages with the same fixtures); a value no option carries is shown as itself; Enter opens and selects. The two suites that drove the native controls now pick through the primitive: PublicFormsPage.redirect's editor helper, and ProfilePage.language, whose adapter mock is now a stable object as the app's provider is (a fresh one per render re-read the row and reset the pick before Save). Patch changeset for @object-ui/console. Part of objectui#11865. Claude-Session: https://claude.ai/code/session_01MgfduSkFrfM3eorB3UGfAU Co-authored-by: Claude <noreply@anthropic.com>
Part of objectui#11865. Claude-Session: https://claude.ai/code/session_01MgfduSkFrfM3eorB3UGfAU Co-authored-by: Claude <noreply@anthropic.com>
…s the adapter does developerMetadataEnvelope.contractEnvelope-6917 and consoleFaces.displayLocale-9909 built a fresh client on every getClient() call. Flow Runs keys its flow and run loads on the client, so each render re-ran them: measured with that harness shape, 251 meta.getItems calls in 600 ms on the base page and 73 on this branch, against 2 with one client. The native select's option text was readable between those reloads; the shared Select's trigger value never settled long enough, so both suites' Flow Runs cases went red. The real adapter's getClient() returns its one client, which is what the harnesses now do. Part of objectui#11865. Claude-Session: https://claude.ai/code/session_01MgfduSkFrfM3eorB3UGfAU 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
|
objectstack-fleet
Bot
deleted the
claude/issue-11865-console-pages-select
branch
October 8, 2026 23:14
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.
Part of #11865
Clause-②: no
Slice h of claim
6069665700, the console's own pages: four browser-native select elements on three pages become the shared RadixSelect(packages/components/src/ui/select, used, not edited), following objectui#11976, #11990, #11995, #12000 and #12005. This PR converts these files and no others:apps/console/src/pages/developer/PublicFormsPage.tsx: "FormView" in Publish a FormView and "After submit" in the edit dialog, through one module-privateFormsPicker.apps/console/src/pages/developer/FlowRunsPage.tsx: the flow picker, through a module-privateFlowPicker.apps/console/src/pages/system/ProfilePage.tsx: "Preferred language", through a module-privateLanguagePicker.Each picker follows the card's earlier pickers. Items carry their option's index, so the two options whose value is the empty string ("— Select a FormView —", "Use the deployment default") need no empty
SelectItem. A value no option carries gets an item of its own and is shown as itself. No picker is exported, and no listing logic on Public Forms moved (objectui#11545 is untouched).Hypotheses, measured
902fbe190, with the native selects and the same fixtures as the pins, read what every option led to. The pins compare against those readings as JSON text:meta.saveItemcall (["view","lead.intake",{…,"sharing":{"enabled":true,"allowAnonymous":true,"publicLink":"/forms/contact-us"}}], and the same for the view with no label or object). "— Select a FormView —" leaves Publish disabled with no call.redirectwith/done, orcontinue, by each of the four options), each the same fullsaveItemcall,submitBehaviorincluded.[["nightly_sync",{"params":{}}]]) and whose runs are listed ([["nightly_sync",{"limit":20}]]), and the same forreassign_wizard.jaorpt-BR, by each option), each the sameadapter.updatecall; "Use the deployment default" still saves{"locale":null}. Re-picking the current option leaves Save disabled, as before.getByRole('combobox', { name }): "FormView", "After submit" and "Preferred language" come from each field's Label htmlFor. Each trigger now carries thatid, and the name pins are green on base and head by design.idoraria-label, so its name was empty. It is still empty, and is pinned so (see Acceptance notes).ProfilePage.language's "degrades to read-only" case. Public Forms' two dialogs open only from the page's own buttons, and Flow Runs has no such state.nightly_syncand showed no runner.zh.PublicFormsPage-*,FlowRunsPage-*andProfilePage-*), none among the 336 members ofdist/eager-closure.json. The positive controls were the entry chunk andui-components, both eager.ui-componentskeeps its file name, so the sharedSelectwas already in it.Tests
New pins (one per page):
PublicFormsPage.sharedSelect-11865.test.tsx,FlowRunsPage.sharedSelect-11865.test.tsx,ProfilePage.sharedSelect-11865.test.tsx.Suites that drove or mount these pages, changed only in their harness:
PublicFormsPage.redirect: the editor helper picks "Redirect to a URL" through the primitive.ProfilePage.language: picks through the primitive. Its adapter mock is now one object, as the app's provider hands out. A fresh one per render re-read the row and reset the pick before Save could be reached. The native control's synchronous change event used to win that race.developerMetadataEnvelope.contractEnvelope-6917andconsoleFaces.displayLocale-9909:getClient()now returns one client, as the real adapter's does. With a fresh client per call, Flow Runs re-ran its loads on every render. Measured with that harness shape: 251meta.getItemscalls in 600 ms on the base page and 73 on this branch, against 2 with one client. The native option text was readable between reloads; the shared trigger's value never settled, so their Flow Runs cases went red.Reverse leg, from the committed head
699224076:Tests 42 failed | 3 passed (45). The three passing are the name pins, green on both sides by design.git checkout HEAD. The blobs on disk equal HEAD's, andgit diff HEADis empty. A trap restored on EXIT, INT and TERM.Gates (head
f0ec3325f, worktree clean)pnpm exec vitest runover the 3 new pins, the 8 suites that mount these pages,submitRedirect.test.ts,column-identity.ratchet.test.tsandone-authority-per-exported-name-6273.test.ts:Test Files 14 passed (14),Tests 180 passed (180).pnpm --filter @object-ui/console type-check, afterturbo run build --filter='@object-ui/console^...'(Tasks: 34 successful, 34 total): exit 0.tsc --listFilesOnlylists every touched file.pnpm exec eslinton the 10 touched ts/tsx files: 0 errors and 32 warnings, all pre-existing rule kinds. The base blobs carry 33, andPublicFormsPageloses oneno-explicit-any.pnpm check:eager-closureon the head build: "Console eager closure is 3311.8 KB gzipped across 336 of 2458 chunks (budget: 3312.0 KB, headroom: 0.2 KB)."node scripts/check-changeset-presence.mjs: "10 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)".node scripts/check-changeset-no-major.mjs.pnpm check:new-line-citations: "0 new citation(s)".pnpm check:control-bytes.check:vi-mock-specifiers,check:vi-mock-inherit,check:vi-mock-override-shape,check:test-path-roots,check:i18n-keys,check:changeset-claims,check:pending-changeset-literals,check:phantom-deps,check:metadata-write-doors,check:unreferenced-sourcesandcheck:handler-key-reads.Changeset:
.changeset/11865-h-console-pages-shared-select.md,'@object-ui/console': patch.Docs: no guide or README describes these controls. A
git grepofcontent/docsand the console README for the page names and labels finds onlypublic-forms.md, which documents the route and the redirect contract, not the dialog's controls. So no doc change.Acceptance notes
None of these is filed. Each is noted with no carrier.
idoraria-labelis associated with it. Kept for parity, as the claim asks. Naming it is a separate change.loadFlowsdepends on the picked name. The picker unmounts while the list loads, so focus does not come back to it after a pick. Read in jsdom, the same before and after.getClient(). The real adapter returns one client, so this is dormant in the app; only a harness that builds a fresh client loops.FlowRunsPage.test.tsxstill builds one per call and passes.submitBehavior.kindoutside the spec's four is saved away: Save writes the view withoutsubmitBehavior, before and after. The spec refuses such a kind, so reaching this needs an off-spec stored view.Session:
https://claude.ai/code/session_01MgfduSkFrfM3eorB3UGfAU.Generated by Claude Code