From 8c2d58183cacba477acfa28d3372a192b0358282 Mon Sep 17 00:00:00 2001 From: Mike Fortman Date: Wed, 22 Oct 2025 17:05:24 -0500 Subject: [PATCH] Finish up loading states --- .../components/onboarding-content.tsx | 23 +++++-- .../components/onboarding-upload.tsx | 67 ++++++++++++++----- .../components/animated-provider-steps.tsx | 10 +-- .../onboarding/components/onboarding-card.tsx | 11 ++- 4 files changed, 79 insertions(+), 32 deletions(-) diff --git a/frontend/src/app/new-onboarding/components/onboarding-content.tsx b/frontend/src/app/new-onboarding/components/onboarding-content.tsx index f9adf224..645d6e40 100644 --- a/frontend/src/app/new-onboarding/components/onboarding-content.tsx +++ b/frontend/src/app/new-onboarding/components/onboarding-content.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { StickToBottom } from "use-stick-to-bottom"; import { AssistantMessage } from "@/app/chat/components/assistant-message"; import { UserMessage } from "@/app/chat/components/user-message"; @@ -59,6 +59,12 @@ export function OnboardingContent({ // Determine which message to show (streaming takes precedence) const displayMessage = streamingMessage || assistantMessage; + useEffect(() => { + if (currentStep === 1 && !isLoading && !!displayMessage) { + handleStepComplete(); + } + }, [isLoading, displayMessage, handleStepComplete]); + return (
+ {/* Step 1 */} = 0} isCompleted={currentStep > 0} @@ -76,6 +83,7 @@ export function OnboardingContent({ + {/* Step 2 */} = 1} isCompleted={currentStep > 1 || !!selectedNudge} @@ -94,7 +102,7 @@ export function OnboardingContent({ {currentStep >= 1 && !!selectedNudge && ( 1} + isCompleted={currentStep > 2} /> )} @@ -109,13 +117,13 @@ export function OnboardingContent({ expandedFunctionCalls={new Set()} onToggle={() => {}} isStreaming={!!streamingMessage} - isCompleted={currentStep > 1} + isCompleted={currentStep > 2} /> )} - {/* Still kind of part of step 2 */} + {/* Step 3 */} = 2 && !isLoading && !!displayMessage} isCompleted={currentStep > 2} text="Now, let's add your data." hideIcon={true} @@ -123,9 +131,10 @@ export function OnboardingContent({ + {/* Step 4 */} = 2} - isCompleted={currentStep > 2} + isVisible={currentStep >= 3} + isCompleted={currentStep > 3} text="Step 3: You're all set!" >
diff --git a/frontend/src/app/new-onboarding/components/onboarding-upload.tsx b/frontend/src/app/new-onboarding/components/onboarding-upload.tsx index 0c4a1fc9..00d90097 100644 --- a/frontend/src/app/new-onboarding/components/onboarding-upload.tsx +++ b/frontend/src/app/new-onboarding/components/onboarding-upload.tsx @@ -1,6 +1,8 @@ import { ChangeEvent, useRef, useState } from "react"; import { Button } from "@/components/ui/button"; import { duplicateCheck, uploadFile } from "@/lib/upload-utils"; +import { AnimatePresence, motion } from "motion/react"; +import { AnimatedProviderSteps } from "@/app/onboarding/components/animated-provider-steps"; interface OnboardingUploadProps { onComplete: () => void; @@ -9,6 +11,12 @@ interface OnboardingUploadProps { const OnboardingUpload = ({ onComplete }: OnboardingUploadProps) => { const fileInputRef = useRef(null); const [isUploading, setIsUploading] = useState(false); + const [currentStep, setCurrentStep] = useState(null); + + const STEP_LIST = [ + "Analyzing your document", + "Ingesting your document", + ]; const resetFileInput = () => { if (fileInputRef.current) { @@ -24,12 +32,14 @@ const OnboardingUpload = ({ onComplete }: OnboardingUploadProps) => { const performUpload = async (file: File, replace = false) => { setIsUploading(true); try { + setCurrentStep(1); await uploadFile(file, replace); console.log("Document uploaded successfully"); } catch (error) { console.error("Upload failed", (error as Error).message); } finally { setIsUploading(false); + setCurrentStep(STEP_LIST.length); onComplete(); } }; @@ -42,6 +52,7 @@ const OnboardingUpload = ({ onComplete }: OnboardingUploadProps) => { } try { + setCurrentStep(0); const duplicateInfo = await duplicateCheck(selectedFile); if (duplicateInfo.exists) { console.log("Duplicate file detected"); @@ -58,23 +69,45 @@ const OnboardingUpload = ({ onComplete }: OnboardingUploadProps) => { return ( -
- - -
+ + {currentStep === null ? ( + + + + + ) : ( + + + + )} + ) } diff --git a/frontend/src/app/onboarding/components/animated-provider-steps.tsx b/frontend/src/app/onboarding/components/animated-provider-steps.tsx index cc52b783..f2b48c99 100644 --- a/frontend/src/app/onboarding/components/animated-provider-steps.tsx +++ b/frontend/src/app/onboarding/components/animated-provider-steps.tsx @@ -9,16 +9,12 @@ import { cn } from "@/lib/utils"; export function AnimatedProviderSteps({ currentStep, setCurrentStep, + steps, }: { currentStep: number; setCurrentStep: (step: number) => void; + steps: string[]; }) { - const steps = [ - "Setting up your model provider", - "Defining schema", - "Configuring Langflow", - "Ingesting sample data", - ]; useEffect(() => { if (currentStep < steps.length - 1) { @@ -27,7 +23,7 @@ export function AnimatedProviderSteps({ }, 1000); return () => clearInterval(interval); } - }, [currentStep, setCurrentStep]); + }, [currentStep, setCurrentStep, steps]); const isDone = currentStep >= steps.length; diff --git a/frontend/src/app/onboarding/components/onboarding-card.tsx b/frontend/src/app/onboarding/components/onboarding-card.tsx index 898409a3..10f08d09 100644 --- a/frontend/src/app/onboarding/components/onboarding-card.tsx +++ b/frontend/src/app/onboarding/components/onboarding-card.tsx @@ -34,7 +34,15 @@ interface OnboardingCardProps { onComplete: () => void; } -const TOTAL_PROVIDER_STEPS = 4; + +const STEP_LIST = [ + "Setting up your model provider", + "Defining schema", + "Configuring Langflow", + "Ingesting sample data", +]; + +const TOTAL_PROVIDER_STEPS = STEP_LIST.length; const OnboardingCard = ({ onComplete }: OnboardingCardProps) => { const updatedOnboarding = process.env.UPDATED_ONBOARDING === "true"; @@ -245,6 +253,7 @@ const OnboardingCard = ({ onComplete }: OnboardingCardProps) => { )}