Skip to content

Commit fa41d42

Browse files
authored
Merge pull request #344 from kmcfaul/qs-custom-drawer
feat(QuickStarts): decouple content from quickstart drawer
2 parents ee2569e + 8b6aa3b commit fa41d42

File tree

9 files changed

+580
-161
lines changed

9 files changed

+580
-161
lines changed
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
import './App.css';
2+
import {
3+
Page,
4+
Button,
5+
Drawer,
6+
DrawerContent,
7+
DrawerPanelContent,
8+
DrawerHead,
9+
DrawerActions,
10+
DrawerCloseButton,
11+
DrawerPanelDescription,
12+
DrawerPanelBody,
13+
DrawerContentBody,
14+
} from '@patternfly/react-core';
15+
import {
16+
LoadingBox,
17+
QuickStartContainer,
18+
QuickStartContainerProps,
19+
QuickStartDrawerContent,
20+
QuickStartCloseModal,
21+
QuickStartStatus,
22+
useLocalStorage,
23+
setQueryArgument,
24+
removeQueryArgument,
25+
QUICKSTART_ID_FILTER_KEY,
26+
} from '@patternfly/quickstarts';
27+
import { allQuickStarts as yamlQuickStarts } from './quickstarts-data/quick-start-test-data';
28+
import React from 'react';
29+
import i18n from './i18n/i18n';
30+
import { AppHeader, AppSidebar } from './common/Page';
31+
32+
interface AppProps {
33+
children?: React.ReactNode;
34+
showCardFooters?: boolean;
35+
}
36+
37+
const App: React.FC<AppProps> = ({ children, showCardFooters }) => {
38+
const [activeQuickStartID, setActiveQuickStartID] = useLocalStorage('quickstartId', '');
39+
const [allQuickStartStates, setAllQuickStartStates] = useLocalStorage('quickstarts', {});
40+
const language = localStorage.getItem('bridge/language') || 'en';
41+
const resourceBundle = i18n.getResourceBundle(language, 'quickstart');
42+
43+
// eslint-disable-next-line no-console
44+
React.useEffect(() => console.log(activeQuickStartID), [activeQuickStartID]);
45+
React.useEffect(() => {
46+
// callback on state change
47+
// eslint-disable-next-line no-console
48+
console.log(allQuickStartStates);
49+
}, [allQuickStartStates]);
50+
51+
const withQueryParams = true;
52+
53+
const containerProps: QuickStartContainerProps = {
54+
quickStarts: yamlQuickStarts,
55+
activeQuickStartID,
56+
allQuickStartStates,
57+
setActiveQuickStartID,
58+
setAllQuickStartStates,
59+
resourceBundle,
60+
showCardFooters,
61+
language,
62+
useQueryParams: withQueryParams,
63+
alwaysShowTaskReview: true,
64+
markdown: {
65+
extensions: [
66+
// variable substitution
67+
{
68+
type: 'output',
69+
filter(html: string) {
70+
html = html.replace(/\[APPLICATION\]/g, 'Mercury');
71+
html = html.replace(/\[PRODUCT\]/g, 'Lightning');
72+
73+
return html;
74+
},
75+
},
76+
],
77+
},
78+
};
79+
80+
const toggleQuickStart = (quickStartId: string) => {
81+
if (activeQuickStartID !== quickStartId) {
82+
// activate
83+
setActiveQuickStartID(quickStartId);
84+
// optionally add the query param
85+
withQueryParams && setQueryArgument(QUICKSTART_ID_FILTER_KEY, quickStartId);
86+
} else {
87+
// deactivate
88+
setActiveQuickStartID('');
89+
// optionally remove the query param
90+
withQueryParams && removeQueryArgument(QUICKSTART_ID_FILTER_KEY);
91+
}
92+
};
93+
94+
const [modalOpen, setModalOpen] = React.useState<boolean>(false);
95+
const onClose = () => {
96+
setActiveQuickStartID('');
97+
setDrawerContent('none');
98+
};
99+
const handleClose = (activeQuickStartStatus: string | number) => {
100+
if (activeQuickStartStatus === QuickStartStatus.IN_PROGRESS) {
101+
setModalOpen(true);
102+
} else {
103+
onClose();
104+
}
105+
onClose();
106+
};
107+
const onModalConfirm = () => {
108+
setModalOpen(false);
109+
onClose();
110+
};
111+
const onModalCancel = () => setModalOpen(false);
112+
113+
const [drawerContent, setDrawerContent] = React.useState('none');
114+
115+
const otherDrawerPanelContent = (
116+
<DrawerPanelContent>
117+
<DrawerHead>
118+
<span tabIndex={drawerContent === 'custom' ? 0 : -1}>Drawer panel header</span>
119+
<DrawerActions>
120+
<DrawerCloseButton onClick={() => setDrawerContent('none')} />
121+
</DrawerActions>
122+
</DrawerHead>
123+
<DrawerPanelDescription>Drawer panel description</DrawerPanelDescription>
124+
<DrawerPanelBody>Drawer panel body</DrawerPanelBody>
125+
</DrawerPanelContent>
126+
);
127+
128+
return (
129+
<React.Suspense fallback={<LoadingBox />}>
130+
<QuickStartContainer {...containerProps} isManagedDrawer={false}>
131+
<Drawer isExpanded={drawerContent !== 'none'} isInline>
132+
<DrawerContent
133+
panelContent={
134+
drawerContent === 'quickstart' || activeQuickStartID !== '' ? (
135+
<QuickStartDrawerContent handleDrawerClose={handleClose} />
136+
) : (
137+
otherDrawerPanelContent
138+
)
139+
}
140+
>
141+
<DrawerContentBody>
142+
<Page masthead={AppHeader} sidebar={AppSidebar} isManagedSidebar>
143+
<Button
144+
variant="secondary"
145+
onClick={() => {
146+
toggleQuickStart('getting-started-with-quick-starts');
147+
setDrawerContent('quickstart');
148+
}}
149+
>
150+
Getting started with quick starts
151+
</Button>
152+
<Button
153+
variant="secondary"
154+
onClick={() => {
155+
setActiveQuickStartID('');
156+
setDrawerContent('custom');
157+
}}
158+
>
159+
Open a different drawer
160+
</Button>
161+
{children}
162+
</Page>
163+
</DrawerContentBody>
164+
</DrawerContent>
165+
</Drawer>
166+
<QuickStartCloseModal
167+
isOpen={modalOpen}
168+
onConfirm={onModalConfirm}
169+
onCancel={onModalCancel}
170+
/>
171+
</QuickStartContainer>
172+
</React.Suspense>
173+
);
174+
};
175+
export default App;

