diff --git a/web/src/app/home/components/models-dialog/component/provider-form/ProviderForm.tsx b/web/src/app/home/components/models-dialog/component/provider-form/ProviderForm.tsx index b59127cee..97655cebb 100644 --- a/web/src/app/home/components/models-dialog/component/provider-form/ProviderForm.tsx +++ b/web/src/app/home/components/models-dialog/component/provider-form/ProviderForm.tsx @@ -31,14 +31,25 @@ const getFormSchema = (t: (key: string) => string) => api_key: z.string().optional(), }); +export interface ProviderFormInitialValues { + name?: string; + requester?: string; + base_url?: string; + api_key?: string; +} + interface ProviderFormProps { providerId?: string; + initialValues?: ProviderFormInitialValues; + onValuesChange?: (values: ProviderFormInitialValues) => void; onFormSubmit: (providerUuid?: string) => void; onFormCancel: () => void; } export default function ProviderForm({ providerId, + initialValues, + onValuesChange, onFormSubmit, onFormCancel, }: ProviderFormProps) { @@ -48,13 +59,22 @@ export default function ProviderForm({ const form = useForm>({ resolver: zodResolver(formSchema), defaultValues: { - name: '', - requester: '', - base_url: '', - api_key: '', + name: initialValues?.name ?? '', + requester: initialValues?.requester ?? '', + base_url: initialValues?.base_url ?? '', + api_key: initialValues?.api_key ?? '', }, }); - const { setValue } = form; + const { setValue, watch } = form; + + // Report form values changes to parent + useEffect(() => { + if (!onValuesChange) return; + const subscription = watch((values) => { + onValuesChange(values as ProviderFormInitialValues); + }); + return () => subscription.unsubscribe(); + }, [watch, onValuesChange]); const [requesterList, setRequesterList] = useState< { diff --git a/web/src/app/wizard/page.tsx b/web/src/app/wizard/page.tsx index 7eef3c3a5..cccf97ad6 100644 --- a/web/src/app/wizard/page.tsx +++ b/web/src/app/wizard/page.tsx @@ -109,6 +109,17 @@ export default function WizardPage() { const [modelsAdded, setModelsAdded] = useState(false); // Sub-layer within Step 2: 0=main, 1=sub-choice, 2=provider, 3=scan, 4=config const [step2Layer, setStep2Layer] = useState(0); + // Saved provider form data for back navigation + const [savedProviderForm, setSavedProviderForm] = useState<{ + name?: string; + requester?: string; + base_url?: string; + api_key?: string; + }>({}); + // Saved selected scanned models for back navigation + const [savedSelectedModels, setSavedSelectedModels] = useState>( + new Set(), + ); const [createdBotUuid, setCreatedBotUuid] = useState(null); const [webhookUrl, setWebhookUrl] = useState(''); const [extraWebhookUrl, setExtraWebhookUrl] = useState(''); @@ -334,7 +345,7 @@ export default function WizardPage() { aiEngineMode, selectedRunner, modelSource, - providerCreated, + modelsAdded, ]); const goNext = useCallback(() => { @@ -748,6 +759,10 @@ export default function WizardPage() { saveProgress({ step: 2, selected_runner: 'local-agent' }); }} onResetModelSource={() => setModelSource(null)} + savedProviderForm={savedProviderForm} + onSavedProviderFormChange={setSavedProviderForm} + savedSelectedModels={savedSelectedModels} + onSavedSelectedModelsChange={setSavedSelectedModels} runnerConfigItems={selectedRunnerConfigItems} runnerConfigValues={runnerConfig} onRunnerConfigChange={setRunnerConfig} @@ -1088,9 +1103,13 @@ function StepBotConfig({ function WizardModelScan({ providerUuid, + initialSelectedModels, + onSelectedModelsChange, onModelsAdded, }: { providerUuid: string | null; + initialSelectedModels: Set; + onSelectedModelsChange: (v: Set) => void; onModelsAdded: () => void; }) { const { t } = useTranslation(); @@ -1098,7 +1117,9 @@ function WizardModelScan({ const [scannedModels, setScannedModels] = useState< { name: string; context_length?: number | null }[] >([]); - const [selectedModels, setSelectedModels] = useState>(new Set()); + const [selectedModels, setSelectedModels] = useState>( + initialSelectedModels, + ); const [adding, setAdding] = useState(false); const [scanDone, setScanDone] = useState(false); @@ -1133,6 +1154,7 @@ function WizardModelScan({ const next = new Set(prev); if (next.has(name)) next.delete(name); else next.add(name); + onSelectedModelsChange(next); return next; }); }; @@ -1261,6 +1283,10 @@ function StepAIEngine({ onProviderCreated, onModelsAdded, onResetModelSource, + savedProviderForm, + onSavedProviderFormChange, + savedSelectedModels, + onSavedSelectedModelsChange, runnerConfigItems, runnerConfigValues, onRunnerConfigChange, @@ -1281,6 +1307,10 @@ function StepAIEngine({ onProviderCreated: (uuid?: string) => void; onModelsAdded: () => void; onResetModelSource: () => void; + savedProviderForm: { name?: string; requester?: string; base_url?: string; api_key?: string }; + onSavedProviderFormChange: (v: { name?: string; requester?: string; base_url?: string; api_key?: string }) => void; + savedSelectedModels: Set; + onSavedSelectedModelsChange: (v: Set) => void; runnerConfigItems: IDynamicFormItemSchema[]; runnerConfigValues: Record; onRunnerConfigChange: (v: Record) => void; @@ -1481,7 +1511,11 @@ function StepAIEngine({
{ + onProviderCreated(uuid); + }} onFormCancel={onResetModelSource} />
@@ -1494,6 +1528,8 @@ function StepAIEngine({ return ( );