feat(ws): Add "Connect" column to workspace table and display popup with workspace endpoints. (#161)

* feat(ws): Add Connect column to workspace table and popup with workspace endpoints

Signed-off-by: Yael <fishel.yael@gmail.com>

* feat(ws): Split the Connect button, such that clicking it opens the default (main) endpoint

Signed-off-by: Yael <fishel.yael@gmail.com>

---------

Signed-off-by: Yael <fishel.yael@gmail.com>
This commit is contained in:
Yael Fishel 2025-02-04 18:11:37 +02:00 committed by GitHub
parent 055150bb2e
commit 16f97f86d9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 102 additions and 0 deletions

View File

@ -0,0 +1,78 @@
import React from 'react';
import {
Dropdown,
DropdownItem,
DropdownList,
MenuToggle,
MenuToggleElement,
MenuToggleAction,
} from '@patternfly/react-core';
import { Workspace, WorkspaceState } from '~/shared/types';
type WorkspaceConnectActionProps = {
workspace: Workspace;
};
export const WorkspaceConnectAction: React.FunctionComponent<WorkspaceConnectActionProps> = ({
workspace,
}) => {
const [open, setIsOpen] = React.useState(false);
const onToggleClick = () => {
setIsOpen(!open);
};
const onSelect = (
_event: React.MouseEvent<Element, MouseEvent> | undefined,
value: string | number | undefined,
) => {
setIsOpen(false);
if (typeof value === 'string') {
openEndpoint(value);
}
};
const onClickConnect = () => {
openEndpoint(workspace.podTemplate.endpoints[0].port);
};
const openEndpoint = (port: string) => {
window.open(`workspace/${workspace.namespace}/${workspace.name}/${port}`, '_blank');
};
return (
<Dropdown
isOpen={open}
onSelect={onSelect}
onOpenChange={(isOpen: boolean) => setIsOpen(isOpen)}
toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
<MenuToggle
ref={toggleRef}
onClick={onToggleClick}
isExpanded={open}
isFullWidth
isDisabled={workspace.status.state !== WorkspaceState.Running}
splitButtonItems={[
<MenuToggleAction
id="connect-endpoint-button"
key="connect-endpoint-button"
onClick={onClickConnect}
>
Connect
</MenuToggleAction>,
]}
/>
)}
ouiaId="BasicDropdown"
shouldFocusToggleOnSelect
>
<DropdownList>
{workspace.podTemplate.endpoints.map((endpoint) => (
<DropdownItem value={endpoint.port} key={`${workspace.name}-${endpoint.port}`}>
{endpoint.displayName}
</DropdownItem>
))}
</DropdownList>
</Dropdown>
);
};

View File

@ -33,6 +33,7 @@ import { ExpandedWorkspaceRow } from '~/app/pages/Workspaces/ExpandedWorkspaceRo
import DeleteModal from '~/shared/components/DeleteModal';
import { buildKindLogoDictionary } from '~/app/actions/WorkspaceKindsActions';
import useWorkspaceKinds from '~/app/hooks/useWorkspaceKinds';
import { WorkspaceConnectAction } from '~/app/pages/Workspaces/WorkspaceConnectAction';
import Filter, { FilteredColumn } from 'shared/components/Filter';
import { formatRam } from 'shared/utilities/WorkspaceResources';
@ -67,6 +68,12 @@ export const Workspaces: React.FunctionComponent = () => {
},
],
},
endpoints: [
{
displayName: 'JupyterLab',
port: '7777',
},
],
},
options: {
imageConfig: 'jupyterlab_scipy_180',
@ -112,6 +119,16 @@ export const Workspaces: React.FunctionComponent = () => {
},
],
},
endpoints: [
{
displayName: 'JupyterLab',
port: '8888',
},
{
displayName: 'Spark Master',
port: '9999',
},
],
},
options: {
imageConfig: 'jupyterlab_scipy_180',
@ -461,6 +478,9 @@ export const Workspaces: React.FunctionComponent = () => {
1 hour ago
</Timestamp>
</Td>
<Td>
<WorkspaceConnectAction workspace={workspace} />
</Td>
<Td isActionCell data-testid="action-column">
<ActionsColumn
items={defaultActions(workspace).map((action) => ({

View File

@ -116,6 +116,10 @@ export interface Workspace {
readOnly: boolean;
}[];
};
endpoints: {
displayName: string;
port: string;
}[];
};
options: {
imageConfig: string;