diff --git a/client/src/features/admin/AddSessionEnvironmentButton.tsx b/client/src/features/admin/AddSessionEnvironmentButton.tsx index 0ebc9c11e..237fd87fa 100644 --- a/client/src/features/admin/AddSessionEnvironmentButton.tsx +++ b/client/src/features/admin/AddSessionEnvironmentButton.tsx @@ -35,6 +35,7 @@ import SessionEnvironmentFormContent, { SessionEnvironmentForm, } from "./SessionEnvironmentFormContent"; import { useAddSessionEnvironmentMutation } from "./adminSessions.api"; +import { safeParse } from "../sessionsV2/session.utils"; export default function AddSessionEnvironmentButton() { const [isOpen, setIsOpen] = useState(false); @@ -84,6 +85,17 @@ function AddSessionEnvironmentModal({ name: data.name, default_url: data.default_url.trim() ? data.default_url : undefined, description: data.description.trim() ? data.description : undefined, + port: data.port ?? undefined, + working_directory: data.working_directory.trim() + ? data.working_directory + : undefined, + mount_directory: data.mount_directory.trim() + ? data.working_directory + : undefined, + uid: data.uid ?? undefined, + gid: data.gid ?? undefined, + command: safeParse(data.command), + args: safeParse(data.args), }); }, [addSessionEnvironment] diff --git a/client/src/features/admin/SessionEnvironmentAdvanceFields.tsx b/client/src/features/admin/SessionEnvironmentAdvanceFields.tsx new file mode 100644 index 000000000..eba3e1a77 --- /dev/null +++ b/client/src/features/admin/SessionEnvironmentAdvanceFields.tsx @@ -0,0 +1,62 @@ +/*! + * Copyright 2024 - Swiss Data Science Center (SDSC) + * A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and + * Eidgenössische Technische Hochschule Zürich (ETHZ). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import cx from "classnames"; +import { useCallback, useState } from "react"; +import { Control, FieldErrors } from "react-hook-form"; +import { Collapse } from "reactstrap"; +import ChevronFlippedIcon from "../../components/icons/ChevronFlippedIcon"; +import { AdvanceSettingsFields } from "../sessionsV2/components/SessionForm/AdvanceSettingsFields"; +import { SessionEnvironmentForm } from "./SessionEnvironmentFormContent"; + +interface SessionEnvironmentAdvanceFieldsProps { + control: Control; + errors: FieldErrors; +} + +export default function SessionEnvironmentAdvanceFields({ + control, + errors, +}: SessionEnvironmentAdvanceFieldsProps) { + const [isAdvanceSettingOpen, setIsAdvanceSettingsOpen] = useState(false); + const toggleIsOpen = useCallback( + () => + setIsAdvanceSettingsOpen((isAdvanceSettingOpen) => !isAdvanceSettingOpen), + [] + ); + return ( + <> +
+ + Advance settings + +
+ +
+ + control={control} + errors={errors} + /> +
+
+ + ); +} diff --git a/client/src/features/admin/SessionEnvironmentFormContent.tsx b/client/src/features/admin/SessionEnvironmentFormContent.tsx index 807cfe985..1cffdb209 100644 --- a/client/src/features/admin/SessionEnvironmentFormContent.tsx +++ b/client/src/features/admin/SessionEnvironmentFormContent.tsx @@ -19,12 +19,20 @@ import cx from "classnames"; import { Control, Controller, FieldErrors } from "react-hook-form"; import { Input, Label } from "reactstrap"; +import SessionEnvironmentAdvanceFields from "./SessionEnvironmentAdvanceFields"; export interface SessionEnvironmentForm { container_image: string; default_url: string; description: string; name: string; + port: number; + working_directory: string; + uid: number; + gid: number; + mount_directory: string; + command: string; + args: string; } interface SessionEnvironmentFormContentProps { @@ -101,25 +109,7 @@ export default function SessionEnvironmentFormContent({ />
Please provide a container image
- -
- - ( - - )} - /> -
+ ); } diff --git a/client/src/features/admin/SessionEnvironmentsSection.tsx b/client/src/features/admin/SessionEnvironmentsSection.tsx index 92ff6fc2a..23734cd98 100644 --- a/client/src/features/admin/SessionEnvironmentsSection.tsx +++ b/client/src/features/admin/SessionEnvironmentsSection.tsx @@ -39,11 +39,12 @@ import AddSessionEnvironmentButton from "./AddSessionEnvironmentButton"; import DeleteSessionEnvironmentButton from "./DeleteSessionEnvironmentButton"; import UpdateSessionEnvironmentButton from "./UpdateSessionEnvironmentButton"; import { useGetSessionEnvironmentsQuery } from "./adminSessions.api"; +import { safeStringify } from "../sessionsV2/session.utils"; export default function SessionEnvironmentsSection() { return (
-

Session Environments - Renku 1.0

+

Session Environments - Renku 2.0

); @@ -107,8 +108,20 @@ interface SessionEnvironmentDisplayProps { function SessionEnvironmentDisplay({ environment, }: SessionEnvironmentDisplayProps) { - const { container_image, creation_date, name, default_url, description } = - environment; + const { + container_image, + creation_date, + name, + default_url, + description, + port, + gid, + uid, + working_directory, + mount_directory, + command, + args, + } = environment; return ( @@ -135,6 +148,27 @@ function SessionEnvironmentDisplay({ )} + + Mount directory: {mount_directory} + + + Work directory: {working_directory} + + + Port: {port} + + + GID: {gid} + + + UID: {uid} + + + Command: {command ? safeStringify(command) : "-"} + + + Args: {args ? safeStringify(args) : "-"} + Update session environment {result.error && } - diff --git a/client/src/features/admin/adminSessions.types.ts b/client/src/features/admin/adminSessions.types.ts index ea6cdb3bd..8f7235525 100644 --- a/client/src/features/admin/adminSessions.types.ts +++ b/client/src/features/admin/adminSessions.types.ts @@ -21,6 +21,13 @@ export interface AddSessionEnvironmentParams { name: string; default_url?: string; description?: string; + uid?: number; + gid?: number; + working_directory?: string; + mount_directory?: string; + port?: number; + command?: string[]; + args?: string[]; } export interface UpdateSessionEnvironmentParams { @@ -29,6 +36,13 @@ export interface UpdateSessionEnvironmentParams { default_url?: string; description?: string; name?: string; + uid?: number; + gid?: number; + working_directory?: string; + mount_directory?: string; + port?: number; + command?: string[]; + args?: string[]; } export interface DeleteSessionEnvironmentParams { diff --git a/client/src/features/sessionsV2/components/SessionForm/AdvanceSettingsFields.tsx b/client/src/features/sessionsV2/components/SessionForm/AdvanceSettingsFields.tsx index de15ec6bb..e5798e15b 100644 --- a/client/src/features/sessionsV2/components/SessionForm/AdvanceSettingsFields.tsx +++ b/client/src/features/sessionsV2/components/SessionForm/AdvanceSettingsFields.tsx @@ -21,25 +21,22 @@ import { Control, Controller, FieldErrors, + FieldValues, + Path, RegisterOptions, } from "react-hook-form"; import { FormText, Input, Label } from "reactstrap"; import { InputType } from "reactstrap/types/lib/Input"; import { MoreInfo } from "../../../../components/MoreInfo"; -import { DEFAULT_URL, getFormCustomValuesDesc } from "../../session.utils"; +import { + DEFAULT_URL, + getFormCustomValuesDesc, + isValidJSONArrayString, +} from "../../session.utils"; import { SessionLauncherForm } from "../../sessionsV2.types"; +import { SessionEnvironmentForm } from "../../../admin/SessionEnvironmentFormContent"; -type SessionLauncherFieldNames = - | "container_image" - | "description" - | "default_url" - | "port" - | "working_directory" - | "uid" - | "gid" - | "mount_directory"; - -function FormField({ +function FormField({ control, name, label, @@ -49,15 +46,15 @@ function FormField({ type = "text", rules, }: { - control: Control; - name: SessionLauncherFieldNames; + control: Control; + name: Path; label: string; placeholder?: string; - errors?: FieldErrors; + errors?: FieldErrors; info: string; type: InputType; rules?: Omit< - RegisterOptions, + RegisterOptions>, "valueAsNumber" | "valueAsDate" | "setValueAs" | "disabled" >; }) { @@ -90,21 +87,23 @@ function FormField({ ); } -function JsonField({ +interface JsonFieldProps { + control: Control; + name: Path; + label: string; + info: string; + errors?: FieldErrors; + helpText: string; +} + +function JsonField({ control, name, label, info, errors, helpText, -}: { - control: Control; - name: "args" | "command"; - label: string; - info: string; - errors?: FieldErrors; - helpText: string; -}) { +}: JsonFieldProps) { return ( <>