mirror of
https://github.com/Mintplex-Labs/anything-llm.git
synced 2025-03-16 23:22:22 +00:00
added onboarding data handling modal (#342)
* added onboarding data handling modal * adding data handling modal component * update element to list Update copy * remove useEffect dep * refactor onboarding navigation using history --------- Co-authored-by: timothycarambat <rambat1010@gmail.com>
This commit is contained in:
parent
997482ef8f
commit
458ffed0c7
9 changed files with 232 additions and 45 deletions
|
@ -5,7 +5,7 @@ import useLogo from "../../../../../hooks/useLogo";
|
||||||
import { Plus } from "@phosphor-icons/react";
|
import { Plus } from "@phosphor-icons/react";
|
||||||
import showToast from "../../../../../utils/toast";
|
import showToast from "../../../../../utils/toast";
|
||||||
|
|
||||||
function AppearanceSetup({ nextStep }) {
|
function AppearanceSetup({ prevStep, nextStep }) {
|
||||||
const { logo: _initLogo } = useLogo();
|
const { logo: _initLogo } = useLogo();
|
||||||
const [logo, setLogo] = useState("");
|
const [logo, setLogo] = useState("");
|
||||||
const [isDefaultLogo, setIsDefaultLogo] = useState(true);
|
const [isDefaultLogo, setIsDefaultLogo] = useState(true);
|
||||||
|
@ -57,7 +57,7 @@ function AppearanceSetup({ nextStep }) {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="w-full">
|
||||||
<div className="flex flex-col w-full px-10 py-12">
|
<div className="flex flex-col w-full px-10 py-12">
|
||||||
<div className="flex flex-col gap-y-2">
|
<div className="flex flex-col gap-y-2">
|
||||||
<h2 className="text-white text-sm font-medium">Custom Logo</h2>
|
<h2 className="text-white text-sm font-medium">Custom Logo</h2>
|
||||||
|
@ -109,20 +109,23 @@ function AppearanceSetup({ nextStep }) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex w-full justify-between items-center p-6 space-x-6 border-t rounded-b border-gray-500/50">
|
<div className="flex w-full justify-between items-center p-6 space-x-6 border-t rounded-b border-gray-500/50">
|
||||||
<div className="w-96 text-white text-opacity-80 text-xs font-base">
|
<button
|
||||||
Want to customize the automatic messages in your chat? Find more
|
onClick={prevStep}
|
||||||
customization options on the appearance settings page.
|
type="button"
|
||||||
</div>
|
className="px-4 py-2 rounded-lg text-white hover:bg-sidebar"
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</button>
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<button
|
<button
|
||||||
onClick={nextStep}
|
onClick={() => nextStep("user_mode_setup")}
|
||||||
type="button"
|
type="button"
|
||||||
className="px-4 py-2 rounded-lg text-white hover:bg-sidebar"
|
className="px-4 py-2 rounded-lg text-white hover:bg-sidebar"
|
||||||
>
|
>
|
||||||
Skip
|
Skip
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={nextStep}
|
onClick={() => nextStep("user_mode_setup")}
|
||||||
type="button"
|
type="button"
|
||||||
className="border border-slate-200 px-4 py-2 rounded-lg text-slate-800 bg-slate-200 text-sm items-center flex gap-x-2 hover:text-white hover:bg-transparent focus:ring-gray-800 font-semibold shadow"
|
className="border border-slate-200 px-4 py-2 rounded-lg text-slate-800 bg-slate-200 text-sm items-center flex gap-x-2 hover:text-white hover:bg-transparent focus:ring-gray-800 font-semibold shadow"
|
||||||
>
|
>
|
||||||
|
|
|
@ -0,0 +1,171 @@
|
||||||
|
import React, { memo, useEffect, useState } from "react";
|
||||||
|
import System from "../../../../../models/system";
|
||||||
|
import OpenAiLogo from "../../../../../media/llmprovider/openai.png";
|
||||||
|
import AzureOpenAiLogo from "../../../../../media/llmprovider/azure.png";
|
||||||
|
import AnthropicLogo from "../../../../../media/llmprovider/anthropic.png";
|
||||||
|
import ChromaLogo from "../../../../../media/vectordbs/chroma.png";
|
||||||
|
import PineconeLogo from "../../../../../media/vectordbs/pinecone.png";
|
||||||
|
import LanceDbLogo from "../../../../../media/vectordbs/lancedb.png";
|
||||||
|
import WeaviateLogo from "../../../../../media/vectordbs/weaviate.png";
|
||||||
|
import QDrantLogo from "../../../../../media/vectordbs/qdrant.png";
|
||||||
|
import PreLoader from "../../../../../components/Preloader";
|
||||||
|
|
||||||
|
const LLM_SELECTION_PRIVACY = {
|
||||||
|
openai: {
|
||||||
|
name: "OpenAI",
|
||||||
|
description: [
|
||||||
|
"Your chats will not be used for training",
|
||||||
|
"Your prompts and document text used in responses are visible to OpenAI",
|
||||||
|
],
|
||||||
|
logo: OpenAiLogo,
|
||||||
|
},
|
||||||
|
azure: {
|
||||||
|
name: "Azure OpenAI",
|
||||||
|
description: [
|
||||||
|
"Your chats will not be used for training",
|
||||||
|
"Your text and embedding text are not visible to OpenAI or Microsoft",
|
||||||
|
],
|
||||||
|
logo: AzureOpenAiLogo,
|
||||||
|
},
|
||||||
|
anthropic: {
|
||||||
|
name: "Anthropic",
|
||||||
|
description: [
|
||||||
|
"Your chats will not be used for training",
|
||||||
|
"Your prompts and document text used in responses are visible to Anthropic",
|
||||||
|
],
|
||||||
|
logo: AnthropicLogo,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const VECTOR_DB_PRIVACY = {
|
||||||
|
chroma: {
|
||||||
|
name: "Chroma",
|
||||||
|
description: [
|
||||||
|
"Your embedded text not visible outside of your Chroma instance",
|
||||||
|
"Access to your instance is managed by you",
|
||||||
|
],
|
||||||
|
logo: ChromaLogo,
|
||||||
|
},
|
||||||
|
pinecone: {
|
||||||
|
name: "Pinecone",
|
||||||
|
description: [
|
||||||
|
"Your embedded text and vectors are visible to Pinecone, but is not accessed",
|
||||||
|
"They manage your data and access to their servers",
|
||||||
|
],
|
||||||
|
logo: PineconeLogo,
|
||||||
|
},
|
||||||
|
qdrant: {
|
||||||
|
name: "Qdrant",
|
||||||
|
description: [
|
||||||
|
"Your embedded text is visible to Qdrant if using a hosted instance",
|
||||||
|
"Your embedded text is not visible to Qdrant if using a self-hosted instance",
|
||||||
|
"Your data is stored on your Qdrant instance",
|
||||||
|
],
|
||||||
|
logo: QDrantLogo,
|
||||||
|
},
|
||||||
|
weaviate: {
|
||||||
|
name: "Weaviate",
|
||||||
|
description: [
|
||||||
|
"Your embedded text is visible to Weaviate, if using a hosted instance",
|
||||||
|
"Your embedded text is not visible to Weaviate, if using a self-hosted instance",
|
||||||
|
"Your data is stored on your Weaviate instance",
|
||||||
|
],
|
||||||
|
logo: WeaviateLogo,
|
||||||
|
},
|
||||||
|
lancedb: {
|
||||||
|
name: "LanceDB",
|
||||||
|
description: [
|
||||||
|
"Your embedded text and vectors are only accessible by this AnythingLLM instance",
|
||||||
|
],
|
||||||
|
logo: LanceDbLogo,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function DataHandling({ nextStep, prevStep, currentStep }) {
|
||||||
|
const [llmChoice, setLLMChoice] = useState("openai");
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [vectorDb, setVectorDb] = useState("pinecone");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
async function fetchKeys() {
|
||||||
|
const _settings = await System.keys();
|
||||||
|
setLLMChoice(_settings?.LLMProvider);
|
||||||
|
setVectorDb(_settings?.VectorDB);
|
||||||
|
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
if (currentStep === "data_handling") {
|
||||||
|
fetchKeys();
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (loading)
|
||||||
|
return (
|
||||||
|
<div className="w-full h-full flex justify-center items-center p-20">
|
||||||
|
<PreLoader />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="max-w-[750px]">
|
||||||
|
<div className="p-8 flex gap-x-16">
|
||||||
|
<div className="w-1/2 flex flex-col gap-y-3.5">
|
||||||
|
<div className="text-white text-base font-bold">LLM Selection</div>
|
||||||
|
<div className="flex items-center gap-2.5">
|
||||||
|
<img
|
||||||
|
src={LLM_SELECTION_PRIVACY[llmChoice].logo}
|
||||||
|
alt="LLM Logo"
|
||||||
|
className="w-8 h-8 rounded"
|
||||||
|
/>
|
||||||
|
<p className="text-white text-sm font-bold">
|
||||||
|
{LLM_SELECTION_PRIVACY[llmChoice].name}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col">
|
||||||
|
{LLM_SELECTION_PRIVACY[llmChoice].description.map((desc) => (
|
||||||
|
<p className="text-white/90 text-sm">
|
||||||
|
<b>•</b> {desc}
|
||||||
|
</p>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="w-1/2 flex flex-col gap-y-3.5">
|
||||||
|
<div className="text-white text-base font-bold">Vector Database</div>
|
||||||
|
<div className="flex items-center gap-2.5">
|
||||||
|
<img
|
||||||
|
src={VECTOR_DB_PRIVACY[vectorDb].logo}
|
||||||
|
alt="Vector DB Logo"
|
||||||
|
className="w-8 h-8 rounded"
|
||||||
|
/>
|
||||||
|
<p className="text-white text-sm font-bold">
|
||||||
|
{VECTOR_DB_PRIVACY[vectorDb].name}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<ul className="flex flex-col list-disc">
|
||||||
|
{VECTOR_DB_PRIVACY[vectorDb].description.map((desc) => (
|
||||||
|
<li className="text-white/90 text-sm">{desc}</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex w-full justify-between items-center p-6 space-x-2 border-t rounded-b border-gray-500/50">
|
||||||
|
<button
|
||||||
|
onClick={prevStep}
|
||||||
|
type="button"
|
||||||
|
className="px-4 py-2 rounded-lg text-white hover:bg-sidebar"
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => nextStep("create_workspace")}
|
||||||
|
className="border border-slate-200 px-4 py-2 rounded-lg text-slate-800 bg-slate-200 text-sm items-center flex gap-x-2 hover:text-white hover:bg-transparent focus:ring-gray-800 font-semibold shadow"
|
||||||
|
>
|
||||||
|
Continue
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memo(DataHandling);
|
|
@ -5,7 +5,7 @@ import System from "../../../../../models/system";
|
||||||
import PreLoader from "../../../../../components/Preloader";
|
import PreLoader from "../../../../../components/Preloader";
|
||||||
import LLMProviderOption from "../../../../../components/LLMSelection/LLMProviderOption";
|
import LLMProviderOption from "../../../../../components/LLMSelection/LLMProviderOption";
|
||||||
|
|
||||||
function EmbeddingSelection({ nextStep, prevStep, currentStep, goToStep }) {
|
function EmbeddingSelection({ nextStep, prevStep, currentStep }) {
|
||||||
const [embeddingChoice, setEmbeddingChoice] = useState("openai");
|
const [embeddingChoice, setEmbeddingChoice] = useState("openai");
|
||||||
const [settings, setSettings] = useState(null);
|
const [settings, setSettings] = useState(null);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
|
@ -35,7 +35,7 @@ function EmbeddingSelection({ nextStep, prevStep, currentStep, goToStep }) {
|
||||||
alert(`Failed to save LLM settings: ${error}`, "error");
|
alert(`Failed to save LLM settings: ${error}`, "error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
goToStep(2);
|
nextStep("vector_database");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ function EmbeddingSelection({ nextStep, prevStep, currentStep, goToStep }) {
|
||||||
</div>
|
</div>
|
||||||
<div className="flex w-full justify-between items-center p-6 space-x-2 border-t rounded-b border-gray-500/50">
|
<div className="flex w-full justify-between items-center p-6 space-x-2 border-t rounded-b border-gray-500/50">
|
||||||
<button
|
<button
|
||||||
onClick={() => goToStep(1)}
|
onClick={prevStep}
|
||||||
type="button"
|
type="button"
|
||||||
className="px-4 py-2 rounded-lg text-white hover:bg-sidebar"
|
className="px-4 py-2 rounded-lg text-white hover:bg-sidebar"
|
||||||
>
|
>
|
||||||
|
|
|
@ -9,7 +9,7 @@ import OpenAiOptions from "../../../../../components/LLMSelection/OpenAiOptions"
|
||||||
import AzureAiOptions from "../../../../../components/LLMSelection/AzureAiOptions";
|
import AzureAiOptions from "../../../../../components/LLMSelection/AzureAiOptions";
|
||||||
import AnthropicAiOptions from "../../../../../components/LLMSelection/AnthropicAiOptions";
|
import AnthropicAiOptions from "../../../../../components/LLMSelection/AnthropicAiOptions";
|
||||||
|
|
||||||
function LLMSelection({ nextStep, prevStep, currentStep, goToStep }) {
|
function LLMSelection({ nextStep, prevStep, currentStep }) {
|
||||||
const [llmChoice, setLLMChoice] = useState("openai");
|
const [llmChoice, setLLMChoice] = useState("openai");
|
||||||
const [settings, setSettings] = useState(null);
|
const [settings, setSettings] = useState(null);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
|
@ -26,10 +26,10 @@ function LLMSelection({ nextStep, prevStep, currentStep, goToStep }) {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentStep === 1) {
|
if (currentStep === "llm_preference") {
|
||||||
fetchKeys();
|
fetchKeys();
|
||||||
}
|
}
|
||||||
}, [currentStep]);
|
}, []);
|
||||||
|
|
||||||
const handleSubmit = async (e) => {
|
const handleSubmit = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -45,11 +45,10 @@ function LLMSelection({ nextStep, prevStep, currentStep, goToStep }) {
|
||||||
|
|
||||||
switch (data.LLMProvider) {
|
switch (data.LLMProvider) {
|
||||||
case "anthropic":
|
case "anthropic":
|
||||||
goToStep(7);
|
return nextStep("embedding_preferences");
|
||||||
default:
|
default:
|
||||||
nextStep();
|
return nextStep("vector_database");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (loading)
|
if (loading)
|
||||||
|
|
|
@ -33,7 +33,7 @@ function MultiUserSetup({ nextStep, prevStep }) {
|
||||||
window.localStorage.setItem(AUTH_TOKEN, token);
|
window.localStorage.setItem(AUTH_TOKEN, token);
|
||||||
window.localStorage.removeItem(AUTH_TIMESTAMP);
|
window.localStorage.removeItem(AUTH_TIMESTAMP);
|
||||||
|
|
||||||
nextStep();
|
nextStep("data_handling");
|
||||||
};
|
};
|
||||||
|
|
||||||
const setNewUsername = (e) => setUsername(e.target.value);
|
const setNewUsername = (e) => setUsername(e.target.value);
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
} from "../../../../../utils/constants";
|
} from "../../../../../utils/constants";
|
||||||
import debounce from "lodash.debounce";
|
import debounce from "lodash.debounce";
|
||||||
|
|
||||||
function PasswordProtection({ goToStep, prevStep }) {
|
function PasswordProtection({ nextStep, prevStep }) {
|
||||||
const [password, setPassword] = useState("");
|
const [password, setPassword] = useState("");
|
||||||
const handleSubmit = async (e) => {
|
const handleSubmit = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -32,12 +32,12 @@ function PasswordProtection({ goToStep, prevStep }) {
|
||||||
window.localStorage.removeItem(AUTH_TIMESTAMP);
|
window.localStorage.removeItem(AUTH_TIMESTAMP);
|
||||||
window.localStorage.setItem(AUTH_TOKEN, token);
|
window.localStorage.setItem(AUTH_TOKEN, token);
|
||||||
|
|
||||||
goToStep(7);
|
nextStep("data_handling");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSkip = () => {
|
const handleSkip = () => {
|
||||||
goToStep(7);
|
nextStep("data_handling");
|
||||||
};
|
};
|
||||||
|
|
||||||
const setNewPassword = (e) => setPassword(e.target.value);
|
const setNewPassword = (e) => setPassword(e.target.value);
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import React, { memo } from "react";
|
import React, { memo } from "react";
|
||||||
|
|
||||||
// How many people will be using your instance step
|
// How many people will be using your instance step
|
||||||
function UserModeSelection({ goToStep, prevStep }) {
|
function UserModeSelection({ nextStep, prevStep }) {
|
||||||
const justMeClicked = () => {
|
const justMeClicked = () => {
|
||||||
goToStep(5);
|
nextStep("password_protection");
|
||||||
};
|
};
|
||||||
|
|
||||||
const myTeamClicked = () => {
|
const myTeamClicked = () => {
|
||||||
goToStep(6);
|
nextStep("multi_user_mode");
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -21,7 +21,7 @@ function VectorDatabaseConnection({ nextStep, prevStep, currentStep }) {
|
||||||
setVectorDB(_settings?.VectorDB || "lancedb");
|
setVectorDB(_settings?.VectorDB || "lancedb");
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
if (currentStep === 2) {
|
if (currentStep === "vector_database") {
|
||||||
fetchKeys();
|
fetchKeys();
|
||||||
}
|
}
|
||||||
}, [currentStep]);
|
}, [currentStep]);
|
||||||
|
@ -41,7 +41,7 @@ function VectorDatabaseConnection({ nextStep, prevStep, currentStep }) {
|
||||||
alert(`Failed to save settings: ${error}`, "error");
|
alert(`Failed to save settings: ${error}`, "error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nextStep();
|
nextStep("appearance");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import PasswordProtection from "./Steps/PasswordProtection";
|
||||||
import MultiUserSetup from "./Steps/MultiUserSetup";
|
import MultiUserSetup from "./Steps/MultiUserSetup";
|
||||||
import CreateFirstWorkspace from "./Steps/CreateFirstWorkspace";
|
import CreateFirstWorkspace from "./Steps/CreateFirstWorkspace";
|
||||||
import EmbeddingSelection from "./Steps/EmbeddingSelection";
|
import EmbeddingSelection from "./Steps/EmbeddingSelection";
|
||||||
|
import DataHandling from "./Steps/DataHandling";
|
||||||
|
|
||||||
const DIALOG_ID = "onboarding-modal";
|
const DIALOG_ID = "onboarding-modal";
|
||||||
|
|
||||||
|
@ -16,46 +17,53 @@ function hideModal() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const STEPS = {
|
const STEPS = {
|
||||||
1: {
|
llm_preference: {
|
||||||
title: "LLM Preference",
|
title: "LLM Preference",
|
||||||
description:
|
description:
|
||||||
"These are the credentials and settings for your preferred LLM chat & embedding provider.",
|
"These are the credentials and settings for your preferred LLM chat & embedding provider.",
|
||||||
component: LLMSelection,
|
component: LLMSelection,
|
||||||
},
|
},
|
||||||
2: {
|
vector_database: {
|
||||||
title: "Vector Database",
|
title: "Vector Database",
|
||||||
description:
|
description:
|
||||||
"These are the credentials and settings for how your AnythingLLM instance will function.",
|
"These are the credentials and settings for how your AnythingLLM instance will function.",
|
||||||
component: VectorDatabaseConnection,
|
component: VectorDatabaseConnection,
|
||||||
},
|
},
|
||||||
3: {
|
appearance: {
|
||||||
title: "Appearance",
|
title: "Appearance",
|
||||||
description: "Customize the appearance of your AnythingLLM instance.",
|
description:
|
||||||
|
"Customize the appearance of your AnythingLLM instance.\nFind more customization options on the appearance settings page.",
|
||||||
component: AppearanceSetup,
|
component: AppearanceSetup,
|
||||||
},
|
},
|
||||||
4: {
|
user_mode_setup: {
|
||||||
title: "User Mode Setup",
|
title: "User Mode Setup",
|
||||||
description: "Choose how many people will be using your instance.",
|
description: "Choose how many people will be using your instance.",
|
||||||
component: UserModeSelection,
|
component: UserModeSelection,
|
||||||
},
|
},
|
||||||
5: {
|
password_protection: {
|
||||||
title: "Password Protect",
|
title: "Password Protect",
|
||||||
description:
|
description:
|
||||||
"Protect your instance with a password. It is important to save this password as it cannot be recovered.",
|
"Protect your instance with a password. It is important to save this password as it cannot be recovered.",
|
||||||
component: PasswordProtection,
|
component: PasswordProtection,
|
||||||
},
|
},
|
||||||
6: {
|
multi_user_mode: {
|
||||||
title: "Multi-User Mode",
|
title: "Multi-User Mode",
|
||||||
description:
|
description:
|
||||||
"Setup your instance to support your team by activating multi-user mode.",
|
"Setup your instance to support your team by activating multi-user mode.",
|
||||||
component: MultiUserSetup,
|
component: MultiUserSetup,
|
||||||
},
|
},
|
||||||
7: {
|
data_handling: {
|
||||||
|
title: "Data Handling",
|
||||||
|
description:
|
||||||
|
"We are committed to transparency and control when it comes to your personal data.",
|
||||||
|
component: DataHandling,
|
||||||
|
},
|
||||||
|
create_workspace: {
|
||||||
title: "Create Workspace",
|
title: "Create Workspace",
|
||||||
description: "To get started, create a new workspace.",
|
description: "To get started, create a new workspace.",
|
||||||
component: CreateFirstWorkspace,
|
component: CreateFirstWorkspace,
|
||||||
},
|
},
|
||||||
8: {
|
embedding_preferences: {
|
||||||
title: "Embedding Preference",
|
title: "Embedding Preference",
|
||||||
description:
|
description:
|
||||||
"Due to your LLM selection you need to set up a provider for embedding files and text.",
|
"Due to your LLM selection you need to set up a provider for embedding files and text.",
|
||||||
|
@ -65,19 +73,26 @@ const STEPS = {
|
||||||
|
|
||||||
export const OnboardingModalId = DIALOG_ID;
|
export const OnboardingModalId = DIALOG_ID;
|
||||||
export default function OnboardingModal() {
|
export default function OnboardingModal() {
|
||||||
const [currentStep, setCurrentStep] = useState(1);
|
const [currentStep, setCurrentStep] = useState("llm_preference");
|
||||||
|
const [history, setHistory] = useState(["llm_preference"]);
|
||||||
|
|
||||||
const nextStep = () => {
|
const nextStep = (stepKey) => {
|
||||||
setCurrentStep((prevStep) => prevStep + 1);
|
setCurrentStep(stepKey);
|
||||||
|
setHistory([...history, stepKey]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const prevStep = () => {
|
const prevStep = () => {
|
||||||
if (currentStep === 1) return hideModal();
|
const currentStepIdx = history.indexOf(currentStep);
|
||||||
setCurrentStep((prevStep) => prevStep - 1);
|
if (currentStepIdx === -1 || currentStepIdx === 0) {
|
||||||
};
|
setCurrentStep("llm_preference");
|
||||||
|
setHistory(["llm_preference"]);
|
||||||
|
return hideModal();
|
||||||
|
}
|
||||||
|
|
||||||
const goToStep = (step) => {
|
const prevStep = history[currentStepIdx - 1];
|
||||||
setCurrentStep(step);
|
const _history = [...history].slice(0, currentStepIdx);
|
||||||
|
setCurrentStep(prevStep);
|
||||||
|
setHistory(_history);
|
||||||
};
|
};
|
||||||
|
|
||||||
const { component: StepComponent, ...step } = STEPS[currentStep];
|
const { component: StepComponent, ...step } = STEPS[currentStep];
|
||||||
|
@ -88,7 +103,7 @@ export default function OnboardingModal() {
|
||||||
<div className="flex items-start justify-between p-8 border-b rounded-t border-gray-500/50">
|
<div className="flex items-start justify-between p-8 border-b rounded-t border-gray-500/50">
|
||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
<h3 className="text-xl font-semibold text-white">{step.title}</h3>
|
<h3 className="text-xl font-semibold text-white">{step.title}</h3>
|
||||||
<p className="text-sm font-base text-white text-opacity-60">
|
<p className="text-sm font-base text-white text-opacity-60 whitespace-pre">
|
||||||
{step.description || ""}
|
{step.description || ""}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -106,7 +121,6 @@ export default function OnboardingModal() {
|
||||||
currentStep={currentStep}
|
currentStep={currentStep}
|
||||||
nextStep={nextStep}
|
nextStep={nextStep}
|
||||||
prevStep={prevStep}
|
prevStep={prevStep}
|
||||||
goToStep={goToStep}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Add table
Reference in a new issue