mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-08-22 02:07:13 +00:00
fix(wizard): preserve state when navigating back between layers
Use a dedicated step2Layer state for sub-layer navigation within Step 2, instead of resetting data flags. This preserves provider form data, scan results, and model selections when going back.
This commit is contained in:
+27
-62
@@ -107,6 +107,8 @@ export default function WizardPage() {
|
|||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
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
|
||||||
|
const [step2Layer, setStep2Layer] = useState(0);
|
||||||
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>('');
|
||||||
@@ -288,6 +290,7 @@ export default function WizardPage() {
|
|||||||
const handleSelectRunner = useCallback(
|
const handleSelectRunner = useCallback(
|
||||||
(runner: string) => {
|
(runner: string) => {
|
||||||
setSelectedRunner(runner);
|
setSelectedRunner(runner);
|
||||||
|
setStep2Layer(4);
|
||||||
saveProgress({ step: 2, selected_runner: runner });
|
saveProgress({ step: 2, selected_runner: runner });
|
||||||
},
|
},
|
||||||
[saveProgress],
|
[saveProgress],
|
||||||
@@ -296,9 +299,7 @@ export default function WizardPage() {
|
|||||||
const handleAiEngineModeSelect = useCallback(
|
const handleAiEngineModeSelect = useCallback(
|
||||||
(mode: 'orchestrated' | 'llm') => {
|
(mode: 'orchestrated' | 'llm') => {
|
||||||
setAiEngineMode(mode);
|
setAiEngineMode(mode);
|
||||||
setSelectedRunner(null);
|
setStep2Layer(1);
|
||||||
setModelSource(null);
|
|
||||||
setProviderCreated(false);
|
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
@@ -345,55 +346,16 @@ export default function WizardPage() {
|
|||||||
}, [currentStep, canProceed, saveProgress]);
|
}, [currentStep, canProceed, saveProgress]);
|
||||||
|
|
||||||
const goPrev = useCallback(() => {
|
const goPrev = useCallback(() => {
|
||||||
if (currentStep === 2) {
|
if (currentStep === 2 && step2Layer > 0) {
|
||||||
// Intra-step back navigation for AI Engine step
|
setStep2Layer(step2Layer - 1);
|
||||||
if (aiEngineMode === 'orchestrated' && selectedRunner) {
|
return;
|
||||||
setSelectedRunner(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// LLM + custom: config form → model scan
|
|
||||||
if (aiEngineMode === 'llm' && modelSource === 'custom' && modelsAdded) {
|
|
||||||
setModelsAdded(false);
|
|
||||||
setSelectedRunner(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// LLM + custom: model scan → provider form
|
|
||||||
if (
|
|
||||||
aiEngineMode === 'llm' &&
|
|
||||||
modelSource === 'custom' &&
|
|
||||||
providerCreated &&
|
|
||||||
!modelsAdded
|
|
||||||
) {
|
|
||||||
setProviderCreated(false);
|
|
||||||
setCreatedProviderUuid(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// LLM + custom: provider form → model source
|
|
||||||
if (
|
|
||||||
aiEngineMode === 'llm' &&
|
|
||||||
modelSource === 'custom' &&
|
|
||||||
!providerCreated
|
|
||||||
) {
|
|
||||||
setModelSource(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// LLM: model source → main choice
|
|
||||||
if (modelSource) {
|
|
||||||
setModelSource(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Main choice → previous step
|
|
||||||
if (aiEngineMode) {
|
|
||||||
setAiEngineMode(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (currentStep > 0) {
|
if (currentStep > 0) {
|
||||||
const prevStep = currentStep - 1;
|
const prevStep = currentStep - 1;
|
||||||
setCurrentStep(prevStep);
|
setCurrentStep(prevStep);
|
||||||
saveProgress({ step: prevStep });
|
saveProgress({ step: prevStep });
|
||||||
}
|
}
|
||||||
}, [currentStep, saveProgress, aiEngineMode, selectedRunner, modelSource, providerCreated, modelsAdded]);
|
}, [currentStep, step2Layer, saveProgress]);
|
||||||
|
|
||||||
// ---- Create Bot (Step 0) ----
|
// ---- Create Bot (Step 0) ----
|
||||||
// Creates a disabled bot using the adapter label as name.
|
// Creates a disabled bot using the adapter label as name.
|
||||||
@@ -594,9 +556,15 @@ export default function WizardPage() {
|
|||||||
setModelSource(source);
|
setModelSource(source);
|
||||||
if (source === 'space') {
|
if (source === 'space') {
|
||||||
handleSpaceAuth();
|
handleSpaceAuth();
|
||||||
|
} else if (providerCreated && modelsAdded) {
|
||||||
|
setStep2Layer(4);
|
||||||
|
} else if (providerCreated) {
|
||||||
|
setStep2Layer(3);
|
||||||
|
} else {
|
||||||
|
setStep2Layer(2);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[handleSpaceAuth],
|
[handleSpaceAuth, providerCreated, modelsAdded],
|
||||||
);
|
);
|
||||||
|
|
||||||
// ---- Check if local account ----
|
// ---- Check if local account ----
|
||||||
@@ -756,6 +724,7 @@ export default function WizardPage() {
|
|||||||
{currentStep === 2 && (
|
{currentStep === 2 && (
|
||||||
<StepAIEngine
|
<StepAIEngine
|
||||||
runnerOptions={runnerOptions}
|
runnerOptions={runnerOptions}
|
||||||
|
step2Layer={step2Layer}
|
||||||
aiEngineMode={aiEngineMode}
|
aiEngineMode={aiEngineMode}
|
||||||
onAiEngineModeSelect={handleAiEngineModeSelect}
|
onAiEngineModeSelect={handleAiEngineModeSelect}
|
||||||
selectedRunner={selectedRunner}
|
selectedRunner={selectedRunner}
|
||||||
@@ -770,10 +739,13 @@ export default function WizardPage() {
|
|||||||
onProviderCreated={(uuid) => {
|
onProviderCreated={(uuid) => {
|
||||||
setProviderCreated(true);
|
setProviderCreated(true);
|
||||||
setCreatedProviderUuid(uuid ?? null);
|
setCreatedProviderUuid(uuid ?? null);
|
||||||
|
setStep2Layer(3);
|
||||||
}}
|
}}
|
||||||
onModelsAdded={() => {
|
onModelsAdded={() => {
|
||||||
setModelsAdded(true);
|
setModelsAdded(true);
|
||||||
handleSelectRunner('local-agent');
|
setSelectedRunner('local-agent');
|
||||||
|
setStep2Layer(4);
|
||||||
|
saveProgress({ step: 2, selected_runner: 'local-agent' });
|
||||||
}}
|
}}
|
||||||
onResetModelSource={() => setModelSource(null)}
|
onResetModelSource={() => setModelSource(null)}
|
||||||
runnerConfigItems={selectedRunnerConfigItems}
|
runnerConfigItems={selectedRunnerConfigItems}
|
||||||
@@ -1274,6 +1246,7 @@ function WizardModelScan({
|
|||||||
|
|
||||||
function StepAIEngine({
|
function StepAIEngine({
|
||||||
runnerOptions,
|
runnerOptions,
|
||||||
|
step2Layer,
|
||||||
aiEngineMode,
|
aiEngineMode,
|
||||||
onAiEngineModeSelect,
|
onAiEngineModeSelect,
|
||||||
selectedRunner,
|
selectedRunner,
|
||||||
@@ -1293,6 +1266,7 @@ function StepAIEngine({
|
|||||||
onRunnerConfigChange,
|
onRunnerConfigChange,
|
||||||
}: {
|
}: {
|
||||||
runnerOptions: { name: string; label: { en_US: string; zh_Hans: string } }[];
|
runnerOptions: { name: string; label: { en_US: string; zh_Hans: string } }[];
|
||||||
|
step2Layer: number;
|
||||||
aiEngineMode: 'orchestrated' | 'llm' | null;
|
aiEngineMode: 'orchestrated' | 'llm' | null;
|
||||||
onAiEngineModeSelect: (mode: 'orchestrated' | 'llm') => void;
|
onAiEngineModeSelect: (mode: 'orchestrated' | 'llm') => void;
|
||||||
selectedRunner: string | null;
|
selectedRunner: string | null;
|
||||||
@@ -1332,7 +1306,7 @@ function StepAIEngine({
|
|||||||
);
|
);
|
||||||
|
|
||||||
// ---- Layer 0: Main choice ----
|
// ---- Layer 0: Main choice ----
|
||||||
if (!aiEngineMode) {
|
if (step2Layer === 0) {
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6 max-w-3xl mx-auto">
|
<div className="space-y-6 max-w-3xl mx-auto">
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
@@ -1395,7 +1369,7 @@ function StepAIEngine({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---- Layer 1a: Orchestrated runners ----
|
// ---- Layer 1a: Orchestrated runners ----
|
||||||
if (aiEngineMode === 'orchestrated' && !selectedRunner) {
|
if (step2Layer === 1 && aiEngineMode === 'orchestrated') {
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6 max-w-4xl mx-auto">
|
<div className="space-y-6 max-w-4xl mx-auto">
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
@@ -1431,7 +1405,7 @@ function StepAIEngine({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---- Layer 1b: LLM model source selection ----
|
// ---- Layer 1b: LLM model source selection ----
|
||||||
if (aiEngineMode === 'llm' && !modelSource) {
|
if (step2Layer === 1 && aiEngineMode === 'llm') {
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6 max-w-3xl mx-auto">
|
<div className="space-y-6 max-w-3xl mx-auto">
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
@@ -1494,11 +1468,7 @@ function StepAIEngine({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---- Layer 2: Custom provider creation form ----
|
// ---- Layer 2: Custom provider creation form ----
|
||||||
if (
|
if (step2Layer === 2) {
|
||||||
aiEngineMode === 'llm' &&
|
|
||||||
modelSource === 'custom' &&
|
|
||||||
!providerCreated
|
|
||||||
) {
|
|
||||||
return (
|
return (
|
||||||
<div className="max-w-2xl mx-auto w-full animate-in fade-in slide-in-from-bottom-2 duration-300">
|
<div className="max-w-2xl mx-auto w-full animate-in fade-in slide-in-from-bottom-2 duration-300">
|
||||||
<div className="text-center mb-6">
|
<div className="text-center mb-6">
|
||||||
@@ -1520,12 +1490,7 @@ function StepAIEngine({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---- Layer 2.5: Model scan & add after provider creation ----
|
// ---- Layer 2.5: Model scan & add after provider creation ----
|
||||||
if (
|
if (step2Layer === 3) {
|
||||||
aiEngineMode === 'llm' &&
|
|
||||||
modelSource === 'custom' &&
|
|
||||||
providerCreated &&
|
|
||||||
!modelsAdded
|
|
||||||
) {
|
|
||||||
return (
|
return (
|
||||||
<WizardModelScan
|
<WizardModelScan
|
||||||
providerUuid={createdProviderUuid}
|
providerUuid={createdProviderUuid}
|
||||||
|
|||||||
Reference in New Issue
Block a user