@patternfly/quickstarts 2.2.1 → 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 (203) hide show
  1. package/README.md +20 -20
  2. package/dist/ConsoleShared/src/components/markdown-extensions/code-extension.d.ts +7 -0
  3. package/dist/ConsoleShared/src/components/markdown-extensions/index.d.ts +1 -0
  4. package/dist/HelpTopicDrawer.d.ts +8 -2
  5. package/dist/QuickStartDrawer.d.ts +21 -2
  6. package/dist/index.d.ts +1 -0
  7. package/dist/index.es.js +127 -21
  8. package/dist/index.es.js.map +1 -1
  9. package/dist/index.js +126 -19
  10. package/dist/index.js.map +1 -1
  11. package/dist/patternfly-docs/quick-starts/design-guidelines/design-guidelines.md +105 -0
  12. package/dist/patternfly-docs/quick-starts/design-guidelines/img/card-elements copy.png +0 -0
  13. package/dist/patternfly-docs/quick-starts/design-guidelines/img/card-elements.png +0 -0
  14. package/dist/patternfly-docs/quick-starts/design-guidelines/img/catalog-elements.png +0 -0
  15. package/dist/patternfly-docs/quick-starts/design-guidelines/img/check-your-work.png +0 -0
  16. package/dist/patternfly-docs/quick-starts/design-guidelines/img/introduction-screen.png +0 -0
  17. package/dist/patternfly-docs/quick-starts/design-guidelines/img/mixed-catalog.png +0 -0
  18. package/dist/patternfly-docs/quick-starts/design-guidelines/img/prerequisites.png +0 -0
  19. package/dist/patternfly-docs/quick-starts/design-guidelines/img/qs-context.png +0 -0
  20. package/dist/patternfly-docs/quick-starts/design-guidelines/img/side-panel-elements.png +0 -0
  21. package/dist/patternfly-docs/quick-starts/design-guidelines/img/side-panel-resized.png +0 -0
  22. package/dist/patternfly-docs/quick-starts/design-guidelines/img/side-panel.png +0 -0
  23. package/dist/patternfly-docs/quick-starts/design-guidelines/img/task-no.png +0 -0
  24. package/dist/patternfly-docs/quick-starts/design-guidelines/img/task-yes.png +0 -0
  25. package/dist/patternfly-docs/quick-starts/design-guidelines/img/task.png +0 -0
  26. package/dist/patternfly-docs/quick-starts/examples/Basic.jsx +73 -0
  27. package/dist/patternfly-docs/quick-starts/examples/HelpTopic.jsx +53 -0
  28. package/dist/patternfly-docs/quick-starts/examples/about.md +77 -0
  29. package/dist/patternfly-docs/quick-starts/examples/basic.md +27 -0
  30. package/dist/patternfly-docs/quick-starts/examples/example-data/example-help-topics.js +173 -0
  31. package/dist/patternfly-docs/quick-starts/examples/example-data/example-quickstarts.js +215 -0
  32. package/dist/patternfly-docs/quick-starts/examples/example-data/index.js +15 -0
  33. package/dist/patternfly-docs/quick-starts/examples/help-topics.md +25 -0
  34. package/dist/patternfly-docs/quick-starts/examples/img/catalog.png +0 -0
  35. package/dist/patternfly-docs/quick-starts/examples/img/help-topic.png +0 -0
  36. package/dist/patternfly-docs/quick-starts/examples/img/side-panel.png +0 -0
  37. package/dist/patternfly-nested.css +11 -1
  38. package/dist/quickstarts-base.css +49 -11
  39. package/dist/quickstarts-full.es.js +451 -305
  40. package/dist/quickstarts-full.es.js.map +1 -1
  41. package/dist/quickstarts-standalone.css +5 -15
  42. package/dist/quickstarts-standalone.min.css +1 -1
  43. package/dist/quickstarts.css +49 -11
  44. package/dist/quickstarts.min.css +1 -1
  45. package/dist/utils/asciidoc-procedure-parser.d.ts +12 -0
  46. package/dist/utils/help-topic-types.d.ts +7 -1
  47. package/package.json +11 -4
  48. package/src/ConsoleInternal/components/_icon-and-text.scss +14 -0
  49. package/src/ConsoleInternal/components/_markdown-view.scss +19 -0
  50. package/src/ConsoleInternal/components/catalog/_catalog.scss +390 -0
  51. package/src/ConsoleInternal/components/markdown-view.tsx +305 -0
  52. package/src/ConsoleInternal/components/utils/_status-box.scss +58 -0
  53. package/src/ConsoleInternal/components/utils/camel-case-wrap.tsx +33 -0
  54. package/src/ConsoleInternal/components/utils/index.tsx +3 -0
  55. package/src/ConsoleInternal/components/utils/router.ts +47 -0
  56. package/src/ConsoleInternal/components/utils/status-box.tsx +94 -0
  57. package/src/ConsoleInternal/module/k8s/types.ts +53 -0
  58. package/src/ConsoleShared/index.ts +1 -0
  59. package/src/ConsoleShared/src/components/index.ts +7 -0
  60. package/src/ConsoleShared/src/components/layout/PageLayout.scss +29 -0
  61. package/src/ConsoleShared/src/components/markdown-extensions/MarkdownCopyClipboard.tsx +93 -0
  62. package/src/ConsoleShared/src/components/markdown-extensions/__tests__/MarkdownCopyClipboard.spec.tsx +25 -0
  63. package/src/ConsoleShared/src/components/markdown-extensions/__tests__/test-data.ts +5 -0
  64. package/src/ConsoleShared/src/components/markdown-extensions/admonition-extension.tsx +66 -0
  65. package/src/ConsoleShared/src/components/markdown-extensions/code-extension.tsx +25 -0
  66. package/src/ConsoleShared/src/components/markdown-extensions/const.ts +3 -0
  67. package/src/ConsoleShared/src/components/markdown-extensions/index.ts +5 -0
  68. package/src/ConsoleShared/src/components/markdown-extensions/inline-clipboard-extension.tsx +45 -0
  69. package/src/ConsoleShared/src/components/markdown-extensions/multiline-clipboard-extension.tsx +50 -0
  70. package/src/ConsoleShared/src/components/markdown-extensions/showdown-extension.scss +52 -0
  71. package/src/ConsoleShared/src/components/markdown-extensions/utils.ts +3 -0
  72. package/src/ConsoleShared/src/components/markdown-highlight-extension/MarkdownHighlightExtension.tsx +64 -0
  73. package/src/ConsoleShared/src/components/markdown-highlight-extension/highlight-consts.ts +9 -0
  74. package/src/ConsoleShared/src/components/markdown-highlight-extension/index.ts +1 -0
  75. package/src/ConsoleShared/src/components/modal/Modal.scss +3 -0
  76. package/src/ConsoleShared/src/components/modal/Modal.tsx +19 -0
  77. package/src/ConsoleShared/src/components/modal/index.ts +1 -0
  78. package/src/ConsoleShared/src/components/popper/Portal.tsx +23 -0
  79. package/src/ConsoleShared/src/components/popper/SimplePopper.tsx +90 -0
  80. package/src/ConsoleShared/src/components/popper/index.ts +2 -0
  81. package/src/ConsoleShared/src/components/spotlight/InteractiveSpotlight.tsx +58 -0
  82. package/src/ConsoleShared/src/components/spotlight/Spotlight.tsx +35 -0
  83. package/src/ConsoleShared/src/components/spotlight/StaticSpotlight.tsx +32 -0
  84. package/src/ConsoleShared/src/components/spotlight/index.ts +1 -0
  85. package/src/ConsoleShared/src/components/spotlight/spotlight.scss +63 -0
  86. package/src/ConsoleShared/src/components/status/GenericStatus.tsx +33 -0
  87. package/src/ConsoleShared/src/components/status/NotStartedIcon.tsx +27 -0
  88. package/src/ConsoleShared/src/components/status/PopoverStatus.tsx +42 -0
  89. package/src/ConsoleShared/src/components/status/Status.tsx +38 -0
  90. package/src/ConsoleShared/src/components/status/StatusIconAndText.tsx +42 -0
  91. package/src/ConsoleShared/src/components/status/icons.tsx +77 -0
  92. package/src/ConsoleShared/src/components/status/index.tsx +1 -0
  93. package/src/ConsoleShared/src/components/status/statuses.tsx +36 -0
  94. package/src/ConsoleShared/src/components/status/types.ts +7 -0
  95. package/src/ConsoleShared/src/components/utils/FallbackImg.tsx +20 -0
  96. package/src/ConsoleShared/src/components/utils/index.ts +1 -0
  97. package/src/ConsoleShared/src/constants/index.ts +1 -0
  98. package/src/ConsoleShared/src/constants/ui.ts +1 -0
  99. package/src/ConsoleShared/src/hooks/index.ts +6 -0
  100. package/src/ConsoleShared/src/hooks/scroll.ts +52 -0
  101. package/src/ConsoleShared/src/hooks/useBoundingClientRect.ts +18 -0
  102. package/src/ConsoleShared/src/hooks/useEventListener.ts +14 -0
  103. package/src/ConsoleShared/src/hooks/useForceRender.ts +6 -0
  104. package/src/ConsoleShared/src/hooks/useResizeObserver.ts +20 -0
  105. package/src/ConsoleShared/src/hooks/useScrollShadows.ts +45 -0
  106. package/src/ConsoleShared/src/index.ts +4 -0
  107. package/src/ConsoleShared/src/utils/index.ts +1 -0
  108. package/src/ConsoleShared/src/utils/useCombineRefs.ts +17 -0
  109. package/src/HelpTopicDrawer.tsx +124 -0
  110. package/src/HelpTopicPanelContent.tsx +152 -0
  111. package/src/QuickStartCatalogPage.tsx +190 -0
  112. package/src/QuickStartCloseModal.tsx +47 -0
  113. package/src/QuickStartController.tsx +113 -0
  114. package/src/QuickStartDrawer.scss +11 -0
  115. package/src/QuickStartDrawer.tsx +265 -0
  116. package/src/QuickStartMarkdownView.tsx +75 -0
  117. package/src/QuickStartPanelContent.scss +46 -0
  118. package/src/QuickStartPanelContent.tsx +153 -0
  119. package/src/__tests__/quick-start-utils.spec.tsx +16 -0
  120. package/src/catalog/Catalog/QuickStartCatalogHeader.tsx +18 -0
  121. package/src/catalog/Catalog/QuickStartCatalogSection.tsx +9 -0
  122. package/src/catalog/Catalog/QuickStartCatalogToolbar.tsx +12 -0
  123. package/src/catalog/Catalog/index.ts +3 -0
  124. package/src/catalog/QuickStartCatalog.scss +8 -0
  125. package/src/catalog/QuickStartCatalog.tsx +42 -0
  126. package/src/catalog/QuickStartTile.scss +11 -0
  127. package/src/catalog/QuickStartTile.tsx +105 -0
  128. package/src/catalog/QuickStartTileDescription.scss +29 -0
  129. package/src/catalog/QuickStartTileDescription.tsx +79 -0
  130. package/src/catalog/QuickStartTileFooter.tsx +101 -0
  131. package/src/catalog/QuickStartTileFooterExternal.tsx +40 -0
  132. package/src/catalog/QuickStartTileHeader.scss +12 -0
  133. package/src/catalog/QuickStartTileHeader.tsx +77 -0
  134. package/src/catalog/Toolbar/QuickStartCatalogFilter.scss +25 -0
  135. package/src/catalog/Toolbar/QuickStartCatalogFilter.tsx +34 -0
  136. package/src/catalog/Toolbar/QuickStartCatalogFilterItems.tsx +199 -0
  137. package/src/catalog/__tests__/QuickStartCatalog.spec.tsx +35 -0
  138. package/src/catalog/__tests__/QuickStartTile.spec.tsx +38 -0
  139. package/src/catalog/__tests__/QuickStartTileDescription.spec.tsx +44 -0
  140. package/src/catalog/index.ts +9 -0
  141. package/src/controller/QuickStartConclusion.tsx +63 -0
  142. package/src/controller/QuickStartContent.scss +12 -0
  143. package/src/controller/QuickStartContent.tsx +72 -0
  144. package/src/controller/QuickStartFooter.scss +13 -0
  145. package/src/controller/QuickStartFooter.tsx +128 -0
  146. package/src/controller/QuickStartIntroduction.scss +35 -0
  147. package/src/controller/QuickStartIntroduction.tsx +66 -0
  148. package/src/controller/QuickStartTaskHeader.scss +58 -0
  149. package/src/controller/QuickStartTaskHeader.tsx +116 -0
  150. package/src/controller/QuickStartTaskHeaderList.scss +17 -0
  151. package/src/controller/QuickStartTaskHeaderList.tsx +35 -0
  152. package/src/controller/QuickStartTaskReview.scss +30 -0
  153. package/src/controller/QuickStartTaskReview.tsx +81 -0
  154. package/src/controller/QuickStartTasks.scss +89 -0
  155. package/src/controller/QuickStartTasks.tsx +75 -0
  156. package/src/controller/__tests__/QuickStartConclusion.spec.tsx +95 -0
  157. package/src/controller/__tests__/QuickStartContent.spec.tsx +52 -0
  158. package/src/controller/__tests__/QuickStartFooter.spec.tsx +148 -0
  159. package/src/controller/__tests__/QuickStartTaskHeader.spec.tsx +56 -0
  160. package/src/controller/__tests__/QuickStartTaskReview.spec.tsx +45 -0
  161. package/src/controller/__tests__/QuickStartTasks.spec.tsx +81 -0
  162. package/src/data/mocks/json/explore-pipeline-quickstart.ts +66 -0
  163. package/src/data/mocks/json/explore-serverless-quickstart.ts +90 -0
  164. package/src/data/mocks/json/monitor-sampleapp-quickstart.ts +77 -0
  165. package/src/data/mocks/json/tour-icons.ts +3 -0
  166. package/src/data/mocks/yamls/add-healthchecks-quickstart.yaml +67 -0
  167. package/src/data/mocks/yamls/explore-pipeline-quickstart.yaml +57 -0
  168. package/src/data/mocks/yamls/explore-serverless-quickstart.yaml +83 -0
  169. package/src/data/mocks/yamls/install-associate-pipeline-quickstart.yaml +74 -0
  170. package/src/data/mocks/yamls/monitor-sampleapp-quickstart.yaml +66 -0
  171. package/src/data/mocks/yamls/sample-application-quickstart.yaml +97 -0
  172. package/src/data/mocks/yamls/serverless-application-quickstart.yaml +141 -0
  173. package/src/data/quick-start-test-data.ts +10 -0
  174. package/src/data/test-utils.ts +11 -0
  175. package/src/declaration.d.ts +2 -0
  176. package/src/index.ts +17 -0
  177. package/src/locales/en/quickstart.json +46 -0
  178. package/src/styles/_base.scss +54 -0
  179. package/src/styles/_dark-custom-override.scss +62 -0
  180. package/src/styles/legacy-bootstrap/README.md +21 -0
  181. package/src/styles/legacy-bootstrap/_code.scss +44 -0
  182. package/src/styles/legacy-bootstrap/_tables.scss +38 -0
  183. package/src/styles/legacy-bootstrap/_type.scss +90 -0
  184. package/src/styles/legacy-bootstrap/_variables.scss +48 -0
  185. package/src/styles/legacy-bootstrap.scss +5 -0
  186. package/src/styles/patternfly-global-entry.ts +1 -0
  187. package/src/styles/patternfly-global.scss +28 -0
  188. package/src/styles/patternfly-nested-entry.ts +1 -0
  189. package/src/styles/patternfly-nested.scss +18 -0
  190. package/src/styles/quickstarts-standalone-entry.ts +1 -0
  191. package/src/styles/quickstarts-standalone.scss +7 -0
  192. package/src/styles/style.scss +12 -0
  193. package/src/styles/vendor-entry.ts +1 -0
  194. package/src/styles/vendor.scss +7 -0
  195. package/src/utils/PluralResolver.ts +356 -0
  196. package/src/utils/asciidoc-procedure-parser.ts +132 -0
  197. package/src/utils/const.ts +10 -0
  198. package/src/utils/help-topic-context.tsx +74 -0
  199. package/src/utils/help-topic-types.ts +16 -0
  200. package/src/utils/quick-start-context.tsx +477 -0
  201. package/src/utils/quick-start-types.ts +72 -0
  202. package/src/utils/quick-start-utils.ts +92 -0
  203. package/src/utils/useLocalStorage.ts +38 -0
