Skip to content

Commit 5c9fe22

Browse files
committed
feat(misc): chatbot support
1 parent 22909d8 commit 5c9fe22

File tree

5 files changed

+247
-5
lines changed

5 files changed

+247
-5
lines changed

packages/dev/src/AppTabs.tsx

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
import './App.css';
2+
import {
3+
Page,
4+
Button,
5+
Drawer,
6+
DrawerContent,
7+
Tabs,
8+
Tab,
9+
TabTitleText,
10+
DrawerContentBody,
11+
DrawerPanelContent,
12+
DrawerHead,
13+
DrawerActions,
14+
DrawerCloseButton,
15+
DrawerPanelDescription,
16+
DrawerPanelBody,
17+
} from '@patternfly/react-core';
18+
import {
19+
LoadingBox,
20+
QuickStartContainer,
21+
QuickStartContainerProps,
22+
QuickStartController,
23+
QuickStartCloseModal,
24+
QuickStartStatus,
25+
useLocalStorage,
26+
setQueryArgument,
27+
removeQueryArgument,
28+
QUICKSTART_ID_FILTER_KEY,
29+
} from '@patternfly/quickstarts';
30+
import { allQuickStarts as yamlQuickStarts } from './quickstarts-data/quick-start-test-data';
31+
import React from 'react';
32+
import i18n from './i18n/i18n';
33+
import { AppHeader, AppSidebar } from './common/Page';
34+
35+
interface AppProps {
36+
children?: React.ReactNode;
37+
showCardFooters?: boolean;
38+
}
39+
40+
const App: React.FC<AppProps> = ({ children, showCardFooters }) => {
41+
const [activeQuickStartID, setActiveQuickStartID] = useLocalStorage('quickstartId', '');
42+
const [allQuickStartStates, setAllQuickStartStates] = useLocalStorage('quickstarts', {});
43+
const language = localStorage.getItem('bridge/language') || 'en';
44+
const resourceBundle = i18n.getResourceBundle(language, 'quickstart');
45+
46+
// eslint-disable-next-line no-console
47+
React.useEffect(() => console.log(activeQuickStartID), [activeQuickStartID]);
48+
React.useEffect(() => {
49+
// callback on state change
50+
// eslint-disable-next-line no-console
51+
console.log(allQuickStartStates);
52+
}, [allQuickStartStates]);
53+
54+
const withQueryParams = true;
55+
56+
const containerProps: QuickStartContainerProps = {
57+
quickStarts: yamlQuickStarts,
58+
activeQuickStartID,
59+
allQuickStartStates,
60+
setActiveQuickStartID,
61+
setAllQuickStartStates,
62+
resourceBundle,
63+
showCardFooters,
64+
language,
65+
useQueryParams: withQueryParams,
66+
alwaysShowTaskReview: true,
67+
markdown: {
68+
extensions: [
69+
// variable substitution
70+
{
71+
type: 'output',
72+
filter(html: string) {
73+
html = html.replace(/\[APPLICATION\]/g, 'Mercury');
74+
html = html.replace(/\[PRODUCT\]/g, 'Lightning');
75+
76+
return html;
77+
},
78+
},
79+
],
80+
},
81+
};
82+
83+
const toggleQuickStart = (quickStartId: string) => {
84+
if (activeQuickStartID !== quickStartId) {
85+
// activate
86+
setActiveQuickStartID(quickStartId);
87+
// optionally add the query param
88+
withQueryParams && setQueryArgument(QUICKSTART_ID_FILTER_KEY, quickStartId);
89+
} else {
90+
// deactivate
91+
setActiveQuickStartID('');
92+
// optionally remove the query param
93+
withQueryParams && removeQueryArgument(QUICKSTART_ID_FILTER_KEY);
94+
}
95+
};
96+
97+
const [modalOpen, setModalOpen] = React.useState<boolean>(false);
98+
const onClose = () => {
99+
setActiveQuickStartID('');
100+
setIsDrawerOpen(false);
101+
};
102+
const handleClose = (activeQuickStartStatus: string | number) => {
103+
// need to hook up to modal close button
104+
if (activeQuickStartStatus === QuickStartStatus.IN_PROGRESS) {
105+
setModalOpen(true);
106+
} else {
107+
onClose();
108+
}
109+
onClose();
110+
};
111+
const onModalConfirm = () => {
112+
setModalOpen(false);
113+
onClose();
114+
};
115+
const onModalCancel = () => setModalOpen(false);
116+
117+
const [isDrawerOpen, setIsDrawerOpen] = React.useState(false);
118+
const [activeTabKey, setActiveTabKey] = React.useState<string | number>(0);
119+
// Toggle currently active tab
120+
const handleTabClick = (
121+
event: React.MouseEvent<any> | React.KeyboardEvent | MouseEvent,
122+
tabIndex: string | number,
123+
) => {
124+
setActiveTabKey(tabIndex);
125+
};
126+
127+
// needed for QuickStartController and metadata filling out
128+
// we're basically rendering the QS on the user code opposed to QuickStartPanelContent
129+
const quickStart = yamlQuickStarts.find((qs) => qs.metadata.name === activeQuickStartID);
130+
const nextQuickStart = yamlQuickStarts.filter((qs) =>
131+
quickStart?.spec.nextQuickStart?.includes(qs.metadata.name),
132+
);
133+
const panelContent = (
134+
<DrawerPanelContent isResizable>
135+
<DrawerHead>
136+
<span>{activeQuickStartID !== '' ? quickStart?.spec.displayName : 'No QS title'}</span>
137+
<DrawerActions>
138+
<DrawerCloseButton onClick={() => setIsDrawerOpen(false)} />
139+
</DrawerActions>
140+
</DrawerHead>
141+
<DrawerPanelDescription>Drawer panel description</DrawerPanelDescription>
142+
<DrawerPanelBody
143+
style={{ display: 'flex', flexDirection: 'column' } /** need for footer spacing */}
144+
>
145+
<Tabs
146+
activeKey={activeTabKey}
147+
onSelect={handleTabClick}
148+
aria-label="Tabs in a drawer"
149+
role="region"
150+
>
151+
{activeQuickStartID !== '' && (
152+
<Tab
153+
eventKey={0}
154+
title={<TabTitleText>Quickstart</TabTitleText>}
155+
aria-label="Default content - users"
156+
style={{ flex: '1 1', display: 'flex', flexDirection: 'column' }} // not currently spread to tab - react issue opened https://github.com/patternfly/patternfly-react/issues/11342
157+
>
158+
<QuickStartController quickStart={quickStart} nextQuickStarts={nextQuickStart} />
159+
</Tab>
160+
)}
161+
162+
<Tab eventKey={1} title={<TabTitleText>Chatbot</TabTitleText>}>
163+
Chatbot
164+
<Button
165+
variant="secondary"
166+
onClick={() => {
167+
toggleQuickStart('getting-started-with-quick-starts');
168+
}}
169+
>
170+
Toggle QS
171+
</Button>
172+
</Tab>
173+
</Tabs>
174+
</DrawerPanelBody>
175+
</DrawerPanelContent>
176+
);
177+
178+
return (
179+
<React.Suspense fallback={<LoadingBox />}>
180+
<QuickStartContainer {...containerProps} isManagedDrawer={false}>
181+
<Drawer isExpanded={isDrawerOpen} isInline>
182+
<DrawerContent panelContent={panelContent}>
183+
<DrawerContentBody>
184+
<Page masthead={AppHeader} sidebar={AppSidebar} isManagedSidebar>
185+
<Button
186+
variant="secondary"
187+
onClick={() => {
188+
setIsDrawerOpen(!isDrawerOpen);
189+
}}
190+
>
191+
Toggle Drawer
192+
</Button>
193+
<Button
194+
variant="secondary"
195+
onClick={() => {
196+
toggleQuickStart('getting-started-with-quick-starts');
197+
}}
198+
>
199+
Toggle QS
200+
</Button>
201+
{children}
202+
</Page>
203+
</DrawerContentBody>
204+
</DrawerContent>
205+
</Drawer>
206+
<QuickStartCloseModal
207+
isOpen={modalOpen}
208+
onConfirm={onModalConfirm}
209+
onCancel={onModalCancel}
210+
/>
211+
</QuickStartContainer>
212+
</React.Suspense>
213+
);
214+
};
215+
export default App;

