From 7c10920a5413d1f75cb409149d8f339d537381c6 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 8 Oct 2026 21:56:59 +0000 Subject: [PATCH 1/4] feat(console): Public Forms, Flow Runs and Profile pick with the shared Select MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../src/pages/developer/FlowRunsPage.tsx | 77 ++++++++++-- .../src/pages/developer/PublicFormsPage.tsx | 113 +++++++++++++---- apps/console/src/pages/system/ProfilePage.tsx | 118 +++++++++++++++--- 3 files changed, 256 insertions(+), 52 deletions(-) diff --git a/apps/console/src/pages/developer/FlowRunsPage.tsx b/apps/console/src/pages/developer/FlowRunsPage.tsx index b5c6471b6c..5b3af536c6 100644 --- a/apps/console/src/pages/developer/FlowRunsPage.tsx +++ b/apps/console/src/pages/developer/FlowRunsPage.tsx @@ -45,6 +45,11 @@ import { SheetTitle, SheetDescription, ScrollArea, + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, } from '@object-ui/components'; import { Play, Loader2, CheckCircle2, XCircle, Clock, AlertCircle, RefreshCw, Workflow, @@ -130,6 +135,61 @@ function JsonBlock({ data }: { data: unknown }) { ); } +/** The item a value none of the picker's options carries is shown by. */ +const OUTSIDE_OPTIONS = 'outside'; + +/** + * objectui#11865 — the flow picker, drawn with the shared `Select` the rest of + * the console picks with. It used to be a browser-native ` { + // `undefined` for the outside item: it is the page's own value, so there is nothing to write. + const picked = options[Number(token)]; + if (picked) onPick(picked.value); + }} + > + + + + + {at === -1 && {value}} + {options.map((o, i) => ( + + {o.label} + + ))} + + + ); +} + export function FlowRunsPage() { const adapter = useAdapter(); const client: any = adapter?.getClient?.(); @@ -216,17 +276,14 @@ export function FlowRunsPage() {

No flow definitions found.

)} {!flowsLoading && !flowsError && flows.length > 0 && ( - + options={flows.map(f => ({ + value: f.name, + label: f.label ? `${f.label} (${f.name})` : f.name, + }))} + onPick={setSelectedFlowName} + /> )} diff --git a/apps/console/src/pages/developer/PublicFormsPage.tsx b/apps/console/src/pages/developer/PublicFormsPage.tsx index c8a3e7d2c5..07174548dc 100644 --- a/apps/console/src/pages/developer/PublicFormsPage.tsx +++ b/apps/console/src/pages/developer/PublicFormsPage.tsx @@ -69,6 +69,11 @@ import { Input, Label, EmptyValue, + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, } from '@object-ui/components'; import { Copy, ExternalLink, FormInput, RefreshCw, Code2, Link2, Settings2, Plus } from 'lucide-react'; import { toast } from 'sonner'; @@ -104,6 +109,76 @@ function sanitizeSlug(s: string): string { /** The anonymous form route's prefix, as `App.tsx` declares it (`/f/:slug`). */ const PUBLIC_FORM_ROUTE = '/f'; +type SubmitBehaviorKind = 'thank-you' | 'redirect' | 'continue' | 'next-record'; + +/** The "After submit" picker's options, in the order the dialog offers them. */ +const SUBMIT_BEHAVIOR_OPTIONS: ReadonlyArray<{ value: SubmitBehaviorKind; label: string }> = [ + { value: 'thank-you', label: 'Show a thank-you panel' }, + { value: 'redirect', label: 'Redirect to a URL' }, + { value: 'continue', label: 'Reset for another response' }, + { value: 'next-record', label: 'Advance to next record (internal queues)' }, +]; + +/** The item a value none of a picker's options carries is shown by. */ +const OUTSIDE_OPTIONS = 'outside'; + +/** + * objectui#11865 — the two dialogs' pickers (the FormView to publish, and what + * happens after submit), drawn with the shared `Select` the rest of the + * console picks with. They used to be browser-native ` { + // `undefined` for the outside item: it is the dialog's own value, so there is nothing to write. + const picked = options[Number(token)]; + if (picked) onPick(picked.value); + }} + > + + + + + {at === -1 && {value}} + {options.map((o, i) => ( + + {o.label} + + ))} + + + ); +} + export function PublicFormsPage() { const adapter = useAdapter(); const client: any = adapter?.getClient?.(); @@ -121,7 +196,7 @@ export function PublicFormsPage() { const [editOpen, setEditOpen] = useState(false); const [editRow, setEditRow] = useState(null); const [editSlug, setEditSlug] = useState(''); - const [editBehavior, setEditBehavior] = useState<'thank-you' | 'redirect' | 'continue' | 'next-record'>('thank-you'); + const [editBehavior, setEditBehavior] = useState('thank-you'); const [editBehaviorTitle, setEditBehaviorTitle] = useState(''); const [editBehaviorMessage, setEditBehaviorMessage] = useState(''); const [editBehaviorUrl, setEditBehaviorUrl] = useState(''); @@ -478,19 +553,18 @@ export function PublicFormsPage() {
- + options={[ + { value: '', label: '— Select a FormView —' }, + ...publishable.map((p) => ({ + value: p.name, + label: `${p.label ?? p.name} (${p.name}) ${p.object ? `· ${p.object}` : ''}`, + })), + ]} + onPick={setPublishView} + />
@@ -543,20 +617,15 @@ export function PublicFormsPage() {
- + />
{editBehavior === 'thank-you' && ( <> diff --git a/apps/console/src/pages/system/ProfilePage.tsx b/apps/console/src/pages/system/ProfilePage.tsx index 4f03c7cf3a..f1d73f080a 100644 --- a/apps/console/src/pages/system/ProfilePage.tsx +++ b/apps/console/src/pages/system/ProfilePage.tsx @@ -29,6 +29,11 @@ import { Badge, Alert, AlertDescription, + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, } from '@object-ui/components'; import { useUpload } from '@object-ui/providers'; import { useObjectTranslation, type TranslateFn } from '@object-ui/i18n'; @@ -331,9 +336,85 @@ function nativeLanguageName(code: string): string { } } -/** The `