Skip to content

Commit 8b126c5

Browse files
thaorellmkoushni
authored andcommitted
feat(ws): Introduce drawer to workspace creation wizard (kubeflow#310)
fix(ws): Change label titles in Workspace Creation Add custom rules for drawer body to have full length Signed-off-by: Charles Thao <[email protected]> Signed-off-by: CI Bot <[email protected]>
1 parent 782fc52 commit 8b126c5

File tree

8 files changed

+190
-62
lines changed

8 files changed

+190
-62
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import React, { Ref } from 'react';
2+
import {
3+
Drawer,
4+
DrawerPanelContent,
5+
DrawerContent,
6+
DrawerContentBody,
7+
DrawerHead,
8+
DrawerActions,
9+
DrawerCloseButton,
10+
Title,
11+
} from '@patternfly/react-core';
12+
13+
interface WorkspaceCreationDrawerProps {
14+
children: React.ReactNode;
15+
title: string;
16+
info: React.ReactNode;
17+
isExpanded: boolean;
18+
drawerRef?: Ref<HTMLSpanElement>;
19+
onCloseClick: () => void;
20+
onExpand: () => void;
21+
}
22+
23+
export const WorkspaceCreationDrawer: React.FC<WorkspaceCreationDrawerProps> = ({
24+
children,
25+
isExpanded,
26+
drawerRef,
27+
title,
28+
info,
29+
onCloseClick,
30+
onExpand,
31+
}) => {
32+
const panelContent = (
33+
<DrawerPanelContent>
34+
<DrawerHead>
35+
<span role="button" tabIndex={isExpanded ? 0 : -1} ref={drawerRef as Ref<HTMLSpanElement>}>
36+
<Title headingLevel="h6">{title}</Title>
37+
</span>
38+
<DrawerActions>
39+
<DrawerCloseButton onClick={onCloseClick} />
40+
</DrawerActions>
41+
</DrawerHead>
42+
{info}
43+
</DrawerPanelContent>
44+
);
45+
46+
return (
47+
<>
48+
<Drawer isExpanded={isExpanded} isInline onExpand={onExpand}>
49+
<DrawerContent panelContent={panelContent}>
50+
<DrawerContentBody>{children}</DrawerContentBody>
51+
</DrawerContent>
52+
</Drawer>
53+
</>
54+
);
55+
};

workspaces/frontend/src/app/pages/Workspaces/Creation/image/WorkspaceCreationImageDetails.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,9 @@ type WorkspaceCreationImageDetailsProps = {
99
export const WorkspaceCreationImageDetails: React.FunctionComponent<
1010
WorkspaceCreationImageDetailsProps
1111
> = ({ workspaceImage }) => (
12-
<>
13-
{!workspaceImage && <p>Select an image to view its details here.</p>}
14-
12+
<div style={{ marginLeft: 'var(--pf-t--global--spacer--md)' }}>
1513
{workspaceImage && (
1614
<>
17-
<Title headingLevel="h6">Image</Title>
1815
<Title headingLevel="h3">{workspaceImage.displayName}</Title>
1916
<br />
2017
<List isPlain>
@@ -26,5 +23,5 @@ export const WorkspaceCreationImageDetails: React.FunctionComponent<
2623
</List>
2724
</>
2825
)}
29-
</>
26+
</div>
3027
);

workspaces/frontend/src/app/pages/Workspaces/Creation/image/WorkspaceCreationImageSelection.tsx

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import * as React from 'react';
1+
import React, { useMemo, useState, useCallback } from 'react';
22
import { Content, Divider, Split, SplitItem } from '@patternfly/react-core';
3-
import { useMemo, useState } from 'react';
43
import { WorkspaceCreationImageDetails } from '~/app/pages/Workspaces/Creation/image/WorkspaceCreationImageDetails';
54
import { WorkspaceCreationImageList } from '~/app/pages/Workspaces/Creation/image/WorkspaceCreationImageList';
65
import { FilterByLabels } from '~/app/pages/Workspaces/Creation/labelFilter/FilterByLabels';
76
import { WorkspaceImageConfigValue } from '~/shared/api/backendApiTypes';
7+
import { WorkspaceCreationDrawer } from '~/app/pages/Workspaces/Creation/WorkspaceCreationDrawer';
88

99
interface WorkspaceCreationImageSelectionProps {
1010
images: WorkspaceImageConfigValue[];
@@ -16,6 +16,26 @@ const WorkspaceCreationImageSelection: React.FunctionComponent<
1616
WorkspaceCreationImageSelectionProps
1717
> = ({ images, selectedImage, onSelect }) => {
1818
const [selectedLabels, setSelectedLabels] = useState<Map<string, Set<string>>>(new Map());
19+
const [isExpanded, setIsExpanded] = useState(false);
20+
const drawerRef = React.useRef<HTMLSpanElement>(undefined);
21+
22+
const onExpand = useCallback(() => {
23+
if (drawerRef.current) {
24+
drawerRef.current.focus();
25+
}
26+
}, []);
27+
28+
const onClick = useCallback(
29+
(image?: WorkspaceImageConfigValue) => {
30+
setIsExpanded(true);
31+
onSelect(image);
32+
},
33+
[onSelect],
34+
);
35+
36+
const onCloseClick = useCallback(() => {
37+
setIsExpanded(false);
38+
}, []);
1939

2040
const imageFilterContent = useMemo(
2141
() => (
@@ -37,18 +57,25 @@ const WorkspaceCreationImageSelection: React.FunctionComponent<
3757
<Content style={{ height: '100%' }}>
3858
<p>Select a workspace image and image version to use for the workspace.</p>
3959
<Divider />
40-
<Split hasGutter>
41-
<SplitItem style={{ minWidth: '200px' }}>{imageFilterContent}</SplitItem>
42-
<SplitItem isFilled>
43-
<WorkspaceCreationImageList
44-
images={images}
45-
selectedLabels={selectedLabels}
46-
selectedImage={selectedImage}
47-
onSelect={onSelect}
48-
/>
49-
</SplitItem>
50-
<SplitItem style={{ minWidth: '200px' }}>{imageDetailsContent}</SplitItem>
51-
</Split>
60+
<WorkspaceCreationDrawer
61+
title="Image"
62+
info={imageDetailsContent}
63+
isExpanded={isExpanded}
64+
onCloseClick={onCloseClick}
65+
onExpand={onExpand}
66+
>
67+
<Split hasGutter>
68+
<SplitItem style={{ minWidth: '200px' }}>{imageFilterContent}</SplitItem>
69+
<SplitItem isFilled>
70+
<WorkspaceCreationImageList
71+
images={images}
72+
selectedLabels={selectedLabels}
73+
selectedImage={selectedImage}
74+
onSelect={onClick}
75+
/>
76+
</SplitItem>
77+
</Split>
78+
</WorkspaceCreationDrawer>
5279
</Content>
5380
);
5481
};

workspaces/frontend/src/app/pages/Workspaces/Creation/kind/WorkspaceCreationKindDetails.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,12 @@ type WorkspaceCreationKindDetailsProps = {
99
export const WorkspaceCreationKindDetails: React.FunctionComponent<
1010
WorkspaceCreationKindDetailsProps
1111
> = ({ workspaceKind }) => (
12-
<>
13-
{!workspaceKind && <p>Select a workspace kind to view its details here.</p>}
14-
12+
<div style={{ marginLeft: 'var(--pf-t--global--spacer--md)' }}>
1513
{workspaceKind && (
1614
<>
17-
<Title headingLevel="h6">Workspace kind</Title>
1815
<Title headingLevel="h3">{workspaceKind.name}</Title>
1916
<p>{workspaceKind.description}</p>
2017
</>
2118
)}
22-
</>
19+
</div>
2320
);

workspaces/frontend/src/app/pages/Workspaces/Creation/kind/WorkspaceCreationKindSelection.tsx

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import * as React from 'react';
2-
import { Content, Divider, Split, SplitItem } from '@patternfly/react-core';
3-
import { useMemo } from 'react';
1+
import React, { useState, useRef, useMemo, useCallback } from 'react';
2+
import { Content, Divider } from '@patternfly/react-core';
43
import { WorkspaceKind } from '~/shared/api/backendApiTypes';
4+
import useWorkspaceKinds from '~/app/hooks/useWorkspaceKinds';
55
import { WorkspaceCreationKindDetails } from '~/app/pages/Workspaces/Creation/kind/WorkspaceCreationKindDetails';
66
import { WorkspaceCreationKindList } from '~/app/pages/Workspaces/Creation/kind/WorkspaceCreationKindList';
7-
import useWorkspaceKinds from '~/app/hooks/useWorkspaceKinds';
7+
import { WorkspaceCreationDrawer } from '~/app/pages/Workspaces/Creation/WorkspaceCreationDrawer';
88

99
interface WorkspaceCreationKindSelectionProps {
1010
selectedKind: WorkspaceKind | undefined;
@@ -15,6 +15,26 @@ const WorkspaceCreationKindSelection: React.FunctionComponent<
1515
WorkspaceCreationKindSelectionProps
1616
> = ({ selectedKind, onSelect }) => {
1717
const [workspaceKinds, loaded, error] = useWorkspaceKinds();
18+
const [isExpanded, setIsExpanded] = useState(false);
19+
const drawerRef = useRef<HTMLSpanElement>(undefined);
20+
21+
const onExpand = useCallback(() => {
22+
if (drawerRef.current) {
23+
drawerRef.current.focus();
24+
}
25+
}, []);
26+
27+
const onClick = useCallback(
28+
(kind?: WorkspaceKind) => {
29+
setIsExpanded(true);
30+
onSelect(kind);
31+
},
32+
[onSelect],
33+
);
34+
35+
const onCloseClick = useCallback(() => {
36+
setIsExpanded(false);
37+
}, []);
1838

1939
const kindDetailsContent = useMemo(
2040
() => <WorkspaceCreationKindDetails workspaceKind={selectedKind} />,
@@ -31,18 +51,21 @@ const WorkspaceCreationKindSelection: React.FunctionComponent<
3151

3252
return (
3353
<Content style={{ height: '100%' }}>
34-
<p>Select a workspace kind to use for the workspace.</p>
35-
<Divider />
36-
<Split hasGutter>
37-
<SplitItem isFilled>
38-
<WorkspaceCreationKindList
39-
allWorkspaceKinds={workspaceKinds}
40-
selectedKind={selectedKind}
41-
onSelect={onSelect}
42-
/>
43-
</SplitItem>
44-
<SplitItem style={{ minWidth: '200px' }}>{kindDetailsContent}</SplitItem>
45-
</Split>
54+
<WorkspaceCreationDrawer
55+
title="Workspace kind"
56+
info={kindDetailsContent}
57+
isExpanded={isExpanded}
58+
onCloseClick={onCloseClick}
59+
onExpand={onExpand}
60+
>
61+
<p>Select a workspace kind to use for the workspace.</p>
62+
<Divider />
63+
<WorkspaceCreationKindList
64+
allWorkspaceKinds={workspaceKinds}
65+
selectedKind={selectedKind}
66+
onSelect={onClick}
67+
/>
68+
</WorkspaceCreationDrawer>
4669
</Content>
4770
);
4871
};
Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { List, ListItem, Title } from '@patternfly/react-core';
2+
import { List, ListItem } from '@patternfly/react-core';
33
import { WorkspacePodConfigValue } from '~/shared/api/backendApiTypes';
44

55
type WorkspaceCreationPodConfigDetailsProps = {
@@ -10,12 +10,8 @@ export const WorkspaceCreationPodConfigDetails: React.FunctionComponent<
1010
WorkspaceCreationPodConfigDetailsProps
1111
> = ({ workspacePodConfig }) => (
1212
<>
13-
{!workspacePodConfig && <p>Select a pod config to view its details here.</p>}
14-
1513
{workspacePodConfig && (
16-
<>
17-
<Title headingLevel="h6">Pod config</Title>
18-
<Title headingLevel="h3">{workspacePodConfig.displayName}</Title>
14+
<div style={{ marginLeft: 'var(--pf-t--global--spacer--md)' }}>
1915
<p>{workspacePodConfig.description}</p>
2016
<List isPlain>
2117
{workspacePodConfig.labels.map((label) => (
@@ -24,7 +20,7 @@ export const WorkspaceCreationPodConfigDetails: React.FunctionComponent<
2420
</ListItem>
2521
))}
2622
</List>
27-
</>
23+
</div>
2824
)}
2925
</>
3026
);

workspaces/frontend/src/app/pages/Workspaces/Creation/podConfig/WorkspaceCreationPodConfigSelection.tsx

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import * as React from 'react';
1+
import React, { useCallback, useMemo, useState } from 'react';
22
import { Content, Divider, Split, SplitItem } from '@patternfly/react-core';
3-
import { useMemo, useState } from 'react';
4-
import { WorkspacePodConfigValue } from '~/shared/api/backendApiTypes';
53
import { WorkspaceCreationPodConfigDetails } from '~/app/pages/Workspaces/Creation/podConfig/WorkspaceCreationPodConfigDetails';
64
import { WorkspaceCreationPodConfigList } from '~/app/pages/Workspaces/Creation/podConfig/WorkspaceCreationPodConfigList';
75
import { FilterByLabels } from '~/app/pages/Workspaces/Creation/labelFilter/FilterByLabels';
6+
import { WorkspaceCreationDrawer } from '~/app/pages/Workspaces/Creation/WorkspaceCreationDrawer';
7+
import { WorkspacePodConfigValue } from '~/shared/api/backendApiTypes';
88

99
interface WorkspaceCreationPodConfigSelectionProps {
1010
podConfigs: WorkspacePodConfigValue[];
@@ -16,6 +16,26 @@ const WorkspaceCreationPodConfigSelection: React.FunctionComponent<
1616
WorkspaceCreationPodConfigSelectionProps
1717
> = ({ podConfigs, selectedPodConfig, onSelect }) => {
1818
const [selectedLabels, setSelectedLabels] = useState<Map<string, Set<string>>>(new Map());
19+
const [isExpanded, setIsExpanded] = useState(false);
20+
const drawerRef = React.useRef<HTMLSpanElement>(undefined);
21+
22+
const onExpand = useCallback(() => {
23+
if (drawerRef.current) {
24+
drawerRef.current.focus();
25+
}
26+
}, []);
27+
28+
const onClick = useCallback(
29+
(podConfig?: WorkspacePodConfigValue) => {
30+
setIsExpanded(true);
31+
onSelect(podConfig);
32+
},
33+
[onSelect],
34+
);
35+
36+
const onCloseClick = useCallback(() => {
37+
setIsExpanded(false);
38+
}, []);
1939

2040
const podConfigFilterContent = useMemo(
2141
() => (
@@ -37,18 +57,26 @@ const WorkspaceCreationPodConfigSelection: React.FunctionComponent<
3757
<Content style={{ height: '100%' }}>
3858
<p>Select a pod config to use for the workspace.</p>
3959
<Divider />
40-
<Split hasGutter>
41-
<SplitItem style={{ minWidth: '200px' }}>{podConfigFilterContent}</SplitItem>
42-
<SplitItem isFilled>
43-
<WorkspaceCreationPodConfigList
44-
podConfigs={podConfigs}
45-
selectedLabels={selectedLabels}
46-
selectedPodConfig={selectedPodConfig}
47-
onSelect={onSelect}
48-
/>
49-
</SplitItem>
50-
<SplitItem style={{ minWidth: '200px' }}>{podConfigDetailsContent}</SplitItem>
51-
</Split>
60+
61+
<WorkspaceCreationDrawer
62+
title="Pod config"
63+
info={podConfigDetailsContent}
64+
isExpanded={isExpanded}
65+
onCloseClick={onCloseClick}
66+
onExpand={onExpand}
67+
>
68+
<Split hasGutter>
69+
<SplitItem style={{ minWidth: '200px' }}>{podConfigFilterContent}</SplitItem>
70+
<SplitItem isFilled>
71+
<WorkspaceCreationPodConfigList
72+
podConfigs={podConfigs}
73+
selectedLabels={selectedLabels}
74+
selectedPodConfig={selectedPodConfig}
75+
onSelect={onClick}
76+
/>
77+
</SplitItem>
78+
</Split>
79+
</WorkspaceCreationDrawer>
5280
</Content>
5381
);
5482
};

workspaces/frontend/src/shared/style/MUI-theme.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,11 @@
769769
flex-grow: 0;
770770
}
771771

772+
// TODO: Remove when https://github.com/patternfly/patternfly-react/issues/11826 is resolved.
773+
.pf-v6-c-page__main-section .pf-v6-c-page__main-body {
774+
height: 100%;
775+
}
776+
772777
.mui-theme .pf-v6-c-pagination {
773778
--pf-v6-c-pagination__total-items--Display: block;
774779
}

0 commit comments

Comments
 (0)