From 73a744cf70ac8a0a47acba4e94662a4b0bbffd3c Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 10 Jun 2026 16:17:41 +0000 Subject: [PATCH 1/2] Optimize add provider dialog renders Co-authored-by: Julius Marminge --- .../settings/AddProviderInstanceDialog.tsx | 500 +++++++++--------- 1 file changed, 243 insertions(+), 257 deletions(-) diff --git a/apps/web/src/components/settings/AddProviderInstanceDialog.tsx b/apps/web/src/components/settings/AddProviderInstanceDialog.tsx index affa35ff260..12a156565cf 100644 --- a/apps/web/src/components/settings/AddProviderInstanceDialog.tsx +++ b/apps/web/src/components/settings/AddProviderInstanceDialog.tsx @@ -2,7 +2,7 @@ import { CheckIcon } from "lucide-react"; import { Radio as RadioPrimitive } from "@base-ui/react/radio"; -import { useCallback, useEffect, useMemo, useState } from "react"; +import { useCallback, useMemo, useState } from "react"; import { ProviderInstanceId, ProviderDriverKind, @@ -114,6 +114,16 @@ interface AddProviderInstanceDialogProps { } export function AddProviderInstanceDialog({ open, onOpenChange }: AddProviderInstanceDialogProps) { + return ( + + {open ? : null} + + ); +} + +function AddProviderInstanceDialogContent({ + onOpenChange, +}: Pick) { const settings = useSettings(); const { updateSettings } = useUpdateSettings(); @@ -121,7 +131,7 @@ export function AddProviderInstanceDialog({ open, onOpenChange }: AddProviderIns const [driver, setDriver] = useState(DEFAULT_DRIVER_KIND); const [label, setLabel] = useState(""); const [accentColor, setAccentColor] = useState(""); - const [instanceId, setInstanceId] = useState(""); + const [manualInstanceId, setManualInstanceId] = useState(""); const [instanceIdDirty, setInstanceIdDirty] = useState(false); // Driver-specific config drafts keyed by driver so toggling between drivers // during the same dialog session does not lose in-progress input. @@ -135,32 +145,13 @@ export function AddProviderInstanceDialog({ open, onOpenChange }: AddProviderIns [settings.providerInstances], ); - // Reset the form every time the dialog opens so each creation starts - // from a clean slate. - useEffect(() => { - if (!open) return; - setDriver(DEFAULT_DRIVER_KIND); - setLabel(""); - setAccentColor(""); - setInstanceId(""); - setWizardStep(0); - setInstanceIdDirty(false); - setConfigByDriver({}); - setHasAttemptedSubmit(false); - }, [open]); - - // Auto-derive the instance id from driver + label until the user types - // in the Instance ID field directly (after which they own its value). - useEffect(() => { - if (instanceIdDirty) return; - setInstanceId(deriveInstanceId(driver, label)); - }, [driver, label, instanceIdDirty]); - const driverOption = DRIVER_OPTION_BY_VALUE[driver] ?? DEFAULT_DRIVER_OPTION; const driverSettingsFields = useMemo( () => deriveProviderSettingsFields(driverOption), [driverOption], ); + const derivedInstanceId = deriveInstanceId(driver, label); + const instanceId = instanceIdDirty ? manualInstanceId : derivedInstanceId; const instanceIdError = validateInstanceId(instanceId, existingIds); const showInstanceIdError = hasAttemptedSubmit && instanceIdError !== null; const previewLabel = label.trim() || `${driverOption.label} Workspace`; @@ -236,256 +227,251 @@ export function AddProviderInstanceDialog({ open, onOpenChange }: AddProviderIns ]); return ( - - -
- - Add provider instance - - Configure an additional provider instance — for example, a second Codex install - pointed at a different workspace. - -
- {wizardSteps.map((step, index) => ( - - ))} + {index < wizardStep ? : null} + + + Step {index + 1} + + + {step} + {index < wizardStep && wizardStepSummaries[index] + ? `: ${wizardStepSummaries[index]}` + : ""} + + + ))} +
+
+ +
+ +
+ + Driver + + setDriver(ProviderDriverKind.make(value))} + aria-labelledby="add-instance-driver-label" + className="grid grid-cols-2 gap-2.5" + > + {DRIVER_OPTIONS.map((option) => { + const IconComponent = option.icon; + const isSelected = option.value === driver; + return ( + + + + {option.label} + + {option.badgeLabel ? ( + + {option.badgeLabel} + + ) : null} + + ); + })} + {COMING_SOON_DRIVER_OPTIONS.map((option) => { + const IconComponent = option.icon; + return ( + + + + {option.label} + + + Coming Soon + + + ); + })} +
- -
- -
- - Driver + + + + +
+ Accent color +
+ setAccentColor(event.target.value)} + aria-label="Provider instance accent color" + className="h-8 w-10 cursor-pointer rounded-xl border border-input bg-background p-0.5" + /> +
+ {PROVIDER_ACCENT_SWATCHES.map((swatch) => { + const selected = accentColor.toLowerCase() === swatch; return ( - - - - {option.label} - - - Coming Soon - - + style={{ backgroundColor: swatch }} + onClick={() => setAccentColor(swatch)} + aria-label={`Use ${swatch} accent`} + /> ); })} - +
+ {accentColor ? ( + + ) : null}
+ + Optional marker shown in the picker. + +
- - -
- - - + {wizardStep < wizardSteps.length - 1 ? ( + - {wizardStep < wizardSteps.length - 1 ? ( - - ) : ( - - )} - -
- -
+ ) : ( + + )} + + + ); } From e07e155cf6c63f58151a49cc858d46ebcababfcd Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 10 Jun 2026 16:29:26 +0000 Subject: [PATCH 2/2] Split add provider dialog draft state Co-authored-by: Julius Marminge --- .../settings/AddProviderInstanceDialog.tsx | 729 +++++++++++------- 1 file changed, 467 insertions(+), 262 deletions(-) diff --git a/apps/web/src/components/settings/AddProviderInstanceDialog.tsx b/apps/web/src/components/settings/AddProviderInstanceDialog.tsx index 12a156565cf..4b43f4b54ae 100644 --- a/apps/web/src/components/settings/AddProviderInstanceDialog.tsx +++ b/apps/web/src/components/settings/AddProviderInstanceDialog.tsx @@ -2,7 +2,7 @@ import { CheckIcon } from "lucide-react"; import { Radio as RadioPrimitive } from "@base-ui/react/radio"; -import { useCallback, useMemo, useState } from "react"; +import { useCallback, useMemo, useReducer } from "react"; import { ProviderInstanceId, ProviderDriverKind, @@ -64,6 +64,7 @@ const INSTANCE_ID_PATTERN = /^[a-zA-Z][a-zA-Z0-9_-]*$/; const DEFAULT_DRIVER_KIND = ProviderDriverKind.make("codex"); const DEFAULT_DRIVER_OPTION = DRIVER_OPTIONS[0]!; const EMPTY_CONFIG_DRAFT: Record = {}; +const WIZARD_STEPS = ["Driver", "Identity", "Config"] as const; interface ComingSoonDriverOption { readonly value: ProviderDriverKind; readonly label: string; @@ -113,6 +114,76 @@ interface AddProviderInstanceDialogProps { onOpenChange: (open: boolean) => void; } +interface AddProviderInstanceDraftState { + readonly wizardStep: number; + readonly driver: ProviderDriverKind; + readonly label: string; + readonly accentColor: string; + readonly manualInstanceId: string; + readonly instanceIdDirty: boolean; + readonly configByDriver: Record>; + readonly hasAttemptedSubmit: boolean; +} + +type AddProviderInstanceDraftAction = + | { readonly type: "setWizardStep"; readonly step: number } + | { readonly type: "setDriver"; readonly driver: ProviderDriverKind } + | { readonly type: "setLabel"; readonly label: string } + | { readonly type: "setAccentColor"; readonly accentColor: string } + | { readonly type: "setManualInstanceId"; readonly instanceId: string } + | { + readonly type: "setConfigDraft"; + readonly driver: ProviderDriverKind; + readonly config: Record | undefined; + } + | { readonly type: "markAttemptedSubmit" }; + +function createInitialAddProviderInstanceDraftState(): AddProviderInstanceDraftState { + return { + wizardStep: 0, + driver: DEFAULT_DRIVER_KIND, + label: "", + accentColor: "", + manualInstanceId: "", + instanceIdDirty: false, + configByDriver: {}, + hasAttemptedSubmit: false, + }; +} + +function addProviderInstanceDraftReducer( + state: AddProviderInstanceDraftState, + action: AddProviderInstanceDraftAction, +): AddProviderInstanceDraftState { + switch (action.type) { + case "setWizardStep": + return state.wizardStep === action.step ? state : { ...state, wizardStep: action.step }; + case "setDriver": + return state.driver === action.driver ? state : { ...state, driver: action.driver }; + case "setLabel": + return state.label === action.label ? state : { ...state, label: action.label }; + case "setAccentColor": + return state.accentColor === action.accentColor + ? state + : { ...state, accentColor: action.accentColor }; + case "setManualInstanceId": + return state.manualInstanceId === action.instanceId && state.instanceIdDirty + ? state + : { ...state, manualInstanceId: action.instanceId, instanceIdDirty: true }; + case "setConfigDraft": { + const next = { ...state.configByDriver }; + if (action.config === undefined || Object.keys(action.config).length === 0) { + delete next[action.driver]; + } else { + next[action.driver] = action.config; + } + return { ...state, configByDriver: next }; + } + case "markAttemptedSubmit": + return state.hasAttemptedSubmit ? state : { ...state, hasAttemptedSubmit: true }; + } +} + export function AddProviderInstanceDialog({ open, onOpenChange }: AddProviderInstanceDialogProps) { return ( @@ -126,19 +197,21 @@ function AddProviderInstanceDialogContent({ }: Pick) { const settings = useSettings(); const { updateSettings } = useUpdateSettings(); - - const [wizardStep, setWizardStep] = useState(0); - const [driver, setDriver] = useState(DEFAULT_DRIVER_KIND); - const [label, setLabel] = useState(""); - const [accentColor, setAccentColor] = useState(""); - const [manualInstanceId, setManualInstanceId] = useState(""); - const [instanceIdDirty, setInstanceIdDirty] = useState(false); - // Driver-specific config drafts keyed by driver so toggling between drivers - // during the same dialog session does not lose in-progress input. - const [configByDriver, setConfigByDriver] = useState>>({}); - // Errors are suppressed until the user has tried to submit once. After that - // they update live so fixing the problem clears the message in place. - const [hasAttemptedSubmit, setHasAttemptedSubmit] = useState(false); + const [draft, dispatch] = useReducer( + addProviderInstanceDraftReducer, + undefined, + createInitialAddProviderInstanceDraftState, + ); + const { + wizardStep, + driver, + label, + accentColor, + manualInstanceId, + instanceIdDirty, + configByDriver, + hasAttemptedSubmit, + } = draft; const existingIds = useMemo( () => new Set(Object.keys(settings.providerInstances ?? {})), @@ -155,27 +228,18 @@ function AddProviderInstanceDialogContent({ const instanceIdError = validateInstanceId(instanceId, existingIds); const showInstanceIdError = hasAttemptedSubmit && instanceIdError !== null; const previewLabel = label.trim() || `${driverOption.label} Workspace`; - const wizardSteps = ["Driver", "Identity", "Config"] as const; const wizardStepSummaries = [driverOption.label, previewLabel, null] as const; const configDraft = configByDriver[driver] ?? EMPTY_CONFIG_DRAFT; const setConfigDraft = useCallback( (config: Record | undefined) => { - setConfigByDriver((existing) => { - const next = { ...existing }; - if (config === undefined || Object.keys(config).length === 0) { - delete next[driver]; - } else { - next[driver] = config; - } - return next; - }); + dispatch({ type: "setConfigDraft", driver, config }); }, [driver], ); const handleSave = useCallback(() => { - setHasAttemptedSubmit(true); + dispatch({ type: "markAttemptedSubmit" }); if (instanceIdError !== null) return; const config = configByDriver[driver] ?? {}; @@ -229,249 +293,390 @@ function AddProviderInstanceDialogContent({ return (
- - Add provider instance - - Configure an additional provider instance — for example, a second Codex install pointed - at a different workspace. - -
- {wizardSteps.map((step, index) => ( - - ))} -
-
- -
- -
- - Driver - - setDriver(ProviderDriverKind.make(value))} - aria-labelledby="add-instance-driver-label" - className="grid grid-cols-2 gap-2.5" - > - {DRIVER_OPTIONS.map((option) => { - const IconComponent = option.icon; - const isSelected = option.value === driver; - return ( - - - - {option.label} - - {option.badgeLabel ? ( - - {option.badgeLabel} - - ) : null} - - ); - })} - {COMING_SOON_DRIVER_OPTIONS.map((option) => { - const IconComponent = option.icon; - return ( - - - - {option.label} - - - Coming Soon - - - ); - })} - -
- -
+ + ); +} + +function AddProviderInstanceDialogHeader(props: { + wizardStep: number; + wizardStepSummaries: readonly (string | null)[]; + onStepSelect: (step: number) => void; +}) { + return ( + + Add provider instance + + Configure an additional provider instance — for example, a second Codex install pointed at a + different workspace. + +
+ {WIZARD_STEPS.map((step, index) => ( + + ))} +
+
+ ); +} + +function AddProviderInstanceDialogPanel(props: { + wizardStep: number; + driver: ProviderDriverKind; + driverOption: typeof DEFAULT_DRIVER_OPTION; + driverSettingsFields: ReturnType; + label: string; + onLabelChange: (label: string) => void; + instanceId: string; + instanceIdError: string | null; + showInstanceIdError: boolean; + onInstanceIdChange: (instanceId: string) => void; + accentColor: string; + onAccentColorChange: (accentColor: string) => void; + onDriverChange: (driver: ProviderDriverKind) => void; + configDraft: Record; + onConfigDraftChange: (config: Record | undefined) => void; +}) { + return ( +
+ + + + + +
+ ); +} + +function AddProviderInstanceDriverStep(props: { + active: boolean; + driver: ProviderDriverKind; + onDriverChange: (driver: ProviderDriverKind) => void; +}) { + return ( +
+ + Driver + + props.onDriverChange(ProviderDriverKind.make(value))} + aria-labelledby="add-instance-driver-label" + className="grid grid-cols-2 gap-2.5" + > + {DRIVER_OPTIONS.map((option) => { + const IconComponent = option.icon; + const isSelected = option.value === props.driver; + return ( + + + + {option.label} - - - + ); + })} + {COMING_SOON_DRIVER_OPTIONS.map((option) => { + const IconComponent = option.icon; + return ( + - -
- Accent color -
- setAccentColor(event.target.value)} - aria-label="Provider instance accent color" - className="h-8 w-10 cursor-pointer rounded-xl border border-input bg-background p-0.5" - /> -
- {PROVIDER_ACCENT_SWATCHES.map((swatch) => { - const selected = accentColor.toLowerCase() === swatch; - return ( -
- {accentColor ? ( - - ) : null} -
- - Optional marker shown in the picker. + > + + + {option.label} -
- - {driverSettingsFields.length > 0 ? ( -
- + Coming Soon + + + ); + })} + +
+ ); +} + +function AddProviderInstanceIdentityStep(props: { + active: boolean; + driver: ProviderDriverKind; + label: string; + onLabelChange: (label: string) => void; + instanceId: string; + instanceIdError: string | null; + showInstanceIdError: boolean; + onInstanceIdChange: (instanceId: string) => void; + accentColor: string; + onAccentColorChange: (accentColor: string) => void; +}) { + return ( + <> + + + + +
+ Accent color +
+ props.onAccentColorChange(event.target.value)} + aria-label="Provider instance accent color" + className="h-8 w-10 cursor-pointer rounded-xl border border-input bg-background p-0.5" + /> +
+ {PROVIDER_ACCENT_SWATCHES.map((swatch) => { + const selected = props.accentColor.toLowerCase() === swatch; + return ( +
- ) : wizardStep === 2 ? ( -
-

- This driver has no required configuration. You can add the instance now. -

-
- ) : null} - + ); + })} +
+ {props.accentColor ? ( + + ) : null}
+ + Optional marker shown in the picker. + +
+ + ); +} - - - {wizardStep < wizardSteps.length - 1 ? ( - - ) : ( - - )} - +function AddProviderInstanceConfigStep(props: { + active: boolean; + driver: ProviderDriverKind; + driverOption: typeof DEFAULT_DRIVER_OPTION; + driverSettingsFields: ReturnType; + configDraft: Record; + onConfigDraftChange: (config: Record | undefined) => void; +}) { + if (props.driverSettingsFields.length > 0) { + return ( +
+
- + ); + } + + if (!props.active) { + return null; + } + + return ( +
+

+ This driver has no required configuration. You can add the instance now. +

+
+ ); +} + +function AddProviderInstanceDialogFooter(props: { + wizardStep: number; + onBack: () => void; + onNext: () => void; + onSave: () => void; +}) { + return ( + + + {props.wizardStep < WIZARD_STEPS.length - 1 ? ( + + ) : ( + + )} + ); }