@patternfly/quickstarts 2.2.3 → 2.3.1

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 (198) hide show
  1. package/README.md +4 -4
  2. package/dist/ConsoleShared/src/components/markdown-extensions/inline-clipboard-extension.d.ts +1 -1
  3. package/dist/ConsoleShared/src/components/markdown-extensions/multiline-clipboard-extension.d.ts +1 -1
  4. package/dist/HelpTopicDrawer.d.ts +8 -2
  5. package/dist/QuickStartDrawer.d.ts +21 -2
  6. package/dist/controller/QuickStartTaskHeader.d.ts +1 -1
  7. package/dist/index.es.js +14 -13
  8. package/dist/index.es.js.map +1 -1
  9. package/dist/index.js +14 -13
  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/quickstarts-base.css +24 -24
  38. package/dist/quickstarts-full.es.js +14 -13
  39. package/dist/quickstarts-full.es.js.map +1 -1
  40. package/dist/quickstarts.css +24 -24
  41. package/dist/quickstarts.min.css +1 -1
  42. package/package.json +11 -4
  43. package/src/ConsoleInternal/components/_icon-and-text.scss +14 -0
  44. package/src/ConsoleInternal/components/_markdown-view.scss +19 -0
  45. package/src/ConsoleInternal/components/catalog/_catalog.scss +390 -0
  46. package/src/ConsoleInternal/components/markdown-view.tsx +305 -0
  47. package/src/ConsoleInternal/components/utils/_status-box.scss +58 -0
  48. package/src/ConsoleInternal/components/utils/camel-case-wrap.tsx +33 -0
  49. package/src/ConsoleInternal/components/utils/index.tsx +3 -0
  50. package/src/ConsoleInternal/components/utils/router.ts +47 -0
  51. package/src/ConsoleInternal/components/utils/status-box.tsx +94 -0
  52. package/src/ConsoleInternal/module/k8s/types.ts +53 -0
  53. package/src/ConsoleShared/index.ts +1 -0
  54. package/src/ConsoleShared/src/components/index.ts +7 -0
  55. package/src/ConsoleShared/src/components/layout/PageLayout.scss +29 -0
  56. package/src/ConsoleShared/src/components/markdown-extensions/MarkdownCopyClipboard.tsx +93 -0
  57. package/src/ConsoleShared/src/components/markdown-extensions/__tests__/MarkdownCopyClipboard.spec.tsx +25 -0
  58. package/src/ConsoleShared/src/components/markdown-extensions/__tests__/test-data.ts +5 -0
  59. package/src/ConsoleShared/src/components/markdown-extensions/admonition-extension.tsx +66 -0
  60. package/src/ConsoleShared/src/components/markdown-extensions/code-extension.tsx +25 -0
  61. package/src/ConsoleShared/src/components/markdown-extensions/const.ts +3 -0
  62. package/src/ConsoleShared/src/components/markdown-extensions/index.ts +5 -0
  63. package/src/ConsoleShared/src/components/markdown-extensions/inline-clipboard-extension.tsx +39 -0
  64. package/src/ConsoleShared/src/components/markdown-extensions/multiline-clipboard-extension.tsx +44 -0
  65. package/src/ConsoleShared/src/components/markdown-extensions/showdown-extension.scss +52 -0
  66. package/src/ConsoleShared/src/components/markdown-extensions/utils.ts +3 -0
  67. package/src/ConsoleShared/src/components/markdown-highlight-extension/MarkdownHighlightExtension.tsx +64 -0
  68. package/src/ConsoleShared/src/components/markdown-highlight-extension/highlight-consts.ts +9 -0
  69. package/src/ConsoleShared/src/components/markdown-highlight-extension/index.ts +1 -0
  70. package/src/ConsoleShared/src/components/modal/Modal.scss +3 -0
  71. package/src/ConsoleShared/src/components/modal/Modal.tsx +19 -0
  72. package/src/ConsoleShared/src/components/modal/index.ts +1 -0
  73. package/src/ConsoleShared/src/components/popper/Portal.tsx +23 -0
  74. package/src/ConsoleShared/src/components/popper/SimplePopper.tsx +90 -0
  75. package/src/ConsoleShared/src/components/popper/index.ts +2 -0
  76. package/src/ConsoleShared/src/components/spotlight/InteractiveSpotlight.tsx +58 -0
  77. package/src/ConsoleShared/src/components/spotlight/Spotlight.tsx +35 -0
  78. package/src/ConsoleShared/src/components/spotlight/StaticSpotlight.tsx +32 -0
  79. package/src/ConsoleShared/src/components/spotlight/index.ts +1 -0
  80. package/src/ConsoleShared/src/components/spotlight/spotlight.scss +63 -0
  81. package/src/ConsoleShared/src/components/status/GenericStatus.tsx +33 -0
  82. package/src/ConsoleShared/src/components/status/NotStartedIcon.tsx +27 -0
  83. package/src/ConsoleShared/src/components/status/PopoverStatus.tsx +42 -0
  84. package/src/ConsoleShared/src/components/status/Status.tsx +38 -0
  85. package/src/ConsoleShared/src/components/status/StatusIconAndText.tsx +42 -0
  86. package/src/ConsoleShared/src/components/status/icons.tsx +77 -0
  87. package/src/ConsoleShared/src/components/status/index.tsx +1 -0
  88. package/src/ConsoleShared/src/components/status/statuses.tsx +36 -0
  89. package/src/ConsoleShared/src/components/status/types.ts +7 -0
  90. package/src/ConsoleShared/src/components/utils/FallbackImg.tsx +20 -0
  91. package/src/ConsoleShared/src/components/utils/index.ts +1 -0
  92. package/src/ConsoleShared/src/constants/index.ts +1 -0
  93. package/src/ConsoleShared/src/constants/ui.ts +1 -0
  94. package/src/ConsoleShared/src/hooks/index.ts +6 -0
  95. package/src/ConsoleShared/src/hooks/scroll.ts +52 -0
  96. package/src/ConsoleShared/src/hooks/useBoundingClientRect.ts +18 -0
  97. package/src/ConsoleShared/src/hooks/useEventListener.ts +14 -0
  98. package/src/ConsoleShared/src/hooks/useForceRender.ts +6 -0
  99. package/src/ConsoleShared/src/hooks/useResizeObserver.ts +20 -0
  100. package/src/ConsoleShared/src/hooks/useScrollShadows.ts +45 -0
  101. package/src/ConsoleShared/src/index.ts +4 -0
  102. package/src/ConsoleShared/src/utils/index.ts +1 -0
  103. package/src/ConsoleShared/src/utils/useCombineRefs.ts +17 -0
  104. package/src/HelpTopicDrawer.tsx +124 -0
  105. package/src/HelpTopicPanelContent.tsx +152 -0
  106. package/src/QuickStartCatalogPage.tsx +190 -0
  107. package/src/QuickStartCloseModal.tsx +47 -0
  108. package/src/QuickStartController.tsx +113 -0
  109. package/src/QuickStartDrawer.scss +11 -0
  110. package/src/QuickStartDrawer.tsx +265 -0
  111. package/src/QuickStartMarkdownView.tsx +75 -0
  112. package/src/QuickStartPanelContent.scss +46 -0
  113. package/src/QuickStartPanelContent.tsx +153 -0
  114. package/src/__tests__/quick-start-utils.spec.tsx +16 -0
  115. package/src/catalog/Catalog/QuickStartCatalogHeader.tsx +18 -0
  116. package/src/catalog/Catalog/QuickStartCatalogSection.tsx +9 -0
  117. package/src/catalog/Catalog/QuickStartCatalogToolbar.tsx +12 -0
  118. package/src/catalog/Catalog/index.ts +3 -0
  119. package/src/catalog/QuickStartCatalog.scss +8 -0
  120. package/src/catalog/QuickStartCatalog.tsx +42 -0
  121. package/src/catalog/QuickStartTile.scss +11 -0
  122. package/src/catalog/QuickStartTile.tsx +105 -0
  123. package/src/catalog/QuickStartTileDescription.scss +29 -0
  124. package/src/catalog/QuickStartTileDescription.tsx +79 -0
  125. package/src/catalog/QuickStartTileFooter.tsx +101 -0
  126. package/src/catalog/QuickStartTileFooterExternal.tsx +40 -0
  127. package/src/catalog/QuickStartTileHeader.scss +12 -0
  128. package/src/catalog/QuickStartTileHeader.tsx +77 -0
  129. package/src/catalog/Toolbar/QuickStartCatalogFilter.scss +25 -0
  130. package/src/catalog/Toolbar/QuickStartCatalogFilter.tsx +34 -0
  131. package/src/catalog/Toolbar/QuickStartCatalogFilterItems.tsx +199 -0
  132. package/src/catalog/__tests__/QuickStartCatalog.spec.tsx +35 -0
  133. package/src/catalog/__tests__/QuickStartTile.spec.tsx +38 -0
  134. package/src/catalog/__tests__/QuickStartTileDescription.spec.tsx +44 -0
  135. package/src/catalog/index.ts +9 -0
  136. package/src/controller/QuickStartConclusion.tsx +63 -0
  137. package/src/controller/QuickStartContent.scss +12 -0
  138. package/src/controller/QuickStartContent.tsx +72 -0
  139. package/src/controller/QuickStartFooter.scss +13 -0
  140. package/src/controller/QuickStartFooter.tsx +128 -0
  141. package/src/controller/QuickStartIntroduction.scss +35 -0
  142. package/src/controller/QuickStartIntroduction.tsx +66 -0
  143. package/src/controller/QuickStartTaskHeader.scss +58 -0
  144. package/src/controller/QuickStartTaskHeader.tsx +116 -0
  145. package/src/controller/QuickStartTaskHeaderList.scss +17 -0
  146. package/src/controller/QuickStartTaskHeaderList.tsx +35 -0
  147. package/src/controller/QuickStartTaskReview.scss +30 -0
  148. package/src/controller/QuickStartTaskReview.tsx +81 -0
  149. package/src/controller/QuickStartTasks.scss +89 -0
  150. package/src/controller/QuickStartTasks.tsx +75 -0
  151. package/src/controller/__tests__/QuickStartConclusion.spec.tsx +95 -0
  152. package/src/controller/__tests__/QuickStartContent.spec.tsx +52 -0
  153. package/src/controller/__tests__/QuickStartFooter.spec.tsx +148 -0
  154. package/src/controller/__tests__/QuickStartTaskHeader.spec.tsx +56 -0
  155. package/src/controller/__tests__/QuickStartTaskReview.spec.tsx +45 -0
  156. package/src/controller/__tests__/QuickStartTasks.spec.tsx +81 -0
  157. package/src/data/mocks/json/explore-pipeline-quickstart.ts +66 -0
  158. package/src/data/mocks/json/explore-serverless-quickstart.ts +90 -0
  159. package/src/data/mocks/json/monitor-sampleapp-quickstart.ts +77 -0
  160. package/src/data/mocks/json/tour-icons.ts +3 -0
  161. package/src/data/mocks/yamls/add-healthchecks-quickstart.yaml +67 -0
  162. package/src/data/mocks/yamls/explore-pipeline-quickstart.yaml +57 -0
  163. package/src/data/mocks/yamls/explore-serverless-quickstart.yaml +83 -0
  164. package/src/data/mocks/yamls/install-associate-pipeline-quickstart.yaml +74 -0
  165. package/src/data/mocks/yamls/monitor-sampleapp-quickstart.yaml +66 -0
  166. package/src/data/mocks/yamls/sample-application-quickstart.yaml +97 -0
  167. package/src/data/mocks/yamls/serverless-application-quickstart.yaml +141 -0
  168. package/src/data/quick-start-test-data.ts +10 -0
  169. package/src/data/test-utils.ts +11 -0
  170. package/src/declaration.d.ts +2 -0
  171. package/src/index.ts +17 -0
  172. package/src/locales/en/quickstart.json +46 -0
  173. package/src/styles/_base.scss +54 -0
  174. package/src/styles/_dark-custom-override.scss +62 -0
  175. package/src/styles/legacy-bootstrap/README.md +21 -0
  176. package/src/styles/legacy-bootstrap/_code.scss +44 -0
  177. package/src/styles/legacy-bootstrap/_tables.scss +38 -0
  178. package/src/styles/legacy-bootstrap/_type.scss +90 -0
  179. package/src/styles/legacy-bootstrap/_variables.scss +48 -0
  180. package/src/styles/legacy-bootstrap.scss +5 -0
  181. package/src/styles/patternfly-global-entry.ts +1 -0
  182. package/src/styles/patternfly-global.scss +28 -0
  183. package/src/styles/patternfly-nested-entry.ts +1 -0
  184. package/src/styles/patternfly-nested.scss +18 -0
  185. package/src/styles/quickstarts-standalone-entry.ts +1 -0
  186. package/src/styles/quickstarts-standalone.scss +7 -0
  187. package/src/styles/style.scss +12 -0
  188. package/src/styles/vendor-entry.ts +1 -0
  189. package/src/styles/vendor.scss +7 -0
  190. package/src/utils/PluralResolver.ts +356 -0
  191. package/src/utils/asciidoc-procedure-parser.ts +132 -0
  192. package/src/utils/const.ts +10 -0
  193. package/src/utils/help-topic-context.tsx +74 -0
  194. package/src/utils/help-topic-types.ts +16 -0
  195. package/src/utils/quick-start-context.tsx +477 -0
  196. package/src/utils/quick-start-types.ts +72 -0
  197. package/src/utils/quick-start-utils.ts +92 -0
  198. package/src/utils/useLocalStorage.ts +38 -0