packages/dev/src/Nav.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ export const Nav: NavInterface[] = [
4040
name: 'With custom drawer',
4141
to: '/quickstarts-drawer',
4242
},
43+
{
44+
id: 'chatbot-drawer',
45+
name: 'With chatbot drawer',
46+
to: '/chatbot-drawer',
47+
},
4348
];
4449

4550
export default Nav;

packages/dev/src/index.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import AppProps from './AppProps';
1212
import AppLocalized from './AppLocalized';
1313
import AppHelpTopicDemo from './AppHelpTopicDemo';
1414
import AppCustomDrawer from './AppCustomDrawer';
15+
import AppChatbotDrawer from './AppTabs';
1516
import { DefaultCatalog } from './DefaultCatalog';
1617
import { CustomCatalog } from './CustomCatalog';
1718
import { MockConsole } from './MockConsole';
@@ -70,6 +71,14 @@ root.render(
7071
</AppCustomDrawer>
7172
}
7273
/>
74+
<Route
75+
path="/chatbot-drawer"
76+
element={
77+
<AppChatbotDrawer showCardFooters={false}>
78+
<DefaultCatalog hint="This catalog is for testing the component props based quick starts approach by utilizing the QuickStartContainer component" />
79+
</AppChatbotDrawer>
80+
}
81+
/>
7382
</Routes>
7483
</BrowserRouter>,
7584
);