@@ -0,0 +1,12 @@
1
+ .pfext-quick-start-tile-header {
2
+ &__status {
3
+ margin: var(--pf-global--spacer--sm) 0;
4
+ }
5
+ &--margin {
6
+ margin-right: var(--pf-global--spacer--sm);
7
+ margin-bottom: var(--pf-global--spacer--sm);
8
+ }
9
+ & .pf-c-badge:not(:last-of-type) {
10
+ margin-right: var(--pf-global--spacer--sm);
11
+ }
12
+ }
@@ -0,0 +1,77 @@
1
+ import './QuickStartTileHeader.scss';
2
+ import * as React from 'react';
3
+ import { Label, Title } from '@patternfly/react-core';
4
+ import OutlinedClockIcon from '@patternfly/react-icons/dist/js/icons/outlined-clock-icon';
5
+ import { StatusIcon } from '@console/shared';
6
+ import { QuickStartContext, QuickStartContextValues } from '../utils/quick-start-context';
7
+ import { QuickStartStatus, QuickStartType } from '../utils/quick-start-types';
8
+
9
+ type QuickStartTileHeaderProps = {
10
+ status: string;
11
+ duration: number;
12
+ name: string;
13
+ type?: QuickStartType;
14
+ quickStartId?: string;
15
+ };
16
+
17
+ const statusColorMap = {
18
+ [QuickStartStatus.COMPLETE]: 'green',
19
+ [QuickStartStatus.IN_PROGRESS]: 'purple',
20
+ [QuickStartStatus.NOT_STARTED]: 'grey',
21
+ };
22
+
23
+ const QuickStartTileHeader: React.FC<QuickStartTileHeaderProps> = ({
24
+ status,
25
+ duration,
26
+ name,
27
+ type,
28
+ quickStartId,
29
+ }) => {
30
+ const { getResource } = React.useContext<QuickStartContextValues>(QuickStartContext);
31
+
32
+ const statusLocaleMap = {
33
+ [QuickStartStatus.COMPLETE]: getResource('Complete'),
34
+ [QuickStartStatus.IN_PROGRESS]: getResource('In progress'),
35
+ [QuickStartStatus.NOT_STARTED]: getResource('Not started'),
36
+ };
37
+
38
+ return (
39
+ <div className="pfext-quick-start-tile-header">
40
+ <Title headingLevel="h3" data-test="title" id={quickStartId}>
41
+ {name}
42
+ </Title>
43
+ <div className="pfext-quick-start-tile-header__status">
44
+ {type && (
45
+ <Label className="pfext-quick-start-tile-header--margin" color={type.color}>
46
+ {type.text}
47
+ </Label>
48
+ )}
49
+ {duration && (
50
+ <Label
51
+ variant="outline"
52
+ data-test="duration"
53
+ icon={<OutlinedClockIcon />}
54
+ className="pfext-quick-start-tile-header--margin"
55
+ >
56
+ {getResource('{{duration, number}} minutes', duration).replace(
57
+ '{{duration, number}}',
58
+ duration,
59
+ )}
60
+ </Label>
61
+ )}
62
+ {status !== QuickStartStatus.NOT_STARTED && (
63
+ <Label
64
+ variant="outline"
65
+ color={statusColorMap[status]}
66
+ icon={<StatusIcon status={status} />}
67
+ data-test="status"
68
+ >
69
+ {statusLocaleMap[status]}
70
+ </Label>
71
+ )}
72
+ </div>
73
+ </div>
74
+ );
75
+ };
76
+
77
+ export default QuickStartTileHeader;
@@ -0,0 +1,25 @@
1
+ .pfext-quick-start-catalog-filter {
2
+ &__input {
3
+ flex-grow: 1;
4
+ max-width: 500px;
5
+ }
6
+
7
+ &__count {
8
+ font-weight: var(--pf-global--FontWeight--bold);
9
+ }
10
+ }
11
+
12
+ .pf-c-toolbar.pf-m-page-insets.pfext-quick-start-catalog-filter__flex {
13
+ --pf-c-toolbar--PaddingBottom: var(--pf-global--spacer--sm);
14
+ --pf-c-toolbar--PaddingTop: var(--pf-global--spacer--sm);
15
+ --pf-c-toolbar--RowGap: 0;
16
+ font-size: 14px;
17
+
18
+ .pf-c-select {
19
+ --pf-c-select__toggle--FontSize: 14px;
20
+ }
21
+
22
+ .pf-c-check {
23
+ --pf-c-check__label--FontSize: 14px;
24
+ }
25
+ }
@@ -0,0 +1,34 @@
1
+ import * as React from 'react';
2
+ import { Toolbar, ToolbarContent, ToolbarProps } from '@patternfly/react-core';
3
+ import {
4
+ QuickStartCatalogFilterCountWrapper,
5
+ QuickStartCatalogFilterSearchWrapper,
6
+ QuickStartCatalogFilterStatusWrapper,
7
+ } from './QuickStartCatalogFilterItems';
8
+
9
+ import './QuickStartCatalogFilter.scss';
10
+
11
+ interface QuickStartCatalogFilterProps extends Omit<ToolbarProps, 'ref'> {
12
+ quickStartsCount: number;
13
+ onSearchInputChange: any;
14
+ onStatusChange: any;
15
+ }
16
+
17
+ const QuickStartCatalogFilter: React.FC<QuickStartCatalogFilterProps> = ({
18
+ quickStartsCount,
19
+ onSearchInputChange = () => {},
20
+ onStatusChange = () => {},
21
+ ...props
22
+ }) => {
23
+ return (
24
+ <Toolbar usePageInsets className="pfext-quick-start-catalog-filter__flex" {...props}>
25
+ <ToolbarContent>
26
+ <QuickStartCatalogFilterSearchWrapper onSearchInputChange={onSearchInputChange} />
27
+ <QuickStartCatalogFilterStatusWrapper onStatusChange={onStatusChange} />
28
+ <QuickStartCatalogFilterCountWrapper quickStartsCount={quickStartsCount} />
29
+ </ToolbarContent>
30
+ </Toolbar>
31
+ );
32
+ };
33
+
34
+ export default QuickStartCatalogFilter;
@@ -0,0 +1,199 @@
1
+ import * as React from 'react';
2
+ import {
3
+ SearchInput,
4
+ Select,
5
+ SelectOption,
6
+ SelectVariant,
7
+ ToolbarItem,
8
+ } from '@patternfly/react-core';
9
+ import { removeQueryArgument, setQueryArgument } from '@console/internal/components/utils';
10
+ import { history } from '../../ConsoleInternal/components/utils/router';
11
+ import { QUICKSTART_SEARCH_FILTER_KEY, QUICKSTART_STATUS_FILTER_KEY } from '../../utils/const';
12
+ import { QuickStartContext, QuickStartContextValues } from '../../utils/quick-start-context';
13
+
14
+ export const QuickStartCatalogFilterSearch = ({ searchInputText, handleTextChange, ...props }) => {
15
+ const { getResource } = React.useContext<QuickStartContextValues>(QuickStartContext);
16
+ return (
17
+ <ToolbarItem className="pfext-quick-start-catalog-filter__input">
18
+ <SearchInput
19
+ placeholder={getResource('Filter by keyword...')}
20
+ value={searchInputText}
21
+ onChange={handleTextChange}
22
+ onClear={() => handleTextChange('')}
23
+ {...props}
24
+ />
25
+ </ToolbarItem>
26
+ );
27
+ };
28
+
29
+ export const QuickStartCatalogFilterSelect = ({
30
+ isDropdownOpen,
31
+ setIsDropdownOpen,
32
+ onRowfilterSelect,
33
+ selectedFilters,
34
+ dropdownItems,
35
+ ...props
36
+ }) => {
37
+ const { getResource } = React.useContext<QuickStartContextValues>(QuickStartContext);
38
+ return (
39
+ <ToolbarItem>
40
+ <Select
41
+ variant={SelectVariant.checkbox}
42
+ aria-label={getResource('Select filter')}
43
+ isOpen={isDropdownOpen}
44
+ onToggle={(isEnabled) => setIsDropdownOpen(isEnabled)}
45
+ placeholderText={getResource('Status')}
46
+ onSelect={onRowfilterSelect}
47
+ selections={selectedFilters}
48
+ {...props}
49
+ >
50
+ {dropdownItems}
51
+ </Select>
52
+ </ToolbarItem>
53
+ );
54
+ };
55
+
56
+ export const QuickStartCatalogFilterCount = ({ quickStartsCount }) => {
57
+ const { getResource } = React.useContext<QuickStartContextValues>(QuickStartContext);
58
+ return (
59
+ <ToolbarItem
60
+ className="pfext-quick-start-catalog-filter__count"
61
+ alignment={{ default: 'alignRight' }}
62
+ >
63
+ {getResource('{{count, number}} item', quickStartsCount).replace(
64
+ '{{count, number}}',
65
+ quickStartsCount,
66
+ )}
67
+ </ToolbarItem>
68
+ );
69
+ };
70
+
71
+ interface QuickStartCatalogFilterSearchWrapperProps {
72
+ onSearchInputChange: any;
73
+ }
74
+ export const QuickStartCatalogFilterSearchWrapper: React.FC<QuickStartCatalogFilterSearchWrapperProps> = ({
75
+ onSearchInputChange = () => {},
76
+ }) => {
77
+ const { useQueryParams, filter, setFilter } = React.useContext<QuickStartContextValues>(
78
+ QuickStartContext,
79
+ );
80
+ React.useEffect(() => {
81
+ // use this effect to clear the search when a `clear all` action is performed higher up
82
+ const unlisten = history.listen(({ location }) => {
83
+ const searchParams = new URLSearchParams(location.search);
84
+ const searchQuery = searchParams.get(QUICKSTART_SEARCH_FILTER_KEY) || '';
85
+ if (searchQuery === '') {
86
+ setFilter('keyword', '');
87
+ onSearchInputChange('');
88
+ }
89
+ });
90
+ return () => {
91
+ unlisten();
92
+ };
93
+ }, [onSearchInputChange, setFilter]);
94
+ const handleTextChange = (val: string) => {
95
+ if (val.length > 0) {
96
+ useQueryParams && setQueryArgument(QUICKSTART_SEARCH_FILTER_KEY, val);
97
+ } else {
98
+ useQueryParams && removeQueryArgument(QUICKSTART_SEARCH_FILTER_KEY);
99
+ }
100
+ if (filter?.keyword !== val) {
101
+ setFilter('keyword', val);
102
+ }
103
+ onSearchInputChange(val);
104
+ };
105
+
106
+ return (
107
+ <QuickStartCatalogFilterSearch
108
+ searchInputText={filter?.keyword}
109
+ handleTextChange={handleTextChange}
110
+ />
111
+ );
112
+ };
113
+
114
+ // compare string/number arrays
115
+ export const equalsIgnoreOrder = (a: any[], b: any[]) => {
116
+ if (a.length !== b.length) {
117
+ return false;
118
+ }
119
+ const uniqueValues = new Set([...a, ...b]);
120
+ for (const v of uniqueValues) {
121
+ const aCount = a.filter((e) => e === v).length;
122
+ const bCount = b.filter((e) => e === v).length;
123
+ if (aCount !== bCount) {
124
+ return false;
125
+ }
126
+ }
127
+ return true;
128
+ };
129
+
130
+ interface QuickStartCatalogFilterStatusWrapperProps {
131
+ onStatusChange: any;
132
+ }
133
+ export const QuickStartCatalogFilterStatusWrapper: React.FC<QuickStartCatalogFilterStatusWrapperProps> = ({
134
+ onStatusChange = () => {},
135
+ }) => {
136
+ const { useQueryParams, filter, setFilter } = React.useContext<QuickStartContextValues>(
137
+ QuickStartContext,
138
+ );
139
+ React.useEffect(() => {
140
+ // use this effect to clear the status when a `clear all` action is performed higher up
141
+ const unlisten = history.listen(({ location }) => {
142
+ const searchParams = new URLSearchParams(location.search);
143
+ const updatedStatusFilters = searchParams.get(QUICKSTART_STATUS_FILTER_KEY)?.split(',') || [];
144
+ if (updatedStatusFilters.length === 0) {
145
+ setFilter('status', []);
146
+ onStatusChange([]);
147
+ }
148
+ });
149
+ return () => {
150
+ unlisten();
151
+ };
152
+ });
153
+ const [isDropdownOpen, setIsDropdownOpen] = React.useState(false);
154
+
155
+ const onRowfilterSelect = React.useCallback(
156
+ (e) => {
157
+ setIsDropdownOpen(false);
158
+ const selection = e.target.parentElement.getAttribute('data-key');
159
+ const selectedFiltersList = filter.status.statusFilters.includes(selection)
160
+ ? filter.status.statusFilters.filter((status) => status !== selection)
161
+ : [...filter.status.statusFilters, selection];
162
+ if (!equalsIgnoreOrder(filter.status.statusFilters, selectedFiltersList)) {
163
+ setFilter('status', selectedFiltersList);
164
+ }
165
+ if (selectedFiltersList.length > 0) {
166
+ useQueryParams && setQueryArgument('status', selectedFiltersList.join(','));
167
+ } else {
168
+ useQueryParams && removeQueryArgument(QUICKSTART_STATUS_FILTER_KEY);
169
+ }
170
+ onStatusChange(selectedFiltersList);
171
+ },
172
+ [filter.status.statusFilters, onStatusChange, setFilter, useQueryParams],
173
+ );
174
+
175
+ const dropdownItems = Object.entries(filter.status.statusTypes).map(([key, val]) => (
176
+ <SelectOption key={key} data-key={key} value={key}>
177
+ {val}
178
+ </SelectOption>
179
+ ));
180
+
181
+ return (
182
+ <QuickStartCatalogFilterSelect
183
+ isDropdownOpen={isDropdownOpen}
184
+ setIsDropdownOpen={setIsDropdownOpen}
185
+ onRowfilterSelect={onRowfilterSelect}
186
+ selectedFilters={filter.status.statusFilters}
187
+ dropdownItems={dropdownItems}
188
+ />
189
+ );
190
+ };
191
+
192
+ interface QuickStartCatalogFilterCountWrapperProps {
193
+ quickStartsCount: number;
194
+ }
195
+ export const QuickStartCatalogFilterCountWrapper: React.FC<QuickStartCatalogFilterCountWrapperProps> = ({
196
+ quickStartsCount,
197
+ }) => {
198
+ return <QuickStartCatalogFilterCount quickStartsCount={quickStartsCount} />;
199
+ };
@@ -0,0 +1,35 @@
1
+ import * as React from 'react';
2
+ import { Gallery, GalleryItem } from '@patternfly/react-core';
3
+ import { shallow } from 'enzyme';
4
+ import { EmptyBox } from '@console/internal/components/utils';
5
+ import { getQuickStarts } from '../../data/test-utils';
6
+ import { QuickStartCatalogPage } from '../../QuickStartCatalogPage';
7
+ import QuickStartCatalog from '../QuickStartCatalog';
8
+
9
+ jest.mock('@console/shared', () => {
10
+ const ActualShared = require.requireActual('@console/shared');
11
+ return {
12
+ ...ActualShared,
13
+ useQueryParams: () => new Map(),
14
+ };
15
+ });
16
+
17
+ describe('QuickStartCatalog', () => {
18
+ it('should load an emptybox if no QS exist', () => {
19
+ const QuickStartCatalogProps = { quickStarts: [], onClick: jest.fn() };
20
+ const QuickStartCatalogWrapper = shallow(<QuickStartCatalogPage {...QuickStartCatalogProps} />);
21
+ expect(QuickStartCatalogWrapper.find(EmptyBox).exists()).toBeTruthy();
22
+ });
23
+ it('should load a gallery if QS exist', () => {
24
+ const QuickStartCatalogProps = { quickStarts: getQuickStarts(), onClick: jest.fn() };
25
+ const QuickStartCatalogWrapper = shallow(<QuickStartCatalog {...QuickStartCatalogProps} />);
26
+ expect(QuickStartCatalogWrapper.find(Gallery).exists()).toBeTruthy();
27
+ });
28
+ it('should load galleryItems equal to the number of QS', () => {
29
+ const QuickStartCatalogProps = { quickStarts: getQuickStarts(), onClick: jest.fn() };
30
+ const QuickStartCatalogWrapper = shallow(<QuickStartCatalog {...QuickStartCatalogProps} />);
31
+ const galleryItems = QuickStartCatalogWrapper.find(GalleryItem);
32
+ expect(galleryItems.exists()).toBeTruthy();
33
+ expect(galleryItems.length).toEqual(getQuickStarts().length);
34
+ });
35
+ });
@@ -0,0 +1,38 @@
1
+ import * as React from 'react';
2
+ import { CatalogTile } from '@patternfly/react-catalog-view-extension';
3
+ import { shallow } from 'enzyme';
4
+ import { getQuickStarts } from '../../data/test-utils';
5
+ import { QuickStartStatus } from '../../utils/quick-start-types';
6
+ import QuickStartTile from '../QuickStartTile';
7
+
8
+ describe('QuickStartTile', () => {
9
+ const quickstarts = getQuickStarts();
10
+
11
+ it('should load proper catalog tile without featured property', () => {
12
+ const wrapper = shallow(
13
+ <QuickStartTile
14
+ quickStart={quickstarts[0]}
15
+ status={QuickStartStatus.NOT_STARTED}
16
+ onClick={jest.fn()}
17
+ isActive={false}
18
+ />,
19
+ );
20
+ const catalogTile = wrapper.find(CatalogTile);
21
+ expect(catalogTile.exists()).toBeTruthy();
22
+ expect(catalogTile.prop('featured')).toBe(false);
23
+ });
24
+
25
+ it('should load proper catalog tile with featured property', () => {
26
+ const wrapper = shallow(
27
+ <QuickStartTile
28
+ quickStart={quickstarts[1]}
29
+ status={QuickStartStatus.IN_PROGRESS}
30
+ onClick={jest.fn()}
31
+ isActive
32
+ />,
33
+ );
34
+ const catalogTile = wrapper.find(CatalogTile);
35
+ expect(catalogTile.exists()).toBeTruthy();
36
+ expect(catalogTile.prop('featured')).toBe(true);
37
+ });
38
+ });
@@ -0,0 +1,44 @@
1
+ import * as React from 'react';
2
+ import { Popover, Text } from '@patternfly/react-core';
3
+ import { shallow } from 'enzyme';
4
+ import { getQuickStarts } from '../../data/test-utils';
5
+ import QuickStartTileDescription from '../QuickStartTileDescription';
6
+
7
+ jest.mock('react', () => {
8
+ const ActualReact = require.requireActual('react');
9
+ return {
10
+ ...ActualReact,
11
+ useContext: () => jest.fn(),
12
+ };
13
+ });
14
+
15
+ describe('QuickStartCatalog', () => {
16
+ beforeEach(() => {
17
+ spyOn(React, 'useContext').and.returnValue({
18
+ activeQuickStartID: '',
19
+ startQuickStart: () => {},
20
+ restartQuickStart: () => {},
21
+ getResource: (key) => `quickstart~${key}`,
22
+ });
23
+ });
24
+
25
+ it('should show prerequisites only if provided', () => {
26
+ // this quick start does not have prereqs
27
+ const quickStart = getQuickStarts()[0].spec;
28
+ const QuickStartTileDescriptionWrapper = shallow(
29
+ <QuickStartTileDescription description={quickStart.description} />,
30
+ );
31
+ expect(QuickStartTileDescriptionWrapper.find(Text)).toHaveLength(0);
32
+ });
33
+
34
+ it('shoould render prerequisites inside a popover', () => {
35
+ const quickStart = getQuickStarts()[2].spec;
36
+ const QuickStartTileDescriptionWrapper = shallow(
37
+ <QuickStartTileDescription
38
+ description={quickStart.description}
39
+ prerequisites={quickStart.prerequisites}
40
+ />,
41
+ );
42
+ expect(QuickStartTileDescriptionWrapper.find(Popover)).toHaveLength(1);
43
+ });
44
+ });
@@ -0,0 +1,9 @@
1
+ export { default as QuickStartCatalog } from './QuickStartCatalog';
2
+ export { default as QuickStartCatalogFilter } from './Toolbar/QuickStartCatalogFilter';
3
+ export { default as QuickStartTile } from './QuickStartTile';
4
+ export { default as QuickStartTileDescription } from './QuickStartTileDescription';
5
+ export { default as QuickStartTileFooter } from './QuickStartTileFooter';
6
+ export { default as QuickStartTileFooterExternal } from './QuickStartTileFooterExternal';
7
+ export { default as QuickStartTileHeader } from './QuickStartTileHeader';
8
+ export * from './Toolbar/QuickStartCatalogFilterItems';
9
+ export * from './Catalog';
@@ -0,0 +1,63 @@
1
+ import * as React from 'react';
2
+ import { Button } from '@patternfly/react-core';
3
+ import ArrowRightIcon from '@patternfly/react-icons/dist/js/icons/arrow-right-icon';
4
+ import QuickStartMarkdownView from '../QuickStartMarkdownView';
5
+ import { QuickStartContext, QuickStartContextValues } from '../utils/quick-start-context';
6
+ import { QuickStart, QuickStartTask, QuickStartTaskStatus } from '../utils/quick-start-types';
7
+ import TaskHeaderList from './QuickStartTaskHeaderList';
8
+
9
+ type QuickStartConclusionProps = {
10
+ tasks: QuickStartTask[];
11
+ conclusion: string;
12
+ allTaskStatuses: QuickStartTaskStatus[];
13
+ nextQuickStarts?: QuickStart[];
14
+ onQuickStartChange: (quickStartid: string) => void;
15
+ onTaskSelect: (selectedTaskNumber: number) => void;
16
+ };
17
+
18
+ const QuickStartConclusion: React.FC<QuickStartConclusionProps> = ({
19
+ tasks,
20
+ conclusion,
21
+ allTaskStatuses,
22
+ nextQuickStarts,
23
+ onQuickStartChange,
24
+ onTaskSelect,
25
+ }) => {
26
+ const hasFailedTask = allTaskStatuses.includes(QuickStartTaskStatus.FAILED);
27
+ const { getResource } = React.useContext<QuickStartContextValues>(QuickStartContext);
28
+ return (
29
+ <>
30
+ <TaskHeaderList tasks={tasks} allTaskStatuses={allTaskStatuses} onTaskSelect={onTaskSelect} />
31
+ <QuickStartMarkdownView
32
+ content={
33
+ hasFailedTask
34
+ ? getResource(
35
+ 'One or more verifications did not pass during this quick start. Revisit the tasks or the help links, and then try again.',
36
+ )
37
+ : conclusion
38
+ }
39
+ />
40
+ {!hasFailedTask &&
41
+ nextQuickStarts &&
42
+ nextQuickStarts.length > 0 &&
43
+ nextQuickStarts.map((nextQuickStart, index) => (
44
+ <Button
45
+ variant="link"
46
+ onClick={() => onQuickStartChange(nextQuickStart.metadata.name)}
47
+ isInline
48
+ isBlock
49
+ key={index}
50
+ >
51
+ {getResource('Start {{nextQSDisplayName}} quick start').replace(
52
+ '{{nextQSDisplayName}}',
53
+ nextQuickStart?.spec?.displayName,
54
+ )}{' '}
55
+ <ArrowRightIcon
56
+ style={{ marginLeft: 'var(--pf-global--spacer--xs)', verticalAlign: 'middle' }}
57
+ />
58
+ </Button>
59
+ ))}
60
+ </>
61
+ );
62
+ };
63
+ export default QuickStartConclusion;
@@ -0,0 +1,12 @@
1
+ .pfext-quick-start-content {
2
+ flex: 1 1 0;
3
+ overflow: auto;
4
+ padding: var(--pf-global--spacer--lg);
5
+ font-size: 16px;
6
+
7
+ .pf-c-alert__description {
8
+ p {
9
+ font-size: 13px;
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,72 @@
1
+ import * as React from 'react';
2
+ import { QuickStart, QuickStartTaskStatus } from '../utils/quick-start-types';
3
+ import QuickStartConclusion from './QuickStartConclusion';
4
+ import QuickStartIntroduction from './QuickStartIntroduction';
5
+ import QuickStartTasks from './QuickStartTasks';
6
+
7
+ import './QuickStartContent.scss';
8
+
9
+ type QuickStartContentProps = {
10
+ quickStart: QuickStart;
11
+ nextQuickStarts?: QuickStart[];
12
+ taskNumber: number;
13
+ allTaskStatuses: QuickStartTaskStatus[];
14
+ onTaskSelect: (selectedTaskNumber: number) => void;
15
+ onTaskReview: (taskStatus: QuickStartTaskStatus) => void;
16
+ onQuickStartChange?: (quickStartId: string) => void;
17
+ };
18
+
19
+ const QuickStartContent = React.forwardRef<HTMLDivElement, QuickStartContentProps>(
20
+ (
21
+ {
22
+ quickStart,
23
+ nextQuickStarts = [],
24
+ taskNumber,
25
+ allTaskStatuses,
26
+ onTaskSelect,
27
+ onTaskReview,
28
+ onQuickStartChange,
29
+ },
30
+ ref,
31
+ ) => {
32
+ const {
33
+ spec: { introduction, tasks, conclusion, prerequisites },
34
+ } = quickStart;
35
+ const totalTasks = tasks.length;
36
+
37
+ return (
38
+ <div className="pfext-quick-start-content" ref={ref}>
39
+ {taskNumber === -1 && (
40
+ <QuickStartIntroduction
41
+ tasks={tasks}
42
+ allTaskStatuses={allTaskStatuses}
43
+ introduction={introduction}
44
+ prerequisites={prerequisites}
45
+ onTaskSelect={onTaskSelect}
46
+ />
47
+ )}
48
+ {taskNumber > -1 && taskNumber < totalTasks && (
49
+ <QuickStartTasks
50
+ tasks={tasks}
51
+ taskNumber={taskNumber}
52
+ allTaskStatuses={allTaskStatuses}
53
+ onTaskReview={onTaskReview}
54
+ onTaskSelect={onTaskSelect}
55
+ />
56
+ )}
57
+ {taskNumber === totalTasks && (
58
+ <QuickStartConclusion
59
+ tasks={tasks}
60
+ conclusion={conclusion}
61
+ allTaskStatuses={allTaskStatuses}
62
+ nextQuickStarts={nextQuickStarts}
63
+ onQuickStartChange={onQuickStartChange}
64
+ onTaskSelect={onTaskSelect}
65
+ />
66
+ )}
67
+ </div>
68
+ );
69
+ },
70
+ );
71
+
72
+ export default QuickStartContent;
@@ -0,0 +1,13 @@
1
+ .pfext-quick-start-footer {
2
+ background-color: var(--pf-global--BackgroundColor--100); // this is an example about how we should use PF variables
3
+ flex: 0 0 auto;
4
+ padding: var(--pf-global--spacer--md) var(--pf-global--spacer--lg);
5
+
6
+ &__actionbtn {
7
+ margin-right: var(--pf-global--spacer--md);
8
+ }
9
+
10
+ &__restartbtn {
11
+ float: right;
12
+ }
13
+ }