@patternfly/quickstarts 2.2.3 → 2.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. package/dist/HelpTopicDrawer.d.ts +8 -2
  2. package/dist/QuickStartDrawer.d.ts +21 -2
  3. package/dist/index.es.js.map +1 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/patternfly-docs/quick-starts/design-guidelines/design-guidelines.md +105 -0
  6. package/dist/patternfly-docs/quick-starts/design-guidelines/img/card-elements copy.png +0 -0
  7. package/dist/patternfly-docs/quick-starts/design-guidelines/img/card-elements.png +0 -0
  8. package/dist/patternfly-docs/quick-starts/design-guidelines/img/catalog-elements.png +0 -0
  9. package/dist/patternfly-docs/quick-starts/design-guidelines/img/check-your-work.png +0 -0
  10. package/dist/patternfly-docs/quick-starts/design-guidelines/img/introduction-screen.png +0 -0
  11. package/dist/patternfly-docs/quick-starts/design-guidelines/img/mixed-catalog.png +0 -0
  12. package/dist/patternfly-docs/quick-starts/design-guidelines/img/prerequisites.png +0 -0
  13. package/dist/patternfly-docs/quick-starts/design-guidelines/img/qs-context.png +0 -0
  14. package/dist/patternfly-docs/quick-starts/design-guidelines/img/side-panel-elements.png +0 -0
  15. package/dist/patternfly-docs/quick-starts/design-guidelines/img/side-panel-resized.png +0 -0
  16. package/dist/patternfly-docs/quick-starts/design-guidelines/img/side-panel.png +0 -0
  17. package/dist/patternfly-docs/quick-starts/design-guidelines/img/task-no.png +0 -0
  18. package/dist/patternfly-docs/quick-starts/design-guidelines/img/task-yes.png +0 -0
  19. package/dist/patternfly-docs/quick-starts/design-guidelines/img/task.png +0 -0
  20. package/dist/patternfly-docs/quick-starts/examples/Basic.jsx +73 -0
  21. package/dist/patternfly-docs/quick-starts/examples/HelpTopic.jsx +53 -0
  22. package/dist/patternfly-docs/quick-starts/examples/about.md +77 -0
  23. package/dist/patternfly-docs/quick-starts/examples/basic.md +27 -0
  24. package/dist/patternfly-docs/quick-starts/examples/example-data/example-help-topics.js +173 -0
  25. package/dist/patternfly-docs/quick-starts/examples/example-data/example-quickstarts.js +215 -0
  26. package/dist/patternfly-docs/quick-starts/examples/example-data/index.js +15 -0
  27. package/dist/patternfly-docs/quick-starts/examples/help-topics.md +25 -0
  28. package/dist/patternfly-docs/quick-starts/examples/img/catalog.png +0 -0
  29. package/dist/patternfly-docs/quick-starts/examples/img/help-topic.png +0 -0
  30. package/dist/patternfly-docs/quick-starts/examples/img/side-panel.png +0 -0
  31. package/dist/quickstarts-full.es.js.map +1 -1
  32. package/package.json +11 -4
  33. package/src/ConsoleInternal/components/_icon-and-text.scss +14 -0
  34. package/src/ConsoleInternal/components/_markdown-view.scss +19 -0
  35. package/src/ConsoleInternal/components/catalog/_catalog.scss +390 -0
  36. package/src/ConsoleInternal/components/markdown-view.tsx +305 -0
  37. package/src/ConsoleInternal/components/utils/_status-box.scss +58 -0
  38. package/src/ConsoleInternal/components/utils/camel-case-wrap.tsx +33 -0
  39. package/src/ConsoleInternal/components/utils/index.tsx +3 -0
  40. package/src/ConsoleInternal/components/utils/router.ts +47 -0
  41. package/src/ConsoleInternal/components/utils/status-box.tsx +94 -0
  42. package/src/ConsoleInternal/module/k8s/types.ts +53 -0
  43. package/src/ConsoleShared/index.ts +1 -0
  44. package/src/ConsoleShared/src/components/index.ts +7 -0
  45. package/src/ConsoleShared/src/components/layout/PageLayout.scss +29 -0
  46. package/src/ConsoleShared/src/components/markdown-extensions/MarkdownCopyClipboard.tsx +93 -0
  47. package/src/ConsoleShared/src/components/markdown-extensions/__tests__/MarkdownCopyClipboard.spec.tsx +25 -0
  48. package/src/ConsoleShared/src/components/markdown-extensions/__tests__/test-data.ts +5 -0
  49. package/src/ConsoleShared/src/components/markdown-extensions/admonition-extension.tsx +66 -0
  50. package/src/ConsoleShared/src/components/markdown-extensions/code-extension.tsx +25 -0
  51. package/src/ConsoleShared/src/components/markdown-extensions/const.ts +3 -0
  52. package/src/ConsoleShared/src/components/markdown-extensions/index.ts +5 -0
  53. package/src/ConsoleShared/src/components/markdown-extensions/inline-clipboard-extension.tsx +45 -0
  54. package/src/ConsoleShared/src/components/markdown-extensions/multiline-clipboard-extension.tsx +50 -0
  55. package/src/ConsoleShared/src/components/markdown-extensions/showdown-extension.scss +52 -0
  56. package/src/ConsoleShared/src/components/markdown-extensions/utils.ts +3 -0
  57. package/src/ConsoleShared/src/components/markdown-highlight-extension/MarkdownHighlightExtension.tsx +64 -0
  58. package/src/ConsoleShared/src/components/markdown-highlight-extension/highlight-consts.ts +9 -0
  59. package/src/ConsoleShared/src/components/markdown-highlight-extension/index.ts +1 -0
  60. package/src/ConsoleShared/src/components/modal/Modal.scss +3 -0
  61. package/src/ConsoleShared/src/components/modal/Modal.tsx +19 -0
  62. package/src/ConsoleShared/src/components/modal/index.ts +1 -0
  63. package/src/ConsoleShared/src/components/popper/Portal.tsx +23 -0
  64. package/src/ConsoleShared/src/components/popper/SimplePopper.tsx +90 -0
  65. package/src/ConsoleShared/src/components/popper/index.ts +2 -0
  66. package/src/ConsoleShared/src/components/spotlight/InteractiveSpotlight.tsx +58 -0
  67. package/src/ConsoleShared/src/components/spotlight/Spotlight.tsx +35 -0
  68. package/src/ConsoleShared/src/components/spotlight/StaticSpotlight.tsx +32 -0
  69. package/src/ConsoleShared/src/components/spotlight/index.ts +1 -0
  70. package/src/ConsoleShared/src/components/spotlight/spotlight.scss +63 -0
  71. package/src/ConsoleShared/src/components/status/GenericStatus.tsx +33 -0
  72. package/src/ConsoleShared/src/components/status/NotStartedIcon.tsx +27 -0
  73. package/src/ConsoleShared/src/components/status/PopoverStatus.tsx +42 -0
  74. package/src/ConsoleShared/src/components/status/Status.tsx +38 -0
  75. package/src/ConsoleShared/src/components/status/StatusIconAndText.tsx +42 -0
  76. package/src/ConsoleShared/src/components/status/icons.tsx +77 -0
  77. package/src/ConsoleShared/src/components/status/index.tsx +1 -0
  78. package/src/ConsoleShared/src/components/status/statuses.tsx +36 -0
  79. package/src/ConsoleShared/src/components/status/types.ts +7 -0
  80. package/src/ConsoleShared/src/components/utils/FallbackImg.tsx +20 -0
  81. package/src/ConsoleShared/src/components/utils/index.ts +1 -0
  82. package/src/ConsoleShared/src/constants/index.ts +1 -0
  83. package/src/ConsoleShared/src/constants/ui.ts +1 -0
  84. package/src/ConsoleShared/src/hooks/index.ts +6 -0
  85. package/src/ConsoleShared/src/hooks/scroll.ts +52 -0
  86. package/src/ConsoleShared/src/hooks/useBoundingClientRect.ts +18 -0
  87. package/src/ConsoleShared/src/hooks/useEventListener.ts +14 -0
  88. package/src/ConsoleShared/src/hooks/useForceRender.ts +6 -0
  89. package/src/ConsoleShared/src/hooks/useResizeObserver.ts +20 -0
  90. package/src/ConsoleShared/src/hooks/useScrollShadows.ts +45 -0
  91. package/src/ConsoleShared/src/index.ts +4 -0
  92. package/src/ConsoleShared/src/utils/index.ts +1 -0
  93. package/src/ConsoleShared/src/utils/useCombineRefs.ts +17 -0
  94. package/src/HelpTopicDrawer.tsx +124 -0
  95. package/src/HelpTopicPanelContent.tsx +152 -0
  96. package/src/QuickStartCatalogPage.tsx +190 -0
  97. package/src/QuickStartCloseModal.tsx +47 -0
  98. package/src/QuickStartController.tsx +113 -0
  99. package/src/QuickStartDrawer.scss +11 -0
  100. package/src/QuickStartDrawer.tsx +265 -0
  101. package/src/QuickStartMarkdownView.tsx +75 -0
  102. package/src/QuickStartPanelContent.scss +46 -0
  103. package/src/QuickStartPanelContent.tsx +153 -0
  104. package/src/__tests__/quick-start-utils.spec.tsx +16 -0
  105. package/src/catalog/Catalog/QuickStartCatalogHeader.tsx +18 -0
  106. package/src/catalog/Catalog/QuickStartCatalogSection.tsx +9 -0
  107. package/src/catalog/Catalog/QuickStartCatalogToolbar.tsx +12 -0
  108. package/src/catalog/Catalog/index.ts +3 -0
  109. package/src/catalog/QuickStartCatalog.scss +8 -0
  110. package/src/catalog/QuickStartCatalog.tsx +42 -0
  111. package/src/catalog/QuickStartTile.scss +11 -0
  112. package/src/catalog/QuickStartTile.tsx +105 -0
  113. package/src/catalog/QuickStartTileDescription.scss +29 -0
  114. package/src/catalog/QuickStartTileDescription.tsx +79 -0
  115. package/src/catalog/QuickStartTileFooter.tsx +101 -0
  116. package/src/catalog/QuickStartTileFooterExternal.tsx +40 -0
  117. package/src/catalog/QuickStartTileHeader.scss +12 -0
  118. package/src/catalog/QuickStartTileHeader.tsx +77 -0
  119. package/src/catalog/Toolbar/QuickStartCatalogFilter.scss +25 -0
  120. package/src/catalog/Toolbar/QuickStartCatalogFilter.tsx +34 -0
  121. package/src/catalog/Toolbar/QuickStartCatalogFilterItems.tsx +199 -0
  122. package/src/catalog/__tests__/QuickStartCatalog.spec.tsx +35 -0
  123. package/src/catalog/__tests__/QuickStartTile.spec.tsx +38 -0
  124. package/src/catalog/__tests__/QuickStartTileDescription.spec.tsx +44 -0
  125. package/src/catalog/index.ts +9 -0
  126. package/src/controller/QuickStartConclusion.tsx +63 -0
  127. package/src/controller/QuickStartContent.scss +12 -0
  128. package/src/controller/QuickStartContent.tsx +72 -0
  129. package/src/controller/QuickStartFooter.scss +13 -0
  130. package/src/controller/QuickStartFooter.tsx +128 -0
  131. package/src/controller/QuickStartIntroduction.scss +35 -0
  132. package/src/controller/QuickStartIntroduction.tsx +66 -0
  133. package/src/controller/QuickStartTaskHeader.scss +58 -0
  134. package/src/controller/QuickStartTaskHeader.tsx +116 -0
  135. package/src/controller/QuickStartTaskHeaderList.scss +17 -0
  136. package/src/controller/QuickStartTaskHeaderList.tsx +35 -0
  137. package/src/controller/QuickStartTaskReview.scss +30 -0
  138. package/src/controller/QuickStartTaskReview.tsx +81 -0
  139. package/src/controller/QuickStartTasks.scss +89 -0
  140. package/src/controller/QuickStartTasks.tsx +75 -0
  141. package/src/controller/__tests__/QuickStartConclusion.spec.tsx +95 -0
  142. package/src/controller/__tests__/QuickStartContent.spec.tsx +52 -0
  143. package/src/controller/__tests__/QuickStartFooter.spec.tsx +148 -0
  144. package/src/controller/__tests__/QuickStartTaskHeader.spec.tsx +56 -0
  145. package/src/controller/__tests__/QuickStartTaskReview.spec.tsx +45 -0
  146. package/src/controller/__tests__/QuickStartTasks.spec.tsx +81 -0
  147. package/src/data/mocks/json/explore-pipeline-quickstart.ts +66 -0
  148. package/src/data/mocks/json/explore-serverless-quickstart.ts +90 -0
  149. package/src/data/mocks/json/monitor-sampleapp-quickstart.ts +77 -0
  150. package/src/data/mocks/json/tour-icons.ts +3 -0
  151. package/src/data/mocks/yamls/add-healthchecks-quickstart.yaml +67 -0
  152. package/src/data/mocks/yamls/explore-pipeline-quickstart.yaml +57 -0
  153. package/src/data/mocks/yamls/explore-serverless-quickstart.yaml +83 -0
  154. package/src/data/mocks/yamls/install-associate-pipeline-quickstart.yaml +74 -0
  155. package/src/data/mocks/yamls/monitor-sampleapp-quickstart.yaml +66 -0
  156. package/src/data/mocks/yamls/sample-application-quickstart.yaml +97 -0
  157. package/src/data/mocks/yamls/serverless-application-quickstart.yaml +141 -0
  158. package/src/data/quick-start-test-data.ts +10 -0
  159. package/src/data/test-utils.ts +11 -0
  160. package/src/declaration.d.ts +2 -0
  161. package/src/index.ts +17 -0
  162. package/src/locales/en/quickstart.json +46 -0
  163. package/src/styles/_base.scss +54 -0
  164. package/src/styles/_dark-custom-override.scss +62 -0
  165. package/src/styles/legacy-bootstrap/README.md +21 -0
  166. package/src/styles/legacy-bootstrap/_code.scss +44 -0
  167. package/src/styles/legacy-bootstrap/_tables.scss +38 -0
  168. package/src/styles/legacy-bootstrap/_type.scss +90 -0
  169. package/src/styles/legacy-bootstrap/_variables.scss +48 -0
  170. package/src/styles/legacy-bootstrap.scss +5 -0
  171. package/src/styles/patternfly-global-entry.ts +1 -0
  172. package/src/styles/patternfly-global.scss +28 -0
  173. package/src/styles/patternfly-nested-entry.ts +1 -0
  174. package/src/styles/patternfly-nested.scss +18 -0
  175. package/src/styles/quickstarts-standalone-entry.ts +1 -0
  176. package/src/styles/quickstarts-standalone.scss +7 -0
  177. package/src/styles/style.scss +12 -0
  178. package/src/styles/vendor-entry.ts +1 -0
  179. package/src/styles/vendor.scss +7 -0
  180. package/src/utils/PluralResolver.ts +356 -0
  181. package/src/utils/asciidoc-procedure-parser.ts +132 -0
  182. package/src/utils/const.ts +10 -0
  183. package/src/utils/help-topic-context.tsx +74 -0
  184. package/src/utils/help-topic-types.ts +16 -0
  185. package/src/utils/quick-start-context.tsx +477 -0
  186. package/src/utils/quick-start-types.ts +72 -0
  187. package/src/utils/quick-start-utils.ts +92 -0
  188. package/src/utils/useLocalStorage.ts +38 -0