packages/dev/src/Nav.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ export const Nav: NavInterface[] = [
3535
name: 'In-app documentation',
3636
to: '/in-app-documentation',
3737
},
38+
{
39+
id: 'custom-drawer',
40+
name: 'With custom drawer',
41+
to: '/quickstarts-drawer',
42+
},
3843
];
3944

4045
export default Nav;

packages/dev/src/index.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import AppContext from './AppContext';
1111
import AppProps from './AppProps';
1212
import AppLocalized from './AppLocalized';
1313
import AppHelpTopicDemo from './AppHelpTopicDemo';
14+
import AppCustomDrawer from './AppCustomDrawer';
1415
import { DefaultCatalog } from './DefaultCatalog';
1516
import { CustomCatalog } from './CustomCatalog';
1617
import { MockConsole } from './MockConsole';
@@ -61,6 +62,14 @@ root.render(
6162
</AppHelpTopicDemo>
6263
}
6364
/>
65+
<Route
66+
path="/quickstarts-drawer"
67+
element={
68+
<AppCustomDrawer showCardFooters={false}>
69+
<DefaultCatalog hint="This catalog is for testing the component props based quick starts approach by utilizing the QuickStartContainer component" />
70+
</AppCustomDrawer>
71+
}
72+
/>
6473
</Routes>
6574
</BrowserRouter>,
6675
);
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
import React from 'react';
2+
import {
3+
LoadingBox,
4+
QuickStartContainer,
5+
useLocalStorage,
6+
QuickStartCatalogPage,
7+
QuickStartDrawerContent,
8+
QuickStartCloseModal,
9+
QuickStartStatus,
10+
} from '@patternfly/quickstarts';
11+
import {
12+
Drawer,
13+
DrawerContent,
14+
DrawerPanelContent,
15+
DrawerHead,
16+
DrawerActions,
17+
DrawerCloseButton,
18+
DrawerPanelDescription,
19+
DrawerPanelBody,
20+
DrawerContentBody,
21+
Button,
22+
} from '@patternfly/react-core';
23+
import { quickStarts as exampleQuickStarts } from './example-data';
24+
25+
export const App = ({ showCardFooters }) => {
26+
const [activeQuickStartID, setActiveQuickStartID] = useLocalStorage('quickstartId', '');
27+
const [allQuickStartStates, setAllQuickStartStates] = useLocalStorage('quickstarts', {});
28+
const language = localStorage.getItem('bridge/language') || 'en';
29+
30+
// eslint-disable-next-line no-console
31+
React.useEffect(() => console.log(activeQuickStartID), [activeQuickStartID]);
32+
React.useEffect(() => {
33+
// callback on state change
34+
// eslint-disable-next-line no-console
35+
console.log(allQuickStartStates);
36+
}, [allQuickStartStates]);
37+
38+
const [loading, setLoading] = React.useState(true);
39+
const [quickStarts, setQuickStarts] = React.useState([]);
40+
React.useEffect(() => {
41+
const load = async () => {
42+
setQuickStarts(exampleQuickStarts);
43+
setLoading(false);
44+
};
45+
setTimeout(() => {
46+
load();
47+
}, 500);
48+
}, []);
49+
50+
const drawerProps = {
51+
quickStarts,
52+
activeQuickStartID,
53+
allQuickStartStates,
54+
setActiveQuickStartID,
55+
setAllQuickStartStates,
56+
showCardFooters,
57+
language,
58+
loading,
59+
alwaysShowTaskReview: true,
60+
markdown: {
61+
extensions: [
62+
// variable substitution
63+
{
64+
type: 'output',
65+
filter(html) {
66+
html = html.replace(/\[APPLICATION\]/g, 'Mercury');
67+
html = html.replace(/\[PRODUCT\]/g, 'Lightning');
68+
69+
return html;
70+
},
71+
},
72+
],
73+
},
74+
};
75+
76+
const [modalOpen, setModalOpen] = React.useState(false);
77+
const onClose = () => {
78+
setActiveQuickStartID('');
79+
setDrawerContent('none');
80+
};
81+
const handleClose = (activeQuickStartStatus) => {
82+
if (activeQuickStartStatus === QuickStartStatus.IN_PROGRESS) {
83+
setModalOpen(true);
84+
} else {
85+
onClose();
86+
}
87+
};
88+
const onModalConfirm = () => {
89+
setModalOpen(false);
90+
onClose();
91+
};
92+
const onModalCancel = () => setModalOpen(false);
93+
94+
const [drawerContent, setDrawerContent] = React.useState('none');
95+
96+
const otherDrawerPanelContent = (
97+
<DrawerPanelContent>
98+
<DrawerHead>
99+
<span tabIndex={drawerContent === 'custom' ? 0 : -1}>Drawer panel header</span>
100+
<DrawerActions>
101+
<DrawerCloseButton onClick={() => setDrawerContent('none')} />
102+
</DrawerActions>
103+
</DrawerHead>
104+
<DrawerPanelDescription>Drawer panel description</DrawerPanelDescription>
105+
<DrawerPanelBody>Drawer panel body</DrawerPanelBody>
106+
</DrawerPanelContent>
107+
);
108+
109+
return (
110+
<React.Suspense fallback={<LoadingBox />}>
111+
<QuickStartContainer {...drawerProps} isManagedDrawer={false}>
112+
<Drawer isExpanded={drawerContent !== 'none'} isInline>
113+
<DrawerContent
114+
panelContent={
115+
drawerContent === 'quickstart' || activeQuickStartID !== '' ? (
116+
<QuickStartDrawerContent handleDrawerClose={handleClose} />
117+
) : (
118+
otherDrawerPanelContent
119+
)
120+
}
121+
>
122+
<DrawerContentBody>
123+
<Button
124+
variant="secondary"
125+
onClick={() => {
126+
setActiveQuickStartID('explore-pipelines');
127+
setDrawerContent('quickstart');
128+
}}
129+
>
130+
Getting started with quick starts
131+
</Button>
132+
<Button
133+
variant="secondary"
134+
onClick={() => {
135+
setActiveQuickStartID('');
136+
setDrawerContent('custom');
137+
}}
138+
>
139+
Open a different drawer
140+
</Button>
141+
<QuickStartCatalogPage
142+
title="Quick starts"
143+
hint={
144+
'Learn how to create, import, and run applications with step-by-step instructions and tasks.'
145+
}
146+
/>
147+
</DrawerContentBody>
148+
</DrawerContent>
149+
</Drawer>
150+
<QuickStartCloseModal
151+
isOpen={modalOpen}
152+
onConfirm={onModalConfirm}
153+
onCancel={onModalCancel}
154+
/>
155+
</QuickStartContainer>
156+
</React.Suspense>
157+
);
158+
};

0 commit comments

Comments
 (0)