From f3c1390550093e0d0e403910d6c8bd23d599ed35 Mon Sep 17 00:00:00 2001
From: Flora Thiebaut
Date: Fri, 17 Jan 2025 15:37:37 +0100
Subject: [PATCH] wip: add builder type for session launchers
---
.../SessionForm/EditLauncherFormContent.tsx | 2 +-
.../SessionForm/EnvironmentField.tsx | 2 +-
.../SessionForm/EnvironmentKindField.tsx | 2 +-
.../SessionLauncherBreadcrumbNavbar.tsx | 14 +--
.../SessionModals/NewSessionLauncherModal.tsx | 89 ++++++++++---------
.../features/sessionsV2/sessionsV2.types.ts | 2 +-
6 files changed, 56 insertions(+), 55 deletions(-)
diff --git a/client/src/features/sessionsV2/components/SessionForm/EditLauncherFormContent.tsx b/client/src/features/sessionsV2/components/SessionForm/EditLauncherFormContent.tsx
index e7a1529689..d37607295c 100644
--- a/client/src/features/sessionsV2/components/SessionForm/EditLauncherFormContent.tsx
+++ b/client/src/features/sessionsV2/components/SessionForm/EditLauncherFormContent.tsx
@@ -36,7 +36,7 @@ import { prioritizeSelectedEnvironment } from "../../session.utils";
import { useGetSessionEnvironmentsQuery } from "../../sessionsV2.api";
import { SessionLauncherForm } from "../../sessionsV2.types";
import { AdvancedSettingsFields } from "./AdvancedSettingsFields";
-import { EnvironmentKindField } from "./EnvironmentKindField";
+import EnvironmentKindField from "./EnvironmentKindField";
import { SessionEnvironmentItem } from "./SessionEnvironmentItem";
interface SessionLauncherFormContentProps {
diff --git a/client/src/features/sessionsV2/components/SessionForm/EnvironmentField.tsx b/client/src/features/sessionsV2/components/SessionForm/EnvironmentField.tsx
index 47818dc51f..51cc77c549 100644
--- a/client/src/features/sessionsV2/components/SessionForm/EnvironmentField.tsx
+++ b/client/src/features/sessionsV2/components/SessionForm/EnvironmentField.tsx
@@ -25,7 +25,7 @@ import {
} from "react-hook-form";
import { SessionLauncherForm } from "../../sessionsV2.types";
import { CustomEnvironmentFields } from "./CustomEnvironmentFields";
-import { EnvironmentKindField } from "./EnvironmentKindField";
+import EnvironmentKindField from "./EnvironmentKindField";
import { GlobalEnvironmentFields } from "./GlobalEnvironmentFields";
export interface EnvironmentFieldsProps {
diff --git a/client/src/features/sessionsV2/components/SessionForm/EnvironmentKindField.tsx b/client/src/features/sessionsV2/components/SessionForm/EnvironmentKindField.tsx
index baca7c9a32..5846b5c27b 100644
--- a/client/src/features/sessionsV2/components/SessionForm/EnvironmentKindField.tsx
+++ b/client/src/features/sessionsV2/components/SessionForm/EnvironmentKindField.tsx
@@ -24,7 +24,7 @@ interface EnvironmentKindField {
control: Control;
setValue: UseFormSetValue;
}
-export function EnvironmentKindField({
+export default function EnvironmentKindField({
control,
setValue,
}: EnvironmentKindField) {
diff --git a/client/src/features/sessionsV2/components/SessionForm/SessionLauncherBreadcrumbNavbar.tsx b/client/src/features/sessionsV2/components/SessionForm/SessionLauncherBreadcrumbNavbar.tsx
index c52e176331..c809ba2521 100644
--- a/client/src/features/sessionsV2/components/SessionForm/SessionLauncherBreadcrumbNavbar.tsx
+++ b/client/src/features/sessionsV2/components/SessionForm/SessionLauncherBreadcrumbNavbar.tsx
@@ -18,13 +18,13 @@
import cx from "classnames";
import { Breadcrumb, BreadcrumbItem, Button } from "reactstrap";
-export enum LauncherType {
+export enum LauncherStep {
Environment = "environment",
LauncherDetails = "launcherDetails",
}
interface SessionLauncherBreadcrumbNavbarProps {
- setStep: (newState: LauncherType) => void;
- step: LauncherType;
+ setStep: (newState: LauncherStep) => void;
+ step: LauncherStep;
readyToGoNext: boolean;
}
export const SessionLauncherBreadcrumbNavbar = ({
@@ -32,7 +32,7 @@ export const SessionLauncherBreadcrumbNavbar = ({
step,
readyToGoNext,
}: SessionLauncherBreadcrumbNavbarProps) => {
- const handleStepChange = (newStep: LauncherType) => {
+ const handleStepChange = (newStep: LauncherStep) => {
if (newStep === "launcherDetails" && !readyToGoNext) return;
setStep(newStep);
};
@@ -40,12 +40,12 @@ export const SessionLauncherBreadcrumbNavbar = ({
const breadcrumbItems = [
{
label: "1. Define Environment",
- stepKey: "environment",
+ stepKey: LauncherStep.Environment,
isActive: step === "environment",
},
{
label: "2. Define Launcher Details",
- stepKey: "launcherDetails",
+ stepKey: LauncherStep.LauncherDetails,
isActive: step === "launcherDetails",
disabled: !readyToGoNext,
},
@@ -61,7 +61,7 @@ export const SessionLauncherBreadcrumbNavbar = ({
isActive && ["text-decoration-none", "fw-bold"]
)}
color="link"
- onClick={() => handleStepChange(stepKey as LauncherType)}
+ onClick={() => handleStepChange(stepKey)}
disabled={disabled}
>
{label}
diff --git a/client/src/features/sessionsV2/components/SessionModals/NewSessionLauncherModal.tsx b/client/src/features/sessionsV2/components/SessionModals/NewSessionLauncherModal.tsx
index 27a49f4bd3..a1e9ede770 100644
--- a/client/src/features/sessionsV2/components/SessionModals/NewSessionLauncherModal.tsx
+++ b/client/src/features/sessionsV2/components/SessionModals/NewSessionLauncherModal.tsx
@@ -20,19 +20,14 @@ import { skipToken } from "@reduxjs/toolkit/query";
import cx from "classnames";
import { useCallback, useEffect, useMemo, useState } from "react";
import { ArrowRight, CheckLg, XLg } from "react-bootstrap-icons";
-import { useForm } from "react-hook-form";
+import { FormProvider, useForm } from "react-hook-form";
import { useParams } from "react-router-dom-v5-compat";
-import {
- Button,
- Form,
- Modal,
- ModalBody,
- ModalFooter,
- ModalHeader,
-} from "reactstrap";
+import { Button, Form, ModalBody, ModalFooter, ModalHeader } from "reactstrap";
+
import { SuccessAlert } from "../../../../components/Alert";
import { RtkErrorAlert } from "../../../../components/errors/RtkErrorAlert";
import { Loader } from "../../../../components/Loader";
+import ScrollableModal from "../../../../components/modal/ScrollableModal";
import { useGetNamespacesByNamespaceProjectsAndSlugQuery } from "../../../projectsV2/api/projectV2.enhanced-api";
import { DEFAULT_PORT, DEFAULT_URL } from "../../session.constants";
import { getFormattedEnvironmentValues } from "../../session.utils";
@@ -44,7 +39,7 @@ import { SessionLauncherForm } from "../../sessionsV2.types";
import { EnvironmentFields } from "../SessionForm/EnvironmentField";
import { LauncherDetailsFields } from "../SessionForm/LauncherDetailsFields";
import {
- LauncherType,
+ LauncherStep,
SessionLauncherBreadcrumbNavbar,
} from "../SessionForm/SessionLauncherBreadcrumbNavbar";
@@ -57,7 +52,7 @@ export default function NewSessionLauncherModal({
isOpen,
toggle,
}: NewSessionLauncherModalProps) {
- const [step, setStep] = useState(LauncherType.Environment);
+ const [step, setStep] = useState(LauncherStep.Environment);
const { namespace, slug } = useParams<{ namespace: string; slug: string }>();
const { data: environments } = useGetSessionEnvironmentsQuery();
const [addSessionLauncher, result] = useAddSessionLauncherMutation();
@@ -66,15 +61,7 @@ export default function NewSessionLauncherModal({
);
const projectId = project?.id;
- const {
- control,
- formState: { errors, isDirty, touchedFields, isValid },
- handleSubmit,
- reset,
- setValue,
- watch,
- trigger,
- } = useForm({
+ const useFormResult = useForm({
defaultValues: {
name: "",
environment_kind: "GLOBAL",
@@ -84,6 +71,15 @@ export default function NewSessionLauncherModal({
port: DEFAULT_PORT,
},
});
+ const {
+ control,
+ formState: { errors, isDirty, touchedFields, isValid },
+ handleSubmit,
+ reset,
+ setValue,
+ watch,
+ trigger,
+ } = useFormResult;
const watchEnvironmentId = watch("environment_id");
const watchEnvironmentCustomImage = watch("container_image");
@@ -101,11 +97,11 @@ export default function NewSessionLauncherModal({
trigger(["environment_id", "container_image", "command", "args"]);
if (isDirty && isEnvironmentDefined && isValid)
- setStep(LauncherType.LauncherDetails);
+ setStep(LauncherStep.LauncherDetails);
}, [isDirty, setStep, trigger, isEnvironmentDefined, isValid]);
const onCancel = useCallback(() => {
- setStep(LauncherType.Environment);
+ setStep(LauncherStep.Environment);
reset();
toggle();
}, [reset, toggle, setStep]);
@@ -155,24 +151,26 @@ export default function NewSessionLauncherModal({
useEffect(() => {
if (!isOpen) {
- setStep(LauncherType.Environment);
+ setStep(LauncherStep.Environment);
reset();
result.reset();
}
}, [isOpen, reset, result, setStep]);
return (
-
Add session launcher
-
+
{result.isSuccess ? (
) : (
@@ -185,21 +183,23 @@ export default function NewSessionLauncherModal({
>
)}
-
+
+
+
)}
@@ -209,7 +209,7 @@ export default function NewSessionLauncherModal({
)}
@@ -228,7 +228,8 @@ export default function NewSessionLauncherModal({
onClick={onNext}
type="submit"
>
- Next
+ Next
+
)}
{!result.isSuccess && step === "launcherDetails" && (
@@ -248,7 +249,7 @@ export default function NewSessionLauncherModal({
)}
-
+
);
}
diff --git a/client/src/features/sessionsV2/sessionsV2.types.ts b/client/src/features/sessionsV2/sessionsV2.types.ts
index d111671ae0..7186c6646a 100644
--- a/client/src/features/sessionsV2/sessionsV2.types.ts
+++ b/client/src/features/sessionsV2/sessionsV2.types.ts
@@ -49,7 +49,7 @@ export type SessionLauncher = {
environment: SessionLauncherEnvironment;
};
-export type EnvironmentKind = "GLOBAL" | "CUSTOM";
+export type EnvironmentKind = "GLOBAL" | "CUSTOM" | "BUILDER";
export type SessionLauncherEnvironment = {
id?: string;