Skip to content

Commit b1a4636

Browse files
committed
feat(QuickStarts): decouple content from drawer
1 parent 10ff609 commit b1a4636

File tree

9 files changed

+487
-169
lines changed

9 files changed

+487
-169
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import './App.css';
2+
import { Page, Button, Drawer } from '@patternfly/react-core';
3+
import {
4+
LoadingBox,
5+
QuickStartContainer,
6+
QuickStartContainerProps,
7+
QuickStartDrawerContent,
8+
QuickStartCloseModal,
9+
QuickStartStatus,
10+
useLocalStorage,
11+
setQueryArgument,
12+
removeQueryArgument,
13+
QUICKSTART_ID_FILTER_KEY,
14+
} from '@patternfly/quickstarts';
15+
import { allQuickStarts as yamlQuickStarts } from './quickstarts-data/quick-start-test-data';
16+
import React from 'react';
17+
import i18n from './i18n/i18n';
18+
import { AppHeader, AppSidebar } from './common/Page';
19+
20+
interface AppProps {
21+
children?: React.ReactNode;
22+
showCardFooters?: boolean;
23+
}
24+
25+
const App: React.FC<AppProps> = ({ children, showCardFooters }) => {
26+
const [activeQuickStartID, setActiveQuickStartID] = useLocalStorage('quickstartId', '');
27+
const [allQuickStartStates, setAllQuickStartStates] = useLocalStorage('quickstarts', {});
28+
const language = localStorage.getItem('bridge/language') || 'en';
29+
const resourceBundle = i18n.getResourceBundle(language, 'quickstart');
30+
31+
// eslint-disable-next-line no-console
32+
React.useEffect(() => console.log(activeQuickStartID), [activeQuickStartID]);
33+
React.useEffect(() => {
34+
// callback on state change
35+
// eslint-disable-next-line no-console
36+
console.log(allQuickStartStates);
37+
}, [allQuickStartStates]);
38+
39+
const withQueryParams = true;
40+
41+
const containerProps: QuickStartContainerProps = {
42+
quickStarts: yamlQuickStarts,
43+
activeQuickStartID,
44+
allQuickStartStates,
45+
setActiveQuickStartID,
46+
setAllQuickStartStates,
47+
resourceBundle,
48+
showCardFooters,
49+
language,
50+
useQueryParams: withQueryParams,
51+
alwaysShowTaskReview: true,
52+
markdown: {
53+
extensions: [
54+
// variable substitution
55+
{
56+
type: 'output',
57+
filter(html: string) {
58+
html = html.replace(/\[APPLICATION\]/g, 'Mercury');
59+
html = html.replace(/\[PRODUCT\]/g, 'Lightning');
60+
61+
return html;
62+
},
63+
},
64+
],
65+
},
66+
};
67+
68+
const toggleQuickStart = (quickStartId: string) => {
69+
if (activeQuickStartID !== quickStartId) {
70+
// activate
71+
setActiveQuickStartID(quickStartId);
72+
// optionally add the query param
73+
withQueryParams && setQueryArgument(QUICKSTART_ID_FILTER_KEY, quickStartId);
74+
} else {
75+
// deactivate
76+
setActiveQuickStartID('');
77+
// optionally remove the query param
78+
withQueryParams && removeQueryArgument(QUICKSTART_ID_FILTER_KEY);
79+
}
80+
};
81+
82+
const [modalOpen, setModalOpen] = React.useState<boolean>(false);
83+
const onClose = () => setActiveQuickStartID('');
84+
const handleClose = (activeQuickStartStatus: string | number) => {
85+
if (activeQuickStartStatus === QuickStartStatus.IN_PROGRESS) {
86+
setModalOpen(true);
87+
} else {
88+
onClose();
89+
}
90+
onClose();
91+
};
92+
const onModalConfirm = () => {
93+
setModalOpen(false);
94+
onClose();
95+
};
96+
const onModalCancel = () => setModalOpen(false);
97+
98+
return (
99+
<React.Suspense fallback={<LoadingBox />}>
100+
<QuickStartContainer {...containerProps} isManagedDrawer={false}>
101+
<Drawer isExpanded={activeQuickStartID !== ''} isInline>
102+
<QuickStartDrawerContent handleDrawerClose={handleClose}>
103+
<Page masthead={AppHeader} sidebar={AppSidebar} isManagedSidebar>
104+
<Button
105+
variant="secondary"
106+
onClick={() => toggleQuickStart('getting-started-with-quick-starts')}
107+
>
108+
Getting started with quick starts
109+
</Button>
110+
{children}
111+
</Page>
112+
</QuickStartDrawerContent>
113+
</Drawer>
114+
<QuickStartCloseModal
115+
isOpen={modalOpen}
116+
onConfirm={onModalConfirm}
117+
onCancel={onModalCancel}
118+
/>
119+
</QuickStartContainer>
120+
</React.Suspense>
121+
);
122+
};
123+
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: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
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 { Drawer } from '@patternfly/react-core';
12+
import { quickStarts as exampleQuickStarts } from './example-data';
13+
14+
export const App = ({ showCardFooters }) => {
15+
const [activeQuickStartID, setActiveQuickStartID] = useLocalStorage('quickstartId', '');
16+
const [allQuickStartStates, setAllQuickStartStates] = useLocalStorage('quickstarts', {});
17+
const language = localStorage.getItem('bridge/language') || 'en';
18+
19+
// eslint-disable-next-line no-console
20+
React.useEffect(() => console.log(activeQuickStartID), [activeQuickStartID]);
21+
React.useEffect(() => {
22+
// callback on state change
23+
// eslint-disable-next-line no-console
24+
console.log(allQuickStartStates);
25+
}, [allQuickStartStates]);
26+
27+
const [loading, setLoading] = React.useState(true);
28+
const [quickStarts, setQuickStarts] = React.useState([]);
29+
React.useEffect(() => {
30+
const load = async () => {
31+
setQuickStarts(exampleQuickStarts);
32+
setLoading(false);
33+
};
34+
setTimeout(() => {
35+
load();
36+
}, 500);
37+
}, []);
38+
39+
const drawerProps = {
40+
quickStarts,
41+
activeQuickStartID,
42+
allQuickStartStates,
43+
setActiveQuickStartID,
44+
setAllQuickStartStates,
45+
showCardFooters,
46+
language,
47+
loading,
48+
alwaysShowTaskReview: true,
49+
markdown: {
50+
extensions: [
51+
// variable substitution
52+
{
53+
type: 'output',
54+
filter(html) {
55+
html = html.replace(/\[APPLICATION\]/g, 'Mercury');
56+
html = html.replace(/\[PRODUCT\]/g, 'Lightning');
57+
58+
return html;
59+
},
60+
},
61+
],
62+
},
63+
};
64+
65+
// The above code is identical to the current quickstarts setup
66+
// Below is additional handling to support a custom drawer with an in-progress close confirm modal
67+
const [modalOpen, setModalOpen] = React.useState(false);
68+
const onClose = () => setActiveQuickStartID('');
69+
const handleClose = (activeQuickStartStatus) => {
70+
if (activeQuickStartStatus === QuickStartStatus.IN_PROGRESS) {
71+
setModalOpen(true);
72+
} else {
73+
onClose();
74+
}
75+
};
76+
const onModalConfirm = () => {
77+
setModalOpen(false);
78+
onClose();
79+
};
80+
const onModalCancel = () => setModalOpen(false);
81+
82+
return (
83+
<React.Suspense fallback={<LoadingBox />}>
84+
<QuickStartContainer {...drawerProps} isManagedDrawer={false}>
85+
<Drawer isExpanded={activeQuickStartID !== ''} isInline>
86+
<QuickStartDrawerContent handleDrawerClose={handleClose}>
87+
<QuickStartCatalogPage
88+
title="Quick starts"
89+
hint={
90+
'Learn how to create, import, and run applications with step-by-step instructions and tasks.'
91+
}
92+
/>
93+
</QuickStartDrawerContent>
94+
</Drawer>
95+
<QuickStartCloseModal
96+
isOpen={modalOpen}
97+
onConfirm={onModalConfirm}
98+
onCancel={onModalCancel}
99+
/>
100+
</QuickStartContainer>
101+
</React.Suspense>
102+
);
103+
};

packages/module/patternfly-docs/content/extensions/quick-starts/examples/basic.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,26 @@ import { quickStarts as exampleQuickStarts } from './example-data';
1717
import { LoadingBox, QuickStartContainer, QuickStartCatalogPage, useLocalStorage, } from '@patternfly/quickstarts';
1818
import '@patternfly/quickstarts/dist/quickstarts.css';
1919

20-
## Basic quick starts examples
20+
## Basic quick starts examples
21+
22+
### Quick starts catalog
2123

22-
### Quick starts catalog
2324
```js file="./Basic.jsx"
25+
2426
```
2527

2628
### Fullscreen catalog page
29+
2730
To view a fullscreen example, click the image below.
31+
2832
```js file="./Basic.jsx" isFullscreen
33+
34+
```
35+
36+
### Quick starts with custom drawer
37+
38+
Quick starts may be placed into a nonmanaged, custom drawer. To view a fullscreen example, click the image below.
39+
40+
```js file="./Basic.jsx" isFullscreen
41+
2942
```

0 commit comments

Comments
 (0)