mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-08-22 02:07:13 +00:00
fix(wizard): preserve form data and model selection on back nav
- Add initialValues and onValuesChange props to ProviderForm - Save provider form data and selected models in wizard state - Fix canProceed missing modelsAdded dependency - Restore form data and selections when navigating back
This commit is contained in:
@@ -31,14 +31,25 @@ const getFormSchema = (t: (key: string) => string) =>
|
|||||||
api_key: z.string().optional(),
|
api_key: z.string().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export interface ProviderFormInitialValues {
|
||||||
|
name?: string;
|
||||||
|
requester?: string;
|
||||||
|
base_url?: string;
|
||||||
|
api_key?: string;
|
||||||
|
}
|
||||||
|
|
||||||
interface ProviderFormProps {
|
interface ProviderFormProps {
|
||||||
providerId?: string;
|
providerId?: string;
|
||||||
|
initialValues?: ProviderFormInitialValues;
|
||||||
|
onValuesChange?: (values: ProviderFormInitialValues) => void;
|
||||||
onFormSubmit: (providerUuid?: string) => void;
|
onFormSubmit: (providerUuid?: string) => void;
|
||||||
onFormCancel: () => void;
|
onFormCancel: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ProviderForm({
|
export default function ProviderForm({
|
||||||
providerId,
|
providerId,
|
||||||
|
initialValues,
|
||||||
|
onValuesChange,
|
||||||
onFormSubmit,
|
onFormSubmit,
|
||||||
onFormCancel,
|
onFormCancel,
|
||||||
}: ProviderFormProps) {
|
}: ProviderFormProps) {
|
||||||
@@ -48,13 +59,22 @@ export default function ProviderForm({
|
|||||||
const form = useForm<z.infer<typeof formSchema>>({
|
const form = useForm<z.infer<typeof formSchema>>({
|
||||||
resolver: zodResolver(formSchema),
|
resolver: zodResolver(formSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
name: '',
|
name: initialValues?.name ?? '',
|
||||||
requester: '',
|
requester: initialValues?.requester ?? '',
|
||||||
base_url: '',
|
base_url: initialValues?.base_url ?? '',
|
||||||
api_key: '',
|
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<
|
const [requesterList, setRequesterList] = useState<
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -109,6 +109,17 @@ export default function WizardPage() {
|
|||||||
const [modelsAdded, setModelsAdded] = useState(false);
|
const [modelsAdded, setModelsAdded] = useState(false);
|
||||||
// Sub-layer within Step 2: 0=main, 1=sub-choice, 2=provider, 3=scan, 4=config
|
// Sub-layer within Step 2: 0=main, 1=sub-choice, 2=provider, 3=scan, 4=config
|
||||||
const [step2Layer, setStep2Layer] = useState(0);
|
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<Set<string>>(
|
||||||
|
new Set(),
|
||||||
|
);
|
||||||
const [createdBotUuid, setCreatedBotUuid] = useState<string | null>(null);
|
const [createdBotUuid, setCreatedBotUuid] = useState<string | null>(null);
|
||||||
const [webhookUrl, setWebhookUrl] = useState<string>('');
|
const [webhookUrl, setWebhookUrl] = useState<string>('');
|
||||||
const [extraWebhookUrl, setExtraWebhookUrl] = useState<string>('');
|
const [extraWebhookUrl, setExtraWebhookUrl] = useState<string>('');
|
||||||
@@ -334,7 +345,7 @@ export default function WizardPage() {
|
|||||||
aiEngineMode,
|
aiEngineMode,
|
||||||
selectedRunner,
|
selectedRunner,
|
||||||
modelSource,
|
modelSource,
|
||||||
providerCreated,
|
modelsAdded,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const goNext = useCallback(() => {
|
const goNext = useCallback(() => {
|
||||||
@@ -748,6 +759,10 @@ export default function WizardPage() {
|
|||||||
saveProgress({ step: 2, selected_runner: 'local-agent' });
|
saveProgress({ step: 2, selected_runner: 'local-agent' });
|
||||||
}}
|
}}
|
||||||
onResetModelSource={() => setModelSource(null)}
|
onResetModelSource={() => setModelSource(null)}
|
||||||
|
savedProviderForm={savedProviderForm}
|
||||||
|
onSavedProviderFormChange={setSavedProviderForm}
|
||||||
|
savedSelectedModels={savedSelectedModels}
|
||||||
|
onSavedSelectedModelsChange={setSavedSelectedModels}
|
||||||
runnerConfigItems={selectedRunnerConfigItems}
|
runnerConfigItems={selectedRunnerConfigItems}
|
||||||
runnerConfigValues={runnerConfig}
|
runnerConfigValues={runnerConfig}
|
||||||
onRunnerConfigChange={setRunnerConfig}
|
onRunnerConfigChange={setRunnerConfig}
|
||||||
@@ -1088,9 +1103,13 @@ function StepBotConfig({
|
|||||||
|
|
||||||
function WizardModelScan({
|
function WizardModelScan({
|
||||||
providerUuid,
|
providerUuid,
|
||||||
|
initialSelectedModels,
|
||||||
|
onSelectedModelsChange,
|
||||||
onModelsAdded,
|
onModelsAdded,
|
||||||
}: {
|
}: {
|
||||||
providerUuid: string | null;
|
providerUuid: string | null;
|
||||||
|
initialSelectedModels: Set<string>;
|
||||||
|
onSelectedModelsChange: (v: Set<string>) => void;
|
||||||
onModelsAdded: () => void;
|
onModelsAdded: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -1098,7 +1117,9 @@ function WizardModelScan({
|
|||||||
const [scannedModels, setScannedModels] = useState<
|
const [scannedModels, setScannedModels] = useState<
|
||||||
{ name: string; context_length?: number | null }[]
|
{ name: string; context_length?: number | null }[]
|
||||||
>([]);
|
>([]);
|
||||||
const [selectedModels, setSelectedModels] = useState<Set<string>>(new Set());
|
const [selectedModels, setSelectedModels] = useState<Set<string>>(
|
||||||
|
initialSelectedModels,
|
||||||
|
);
|
||||||
const [adding, setAdding] = useState(false);
|
const [adding, setAdding] = useState(false);
|
||||||
const [scanDone, setScanDone] = useState(false);
|
const [scanDone, setScanDone] = useState(false);
|
||||||
|
|
||||||
@@ -1133,6 +1154,7 @@ function WizardModelScan({
|
|||||||
const next = new Set(prev);
|
const next = new Set(prev);
|
||||||
if (next.has(name)) next.delete(name);
|
if (next.has(name)) next.delete(name);
|
||||||
else next.add(name);
|
else next.add(name);
|
||||||
|
onSelectedModelsChange(next);
|
||||||
return next;
|
return next;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -1261,6 +1283,10 @@ function StepAIEngine({
|
|||||||
onProviderCreated,
|
onProviderCreated,
|
||||||
onModelsAdded,
|
onModelsAdded,
|
||||||
onResetModelSource,
|
onResetModelSource,
|
||||||
|
savedProviderForm,
|
||||||
|
onSavedProviderFormChange,
|
||||||
|
savedSelectedModels,
|
||||||
|
onSavedSelectedModelsChange,
|
||||||
runnerConfigItems,
|
runnerConfigItems,
|
||||||
runnerConfigValues,
|
runnerConfigValues,
|
||||||
onRunnerConfigChange,
|
onRunnerConfigChange,
|
||||||
@@ -1281,6 +1307,10 @@ function StepAIEngine({
|
|||||||
onProviderCreated: (uuid?: string) => void;
|
onProviderCreated: (uuid?: string) => void;
|
||||||
onModelsAdded: () => void;
|
onModelsAdded: () => void;
|
||||||
onResetModelSource: () => 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<string>;
|
||||||
|
onSavedSelectedModelsChange: (v: Set<string>) => void;
|
||||||
runnerConfigItems: IDynamicFormItemSchema[];
|
runnerConfigItems: IDynamicFormItemSchema[];
|
||||||
runnerConfigValues: Record<string, unknown>;
|
runnerConfigValues: Record<string, unknown>;
|
||||||
onRunnerConfigChange: (v: Record<string, unknown>) => void;
|
onRunnerConfigChange: (v: Record<string, unknown>) => void;
|
||||||
@@ -1481,7 +1511,11 @@ function StepAIEngine({
|
|||||||
</div>
|
</div>
|
||||||
<div className="border rounded-lg p-6 bg-card">
|
<div className="border rounded-lg p-6 bg-card">
|
||||||
<ProviderForm
|
<ProviderForm
|
||||||
onFormSubmit={onProviderCreated}
|
initialValues={savedProviderForm}
|
||||||
|
onValuesChange={onSavedProviderFormChange}
|
||||||
|
onFormSubmit={(uuid) => {
|
||||||
|
onProviderCreated(uuid);
|
||||||
|
}}
|
||||||
onFormCancel={onResetModelSource}
|
onFormCancel={onResetModelSource}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -1494,6 +1528,8 @@ function StepAIEngine({
|
|||||||
return (
|
return (
|
||||||
<WizardModelScan
|
<WizardModelScan
|
||||||
providerUuid={createdProviderUuid}
|
providerUuid={createdProviderUuid}
|
||||||
|
initialSelectedModels={savedSelectedModels}
|
||||||
|
onSelectedModelsChange={onSavedSelectedModelsChange}
|
||||||
onModelsAdded={onModelsAdded}
|
onModelsAdded={onModelsAdded}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user