packages/module/src/QuickStartController.tsx

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,30 @@ import { QuickStartContext, QuickStartContextValues } from './utils/quick-start-
55
import { QuickStart, QuickStartStatus, QuickStartTaskStatus } from './utils/quick-start-types';
66

77
interface QuickStartControllerProps {
8+
/** The current active quickstart */
89
quickStart: QuickStart;
10+
/** The next quickstart */
911
nextQuickStarts?: QuickStart[];
10-
footerClass: string;
11-
contentRef: React.Ref<HTMLDivElement>;
12+
/** Additional footer classes */
13+
footerClass?: string;
14+
/** Ref for the quickstart content */
15+
contentRef?: React.Ref<HTMLDivElement>;
1216
}
1317

14-
const QuickStartController: React.FC<QuickStartControllerProps> = ({
15-
quickStart,
16-
nextQuickStarts,
18+
export const QuickStartController: React.FC<QuickStartControllerProps> = ({
19+
quickStart, // : propQS, might be able to have default value of current active QS using context?
20+
nextQuickStarts, // : propNextQS, might be same
1721
contentRef,
1822
footerClass,
1923
}) => {
24+
// Should work?
25+
// const { allQuickStarts, activeQuickStartID } =
26+
// React.useContext<QuickStartContextValues>(QuickStartContext);
27+
// const quickStart = propQS || allQuickStarts.find((qs) => qs.metadata.name === activeQuickStartID);
28+
// const nextQuickStarts =
29+
// propNextQS ||
30+
// allQuickStarts.filter((qs) => quickStart?.spec.nextQuickStart?.includes(qs.metadata.name));
31+
2032
const {
2133
metadata: { name },
2234
spec: { tasks = [] },

packages/module/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export * from './QuickStartCatalogPage';
44
export * from './catalog';
55
export * from './ConsoleInternal/components/utils';
66
export * from './QuickStartContainer';
7+
export * from './QuickStartController';
78
export * from './QuickStartDrawer';
89
export * from './QuickStartDrawerContent';
910
export * from './QuickStartCloseModal';

0 commit comments

Comments
 (0)