diff --git a/frontend/lib/components/AddBrainModal/components/AddBrainSteps/AddBrainSteps.tsx b/frontend/lib/components/AddBrainModal/components/AddBrainSteps/AddBrainSteps.tsx
index 76a12a563..d184c2aac 100644
--- a/frontend/lib/components/AddBrainModal/components/AddBrainSteps/AddBrainSteps.tsx
+++ b/frontend/lib/components/AddBrainModal/components/AddBrainSteps/AddBrainSteps.tsx
@@ -5,6 +5,7 @@ import Button from "@/lib/components/ui/Button";
import { Modal } from "@/lib/components/ui/Modal";
import { cn } from "@/lib/utils";
+import { BrainParamsStep } from "./components/BrainParamsStep/BrainParamsStep";
import { BrainTypeSelectionStep } from "./components/BrainTypeSelectionStep/BrainTypeSelectionStep";
import { Stepper } from "./components/Stepper/Stepper";
import { useAddBrainConfig } from "./hooks/useAddBrainConfig";
@@ -22,37 +23,38 @@ export const AddBrainSteps = ({
useAddBrainConfig();
return (
- <>
- void 0}
- variant={"tertiary"}
- className={cn("border-0", triggerClassName)}
- data-testid="add-brain-button"
- >
- {t("newBrain", { ns: "brain" })}
-
-
- }
- title={t("newBrainTitle", { ns: "brain" })}
- desc={t("newBrainSubtitle", { ns: "brain" })}
- isOpen={isBrainCreationModalOpened}
- setOpen={setIsBrainCreationModalOpened}
- CloseTrigger={}
- >
-
-
- >
+ {t("newBrain", { ns: "brain" })}
+
+
+ }
+ title={t("newBrainTitle", { ns: "brain" })}
+ desc={t("newBrainSubtitle", { ns: "brain" })}
+ isOpen={isBrainCreationModalOpened}
+ setOpen={setIsBrainCreationModalOpened}
+ CloseTrigger={
}
+ >
+
+
);
};
diff --git a/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/BrainParamsStep/BrainParamsStep.tsx b/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/BrainParamsStep/BrainParamsStep.tsx
new file mode 100644
index 000000000..582167443
--- /dev/null
+++ b/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/BrainParamsStep/BrainParamsStep.tsx
@@ -0,0 +1,105 @@
+import { Fragment } from "react";
+import { useTranslation } from "react-i18next";
+import { FaArrowLeft, FaArrowRight } from "react-icons/fa";
+
+import { PublicAccessConfirmationModal } from "@/lib/components/AddBrainModalOld/components/AddBrainConfig/components/PublicAccessConfirmationModal";
+import Button from "@/lib/components/ui/Button";
+import Field from "@/lib/components/ui/Field";
+import { Radio } from "@/lib/components/ui/Radio";
+import { TextArea } from "@/lib/components/ui/TextArea";
+
+import { useBrainParamsStep } from "./hooks/useBrainParamsStep";
+import { useBrainStatusOptions } from "./hooks/useBrainStatusOptions";
+import { usePublicAccessConfirmationModal } from "./hooks/usePublicAccessConfirmationModal";
+import { useBrainCreationSteps } from "../../hooks/useBrainCreationSteps";
+import { useBrainTypeSelectionStep } from "../BrainTypeSelectionStep/hooks/useBrainTypeSelectionStep";
+
+type BrainParamsStepProps = {
+ onCancelBrainCreation: () => void;
+};
+
+export const BrainParamsStep = ({
+ onCancelBrainCreation,
+}: BrainParamsStepProps): JSX.Element => {
+ const { goToNextStep, goToPreviousStep, currentStep } =
+ useBrainCreationSteps();
+ const { register } = useBrainTypeSelectionStep();
+ const { t } = useTranslation(["translation", "brain", "config"]);
+ const { brainStatusOptions } = useBrainStatusOptions();
+ const { isNextButtonDisabled } = useBrainParamsStep();
+ const {
+ isPublicAccessConfirmationModalOpened,
+ onCancelPublicAccess,
+ onConfirmPublicAccess,
+ } = usePublicAccessConfirmationModal();
+
+ if (currentStep !== "BRAIN_PARAMS") {
+ return ;
+ }
+
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+};
diff --git a/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/BrainParamsStep/hooks/useBrainParamsStep.ts b/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/BrainParamsStep/hooks/useBrainParamsStep.ts
new file mode 100644
index 000000000..b5de53a34
--- /dev/null
+++ b/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/BrainParamsStep/hooks/useBrainParamsStep.ts
@@ -0,0 +1,16 @@
+import { useFormContext } from "react-hook-form";
+
+import { CreateBrainProps } from "@/lib/components/AddBrainModal/types";
+
+// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+export const useBrainParamsStep = () => {
+ const { watch } = useFormContext();
+ const brainName = watch("name");
+ const description = watch("description");
+
+ const isNextButtonDisabled = brainName === "" || description === "";
+
+ return {
+ isNextButtonDisabled,
+ };
+};
diff --git a/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/BrainParamsStep/hooks/useBrainStatusOptions.ts b/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/BrainParamsStep/hooks/useBrainStatusOptions.ts
new file mode 100644
index 000000000..039340f3f
--- /dev/null
+++ b/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/BrainParamsStep/hooks/useBrainStatusOptions.ts
@@ -0,0 +1,25 @@
+import { useTranslation } from "react-i18next";
+
+import { BrainStatus } from "@/lib/types/brainConfig";
+// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+export const useBrainStatusOptions = () => {
+ const { t } = useTranslation(["translation", "brain", "config"]);
+
+ const brainStatusOptions: {
+ label: string;
+ value: BrainStatus;
+ }[] = [
+ {
+ label: t("private_brain_label", { ns: "brain" }),
+ value: "private",
+ },
+ {
+ label: t("public_brain_label", { ns: "brain" }),
+ value: "public",
+ },
+ ];
+
+ return {
+ brainStatusOptions,
+ };
+};
diff --git a/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/BrainParamsStep/hooks/usePublicAccessConfirmationModal.ts b/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/BrainParamsStep/hooks/usePublicAccessConfirmationModal.ts
new file mode 100644
index 000000000..d3ce93f17
--- /dev/null
+++ b/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/BrainParamsStep/hooks/usePublicAccessConfirmationModal.ts
@@ -0,0 +1,43 @@
+import { useEffect, useState } from "react";
+import { useFormContext } from "react-hook-form";
+
+import { CreateBrainProps } from "@/lib/components/AddBrainModal/types";
+
+// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+export const usePublicAccessConfirmationModal = () => {
+ const {
+ watch,
+ setValue,
+ formState: { dirtyFields },
+ } = useFormContext();
+
+ const [
+ isPublicAccessConfirmationModalOpened,
+ setIsPublicAccessConfirmationModalOpened,
+ ] = useState(false);
+
+ const status = watch("status");
+
+ useEffect(() => {
+ if (status === "public" && dirtyFields.status === true) {
+ setIsPublicAccessConfirmationModalOpened(true);
+ }
+ }, [dirtyFields.status, status]);
+
+ const onConfirmPublicAccess = () => {
+ setIsPublicAccessConfirmationModalOpened(false);
+ };
+
+ const onCancelPublicAccess = () => {
+ setValue("status", "private", {
+ shouldDirty: true,
+ });
+ setIsPublicAccessConfirmationModalOpened(false);
+ };
+
+ return {
+ isPublicAccessConfirmationModalOpened,
+ onConfirmPublicAccess,
+ onCancelPublicAccess,
+ };
+};
diff --git a/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/BrainTypeSelectionStep/BrainTypeSelectionStep.tsx b/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/BrainTypeSelectionStep/BrainTypeSelectionStep.tsx
index c794fa9bc..9f02f5eb5 100644
--- a/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/BrainTypeSelectionStep/BrainTypeSelectionStep.tsx
+++ b/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/BrainTypeSelectionStep/BrainTypeSelectionStep.tsx
@@ -1,4 +1,5 @@
import { Fragment } from "react";
+import { useTranslation } from "react-i18next";
import { FaArrowRight } from "react-icons/fa";
import Button from "@/lib/components/ui/Button";
@@ -18,7 +19,7 @@ export const BrainTypeSelectionStep = ({
const { knowledgeSourceOptions } = useKnowledgeSourceLabel();
const { register } = useBrainTypeSelectionStep();
const { goToNextStep, currentStep } = useBrainCreationSteps();
-
+ const { t } = useTranslation(["translation"]);
if (currentStep !== "BRAIN_TYPE") {
return ;
}
@@ -36,7 +37,7 @@ export const BrainTypeSelectionStep = ({
variant="tertiary"
onClick={onCancelBrainCreation}
>
- Annuler
+ {t("cancel")}
diff --git a/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/BrainTypeSelectionStep/hooks/useBrainTypeSelectionStep.ts b/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/BrainTypeSelectionStep/hooks/useBrainTypeSelectionStep.ts
index b03e6d9a0..ef31ea772 100644
--- a/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/BrainTypeSelectionStep/hooks/useBrainTypeSelectionStep.ts
+++ b/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/BrainTypeSelectionStep/hooks/useBrainTypeSelectionStep.ts
@@ -1,10 +1,19 @@
+import { useEffect } from "react";
import { useFormContext } from "react-hook-form";
import { CreateBrainProps } from "@/lib/components/AddBrainModal/types";
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export const useBrainTypeSelectionStep = () => {
- const { register } = useFormContext();
+ const { register, watch, reset, setValue } =
+ useFormContext();
+ const brainType = watch("brain_type");
+
+ useEffect(() => {
+ const currentBrainType = brainType;
+ reset();
+ setValue("brain_type", currentBrainType);
+ }, [brainType, reset, setValue]);
return {
register,
diff --git a/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/Stepper/Stepper.tsx b/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/Stepper/Stepper.tsx
index 18946857c..2d54aede8 100644
--- a/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/Stepper/Stepper.tsx
+++ b/frontend/lib/components/AddBrainModal/components/AddBrainSteps/components/Stepper/Stepper.tsx
@@ -2,6 +2,7 @@ import { Fragment } from "react";
import { cn } from "@/lib/utils";
+import { Step } from "./components/Step";
import { useBrainCreationSteps } from "../../hooks/useBrainCreationSteps";
export const Stepper = (): JSX.Element => {
@@ -11,24 +12,7 @@ export const Stepper = (): JSX.Element => {
{steps.map((step, index) => (
-
-
-
- {index + 1}
-
-
- {step.label}
-
-
-
+
{index < steps.length - 1 && ( // Add horizontal line for all but the last step
{
+ const { currentStep, currentStepIndex } = useBrainCreationSteps();
+ const isStepDone = index < currentStepIndex;
+ const stepContent = isStepDone ? : index + 1;
+
+ return (
+
+
+
+ {stepContent}
+
+
+ {step.label}
+
+
+
+ );
+};
diff --git a/frontend/lib/components/AddBrainModal/components/AddBrainSteps/hooks/useBrainCreationSteps.ts b/frontend/lib/components/AddBrainModal/components/AddBrainSteps/hooks/useBrainCreationSteps.ts
index 601e41f99..b0b962683 100644
--- a/frontend/lib/components/AddBrainModal/components/AddBrainSteps/hooks/useBrainCreationSteps.ts
+++ b/frontend/lib/components/AddBrainModal/components/AddBrainSteps/hooks/useBrainCreationSteps.ts
@@ -3,13 +3,13 @@ import { useTranslation } from "react-i18next";
import { CreateBrainProps } from "@/lib/components/AddBrainModal/types";
-import { StepperStep } from "../types";
+import { Step } from "../types";
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export const useBrainCreationSteps = () => {
const { t } = useTranslation("brain");
- const steps: StepperStep[] = [
+ const steps: Step[] = [
{
label: t("brain_type"),
value: "BRAIN_TYPE",
@@ -25,11 +25,11 @@ export const useBrainCreationSteps = () => {
];
const { watch, setValue } = useFormContext();
const currentStep = watch("brainCreationStep");
+ const currentStepIndex = steps.findIndex(
+ (step) => step.value === currentStep
+ );
const goToNextStep = () => {
- const currentStepIndex = steps.findIndex(
- (step) => step.value === currentStep
- );
if (currentStepIndex === -1 || currentStepIndex === steps.length - 1) {
return;
}
@@ -39,9 +39,6 @@ export const useBrainCreationSteps = () => {
};
const goToPreviousStep = () => {
- const currentStepIndex = steps.findIndex(
- (step) => step.value === currentStep
- );
if (currentStepIndex === -1 || currentStepIndex === 0) {
return;
}
@@ -55,5 +52,6 @@ export const useBrainCreationSteps = () => {
steps,
goToNextStep,
goToPreviousStep,
+ currentStepIndex,
};
};
diff --git a/frontend/lib/components/AddBrainModal/components/AddBrainSteps/types.ts b/frontend/lib/components/AddBrainModal/components/AddBrainSteps/types.ts
index 9e72cc694..90b5d2992 100644
--- a/frontend/lib/components/AddBrainModal/components/AddBrainSteps/types.ts
+++ b/frontend/lib/components/AddBrainModal/components/AddBrainSteps/types.ts
@@ -1,6 +1,6 @@
import { BrainCreationStep } from "../../types";
-export type StepperStep = {
+export type Step = {
label: string;
value: BrainCreationStep;
};
diff --git a/frontend/public/locales/en/translation.json b/frontend/public/locales/en/translation.json
index 5f55add62..7cc73897c 100644
--- a/frontend/public/locales/en/translation.json
+++ b/frontend/public/locales/en/translation.json
@@ -30,5 +30,8 @@
"invalidUrl": "Invalid URL",
"crawlButton": "Crawl",
"themeSelect": "Interface theme",
- "languageSelect": "Preferred language"
+ "languageSelect": "Preferred language",
+ "cancel": "Cancel",
+ "next": "Next",
+ "previous": "Previous"
}
diff --git a/frontend/public/locales/es/translation.json b/frontend/public/locales/es/translation.json
index 1458b5bf5..217985882 100644
--- a/frontend/public/locales/es/translation.json
+++ b/frontend/public/locales/es/translation.json
@@ -30,5 +30,8 @@
"invalidUrl": "URL inválida",
"crawlButton": "Rastrear",
"themeSelect": "Tema de interfaz",
- "languageSelect": "Idioma preferido"
+ "languageSelect": "Idioma preferido",
+ "cancel": "Cancelar",
+ "next": "Siguiente",
+ "previous": "Anterior"
}
diff --git a/frontend/public/locales/fr/translation.json b/frontend/public/locales/fr/translation.json
index 400b52f4f..7185a88d8 100644
--- a/frontend/public/locales/fr/translation.json
+++ b/frontend/public/locales/fr/translation.json
@@ -6,7 +6,6 @@
"email": "Email",
"or": "ou",
"and": "et",
-
"logoutButton": "Déconnexion",
"updateButton": "Mettre à jour",
"uploadButton": "Télécharger",
@@ -31,5 +30,8 @@
"invalidUrl": "URL invalide",
"crawlButton": "Crawler",
"themeSelect": "Thème de l'interface",
- "languageSelect": "Langue préférée"
+ "languageSelect": "Langue préférée",
+ "cancel": "Annuler",
+ "next": "Suivant",
+ "previous": "Précédent"
}
diff --git a/frontend/public/locales/pt-br/translation.json b/frontend/public/locales/pt-br/translation.json
index 0c070991b..2222bcab2 100644
--- a/frontend/public/locales/pt-br/translation.json
+++ b/frontend/public/locales/pt-br/translation.json
@@ -30,5 +30,8 @@
"invalidUrl": "URL inválida",
"crawlButton": "Rastrear",
"themeSelect": "Tema de interface",
- "languageSelect": "Língua preferida"
+ "languageSelect": "Língua preferida",
+ "cancel": "Cancelar",
+ "next": "Próximo",
+ "previous": "Anterior"
}
diff --git a/frontend/public/locales/ru/translation.json b/frontend/public/locales/ru/translation.json
index 93aecfaf4..38ce3129c 100644
--- a/frontend/public/locales/ru/translation.json
+++ b/frontend/public/locales/ru/translation.json
@@ -30,5 +30,8 @@
"invalidUrl": "Неверный URL",
"crawlButton": "Поиск",
"themeSelect": "Тема интерфейса",
- "languageSelect": "предпочтительный язык"
+ "languageSelect": "предпочтительный язык",
+ "cancel": "Отмена",
+ "next": "Далее",
+ "previous": "Назад"
}
diff --git a/frontend/public/locales/zh-cn/translation.json b/frontend/public/locales/zh-cn/translation.json
index 045cc81c3..f13807fb8 100644
--- a/frontend/public/locales/zh-cn/translation.json
+++ b/frontend/public/locales/zh-cn/translation.json
@@ -30,5 +30,8 @@
"invalidUrl": "无效的 URL",
"crawlButton": "爬取",
"themeSelect": "主题",
- "languageSelect": "首选语言"
+ "languageSelect": "首选语言",
+ "cancel": "取消",
+ "next": "下一个",
+ "previous": "上一个"
}
\ No newline at end of file