@@ -0,0 +1,17 @@
1
+ import * as React from 'react';
2
+
3
+ export const useCombineRefs = <RefType extends any>(...refs: (React.Ref<RefType> | undefined)[]) =>
4
+ React.useCallback(
5
+ (element: RefType | null): void =>
6
+ refs.forEach((ref) => {
7
+ if (ref) {
8
+ if (typeof ref === 'function') {
9
+ ref(element);
10
+ } else {
11
+ (ref as React.MutableRefObject<any>).current = element;
12
+ }
13
+ }
14
+ }),
15
+ // eslint-disable-next-line react-hooks/exhaustive-deps
16
+ refs,
17
+ );
@@ -0,0 +1,124 @@
1
+ import './QuickStartDrawer.scss';
2
+ import * as React from 'react';
3
+ import { Drawer, DrawerContent, DrawerContentBody } from '@patternfly/react-core';
4
+ import HelpTopicPanelContent from './HelpTopicPanelContent';
5
+ import {
6
+ HelpTopicContext,
7
+ HelpTopicContextValues,
8
+ useValuesForHelpTopicContext,
9
+ } from './utils/help-topic-context';
10
+ import { QuickStartContextValues } from './utils/quick-start-context';
11
+ import { HelpTopic } from './utils/help-topic-types';
12
+
13
+ export interface HelpTopicContainerProps extends React.HTMLProps<HTMLDivElement> {
14
+ /** array of HelpTopics */
15
+ helpTopics: HelpTopic[];
16
+ /** text resources object
17
+ * Add custom strings: https://github.com/patternfly/patternfly-quickstarts/tree/main/packages/module#localization
18
+ */
19
+ resourceBundle?: any;
20
+ /** language of the current resource bundle */
21
+ language?: string;
22
+ /** if true, will show a loading spinner on the catalog page (default false) */
23
+ loading?: boolean;
24
+ /**
25
+ * Additional markdown extensions and renderers to use
26
+ * Example usage: https://github.com/patternfly/patternfly-quickstarts/tree/main/packages/module#markdown-extensions
27
+ */
28
+ markdown?: {
29
+ extensions?: any[];
30
+ renderExtension?: (docContext: HTMLDocument, rootSelector: string) => React.ReactNode;
31
+ };
32
+ /** additional quick start context props */
33
+ contextProps?: QuickStartContextValues;
34
+ }
35
+
36
+ export const HelpTopicContainer: React.FC<HelpTopicContainerProps> = ({
37
+ helpTopics,
38
+ children,
39
+ resourceBundle,
40
+ language,
41
+ loading = false,
42
+ markdown,
43
+ contextProps,
44
+ ...props
45
+ }: HelpTopicContainerProps) => {
46
+ const valuesForHelpTopicContext: HelpTopicContextValues = useValuesForHelpTopicContext({
47
+ helpTopics,
48
+ language,
49
+ resourceBundle: {
50
+ ...resourceBundle,
51
+ // Start: "Let's go!",
52
+ // Continue: 'Resume',
53
+ // Restart: 'Start over',
54
+ },
55
+ loading,
56
+ markdown,
57
+ ...contextProps,
58
+ });
59
+
60
+ React.useEffect(() => {
61
+ if (loading !== valuesForHelpTopicContext.loading) {
62
+ valuesForHelpTopicContext.setLoading(loading);
63
+ }
64
+ }, [loading, valuesForHelpTopicContext]);
65
+
66
+ React.useEffect(() => {
67
+ if (
68
+ helpTopics &&
69
+ JSON.stringify(helpTopics) !== JSON.stringify(valuesForHelpTopicContext.helpTopics)
70
+ ) {
71
+ valuesForHelpTopicContext.setHelpTopics(helpTopics);
72
+ }
73
+ }, [helpTopics, valuesForHelpTopicContext]);
74
+
75
+ const drawerProps = {
76
+ //TODO add extras here?
77
+ ...props,
78
+ };
79
+
80
+ return (
81
+ <HelpTopicContext.Provider value={valuesForHelpTopicContext}>
82
+ <HelpTopicDrawer {...drawerProps}>{children}</HelpTopicDrawer>
83
+ </HelpTopicContext.Provider>
84
+ );
85
+ };
86
+
87
+ export interface HelpTopicDrawerProps extends React.HTMLProps<HTMLDivElement> {
88
+ helpTopics?: HelpTopic[];
89
+ children?: React.ReactNode;
90
+ }
91
+
92
+ export const HelpTopicDrawer: React.FC<HelpTopicDrawerProps> = ({ children, ...props }) => {
93
+ const { activeHelpTopic, filteredHelpTopics, setActiveHelpTopicByName } = React.useContext<
94
+ HelpTopicContextValues
95
+ >(HelpTopicContext);
96
+
97
+ const onClose = () => {
98
+ setActiveHelpTopicByName('');
99
+ };
100
+
101
+ const panelContent = (
102
+ <HelpTopicPanelContent
103
+ activeHelpTopic={activeHelpTopic}
104
+ filteredHelpTopics={filteredHelpTopics}
105
+ onClose={onClose}
106
+ />
107
+ );
108
+
109
+ return (
110
+ <>
111
+ <Drawer isExpanded={!!activeHelpTopic} isInline {...props}>
112
+ {children ? (
113
+ <DrawerContent panelContent={panelContent}>
114
+ <DrawerContentBody className="pfext-quick-start-drawer__body">
115
+ {children}
116
+ </DrawerContentBody>
117
+ </DrawerContent>
118
+ ) : (
119
+ <div className="pf-c-drawer__main">{panelContent}</div>
120
+ )}
121
+ </Drawer>
122
+ </>
123
+ );
124
+ };
@@ -0,0 +1,152 @@
1
+ import * as React from 'react';
2
+ import {
3
+ Button,
4
+ Divider,
5
+ DrawerActions,
6
+ DrawerCloseButton,
7
+ DrawerHead,
8
+ DrawerPanelBody,
9
+ DrawerPanelContent,
10
+ OptionsMenu,
11
+ OptionsMenuItem,
12
+ OptionsMenuToggle,
13
+ Stack,
14
+ StackItem,
15
+ Title,
16
+ } from '@patternfly/react-core';
17
+
18
+ import QuickStartMarkdownView from './QuickStartMarkdownView';
19
+ import { HelpTopic } from './utils/help-topic-types';
20
+ import BarsIcon from '@patternfly/react-icons/dist/js/icons/bars-icon';
21
+ import ExternalLinkAltIcon from '@patternfly/react-icons/dist/js/icons/external-link-alt-icon';
22
+
23
+ import './QuickStartPanelContent.scss';
24
+ import { HelpTopicContext, HelpTopicContextValues } from './utils/help-topic-context';
25
+
26
+ type HelpTopicPanelContentProps = {
27
+ activeHelpTopic: HelpTopic;
28
+ filteredHelpTopics?: HelpTopic[];
29
+ isResizable?: boolean;
30
+ onClose: () => void;
31
+ };
32
+
33
+ const HelpTopicPanelContent: React.FC<HelpTopicPanelContentProps> = ({
34
+ activeHelpTopic = null,
35
+ filteredHelpTopics = [],
36
+ isResizable = true,
37
+ onClose,
38
+ ...props
39
+ }) => {
40
+ const { setActiveHelpTopicByName } = React.useContext<HelpTopicContextValues>(HelpTopicContext);
41
+
42
+ const [isHelpTopicMenuOpen, setIsHelpTopicMenuOpen] = React.useState(false);
43
+
44
+ const toggleHelpTopicMenu = () => {
45
+ setIsHelpTopicMenuOpen(!isHelpTopicMenuOpen);
46
+ };
47
+
48
+ const onSelectHelpTopic = (event) => {
49
+ const topicName = event.currentTarget.id;
50
+ setActiveHelpTopicByName(topicName);
51
+ toggleHelpTopicMenu();
52
+ };
53
+
54
+ const menuItems =
55
+ filteredHelpTopics.length > 0 &&
56
+ filteredHelpTopics.map((topic) => {
57
+ return (
58
+ <OptionsMenuItem key={topic.name} onSelect={onSelectHelpTopic} id={topic.name}>
59
+ {topic.title}
60
+ </OptionsMenuItem>
61
+ );
62
+ });
63
+
64
+ const paddingContainer = (children) => <div style={{ padding: '24px' }}>{children}</div>;
65
+
66
+ const panelBodyItems = (
67
+ <>
68
+ {paddingContainer(<QuickStartMarkdownView content={activeHelpTopic?.content} />)}
69
+ {activeHelpTopic?.links?.length && <Divider />}
70
+ {paddingContainer(
71
+ <Stack hasGutter>
72
+ {activeHelpTopic?.links?.map(({ href, text, newTab, isExternal }, index) => {
73
+ return (
74
+ <StackItem key={index}>
75
+ <Button
76
+ component="a"
77
+ href={href}
78
+ target={newTab ? '_blank' : ''}
79
+ rel="noopener noreferrer"
80
+ variant="link"
81
+ aria-label={`Open documentation in new window`}
82
+ isInline
83
+ icon={isExternal ? <ExternalLinkAltIcon /> : null}
84
+ iconPosition="right"
85
+ style={{ fontSize: 'inherit' }}
86
+ >
87
+ {text || href}
88
+ </Button>
89
+ </StackItem>
90
+ );
91
+ })}
92
+ </Stack>,
93
+ )}
94
+ </>
95
+ );
96
+
97
+ const content = (
98
+ <DrawerPanelContent isResizable={isResizable} className="pfext-quick-start__base" {...props}>
99
+ <div>
100
+ <DrawerHead>
101
+ <div className="pfext-quick-start-panel-content__title">
102
+ {menuItems && (
103
+ <OptionsMenu
104
+ id={'helptopics'}
105
+ isPlain
106
+ isOpen={isHelpTopicMenuOpen}
107
+ toggle={
108
+ <OptionsMenuToggle
109
+ style={{ paddingLeft: '0px' }}
110
+ onToggle={toggleHelpTopicMenu}
111
+ toggleTemplate={<BarsIcon />}
112
+ />
113
+ }
114
+ menuItems={menuItems}
115
+ />
116
+ )}
117
+
118
+ <Title
119
+ headingLevel="h1"
120
+ size="xl"
121
+ className="pfext-quick-start-panel-content__name"
122
+ style={{ marginRight: 'var(--pf-global--spacer--md)' }}
123
+ >
124
+ {activeHelpTopic?.title}
125
+ </Title>
126
+ </div>
127
+ {
128
+ <DrawerActions>
129
+ <DrawerCloseButton
130
+ onClick={onClose}
131
+ className="pfext-quick-start-panel-content__close-button"
132
+ data-testid="qs-drawer-close"
133
+ />
134
+ </DrawerActions>
135
+ }
136
+ </DrawerHead>
137
+ <Divider />
138
+ <DrawerPanelBody
139
+ hasNoPadding
140
+ className="pfext-quick-start-panel-content__body"
141
+ data-test="content"
142
+ >
143
+ {panelBodyItems}
144
+ </DrawerPanelBody>
145
+ </div>
146
+ </DrawerPanelContent>
147
+ );
148
+
149
+ return content;
150
+ };
151
+
152
+ export default HelpTopicPanelContent;
@@ -0,0 +1,190 @@
1
+ import * as React from 'react';
2
+ import {
3
+ Button,
4
+ Divider,
5
+ EmptyState,
6
+ EmptyStateBody,
7
+ EmptyStateIcon,
8
+ EmptyStatePrimary,
9
+ Text,
10
+ Title,
11
+ } from '@patternfly/react-core';
12
+ import SearchIcon from '@patternfly/react-icons/dist/js/icons/search-icon';
13
+ import { EmptyBox, LoadingBox, clearFilterParams } from '@console/internal/components/utils';
14
+ import QuickStartCatalog from './catalog/QuickStartCatalog';
15
+ import QuickStartCatalogFilter from './catalog/Toolbar/QuickStartCatalogFilter';
16
+ import { QuickStartContext, QuickStartContextValues } from './utils/quick-start-context';
17
+ import { QuickStart } from './utils/quick-start-types';
18
+ import { filterQuickStarts } from './utils/quick-start-utils';
19
+
20
+ export type QuickStartCatalogPageProps = {
21
+ quickStarts?: QuickStart[];
22
+ showFilter?: boolean;
23
+ sortFnc?: (q1: QuickStart, q2: QuickStart) => number;
24
+ title?: string;
25
+ hint?: string;
26
+ showTitle?: boolean;
27
+ };
28
+
29
+ export const QuickStartCatalogEmptyState = ({ clearFilters }) => {
30
+ const { getResource } = React.useContext<QuickStartContextValues>(QuickStartContext);
31
+ return (
32
+ <EmptyState>
33
+ <EmptyStateIcon icon={SearchIcon} />
34
+ <Title size="lg" headingLevel="h4">
35
+ {getResource('No results found')}
36
+ </Title>
37
+ <EmptyStateBody>
38
+ {getResource(
39
+ 'No results match the filter criteria. Remove filters or clear all filters to show results.',
40
+ )}
41
+ </EmptyStateBody>
42
+ <EmptyStatePrimary>
43
+ <Button variant="link" onClick={clearFilters} data-test="clear-filter button">
44
+ {getResource('Clear all filters')}
45
+ </Button>
46
+ </EmptyStatePrimary>
47
+ </EmptyState>
48
+ );
49
+ };
50
+
51
+ export const QuickStartCatalogPage: React.FC<QuickStartCatalogPageProps> = ({
52
+ quickStarts,
53
+ showFilter,
54
+ sortFnc = (q1, q2) => q1.spec.displayName.localeCompare(q2.spec.displayName),
55
+ title,
56
+ hint,
57
+ showTitle = true,
58
+ }) => {
59
+ const sortFncCallback = React.useCallback(sortFnc, []);
60
+ const {
61
+ allQuickStarts = [],
62
+ setAllQuickStarts,
63
+ allQuickStartStates,
64
+ getResource,
65
+ filter,
66
+ setFilter,
67
+ loading,
68
+ } = React.useContext<QuickStartContextValues>(QuickStartContext);
69
+
70
+ React.useEffect(() => {
71
+ // passed through prop, not context
72
+ if (quickStarts && JSON.stringify(quickStarts) !== JSON.stringify(allQuickStarts)) {
73
+ setAllQuickStarts(quickStarts);
74
+ }
75
+ }, [quickStarts, allQuickStarts, setAllQuickStarts]);
76
+
77
+ const initialFilteredQuickStarts = showFilter
78
+ ? filterQuickStarts(
79
+ allQuickStarts,
80
+ filter.keyword,
81
+ filter.status.statusFilters,
82
+ allQuickStartStates,
83
+ ).sort(sortFncCallback)
84
+ : allQuickStarts;
85
+
86
+ const [filteredQuickStarts, setFilteredQuickStarts] = React.useState(initialFilteredQuickStarts);
87
+ React.useEffect(() => {
88
+ const filteredQs = showFilter
89
+ ? filterQuickStarts(
90
+ allQuickStarts,
91
+ filter.keyword,
92
+ filter.status.statusFilters,
93
+ allQuickStartStates,
94
+ ).sort(sortFncCallback)
95
+ : allQuickStarts;
96
+ // also needs a check whether the content of the QS changed
97
+ if (
98
+ filteredQs.length !== filteredQuickStarts.length ||
99
+ JSON.stringify(filteredQs) !== JSON.stringify(filteredQuickStarts)
100
+ ) {
101
+ setFilteredQuickStarts(filteredQs);
102
+ }
103
+ }, [
104
+ allQuickStarts,
105
+ allQuickStartStates,
106
+ showFilter,
107
+ filter.keyword,
108
+ filter.status.statusFilters,
109
+ sortFncCallback,
110
+ filteredQuickStarts,
111
+ ]);
112
+
113
+ const clearFilters = () => {
114
+ setFilter('keyword', '');
115
+ setFilter('status', []);
116
+ clearFilterParams();
117
+ setFilteredQuickStarts(
118
+ allQuickStarts.sort((q1, q2) => q1.spec.displayName.localeCompare(q2.spec.displayName)),
119
+ );
120
+ };
121
+
122
+ const onSearchInputChange = (searchValue) => {
123
+ const result = filterQuickStarts(
124
+ allQuickStarts,
125
+ searchValue,
126
+ filter.status.statusFilters,
127
+ allQuickStartStates,
128
+ ).sort((q1, q2) => q1.spec.displayName.localeCompare(q2.spec.displayName));
129
+ if (searchValue !== filter.keyword) {
130
+ setFilter('keyword', searchValue);
131
+ }
132
+ if (result.length !== filteredQuickStarts.length) {
133
+ setFilteredQuickStarts(result);
134
+ }
135
+ };
136
+
137
+ const onStatusChange = (statusList) => {
138
+ const result = filterQuickStarts(
139
+ allQuickStarts,
140
+ filter.keyword,
141
+ statusList,
142
+ allQuickStartStates,
143
+ ).sort((q1, q2) => q1.spec.displayName.localeCompare(q2.spec.displayName));
144
+ if (JSON.stringify(statusList) !== JSON.stringify(filter.status)) {
145
+ setFilter('status', statusList);
146
+ }
147
+ if (result.length !== filteredQuickStarts.length) {
148
+ setFilteredQuickStarts(result);
149
+ }
150
+ };
151
+
152
+ if (loading) {
153
+ return <LoadingBox />;
154
+ }
155
+
156
+ if (!allQuickStarts || allQuickStarts.length === 0) {
157
+ return <EmptyBox label={getResource('Quick Starts')} />;
158
+ }
159
+
160
+ return (
161
+ <div className="pfext-quick-start__base">
162
+ {showTitle && (
163
+ <div className="pfext-page-layout__header">
164
+ <Text component="h1" className="pfext-page-layout__title" data-test="page-title">
165
+ {title || getResource('Quick Starts')}
166
+ </Text>
167
+ {hint && <div className="pfext-page-layout__hint">{hint}</div>}
168
+ </div>
169
+ )}
170
+ {showTitle && <Divider component="div" />}
171
+ {showFilter && (
172
+ <>
173
+ <QuickStartCatalogFilter
174
+ quickStartsCount={filteredQuickStarts.length}
175
+ onSearchInputChange={onSearchInputChange}
176
+ onStatusChange={onStatusChange}
177
+ />
178
+ <Divider component="div" />
179
+ </>
180
+ )}
181
+ <>
182
+ {filteredQuickStarts.length === 0 ? (
183
+ <QuickStartCatalogEmptyState clearFilters={clearFilters} />
184
+ ) : (
185
+ <QuickStartCatalog quickStarts={filteredQuickStarts} />
186
+ )}
187
+ </>
188
+ </div>
189
+ );
190
+ };
@@ -0,0 +1,47 @@
1
+ import * as React from 'react';
2
+ import { Button, Flex, FlexItem, ModalVariant } from '@patternfly/react-core';
3
+ import { Modal } from '@console/shared';
4
+ import { QuickStartContext, QuickStartContextValues } from './utils/quick-start-context';
5
+
6
+ type QuickStartCloseModalProps = {
7
+ isOpen: boolean;
8
+ onConfirm: () => void;
9
+ onCancel: () => void;
10
+ };
11
+
12
+ const QuickStartCloseModal: React.FC<QuickStartCloseModalProps> = ({
13
+ isOpen,
14
+ onConfirm,
15
+ onCancel,
16
+ }) => {
17
+ const { getResource } = React.useContext<QuickStartContextValues>(QuickStartContext);
18
+ return (
19
+ <Modal
20
+ className="pfext-quick-start-drawer__modal pfext-quick-start__base"
21
+ isOpen={isOpen}
22
+ variant={ModalVariant.small}
23
+ showClose={false}
24
+ data-test="leave-quickstart"
25
+ title={getResource('Leave quick start?')}
26
+ footer={
27
+ <Flex>
28
+ <FlexItem align={{ default: 'alignRight' }}>
29
+ <Button variant="secondary" data-test="cancel button" onClick={onCancel}>
30
+ {getResource('Cancel')}
31
+ </Button>
32
+ </FlexItem>
33
+ <FlexItem>
34
+ <Button variant="primary" data-test="leave button" onClick={onConfirm}>
35
+ {getResource('Leave')}
36
+ </Button>
37
+ </FlexItem>
38
+ </Flex>
39
+ }
40
+ isFullScreen
41
+ >
42
+ {getResource('Your progress will be saved.')}
43
+ </Modal>
44
+ );
45
+ };
46
+
47
+ export default QuickStartCloseModal;
@@ -0,0 +1,113 @@
1
+ import * as React from 'react';
2
+ import QuickStartContent from './controller/QuickStartContent';
3
+ import QuickStartFooter from './controller/QuickStartFooter';
4
+ import { QuickStartContext, QuickStartContextValues } from './utils/quick-start-context';
5
+ import { QuickStart, QuickStartStatus, QuickStartTaskStatus } from './utils/quick-start-types';
6
+
7
+ type QuickStartControllerProps = {
8
+ quickStart: QuickStart;
9
+ nextQuickStarts?: QuickStart[];
10
+ footerClass: string;
11
+ contentRef: React.Ref<HTMLDivElement>;
12
+ };
13
+
14
+ const QuickStartController: React.FC<QuickStartControllerProps> = ({
15
+ quickStart,
16
+ nextQuickStarts,
17
+ contentRef,
18
+ footerClass,
19
+ }) => {
20
+ const {
21
+ metadata: { name },
22
+ spec: { tasks = [] },
23
+ } = quickStart;
24
+ const totalTasks = tasks?.length;
25
+ const {
26
+ activeQuickStartState,
27
+ setActiveQuickStart,
28
+ setQuickStartTaskNumber,
29
+ setQuickStartTaskStatus,
30
+ nextStep,
31
+ previousStep,
32
+ } = React.useContext<QuickStartContextValues>(QuickStartContext);
33
+ const status = activeQuickStartState?.status as QuickStartStatus;
34
+ const taskNumber = activeQuickStartState?.taskNumber as number;
35
+ const allTaskStatuses = tasks.map(
36
+ (task, index) => activeQuickStartState[`taskStatus${index}`],
37
+ ) as QuickStartTaskStatus[];
38
+
39
+ const handleQuickStartChange = React.useCallback(
40
+ (quickStartId: string) => setActiveQuickStart(quickStartId),
41
+ [setActiveQuickStart],
42
+ );
43
+
44
+ const handleTaskStatusChange = React.useCallback(
45
+ (newTaskStatus: QuickStartTaskStatus) => setQuickStartTaskStatus(newTaskStatus),
46
+ [setQuickStartTaskStatus],
47
+ );
48
+
49
+ const getQuickStartActiveTask = React.useCallback(() => {
50
+ let activeTaskNumber = 0;
51
+ while (
52
+ activeTaskNumber !== totalTasks &&
53
+ activeQuickStartState[`taskStatus${activeTaskNumber}`] !== QuickStartTaskStatus.INIT
54
+ ) {
55
+ activeTaskNumber++;
56
+ }
57
+ return activeTaskNumber;
58
+ }, [totalTasks, activeQuickStartState]);
59
+
60
+ const handleQuickStartContinue = React.useCallback(() => {
61
+ const activeTaskNumber = getQuickStartActiveTask();
62
+ setQuickStartTaskNumber(name, activeTaskNumber);
63
+ }, [getQuickStartActiveTask, setQuickStartTaskNumber, name]);
64
+
65
+ const handleNext = React.useCallback(() => {
66
+ if (status === QuickStartStatus.COMPLETE && taskNumber === totalTasks) {
67
+ return handleQuickStartChange('');
68
+ }
69
+
70
+ if (status !== QuickStartStatus.NOT_STARTED && taskNumber === -1) {
71
+ return handleQuickStartContinue();
72
+ }
73
+
74
+ return nextStep(totalTasks);
75
+ }, [handleQuickStartChange, nextStep, status, taskNumber, totalTasks, handleQuickStartContinue]);
76
+
77
+ const handleBack = React.useCallback(() => {
78
+ return previousStep();
79
+ }, [previousStep]);
80
+
81
+ const handleTaskSelect = React.useCallback(
82
+ (selectedTaskNumber: number) => {
83
+ setQuickStartTaskNumber(name, selectedTaskNumber);
84
+ },
85
+ [name, setQuickStartTaskNumber],
86
+ );
87
+
88
+ return (
89
+ <>
90
+ <QuickStartContent
91
+ quickStart={quickStart}
92
+ nextQuickStarts={nextQuickStarts}
93
+ taskNumber={taskNumber}
94
+ allTaskStatuses={allTaskStatuses}
95
+ onTaskSelect={handleTaskSelect}
96
+ onTaskReview={handleTaskStatusChange}
97
+ onQuickStartChange={handleQuickStartChange}
98
+ ref={contentRef}
99
+ />
100
+ <QuickStartFooter
101
+ status={status}
102
+ taskNumber={taskNumber}
103
+ totalTasks={totalTasks}
104
+ onNext={handleNext}
105
+ onBack={handleBack}
106
+ footerClass={footerClass}
107
+ quickStartId={quickStart.metadata.name}
108
+ />
109
+ </>
110
+ );
111
+ };
112
+
113
+ export default QuickStartController;
@@ -0,0 +1,11 @@
1
+ .pfext-quick-start-drawer {
2
+ &__body {
3
+ display: flex;
4
+ flex-direction: column;
5
+ z-index: 0;
6
+ position: relative;
7
+ }
8
+ &__modal > .pf-c-modal-box__footer {
9
+ display: block;
10
+ }
11
+ }