From a933edc2fa80e85f561ce8bce1b601988c1c1409 Mon Sep 17 00:00:00 2001 From: Yael Date: Mon, 16 Dec 2024 18:54:43 +0200 Subject: [PATCH 1/2] feat(ws): Add Connect column to workspace table and popup with workspace endpoints Signed-off-by: Yael --- .../pages/Workspaces/WorkspaceEndpoints.tsx | 62 +++++++++++++++++++ .../src/app/pages/Workspaces/Workspaces.tsx | 20 ++++++ workspaces/frontend/src/shared/types.ts | 4 ++ 3 files changed, 86 insertions(+) create mode 100644 workspaces/frontend/src/app/pages/Workspaces/WorkspaceEndpoints.tsx diff --git a/workspaces/frontend/src/app/pages/Workspaces/WorkspaceEndpoints.tsx b/workspaces/frontend/src/app/pages/Workspaces/WorkspaceEndpoints.tsx new file mode 100644 index 00000000..dcc69c0c --- /dev/null +++ b/workspaces/frontend/src/app/pages/Workspaces/WorkspaceEndpoints.tsx @@ -0,0 +1,62 @@ +import React from "react"; +import { + Dropdown, + DropdownItem, + DropdownList, + MenuToggle, + MenuToggleElement, +} from "@patternfly/react-core"; +import { Workspace, WorkspaceState } from "~/shared/types"; + +type EndpointsDropdownProps = { + workspace: Workspace; +}; + +export const EndpointsDropdown: React.FunctionComponent = ({workspace}) => { + const [isOpen, setIsOpen] = React.useState(false); + + const onToggleClick = () => { + setIsOpen(!isOpen); + }; + + const onSelect = ( + _event: React.MouseEvent | undefined, + value: string | number | undefined) => { + setIsOpen(false); + if (typeof value === 'string'){ + openEndpoint(value); + } + }; + + const openEndpoint = (port: string) => { + window.open(`workspace/${workspace.namespace}/${workspace.name}/${port}`, '_blank'); + }; + + return ( + setIsOpen(isOpen)} + toggle={(toggleRef: React.Ref) => ( + Connect + + )} + ouiaId="BasicDropdown" + shouldFocusToggleOnSelect + > + + {workspace.podTemplate.endpoints.map((endpoint) => ( + + {endpoint.displayName} + + ))} + + + ); +}; \ No newline at end of file diff --git a/workspaces/frontend/src/app/pages/Workspaces/Workspaces.tsx b/workspaces/frontend/src/app/pages/Workspaces/Workspaces.tsx index 6312a52f..a685d13d 100644 --- a/workspaces/frontend/src/app/pages/Workspaces/Workspaces.tsx +++ b/workspaces/frontend/src/app/pages/Workspaces/Workspaces.tsx @@ -30,6 +30,7 @@ import { ExpandedWorkspaceRow } from '~/app/pages/Workspaces/ExpandedWorkspaceRo import DeleteModal from '~/shared/components/DeleteModal'; import Filter, { FilteredColumn } from 'shared/components/Filter'; import { formatRam } from 'shared/utilities/WorkspaceResources'; +import { EndpointsDropdown } from '~/app/pages/Workspaces/WorkspaceEndpoints'; export const Workspaces: React.FunctionComponent = () => { /* Mocked workspaces, to be removed after fetching info from backend */ @@ -62,6 +63,12 @@ export const Workspaces: React.FunctionComponent = () => { }, ], }, + endpoints: [ + { + displayName: 'JupyterLab', + port: '7777' + } + ], }, options: { imageConfig: 'jupyterlab_scipy_180', @@ -107,6 +114,16 @@ export const Workspaces: React.FunctionComponent = () => { }, ], }, + endpoints: [ + { + displayName: 'JupyterLab', + port: '8888' + }, + { + displayName: 'Spark Master', + port: '9999' + }, + ], }, options: { imageConfig: 'jupyterlab_scipy_180', @@ -438,6 +455,9 @@ export const Workspaces: React.FunctionComponent = () => { 1 hour ago + + + ({ diff --git a/workspaces/frontend/src/shared/types.ts b/workspaces/frontend/src/shared/types.ts index 577c371b..2954a40c 100644 --- a/workspaces/frontend/src/shared/types.ts +++ b/workspaces/frontend/src/shared/types.ts @@ -67,6 +67,10 @@ export interface Workspace { readOnly: boolean; }[]; }; + endpoints: { + displayName: string; + port: string; + }[]; }; options: { imageConfig: string; From a36531d0f8b3a72cbf47ff767a9858b89dcd38b1 Mon Sep 17 00:00:00 2001 From: Yael Date: Thu, 23 Jan 2025 22:57:13 +0200 Subject: [PATCH 2/2] feat(ws): Split the Connect button, such that clicking it opens the default (main) endpoint Signed-off-by: Yael --- .../app/pages/Workspaces/WorkspaceEndpoints.tsx | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/workspaces/frontend/src/app/pages/Workspaces/WorkspaceEndpoints.tsx b/workspaces/frontend/src/app/pages/Workspaces/WorkspaceEndpoints.tsx index dcc69c0c..d4edfecb 100644 --- a/workspaces/frontend/src/app/pages/Workspaces/WorkspaceEndpoints.tsx +++ b/workspaces/frontend/src/app/pages/Workspaces/WorkspaceEndpoints.tsx @@ -5,6 +5,7 @@ import { DropdownList, MenuToggle, MenuToggleElement, + MenuToggleAction } from "@patternfly/react-core"; import { Workspace, WorkspaceState } from "~/shared/types"; @@ -28,6 +29,10 @@ export const EndpointsDropdown: React.FunctionComponent } }; + const onClickConnect = () => { + openEndpoint(workspace.podTemplate.endpoints[0].port); + } + const openEndpoint = (port: string) => { window.open(`workspace/${workspace.namespace}/${workspace.name}/${port}`, '_blank'); }; @@ -44,7 +49,15 @@ export const EndpointsDropdown: React.FunctionComponent isExpanded={isOpen} isFullWidth={true} isDisabled={workspace.status.state != WorkspaceState.Running} - >Connect + splitButtonItems={[ + + Connect + + ]} + > )} ouiaId="BasicDropdown"