@@ -0,0 +1,74 @@
1
+ import React from 'react';
2
+ import { HelpTopic } from './help-topic-types';
3
+
4
+ export type HelpTopicContextValues = {
5
+ helpTopics?: HelpTopic[];
6
+ setHelpTopics?: React.Dispatch<React.SetStateAction<HelpTopic[]>>;
7
+ activeHelpTopic?: HelpTopic;
8
+ setActiveHelpTopicByName?: (helpTopicName: string) => void;
9
+ filteredHelpTopics?: HelpTopic[];
10
+ setFilteredHelpTopics?: React.Dispatch<React.SetStateAction<HelpTopic[]>>;
11
+ loading?: boolean;
12
+ setLoading?: any;
13
+ };
14
+
15
+ export const HelpTopicContextDefaults = {
16
+ helpTopics: [],
17
+ setHelpTopics: () => {},
18
+ activeHelpTopic: null,
19
+ setActiveHelpTopicByName: () => {},
20
+ filteredHelpTopics: [],
21
+ setFilteredHelpTopics: () => {},
22
+ loading: false,
23
+ };
24
+
25
+ export const HelpTopicContext = React.createContext<HelpTopicContextValues>(
26
+ HelpTopicContextDefaults,
27
+ );
28
+
29
+ export const useValuesForHelpTopicContext = (
30
+ value: HelpTopicContextValues = {},
31
+ ): HelpTopicContextValues => {
32
+ const combinedValue = {
33
+ ...HelpTopicContextDefaults,
34
+ ...value,
35
+ };
36
+
37
+ const [loading, setLoading] = React.useState(combinedValue.loading);
38
+
39
+ // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
40
+ const [helpTopics, setHelpTopics] = React.useState<HelpTopic[]>(combinedValue.helpTopics || []);
41
+
42
+ const [activeHelpTopic, setActiveHelpTopic] = React.useState(
43
+ combinedValue.activeHelpTopic || null,
44
+ );
45
+
46
+ const setActiveHelpTopicByName = React.useCallback(
47
+ (helpTopicName: string) => {
48
+ const topic = helpTopics.find((t) => {
49
+ return t.name === helpTopicName;
50
+ });
51
+ if (!helpTopicName) {
52
+ setActiveHelpTopic(null);
53
+ return;
54
+ }
55
+ setActiveHelpTopic(topic);
56
+ },
57
+ [helpTopics],
58
+ );
59
+
60
+ const [filteredHelpTopics, setFilteredHelpTopics] = React.useState(
61
+ combinedValue.filteredHelpTopics || [],
62
+ );
63
+
64
+ return {
65
+ helpTopics,
66
+ setHelpTopics,
67
+ activeHelpTopic,
68
+ setActiveHelpTopicByName,
69
+ filteredHelpTopics,
70
+ setFilteredHelpTopics,
71
+ loading,
72
+ setLoading,
73
+ };
74
+ };
@@ -0,0 +1,16 @@
1
+ export type HelpTopicLink = {
2
+ href: string;
3
+ text?: string;
4
+ // open link in new tab
5
+ newTab?: boolean;
6
+ // add PF icon indicating link is external
7
+ isExternal?: boolean;
8
+ };
9
+
10
+ export type HelpTopic = {
11
+ name: string;
12
+ title: string;
13
+ tags: string[];
14
+ content: string;
15
+ links?: HelpTopicLink[];
16
+ };
@@ -0,0 +1,477 @@
1
+ import React, { createContext, useCallback } from 'react';
2
+ import { removeQueryArgument, setQueryArgument } from '../ConsoleInternal/components/utils/router';
3
+ import en from '../locales/en/quickstart.json';
4
+ import {
5
+ QUICKSTART_ID_FILTER_KEY,
6
+ QUICKSTART_SEARCH_FILTER_KEY,
7
+ QUICKSTART_STATUS_FILTER_KEY,
8
+ QUICKSTART_TASKS_INITIAL_STATES,
9
+ } from './const';
10
+ import PluralResolver from './PluralResolver';
11
+ import {
12
+ AllQuickStartStates,
13
+ QuickStart,
14
+ QuickStartState,
15
+ QuickStartStatus,
16
+ QuickStartTaskStatus,
17
+ } from './quick-start-types';
18
+ import { getQuickStartStatusCount, getTaskStatusKey } from './quick-start-utils';
19
+
20
+ const pluralResolver = new PluralResolver({ simplifyPluralSuffix: true });
21
+
22
+ export type FooterProps = {
23
+ show?: boolean;
24
+ };
25
+
26
+ export const getDefaultQuickStartState = (
27
+ totalTasks?: number,
28
+ initialStatus?: QuickStartStatus,
29
+ ) => {
30
+ const defaultQuickStartState = {
31
+ status: initialStatus || QuickStartStatus.NOT_STARTED,
32
+ taskNumber: -1,
33
+ };
34
+ if (totalTasks) {
35
+ for (let i = 0; i < totalTasks; i++) {
36
+ defaultQuickStartState[getTaskStatusKey(i)] = QuickStartTaskStatus.INIT;
37
+ }
38
+ }
39
+ return defaultQuickStartState;
40
+ };
41
+
42
+ export type QuickStartContextValues = {
43
+ allQuickStarts?: QuickStart[];
44
+ setAllQuickStarts?: React.Dispatch<React.SetStateAction<QuickStart[]>>;
45
+ activeQuickStartID?: string;
46
+ setActiveQuickStartID?: React.Dispatch<React.SetStateAction<string>>;
47
+ allQuickStartStates?: AllQuickStartStates;
48
+ setAllQuickStartStates?: React.Dispatch<React.SetStateAction<AllQuickStartStates>>;
49
+ activeQuickStartState?: QuickStartState;
50
+ setActiveQuickStart?: (quickStartId: string, totalTasks?: number) => void;
51
+ startQuickStart?: (quickStartId: string, totalTasks?: number) => void;
52
+ restartQuickStart?: (quickStartId: string, totalTasks: number) => void;
53
+ nextStep?: (totalTasks: number) => void;
54
+ previousStep?: () => void;
55
+ setQuickStartTaskNumber?: (quickStartId: string, taskNumber: number) => void;
56
+ setQuickStartTaskStatus?: (taskStatus: QuickStartTaskStatus) => void;
57
+ getQuickStartForId?: (id: string) => QuickStartState;
58
+ footer?: FooterProps;
59
+ useLegacyHeaderColors?: boolean;
60
+ useQueryParams?: boolean;
61
+ markdown?: {
62
+ extensions?: any[];
63
+ renderExtension?: (docContext: HTMLDocument, rootSelector: string) => React.ReactNode;
64
+ };
65
+ resourceBundle?: any;
66
+ getResource?: any;
67
+ setResourceBundle?: any;
68
+ language?: string;
69
+ setLanguage?: any;
70
+ filter?: {
71
+ keyword?: string;
72
+ status?: {
73
+ statusTypes?: any;
74
+ statusFilters?: any;
75
+ };
76
+ };
77
+ setFilter?: any;
78
+ loading?: boolean;
79
+ setLoading?: any;
80
+ alwaysShowTaskReview?: boolean;
81
+ setAlwaysShowTaskReview?: any;
82
+ };
83
+
84
+ export const QuickStartContextDefaults = {
85
+ allQuickStarts: [],
86
+ activeQuickStartID: '',
87
+ allQuickStartStates: {},
88
+ activeQuickStartState: {},
89
+ setAllQuickStarts: () => {},
90
+ resourceBundle: en,
91
+ getResource: () => '',
92
+ language: 'en',
93
+ useQueryParams: true,
94
+ filter: {
95
+ keyword: '',
96
+ status: {
97
+ statusTypes: {},
98
+ statusFilters: [],
99
+ },
100
+ },
101
+ setFilter: () => {},
102
+ footer: null,
103
+ useLegacyHeaderColors: false,
104
+ markdown: null,
105
+ loading: false,
106
+ alwaysShowTaskReview: true,
107
+ };
108
+ export const QuickStartContext = createContext<QuickStartContextValues>(QuickStartContextDefaults);
109
+
110
+ export const getResource = (resource: string, options: any, resourceBundle: any, lng: string) => {
111
+ if (options && !isNaN(options.count)) {
112
+ const suffix = pluralResolver.getSuffix(lng, options.count);
113
+ if (suffix && resourceBundle[`${resource}_${suffix}`]) {
114
+ // needs plural
115
+ return resourceBundle[`${resource}_${suffix}`];
116
+ }
117
+ }
118
+ return (resourceBundle && resourceBundle[resource]) || '';
119
+ };
120
+
121
+ export const useValuesForQuickStartContext = (
122
+ value: QuickStartContextValues = {},
123
+ ): QuickStartContextValues => {
124
+ const combinedValue = {
125
+ ...QuickStartContextDefaults,
126
+ ...value,
127
+ };
128
+ const {
129
+ activeQuickStartID,
130
+ setActiveQuickStartID,
131
+ setAllQuickStartStates,
132
+ useQueryParams,
133
+ allQuickStartStates,
134
+ allQuickStarts = [],
135
+ footer,
136
+ useLegacyHeaderColors,
137
+ markdown,
138
+ } = combinedValue;
139
+ const [quickStarts, setQuickStarts] = React.useState(combinedValue.allQuickStarts || []);
140
+ const [resourceBundle, setResourceBundle] = React.useState({
141
+ ...en,
142
+ ...combinedValue.resourceBundle,
143
+ });
144
+ const [language, setLanguage] = React.useState(combinedValue.language);
145
+ const changeResourceBundle = (bundle: any, lng?: string) => {
146
+ lng && setLanguage(lng);
147
+ setResourceBundle({
148
+ ...en,
149
+ ...bundle,
150
+ });
151
+ };
152
+ const findResource = useCallback(
153
+ (resource: string, count?: number) => {
154
+ return getResource(
155
+ resource,
156
+ count !== undefined ? { count } : null,
157
+ resourceBundle,
158
+ language,
159
+ );
160
+ },
161
+ [resourceBundle, language],
162
+ );
163
+ const [loading, setLoading] = React.useState(combinedValue.loading);
164
+ const [alwaysShowTaskReview, setAlwaysShowTaskReview] = React.useState(
165
+ combinedValue.alwaysShowTaskReview,
166
+ );
167
+
168
+ const initialSearchParams = new URLSearchParams(window.location.search);
169
+ const initialSearchQuery = initialSearchParams.get(QUICKSTART_SEARCH_FILTER_KEY) || '';
170
+ const initialStatusFilters =
171
+ initialSearchParams.get(QUICKSTART_STATUS_FILTER_KEY)?.split(',') || [];
172
+
173
+ const quickStartStatusCount = getQuickStartStatusCount(allQuickStartStates, allQuickStarts);
174
+ const [statusTypes, setStatusTypes] = React.useState({
175
+ [QuickStartStatus.COMPLETE]: findResource('Complete ({{statusCount, number}})').replace(
176
+ '{{statusCount, number}}',
177
+ quickStartStatusCount[QuickStartStatus.COMPLETE],
178
+ ),
179
+ [QuickStartStatus.IN_PROGRESS]: findResource('In progress ({{statusCount, number}})').replace(
180
+ '{{statusCount, number}}',
181
+ quickStartStatusCount[QuickStartStatus.IN_PROGRESS],
182
+ ),
183
+ [QuickStartStatus.NOT_STARTED]: findResource('Not started ({{statusCount, number}})').replace(
184
+ '{{statusCount, number}}',
185
+ quickStartStatusCount[QuickStartStatus.NOT_STARTED],
186
+ ),
187
+ });
188
+ const [statusFilters, setStatusFilters] = React.useState<string[]>(initialStatusFilters);
189
+
190
+ const [filterKeyword, setFilterKeyword] = React.useState(initialSearchQuery);
191
+
192
+ const setFilter = (type: 'keyword' | 'status', val: any) => {
193
+ if (type === 'keyword') {
194
+ setFilterKeyword(val);
195
+ } else if (type === 'status') {
196
+ setStatusFilters(val);
197
+ }
198
+ };
199
+
200
+ React.useEffect(() => {
201
+ const updatedQuickStartStatusCount = getQuickStartStatusCount(allQuickStartStates, quickStarts);
202
+ setStatusTypes({
203
+ [QuickStartStatus.COMPLETE]: findResource('Complete ({{statusCount, number}})').replace(
204
+ '{{statusCount, number}}',
205
+ updatedQuickStartStatusCount[QuickStartStatus.COMPLETE],
206
+ ),
207
+ [QuickStartStatus.IN_PROGRESS]: findResource('In progress ({{statusCount, number}})').replace(
208
+ '{{statusCount, number}}',
209
+ updatedQuickStartStatusCount[QuickStartStatus.IN_PROGRESS],
210
+ ),
211
+ [QuickStartStatus.NOT_STARTED]: findResource('Not started ({{statusCount, number}})').replace(
212
+ '{{statusCount, number}}',
213
+ updatedQuickStartStatusCount[QuickStartStatus.NOT_STARTED],
214
+ ),
215
+ });
216
+ }, [allQuickStartStates, findResource, quickStarts]);
217
+
218
+ const updateAllQuickStarts = (qs: QuickStart[]) => {
219
+ setQuickStarts(qs);
220
+ };
221
+
222
+ const setActiveQuickStart = useCallback(
223
+ (quickStartId: string, totalTasks?: number) => {
224
+ setActiveQuickStartID((id) => {
225
+ if (!quickStartId || id === quickStartId) {
226
+ useQueryParams && removeQueryArgument(QUICKSTART_ID_FILTER_KEY);
227
+ return '';
228
+ }
229
+ useQueryParams && setQueryArgument(QUICKSTART_ID_FILTER_KEY, quickStartId);
230
+ return quickStartId;
231
+ });
232
+ setAllQuickStartStates((qs) =>
233
+ !quickStartId || qs[quickStartId]
234
+ ? qs
235
+ : { ...qs, [quickStartId]: getDefaultQuickStartState(totalTasks) },
236
+ );
237
+ },
238
+ [setActiveQuickStartID, setAllQuickStartStates, useQueryParams],
239
+ );
240
+
241
+ const startQuickStart = useCallback(
242
+ (quickStartId: string, totalTasks?: number) => {
243
+ setActiveQuickStartID((id) => {
244
+ if (!id || id !== quickStartId) {
245
+ useQueryParams && setQueryArgument(QUICKSTART_ID_FILTER_KEY, quickStartId);
246
+ return quickStartId;
247
+ }
248
+ useQueryParams && setQueryArgument(QUICKSTART_ID_FILTER_KEY, id);
249
+ return id;
250
+ });
251
+ setAllQuickStartStates((qs) => {
252
+ if (qs.hasOwnProperty(quickStartId)) {
253
+ return {
254
+ ...qs,
255
+ [quickStartId]: {
256
+ ...qs[quickStartId],
257
+ status: QuickStartStatus.IN_PROGRESS,
258
+ },
259
+ };
260
+ }
261
+ return {
262
+ ...qs,
263
+ [quickStartId]: getDefaultQuickStartState(totalTasks, QuickStartStatus.IN_PROGRESS),
264
+ };
265
+ });
266
+ },
267
+ [setActiveQuickStartID, setAllQuickStartStates, useQueryParams],
268
+ );
269
+
270
+ const restartQuickStart = useCallback(
271
+ (quickStartId: string, totalTasks: number) => {
272
+ setActiveQuickStartID((id) => {
273
+ if (!id || id !== quickStartId) {
274
+ useQueryParams && setQueryArgument(QUICKSTART_ID_FILTER_KEY, quickStartId);
275
+ return quickStartId;
276
+ }
277
+ useQueryParams && setQueryArgument(QUICKSTART_ID_FILTER_KEY, id);
278
+ return id;
279
+ });
280
+ setAllQuickStartStates((qs) => ({
281
+ ...qs,
282
+ [quickStartId]: getDefaultQuickStartState(totalTasks, QuickStartStatus.NOT_STARTED),
283
+ }));
284
+ },
285
+ [setActiveQuickStartID, setAllQuickStartStates, useQueryParams],
286
+ );
287
+
288
+ // When alwaysShowTaskReview preference is enabled, skip visited step and go directly to review
289
+ const stepAfterInitial = alwaysShowTaskReview
290
+ ? QuickStartTaskStatus.REVIEW
291
+ : QuickStartTaskStatus.VISITED;
292
+
293
+ const nextStep = useCallback(
294
+ (totalTasks: number) => {
295
+ if (!activeQuickStartID) {
296
+ return;
297
+ }
298
+
299
+ setAllQuickStartStates((qs) => {
300
+ const quickStart = qs[activeQuickStartID];
301
+ const status = quickStart?.status;
302
+ const taskNumber = quickStart?.taskNumber as number;
303
+ const taskStatus = quickStart[getTaskStatusKey(taskNumber)];
304
+
305
+ let updatedStatus;
306
+ let updatedTaskNumber;
307
+ let updatedTaskStatus;
308
+
309
+ if (status === QuickStartStatus.NOT_STARTED) {
310
+ updatedStatus = QuickStartStatus.IN_PROGRESS;
311
+ } else if (
312
+ status === QuickStartStatus.IN_PROGRESS &&
313
+ !QUICKSTART_TASKS_INITIAL_STATES.includes(taskStatus as any) &&
314
+ taskNumber === totalTasks - 1
315
+ ) {
316
+ updatedStatus = QuickStartStatus.COMPLETE;
317
+ }
318
+
319
+ if (taskStatus === QuickStartTaskStatus.VISITED) {
320
+ updatedTaskStatus = QuickStartTaskStatus.REVIEW;
321
+ }
322
+
323
+ if (taskNumber < totalTasks && !updatedTaskStatus) {
324
+ updatedTaskNumber = taskNumber + 1;
325
+ }
326
+
327
+ const markInitialStepVisitedOrReview =
328
+ updatedTaskNumber > -1 &&
329
+ quickStart[getTaskStatusKey(updatedTaskNumber)] === QuickStartTaskStatus.INIT
330
+ ? stepAfterInitial
331
+ : quickStart[getTaskStatusKey(updatedTaskNumber)];
332
+ const newState = {
333
+ ...qs,
334
+ [activeQuickStartID]: {
335
+ ...quickStart,
336
+ ...(updatedStatus ? { status: updatedStatus } : {}),
337
+ ...(updatedTaskNumber > -1
338
+ ? {
339
+ taskNumber: updatedTaskNumber,
340
+ [getTaskStatusKey(updatedTaskNumber)]: markInitialStepVisitedOrReview,
341
+ }
342
+ : {}),
343
+ ...(updatedTaskStatus ? { [getTaskStatusKey(taskNumber)]: updatedTaskStatus } : {}),
344
+ },
345
+ };
346
+ return newState;
347
+ });
348
+ },
349
+ [activeQuickStartID, setAllQuickStartStates, stepAfterInitial],
350
+ );
351
+
352
+ const previousStep = useCallback(() => {
353
+ setAllQuickStartStates((qs) => {
354
+ const quickStart = qs[activeQuickStartID];
355
+ const taskNumber = quickStart?.taskNumber as number;
356
+
357
+ if (taskNumber < 0) {
358
+ return qs;
359
+ }
360
+
361
+ return {
362
+ ...qs,
363
+ [activeQuickStartID]: {
364
+ ...quickStart,
365
+ taskNumber: taskNumber - 1,
366
+ },
367
+ };
368
+ });
369
+ }, [activeQuickStartID, setAllQuickStartStates]);
370
+
371
+ const setQuickStartTaskNumber = useCallback(
372
+ (quickStartId: string, taskNumber: number) => {
373
+ setAllQuickStartStates((qs) => {
374
+ const quickStart = qs[quickStartId];
375
+ const status = quickStart?.status;
376
+ let updatedStatus;
377
+ if (taskNumber > -1 && status === QuickStartStatus.NOT_STARTED) {
378
+ updatedStatus = QuickStartStatus.IN_PROGRESS;
379
+ }
380
+
381
+ let updatedTaskStatus = {};
382
+ for (let taskIndex = 0; taskIndex <= taskNumber; taskIndex++) {
383
+ const taskStatus = quickStart[getTaskStatusKey(taskIndex)];
384
+ const newTaskStatus =
385
+ taskStatus === QuickStartTaskStatus.INIT ? stepAfterInitial : undefined;
386
+ if (newTaskStatus) {
387
+ updatedTaskStatus = {
388
+ ...updatedTaskStatus,
389
+ [getTaskStatusKey(taskIndex)]: newTaskStatus,
390
+ };
391
+ }
392
+ }
393
+ const updatedQuickStart = {
394
+ ...quickStart,
395
+ ...(updatedStatus ? { status: updatedStatus } : {}),
396
+ taskNumber,
397
+ ...updatedTaskStatus,
398
+ };
399
+ return { ...qs, [quickStartId]: updatedQuickStart };
400
+ });
401
+ },
402
+ [setAllQuickStartStates, stepAfterInitial],
403
+ );
404
+
405
+ const setQuickStartTaskStatus = useCallback(
406
+ (taskStatus: QuickStartTaskStatus) => {
407
+ const quickStart = allQuickStartStates[activeQuickStartID];
408
+ const { taskNumber } = quickStart;
409
+ const updatedQuickStart = {
410
+ ...quickStart,
411
+ [getTaskStatusKey(taskNumber as any)]: taskStatus,
412
+ };
413
+ setAllQuickStartStates((qs) => ({
414
+ ...qs,
415
+ [activeQuickStartID]: updatedQuickStart,
416
+ }));
417
+ },
418
+ [allQuickStartStates, activeQuickStartID, setAllQuickStartStates],
419
+ );
420
+
421
+ const activeQuickStartState = allQuickStartStates?.[activeQuickStartID] ?? {};
422
+
423
+ const getQuickStartForId = useCallback((id: string) => allQuickStartStates[id], [
424
+ allQuickStartStates,
425
+ ]);
426
+
427
+ return {
428
+ allQuickStarts: quickStarts,
429
+ setAllQuickStarts: updateAllQuickStarts, // revisit if this should be in public context API
430
+ activeQuickStartID,
431
+ setActiveQuickStartID,
432
+ allQuickStartStates,
433
+ setAllQuickStartStates,
434
+ activeQuickStartState,
435
+ setActiveQuickStart: value.setActiveQuickStart || setActiveQuickStart,
436
+ startQuickStart: value.startQuickStart || startQuickStart,
437
+ restartQuickStart: value.restartQuickStart || restartQuickStart,
438
+ nextStep: value.nextStep || nextStep,
439
+ previousStep: value.previousStep || previousStep,
440
+ setQuickStartTaskNumber, // revisit if this should be in public context API
441
+ setQuickStartTaskStatus, // revisit if this should be in public context API
442
+ getQuickStartForId,
443
+ footer,
444
+ useLegacyHeaderColors,
445
+ useQueryParams,
446
+ markdown,
447
+ resourceBundle,
448
+ getResource: findResource, // revisit if this should be in public context API
449
+ setResourceBundle: changeResourceBundle,
450
+ language,
451
+ setLanguage,
452
+ // revisit if this should be in public context API
453
+ filter: {
454
+ keyword: filterKeyword,
455
+ status: {
456
+ statusTypes,
457
+ statusFilters,
458
+ },
459
+ },
460
+ setFilter, // revisit if this should be in public context API
461
+ loading,
462
+ setLoading,
463
+ alwaysShowTaskReview,
464
+ setAlwaysShowTaskReview,
465
+ };
466
+ };
467
+
468
+ export const QuickStartContextProvider: React.FC<{
469
+ children: React.ReactNode;
470
+ value: QuickStartContextValues;
471
+ }> = ({ children, value }) => {
472
+ return (
473
+ <QuickStartContext.Provider value={useValuesForQuickStartContext(value)}>
474
+ {children}
475
+ </QuickStartContext.Provider>
476
+ );
477
+ };
@@ -0,0 +1,72 @@
1
+ import {
2
+ AccessReviewResourceAttributes,
3
+ ObjectMetadata,
4
+ } from '../ConsoleInternal/module/k8s/types';
5
+
6
+ export type QuickStart = {
7
+ apiVersion?: string;
8
+ kind?: string;
9
+ metadata: ObjectMetadata;
10
+ spec: QuickStartSpec;
11
+ };
12
+
13
+ export type QuickStartSpec = {
14
+ version?: number;
15
+ displayName: string;
16
+ durationMinutes?: number;
17
+ icon: React.ReactNode;
18
+ description: string;
19
+ prerequisites?: string[];
20
+ introduction?: string;
21
+ tasks?: QuickStartTask[];
22
+ conclusion?: string;
23
+ nextQuickStart?: string[];
24
+ accessReviewResources?: AccessReviewResourceAttributes[];
25
+ link?: QuickStartExternal;
26
+ type?: QuickStartType;
27
+ };
28
+
29
+ export type QuickStartTask = {
30
+ title?: string;
31
+ description?: string;
32
+ review?: QuickStartTaskReview;
33
+ summary?: QuickStartTaskSummary;
34
+ };
35
+
36
+ export type QuickStartTaskReview = {
37
+ instructions?: string;
38
+ failedTaskHelp?: string;
39
+ };
40
+
41
+ export type QuickStartTaskSummary = {
42
+ success?: string;
43
+ failed?: string;
44
+ };
45
+
46
+ export type AllQuickStartStates = Record<string, QuickStartState>;
47
+
48
+ export type QuickStartState = Record<string, string | number | QuickStartStatus>;
49
+
50
+ export enum QuickStartStatus {
51
+ COMPLETE = 'Complete',
52
+ IN_PROGRESS = 'In Progress',
53
+ NOT_STARTED = 'Not started',
54
+ }
55
+
56
+ export enum QuickStartTaskStatus {
57
+ INIT = 'Initial',
58
+ VISITED = 'Visited',
59
+ REVIEW = 'Review',
60
+ SUCCESS = 'Success',
61
+ FAILED = 'Failed',
62
+ }
63
+
64
+ export type QuickStartExternal = {
65
+ href: string;
66
+ text?: string;
67
+ };
68
+
69
+ export type QuickStartType = {
70
+ text: string;
71
+ color?: 'blue' | 'cyan' | 'green' | 'orange' | 'purple' | 'red' | 'grey';
72
+ };