@patternfly/quickstarts 5.0.0-prerelease.1 → 5.0.0-prerelease.2

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 (116) hide show
  1. package/dist/ConsoleInternal/components/markdown-view.d.ts +19 -19
  2. package/dist/ConsoleInternal/components/utils/camel-case-wrap.d.ts +6 -6
  3. package/dist/ConsoleInternal/components/utils/index.d.ts +3 -3
  4. package/dist/ConsoleInternal/components/utils/router.d.ts +9 -9
  5. package/dist/ConsoleInternal/components/utils/status-box.d.ts +20 -20
  6. package/dist/ConsoleInternal/module/k8s/types.d.ts +42 -42
  7. package/dist/ConsoleShared/index.d.ts +1 -1
  8. package/dist/ConsoleShared/src/components/index.d.ts +7 -7
  9. package/dist/ConsoleShared/src/components/markdown-extensions/MarkdownCopyClipboard.d.ts +13 -13
  10. package/dist/ConsoleShared/src/components/markdown-extensions/accordion-extension.d.ts +7 -7
  11. package/dist/ConsoleShared/src/components/markdown-extensions/accordion-render-extension.d.ts +6 -6
  12. package/dist/ConsoleShared/src/components/markdown-extensions/admonition-extension.d.ts +7 -7
  13. package/dist/ConsoleShared/src/components/markdown-extensions/code-extension.d.ts +7 -7
  14. package/dist/ConsoleShared/src/components/markdown-extensions/const.d.ts +5 -5
  15. package/dist/ConsoleShared/src/components/markdown-extensions/index.d.ts +7 -7
  16. package/dist/ConsoleShared/src/components/markdown-extensions/inline-clipboard-extension.d.ts +7 -7
  17. package/dist/ConsoleShared/src/components/markdown-extensions/multiline-clipboard-extension.d.ts +7 -7
  18. package/dist/ConsoleShared/src/components/markdown-extensions/utils.d.ts +1 -1
  19. package/dist/ConsoleShared/src/components/markdown-highlight-extension/MarkdownHighlightExtension.d.ts +7 -7
  20. package/dist/ConsoleShared/src/components/markdown-highlight-extension/highlight-consts.d.ts +4 -4
  21. package/dist/ConsoleShared/src/components/markdown-highlight-extension/index.d.ts +1 -1
  22. package/dist/ConsoleShared/src/components/modal/Modal.d.ts +9 -9
  23. package/dist/ConsoleShared/src/components/modal/index.d.ts +1 -1
  24. package/dist/ConsoleShared/src/components/popper/Portal.d.ts +8 -8
  25. package/dist/ConsoleShared/src/components/popper/SimplePopper.d.ts +6 -6
  26. package/dist/ConsoleShared/src/components/popper/index.d.ts +2 -2
  27. package/dist/ConsoleShared/src/components/spotlight/InteractiveSpotlight.d.ts +7 -7
  28. package/dist/ConsoleShared/src/components/spotlight/Spotlight.d.ts +7 -7
  29. package/dist/ConsoleShared/src/components/spotlight/StaticSpotlight.d.ts +7 -7
  30. package/dist/ConsoleShared/src/components/spotlight/index.d.ts +1 -1
  31. package/dist/ConsoleShared/src/components/status/GenericStatus.d.ts +12 -12
  32. package/dist/ConsoleShared/src/components/status/NotStartedIcon.d.ts +3 -3
  33. package/dist/ConsoleShared/src/components/status/PopoverStatus.d.ts +13 -13
  34. package/dist/ConsoleShared/src/components/status/Status.d.ts +11 -11
  35. package/dist/ConsoleShared/src/components/status/StatusIconAndText.d.ts +8 -8
  36. package/dist/ConsoleShared/src/components/status/icons.d.ts +9 -9
  37. package/dist/ConsoleShared/src/components/status/index.d.ts +1 -1
  38. package/dist/ConsoleShared/src/components/status/statuses.d.ts +5 -5
  39. package/dist/ConsoleShared/src/components/status/types.d.ts +9 -9
  40. package/dist/ConsoleShared/src/components/utils/FallbackImg.d.ts +9 -9
  41. package/dist/ConsoleShared/src/components/utils/index.d.ts +1 -1
  42. package/dist/ConsoleShared/src/constants/index.d.ts +1 -1
  43. package/dist/ConsoleShared/src/constants/ui.d.ts +1 -1
  44. package/dist/ConsoleShared/src/hooks/index.d.ts +6 -6
  45. package/dist/ConsoleShared/src/hooks/scroll.d.ts +8 -8
  46. package/dist/ConsoleShared/src/hooks/useBoundingClientRect.d.ts +3 -3
  47. package/dist/ConsoleShared/src/hooks/useEventListener.d.ts +1 -1
  48. package/dist/ConsoleShared/src/hooks/useForceRender.d.ts +4 -4
  49. package/dist/ConsoleShared/src/hooks/useResizeObserver.d.ts +1 -1
  50. package/dist/ConsoleShared/src/hooks/useScrollShadows.d.ts +7 -7
  51. package/dist/ConsoleShared/src/index.d.ts +4 -4
  52. package/dist/ConsoleShared/src/utils/index.d.ts +1 -1
  53. package/dist/ConsoleShared/src/utils/useCombineRefs.d.ts +2 -2
  54. package/dist/HelpTopicDrawer.d.ts +33 -33
  55. package/dist/HelpTopicPanelContent.d.ts +11 -11
  56. package/dist/QuickStartCatalogPage.d.ts +14 -14
  57. package/dist/QuickStartCloseModal.d.ts +8 -8
  58. package/dist/QuickStartController.d.ts +10 -10
  59. package/dist/QuickStartDrawer.d.ts +62 -62
  60. package/dist/QuickStartMarkdownView.d.ts +9 -9
  61. package/dist/QuickStartPanelContent.d.ts +15 -15
  62. package/dist/catalog/Catalog/QuickStartCatalogHeader.d.ts +6 -6
  63. package/dist/catalog/Catalog/QuickStartCatalogSection.d.ts +5 -5
  64. package/dist/catalog/Catalog/QuickStartCatalogToolbar.d.ts +5 -5
  65. package/dist/catalog/Catalog/index.d.ts +3 -3
  66. package/dist/catalog/QuickStartCatalog.d.ts +8 -8
  67. package/dist/catalog/QuickStartTile.d.ts +11 -11
  68. package/dist/catalog/QuickStartTileDescription.d.ts +8 -8
  69. package/dist/catalog/QuickStartTileFooter.d.ts +8 -8
  70. package/dist/catalog/QuickStartTileFooterExternal.d.ts +8 -8
  71. package/dist/catalog/QuickStartTileHeader.d.ts +12 -12
  72. package/dist/catalog/Toolbar/QuickStartCatalogFilter.d.ts +10 -10
  73. package/dist/catalog/Toolbar/QuickStartCatalogFilterItems.d.ts +31 -31
  74. package/dist/catalog/index.d.ts +9 -9
  75. package/dist/controller/QuickStartConclusion.d.ts +12 -12
  76. package/dist/controller/QuickStartContent.d.ts +14 -14
  77. package/dist/controller/QuickStartFooter.d.ts +14 -14
  78. package/dist/controller/QuickStartIntroduction.d.ts +12 -12
  79. package/dist/controller/QuickStartTaskHeader.d.ts +15 -15
  80. package/dist/controller/QuickStartTaskHeaderList.d.ts +10 -10
  81. package/dist/controller/QuickStartTaskReview.d.ts +10 -10
  82. package/dist/controller/QuickStartTasks.d.ts +12 -12
  83. package/dist/data/mocks/json/explore-pipeline-quickstart.d.ts +2 -2
  84. package/dist/data/mocks/json/explore-serverless-quickstart.d.ts +2 -2
  85. package/dist/data/mocks/json/monitor-sampleapp-quickstart.d.ts +2 -2
  86. package/dist/data/mocks/json/tour-icons.d.ts +2 -2
  87. package/dist/data/quick-start-test-data.d.ts +2 -2
  88. package/dist/data/test-utils.d.ts +8 -8
  89. package/dist/index.d.ts +16 -16
  90. package/dist/index.es.js +2296 -2291
  91. package/dist/index.es.js.map +1 -1
  92. package/dist/index.js +2296 -2291
  93. package/dist/index.js.map +1 -1
  94. package/dist/patternfly-nested.css +66 -508
  95. package/dist/quickstarts-base.css +1 -1
  96. package/dist/quickstarts-full.es.js +2528 -2557
  97. package/dist/quickstarts-full.es.js.map +1 -1
  98. package/dist/quickstarts-standalone.css +1 -1
  99. package/dist/quickstarts-standalone.min.css +2 -2
  100. package/dist/quickstarts.css +1 -1
  101. package/dist/quickstarts.min.css +1 -1
  102. package/dist/styles/patternfly-global-entry.d.ts +1 -1
  103. package/dist/styles/patternfly-nested-entry.d.ts +1 -1
  104. package/dist/styles/quickstarts-standalone-entry.d.ts +1 -1
  105. package/dist/styles/vendor-entry.d.ts +1 -1
  106. package/dist/utils/PluralResolver.d.ts +16 -16
  107. package/dist/utils/asciidoc-procedure-parser.d.ts +12 -12
  108. package/dist/utils/const.d.ts +6 -6
  109. package/dist/utils/help-topic-context.d.ts +23 -23
  110. package/dist/utils/help-topic-types.d.ts +13 -13
  111. package/dist/utils/quick-start-context.d.ts +81 -81
  112. package/dist/utils/quick-start-types.d.ts +60 -60
  113. package/dist/utils/quick-start-utils.d.ts +10 -10
  114. package/dist/utils/useLocalStorage.d.ts +1 -1
  115. package/package.json +10 -10
  116. package/src/styles/_dark-custom-override.scss +1 -1
package/dist/index.es.js CHANGED
@@ -53,66 +53,66 @@ m.Pop;a=b();var q=a[0],l=a[1],c=B(),e=B();null==q&&(q=0,f.replaceState(_extends(
53
53
  y(_extends({pathname:"/",search:"",hash:"",state:null,key:D()},"string"===typeof a?F(a):a));"production"!==process.env.NODE_ENV?z("/"===b.pathname.charAt(0),"Relative pathnames are not supported in createMemoryHistory({ initialEntries }) (invalid entry: "+JSON.stringify(a)+")"):void 0;return b}),f=Math.min(Math.max(null==r?h.length-1:r,0),h.length-1),p=m.Pop,n=h[f],q=B(),l=B();return {get index(){return f},get action(){return p},get location(){return n},createHref:function(a){return "string"===typeof a?
54
54
  a:E(a)},push:v,replace:w,go:u,back:function(){u(-1);},forward:function(){u(1);},listen:function(a){return q.push(a)},block:function(a){return l.push(a)}}}
55
55
 
56
- var QuickStartStatus;
57
- (function (QuickStartStatus) {
58
- QuickStartStatus["COMPLETE"] = "Complete";
59
- QuickStartStatus["IN_PROGRESS"] = "In Progress";
60
- QuickStartStatus["NOT_STARTED"] = "Not started";
61
- })(QuickStartStatus || (QuickStartStatus = {}));
62
- var QuickStartTaskStatus;
63
- (function (QuickStartTaskStatus) {
64
- QuickStartTaskStatus["INIT"] = "Initial";
65
- QuickStartTaskStatus["VISITED"] = "Visited";
66
- QuickStartTaskStatus["REVIEW"] = "Review";
67
- QuickStartTaskStatus["SUCCESS"] = "Success";
68
- QuickStartTaskStatus["FAILED"] = "Failed";
56
+ var QuickStartStatus;
57
+ (function (QuickStartStatus) {
58
+ QuickStartStatus["COMPLETE"] = "Complete";
59
+ QuickStartStatus["IN_PROGRESS"] = "In Progress";
60
+ QuickStartStatus["NOT_STARTED"] = "Not started";
61
+ })(QuickStartStatus || (QuickStartStatus = {}));
62
+ var QuickStartTaskStatus;
63
+ (function (QuickStartTaskStatus) {
64
+ QuickStartTaskStatus["INIT"] = "Initial";
65
+ QuickStartTaskStatus["VISITED"] = "Visited";
66
+ QuickStartTaskStatus["REVIEW"] = "Review";
67
+ QuickStartTaskStatus["SUCCESS"] = "Success";
68
+ QuickStartTaskStatus["FAILED"] = "Failed";
69
69
  })(QuickStartTaskStatus || (QuickStartTaskStatus = {}));
70
70
 
71
- const QUICKSTART_SEARCH_FILTER_KEY = 'keyword';
72
- const QUICKSTART_STATUS_FILTER_KEY = 'status';
73
- const QUICKSTART_ID_FILTER_KEY = 'quickstart';
74
- const QUICKSTART_TASKS_INITIAL_STATES = [
75
- QuickStartTaskStatus.INIT,
76
- QuickStartTaskStatus.VISITED,
77
- ];
71
+ const QUICKSTART_SEARCH_FILTER_KEY = 'keyword';
72
+ const QUICKSTART_STATUS_FILTER_KEY = 'status';
73
+ const QUICKSTART_ID_FILTER_KEY = 'quickstart';
74
+ const QUICKSTART_TASKS_INITIAL_STATES = [
75
+ QuickStartTaskStatus.INIT,
76
+ QuickStartTaskStatus.VISITED,
77
+ ];
78
78
  const HELP_TOPIC_NAME_KEY = 'topic';
79
79
 
80
- let createHistory;
81
- try {
82
- if (process.env.NODE_ENV === 'test') {
83
- // Running in node. Can't use browser history
84
- createHistory = createMemoryHistory;
85
- }
86
- else {
87
- createHistory = createBrowserHistory;
88
- }
89
- }
90
- catch (unused) {
91
- createHistory = createBrowserHistory;
92
- }
93
- const history = createHistory();
94
- const removeQueryArgument = (k) => {
95
- const params = new URLSearchParams(window.location.search);
96
- if (params.has(k)) {
97
- params.delete(k);
98
- const url = new URL(window.location.href);
99
- history.replace(`${url.pathname}?${params.toString()}${url.hash}`);
100
- }
101
- };
102
- const setQueryArgument = (k, v) => {
103
- if (!v) {
104
- return removeQueryArgument(k);
105
- }
106
- const params = new URLSearchParams(window.location.search);
107
- if (params.get(k) !== v) {
108
- params.set(k, v);
109
- const url = new URL(window.location.href);
110
- history.replace(`${url.pathname}?${params.toString()}${url.hash}`);
111
- }
112
- };
113
- const clearFilterParams = () => {
114
- removeQueryArgument(QUICKSTART_SEARCH_FILTER_KEY);
115
- removeQueryArgument(QUICKSTART_STATUS_FILTER_KEY);
80
+ let createHistory;
81
+ try {
82
+ if (process.env.NODE_ENV === 'test') {
83
+ // Running in node. Can't use browser history
84
+ createHistory = createMemoryHistory;
85
+ }
86
+ else {
87
+ createHistory = createBrowserHistory;
88
+ }
89
+ }
90
+ catch (unused) {
91
+ createHistory = createBrowserHistory;
92
+ }
93
+ const history = createHistory();
94
+ const removeQueryArgument = (k) => {
95
+ const params = new URLSearchParams(window.location.search);
96
+ if (params.has(k)) {
97
+ params.delete(k);
98
+ const url = new URL(window.location.href);
99
+ history.replace(`${url.pathname}?${params.toString()}${url.hash}`);
100
+ }
101
+ };
102
+ const setQueryArgument = (k, v) => {
103
+ if (!v) {
104
+ return removeQueryArgument(k);
105
+ }
106
+ const params = new URLSearchParams(window.location.search);
107
+ if (params.get(k) !== v) {
108
+ params.set(k, v);
109
+ const url = new URL(window.location.href);
110
+ history.replace(`${url.pathname}?${params.toString()}${url.hash}`);
111
+ }
112
+ };
113
+ const clearFilterParams = () => {
114
+ removeQueryArgument(QUICKSTART_SEARCH_FILTER_KEY);
115
+ removeQueryArgument(QUICKSTART_STATUS_FILTER_KEY);
116
116
  };
117
117
 
118
118
  var Status$1 = "Status";
@@ -176,672 +176,672 @@ var en = {
176
176
  "{{type}} • {{duration, number}} minutes": "{{type}} • {{duration, number}} minutes"
177
177
  };
178
178
 
179
- /* eslint-disable */
180
- // https://github.com/i18next/i18next/blob/master/src/PluralResolver.js
181
- const sets = [
182
- {
183
- lngs: [
184
- 'ach',
185
- 'ak',
186
- 'am',
187
- 'arn',
188
- 'br',
189
- 'fil',
190
- 'gun',
191
- 'ln',
192
- 'mfe',
193
- 'mg',
194
- 'mi',
195
- 'oc',
196
- 'pt',
197
- 'pt-BR',
198
- 'tg',
199
- 'tl',
200
- 'ti',
201
- 'tr',
202
- 'uz',
203
- 'wa',
204
- ],
205
- nr: [1, 2],
206
- fc: 1,
207
- },
208
- {
209
- lngs: [
210
- 'af',
211
- 'an',
212
- 'ast',
213
- 'az',
214
- 'bg',
215
- 'bn',
216
- 'ca',
217
- 'da',
218
- 'de',
219
- 'dev',
220
- 'el',
221
- 'en',
222
- 'eo',
223
- 'es',
224
- 'et',
225
- 'eu',
226
- 'fi',
227
- 'fo',
228
- 'fur',
229
- 'fy',
230
- 'gl',
231
- 'gu',
232
- 'ha',
233
- 'hi',
234
- 'hu',
235
- 'hy',
236
- 'ia',
237
- 'it',
238
- 'kk',
239
- 'kn',
240
- 'ku',
241
- 'lb',
242
- 'mai',
243
- 'ml',
244
- 'mn',
245
- 'mr',
246
- 'nah',
247
- 'nap',
248
- 'nb',
249
- 'ne',
250
- 'nl',
251
- 'nn',
252
- 'no',
253
- 'nso',
254
- 'pa',
255
- 'pap',
256
- 'pms',
257
- 'ps',
258
- 'pt-PT',
259
- 'rm',
260
- 'sco',
261
- 'se',
262
- 'si',
263
- 'so',
264
- 'son',
265
- 'sq',
266
- 'sv',
267
- 'sw',
268
- 'ta',
269
- 'te',
270
- 'tk',
271
- 'ur',
272
- 'yo',
273
- ],
274
- nr: [1, 2],
275
- fc: 2,
276
- },
277
- {
278
- lngs: [
279
- 'ay',
280
- 'bo',
281
- 'cgg',
282
- 'fa',
283
- 'ht',
284
- 'id',
285
- 'ja',
286
- 'jbo',
287
- 'ka',
288
- 'km',
289
- 'ko',
290
- 'ky',
291
- 'lo',
292
- 'ms',
293
- 'sah',
294
- 'su',
295
- 'th',
296
- 'tt',
297
- 'ug',
298
- 'vi',
299
- 'wo',
300
- 'zh',
301
- ],
302
- nr: [1],
303
- fc: 3,
304
- },
305
- { lngs: ['be', 'bs', 'cnr', 'dz', 'hr', 'ru', 'sr', 'uk'], nr: [1, 2, 5], fc: 4 },
306
- { lngs: ['ar'], nr: [0, 1, 2, 3, 11, 100], fc: 5 },
307
- { lngs: ['cs', 'sk'], nr: [1, 2, 5], fc: 6 },
308
- { lngs: ['csb', 'pl'], nr: [1, 2, 5], fc: 7 },
309
- { lngs: ['cy'], nr: [1, 2, 3, 8], fc: 8 },
310
- { lngs: ['fr'], nr: [1, 2], fc: 9 },
311
- { lngs: ['ga'], nr: [1, 2, 3, 7, 11], fc: 10 },
312
- { lngs: ['gd'], nr: [1, 2, 3, 20], fc: 11 },
313
- { lngs: ['is'], nr: [1, 2], fc: 12 },
314
- { lngs: ['jv'], nr: [0, 1], fc: 13 },
315
- { lngs: ['kw'], nr: [1, 2, 3, 4], fc: 14 },
316
- { lngs: ['lt'], nr: [1, 2, 10], fc: 15 },
317
- { lngs: ['lv'], nr: [1, 2, 0], fc: 16 },
318
- { lngs: ['mk'], nr: [1, 2], fc: 17 },
319
- { lngs: ['mnk'], nr: [0, 1, 2], fc: 18 },
320
- { lngs: ['mt'], nr: [1, 2, 11, 20], fc: 19 },
321
- { lngs: ['or'], nr: [2, 1], fc: 2 },
322
- { lngs: ['ro'], nr: [1, 2, 20], fc: 20 },
323
- { lngs: ['sl'], nr: [5, 1, 2, 3], fc: 21 },
324
- { lngs: ['he', 'iw'], nr: [1, 2, 20, 21], fc: 22 },
325
- ];
326
- const _rulesPluralsTypes = {
327
- 1: function (n) {
328
- return Number(n > 1);
329
- },
330
- 2: function (n) {
331
- return Number(n != 1);
332
- },
333
- 3: function (n) {
334
- return 0;
335
- },
336
- 4: function (n) {
337
- return Number(n % 10 == 1 && n % 100 != 11
338
- ? 0
339
- : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20)
340
- ? 1
341
- : 2);
342
- },
343
- 5: function (n) {
344
- return Number(n == 0
345
- ? 0
346
- : n == 1
347
- ? 1
348
- : n == 2
349
- ? 2
350
- : n % 100 >= 3 && n % 100 <= 10
351
- ? 3
352
- : n % 100 >= 11
353
- ? 4
354
- : 5);
355
- },
356
- 6: function (n) {
357
- return Number(n == 1 ? 0 : n >= 2 && n <= 4 ? 1 : 2);
358
- },
359
- 7: function (n) {
360
- return Number(n == 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
361
- },
362
- 8: function (n) {
363
- return Number(n == 1 ? 0 : n == 2 ? 1 : n != 8 && n != 11 ? 2 : 3);
364
- },
365
- 9: function (n) {
366
- return Number(n >= 2);
367
- },
368
- 10: function (n) {
369
- return Number(n == 1 ? 0 : n == 2 ? 1 : n < 7 ? 2 : n < 11 ? 3 : 4);
370
- },
371
- 11: function (n) {
372
- return Number(n == 1 || n == 11 ? 0 : n == 2 || n == 12 ? 1 : n > 2 && n < 20 ? 2 : 3);
373
- },
374
- 12: function (n) {
375
- return Number(n % 10 != 1 || n % 100 == 11);
376
- },
377
- 13: function (n) {
378
- return Number(n !== 0);
379
- },
380
- 14: function (n) {
381
- return Number(n == 1 ? 0 : n == 2 ? 1 : n == 3 ? 2 : 3);
382
- },
383
- 15: function (n) {
384
- return Number(n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
385
- },
386
- 16: function (n) {
387
- return Number(n % 10 == 1 && n % 100 != 11 ? 0 : n !== 0 ? 1 : 2);
388
- },
389
- 17: function (n) {
390
- return Number(n == 1 || (n % 10 == 1 && n % 100 != 11) ? 0 : 1);
391
- },
392
- 18: function (n) {
393
- return Number(n == 0 ? 0 : n == 1 ? 1 : 2);
394
- },
395
- 19: function (n) {
396
- return Number(n == 1
397
- ? 0
398
- : n == 0 || (n % 100 > 1 && n % 100 < 11)
399
- ? 1
400
- : n % 100 > 10 && n % 100 < 20
401
- ? 2
402
- : 3);
403
- },
404
- 20: function (n) {
405
- return Number(n == 1 ? 0 : n == 0 || (n % 100 > 0 && n % 100 < 20) ? 1 : 2);
406
- },
407
- 21: function (n) {
408
- return Number(n % 100 == 1 ? 1 : n % 100 == 2 ? 2 : n % 100 == 3 || n % 100 == 4 ? 3 : 0);
409
- },
410
- 22: function (n) {
411
- return Number(n == 1 ? 0 : n == 2 ? 1 : (n < 0 || n > 10) && n % 10 == 0 ? 2 : 3);
412
- },
413
- };
414
- function createRules() {
415
- const rules = {};
416
- sets.forEach((set) => {
417
- set.lngs.forEach((l) => {
418
- rules[l] = {
419
- numbers: set.nr,
420
- plurals: _rulesPluralsTypes[set.fc],
421
- };
422
- });
423
- });
424
- return rules;
425
- }
426
- class PluralResolver {
427
- constructor(options = {}) {
428
- this.options = options;
429
- this.rules = createRules();
430
- }
431
- addRule(lng, obj) {
432
- this.rules[lng] = obj;
433
- }
434
- getRule(code) {
435
- return this.rules[code];
436
- }
437
- needsPlural(code) {
438
- const rule = this.getRule(code);
439
- return rule && rule.numbers.length > 1;
440
- }
441
- getPluralFormsOfKey(code, key) {
442
- return this.getSuffixes(code).map((suffix) => key + suffix);
443
- }
444
- getSuffixes(code) {
445
- const rule = this.getRule(code);
446
- if (!rule) {
447
- return [];
448
- }
449
- return rule.numbers.map((number) => this.getSuffix(code, number));
450
- }
451
- getSuffix(code, count) {
452
- const rule = this.getRule(code);
453
- if (rule) {
454
- // if (rule.numbers.length === 1) return ''; // only singular
455
- const idx = rule.noAbs ? rule.plurals(count) : rule.plurals(Math.abs(count));
456
- let suffix = rule.numbers[idx];
457
- // special treatment for lngs only having singular and plural
458
- if (this.options.simplifyPluralSuffix && rule.numbers.length === 2 && rule.numbers[0] === 1) {
459
- if (suffix === 2) {
460
- suffix = 'plural';
461
- }
462
- else if (suffix === 1) {
463
- suffix = '';
464
- }
465
- }
466
- const returnSuffix = () => this.options.prepend && suffix.toString()
467
- ? this.options.prepend + suffix.toString()
468
- : suffix.toString();
469
- // COMPATIBILITY JSON
470
- // v1
471
- if (this.options.compatibilityJSON === 'v1') {
472
- if (suffix === 1) {
473
- return '';
474
- }
475
- if (typeof suffix === 'number') {
476
- return `_plural_${suffix.toString()}`;
477
- }
478
- return returnSuffix();
479
- }
480
- if ( /* v2 */this.options.compatibilityJSON === 'v2') {
481
- return returnSuffix();
482
- }
483
- if (
484
- /* v3 - gettext index */ this.options.simplifyPluralSuffix &&
485
- rule.numbers.length === 2 &&
486
- rule.numbers[0] === 1) {
487
- return returnSuffix();
488
- }
489
- return this.options.prepend && idx.toString()
490
- ? this.options.prepend + idx.toString()
491
- : idx.toString();
492
- }
493
- // this.logger.warn(`no plural rule found for: ${code}`);
494
- return '';
495
- }
179
+ /* eslint-disable */
180
+ // https://github.com/i18next/i18next/blob/master/src/PluralResolver.js
181
+ const sets = [
182
+ {
183
+ lngs: [
184
+ 'ach',
185
+ 'ak',
186
+ 'am',
187
+ 'arn',
188
+ 'br',
189
+ 'fil',
190
+ 'gun',
191
+ 'ln',
192
+ 'mfe',
193
+ 'mg',
194
+ 'mi',
195
+ 'oc',
196
+ 'pt',
197
+ 'pt-BR',
198
+ 'tg',
199
+ 'tl',
200
+ 'ti',
201
+ 'tr',
202
+ 'uz',
203
+ 'wa',
204
+ ],
205
+ nr: [1, 2],
206
+ fc: 1,
207
+ },
208
+ {
209
+ lngs: [
210
+ 'af',
211
+ 'an',
212
+ 'ast',
213
+ 'az',
214
+ 'bg',
215
+ 'bn',
216
+ 'ca',
217
+ 'da',
218
+ 'de',
219
+ 'dev',
220
+ 'el',
221
+ 'en',
222
+ 'eo',
223
+ 'es',
224
+ 'et',
225
+ 'eu',
226
+ 'fi',
227
+ 'fo',
228
+ 'fur',
229
+ 'fy',
230
+ 'gl',
231
+ 'gu',
232
+ 'ha',
233
+ 'hi',
234
+ 'hu',
235
+ 'hy',
236
+ 'ia',
237
+ 'it',
238
+ 'kk',
239
+ 'kn',
240
+ 'ku',
241
+ 'lb',
242
+ 'mai',
243
+ 'ml',
244
+ 'mn',
245
+ 'mr',
246
+ 'nah',
247
+ 'nap',
248
+ 'nb',
249
+ 'ne',
250
+ 'nl',
251
+ 'nn',
252
+ 'no',
253
+ 'nso',
254
+ 'pa',
255
+ 'pap',
256
+ 'pms',
257
+ 'ps',
258
+ 'pt-PT',
259
+ 'rm',
260
+ 'sco',
261
+ 'se',
262
+ 'si',
263
+ 'so',
264
+ 'son',
265
+ 'sq',
266
+ 'sv',
267
+ 'sw',
268
+ 'ta',
269
+ 'te',
270
+ 'tk',
271
+ 'ur',
272
+ 'yo',
273
+ ],
274
+ nr: [1, 2],
275
+ fc: 2,
276
+ },
277
+ {
278
+ lngs: [
279
+ 'ay',
280
+ 'bo',
281
+ 'cgg',
282
+ 'fa',
283
+ 'ht',
284
+ 'id',
285
+ 'ja',
286
+ 'jbo',
287
+ 'ka',
288
+ 'km',
289
+ 'ko',
290
+ 'ky',
291
+ 'lo',
292
+ 'ms',
293
+ 'sah',
294
+ 'su',
295
+ 'th',
296
+ 'tt',
297
+ 'ug',
298
+ 'vi',
299
+ 'wo',
300
+ 'zh',
301
+ ],
302
+ nr: [1],
303
+ fc: 3,
304
+ },
305
+ { lngs: ['be', 'bs', 'cnr', 'dz', 'hr', 'ru', 'sr', 'uk'], nr: [1, 2, 5], fc: 4 },
306
+ { lngs: ['ar'], nr: [0, 1, 2, 3, 11, 100], fc: 5 },
307
+ { lngs: ['cs', 'sk'], nr: [1, 2, 5], fc: 6 },
308
+ { lngs: ['csb', 'pl'], nr: [1, 2, 5], fc: 7 },
309
+ { lngs: ['cy'], nr: [1, 2, 3, 8], fc: 8 },
310
+ { lngs: ['fr'], nr: [1, 2], fc: 9 },
311
+ { lngs: ['ga'], nr: [1, 2, 3, 7, 11], fc: 10 },
312
+ { lngs: ['gd'], nr: [1, 2, 3, 20], fc: 11 },
313
+ { lngs: ['is'], nr: [1, 2], fc: 12 },
314
+ { lngs: ['jv'], nr: [0, 1], fc: 13 },
315
+ { lngs: ['kw'], nr: [1, 2, 3, 4], fc: 14 },
316
+ { lngs: ['lt'], nr: [1, 2, 10], fc: 15 },
317
+ { lngs: ['lv'], nr: [1, 2, 0], fc: 16 },
318
+ { lngs: ['mk'], nr: [1, 2], fc: 17 },
319
+ { lngs: ['mnk'], nr: [0, 1, 2], fc: 18 },
320
+ { lngs: ['mt'], nr: [1, 2, 11, 20], fc: 19 },
321
+ { lngs: ['or'], nr: [2, 1], fc: 2 },
322
+ { lngs: ['ro'], nr: [1, 2, 20], fc: 20 },
323
+ { lngs: ['sl'], nr: [5, 1, 2, 3], fc: 21 },
324
+ { lngs: ['he', 'iw'], nr: [1, 2, 20, 21], fc: 22 },
325
+ ];
326
+ const _rulesPluralsTypes = {
327
+ 1: function (n) {
328
+ return Number(n > 1);
329
+ },
330
+ 2: function (n) {
331
+ return Number(n != 1);
332
+ },
333
+ 3: function (n) {
334
+ return 0;
335
+ },
336
+ 4: function (n) {
337
+ return Number(n % 10 == 1 && n % 100 != 11
338
+ ? 0
339
+ : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20)
340
+ ? 1
341
+ : 2);
342
+ },
343
+ 5: function (n) {
344
+ return Number(n == 0
345
+ ? 0
346
+ : n == 1
347
+ ? 1
348
+ : n == 2
349
+ ? 2
350
+ : n % 100 >= 3 && n % 100 <= 10
351
+ ? 3
352
+ : n % 100 >= 11
353
+ ? 4
354
+ : 5);
355
+ },
356
+ 6: function (n) {
357
+ return Number(n == 1 ? 0 : n >= 2 && n <= 4 ? 1 : 2);
358
+ },
359
+ 7: function (n) {
360
+ return Number(n == 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
361
+ },
362
+ 8: function (n) {
363
+ return Number(n == 1 ? 0 : n == 2 ? 1 : n != 8 && n != 11 ? 2 : 3);
364
+ },
365
+ 9: function (n) {
366
+ return Number(n >= 2);
367
+ },
368
+ 10: function (n) {
369
+ return Number(n == 1 ? 0 : n == 2 ? 1 : n < 7 ? 2 : n < 11 ? 3 : 4);
370
+ },
371
+ 11: function (n) {
372
+ return Number(n == 1 || n == 11 ? 0 : n == 2 || n == 12 ? 1 : n > 2 && n < 20 ? 2 : 3);
373
+ },
374
+ 12: function (n) {
375
+ return Number(n % 10 != 1 || n % 100 == 11);
376
+ },
377
+ 13: function (n) {
378
+ return Number(n !== 0);
379
+ },
380
+ 14: function (n) {
381
+ return Number(n == 1 ? 0 : n == 2 ? 1 : n == 3 ? 2 : 3);
382
+ },
383
+ 15: function (n) {
384
+ return Number(n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
385
+ },
386
+ 16: function (n) {
387
+ return Number(n % 10 == 1 && n % 100 != 11 ? 0 : n !== 0 ? 1 : 2);
388
+ },
389
+ 17: function (n) {
390
+ return Number(n == 1 || (n % 10 == 1 && n % 100 != 11) ? 0 : 1);
391
+ },
392
+ 18: function (n) {
393
+ return Number(n == 0 ? 0 : n == 1 ? 1 : 2);
394
+ },
395
+ 19: function (n) {
396
+ return Number(n == 1
397
+ ? 0
398
+ : n == 0 || (n % 100 > 1 && n % 100 < 11)
399
+ ? 1
400
+ : n % 100 > 10 && n % 100 < 20
401
+ ? 2
402
+ : 3);
403
+ },
404
+ 20: function (n) {
405
+ return Number(n == 1 ? 0 : n == 0 || (n % 100 > 0 && n % 100 < 20) ? 1 : 2);
406
+ },
407
+ 21: function (n) {
408
+ return Number(n % 100 == 1 ? 1 : n % 100 == 2 ? 2 : n % 100 == 3 || n % 100 == 4 ? 3 : 0);
409
+ },
410
+ 22: function (n) {
411
+ return Number(n == 1 ? 0 : n == 2 ? 1 : (n < 0 || n > 10) && n % 10 == 0 ? 2 : 3);
412
+ },
413
+ };
414
+ function createRules() {
415
+ const rules = {};
416
+ sets.forEach((set) => {
417
+ set.lngs.forEach((l) => {
418
+ rules[l] = {
419
+ numbers: set.nr,
420
+ plurals: _rulesPluralsTypes[set.fc],
421
+ };
422
+ });
423
+ });
424
+ return rules;
425
+ }
426
+ class PluralResolver {
427
+ constructor(options = {}) {
428
+ this.options = options;
429
+ this.rules = createRules();
430
+ }
431
+ addRule(lng, obj) {
432
+ this.rules[lng] = obj;
433
+ }
434
+ getRule(code) {
435
+ return this.rules[code];
436
+ }
437
+ needsPlural(code) {
438
+ const rule = this.getRule(code);
439
+ return rule && rule.numbers.length > 1;
440
+ }
441
+ getPluralFormsOfKey(code, key) {
442
+ return this.getSuffixes(code).map((suffix) => key + suffix);
443
+ }
444
+ getSuffixes(code) {
445
+ const rule = this.getRule(code);
446
+ if (!rule) {
447
+ return [];
448
+ }
449
+ return rule.numbers.map((number) => this.getSuffix(code, number));
450
+ }
451
+ getSuffix(code, count) {
452
+ const rule = this.getRule(code);
453
+ if (rule) {
454
+ // if (rule.numbers.length === 1) return ''; // only singular
455
+ const idx = rule.noAbs ? rule.plurals(count) : rule.plurals(Math.abs(count));
456
+ let suffix = rule.numbers[idx];
457
+ // special treatment for lngs only having singular and plural
458
+ if (this.options.simplifyPluralSuffix && rule.numbers.length === 2 && rule.numbers[0] === 1) {
459
+ if (suffix === 2) {
460
+ suffix = 'plural';
461
+ }
462
+ else if (suffix === 1) {
463
+ suffix = '';
464
+ }
465
+ }
466
+ const returnSuffix = () => this.options.prepend && suffix.toString()
467
+ ? this.options.prepend + suffix.toString()
468
+ : suffix.toString();
469
+ // COMPATIBILITY JSON
470
+ // v1
471
+ if (this.options.compatibilityJSON === 'v1') {
472
+ if (suffix === 1) {
473
+ return '';
474
+ }
475
+ if (typeof suffix === 'number') {
476
+ return `_plural_${suffix.toString()}`;
477
+ }
478
+ return returnSuffix();
479
+ }
480
+ if ( /* v2 */this.options.compatibilityJSON === 'v2') {
481
+ return returnSuffix();
482
+ }
483
+ if (
484
+ /* v3 - gettext index */ this.options.simplifyPluralSuffix &&
485
+ rule.numbers.length === 2 &&
486
+ rule.numbers[0] === 1) {
487
+ return returnSuffix();
488
+ }
489
+ return this.options.prepend && idx.toString()
490
+ ? this.options.prepend + idx.toString()
491
+ : idx.toString();
492
+ }
493
+ // this.logger.warn(`no plural rule found for: ${code}`);
494
+ return '';
495
+ }
496
496
  }
497
497
 
498
- const QUICK_START_NAME = 'console.openshift.io/name';
499
- const getQuickStartByName = (name, quickStarts) => quickStarts.find((quickStart) => quickStart.metadata.name === name);
500
- const getQuickStartStatus = (allQuickStartStates, quickStartID) => { var _a, _b; return (_b = (_a = allQuickStartStates === null || allQuickStartStates === void 0 ? void 0 : allQuickStartStates[quickStartID]) === null || _a === void 0 ? void 0 : _a.status) !== null && _b !== void 0 ? _b : QuickStartStatus.NOT_STARTED; };
501
- const getTaskStatusKey = (taskNumber) => `taskStatus${taskNumber}`;
502
- const getQuickStartStatusCount = (allQuickStartStates, quickStarts) => quickStarts.reduce((totals, item) => {
503
- totals[getQuickStartStatus(allQuickStartStates, item.metadata.name)]++;
504
- return totals;
505
- }, {
506
- [QuickStartStatus.IN_PROGRESS]: 0,
507
- [QuickStartStatus.COMPLETE]: 0,
508
- [QuickStartStatus.NOT_STARTED]: 0,
509
- });
510
- const getDisabledQuickStarts = () => {
511
- var _a, _b;
512
- let disabledQuickStarts = [];
513
- const quickStartServerData = (_a = window.SERVER_FLAGS) === null || _a === void 0 ? void 0 : _a.quickStarts;
514
- try {
515
- if (quickStartServerData) {
516
- disabledQuickStarts = (_b = JSON.parse(quickStartServerData).disabled) !== null && _b !== void 0 ? _b : [];
517
- }
518
- }
519
- catch (e) {
520
- // eslint-disable-next-line no-console
521
- console.error('error while parsing SERVER_FLAG.quickStarts', e);
522
- }
523
- return disabledQuickStarts;
524
- };
525
- const isDisabledQuickStart = (quickstart, disabledQuickStarts) => {
526
- var _a, _b;
527
- const quickStartName = (_b = (_a = quickstart.metadata.annotations) === null || _a === void 0 ? void 0 : _a[QUICK_START_NAME]) !== null && _b !== void 0 ? _b : quickstart.metadata.name;
528
- return disabledQuickStarts.includes(quickStartName);
529
- };
530
- const filterQuickStarts = (quickStarts, filterText, statusFilters, allQuickStartStates) => {
531
- const searchText = filterText.toLowerCase();
532
- return quickStarts.filter(({ metadata: { name }, spec: { displayName, prerequisites = [], description } }) => {
533
- const matchesFilter = statusFilters.length > 0
534
- ? statusFilters.includes(getQuickStartStatus(allQuickStartStates, name))
535
- : true;
536
- const matchesText = displayName.toLowerCase().includes(searchText) ||
537
- description.toLowerCase().includes(searchText) ||
538
- prerequisites.some((text) => text.toLowerCase().includes(searchText));
539
- return matchesFilter && matchesText;
540
- });
541
- };
542
- const camelize = (str) => str.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, function (match, index) {
543
- if (+match === 0) {
544
- return '';
545
- } // or if (/\s+/.test(match)) for white spaces
546
- return index === 0 ? match.toLowerCase() : match.toUpperCase();
498
+ const QUICK_START_NAME = 'console.openshift.io/name';
499
+ const getQuickStartByName = (name, quickStarts) => quickStarts.find((quickStart) => quickStart.metadata.name === name);
500
+ const getQuickStartStatus = (allQuickStartStates, quickStartID) => { var _a, _b; return (_b = (_a = allQuickStartStates === null || allQuickStartStates === void 0 ? void 0 : allQuickStartStates[quickStartID]) === null || _a === void 0 ? void 0 : _a.status) !== null && _b !== void 0 ? _b : QuickStartStatus.NOT_STARTED; };
501
+ const getTaskStatusKey = (taskNumber) => `taskStatus${taskNumber}`;
502
+ const getQuickStartStatusCount = (allQuickStartStates, quickStarts) => quickStarts.reduce((totals, item) => {
503
+ totals[getQuickStartStatus(allQuickStartStates, item.metadata.name)]++;
504
+ return totals;
505
+ }, {
506
+ [QuickStartStatus.IN_PROGRESS]: 0,
507
+ [QuickStartStatus.COMPLETE]: 0,
508
+ [QuickStartStatus.NOT_STARTED]: 0,
509
+ });
510
+ const getDisabledQuickStarts = () => {
511
+ var _a, _b;
512
+ let disabledQuickStarts = [];
513
+ const quickStartServerData = (_a = window.SERVER_FLAGS) === null || _a === void 0 ? void 0 : _a.quickStarts;
514
+ try {
515
+ if (quickStartServerData) {
516
+ disabledQuickStarts = (_b = JSON.parse(quickStartServerData).disabled) !== null && _b !== void 0 ? _b : [];
517
+ }
518
+ }
519
+ catch (e) {
520
+ // eslint-disable-next-line no-console
521
+ console.error('error while parsing SERVER_FLAG.quickStarts', e);
522
+ }
523
+ return disabledQuickStarts;
524
+ };
525
+ const isDisabledQuickStart = (quickstart, disabledQuickStarts) => {
526
+ var _a, _b;
527
+ const quickStartName = (_b = (_a = quickstart.metadata.annotations) === null || _a === void 0 ? void 0 : _a[QUICK_START_NAME]) !== null && _b !== void 0 ? _b : quickstart.metadata.name;
528
+ return disabledQuickStarts.includes(quickStartName);
529
+ };
530
+ const filterQuickStarts = (quickStarts, filterText, statusFilters, allQuickStartStates) => {
531
+ const searchText = filterText.toLowerCase();
532
+ return quickStarts.filter(({ metadata: { name }, spec: { displayName, prerequisites = [], description } }) => {
533
+ const matchesFilter = statusFilters.length > 0
534
+ ? statusFilters.includes(getQuickStartStatus(allQuickStartStates, name))
535
+ : true;
536
+ const matchesText = displayName.toLowerCase().includes(searchText) ||
537
+ description.toLowerCase().includes(searchText) ||
538
+ prerequisites.some((text) => text.toLowerCase().includes(searchText));
539
+ return matchesFilter && matchesText;
540
+ });
541
+ };
542
+ const camelize = (str) => str.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, function (match, index) {
543
+ if (+match === 0) {
544
+ return '';
545
+ } // or if (/\s+/.test(match)) for white spaces
546
+ return index === 0 ? match.toLowerCase() : match.toUpperCase();
547
547
  });
548
548
 
549
- const pluralResolver = new PluralResolver({ simplifyPluralSuffix: true });
550
- const getDefaultQuickStartState = (totalTasks, initialStatus) => {
551
- const defaultQuickStartState = {
552
- status: initialStatus || QuickStartStatus.NOT_STARTED,
553
- taskNumber: -1,
554
- };
555
- if (totalTasks) {
556
- for (let i = 0; i < totalTasks; i++) {
557
- defaultQuickStartState[getTaskStatusKey(i)] = QuickStartTaskStatus.INIT;
558
- }
559
- }
560
- return defaultQuickStartState;
561
- };
562
- const QuickStartContextDefaults = {
563
- allQuickStarts: [],
564
- activeQuickStartID: '',
565
- allQuickStartStates: {},
566
- activeQuickStartState: {},
567
- setAllQuickStarts: () => { },
568
- resourceBundle: en,
569
- getResource: (resource) => resource,
570
- language: 'en',
571
- useQueryParams: true,
572
- filter: {
573
- keyword: '',
574
- status: {
575
- statusTypes: {},
576
- statusFilters: [],
577
- },
578
- },
579
- setFilter: () => { },
580
- footer: null,
581
- useLegacyHeaderColors: false,
582
- markdown: null,
583
- loading: false,
584
- alwaysShowTaskReview: true,
585
- };
586
- const QuickStartContext = createContext(QuickStartContextDefaults);
587
- const getResource = (resource, options, resourceBundle, lng) => {
588
- if (options && !isNaN(options.count)) {
589
- const suffix = pluralResolver.getSuffix(lng, options.count);
590
- if (suffix && resourceBundle[`${resource}_${suffix}`]) {
591
- // needs plural
592
- return resourceBundle[`${resource}_${suffix}`];
593
- }
594
- }
595
- return (resourceBundle && resourceBundle[resource]) || resource;
596
- };
597
- const useValuesForQuickStartContext = (value = {}) => {
598
- var _a, _b;
599
- const combinedValue = Object.assign(Object.assign({}, QuickStartContextDefaults), value);
600
- const { activeQuickStartID, setActiveQuickStartID, setAllQuickStartStates, useQueryParams, allQuickStartStates, allQuickStarts = [], footer, useLegacyHeaderColors, markdown, } = combinedValue;
601
- const [quickStarts, setQuickStarts] = React__default.useState(combinedValue.allQuickStarts || []);
602
- const [resourceBundle, setResourceBundle] = React__default.useState(Object.assign(Object.assign({}, en), combinedValue.resourceBundle));
603
- const [language, setLanguage] = React__default.useState(combinedValue.language);
604
- const changeResourceBundle = (bundle, lng) => {
605
- lng && setLanguage(lng);
606
- setResourceBundle(Object.assign(Object.assign({}, en), bundle));
607
- };
608
- const findResource = useCallback((resource, count) => getResource(resource, count !== undefined ? { count } : null, resourceBundle, language), [resourceBundle, language]);
609
- const [loading, setLoading] = React__default.useState(combinedValue.loading);
610
- const [alwaysShowTaskReview, setAlwaysShowTaskReview] = React__default.useState(combinedValue.alwaysShowTaskReview);
611
- const initialSearchParams = new URLSearchParams(window.location.search);
612
- const initialSearchQuery = initialSearchParams.get(QUICKSTART_SEARCH_FILTER_KEY) || '';
613
- const initialStatusFilters = ((_a = initialSearchParams.get(QUICKSTART_STATUS_FILTER_KEY)) === null || _a === void 0 ? void 0 : _a.split(',')) || [];
614
- const quickStartStatusCount = getQuickStartStatusCount(allQuickStartStates, allQuickStarts);
615
- const [statusTypes, setStatusTypes] = React__default.useState({
616
- [QuickStartStatus.COMPLETE]: findResource('Complete ({{statusCount, number}})').replace('{{statusCount, number}}', quickStartStatusCount[QuickStartStatus.COMPLETE]),
617
- [QuickStartStatus.IN_PROGRESS]: findResource('In progress ({{statusCount, number}})').replace('{{statusCount, number}}', quickStartStatusCount[QuickStartStatus.IN_PROGRESS]),
618
- [QuickStartStatus.NOT_STARTED]: findResource('Not started ({{statusCount, number}})').replace('{{statusCount, number}}', quickStartStatusCount[QuickStartStatus.NOT_STARTED]),
619
- });
620
- const [statusFilters, setStatusFilters] = React__default.useState(initialStatusFilters);
621
- const [filterKeyword, setFilterKeyword] = React__default.useState(initialSearchQuery);
622
- const setFilter = (type, val) => {
623
- if (type === 'keyword') {
624
- setFilterKeyword(val);
625
- }
626
- else if (type === 'status') {
627
- setStatusFilters(val);
628
- }
629
- };
630
- React__default.useEffect(() => {
631
- const updatedQuickStartStatusCount = getQuickStartStatusCount(allQuickStartStates, quickStarts);
632
- setStatusTypes({
633
- [QuickStartStatus.COMPLETE]: findResource('Complete ({{statusCount, number}})').replace('{{statusCount, number}}', updatedQuickStartStatusCount[QuickStartStatus.COMPLETE]),
634
- [QuickStartStatus.IN_PROGRESS]: findResource('In progress ({{statusCount, number}})').replace('{{statusCount, number}}', updatedQuickStartStatusCount[QuickStartStatus.IN_PROGRESS]),
635
- [QuickStartStatus.NOT_STARTED]: findResource('Not started ({{statusCount, number}})').replace('{{statusCount, number}}', updatedQuickStartStatusCount[QuickStartStatus.NOT_STARTED]),
636
- });
637
- }, [allQuickStartStates, findResource, quickStarts]);
638
- const updateAllQuickStarts = (qs) => {
639
- setQuickStarts(qs);
640
- };
641
- const setActiveQuickStart = useCallback((quickStartId, totalTasks) => {
642
- setActiveQuickStartID((id) => {
643
- if (!quickStartId || id === quickStartId) {
644
- useQueryParams && removeQueryArgument(QUICKSTART_ID_FILTER_KEY);
645
- return '';
646
- }
647
- useQueryParams && setQueryArgument(QUICKSTART_ID_FILTER_KEY, quickStartId);
648
- return quickStartId;
649
- });
650
- setAllQuickStartStates((qs) => !quickStartId || qs[quickStartId]
651
- ? qs
652
- : Object.assign(Object.assign({}, qs), { [quickStartId]: getDefaultQuickStartState(totalTasks) }));
653
- }, [setActiveQuickStartID, setAllQuickStartStates, useQueryParams]);
654
- const startQuickStart = useCallback((quickStartId, totalTasks) => {
655
- setActiveQuickStartID((id) => {
656
- if (!id || id !== quickStartId) {
657
- useQueryParams && setQueryArgument(QUICKSTART_ID_FILTER_KEY, quickStartId);
658
- return quickStartId;
659
- }
660
- useQueryParams && setQueryArgument(QUICKSTART_ID_FILTER_KEY, id);
661
- return id;
662
- });
663
- setAllQuickStartStates((qs) => {
664
- if (qs.hasOwnProperty(quickStartId)) {
665
- return Object.assign(Object.assign({}, qs), { [quickStartId]: Object.assign(Object.assign({}, qs[quickStartId]), { status: QuickStartStatus.IN_PROGRESS }) });
666
- }
667
- return Object.assign(Object.assign({}, qs), { [quickStartId]: getDefaultQuickStartState(totalTasks, QuickStartStatus.IN_PROGRESS) });
668
- });
669
- }, [setActiveQuickStartID, setAllQuickStartStates, useQueryParams]);
670
- const restartQuickStart = useCallback((quickStartId, totalTasks) => {
671
- setActiveQuickStartID((id) => {
672
- if (!id || id !== quickStartId) {
673
- useQueryParams && setQueryArgument(QUICKSTART_ID_FILTER_KEY, quickStartId);
674
- return quickStartId;
675
- }
676
- useQueryParams && setQueryArgument(QUICKSTART_ID_FILTER_KEY, id);
677
- return id;
678
- });
679
- setAllQuickStartStates((qs) => (Object.assign(Object.assign({}, qs), { [quickStartId]: getDefaultQuickStartState(totalTasks, QuickStartStatus.NOT_STARTED) })));
680
- }, [setActiveQuickStartID, setAllQuickStartStates, useQueryParams]);
681
- // When alwaysShowTaskReview preference is enabled, skip visited step and go directly to review
682
- const stepAfterInitial = alwaysShowTaskReview
683
- ? QuickStartTaskStatus.REVIEW
684
- : QuickStartTaskStatus.VISITED;
685
- const nextStep = useCallback((totalTasks) => {
686
- if (!activeQuickStartID) {
687
- return;
688
- }
689
- setAllQuickStartStates((qs) => {
690
- const quickStart = qs[activeQuickStartID];
691
- const status = quickStart === null || quickStart === void 0 ? void 0 : quickStart.status;
692
- const taskNumber = quickStart === null || quickStart === void 0 ? void 0 : quickStart.taskNumber;
693
- const taskStatus = quickStart[getTaskStatusKey(taskNumber)];
694
- let updatedStatus;
695
- let updatedTaskNumber;
696
- let updatedTaskStatus;
697
- if (status === QuickStartStatus.NOT_STARTED) {
698
- updatedStatus = QuickStartStatus.IN_PROGRESS;
699
- }
700
- else if (status === QuickStartStatus.IN_PROGRESS &&
701
- !QUICKSTART_TASKS_INITIAL_STATES.includes(taskStatus) &&
702
- taskNumber === totalTasks - 1) {
703
- updatedStatus = QuickStartStatus.COMPLETE;
704
- }
705
- if (taskStatus === QuickStartTaskStatus.VISITED) {
706
- updatedTaskStatus = QuickStartTaskStatus.REVIEW;
707
- }
708
- if (taskNumber < totalTasks && !updatedTaskStatus) {
709
- updatedTaskNumber = taskNumber + 1;
710
- }
711
- const markInitialStepVisitedOrReview = updatedTaskNumber > -1 &&
712
- quickStart[getTaskStatusKey(updatedTaskNumber)] === QuickStartTaskStatus.INIT
713
- ? stepAfterInitial
714
- : quickStart[getTaskStatusKey(updatedTaskNumber)];
715
- const newState = Object.assign(Object.assign({}, qs), { [activeQuickStartID]: Object.assign(Object.assign(Object.assign(Object.assign({}, quickStart), (updatedStatus ? { status: updatedStatus } : {})), (updatedTaskNumber > -1
716
- ? {
717
- taskNumber: updatedTaskNumber,
718
- [getTaskStatusKey(updatedTaskNumber)]: markInitialStepVisitedOrReview,
719
- }
720
- : {})), (updatedTaskStatus ? { [getTaskStatusKey(taskNumber)]: updatedTaskStatus } : {})) });
721
- return newState;
722
- });
723
- }, [activeQuickStartID, setAllQuickStartStates, stepAfterInitial]);
724
- const previousStep = useCallback(() => {
725
- setAllQuickStartStates((qs) => {
726
- const quickStart = qs[activeQuickStartID];
727
- const taskNumber = quickStart === null || quickStart === void 0 ? void 0 : quickStart.taskNumber;
728
- if (taskNumber < 0) {
729
- return qs;
730
- }
731
- return Object.assign(Object.assign({}, qs), { [activeQuickStartID]: Object.assign(Object.assign({}, quickStart), { taskNumber: taskNumber - 1 }) });
732
- });
733
- }, [activeQuickStartID, setAllQuickStartStates]);
734
- const setQuickStartTaskNumber = useCallback((quickStartId, taskNumber) => {
735
- setAllQuickStartStates((qs) => {
736
- const quickStart = qs[quickStartId];
737
- const status = quickStart === null || quickStart === void 0 ? void 0 : quickStart.status;
738
- let updatedStatus;
739
- if (taskNumber > -1 && status === QuickStartStatus.NOT_STARTED) {
740
- updatedStatus = QuickStartStatus.IN_PROGRESS;
741
- }
742
- let updatedTaskStatus = {};
743
- for (let taskIndex = 0; taskIndex <= taskNumber; taskIndex++) {
744
- const taskStatus = quickStart[getTaskStatusKey(taskIndex)];
745
- const newTaskStatus = taskStatus === QuickStartTaskStatus.INIT ? stepAfterInitial : undefined;
746
- if (newTaskStatus) {
747
- updatedTaskStatus = Object.assign(Object.assign({}, updatedTaskStatus), { [getTaskStatusKey(taskIndex)]: newTaskStatus });
748
- }
749
- }
750
- const updatedQuickStart = Object.assign(Object.assign(Object.assign(Object.assign({}, quickStart), (updatedStatus ? { status: updatedStatus } : {})), { taskNumber }), updatedTaskStatus);
751
- return Object.assign(Object.assign({}, qs), { [quickStartId]: updatedQuickStart });
752
- });
753
- }, [setAllQuickStartStates, stepAfterInitial]);
754
- const setQuickStartTaskStatus = useCallback((taskStatus) => {
755
- const quickStart = allQuickStartStates[activeQuickStartID];
756
- const { taskNumber } = quickStart;
757
- const updatedQuickStart = Object.assign(Object.assign({}, quickStart), { [getTaskStatusKey(taskNumber)]: taskStatus });
758
- setAllQuickStartStates((qs) => (Object.assign(Object.assign({}, qs), { [activeQuickStartID]: updatedQuickStart })));
759
- }, [allQuickStartStates, activeQuickStartID, setAllQuickStartStates]);
760
- const activeQuickStartState = (_b = allQuickStartStates === null || allQuickStartStates === void 0 ? void 0 : allQuickStartStates[activeQuickStartID]) !== null && _b !== void 0 ? _b : {};
761
- const getQuickStartForId = useCallback((id) => allQuickStartStates[id], [
762
- allQuickStartStates,
763
- ]);
764
- return {
765
- allQuickStarts: quickStarts,
766
- setAllQuickStarts: updateAllQuickStarts,
767
- activeQuickStartID,
768
- setActiveQuickStartID,
769
- allQuickStartStates,
770
- setAllQuickStartStates,
771
- activeQuickStartState,
772
- setActiveQuickStart: value.setActiveQuickStart || setActiveQuickStart,
773
- startQuickStart: value.startQuickStart || startQuickStart,
774
- restartQuickStart: value.restartQuickStart || restartQuickStart,
775
- nextStep: value.nextStep || nextStep,
776
- previousStep: value.previousStep || previousStep,
777
- setQuickStartTaskNumber,
778
- setQuickStartTaskStatus,
779
- getQuickStartForId,
780
- footer,
781
- useLegacyHeaderColors,
782
- useQueryParams,
783
- markdown,
784
- resourceBundle,
785
- getResource: findResource,
786
- setResourceBundle: changeResourceBundle,
787
- language,
788
- setLanguage,
789
- // revisit if this should be in public context API
790
- filter: {
791
- keyword: filterKeyword,
792
- status: {
793
- statusTypes,
794
- statusFilters,
795
- },
796
- },
797
- setFilter,
798
- loading,
799
- setLoading,
800
- alwaysShowTaskReview,
801
- setAlwaysShowTaskReview,
802
- };
803
- };
549
+ const pluralResolver = new PluralResolver({ simplifyPluralSuffix: true });
550
+ const getDefaultQuickStartState = (totalTasks, initialStatus) => {
551
+ const defaultQuickStartState = {
552
+ status: initialStatus || QuickStartStatus.NOT_STARTED,
553
+ taskNumber: -1,
554
+ };
555
+ if (totalTasks) {
556
+ for (let i = 0; i < totalTasks; i++) {
557
+ defaultQuickStartState[getTaskStatusKey(i)] = QuickStartTaskStatus.INIT;
558
+ }
559
+ }
560
+ return defaultQuickStartState;
561
+ };
562
+ const QuickStartContextDefaults = {
563
+ allQuickStarts: [],
564
+ activeQuickStartID: '',
565
+ allQuickStartStates: {},
566
+ activeQuickStartState: {},
567
+ setAllQuickStarts: () => { },
568
+ resourceBundle: en,
569
+ getResource: (resource) => resource,
570
+ language: 'en',
571
+ useQueryParams: true,
572
+ filter: {
573
+ keyword: '',
574
+ status: {
575
+ statusTypes: {},
576
+ statusFilters: [],
577
+ },
578
+ },
579
+ setFilter: () => { },
580
+ footer: null,
581
+ useLegacyHeaderColors: false,
582
+ markdown: null,
583
+ loading: false,
584
+ alwaysShowTaskReview: true,
585
+ };
586
+ const QuickStartContext = createContext(QuickStartContextDefaults);
587
+ const getResource = (resource, options, resourceBundle, lng) => {
588
+ if (options && !isNaN(options.count)) {
589
+ const suffix = pluralResolver.getSuffix(lng, options.count);
590
+ if (suffix && resourceBundle[`${resource}_${suffix}`]) {
591
+ // needs plural
592
+ return resourceBundle[`${resource}_${suffix}`];
593
+ }
594
+ }
595
+ return (resourceBundle && resourceBundle[resource]) || resource;
596
+ };
597
+ const useValuesForQuickStartContext = (value = {}) => {
598
+ var _a, _b;
599
+ const combinedValue = Object.assign(Object.assign({}, QuickStartContextDefaults), value);
600
+ const { activeQuickStartID, setActiveQuickStartID, setAllQuickStartStates, useQueryParams, allQuickStartStates, allQuickStarts = [], footer, useLegacyHeaderColors, markdown, } = combinedValue;
601
+ const [quickStarts, setQuickStarts] = React__default.useState(combinedValue.allQuickStarts || []);
602
+ const [resourceBundle, setResourceBundle] = React__default.useState(Object.assign(Object.assign({}, en), combinedValue.resourceBundle));
603
+ const [language, setLanguage] = React__default.useState(combinedValue.language);
604
+ const changeResourceBundle = (bundle, lng) => {
605
+ lng && setLanguage(lng);
606
+ setResourceBundle(Object.assign(Object.assign({}, en), bundle));
607
+ };
608
+ const findResource = useCallback((resource, count) => getResource(resource, count !== undefined ? { count } : null, resourceBundle, language), [resourceBundle, language]);
609
+ const [loading, setLoading] = React__default.useState(combinedValue.loading);
610
+ const [alwaysShowTaskReview, setAlwaysShowTaskReview] = React__default.useState(combinedValue.alwaysShowTaskReview);
611
+ const initialSearchParams = new URLSearchParams(window.location.search);
612
+ const initialSearchQuery = initialSearchParams.get(QUICKSTART_SEARCH_FILTER_KEY) || '';
613
+ const initialStatusFilters = ((_a = initialSearchParams.get(QUICKSTART_STATUS_FILTER_KEY)) === null || _a === void 0 ? void 0 : _a.split(',')) || [];
614
+ const quickStartStatusCount = getQuickStartStatusCount(allQuickStartStates, allQuickStarts);
615
+ const [statusTypes, setStatusTypes] = React__default.useState({
616
+ [QuickStartStatus.COMPLETE]: findResource('Complete ({{statusCount, number}})').replace('{{statusCount, number}}', quickStartStatusCount[QuickStartStatus.COMPLETE]),
617
+ [QuickStartStatus.IN_PROGRESS]: findResource('In progress ({{statusCount, number}})').replace('{{statusCount, number}}', quickStartStatusCount[QuickStartStatus.IN_PROGRESS]),
618
+ [QuickStartStatus.NOT_STARTED]: findResource('Not started ({{statusCount, number}})').replace('{{statusCount, number}}', quickStartStatusCount[QuickStartStatus.NOT_STARTED]),
619
+ });
620
+ const [statusFilters, setStatusFilters] = React__default.useState(initialStatusFilters);
621
+ const [filterKeyword, setFilterKeyword] = React__default.useState(initialSearchQuery);
622
+ const setFilter = (type, val) => {
623
+ if (type === 'keyword') {
624
+ setFilterKeyword(val);
625
+ }
626
+ else if (type === 'status') {
627
+ setStatusFilters(val);
628
+ }
629
+ };
630
+ React__default.useEffect(() => {
631
+ const updatedQuickStartStatusCount = getQuickStartStatusCount(allQuickStartStates, quickStarts);
632
+ setStatusTypes({
633
+ [QuickStartStatus.COMPLETE]: findResource('Complete ({{statusCount, number}})').replace('{{statusCount, number}}', updatedQuickStartStatusCount[QuickStartStatus.COMPLETE]),
634
+ [QuickStartStatus.IN_PROGRESS]: findResource('In progress ({{statusCount, number}})').replace('{{statusCount, number}}', updatedQuickStartStatusCount[QuickStartStatus.IN_PROGRESS]),
635
+ [QuickStartStatus.NOT_STARTED]: findResource('Not started ({{statusCount, number}})').replace('{{statusCount, number}}', updatedQuickStartStatusCount[QuickStartStatus.NOT_STARTED]),
636
+ });
637
+ }, [allQuickStartStates, findResource, quickStarts]);
638
+ const updateAllQuickStarts = (qs) => {
639
+ setQuickStarts(qs);
640
+ };
641
+ const setActiveQuickStart = useCallback((quickStartId, totalTasks) => {
642
+ setActiveQuickStartID((id) => {
643
+ if (!quickStartId || id === quickStartId) {
644
+ useQueryParams && removeQueryArgument(QUICKSTART_ID_FILTER_KEY);
645
+ return '';
646
+ }
647
+ useQueryParams && setQueryArgument(QUICKSTART_ID_FILTER_KEY, quickStartId);
648
+ return quickStartId;
649
+ });
650
+ setAllQuickStartStates((qs) => !quickStartId || qs[quickStartId]
651
+ ? qs
652
+ : Object.assign(Object.assign({}, qs), { [quickStartId]: getDefaultQuickStartState(totalTasks) }));
653
+ }, [setActiveQuickStartID, setAllQuickStartStates, useQueryParams]);
654
+ const startQuickStart = useCallback((quickStartId, totalTasks) => {
655
+ setActiveQuickStartID((id) => {
656
+ if (!id || id !== quickStartId) {
657
+ useQueryParams && setQueryArgument(QUICKSTART_ID_FILTER_KEY, quickStartId);
658
+ return quickStartId;
659
+ }
660
+ useQueryParams && setQueryArgument(QUICKSTART_ID_FILTER_KEY, id);
661
+ return id;
662
+ });
663
+ setAllQuickStartStates((qs) => {
664
+ if (qs.hasOwnProperty(quickStartId)) {
665
+ return Object.assign(Object.assign({}, qs), { [quickStartId]: Object.assign(Object.assign({}, qs[quickStartId]), { status: QuickStartStatus.IN_PROGRESS }) });
666
+ }
667
+ return Object.assign(Object.assign({}, qs), { [quickStartId]: getDefaultQuickStartState(totalTasks, QuickStartStatus.IN_PROGRESS) });
668
+ });
669
+ }, [setActiveQuickStartID, setAllQuickStartStates, useQueryParams]);
670
+ const restartQuickStart = useCallback((quickStartId, totalTasks) => {
671
+ setActiveQuickStartID((id) => {
672
+ if (!id || id !== quickStartId) {
673
+ useQueryParams && setQueryArgument(QUICKSTART_ID_FILTER_KEY, quickStartId);
674
+ return quickStartId;
675
+ }
676
+ useQueryParams && setQueryArgument(QUICKSTART_ID_FILTER_KEY, id);
677
+ return id;
678
+ });
679
+ setAllQuickStartStates((qs) => (Object.assign(Object.assign({}, qs), { [quickStartId]: getDefaultQuickStartState(totalTasks, QuickStartStatus.NOT_STARTED) })));
680
+ }, [setActiveQuickStartID, setAllQuickStartStates, useQueryParams]);
681
+ // When alwaysShowTaskReview preference is enabled, skip visited step and go directly to review
682
+ const stepAfterInitial = alwaysShowTaskReview
683
+ ? QuickStartTaskStatus.REVIEW
684
+ : QuickStartTaskStatus.VISITED;
685
+ const nextStep = useCallback((totalTasks) => {
686
+ if (!activeQuickStartID) {
687
+ return;
688
+ }
689
+ setAllQuickStartStates((qs) => {
690
+ const quickStart = qs[activeQuickStartID];
691
+ const status = quickStart === null || quickStart === void 0 ? void 0 : quickStart.status;
692
+ const taskNumber = quickStart === null || quickStart === void 0 ? void 0 : quickStart.taskNumber;
693
+ const taskStatus = quickStart[getTaskStatusKey(taskNumber)];
694
+ let updatedStatus;
695
+ let updatedTaskNumber;
696
+ let updatedTaskStatus;
697
+ if (status === QuickStartStatus.NOT_STARTED) {
698
+ updatedStatus = QuickStartStatus.IN_PROGRESS;
699
+ }
700
+ else if (status === QuickStartStatus.IN_PROGRESS &&
701
+ !QUICKSTART_TASKS_INITIAL_STATES.includes(taskStatus) &&
702
+ taskNumber === totalTasks - 1) {
703
+ updatedStatus = QuickStartStatus.COMPLETE;
704
+ }
705
+ if (taskStatus === QuickStartTaskStatus.VISITED) {
706
+ updatedTaskStatus = QuickStartTaskStatus.REVIEW;
707
+ }
708
+ if (taskNumber < totalTasks && !updatedTaskStatus) {
709
+ updatedTaskNumber = taskNumber + 1;
710
+ }
711
+ const markInitialStepVisitedOrReview = updatedTaskNumber > -1 &&
712
+ quickStart[getTaskStatusKey(updatedTaskNumber)] === QuickStartTaskStatus.INIT
713
+ ? stepAfterInitial
714
+ : quickStart[getTaskStatusKey(updatedTaskNumber)];
715
+ const newState = Object.assign(Object.assign({}, qs), { [activeQuickStartID]: Object.assign(Object.assign(Object.assign(Object.assign({}, quickStart), (updatedStatus ? { status: updatedStatus } : {})), (updatedTaskNumber > -1
716
+ ? {
717
+ taskNumber: updatedTaskNumber,
718
+ [getTaskStatusKey(updatedTaskNumber)]: markInitialStepVisitedOrReview,
719
+ }
720
+ : {})), (updatedTaskStatus ? { [getTaskStatusKey(taskNumber)]: updatedTaskStatus } : {})) });
721
+ return newState;
722
+ });
723
+ }, [activeQuickStartID, setAllQuickStartStates, stepAfterInitial]);
724
+ const previousStep = useCallback(() => {
725
+ setAllQuickStartStates((qs) => {
726
+ const quickStart = qs[activeQuickStartID];
727
+ const taskNumber = quickStart === null || quickStart === void 0 ? void 0 : quickStart.taskNumber;
728
+ if (taskNumber < 0) {
729
+ return qs;
730
+ }
731
+ return Object.assign(Object.assign({}, qs), { [activeQuickStartID]: Object.assign(Object.assign({}, quickStart), { taskNumber: taskNumber - 1 }) });
732
+ });
733
+ }, [activeQuickStartID, setAllQuickStartStates]);
734
+ const setQuickStartTaskNumber = useCallback((quickStartId, taskNumber) => {
735
+ setAllQuickStartStates((qs) => {
736
+ const quickStart = qs[quickStartId];
737
+ const status = quickStart === null || quickStart === void 0 ? void 0 : quickStart.status;
738
+ let updatedStatus;
739
+ if (taskNumber > -1 && status === QuickStartStatus.NOT_STARTED) {
740
+ updatedStatus = QuickStartStatus.IN_PROGRESS;
741
+ }
742
+ let updatedTaskStatus = {};
743
+ for (let taskIndex = 0; taskIndex <= taskNumber; taskIndex++) {
744
+ const taskStatus = quickStart[getTaskStatusKey(taskIndex)];
745
+ const newTaskStatus = taskStatus === QuickStartTaskStatus.INIT ? stepAfterInitial : undefined;
746
+ if (newTaskStatus) {
747
+ updatedTaskStatus = Object.assign(Object.assign({}, updatedTaskStatus), { [getTaskStatusKey(taskIndex)]: newTaskStatus });
748
+ }
749
+ }
750
+ const updatedQuickStart = Object.assign(Object.assign(Object.assign(Object.assign({}, quickStart), (updatedStatus ? { status: updatedStatus } : {})), { taskNumber }), updatedTaskStatus);
751
+ return Object.assign(Object.assign({}, qs), { [quickStartId]: updatedQuickStart });
752
+ });
753
+ }, [setAllQuickStartStates, stepAfterInitial]);
754
+ const setQuickStartTaskStatus = useCallback((taskStatus) => {
755
+ const quickStart = allQuickStartStates[activeQuickStartID];
756
+ const { taskNumber } = quickStart;
757
+ const updatedQuickStart = Object.assign(Object.assign({}, quickStart), { [getTaskStatusKey(taskNumber)]: taskStatus });
758
+ setAllQuickStartStates((qs) => (Object.assign(Object.assign({}, qs), { [activeQuickStartID]: updatedQuickStart })));
759
+ }, [allQuickStartStates, activeQuickStartID, setAllQuickStartStates]);
760
+ const activeQuickStartState = (_b = allQuickStartStates === null || allQuickStartStates === void 0 ? void 0 : allQuickStartStates[activeQuickStartID]) !== null && _b !== void 0 ? _b : {};
761
+ const getQuickStartForId = useCallback((id) => allQuickStartStates[id], [
762
+ allQuickStartStates,
763
+ ]);
764
+ return {
765
+ allQuickStarts: quickStarts,
766
+ setAllQuickStarts: updateAllQuickStarts,
767
+ activeQuickStartID,
768
+ setActiveQuickStartID,
769
+ allQuickStartStates,
770
+ setAllQuickStartStates,
771
+ activeQuickStartState,
772
+ setActiveQuickStart: value.setActiveQuickStart || setActiveQuickStart,
773
+ startQuickStart: value.startQuickStart || startQuickStart,
774
+ restartQuickStart: value.restartQuickStart || restartQuickStart,
775
+ nextStep: value.nextStep || nextStep,
776
+ previousStep: value.previousStep || previousStep,
777
+ setQuickStartTaskNumber,
778
+ setQuickStartTaskStatus,
779
+ getQuickStartForId,
780
+ footer,
781
+ useLegacyHeaderColors,
782
+ useQueryParams,
783
+ markdown,
784
+ resourceBundle,
785
+ getResource: findResource,
786
+ setResourceBundle: changeResourceBundle,
787
+ language,
788
+ setLanguage,
789
+ // revisit if this should be in public context API
790
+ filter: {
791
+ keyword: filterKeyword,
792
+ status: {
793
+ statusTypes,
794
+ statusFilters,
795
+ },
796
+ },
797
+ setFilter,
798
+ loading,
799
+ setLoading,
800
+ alwaysShowTaskReview,
801
+ setAlwaysShowTaskReview,
802
+ };
803
+ };
804
804
  const QuickStartContextProvider = ({ children, value }) => (React__default.createElement(QuickStartContext.Provider, { value: useValuesForQuickStartContext(value) }, children));
805
805
 
806
- const Box = ({ children, className }) => (React.createElement("div", { className: css('pfext-status-box', className) }, children));
807
- const Loading = ({ className }) => (React.createElement("div", { className: css('pfext-m-loader', className) },
808
- React.createElement("div", { className: "pfext-m-loader-dot__one" }),
809
- React.createElement("div", { className: "pfext-m-loader-dot__two" }),
810
- React.createElement("div", { className: "pfext-m-loader-dot__three" })));
811
- Loading.displayName = 'Loading';
812
- const LoadingBox = ({ className, message }) => (React.createElement(Box, { className: css('pfext-status-box--loading', className) },
813
- React.createElement(Loading, null),
814
- message && React.createElement("div", { className: "pfext-status-box__loading-message" }, message)));
815
- LoadingBox.displayName = 'LoadingBox';
816
- const EmptyBox = ({ label }) => {
817
- const { getResource } = React.useContext(QuickStartContext);
818
- return (React.createElement(Box, null,
819
- React.createElement("div", { "data-test": "empty-message", className: "text-center" }, label
820
- ? getResource('No {{label}} found').replace('{{label}}', label)
821
- : getResource('Not found'))));
822
- };
806
+ const Box = ({ children, className }) => (React.createElement("div", { className: css('pfext-status-box', className) }, children));
807
+ const Loading = ({ className }) => (React.createElement("div", { className: css('pfext-m-loader', className) },
808
+ React.createElement("div", { className: "pfext-m-loader-dot__one" }),
809
+ React.createElement("div", { className: "pfext-m-loader-dot__two" }),
810
+ React.createElement("div", { className: "pfext-m-loader-dot__three" })));
811
+ Loading.displayName = 'Loading';
812
+ const LoadingBox = ({ className, message }) => (React.createElement(Box, { className: css('pfext-status-box--loading', className) },
813
+ React.createElement(Loading, null),
814
+ message && React.createElement("div", { className: "pfext-status-box__loading-message" }, message)));
815
+ LoadingBox.displayName = 'LoadingBox';
816
+ const EmptyBox = ({ label }) => {
817
+ const { getResource } = React.useContext(QuickStartContext);
818
+ return (React.createElement(Box, null,
819
+ React.createElement("div", { "data-test": "empty-message", className: "text-center" }, label
820
+ ? getResource('No {{label}} found').replace('{{label}}', label)
821
+ : getResource('Not found'))));
822
+ };
823
823
  EmptyBox.displayName = 'EmptyBox';
824
824
 
825
- const MEMO = {};
826
- const CamelCaseWrap = ({ value, dataTest }) => {
827
- if (!value) {
828
- return '-';
829
- }
830
- if (MEMO[value]) {
831
- return MEMO[value];
832
- }
833
- // Add word break points before capital letters (but keep consecutive capital letters together).
834
- const words = value.match(/[A-Z]+[^A-Z]*|[^A-Z]+/g);
835
- const rendered = (React.createElement("span", { "data-test": dataTest }, words.map((word, i) => (React.createElement(React.Fragment, { key: i },
836
- word,
837
- i !== words.length - 1 && React.createElement("wbr", null))))));
838
- MEMO[value] = rendered;
839
- return rendered;
825
+ const MEMO = {};
826
+ const CamelCaseWrap = ({ value, dataTest }) => {
827
+ if (!value) {
828
+ return '-';
829
+ }
830
+ if (MEMO[value]) {
831
+ return MEMO[value];
832
+ }
833
+ // Add word break points before capital letters (but keep consecutive capital letters together).
834
+ const words = value.match(/[A-Z]+[^A-Z]*|[^A-Z]+/g);
835
+ const rendered = (React.createElement("span", { "data-test": dataTest }, words.map((word, i) => (React.createElement(React.Fragment, { key: i },
836
+ word,
837
+ i !== words.length - 1 && React.createElement("wbr", null))))));
838
+ MEMO[value] = rendered;
839
+ return rendered;
840
840
  };
841
841
 
842
842
  class CatalogTile extends React.Component {
843
- constructor() {
844
- super(...arguments);
843
+ constructor(props) {
844
+ super(props);
845
845
  this.handleClick = (e) => {
846
846
  const { onClick, href } = this.props;
847
847
  if (!href) {
@@ -857,13 +857,18 @@ class CatalogTile extends React.Component {
857
857
  }
858
858
  return (React.createElement("div", { className: "catalog-tile-pf-badge-container" }, badges.map((badge, index) => (React.createElement("span", { key: `badge-${index}` }, badge)))));
859
859
  };
860
+ this.generatedId = getUniqueId('pf-catalog-tile');
860
861
  }
861
862
  render() {
862
863
  const _a = this.props, { id, className, featured, onClick, href, icon, iconImg, iconAlt, iconClass, badges, title, vendor, description, footer,
863
864
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
864
865
  ref, children } = _a, props = __rest(_a, ["id", "className", "featured", "onClick", "href", "icon", "iconImg", "iconAlt", "iconClass", "badges", "title", "vendor", "description", "footer", "ref", "children"]);
865
- return (React.createElement(Card, Object.assign({ component: href ? 'a' : 'div', id: id, href: href || '#', className: css('catalog-tile-pf', { featured }, className), isClickable: !!onClick }, props),
866
- (badges.length > 0 || iconImg || iconClass || icon || onClick) && (React.createElement(CardHeader, { actions: { actions: badges.length > 0 && this.renderBadges(badges) }, selectableActions: onClick && { selectableActionId: id + '-input', onClickAction: (e) => this.handleClick(e), selectableActionAriaLabelledby: id } },
866
+ return (React.createElement(Card, Object.assign({ component: href ? 'a' : 'div', id: id || this.generatedId, href: href || '#', className: css('catalog-tile-pf', { featured }, className), isClickable: !!onClick }, props),
867
+ (badges.length > 0 || iconImg || iconClass || icon || onClick) && (React.createElement(CardHeader, { actions: { actions: badges.length > 0 && this.renderBadges(badges) }, selectableActions: onClick && {
868
+ selectableActionId: id + '-input',
869
+ onClickAction: (e) => this.handleClick(e),
870
+ selectableActionAriaLabelledby: id
871
+ } },
867
872
  iconImg && React.createElement("img", { className: "catalog-tile-pf-icon", src: iconImg, alt: iconAlt }),
868
873
  !iconImg && (iconClass || icon) && React.createElement("span", { className: `catalog-tile-pf-icon ${iconClass}` }, icon))),
869
874
  React.createElement(CardTitle, { className: "catalog-tile-pf-header" },
@@ -878,7 +883,7 @@ class CatalogTile extends React.Component {
878
883
  }
879
884
  CatalogTile.displayName = 'CatalogTile';
880
885
  CatalogTile.defaultProps = {
881
- id: getUniqueId('pf-catalog-tile'),
886
+ id: null,
882
887
  className: '',
883
888
  featured: false,
884
889
  onClick: null,
@@ -894,335 +899,335 @@ CatalogTile.defaultProps = {
894
899
  children: null
895
900
  };
896
901
 
897
- const Modal = (_a) => {
898
- var { isFullScreen = false, className } = _a, props = __rest(_a, ["isFullScreen", "className"]);
899
- return (React.createElement(Modal$1, Object.assign({}, props, { className: css('pfext-modal', className), appendTo: () => (isFullScreen ? document.body : document.querySelector('#modal-container')) })));
900
- };
901
-
902
- const getContainer = (container) => typeof container === 'function' ? container() : container;
903
- const Portal = ({ children, container }) => {
904
- const [containerNode, setContainerNode] = React.useState();
905
- useIsomorphicLayoutEffect(() => {
906
- setContainerNode(getContainer(container) || document.body);
907
- }, [container]);
908
- return containerNode ? ReactDOM.createPortal(children, containerNode) : null;
909
- };
910
-
911
- const SimplePopper = ({ children }) => {
912
- const openProp = true;
913
- const nodeRef = React.useRef();
914
- const popperRef = React.useRef(null);
915
- const [isOpen, setOpenState] = React.useState(openProp);
916
- const setOpen = React.useCallback((newOpen) => {
917
- setOpenState(newOpen);
918
- }, []);
919
- React.useEffect(() => {
920
- setOpen(openProp);
921
- }, [openProp, setOpen]);
922
- const onKeyDown = React.useCallback((e) => {
923
- if (e.keyCode === 27) {
924
- setOpen(false);
925
- }
926
- }, [setOpen]);
927
- const onClickOutside = React.useCallback((e) => {
928
- if (!nodeRef.current || (e.target instanceof Node && !nodeRef.current.contains(e.target))) {
929
- setOpen(false);
930
- }
931
- }, [setOpen]);
932
- const destroy = React.useCallback(() => {
933
- if (popperRef.current) {
934
- popperRef.current.destroy();
935
- document.removeEventListener('keydown', onKeyDown, true);
936
- document.removeEventListener('mousedown', onClickOutside, true);
937
- document.removeEventListener('touchstart', onClickOutside, true);
938
- }
939
- }, [onClickOutside, onKeyDown]);
940
- const initialize = React.useCallback(() => {
941
- if (!nodeRef.current || !isOpen) {
942
- return;
943
- }
944
- destroy();
945
- }, [isOpen, destroy]);
946
- const nodeRefCallback = React.useCallback((node) => {
947
- nodeRef.current = node;
948
- initialize();
949
- }, [initialize]);
950
- React.useEffect(() => {
951
- initialize();
952
- }, [initialize]);
953
- React.useEffect(() => () => {
954
- destroy();
955
- }, [destroy]);
956
- React.useEffect(() => {
957
- if (!isOpen) {
958
- destroy();
959
- }
960
- }, [destroy, isOpen]);
961
- return isOpen ? (React.createElement(Portal, null,
962
- React.createElement("div", { ref: nodeRefCallback, style: { zIndex: 9999, position: 'absolute', top: 0, left: 0 }, className: "pfext-quick-start__base" }, children))) : null;
963
- };
964
-
965
- const isInViewport = (elementToCheck) => {
966
- const rect = elementToCheck.getBoundingClientRect();
967
- return (rect.top >= 0 &&
968
- rect.left >= 0 &&
969
- rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
970
- rect.right <= (window.innerWidth || document.documentElement.clientWidth));
971
- };
972
- const InteractiveSpotlight = ({ element }) => {
973
- const { top, bottom, left, right, height, width } = element.getBoundingClientRect();
974
- const style = {
975
- height,
976
- width,
977
- top,
978
- left,
979
- bottom,
980
- right,
981
- };
982
- const [clicked, setClicked] = React.useState(false);
983
- React.useEffect(() => {
984
- if (!clicked) {
985
- if (!isInViewport(element)) {
986
- element.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' });
987
- }
988
- const handleClick = () => setClicked(true);
989
- document.addEventListener('click', handleClick);
990
- return () => {
991
- document.removeEventListener('click', handleClick);
992
- };
993
- }
994
- return () => { };
995
- }, [element, clicked]);
996
- if (clicked) {
997
- return null;
998
- }
999
- return (React.createElement(Portal, null,
1000
- React.createElement(SimplePopper, null,
1001
- React.createElement("div", { className: "pfext-spotlight pfext-spotlight__element-highlight-animate", style: style }))));
1002
- };
1003
-
1004
- var ScrollDirection;
1005
- (function (ScrollDirection) {
1006
- ScrollDirection["scrollingUp"] = "scrolling-up";
1007
- ScrollDirection["scrollingDown"] = "scrolling-down";
1008
- ScrollDirection["scrolledToBottom"] = "scrolled-to-bottom";
1009
- ScrollDirection["scrolledToTop"] = "scrolled-to-top";
902
+ const Modal = (_a) => {
903
+ var { isFullScreen = false, className } = _a, props = __rest(_a, ["isFullScreen", "className"]);
904
+ return (React.createElement(Modal$1, Object.assign({}, props, { className: css('pfext-modal', className), appendTo: () => (isFullScreen ? document.body : document.querySelector('#modal-container')) })));
905
+ };
906
+
907
+ const getContainer = (container) => typeof container === 'function' ? container() : container;
908
+ const Portal = ({ children, container }) => {
909
+ const [containerNode, setContainerNode] = React.useState();
910
+ useIsomorphicLayoutEffect(() => {
911
+ setContainerNode(getContainer(container) || document.body);
912
+ }, [container]);
913
+ return containerNode ? ReactDOM.createPortal(children, containerNode) : null;
914
+ };
915
+
916
+ const SimplePopper = ({ children }) => {
917
+ const openProp = true;
918
+ const nodeRef = React.useRef();
919
+ const popperRef = React.useRef(null);
920
+ const [isOpen, setOpenState] = React.useState(openProp);
921
+ const setOpen = React.useCallback((newOpen) => {
922
+ setOpenState(newOpen);
923
+ }, []);
924
+ React.useEffect(() => {
925
+ setOpen(openProp);
926
+ }, [openProp, setOpen]);
927
+ const onKeyDown = React.useCallback((e) => {
928
+ if (e.keyCode === 27) {
929
+ setOpen(false);
930
+ }
931
+ }, [setOpen]);
932
+ const onClickOutside = React.useCallback((e) => {
933
+ if (!nodeRef.current || (e.target instanceof Node && !nodeRef.current.contains(e.target))) {
934
+ setOpen(false);
935
+ }
936
+ }, [setOpen]);
937
+ const destroy = React.useCallback(() => {
938
+ if (popperRef.current) {
939
+ popperRef.current.destroy();
940
+ document.removeEventListener('keydown', onKeyDown, true);
941
+ document.removeEventListener('mousedown', onClickOutside, true);
942
+ document.removeEventListener('touchstart', onClickOutside, true);
943
+ }
944
+ }, [onClickOutside, onKeyDown]);
945
+ const initialize = React.useCallback(() => {
946
+ if (!nodeRef.current || !isOpen) {
947
+ return;
948
+ }
949
+ destroy();
950
+ }, [isOpen, destroy]);
951
+ const nodeRefCallback = React.useCallback((node) => {
952
+ nodeRef.current = node;
953
+ initialize();
954
+ }, [initialize]);
955
+ React.useEffect(() => {
956
+ initialize();
957
+ }, [initialize]);
958
+ React.useEffect(() => () => {
959
+ destroy();
960
+ }, [destroy]);
961
+ React.useEffect(() => {
962
+ if (!isOpen) {
963
+ destroy();
964
+ }
965
+ }, [destroy, isOpen]);
966
+ return isOpen ? (React.createElement(Portal, null,
967
+ React.createElement("div", { ref: nodeRefCallback, style: { zIndex: 9999, position: 'absolute', top: 0, left: 0 }, className: "pfext-quick-start__base" }, children))) : null;
968
+ };
969
+
970
+ const isInViewport = (elementToCheck) => {
971
+ const rect = elementToCheck.getBoundingClientRect();
972
+ return (rect.top >= 0 &&
973
+ rect.left >= 0 &&
974
+ rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
975
+ rect.right <= (window.innerWidth || document.documentElement.clientWidth));
976
+ };
977
+ const InteractiveSpotlight = ({ element }) => {
978
+ const { top, bottom, left, right, height, width } = element.getBoundingClientRect();
979
+ const style = {
980
+ height,
981
+ width,
982
+ top,
983
+ left,
984
+ bottom,
985
+ right,
986
+ };
987
+ const [clicked, setClicked] = React.useState(false);
988
+ React.useEffect(() => {
989
+ if (!clicked) {
990
+ if (!isInViewport(element)) {
991
+ element.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' });
992
+ }
993
+ const handleClick = () => setClicked(true);
994
+ document.addEventListener('click', handleClick);
995
+ return () => {
996
+ document.removeEventListener('click', handleClick);
997
+ };
998
+ }
999
+ return () => { };
1000
+ }, [element, clicked]);
1001
+ if (clicked) {
1002
+ return null;
1003
+ }
1004
+ return (React.createElement(Portal, null,
1005
+ React.createElement(SimplePopper, null,
1006
+ React.createElement("div", { className: "pfext-spotlight pfext-spotlight__element-highlight-animate", style: style }))));
1007
+ };
1008
+
1009
+ var ScrollDirection;
1010
+ (function (ScrollDirection) {
1011
+ ScrollDirection["scrollingUp"] = "scrolling-up";
1012
+ ScrollDirection["scrollingDown"] = "scrolling-down";
1013
+ ScrollDirection["scrolledToBottom"] = "scrolled-to-bottom";
1014
+ ScrollDirection["scrolledToTop"] = "scrolled-to-top";
1010
1015
  })(ScrollDirection || (ScrollDirection = {}));
1011
1016
 
1012
- const useResizeObserver = (callback, targetElement, observerOptions = undefined) => {
1013
- const element = React.useMemo(() => targetElement !== null && targetElement !== void 0 ? targetElement : document.querySelector('body'), [targetElement]);
1014
- React.useEffect(() => {
1015
- const observer = new ResizeObserver(callback);
1016
- observer.observe(element, observerOptions);
1017
- return () => {
1018
- observer.disconnect();
1019
- };
1020
- }, [callback, observerOptions, element]);
1021
- };
1022
-
1023
- var Shadows;
1024
- (function (Shadows) {
1025
- Shadows["none"] = "none";
1026
- Shadows["both"] = "both";
1027
- Shadows["top"] = "top";
1028
- Shadows["bottom"] = "bottom";
1029
- })(Shadows || (Shadows = {}));
1030
- const useScrollShadows = (node) => {
1031
- const [shadows, setShadows] = React.useState(Shadows.none);
1032
- const computeShadows = React.useCallback(() => {
1033
- if (node) {
1034
- const { scrollTop, clientHeight, scrollHeight } = node;
1035
- const top = scrollTop !== 0;
1036
- const bottom = scrollTop + clientHeight < scrollHeight;
1037
- if (top && bottom) {
1038
- setShadows(Shadows.both);
1039
- }
1040
- else if (top) {
1041
- setShadows(Shadows.top);
1042
- }
1043
- else if (bottom) {
1044
- setShadows(Shadows.bottom);
1045
- }
1046
- else {
1047
- setShadows(Shadows.none);
1048
- }
1049
- }
1050
- }, [node]);
1051
- // recompute when the scroll container changes in size
1052
- useResizeObserver(computeShadows, node);
1053
- React.useEffect(() => {
1054
- if (node) {
1055
- // compute initial shadows
1056
- computeShadows();
1057
- // listen for scroll events
1058
- node.addEventListener('scroll', computeShadows);
1059
- }
1060
- return () => {
1061
- if (node) {
1062
- node.removeEventListener('scroll', computeShadows);
1063
- }
1064
- };
1065
- }, [node, computeShadows]);
1066
- return shadows;
1067
- };
1068
-
1069
- const useBoundingClientRect = (targetElement) => {
1070
- const [clientRect, setClientRect] = React.useState(() => targetElement ? targetElement.getBoundingClientRect() : null);
1071
- const observerCallback = React.useCallback(() => {
1072
- setClientRect(targetElement ? targetElement.getBoundingClientRect() : null);
1073
- }, [targetElement]);
1074
- useResizeObserver(observerCallback);
1075
- return clientRect;
1076
- };
1077
-
1078
- /**
1079
- * React hook that forces component render.
1080
- */
1017
+ const useResizeObserver = (callback, targetElement, observerOptions = undefined) => {
1018
+ const element = React.useMemo(() => targetElement !== null && targetElement !== void 0 ? targetElement : document.querySelector('body'), [targetElement]);
1019
+ React.useEffect(() => {
1020
+ const observer = new ResizeObserver(callback);
1021
+ observer.observe(element, observerOptions);
1022
+ return () => {
1023
+ observer.disconnect();
1024
+ };
1025
+ }, [callback, observerOptions, element]);
1026
+ };
1027
+
1028
+ var Shadows;
1029
+ (function (Shadows) {
1030
+ Shadows["none"] = "none";
1031
+ Shadows["both"] = "both";
1032
+ Shadows["top"] = "top";
1033
+ Shadows["bottom"] = "bottom";
1034
+ })(Shadows || (Shadows = {}));
1035
+ const useScrollShadows = (node) => {
1036
+ const [shadows, setShadows] = React.useState(Shadows.none);
1037
+ const computeShadows = React.useCallback(() => {
1038
+ if (node) {
1039
+ const { scrollTop, clientHeight, scrollHeight } = node;
1040
+ const top = scrollTop !== 0;
1041
+ const bottom = scrollTop + clientHeight < scrollHeight;
1042
+ if (top && bottom) {
1043
+ setShadows(Shadows.both);
1044
+ }
1045
+ else if (top) {
1046
+ setShadows(Shadows.top);
1047
+ }
1048
+ else if (bottom) {
1049
+ setShadows(Shadows.bottom);
1050
+ }
1051
+ else {
1052
+ setShadows(Shadows.none);
1053
+ }
1054
+ }
1055
+ }, [node]);
1056
+ // recompute when the scroll container changes in size
1057
+ useResizeObserver(computeShadows, node);
1058
+ React.useEffect(() => {
1059
+ if (node) {
1060
+ // compute initial shadows
1061
+ computeShadows();
1062
+ // listen for scroll events
1063
+ node.addEventListener('scroll', computeShadows);
1064
+ }
1065
+ return () => {
1066
+ if (node) {
1067
+ node.removeEventListener('scroll', computeShadows);
1068
+ }
1069
+ };
1070
+ }, [node, computeShadows]);
1071
+ return shadows;
1072
+ };
1073
+
1074
+ const useBoundingClientRect = (targetElement) => {
1075
+ const [clientRect, setClientRect] = React.useState(() => targetElement ? targetElement.getBoundingClientRect() : null);
1076
+ const observerCallback = React.useCallback(() => {
1077
+ setClientRect(targetElement ? targetElement.getBoundingClientRect() : null);
1078
+ }, [targetElement]);
1079
+ useResizeObserver(observerCallback);
1080
+ return clientRect;
1081
+ };
1082
+
1083
+ /**
1084
+ * React hook that forces component render.
1085
+ */
1081
1086
  const useForceRender = () => React.useReducer((s) => !s, false)[1];
1082
1087
 
1083
- const useEventListener = (target, event, callback) => {
1084
- useEffect(() => {
1085
- target.addEventListener(event, callback);
1086
- return () => {
1087
- target.removeEventListener(event, callback);
1088
- };
1089
- }, [target, event, callback]);
1090
- };
1091
-
1092
- const StaticSpotlight = ({ element }) => {
1093
- const clientRect = useBoundingClientRect(element);
1094
- const style = clientRect
1095
- ? {
1096
- top: clientRect.top,
1097
- left: clientRect.left,
1098
- height: clientRect.height,
1099
- width: clientRect.width,
1100
- }
1101
- : {};
1102
- return clientRect ? (React.createElement(Portal, null,
1103
- React.createElement("div", { className: "pf-v5-c-backdrop pfext-spotlight__with-backdrop" },
1104
- React.createElement("div", { className: "pfext-spotlight pfext-spotlight__element-highlight-noanimate", style: style })))) : null;
1105
- };
1106
-
1107
- const Spotlight = ({ selector, interactive }) => {
1108
- // if target element is a hidden one return null
1109
- const element = React.useMemo(() => {
1110
- const highlightElement = document.querySelector(selector);
1111
- let hiddenElement = highlightElement;
1112
- while (hiddenElement) {
1113
- const ariaHidden = hiddenElement.getAttribute('aria-hidden');
1114
- if (ariaHidden === 'true') {
1115
- return null;
1116
- }
1117
- hiddenElement = hiddenElement.parentElement;
1118
- }
1119
- return highlightElement;
1120
- }, [selector]);
1121
- if (!element) {
1122
- return null;
1123
- }
1124
- return interactive ? (React.createElement(InteractiveSpotlight, { element: element })) : (React.createElement(StaticSpotlight, { element: element }));
1125
- };
1126
-
1127
- const MarkdownHighlightExtension = ({ docContext, rootSelector, }) => {
1128
- const [selector, setSelector] = React.useState(null);
1129
- React.useEffect(() => {
1130
- const elements = docContext.querySelectorAll(`${rootSelector} [data-highlight]`);
1131
- let timeoutId;
1132
- function startHighlight(e) {
1133
- const highlightId = e.target.getAttribute('data-highlight');
1134
- if (!highlightId) {
1135
- return;
1136
- }
1137
- setSelector(null);
1138
- timeoutId = setTimeout(() => {
1139
- setSelector(`[data-quickstart-id="${highlightId}"]`);
1140
- }, 0);
1141
- }
1142
- elements && elements.forEach((elm) => elm.addEventListener('click', startHighlight));
1143
- return () => {
1144
- clearTimeout(timeoutId);
1145
- elements && elements.forEach((elm) => elm.removeEventListener('click', startHighlight));
1146
- };
1147
- }, [docContext, rootSelector]);
1148
- React.useEffect(() => {
1149
- const elements = docContext.querySelectorAll(`${rootSelector} [class^=data-highlight__]`);
1150
- let timeoutId;
1151
- function startHighlight(e) {
1152
- e.preventDefault();
1153
- const classes = e.target.getAttribute('class').split(' ');
1154
- let highlightId;
1155
- for (const className of classes) {
1156
- if (className.startsWith('data-highlight__')) {
1157
- highlightId = className.split('__')[1];
1158
- break;
1159
- }
1160
- }
1161
- if (!highlightId) {
1162
- return;
1163
- }
1164
- setSelector(null);
1165
- timeoutId = setTimeout(() => {
1166
- setSelector(`[data-quickstart-id="${highlightId}"]`);
1167
- }, 0);
1168
- }
1169
- elements && elements.forEach((elm) => elm.addEventListener('click', startHighlight));
1170
- return () => {
1171
- clearTimeout(timeoutId);
1172
- elements && elements.forEach((elm) => elm.removeEventListener('click', startHighlight));
1173
- };
1174
- }, [docContext, rootSelector]);
1175
- if (!selector) {
1176
- return null;
1177
- }
1178
- return React.createElement(Spotlight, { selector: selector, interactive: true });
1179
- };
1180
-
1181
- const MARKDOWN_COPY_BUTTON_ID = 'data-copy-for';
1182
- const MARKDOWN_SNIPPET_ID = 'data-snippet-id';
1183
- const ACCORDION_MARKDOWN_BUTTON_ID = `accordion-markdown-button-id`;
1088
+ const useEventListener = (target, event, callback) => {
1089
+ useEffect(() => {
1090
+ target.addEventListener(event, callback);
1091
+ return () => {
1092
+ target.removeEventListener(event, callback);
1093
+ };
1094
+ }, [target, event, callback]);
1095
+ };
1096
+
1097
+ const StaticSpotlight = ({ element }) => {
1098
+ const clientRect = useBoundingClientRect(element);
1099
+ const style = clientRect
1100
+ ? {
1101
+ top: clientRect.top,
1102
+ left: clientRect.left,
1103
+ height: clientRect.height,
1104
+ width: clientRect.width,
1105
+ }
1106
+ : {};
1107
+ return clientRect ? (React.createElement(Portal, null,
1108
+ React.createElement("div", { className: "pf-v5-c-backdrop pfext-spotlight__with-backdrop" },
1109
+ React.createElement("div", { className: "pfext-spotlight pfext-spotlight__element-highlight-noanimate", style: style })))) : null;
1110
+ };
1111
+
1112
+ const Spotlight = ({ selector, interactive }) => {
1113
+ // if target element is a hidden one return null
1114
+ const element = React.useMemo(() => {
1115
+ const highlightElement = document.querySelector(selector);
1116
+ let hiddenElement = highlightElement;
1117
+ while (hiddenElement) {
1118
+ const ariaHidden = hiddenElement.getAttribute('aria-hidden');
1119
+ if (ariaHidden === 'true') {
1120
+ return null;
1121
+ }
1122
+ hiddenElement = hiddenElement.parentElement;
1123
+ }
1124
+ return highlightElement;
1125
+ }, [selector]);
1126
+ if (!element) {
1127
+ return null;
1128
+ }
1129
+ return interactive ? (React.createElement(InteractiveSpotlight, { element: element })) : (React.createElement(StaticSpotlight, { element: element }));
1130
+ };
1131
+
1132
+ const MarkdownHighlightExtension = ({ docContext, rootSelector, }) => {
1133
+ const [selector, setSelector] = React.useState(null);
1134
+ React.useEffect(() => {
1135
+ const elements = docContext.querySelectorAll(`${rootSelector} [data-highlight]`);
1136
+ let timeoutId;
1137
+ function startHighlight(e) {
1138
+ const highlightId = e.target.getAttribute('data-highlight');
1139
+ if (!highlightId) {
1140
+ return;
1141
+ }
1142
+ setSelector(null);
1143
+ timeoutId = setTimeout(() => {
1144
+ setSelector(`[data-quickstart-id="${highlightId}"]`);
1145
+ }, 0);
1146
+ }
1147
+ elements && elements.forEach((elm) => elm.addEventListener('click', startHighlight));
1148
+ return () => {
1149
+ clearTimeout(timeoutId);
1150
+ elements && elements.forEach((elm) => elm.removeEventListener('click', startHighlight));
1151
+ };
1152
+ }, [docContext, rootSelector]);
1153
+ React.useEffect(() => {
1154
+ const elements = docContext.querySelectorAll(`${rootSelector} [class^=data-highlight__]`);
1155
+ let timeoutId;
1156
+ function startHighlight(e) {
1157
+ e.preventDefault();
1158
+ const classes = e.target.getAttribute('class').split(' ');
1159
+ let highlightId;
1160
+ for (const className of classes) {
1161
+ if (className.startsWith('data-highlight__')) {
1162
+ highlightId = className.split('__')[1];
1163
+ break;
1164
+ }
1165
+ }
1166
+ if (!highlightId) {
1167
+ return;
1168
+ }
1169
+ setSelector(null);
1170
+ timeoutId = setTimeout(() => {
1171
+ setSelector(`[data-quickstart-id="${highlightId}"]`);
1172
+ }, 0);
1173
+ }
1174
+ elements && elements.forEach((elm) => elm.addEventListener('click', startHighlight));
1175
+ return () => {
1176
+ clearTimeout(timeoutId);
1177
+ elements && elements.forEach((elm) => elm.removeEventListener('click', startHighlight));
1178
+ };
1179
+ }, [docContext, rootSelector]);
1180
+ if (!selector) {
1181
+ return null;
1182
+ }
1183
+ return React.createElement(Spotlight, { selector: selector, interactive: true });
1184
+ };
1185
+
1186
+ const MARKDOWN_COPY_BUTTON_ID = 'data-copy-for';
1187
+ const MARKDOWN_SNIPPET_ID = 'data-snippet-id';
1188
+ const ACCORDION_MARKDOWN_BUTTON_ID = `accordion-markdown-button-id`;
1184
1189
  const ACCORDION_MARKDOWN_CONTENT_ID = `accordion-markdown-content-id`;
1185
1190
 
1186
- const CopyClipboard = ({ element, rootSelector, docContext, }) => {
1187
- const { getResource } = React.useContext(QuickStartContext);
1188
- const [showSuccessContent, setShowSuccessContent] = React.useState(false);
1189
- const textToCopy = React.useMemo(() => {
1190
- var _a;
1191
- const copyTextId = element.getAttribute(MARKDOWN_COPY_BUTTON_ID);
1192
- return (_a = docContext.querySelector(`${rootSelector} [${MARKDOWN_SNIPPET_ID}="${copyTextId}"]`)) === null || _a === void 0 ? void 0 : _a.innerText;
1193
- }, [element, docContext, rootSelector]);
1194
- useEventListener(element, 'click', React.useCallback(() => {
1195
- navigator.clipboard
1196
- .writeText(textToCopy.trim())
1197
- .then(() => {
1198
- setShowSuccessContent(true);
1199
- })
1200
- .catch(() => { });
1201
- }, [textToCopy]));
1202
- useEventListener(element, 'mouseleave', React.useCallback(() => {
1203
- setShowSuccessContent(false);
1204
- }, []));
1205
- return showSuccessContent ? (React.createElement(Tooltip, { key: "after-copy", isVisible: true, triggerRef: () => element, content: getResource('Successfully copied to clipboard!'), className: "pfext-quick-start__base" })) : (React.createElement(Tooltip, { key: "before-copy", triggerRef: () => element, content: getResource('Copy to clipboard'), className: "pfext-quick-start__base" }));
1206
- };
1207
- const MarkdownCopyClipboard = ({ docContext, rootSelector, }) => {
1208
- const elements = docContext.querySelectorAll(`${rootSelector} [${MARKDOWN_COPY_BUTTON_ID}]`);
1209
- return elements.length > 0 ? (React.createElement(React.Fragment, null, Array.from(elements).map((elm) => {
1210
- const attributeValue = elm.getAttribute(MARKDOWN_COPY_BUTTON_ID);
1211
- return (React.createElement(CopyClipboard, { key: attributeValue, element: elm, rootSelector: rootSelector, docContext: docContext }));
1212
- }))) : null;
1191
+ const CopyClipboard = ({ element, rootSelector, docContext, }) => {
1192
+ const { getResource } = React.useContext(QuickStartContext);
1193
+ const [showSuccessContent, setShowSuccessContent] = React.useState(false);
1194
+ const textToCopy = React.useMemo(() => {
1195
+ var _a;
1196
+ const copyTextId = element.getAttribute(MARKDOWN_COPY_BUTTON_ID);
1197
+ return (_a = docContext.querySelector(`${rootSelector} [${MARKDOWN_SNIPPET_ID}="${copyTextId}"]`)) === null || _a === void 0 ? void 0 : _a.innerText;
1198
+ }, [element, docContext, rootSelector]);
1199
+ useEventListener(element, 'click', React.useCallback(() => {
1200
+ navigator.clipboard
1201
+ .writeText(textToCopy.trim())
1202
+ .then(() => {
1203
+ setShowSuccessContent(true);
1204
+ })
1205
+ .catch(() => { });
1206
+ }, [textToCopy]));
1207
+ useEventListener(element, 'mouseleave', React.useCallback(() => {
1208
+ setShowSuccessContent(false);
1209
+ }, []));
1210
+ return showSuccessContent ? (React.createElement(Tooltip, { key: "after-copy", isVisible: true, triggerRef: () => element, content: getResource('Successfully copied to clipboard!'), className: "pfext-quick-start__base" })) : (React.createElement(Tooltip, { key: "before-copy", triggerRef: () => element, content: getResource('Copy to clipboard'), className: "pfext-quick-start__base" }));
1211
+ };
1212
+ const MarkdownCopyClipboard = ({ docContext, rootSelector, }) => {
1213
+ const elements = docContext.querySelectorAll(`${rootSelector} [${MARKDOWN_COPY_BUTTON_ID}]`);
1214
+ return elements.length > 0 ? (React.createElement(React.Fragment, null, Array.from(elements).map((elm) => {
1215
+ const attributeValue = elm.getAttribute(MARKDOWN_COPY_BUTTON_ID);
1216
+ return (React.createElement(CopyClipboard, { key: attributeValue, element: elm, rootSelector: rootSelector, docContext: docContext }));
1217
+ }))) : null;
1213
1218
  };
1214
1219
 
1215
1220
  const removeTemplateWhitespace = (template) => template.replace(/>(?:\s|\n)+</g, '><');
1216
1221
 
1217
- const useInlineCopyClipboardShowdownExtension = () => {
1218
- const { getResource } = React.useContext(QuickStartContext);
1219
- return React.useMemo(() => ({
1220
- type: 'lang',
1221
- regex: /`([^`](.*?)[^`])`{{copy}}/g,
1222
- replace: (text, group, _, groupId) => {
1223
- if (!group || isNaN(groupId)) {
1224
- return text;
1225
- }
1222
+ const useInlineCopyClipboardShowdownExtension = () => {
1223
+ const { getResource } = React.useContext(QuickStartContext);
1224
+ return React.useMemo(() => ({
1225
+ type: 'lang',
1226
+ regex: /`([^`](.*?)[^`])`{{copy}}/g,
1227
+ replace: (text, group, _, groupId) => {
1228
+ if (!group || isNaN(groupId)) {
1229
+ return text;
1230
+ }
1226
1231
  return removeTemplateWhitespace(`<span class="pf-v5-c-clipboard-copy pf-m-inline">
1227
1232
  <span class="pf-v5-c-clipboard-copy__text" ${MARKDOWN_SNIPPET_ID}="${groupId}">${group}</span>
1228
1233
  <span class="pf-v5-c-clipboard-copy__actions">
@@ -1232,20 +1237,20 @@ const useInlineCopyClipboardShowdownExtension = () => {
1232
1237
  </button>
1233
1238
  </span>
1234
1239
  </span>
1235
- </span>`);
1236
- },
1237
- }), [getResource]);
1238
- };
1239
-
1240
- const useMultilineCopyClipboardShowdownExtension = () => {
1241
- const { getResource } = React.useContext(QuickStartContext);
1242
- return React.useMemo(() => ({
1243
- type: 'lang',
1244
- regex: /```[\n]\s*((((?!```).)*?\n)+)\s*```{{copy}}/g,
1245
- replace: (text, group, _1, _2, groupId) => {
1246
- if (!group || isNaN(groupId)) {
1247
- return text;
1248
- }
1240
+ </span>`);
1241
+ },
1242
+ }), [getResource]);
1243
+ };
1244
+
1245
+ const useMultilineCopyClipboardShowdownExtension = () => {
1246
+ const { getResource } = React.useContext(QuickStartContext);
1247
+ return React.useMemo(() => ({
1248
+ type: 'lang',
1249
+ regex: /```[\n]\s*((((?!```).)*?\n)+)\s*```{{copy}}/g,
1250
+ replace: (text, group, _1, _2, groupId) => {
1251
+ if (!group || isNaN(groupId)) {
1252
+ return text;
1253
+ }
1249
1254
  return `<div class="pf-v5-c-code-block">
1250
1255
  <div class="pf-v5-c-code-block__header">
1251
1256
  <div class="pf-v5-c-code-block__actions">
@@ -1262,138 +1267,138 @@ const useMultilineCopyClipboardShowdownExtension = () => {
1262
1267
  ${MARKDOWN_SNIPPET_ID}="${groupId}">${group.trim()}</code>
1263
1268
  </pre>
1264
1269
  </div>
1265
- </div>`;
1266
- },
1267
- }), [getResource]);
1268
- };
1269
-
1270
- // eslint-disable-next-line @typescript-eslint/no-require-imports
1271
- const DOMPurify = require('dompurify');
1272
- const markdownConvert = (markdown, extensions) => {
1273
- const converter = new Converter({
1274
- tables: true,
1275
- openLinksInNewWindow: true,
1276
- strikethrough: true,
1277
- emoji: false,
1278
- });
1279
- if (extensions) {
1280
- converter.addExtension(extensions);
1281
- }
1282
- DOMPurify.addHook('beforeSanitizeElements', function (node) {
1283
- // nodeType 1 = element type
1284
- // transform anchor tags
1285
- if (node.nodeType === 1 && node.nodeName.toLowerCase() === 'a') {
1286
- node.setAttribute('rel', 'noopener noreferrer');
1287
- return node;
1288
- }
1289
- // add PF class to ul and ol lists
1290
- if (node.nodeType === 1 &&
1291
- (node.nodeName.toLowerCase() === 'ul' || node.nodeName.toLowerCase() === 'ol')) {
1292
- node.setAttribute('class', 'pf-v5-c-list');
1293
- return node;
1294
- }
1295
- });
1296
- // Add a hook to make all links open a new window
1297
- DOMPurify.addHook('afterSanitizeAttributes', function (node) {
1298
- // set all elements owning target to target=_blank
1299
- if ('target' in node) {
1300
- node.setAttribute('target', '_blank');
1301
- }
1302
- // set non-HTML/MathML links to xlink:show=new
1303
- if (!node.hasAttribute('target') &&
1304
- (node.hasAttribute('xlink:href') || node.hasAttribute('href'))) {
1305
- node.setAttribute('xlink:show', 'new');
1306
- }
1307
- });
1308
- return DOMPurify.sanitize(converter.makeHtml(markdown), {
1309
- USE_PROFILES: {
1310
- html: true,
1311
- svg: true,
1312
- },
1313
- });
1314
- };
1315
- const SyncMarkdownView = ({ content, emptyMsg, extensions, renderExtension, exactHeight, inline, className, }) => {
1316
- const { getResource } = React.useContext(QuickStartContext);
1317
- const markup = React.useMemo(() => markdownConvert(content || emptyMsg || getResource('Not available'), extensions), [content, emptyMsg, extensions, getResource]);
1318
- const innerProps = {
1319
- renderExtension: (extensions === null || extensions === void 0 ? void 0 : extensions.length) > 0 ? renderExtension : undefined,
1320
- exactHeight,
1321
- markup,
1322
- isEmpty: !content,
1323
- className,
1324
- };
1325
- return inline ? React.createElement(InlineMarkdownView, Object.assign({}, innerProps)) : React.createElement(IFrameMarkdownView, Object.assign({}, innerProps));
1326
- };
1327
- const uniqueId = (function () {
1328
- let num = 0;
1329
- return function (prefix) {
1330
- const prefixStr = String(prefix) || '';
1331
- num += 1;
1332
- return prefixStr + num;
1333
- };
1334
- })();
1335
- const RenderExtension = ({ renderExtension, selector, markup, docContext, }) => {
1336
- const forceRender = useForceRender();
1337
- const markupRef = React.useRef(null);
1338
- const shouldRenderExtension = React.useCallback(() => {
1339
- if (markupRef.current === markup) {
1340
- return true;
1341
- }
1342
- markupRef.current = markup;
1343
- return false;
1344
- }, [markup]);
1345
- /**
1346
- * During a render cycle in which markup changes, renderExtension receives an old copy of document
1347
- * because react is still updating the dom using `dangerouslySetInnerHTML` with latest markdown markup
1348
- * which causes the component rendered by renderExtension to receive old copy of document
1349
- * use forceRender to delay the rendering of extension by one render cycle
1350
- */
1351
- React.useEffect(() => {
1352
- if (renderExtension) {
1353
- forceRender();
1354
- }
1355
- // eslint-disable-next-line react-hooks/exhaustive-deps
1356
- }, [markup]);
1357
- return (React.createElement(React.Fragment, null, shouldRenderExtension() ? renderExtension === null || renderExtension === void 0 ? void 0 : renderExtension(docContext !== null && docContext !== void 0 ? docContext : document, selector) : null));
1358
- };
1359
- const InlineMarkdownView = ({ markup, isEmpty, renderExtension, className, }) => {
1360
- const id = React.useMemo(() => uniqueId('markdown'), []);
1361
- return (React.createElement("div", { className: css('pfext-markdown-view', { 'is-empty': isEmpty }, className), id: id },
1362
- React.createElement("div", { dangerouslySetInnerHTML: { __html: markup } }),
1363
- renderExtension && (React.createElement(RenderExtension, { renderExtension: renderExtension, selector: `#${id}`, markup: markup }))));
1364
- };
1365
- const IFrameMarkdownView = ({ exactHeight, markup, isEmpty, renderExtension, className, }) => {
1366
- const [frame, setFrame] = React.useState();
1367
- const [loaded, setLoaded] = React.useState(false);
1368
- const updateTimeoutHandle = React.useRef();
1369
- const updateDimensions = React.useCallback(() => {
1370
- var _a;
1371
- if (!((_a = frame === null || frame === void 0 ? void 0 : frame.contentWindow) === null || _a === void 0 ? void 0 : _a.document.body.firstChild)) {
1372
- return;
1373
- }
1374
- frame.style.height = `${frame.contentWindow.document.body.firstElementChild.scrollHeight}px`;
1375
- // Let the new height take effect, then reset again once we recompute
1376
- updateTimeoutHandle.current = setTimeout(() => {
1377
- if (exactHeight) {
1378
- frame.style.height = `${frame.contentWindow.document.body.firstElementChild.scrollHeight}px`;
1379
- }
1380
- else {
1381
- // Increase by 15px for the case where a horizontal scrollbar might appear
1382
- frame.style.height = `${frame.contentWindow.document.body.firstElementChild.scrollHeight + 15}px`;
1383
- }
1384
- });
1385
- }, [frame, exactHeight]);
1386
- React.useEffect(() => () => {
1387
- clearTimeout(updateTimeoutHandle.current);
1388
- }, []);
1389
- const onLoad = React.useCallback(() => {
1390
- updateDimensions();
1391
- setLoaded(true);
1392
- }, [updateDimensions]);
1393
- // Find the app's stylesheets and inject them into the frame to ensure consistent styling.
1394
- const filteredLinks = Array.from(document.getElementsByTagName('link')).filter((l) => l.href.includes('app-bundle'));
1270
+ </div>`;
1271
+ },
1272
+ }), [getResource]);
1273
+ };
1274
+
1275
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
1276
+ const DOMPurify = require('dompurify');
1277
+ const markdownConvert = (markdown, extensions) => {
1278
+ const converter = new Converter({
1279
+ tables: true,
1280
+ openLinksInNewWindow: true,
1281
+ strikethrough: true,
1282
+ emoji: false,
1283
+ });
1284
+ if (extensions) {
1285
+ converter.addExtension(extensions);
1286
+ }
1287
+ DOMPurify.addHook('beforeSanitizeElements', function (node) {
1288
+ // nodeType 1 = element type
1289
+ // transform anchor tags
1290
+ if (node.nodeType === 1 && node.nodeName.toLowerCase() === 'a') {
1291
+ node.setAttribute('rel', 'noopener noreferrer');
1292
+ return node;
1293
+ }
1294
+ // add PF class to ul and ol lists
1295
+ if (node.nodeType === 1 &&
1296
+ (node.nodeName.toLowerCase() === 'ul' || node.nodeName.toLowerCase() === 'ol')) {
1297
+ node.setAttribute('class', 'pf-v5-c-list');
1298
+ return node;
1299
+ }
1300
+ });
1301
+ // Add a hook to make all links open a new window
1302
+ DOMPurify.addHook('afterSanitizeAttributes', function (node) {
1303
+ // set all elements owning target to target=_blank
1304
+ if ('target' in node) {
1305
+ node.setAttribute('target', '_blank');
1306
+ }
1307
+ // set non-HTML/MathML links to xlink:show=new
1308
+ if (!node.hasAttribute('target') &&
1309
+ (node.hasAttribute('xlink:href') || node.hasAttribute('href'))) {
1310
+ node.setAttribute('xlink:show', 'new');
1311
+ }
1312
+ });
1313
+ return DOMPurify.sanitize(converter.makeHtml(markdown), {
1314
+ USE_PROFILES: {
1315
+ html: true,
1316
+ svg: true,
1317
+ },
1318
+ });
1319
+ };
1320
+ const SyncMarkdownView = ({ content, emptyMsg, extensions, renderExtension, exactHeight, inline, className, }) => {
1321
+ const { getResource } = React.useContext(QuickStartContext);
1322
+ const markup = React.useMemo(() => markdownConvert(content || emptyMsg || getResource('Not available'), extensions), [content, emptyMsg, extensions, getResource]);
1323
+ const innerProps = {
1324
+ renderExtension: (extensions === null || extensions === void 0 ? void 0 : extensions.length) > 0 ? renderExtension : undefined,
1325
+ exactHeight,
1326
+ markup,
1327
+ isEmpty: !content,
1328
+ className,
1329
+ };
1330
+ return inline ? React.createElement(InlineMarkdownView, Object.assign({}, innerProps)) : React.createElement(IFrameMarkdownView, Object.assign({}, innerProps));
1331
+ };
1332
+ const uniqueId = (function () {
1333
+ let num = 0;
1334
+ return function (prefix) {
1335
+ const prefixStr = String(prefix) || '';
1336
+ num += 1;
1337
+ return prefixStr + num;
1338
+ };
1339
+ })();
1340
+ const RenderExtension = ({ renderExtension, selector, markup, docContext, }) => {
1341
+ const forceRender = useForceRender();
1342
+ const markupRef = React.useRef(null);
1343
+ const shouldRenderExtension = React.useCallback(() => {
1344
+ if (markupRef.current === markup) {
1345
+ return true;
1346
+ }
1347
+ markupRef.current = markup;
1348
+ return false;
1349
+ }, [markup]);
1350
+ /**
1351
+ * During a render cycle in which markup changes, renderExtension receives an old copy of document
1352
+ * because react is still updating the dom using `dangerouslySetInnerHTML` with latest markdown markup
1353
+ * which causes the component rendered by renderExtension to receive old copy of document
1354
+ * use forceRender to delay the rendering of extension by one render cycle
1355
+ */
1356
+ React.useEffect(() => {
1357
+ if (renderExtension) {
1358
+ forceRender();
1359
+ }
1360
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1361
+ }, [markup]);
1362
+ return (React.createElement(React.Fragment, null, shouldRenderExtension() ? renderExtension === null || renderExtension === void 0 ? void 0 : renderExtension(docContext !== null && docContext !== void 0 ? docContext : document, selector) : null));
1363
+ };
1364
+ const InlineMarkdownView = ({ markup, isEmpty, renderExtension, className, }) => {
1365
+ const id = React.useMemo(() => uniqueId('markdown'), []);
1366
+ return (React.createElement("div", { className: css('pfext-markdown-view', { 'is-empty': isEmpty }, className), id: id },
1367
+ React.createElement("div", { dangerouslySetInnerHTML: { __html: markup } }),
1368
+ renderExtension && (React.createElement(RenderExtension, { renderExtension: renderExtension, selector: `#${id}`, markup: markup }))));
1369
+ };
1370
+ const IFrameMarkdownView = ({ exactHeight, markup, isEmpty, renderExtension, className, }) => {
1371
+ const [frame, setFrame] = React.useState();
1372
+ const [loaded, setLoaded] = React.useState(false);
1373
+ const updateTimeoutHandle = React.useRef();
1374
+ const updateDimensions = React.useCallback(() => {
1375
+ var _a;
1376
+ if (!((_a = frame === null || frame === void 0 ? void 0 : frame.contentWindow) === null || _a === void 0 ? void 0 : _a.document.body.firstChild)) {
1377
+ return;
1378
+ }
1379
+ frame.style.height = `${frame.contentWindow.document.body.firstElementChild.scrollHeight}px`;
1380
+ // Let the new height take effect, then reset again once we recompute
1381
+ updateTimeoutHandle.current = setTimeout(() => {
1382
+ if (exactHeight) {
1383
+ frame.style.height = `${frame.contentWindow.document.body.firstElementChild.scrollHeight}px`;
1384
+ }
1385
+ else {
1386
+ // Increase by 15px for the case where a horizontal scrollbar might appear
1387
+ frame.style.height = `${frame.contentWindow.document.body.firstElementChild.scrollHeight + 15}px`;
1388
+ }
1389
+ });
1390
+ }, [frame, exactHeight]);
1391
+ React.useEffect(() => () => {
1392
+ clearTimeout(updateTimeoutHandle.current);
1393
+ }, []);
1394
+ const onLoad = React.useCallback(() => {
1395
+ updateDimensions();
1396
+ setLoaded(true);
1397
+ }, [updateDimensions]);
1398
+ // Find the app's stylesheets and inject them into the frame to ensure consistent styling.
1399
+ const filteredLinks = Array.from(document.getElementsByTagName('link')).filter((l) => l.href.includes('app-bundle'));
1395
1400
  const linkRefs = filteredLinks.reduce((refs, link) => `${refs}
1396
- <link rel="stylesheet" href="${link.href}">`, '');
1401
+ <link rel="stylesheet" href="${link.href}">`, '');
1397
1402
  const contents = `
1398
1403
  ${linkRefs}
1399
1404
  <style type="text/css">
@@ -1418,1161 +1423,1161 @@ const IFrameMarkdownView = ({ exactHeight, markup, isEmpty, renderExtension, cla
1418
1423
  padding-top: 0;
1419
1424
  }
1420
1425
  </style>
1421
- <body class="pf-m-redhat-font"><div style="overflow-y: auto;">${markup}</div></body>`;
1422
- return (React.createElement(React.Fragment, null,
1423
- React.createElement("iframe", { sandbox: "allow-popups allow-popups-to-escape-sandbox allow-same-origin", srcDoc: contents, style: { border: '0px', display: 'block', width: '100%', height: '0' }, ref: (r) => setFrame(r), onLoad: () => onLoad(), className: className }),
1424
- loaded && frame && renderExtension && (React.createElement(RenderExtension, { markup: markup, selector: '', renderExtension: renderExtension, docContext: frame.contentDocument }))));
1426
+ <body class="pf-m-redhat-font"><div style="overflow-y: auto;">${markup}</div></body>`;
1427
+ return (React.createElement(React.Fragment, null,
1428
+ React.createElement("iframe", { sandbox: "allow-popups allow-popups-to-escape-sandbox allow-same-origin", srcDoc: contents, style: { border: '0px', display: 'block', width: '100%', height: '0' }, ref: (r) => setFrame(r), onLoad: () => onLoad(), className: className }),
1429
+ loaded && frame && renderExtension && (React.createElement(RenderExtension, { markup: markup, selector: '', renderExtension: renderExtension, docContext: frame.contentDocument }))));
1425
1430
  };
1426
1431
 
1427
- const LINK_LABEL = '[\\d\\w\\s-()$!]+';
1428
- const HIGHLIGHT_ACTIONS = ['highlight'];
1429
- const SELECTOR_ID = `[\\w-]+`;
1430
- // [linkLabel]{{action id}}
1432
+ const LINK_LABEL = '[\\d\\w\\s-()$!]+';
1433
+ const HIGHLIGHT_ACTIONS = ['highlight'];
1434
+ const SELECTOR_ID = `[\\w-]+`;
1435
+ // [linkLabel]{{action id}}
1431
1436
  const HIGHLIGHT_REGEXP = new RegExp(`\\[(${LINK_LABEL})]{{(${HIGHLIGHT_ACTIONS.join('|')}) (${SELECTOR_ID})}}`, 'g');
1432
1437
 
1433
- const removeParagraphWrap = (markdown) => markdown.replace(/^<p>|<\/p>$/g, '');
1434
- const QuickStartMarkdownView = ({ content, exactHeight, className, }) => {
1435
- const { markdown } = React.useContext(QuickStartContext);
1436
- const inlineCopyClipboardShowdownExtension = useInlineCopyClipboardShowdownExtension();
1437
- const multilineCopyClipboardShowdownExtension = useMultilineCopyClipboardShowdownExtension();
1438
- const admonitionShowdownExtension = useAdmonitionShowdownExtension();
1439
- const codeShowdownExtension = useCodeShowdownExtension();
1440
- const accordionShowdownExtension = useAccordionShowdownExtension();
1441
- return (React.createElement(SyncMarkdownView, { inline: true, content: content, exactHeight: exactHeight, extensions: [
1442
- {
1443
- type: 'lang',
1444
- regex: HIGHLIGHT_REGEXP,
1445
- replace: (text, linkLabel, linkType, linkId) => {
1446
- if (!linkLabel || !linkType || !linkId) {
1447
- return text;
1448
- }
1449
- return `<button class="pf-v5-c-button pf-m-inline pf-m-link" data-highlight="${linkId}">${linkLabel}</button>`;
1450
- },
1451
- },
1452
- {
1453
- type: 'output',
1454
- filter(text) {
1455
- // check HTML for patterns like: <em>Status: unknown</em>{#extension-requirement-status}
1456
- // and replace with <em id="extension-requirement-status">Status: unknown</em>
1457
- return text.replace(/<em>(.*)<\/em>{#(.*)}/g, '<em id="$2">$1</em>');
1458
- },
1459
- },
1460
- inlineCopyClipboardShowdownExtension,
1461
- multilineCopyClipboardShowdownExtension,
1462
- admonitionShowdownExtension,
1463
- codeShowdownExtension,
1464
- accordionShowdownExtension,
1465
- ...(markdown ? markdown.extensions : []),
1466
- ], renderExtension: (docContext, rootSelector) => (React.createElement(React.Fragment, null,
1467
- React.createElement(AccordionRenderExtension, { docContext: docContext }),
1468
- React.createElement(MarkdownHighlightExtension, { docContext: docContext, rootSelector: rootSelector }),
1469
- React.createElement(MarkdownCopyClipboard, { docContext: docContext, rootSelector: rootSelector }),
1470
- markdown &&
1471
- markdown.renderExtension &&
1472
- markdown.renderExtension(docContext, rootSelector))), className: className }));
1473
- };
1474
-
1475
- var AdmonitionType;
1476
- (function (AdmonitionType) {
1477
- AdmonitionType["TIP"] = "TIP";
1478
- AdmonitionType["NOTE"] = "NOTE";
1479
- AdmonitionType["IMPORTANT"] = "IMPORTANT";
1480
- AdmonitionType["WARNING"] = "WARNING";
1481
- AdmonitionType["CAUTION"] = "CAUTION";
1482
- })(AdmonitionType || (AdmonitionType = {}));
1483
- const admonitionToAlertVariantMap = {
1484
- [AdmonitionType.NOTE]: { variant: 'info' },
1485
- [AdmonitionType.TIP]: { variant: 'default', customIcon: React.createElement(LightbulbIcon, null) },
1486
- [AdmonitionType.IMPORTANT]: { variant: 'danger' },
1487
- [AdmonitionType.CAUTION]: { variant: 'warning', customIcon: React.createElement(FireIcon, null) },
1488
- [AdmonitionType.WARNING]: { variant: 'warning' },
1489
- };
1490
- const useAdmonitionShowdownExtension = () =>
1491
- // const { getResource } = React.useContext<QuickStartContextValues>(QuickStartContext);
1492
- React.useMemo(() => ({
1493
- type: 'lang',
1494
- regex: /\[(.+)]{{(admonition) ([\w-]+)}}/g,
1495
- replace: (text, content, admonitionLabel, admonitionType, groupId) => {
1496
- if (!content || !admonitionLabel || !admonitionType || !groupId) {
1497
- return text;
1498
- }
1499
- admonitionType = admonitionType.toUpperCase();
1500
- const { variant, customIcon } = admonitionToAlertVariantMap[admonitionType];
1501
- const style = admonitionType === AdmonitionType.CAUTION ? { backgroundColor: '#ec7a0915' } : {};
1502
- const mdContent = React.createElement(QuickStartMarkdownView, { content: content });
1503
- const pfAlert = (React.createElement(Alert, { variant: variant, customIcon: customIcon && customIcon, isInline: true, title: admonitionType, className: "pfext-markdown-admonition", style: style }, mdContent));
1504
- return removeTemplateWhitespace(renderToStaticMarkup(pfAlert));
1505
- },
1438
+ const removeParagraphWrap = (markdown) => markdown.replace(/^<p>|<\/p>$/g, '');
1439
+ const QuickStartMarkdownView = ({ content, exactHeight, className, }) => {
1440
+ const { markdown } = React.useContext(QuickStartContext);
1441
+ const inlineCopyClipboardShowdownExtension = useInlineCopyClipboardShowdownExtension();
1442
+ const multilineCopyClipboardShowdownExtension = useMultilineCopyClipboardShowdownExtension();
1443
+ const admonitionShowdownExtension = useAdmonitionShowdownExtension();
1444
+ const codeShowdownExtension = useCodeShowdownExtension();
1445
+ const accordionShowdownExtension = useAccordionShowdownExtension();
1446
+ return (React.createElement(SyncMarkdownView, { inline: true, content: content, exactHeight: exactHeight, extensions: [
1447
+ {
1448
+ type: 'lang',
1449
+ regex: HIGHLIGHT_REGEXP,
1450
+ replace: (text, linkLabel, linkType, linkId) => {
1451
+ if (!linkLabel || !linkType || !linkId) {
1452
+ return text;
1453
+ }
1454
+ return `<button class="pf-v5-c-button pf-m-inline pf-m-link" data-highlight="${linkId}">${linkLabel}</button>`;
1455
+ },
1456
+ },
1457
+ {
1458
+ type: 'output',
1459
+ filter(text) {
1460
+ // check HTML for patterns like: <em>Status: unknown</em>{#extension-requirement-status}
1461
+ // and replace with <em id="extension-requirement-status">Status: unknown</em>
1462
+ return text.replace(/<em>(.*)<\/em>{#(.*)}/g, '<em id="$2">$1</em>');
1463
+ },
1464
+ },
1465
+ inlineCopyClipboardShowdownExtension,
1466
+ multilineCopyClipboardShowdownExtension,
1467
+ admonitionShowdownExtension,
1468
+ codeShowdownExtension,
1469
+ accordionShowdownExtension,
1470
+ ...(markdown ? markdown.extensions : []),
1471
+ ], renderExtension: (docContext, rootSelector) => (React.createElement(React.Fragment, null,
1472
+ React.createElement(AccordionRenderExtension, { docContext: docContext }),
1473
+ React.createElement(MarkdownHighlightExtension, { docContext: docContext, rootSelector: rootSelector }),
1474
+ React.createElement(MarkdownCopyClipboard, { docContext: docContext, rootSelector: rootSelector }),
1475
+ markdown &&
1476
+ markdown.renderExtension &&
1477
+ markdown.renderExtension(docContext, rootSelector))), className: className }));
1478
+ };
1479
+
1480
+ var AdmonitionType;
1481
+ (function (AdmonitionType) {
1482
+ AdmonitionType["TIP"] = "TIP";
1483
+ AdmonitionType["NOTE"] = "NOTE";
1484
+ AdmonitionType["IMPORTANT"] = "IMPORTANT";
1485
+ AdmonitionType["WARNING"] = "WARNING";
1486
+ AdmonitionType["CAUTION"] = "CAUTION";
1487
+ })(AdmonitionType || (AdmonitionType = {}));
1488
+ const admonitionToAlertVariantMap = {
1489
+ [AdmonitionType.NOTE]: { variant: 'info' },
1490
+ [AdmonitionType.TIP]: { variant: 'default', customIcon: React.createElement(LightbulbIcon, null) },
1491
+ [AdmonitionType.IMPORTANT]: { variant: 'danger' },
1492
+ [AdmonitionType.CAUTION]: { variant: 'warning', customIcon: React.createElement(FireIcon, null) },
1493
+ [AdmonitionType.WARNING]: { variant: 'warning' },
1494
+ };
1495
+ const useAdmonitionShowdownExtension = () =>
1496
+ // const { getResource } = React.useContext<QuickStartContextValues>(QuickStartContext);
1497
+ React.useMemo(() => ({
1498
+ type: 'lang',
1499
+ regex: /\[(.+)]{{(admonition) ([\w-]+)}}/g,
1500
+ replace: (text, content, admonitionLabel, admonitionType, groupId) => {
1501
+ if (!content || !admonitionLabel || !admonitionType || !groupId) {
1502
+ return text;
1503
+ }
1504
+ admonitionType = admonitionType.toUpperCase();
1505
+ const { variant, customIcon } = admonitionToAlertVariantMap[admonitionType];
1506
+ const style = admonitionType === AdmonitionType.CAUTION ? { backgroundColor: '#ec7a0915' } : {};
1507
+ const mdContent = React.createElement(QuickStartMarkdownView, { content: content });
1508
+ const pfAlert = (React.createElement(Alert, { variant: variant, customIcon: customIcon && customIcon, isInline: true, title: admonitionType, className: "pfext-markdown-admonition", style: style }, mdContent));
1509
+ return removeTemplateWhitespace(renderToStaticMarkup(pfAlert));
1510
+ },
1506
1511
  }), []);
1507
1512
 
1508
- const useCodeShowdownExtension = () => React.useMemo(() => ({
1509
- type: 'output',
1510
- regex: /<pre><code>(.*?)\n?<\/code><\/pre>/g,
1511
- replace: (text, content) => {
1512
- if (!content) {
1513
- return text;
1514
- }
1515
- const pfCodeBlock = React.createElement(CodeBlock, null, content);
1516
- return removeTemplateWhitespace(renderToStaticMarkup(pfCodeBlock));
1517
- },
1513
+ const useCodeShowdownExtension = () => React.useMemo(() => ({
1514
+ type: 'output',
1515
+ regex: /<pre><code>(.*?)\n?<\/code><\/pre>/g,
1516
+ replace: (text, content) => {
1517
+ if (!content) {
1518
+ return text;
1519
+ }
1520
+ const pfCodeBlock = React.createElement(CodeBlock, null, content);
1521
+ return removeTemplateWhitespace(renderToStaticMarkup(pfCodeBlock));
1522
+ },
1518
1523
  }), []);
1519
1524
 
1520
- const useAccordionShowdownExtension = () => React.useMemo(() => ({
1521
- type: 'lang',
1522
- regex: /\[(.+)]{{(accordion) ("(.*?)")}}/g,
1523
- replace: (_text, accordionContent, _command, accordionHeading) => {
1524
- const accordionId = String(accordionHeading).replace(/\s/g, '-');
1525
- return removeTemplateWhitespace(renderToStaticMarkup(React.createElement(Accordion, { asDefinitionList: true },
1526
- React.createElement(AccordionItem, null,
1527
- React.createElement(AccordionToggle, { isExpanded: false, id: `${ACCORDION_MARKDOWN_BUTTON_ID}-${accordionId}` }, accordionHeading),
1528
- React.createElement(AccordionContent, { id: `${ACCORDION_MARKDOWN_CONTENT_ID}-${accordionId}`, isHidden: !false }, accordionContent)))));
1529
- },
1525
+ const useAccordionShowdownExtension = () => React.useMemo(() => ({
1526
+ type: 'lang',
1527
+ regex: /\[(.+)]{{(accordion) ("(.*?)")}}/g,
1528
+ replace: (_text, accordionContent, _command, accordionHeading) => {
1529
+ const accordionId = String(accordionHeading).replace(/\s/g, '-');
1530
+ return removeTemplateWhitespace(renderToStaticMarkup(React.createElement(Accordion, { asDefinitionList: true },
1531
+ React.createElement(AccordionItem, null,
1532
+ React.createElement(AccordionToggle, { isExpanded: false, id: `${ACCORDION_MARKDOWN_BUTTON_ID}-${accordionId}` }, accordionHeading),
1533
+ React.createElement(AccordionContent, { id: `${ACCORDION_MARKDOWN_CONTENT_ID}-${accordionId}`, isHidden: !false }, accordionContent)))));
1534
+ },
1530
1535
  }), []);
1531
1536
 
1532
- const AccordionShowdownHandler = ({ buttonElement, contentElement, }) => {
1533
- const [expanded, setExpanded] = React.useState(false);
1534
- const handleClick = () => {
1535
- const expandedModifier = 'pf-m-expanded';
1536
- buttonElement.className = `pf-v5-c-accordion__toggle ${!expanded ? expandedModifier : ''}`;
1537
- contentElement.hidden = expanded;
1538
- contentElement.className = `pf-v5-c-accordion__expanded-content ${!expanded ? expandedModifier : ''}`;
1539
- setExpanded(!expanded);
1540
- };
1541
- useEventListener(buttonElement, 'click', handleClick);
1542
- return React.createElement(React.Fragment, null);
1543
- };
1544
- const AccordionRenderExtension = ({ docContext }) => {
1545
- const buttonElements = docContext.querySelectorAll(`[id ^= ${ACCORDION_MARKDOWN_BUTTON_ID}]`);
1546
- const contentElements = docContext.querySelectorAll(`[id ^= ${ACCORDION_MARKDOWN_CONTENT_ID}]`);
1547
- return buttonElements.length > 0 ? (React.createElement(React.Fragment, null, Array.from(buttonElements).map((elm) => {
1548
- const content = Array.from(contentElements).find((elm2) => {
1549
- const elmId = elm.id.split(ACCORDION_MARKDOWN_BUTTON_ID)[1];
1550
- const elm2Id = elm2.id.split(ACCORDION_MARKDOWN_CONTENT_ID)[1];
1551
- return elmId === elm2Id;
1552
- });
1553
- return (React.createElement(AccordionShowdownHandler, { key: elm.id.split(ACCORDION_MARKDOWN_BUTTON_ID)[1], buttonElement: elm, contentElement: content }));
1554
- }))) : null;
1555
- };
1556
-
1557
- const FallbackImg = ({ src, alt, className, fallback }) => {
1558
- const [isSrcValid, setIsSrcValid] = React.useState(true);
1559
- if (src && isSrcValid) {
1560
- return React.createElement("img", { className: className, src: src, alt: alt, onError: () => setIsSrcValid(false) });
1561
- }
1562
- return React.createElement(React.Fragment, null, fallback);
1537
+ const AccordionShowdownHandler = ({ buttonElement, contentElement, }) => {
1538
+ const [expanded, setExpanded] = React.useState(false);
1539
+ const handleClick = () => {
1540
+ const expandedModifier = 'pf-m-expanded';
1541
+ buttonElement.className = `pf-v5-c-accordion__toggle ${!expanded ? expandedModifier : ''}`;
1542
+ contentElement.hidden = expanded;
1543
+ contentElement.className = `pf-v5-c-accordion__expanded-content ${!expanded ? expandedModifier : ''}`;
1544
+ setExpanded(!expanded);
1545
+ };
1546
+ useEventListener(buttonElement, 'click', handleClick);
1547
+ return React.createElement(React.Fragment, null);
1548
+ };
1549
+ const AccordionRenderExtension = ({ docContext }) => {
1550
+ const buttonElements = docContext.querySelectorAll(`[id ^= ${ACCORDION_MARKDOWN_BUTTON_ID}]`);
1551
+ const contentElements = docContext.querySelectorAll(`[id ^= ${ACCORDION_MARKDOWN_CONTENT_ID}]`);
1552
+ return buttonElements.length > 0 ? (React.createElement(React.Fragment, null, Array.from(buttonElements).map((elm) => {
1553
+ const content = Array.from(contentElements).find((elm2) => {
1554
+ const elmId = elm.id.split(ACCORDION_MARKDOWN_BUTTON_ID)[1];
1555
+ const elm2Id = elm2.id.split(ACCORDION_MARKDOWN_CONTENT_ID)[1];
1556
+ return elmId === elm2Id;
1557
+ });
1558
+ return (React.createElement(AccordionShowdownHandler, { key: elm.id.split(ACCORDION_MARKDOWN_BUTTON_ID)[1], buttonElement: elm, contentElement: content }));
1559
+ }))) : null;
1560
+ };
1561
+
1562
+ const FallbackImg = ({ src, alt, className, fallback }) => {
1563
+ const [isSrcValid, setIsSrcValid] = React.useState(true);
1564
+ if (src && isSrcValid) {
1565
+ return React.createElement("img", { className: className, src: src, alt: alt, onError: () => setIsSrcValid(false) });
1566
+ }
1567
+ return React.createElement(React.Fragment, null, fallback);
1563
1568
  };
1564
1569
 
1565
1570
  const DASH = '-';
1566
1571
 
1567
- const PopoverStatus = ({ hideHeader, children, isVisible = null, statusBody, title, onHide, onShow, }) => (React.createElement(Popover, { position: PopoverPosition.right, headerContent: hideHeader ? null : title, bodyContent: children, "aria-label": title, onHide: onHide, onShow: onShow, isVisible: isVisible },
1572
+ const PopoverStatus = ({ hideHeader, children, isVisible = null, statusBody, title, onHide, onShow, }) => (React.createElement(Popover, { position: PopoverPosition.right, headerContent: hideHeader ? null : title, bodyContent: children, "aria-label": title, onHide: onHide, onShow: onShow, isVisible: isVisible },
1568
1573
  React.createElement(Button, { variant: "link", isInline: true }, statusBody)));
1569
1574
 
1570
- const StatusIconAndText = ({ icon, title, spin, iconOnly, noTooltip, className, }) => {
1571
- if (!title) {
1572
- return React.createElement(React.Fragment, null, DASH);
1573
- }
1574
- return (React.createElement("span", { className: css('pfext-icon-and-text', className), title: iconOnly && !noTooltip ? title : undefined },
1575
- icon &&
1576
- React.cloneElement(icon, {
1577
- className: css(spin && 'fa-spin', icon.props.className, !iconOnly && 'pfext-icon-and-text__icon pfext-icon-flex-child'),
1578
- }),
1579
- !iconOnly && React.createElement(CamelCaseWrap, { value: title, dataTest: "status-text" })));
1575
+ const StatusIconAndText = ({ icon, title, spin, iconOnly, noTooltip, className, }) => {
1576
+ if (!title) {
1577
+ return React.createElement(React.Fragment, null, DASH);
1578
+ }
1579
+ return (React.createElement("span", { className: css('pfext-icon-and-text', className), title: iconOnly && !noTooltip ? title : undefined },
1580
+ icon &&
1581
+ React.cloneElement(icon, {
1582
+ className: css(spin && 'fa-spin', icon.props.className, !iconOnly && 'pfext-icon-and-text__icon pfext-icon-flex-child'),
1583
+ }),
1584
+ !iconOnly && React.createElement(CamelCaseWrap, { value: title, dataTest: "status-text" })));
1580
1585
  };
1581
1586
 
1582
- const GenericStatus = (props) => {
1583
- const { Icon, children, popoverTitle, title, noTooltip, iconOnly } = props, restProps = __rest(props, ["Icon", "children", "popoverTitle", "title", "noTooltip", "iconOnly"]);
1584
- const renderIcon = iconOnly && !noTooltip ? React.createElement(Icon, { title: title }) : React.createElement(Icon, null);
1585
- const statusBody = (React.createElement(StatusIconAndText, Object.assign({}, restProps, { noTooltip: noTooltip, title: title, iconOnly: iconOnly, icon: renderIcon })));
1586
- return React.Children.toArray(children).length ? (React.createElement(PopoverStatus, Object.assign({ title: popoverTitle || title }, restProps, { statusBody: statusBody }), children)) : (statusBody);
1587
+ const GenericStatus = (props) => {
1588
+ const { Icon, children, popoverTitle, title, noTooltip, iconOnly } = props, restProps = __rest(props, ["Icon", "children", "popoverTitle", "title", "noTooltip", "iconOnly"]);
1589
+ const renderIcon = iconOnly && !noTooltip ? React.createElement(Icon, { title: title }) : React.createElement(Icon, null);
1590
+ const statusBody = (React.createElement(StatusIconAndText, Object.assign({}, restProps, { noTooltip: noTooltip, title: title, iconOnly: iconOnly, icon: renderIcon })));
1591
+ return React.Children.toArray(children).length ? (React.createElement(PopoverStatus, Object.assign({ title: popoverTitle || title }, restProps, { statusBody: statusBody }), children)) : (statusBody);
1587
1592
  };
1588
1593
 
1589
- const GreenCheckCircleIcon = ({ className, title, size }) => (React.createElement(Icon, { size: size },
1594
+ const GreenCheckCircleIcon = ({ className, title, size }) => (React.createElement(Icon, { size: size },
1590
1595
  React.createElement(CheckCircleIcon, { "data-test": "success-icon", color: okColor.value, className: className, title: title })));
1591
1596
 
1592
- const SuccessStatus = (props) => (React.createElement(GenericStatus, Object.assign({}, props, { Icon: GreenCheckCircleIcon, title: props.title || 'Healthy' })));
1597
+ const SuccessStatus = (props) => (React.createElement(GenericStatus, Object.assign({}, props, { Icon: GreenCheckCircleIcon, title: props.title || 'Healthy' })));
1593
1598
  SuccessStatus.displayName = 'SuccessStatus';
1594
1599
 
1595
- const Status = ({ status, title, iconOnly, noTooltip, className, }) => {
1596
- const statusProps = { title: title || status, iconOnly, noTooltip, className };
1597
- switch (status) {
1598
- case 'In Progress':
1599
- return React.createElement(StatusIconAndText, Object.assign({}, statusProps, { icon: React.createElement(SyncAltIcon, null) }));
1600
- case 'Complete':
1601
- return React.createElement(SuccessStatus, Object.assign({}, statusProps));
1602
- default:
1603
- return React.createElement(React.Fragment, null, status || DASH);
1604
- }
1605
- };
1600
+ const Status = ({ status, title, iconOnly, noTooltip, className, }) => {
1601
+ const statusProps = { title: title || status, iconOnly, noTooltip, className };
1602
+ switch (status) {
1603
+ case 'In Progress':
1604
+ return React.createElement(StatusIconAndText, Object.assign({}, statusProps, { icon: React.createElement(SyncAltIcon, null) }));
1605
+ case 'Complete':
1606
+ return React.createElement(SuccessStatus, Object.assign({}, statusProps));
1607
+ default:
1608
+ return React.createElement(React.Fragment, null, status || DASH);
1609
+ }
1610
+ };
1606
1611
  const StatusIcon = ({ status }) => (React.createElement(Status, { status: status, iconOnly: true }));
1607
1612
 
1608
- const QuickStartTileDescription = ({ description, prerequisites, }) => {
1609
- const { getResource } = React.useContext(QuickStartContext);
1610
- const prereqs = prerequisites === null || prerequisites === void 0 ? void 0 : prerequisites.filter((p) => p);
1611
- return (React.createElement(React.Fragment, null,
1612
- React.createElement(QuickStartMarkdownView, { content: description, className: "pfext-quick-start-tile-description" }),
1613
- (prereqs === null || prereqs === void 0 ? void 0 : prereqs.length) > 0 && (React.createElement("div", { className: "pfext-quick-start-tile-prerequisites" },
1614
- React.createElement(Text, { component: TextVariants.h5, className: "pfext-quick-start-tile-prerequisites__text" },
1615
- getResource('Prerequisites ({{totalPrereqs}})').replace('{{totalPrereqs}}', prereqs.length),
1616
- ' '),
1617
- React.createElement(Popover, { "aria-label": getResource('Prerequisites'), headerContent: getResource('Prerequisites'), className: "pfext-quick-start__base", bodyContent: React.createElement("div", { className: "pfext-popover__base" },
1618
- React.createElement(TextList, { "aria-label": getResource('Prerequisites'), className: "pfext-quick-start-tile-prerequisites-list" }, prereqs.map((prerequisite, index) => (
1619
- // eslint-disable-next-line react/no-array-index-key
1620
- React.createElement(TextListItem, { key: index },
1621
- React.createElement(QuickStartMarkdownView, { content: prerequisite })))))) },
1622
- React.createElement(Button, { variant: "link", isInline: true, className: "pfext-quick-start-tile-prerequisites__icon", "data-testid": "qs-card-prereqs", onClick: (e) => {
1623
- e.preventDefault();
1624
- e.stopPropagation();
1625
- }, "aria-label": getResource('Show prerequisites') },
1626
- React.createElement(InfoCircleIcon, null)))))));
1627
- };
1628
-
1629
- const QuickStartTileFooter = ({ quickStartId, status, totalTasks, }) => {
1630
- const { getResource } = React.useContext(QuickStartContext);
1631
- const { activeQuickStartID, startQuickStart, restartQuickStart } = React.useContext(QuickStartContext);
1632
- const start = React.useCallback((e) => {
1633
- e.preventDefault();
1634
- e.stopPropagation();
1635
- startQuickStart(quickStartId, totalTasks);
1636
- }, [quickStartId, startQuickStart, totalTasks]);
1637
- const restart = React.useCallback((e) => {
1638
- e.preventDefault();
1639
- e.stopPropagation();
1640
- restartQuickStart(quickStartId, totalTasks);
1641
- }, [quickStartId, restartQuickStart, totalTasks]);
1642
- return (React.createElement(Flex, { justifyContent: { default: 'justifyContentSpaceBetween' } },
1643
- status === QuickStartStatus.NOT_STARTED && (React.createElement(FlexItem, null,
1644
- React.createElement(Button, { onClick: start, variant: "link", isInline: true, "data-testid": "qs-card-notStarted-start", id: `${quickStartId}-start`, "aria-labelledby": `${quickStartId}-start ${quickStartId}` }, getResource('Start')))),
1645
- status === QuickStartStatus.IN_PROGRESS && activeQuickStartID !== quickStartId && (React.createElement(FlexItem, null,
1646
- React.createElement(Button, { variant: "link", isInline: true, "data-testid": "qs-card-inProgress-resume", id: `${quickStartId}-continue`, "aria-labelledby": `${quickStartId}-continue ${quickStartId}` }, getResource('Continue')))),
1647
- status === QuickStartStatus.COMPLETE && (React.createElement(FlexItem, null,
1648
- React.createElement(Button, { onClick: restart, variant: "link", isInline: true, "data-testid": "qs-card-complete-restart", id: `${quickStartId}-restart`, "aria-labelledby": `${quickStartId}-restart ${quickStartId}` }, getResource('Restart')))),
1649
- status === QuickStartStatus.IN_PROGRESS && (React.createElement(FlexItem, null,
1650
- React.createElement(Button, { onClick: restart, variant: "link", isInline: true, "data-testid": "qs-card-inProgress-restart", id: `${quickStartId}-restart`, "aria-labelledby": `${quickStartId}-restart ${quickStartId}` }, getResource('Restart'))))));
1651
- };
1652
-
1653
- const QuickStartTileFooterExternal = ({ link, quickStartId, }) => {
1654
- const { href, text } = link;
1655
- return (React.createElement(Flex, { justifyContent: { default: 'justifyContentSpaceBetween' } },
1656
- React.createElement(FlexItem, null,
1657
- React.createElement(Button, { component: "a", href: href, target: "_blank", rel: "noopener noreferrer", variant: "link", "aria-label": `Open documentation in new window`, isInline: true, icon: React.createElement(ExternalLinkAltIcon, null), iconPosition: "right", id: quickStartId, "aria-labelledby": `${quickStartId}-external ${quickStartId}` }, text || href))));
1658
- };
1659
-
1660
- const statusColorMap = {
1661
- [QuickStartStatus.COMPLETE]: 'green',
1662
- [QuickStartStatus.IN_PROGRESS]: 'purple',
1663
- [QuickStartStatus.NOT_STARTED]: 'grey',
1664
- };
1665
- const QuickStartTileHeader = ({ status, duration, name, type, quickStartId, }) => {
1666
- const { getResource } = React.useContext(QuickStartContext);
1667
- const statusLocaleMap = {
1668
- [QuickStartStatus.COMPLETE]: getResource('Complete'),
1669
- [QuickStartStatus.IN_PROGRESS]: getResource('In progress'),
1670
- [QuickStartStatus.NOT_STARTED]: getResource('Not started'),
1671
- };
1672
- return (React.createElement("div", { className: "pfext-quick-start-tile-header" },
1673
- React.createElement(Title, { headingLevel: "h3", "data-test": "title", id: quickStartId },
1674
- React.createElement(QuickStartMarkdownView, { content: name })),
1675
- React.createElement("div", { className: "pfext-quick-start-tile-header__status" },
1676
- type && (React.createElement(Label, { className: "pfext-quick-start-tile-header--margin", color: type.color }, type.text)),
1677
- duration && (React.createElement(Label, { variant: "outline", "data-test": "duration", icon: React.createElement(OutlinedClockIcon, null), className: "pfext-quick-start-tile-header--margin" }, getResource('{{duration, number}} minutes', duration).replace('{{duration, number}}', duration))),
1678
- status !== QuickStartStatus.NOT_STARTED && (React.createElement(Label, { variant: "outline", color: statusColorMap[status], icon: React.createElement(StatusIcon, { status: status }), "data-test": "status" }, statusLocaleMap[status])))));
1679
- };
1680
-
1681
- const QuickStartTile = ({ quickStart, status, isActive, onClick = () => { }, }) => {
1682
- const { metadata: { name: id }, spec: { icon, tasks, displayName, description, durationMinutes, prerequisites, link, type }, } = quickStart;
1683
- const { setActiveQuickStart, footer } = React.useContext(QuickStartContext);
1684
- const ref = React.useRef(null);
1685
- let quickStartIcon;
1686
- if (typeof icon === 'object') {
1687
- quickStartIcon = icon;
1688
- }
1689
- else {
1690
- quickStartIcon = (React.createElement(FallbackImg, { className: "pfext-catalog-item-icon__img--large", src: icon, alt: "", fallback: React.createElement(RocketIcon, null) }));
1691
- }
1692
- const footerComponent = React.useMemo(() => {
1693
- if (footer && footer.show === false) {
1694
- return null;
1695
- }
1696
- if (link) {
1697
- return React.createElement(QuickStartTileFooterExternal, { link: link, quickStartId: id });
1698
- }
1699
- return React.createElement(QuickStartTileFooter, { quickStartId: id, status: status, totalTasks: tasks === null || tasks === void 0 ? void 0 : tasks.length });
1700
- }, [footer, id, link, status, tasks === null || tasks === void 0 ? void 0 : tasks.length]);
1701
- const handleClick = (e) => {
1702
- var _a;
1703
- if ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.contains(e.target)) {
1704
- if (link) {
1705
- window.open(link.href);
1706
- }
1707
- else {
1708
- setActiveQuickStart(id, tasks === null || tasks === void 0 ? void 0 : tasks.length);
1709
- }
1710
- onClick();
1711
- }
1712
- };
1713
- return (React.createElement("div", { ref: ref },
1714
- React.createElement(CatalogTile, { id: id + '-catalog-tile', style: {
1715
- cursor: 'pointer',
1716
- }, icon: quickStartIcon, className: "pfext-quick-start-tile", "data-testid": `qs-card-${camelize(displayName)}`, featured: isActive, title: React.createElement(QuickStartTileHeader, { name: displayName, status: status, duration: durationMinutes, type: type, quickStartId: id }), onClick: handleClick, onKeyDown: (event) => {
1717
- if (event.key === 'Enter' || event.key === ' ') {
1718
- setActiveQuickStart(id, tasks === null || tasks === void 0 ? void 0 : tasks.length);
1719
- onClick();
1720
- }
1721
- },
1722
- // https://github.com/patternfly/patternfly-react/issues/7039
1723
- href: link === null || link === void 0 ? void 0 : link.href, "data-test": `tile ${id}`, description: React.createElement(QuickStartTileDescription, { description: description, prerequisites: prerequisites }), footer: footerComponent, tabIndex: 0 })));
1724
- };
1725
-
1726
- const QuickStartCatalog = ({ quickStarts }) => {
1727
- const { activeQuickStartID, allQuickStartStates } = React.useContext(QuickStartContext);
1728
- return (React.createElement("div", { className: "pfext-page-layout__content" },
1729
- React.createElement(Gallery, { className: "pfext-quick-start-catalog__gallery", hasGutter: true }, quickStarts.map((quickStart) => {
1730
- const { metadata: { name: id }, } = quickStart;
1731
- return (React.createElement(GalleryItem, { key: id, className: "pfext-quick-start-catalog__gallery-item" },
1732
- React.createElement(QuickStartTile, { quickStart: quickStart, isActive: id === activeQuickStartID, status: getQuickStartStatus(allQuickStartStates, id) })));
1733
- }))));
1734
- };
1735
-
1736
- const QuickStartCatalogFilterSearch = (_a) => {
1737
- var { searchInputText, handleTextChange } = _a, props = __rest(_a, ["searchInputText", "handleTextChange"]);
1738
- const { getResource } = React.useContext(QuickStartContext);
1739
- return (React.createElement(ToolbarItem, { className: "pfext-quick-start-catalog-filter__input" },
1740
- React.createElement(SearchInput, Object.assign({ placeholder: getResource('Filter by keyword...'), value: searchInputText, onChange: (_ev, value) => handleTextChange(value), onClear: () => handleTextChange('') }, props))));
1741
- };
1742
- const QuickStartCatalogFilterSelect = (_a) => {
1743
- var { isDropdownOpen, setIsDropdownOpen, onRowfilterSelect, selectedFilters, dropdownItems } = _a, props = __rest(_a, ["isDropdownOpen", "setIsDropdownOpen", "onRowfilterSelect", "selectedFilters", "dropdownItems"]);
1744
- const { getResource } = React.useContext(QuickStartContext);
1745
- const toggle = (toggleRef) => (React.createElement(MenuToggle, { isFullWidth: true, ref: toggleRef, onClick: () => setIsDropdownOpen(!isDropdownOpen), isExpanded: isDropdownOpen },
1746
- getResource('Status'),
1747
- selectedFilters.length > 0 && React.createElement(Badge, { isRead: true }, selectedFilters.length)));
1748
- return (React.createElement(ToolbarItem, null,
1749
- React.createElement(Select, Object.assign({ "aria-label": getResource('Select filter'), isOpen: isDropdownOpen, selected: selectedFilters, onSelect: onRowfilterSelect, onOpenChange: (isOpen) => setIsDropdownOpen(isOpen), toggle: toggle }, props),
1750
- React.createElement(SelectList, null, dropdownItems))));
1751
- };
1752
- const QuickStartCatalogFilterCount = ({ quickStartsCount }) => {
1753
- const { getResource } = React.useContext(QuickStartContext);
1754
- return (React.createElement(ToolbarItem, { className: "pfext-quick-start-catalog-filter__count", align: { default: 'alignRight' } }, getResource('{{count, number}} item', quickStartsCount).replace('{{count, number}}', quickStartsCount)));
1755
- };
1756
- const QuickStartCatalogFilterSearchWrapper = ({ onSearchInputChange = () => { } }) => {
1757
- const { useQueryParams, filter, setFilter } = React.useContext(QuickStartContext);
1758
- React.useEffect(() => {
1759
- // use this effect to clear the search when a `clear all` action is performed higher up
1760
- const unlisten = history.listen(({ location }) => {
1761
- const searchParams = new URLSearchParams(location.search);
1762
- const searchQuery = searchParams.get(QUICKSTART_SEARCH_FILTER_KEY) || '';
1763
- if (searchQuery === '') {
1764
- setFilter('keyword', '');
1765
- onSearchInputChange('');
1766
- }
1767
- });
1768
- return () => {
1769
- unlisten();
1770
- };
1771
- }, [onSearchInputChange, setFilter]);
1772
- const handleTextChange = (val) => {
1773
- if (val.length > 0) {
1774
- useQueryParams && setQueryArgument(QUICKSTART_SEARCH_FILTER_KEY, val);
1775
- }
1776
- else {
1777
- useQueryParams && removeQueryArgument(QUICKSTART_SEARCH_FILTER_KEY);
1778
- }
1779
- if ((filter === null || filter === void 0 ? void 0 : filter.keyword) !== val) {
1780
- setFilter('keyword', val);
1781
- }
1782
- onSearchInputChange(val);
1783
- };
1784
- return (React.createElement(QuickStartCatalogFilterSearch, { searchInputText: filter === null || filter === void 0 ? void 0 : filter.keyword, handleTextChange: handleTextChange }));
1785
- };
1786
- // compare string/number arrays
1787
- const equalsIgnoreOrder = (a, b) => {
1788
- if (a.length !== b.length) {
1789
- return false;
1790
- }
1791
- const uniqueValues = new Set([...a, ...b]);
1792
- for (const v of uniqueValues) {
1793
- const aCount = a.filter((e) => e === v).length;
1794
- const bCount = b.filter((e) => e === v).length;
1795
- if (aCount !== bCount) {
1796
- return false;
1797
- }
1798
- }
1799
- return true;
1800
- };
1801
- const QuickStartCatalogFilterStatusWrapper = ({ onStatusChange = () => { } }) => {
1802
- const { useQueryParams, filter, setFilter } = React.useContext(QuickStartContext);
1803
- React.useEffect(() => {
1804
- // use this effect to clear the status when a `clear all` action is performed higher up
1805
- const unlisten = history.listen(({ location }) => {
1806
- var _a;
1807
- const searchParams = new URLSearchParams(location.search);
1808
- const updatedStatusFilters = ((_a = searchParams.get(QUICKSTART_STATUS_FILTER_KEY)) === null || _a === void 0 ? void 0 : _a.split(',')) || [];
1809
- if (updatedStatusFilters.length === 0) {
1810
- setFilter('status', []);
1811
- onStatusChange([]);
1812
- }
1813
- });
1814
- return () => {
1815
- unlisten();
1816
- };
1817
- });
1818
- const [isDropdownOpen, setIsDropdownOpen] = React.useState(false);
1819
- const onRowfilterSelect = React.useCallback((_e, selectedValue) => {
1820
- setIsDropdownOpen(false);
1821
- const selection = Object.entries(filter.status.statusTypes).find(([_key, value]) => value === selectedValue)[0];
1822
- const selectedFiltersList = filter.status.statusFilters.includes(selection)
1823
- ? filter.status.statusFilters.filter((status) => status !== selection)
1824
- : [...filter.status.statusFilters, selection];
1825
- if (!equalsIgnoreOrder(filter.status.statusFilters, selectedFiltersList)) {
1826
- setFilter('status', selectedFiltersList);
1827
- }
1828
- if (selectedFiltersList.length > 0) {
1829
- useQueryParams && setQueryArgument('status', selectedFiltersList.join(','));
1830
- }
1831
- else {
1832
- useQueryParams && removeQueryArgument(QUICKSTART_STATUS_FILTER_KEY);
1833
- }
1834
- onStatusChange(selectedFiltersList);
1835
- }, [filter.status.statusFilters, onStatusChange, setFilter, useQueryParams]);
1836
- const dropdownItems = Object.entries(filter.status.statusTypes).map(([key, value]) => (React.createElement(SelectOption, { key: key, "data-key": key, value: value, hasCheckbox: true, isSelected: filter.status.statusFilters.includes(key) },
1837
- React.createElement(React.Fragment, null, value))));
1838
- return (React.createElement(QuickStartCatalogFilterSelect, { isDropdownOpen: isDropdownOpen, setIsDropdownOpen: setIsDropdownOpen, onRowfilterSelect: onRowfilterSelect, selectedFilters: filter.status.statusFilters, dropdownItems: dropdownItems }));
1839
- };
1613
+ const QuickStartTileDescription = ({ description, prerequisites, }) => {
1614
+ const { getResource } = React.useContext(QuickStartContext);
1615
+ const prereqs = prerequisites === null || prerequisites === void 0 ? void 0 : prerequisites.filter((p) => p);
1616
+ return (React.createElement(React.Fragment, null,
1617
+ React.createElement(QuickStartMarkdownView, { content: description, className: "pfext-quick-start-tile-description" }),
1618
+ (prereqs === null || prereqs === void 0 ? void 0 : prereqs.length) > 0 && (React.createElement("div", { className: "pfext-quick-start-tile-prerequisites" },
1619
+ React.createElement(Text, { component: TextVariants.h5, className: "pfext-quick-start-tile-prerequisites__text" },
1620
+ getResource('Prerequisites ({{totalPrereqs}})').replace('{{totalPrereqs}}', prereqs.length),
1621
+ ' '),
1622
+ React.createElement(Popover, { "aria-label": getResource('Prerequisites'), headerContent: getResource('Prerequisites'), className: "pfext-quick-start__base", bodyContent: React.createElement("div", { className: "pfext-popover__base" },
1623
+ React.createElement(TextList, { "aria-label": getResource('Prerequisites'), className: "pfext-quick-start-tile-prerequisites-list" }, prereqs.map((prerequisite, index) => (
1624
+ // eslint-disable-next-line react/no-array-index-key
1625
+ React.createElement(TextListItem, { key: index },
1626
+ React.createElement(QuickStartMarkdownView, { content: prerequisite })))))) },
1627
+ React.createElement(Button, { variant: "link", isInline: true, className: "pfext-quick-start-tile-prerequisites__icon", "data-testid": "qs-card-prereqs", onClick: (e) => {
1628
+ e.preventDefault();
1629
+ e.stopPropagation();
1630
+ }, "aria-label": getResource('Show prerequisites') },
1631
+ React.createElement(InfoCircleIcon, null)))))));
1632
+ };
1633
+
1634
+ const QuickStartTileFooter = ({ quickStartId, status, totalTasks, }) => {
1635
+ const { getResource } = React.useContext(QuickStartContext);
1636
+ const { activeQuickStartID, startQuickStart, restartQuickStart } = React.useContext(QuickStartContext);
1637
+ const start = React.useCallback((e) => {
1638
+ e.preventDefault();
1639
+ e.stopPropagation();
1640
+ startQuickStart(quickStartId, totalTasks);
1641
+ }, [quickStartId, startQuickStart, totalTasks]);
1642
+ const restart = React.useCallback((e) => {
1643
+ e.preventDefault();
1644
+ e.stopPropagation();
1645
+ restartQuickStart(quickStartId, totalTasks);
1646
+ }, [quickStartId, restartQuickStart, totalTasks]);
1647
+ return (React.createElement(Flex, { justifyContent: { default: 'justifyContentSpaceBetween' } },
1648
+ status === QuickStartStatus.NOT_STARTED && (React.createElement(FlexItem, null,
1649
+ React.createElement(Button, { onClick: start, variant: "link", isInline: true, "data-testid": "qs-card-notStarted-start", id: `${quickStartId}-start`, "aria-labelledby": `${quickStartId}-start ${quickStartId}` }, getResource('Start')))),
1650
+ status === QuickStartStatus.IN_PROGRESS && activeQuickStartID !== quickStartId && (React.createElement(FlexItem, null,
1651
+ React.createElement(Button, { variant: "link", isInline: true, "data-testid": "qs-card-inProgress-resume", id: `${quickStartId}-continue`, "aria-labelledby": `${quickStartId}-continue ${quickStartId}` }, getResource('Continue')))),
1652
+ status === QuickStartStatus.COMPLETE && (React.createElement(FlexItem, null,
1653
+ React.createElement(Button, { onClick: restart, variant: "link", isInline: true, "data-testid": "qs-card-complete-restart", id: `${quickStartId}-restart`, "aria-labelledby": `${quickStartId}-restart ${quickStartId}` }, getResource('Restart')))),
1654
+ status === QuickStartStatus.IN_PROGRESS && (React.createElement(FlexItem, null,
1655
+ React.createElement(Button, { onClick: restart, variant: "link", isInline: true, "data-testid": "qs-card-inProgress-restart", id: `${quickStartId}-restart`, "aria-labelledby": `${quickStartId}-restart ${quickStartId}` }, getResource('Restart'))))));
1656
+ };
1657
+
1658
+ const QuickStartTileFooterExternal = ({ link, quickStartId, }) => {
1659
+ const { href, text } = link;
1660
+ return (React.createElement(Flex, { justifyContent: { default: 'justifyContentSpaceBetween' } },
1661
+ React.createElement(FlexItem, null,
1662
+ React.createElement(Button, { component: "a", href: href, target: "_blank", rel: "noopener noreferrer", variant: "link", "aria-label": `Open documentation in new window`, isInline: true, icon: React.createElement(ExternalLinkAltIcon, null), iconPosition: "right", id: quickStartId, "aria-labelledby": `${quickStartId}-external ${quickStartId}` }, text || href))));
1663
+ };
1664
+
1665
+ const statusColorMap = {
1666
+ [QuickStartStatus.COMPLETE]: 'green',
1667
+ [QuickStartStatus.IN_PROGRESS]: 'purple',
1668
+ [QuickStartStatus.NOT_STARTED]: 'grey',
1669
+ };
1670
+ const QuickStartTileHeader = ({ status, duration, name, type, quickStartId, }) => {
1671
+ const { getResource } = React.useContext(QuickStartContext);
1672
+ const statusLocaleMap = {
1673
+ [QuickStartStatus.COMPLETE]: getResource('Complete'),
1674
+ [QuickStartStatus.IN_PROGRESS]: getResource('In progress'),
1675
+ [QuickStartStatus.NOT_STARTED]: getResource('Not started'),
1676
+ };
1677
+ return (React.createElement("div", { className: "pfext-quick-start-tile-header" },
1678
+ React.createElement(Title, { headingLevel: "h3", "data-test": "title", id: quickStartId },
1679
+ React.createElement(QuickStartMarkdownView, { content: name })),
1680
+ React.createElement("div", { className: "pfext-quick-start-tile-header__status" },
1681
+ type && (React.createElement(Label, { className: "pfext-quick-start-tile-header--margin", color: type.color }, type.text)),
1682
+ duration && (React.createElement(Label, { variant: "outline", "data-test": "duration", icon: React.createElement(OutlinedClockIcon, null), className: "pfext-quick-start-tile-header--margin" }, getResource('{{duration, number}} minutes', duration).replace('{{duration, number}}', duration))),
1683
+ status !== QuickStartStatus.NOT_STARTED && (React.createElement(Label, { variant: "outline", color: statusColorMap[status], icon: React.createElement(StatusIcon, { status: status }), "data-test": "status" }, statusLocaleMap[status])))));
1684
+ };
1685
+
1686
+ const QuickStartTile = ({ quickStart, status, isActive, onClick = () => { }, }) => {
1687
+ const { metadata: { name: id }, spec: { icon, tasks, displayName, description, durationMinutes, prerequisites, link, type }, } = quickStart;
1688
+ const { setActiveQuickStart, footer } = React.useContext(QuickStartContext);
1689
+ const ref = React.useRef(null);
1690
+ let quickStartIcon;
1691
+ if (typeof icon === 'object') {
1692
+ quickStartIcon = icon;
1693
+ }
1694
+ else {
1695
+ quickStartIcon = (React.createElement(FallbackImg, { className: "pfext-catalog-item-icon__img--large", src: icon, alt: "", fallback: React.createElement(RocketIcon, null) }));
1696
+ }
1697
+ const footerComponent = React.useMemo(() => {
1698
+ if (footer && footer.show === false) {
1699
+ return null;
1700
+ }
1701
+ if (link) {
1702
+ return React.createElement(QuickStartTileFooterExternal, { link: link, quickStartId: id });
1703
+ }
1704
+ return React.createElement(QuickStartTileFooter, { quickStartId: id, status: status, totalTasks: tasks === null || tasks === void 0 ? void 0 : tasks.length });
1705
+ }, [footer, id, link, status, tasks === null || tasks === void 0 ? void 0 : tasks.length]);
1706
+ const handleClick = (e) => {
1707
+ var _a;
1708
+ if ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.contains(e.target)) {
1709
+ if (link) {
1710
+ window.open(link.href);
1711
+ }
1712
+ else {
1713
+ setActiveQuickStart(id, tasks === null || tasks === void 0 ? void 0 : tasks.length);
1714
+ }
1715
+ onClick();
1716
+ }
1717
+ };
1718
+ return (React.createElement("div", { ref: ref },
1719
+ React.createElement(CatalogTile, { id: id + '-catalog-tile', style: {
1720
+ cursor: 'pointer',
1721
+ }, icon: quickStartIcon, className: "pfext-quick-start-tile", "data-testid": `qs-card-${camelize(displayName)}`, featured: isActive, title: React.createElement(QuickStartTileHeader, { name: displayName, status: status, duration: durationMinutes, type: type, quickStartId: id }), onClick: handleClick, onKeyDown: (event) => {
1722
+ if (event.key === 'Enter' || event.key === ' ') {
1723
+ setActiveQuickStart(id, tasks === null || tasks === void 0 ? void 0 : tasks.length);
1724
+ onClick();
1725
+ }
1726
+ },
1727
+ // https://github.com/patternfly/patternfly-react/issues/7039
1728
+ href: link === null || link === void 0 ? void 0 : link.href, "data-test": `tile ${id}`, description: React.createElement(QuickStartTileDescription, { description: description, prerequisites: prerequisites }), footer: footerComponent, tabIndex: 0 })));
1729
+ };
1730
+
1731
+ const QuickStartCatalog = ({ quickStarts }) => {
1732
+ const { activeQuickStartID, allQuickStartStates } = React.useContext(QuickStartContext);
1733
+ return (React.createElement("div", { className: "pfext-page-layout__content" },
1734
+ React.createElement(Gallery, { className: "pfext-quick-start-catalog__gallery", hasGutter: true }, quickStarts.map((quickStart) => {
1735
+ const { metadata: { name: id }, } = quickStart;
1736
+ return (React.createElement(GalleryItem, { key: id, className: "pfext-quick-start-catalog__gallery-item" },
1737
+ React.createElement(QuickStartTile, { quickStart: quickStart, isActive: id === activeQuickStartID, status: getQuickStartStatus(allQuickStartStates, id) })));
1738
+ }))));
1739
+ };
1740
+
1741
+ const QuickStartCatalogFilterSearch = (_a) => {
1742
+ var { searchInputText, handleTextChange } = _a, props = __rest(_a, ["searchInputText", "handleTextChange"]);
1743
+ const { getResource } = React.useContext(QuickStartContext);
1744
+ return (React.createElement(ToolbarItem, { className: "pfext-quick-start-catalog-filter__input" },
1745
+ React.createElement(SearchInput, Object.assign({ placeholder: getResource('Filter by keyword...'), value: searchInputText, onChange: (_ev, value) => handleTextChange(value), onClear: () => handleTextChange('') }, props))));
1746
+ };
1747
+ const QuickStartCatalogFilterSelect = (_a) => {
1748
+ var { isDropdownOpen, setIsDropdownOpen, onRowfilterSelect, selectedFilters, dropdownItems } = _a, props = __rest(_a, ["isDropdownOpen", "setIsDropdownOpen", "onRowfilterSelect", "selectedFilters", "dropdownItems"]);
1749
+ const { getResource } = React.useContext(QuickStartContext);
1750
+ const toggle = (toggleRef) => (React.createElement(MenuToggle, { isFullWidth: true, ref: toggleRef, onClick: () => setIsDropdownOpen(!isDropdownOpen), isExpanded: isDropdownOpen },
1751
+ getResource('Status'),
1752
+ selectedFilters.length > 0 && React.createElement(Badge, { isRead: true }, selectedFilters.length)));
1753
+ return (React.createElement(ToolbarItem, null,
1754
+ React.createElement(Select, Object.assign({ "aria-label": getResource('Select filter'), isOpen: isDropdownOpen, selected: selectedFilters, onSelect: onRowfilterSelect, onOpenChange: (isOpen) => setIsDropdownOpen(isOpen), toggle: toggle }, props),
1755
+ React.createElement(SelectList, null, dropdownItems))));
1756
+ };
1757
+ const QuickStartCatalogFilterCount = ({ quickStartsCount }) => {
1758
+ const { getResource } = React.useContext(QuickStartContext);
1759
+ return (React.createElement(ToolbarItem, { className: "pfext-quick-start-catalog-filter__count", align: { default: 'alignRight' } }, getResource('{{count, number}} item', quickStartsCount).replace('{{count, number}}', quickStartsCount)));
1760
+ };
1761
+ const QuickStartCatalogFilterSearchWrapper = ({ onSearchInputChange = () => { } }) => {
1762
+ const { useQueryParams, filter, setFilter } = React.useContext(QuickStartContext);
1763
+ React.useEffect(() => {
1764
+ // use this effect to clear the search when a `clear all` action is performed higher up
1765
+ const unlisten = history.listen(({ location }) => {
1766
+ const searchParams = new URLSearchParams(location.search);
1767
+ const searchQuery = searchParams.get(QUICKSTART_SEARCH_FILTER_KEY) || '';
1768
+ if (searchQuery === '') {
1769
+ setFilter('keyword', '');
1770
+ onSearchInputChange('');
1771
+ }
1772
+ });
1773
+ return () => {
1774
+ unlisten();
1775
+ };
1776
+ }, [onSearchInputChange, setFilter]);
1777
+ const handleTextChange = (val) => {
1778
+ if (val.length > 0) {
1779
+ useQueryParams && setQueryArgument(QUICKSTART_SEARCH_FILTER_KEY, val);
1780
+ }
1781
+ else {
1782
+ useQueryParams && removeQueryArgument(QUICKSTART_SEARCH_FILTER_KEY);
1783
+ }
1784
+ if ((filter === null || filter === void 0 ? void 0 : filter.keyword) !== val) {
1785
+ setFilter('keyword', val);
1786
+ }
1787
+ onSearchInputChange(val);
1788
+ };
1789
+ return (React.createElement(QuickStartCatalogFilterSearch, { searchInputText: filter === null || filter === void 0 ? void 0 : filter.keyword, handleTextChange: handleTextChange }));
1790
+ };
1791
+ // compare string/number arrays
1792
+ const equalsIgnoreOrder = (a, b) => {
1793
+ if (a.length !== b.length) {
1794
+ return false;
1795
+ }
1796
+ const uniqueValues = new Set([...a, ...b]);
1797
+ for (const v of uniqueValues) {
1798
+ const aCount = a.filter((e) => e === v).length;
1799
+ const bCount = b.filter((e) => e === v).length;
1800
+ if (aCount !== bCount) {
1801
+ return false;
1802
+ }
1803
+ }
1804
+ return true;
1805
+ };
1806
+ const QuickStartCatalogFilterStatusWrapper = ({ onStatusChange = () => { } }) => {
1807
+ const { useQueryParams, filter, setFilter } = React.useContext(QuickStartContext);
1808
+ React.useEffect(() => {
1809
+ // use this effect to clear the status when a `clear all` action is performed higher up
1810
+ const unlisten = history.listen(({ location }) => {
1811
+ var _a;
1812
+ const searchParams = new URLSearchParams(location.search);
1813
+ const updatedStatusFilters = ((_a = searchParams.get(QUICKSTART_STATUS_FILTER_KEY)) === null || _a === void 0 ? void 0 : _a.split(',')) || [];
1814
+ if (updatedStatusFilters.length === 0) {
1815
+ setFilter('status', []);
1816
+ onStatusChange([]);
1817
+ }
1818
+ });
1819
+ return () => {
1820
+ unlisten();
1821
+ };
1822
+ });
1823
+ const [isDropdownOpen, setIsDropdownOpen] = React.useState(false);
1824
+ const onRowfilterSelect = React.useCallback((_e, selectedValue) => {
1825
+ setIsDropdownOpen(false);
1826
+ const selection = Object.entries(filter.status.statusTypes).find(([_key, value]) => value === selectedValue)[0];
1827
+ const selectedFiltersList = filter.status.statusFilters.includes(selection)
1828
+ ? filter.status.statusFilters.filter((status) => status !== selection)
1829
+ : [...filter.status.statusFilters, selection];
1830
+ if (!equalsIgnoreOrder(filter.status.statusFilters, selectedFiltersList)) {
1831
+ setFilter('status', selectedFiltersList);
1832
+ }
1833
+ if (selectedFiltersList.length > 0) {
1834
+ useQueryParams && setQueryArgument('status', selectedFiltersList.join(','));
1835
+ }
1836
+ else {
1837
+ useQueryParams && removeQueryArgument(QUICKSTART_STATUS_FILTER_KEY);
1838
+ }
1839
+ onStatusChange(selectedFiltersList);
1840
+ }, [filter.status.statusFilters, onStatusChange, setFilter, useQueryParams]);
1841
+ const dropdownItems = Object.entries(filter.status.statusTypes).map(([key, value]) => (React.createElement(SelectOption, { key: key, "data-key": key, value: value, hasCheckbox: true, isSelected: filter.status.statusFilters.includes(key) },
1842
+ React.createElement(React.Fragment, null, value))));
1843
+ return (React.createElement(QuickStartCatalogFilterSelect, { isDropdownOpen: isDropdownOpen, setIsDropdownOpen: setIsDropdownOpen, onRowfilterSelect: onRowfilterSelect, selectedFilters: filter.status.statusFilters, dropdownItems: dropdownItems }));
1844
+ };
1840
1845
  const QuickStartCatalogFilterCountWrapper = ({ quickStartsCount }) => React.createElement(QuickStartCatalogFilterCount, { quickStartsCount: quickStartsCount });
1841
1846
 
1842
- const QuickStartCatalogFilter = (_a) => {
1843
- var { quickStartsCount, onSearchInputChange = () => { }, onStatusChange = () => { } } = _a, props = __rest(_a, ["quickStartsCount", "onSearchInputChange", "onStatusChange"]);
1844
- return (React.createElement(Toolbar, Object.assign({ usePageInsets: true, className: "pfext-quick-start-catalog-filter__flex" }, props),
1845
- React.createElement(ToolbarContent, null,
1846
- React.createElement(QuickStartCatalogFilterSearchWrapper, { onSearchInputChange: onSearchInputChange }),
1847
- React.createElement(QuickStartCatalogFilterStatusWrapper, { onStatusChange: onStatusChange }),
1848
- React.createElement(QuickStartCatalogFilterCountWrapper, { quickStartsCount: quickStartsCount }))));
1849
- };
1850
-
1851
- const QuickStartCatalogEmptyState = ({ clearFilters }) => {
1852
- const { getResource } = React.useContext(QuickStartContext);
1853
- return (React.createElement(EmptyState, null,
1854
- React.createElement(EmptyStateHeader, { titleText: React.createElement(React.Fragment, null, getResource('No results found')), icon: React.createElement(EmptyStateIcon, { icon: SearchIcon }), headingLevel: "h4" }),
1855
- React.createElement(EmptyStateBody, null, getResource('No results match the filter criteria. Remove filters or clear all filters to show results.')),
1856
- React.createElement(EmptyStateFooter, null,
1857
- React.createElement(EmptyStateActions, null,
1858
- React.createElement(Button, { variant: "link", onClick: clearFilters, "data-test": "clear-filter button" }, getResource('Clear all filters'))))));
1859
- };
1860
- const QuickStartCatalogPage = ({ quickStarts, showFilter, sortFnc = (q1, q2) => q1.spec.displayName.localeCompare(q2.spec.displayName), title, hint, showTitle = true, }) => {
1861
- const sortFncCallback = React.useCallback(sortFnc, [sortFnc]);
1862
- const { allQuickStarts = [], setAllQuickStarts, allQuickStartStates, getResource, filter, setFilter, loading, } = React.useContext(QuickStartContext);
1863
- React.useEffect(() => {
1864
- // passed through prop, not context
1865
- if (quickStarts && JSON.stringify(quickStarts) !== JSON.stringify(allQuickStarts)) {
1866
- setAllQuickStarts(quickStarts);
1867
- }
1868
- }, [quickStarts, allQuickStarts, setAllQuickStarts]);
1869
- const initialFilteredQuickStarts = showFilter
1870
- ? filterQuickStarts(allQuickStarts, filter.keyword, filter.status.statusFilters, allQuickStartStates).sort(sortFncCallback)
1871
- : allQuickStarts;
1872
- const [filteredQuickStarts, setFilteredQuickStarts] = React.useState(initialFilteredQuickStarts);
1873
- React.useEffect(() => {
1874
- const filteredQs = showFilter
1875
- ? filterQuickStarts(allQuickStarts, filter.keyword, filter.status.statusFilters, allQuickStartStates).sort(sortFncCallback)
1876
- : allQuickStarts;
1877
- // also needs a check whether the content of the QS changed
1878
- if (filteredQs.length !== filteredQuickStarts.length ||
1879
- JSON.stringify(filteredQs) !== JSON.stringify(filteredQuickStarts)) {
1880
- setFilteredQuickStarts(filteredQs);
1881
- }
1882
- }, [
1883
- allQuickStarts,
1884
- allQuickStartStates,
1885
- showFilter,
1886
- filter.keyword,
1887
- filter.status.statusFilters,
1888
- sortFncCallback,
1889
- filteredQuickStarts,
1890
- ]);
1891
- const clearFilters = () => {
1892
- setFilter('keyword', '');
1893
- setFilter('status', []);
1894
- clearFilterParams();
1895
- setFilteredQuickStarts(allQuickStarts.sort((q1, q2) => q1.spec.displayName.localeCompare(q2.spec.displayName)));
1896
- };
1897
- const onSearchInputChange = (searchValue) => {
1898
- const result = filterQuickStarts(allQuickStarts, searchValue, filter.status.statusFilters, allQuickStartStates).sort((q1, q2) => q1.spec.displayName.localeCompare(q2.spec.displayName));
1899
- if (searchValue !== filter.keyword) {
1900
- setFilter('keyword', searchValue);
1901
- }
1902
- if (result.length !== filteredQuickStarts.length) {
1903
- setFilteredQuickStarts(result);
1904
- }
1905
- };
1906
- const onStatusChange = (statusList) => {
1907
- const result = filterQuickStarts(allQuickStarts, filter.keyword, statusList, allQuickStartStates).sort((q1, q2) => q1.spec.displayName.localeCompare(q2.spec.displayName));
1908
- if (JSON.stringify(statusList) !== JSON.stringify(filter.status)) {
1909
- setFilter('status', statusList);
1910
- }
1911
- if (result.length !== filteredQuickStarts.length) {
1912
- setFilteredQuickStarts(result);
1913
- }
1914
- };
1915
- if (loading) {
1916
- return React.createElement(LoadingBox, null);
1917
- }
1918
- if (!allQuickStarts || allQuickStarts.length === 0) {
1919
- return React.createElement(EmptyBox, { label: getResource('Quick Starts') });
1920
- }
1921
- return (React.createElement("div", { className: "pfext-quick-start__base" },
1922
- showTitle && (React.createElement("div", { className: "pfext-page-layout__header" },
1923
- React.createElement(Text, { component: "h1", className: "pfext-page-layout__title", "data-test": "page-title" }, title || getResource('Quick Starts')),
1924
- hint && React.createElement("div", { className: "pfext-page-layout__hint" }, hint))),
1925
- showTitle && React.createElement(Divider, { component: "div" }),
1926
- showFilter && (React.createElement(React.Fragment, null,
1927
- React.createElement(QuickStartCatalogFilter, { quickStartsCount: filteredQuickStarts.length, onSearchInputChange: onSearchInputChange, onStatusChange: onStatusChange }),
1928
- React.createElement(Divider, { component: "div" }))),
1929
- React.createElement(React.Fragment, null, filteredQuickStarts.length === 0 ? (React.createElement(QuickStartCatalogEmptyState, { clearFilters: clearFilters })) : (React.createElement(QuickStartCatalog, { quickStarts: filteredQuickStarts })))));
1930
- };
1931
-
1932
- const QuickStartCatalogHeader = ({ title, hint, }) => (React.createElement("div", { className: "pfext-page-layout__header" },
1933
- React.createElement("h1", { "data-pf-content": "true", className: "pfext-page-layout__title" }, title),
1847
+ const QuickStartCatalogFilter = (_a) => {
1848
+ var { quickStartsCount, onSearchInputChange = () => { }, onStatusChange = () => { } } = _a, props = __rest(_a, ["quickStartsCount", "onSearchInputChange", "onStatusChange"]);
1849
+ return (React.createElement(Toolbar, Object.assign({ usePageInsets: true, className: "pfext-quick-start-catalog-filter__flex" }, props),
1850
+ React.createElement(ToolbarContent, null,
1851
+ React.createElement(QuickStartCatalogFilterSearchWrapper, { onSearchInputChange: onSearchInputChange }),
1852
+ React.createElement(QuickStartCatalogFilterStatusWrapper, { onStatusChange: onStatusChange }),
1853
+ React.createElement(QuickStartCatalogFilterCountWrapper, { quickStartsCount: quickStartsCount }))));
1854
+ };
1855
+
1856
+ const QuickStartCatalogEmptyState = ({ clearFilters }) => {
1857
+ const { getResource } = React.useContext(QuickStartContext);
1858
+ return (React.createElement(EmptyState, null,
1859
+ React.createElement(EmptyStateHeader, { titleText: React.createElement(React.Fragment, null, getResource('No results found')), icon: React.createElement(EmptyStateIcon, { icon: SearchIcon }), headingLevel: "h4" }),
1860
+ React.createElement(EmptyStateBody, null, getResource('No results match the filter criteria. Remove filters or clear all filters to show results.')),
1861
+ React.createElement(EmptyStateFooter, null,
1862
+ React.createElement(EmptyStateActions, null,
1863
+ React.createElement(Button, { variant: "link", onClick: clearFilters, "data-test": "clear-filter button" }, getResource('Clear all filters'))))));
1864
+ };
1865
+ const QuickStartCatalogPage = ({ quickStarts, showFilter, sortFnc = (q1, q2) => q1.spec.displayName.localeCompare(q2.spec.displayName), title, hint, showTitle = true, }) => {
1866
+ const sortFncCallback = React.useCallback(sortFnc, [sortFnc]);
1867
+ const { allQuickStarts = [], setAllQuickStarts, allQuickStartStates, getResource, filter, setFilter, loading, } = React.useContext(QuickStartContext);
1868
+ React.useEffect(() => {
1869
+ // passed through prop, not context
1870
+ if (quickStarts && JSON.stringify(quickStarts) !== JSON.stringify(allQuickStarts)) {
1871
+ setAllQuickStarts(quickStarts);
1872
+ }
1873
+ }, [quickStarts, allQuickStarts, setAllQuickStarts]);
1874
+ const initialFilteredQuickStarts = showFilter
1875
+ ? filterQuickStarts(allQuickStarts, filter.keyword, filter.status.statusFilters, allQuickStartStates).sort(sortFncCallback)
1876
+ : allQuickStarts;
1877
+ const [filteredQuickStarts, setFilteredQuickStarts] = React.useState(initialFilteredQuickStarts);
1878
+ React.useEffect(() => {
1879
+ const filteredQs = showFilter
1880
+ ? filterQuickStarts(allQuickStarts, filter.keyword, filter.status.statusFilters, allQuickStartStates).sort(sortFncCallback)
1881
+ : allQuickStarts;
1882
+ // also needs a check whether the content of the QS changed
1883
+ if (filteredQs.length !== filteredQuickStarts.length ||
1884
+ JSON.stringify(filteredQs) !== JSON.stringify(filteredQuickStarts)) {
1885
+ setFilteredQuickStarts(filteredQs);
1886
+ }
1887
+ }, [
1888
+ allQuickStarts,
1889
+ allQuickStartStates,
1890
+ showFilter,
1891
+ filter.keyword,
1892
+ filter.status.statusFilters,
1893
+ sortFncCallback,
1894
+ filteredQuickStarts,
1895
+ ]);
1896
+ const clearFilters = () => {
1897
+ setFilter('keyword', '');
1898
+ setFilter('status', []);
1899
+ clearFilterParams();
1900
+ setFilteredQuickStarts(allQuickStarts.sort((q1, q2) => q1.spec.displayName.localeCompare(q2.spec.displayName)));
1901
+ };
1902
+ const onSearchInputChange = (searchValue) => {
1903
+ const result = filterQuickStarts(allQuickStarts, searchValue, filter.status.statusFilters, allQuickStartStates).sort((q1, q2) => q1.spec.displayName.localeCompare(q2.spec.displayName));
1904
+ if (searchValue !== filter.keyword) {
1905
+ setFilter('keyword', searchValue);
1906
+ }
1907
+ if (result.length !== filteredQuickStarts.length) {
1908
+ setFilteredQuickStarts(result);
1909
+ }
1910
+ };
1911
+ const onStatusChange = (statusList) => {
1912
+ const result = filterQuickStarts(allQuickStarts, filter.keyword, statusList, allQuickStartStates).sort((q1, q2) => q1.spec.displayName.localeCompare(q2.spec.displayName));
1913
+ if (JSON.stringify(statusList) !== JSON.stringify(filter.status)) {
1914
+ setFilter('status', statusList);
1915
+ }
1916
+ if (result.length !== filteredQuickStarts.length) {
1917
+ setFilteredQuickStarts(result);
1918
+ }
1919
+ };
1920
+ if (loading) {
1921
+ return React.createElement(LoadingBox, null);
1922
+ }
1923
+ if (!allQuickStarts || allQuickStarts.length === 0) {
1924
+ return React.createElement(EmptyBox, { label: getResource('Quick Starts') });
1925
+ }
1926
+ return (React.createElement("div", { className: "pfext-quick-start__base" },
1927
+ showTitle && (React.createElement("div", { className: "pfext-page-layout__header" },
1928
+ React.createElement(Text, { component: "h1", className: "pfext-page-layout__title", "data-test": "page-title" }, title || getResource('Quick Starts')),
1929
+ hint && React.createElement("div", { className: "pfext-page-layout__hint" }, hint))),
1930
+ showTitle && React.createElement(Divider, { component: "div" }),
1931
+ showFilter && (React.createElement(React.Fragment, null,
1932
+ React.createElement(QuickStartCatalogFilter, { quickStartsCount: filteredQuickStarts.length, onSearchInputChange: onSearchInputChange, onStatusChange: onStatusChange }),
1933
+ React.createElement(Divider, { component: "div" }))),
1934
+ React.createElement(React.Fragment, null, filteredQuickStarts.length === 0 ? (React.createElement(QuickStartCatalogEmptyState, { clearFilters: clearFilters })) : (React.createElement(QuickStartCatalog, { quickStarts: filteredQuickStarts })))));
1935
+ };
1936
+
1937
+ const QuickStartCatalogHeader = ({ title, hint, }) => (React.createElement("div", { className: "pfext-page-layout__header" },
1938
+ React.createElement("h1", { "data-pf-content": "true", className: "pfext-page-layout__title" }, title),
1934
1939
  hint && React.createElement("div", { className: "pfext-page-layout__hint" }, hint)));
1935
1940
 
1936
1941
  const QuickStartCatalogSection = ({ children }) => (React.createElement("div", { className: "pfext-page-layout__content" }, children));
1937
1942
 
1938
1943
  const QuickStartCatalogToolbar = ({ children }) => (React.createElement(Toolbar, { usePageInsets: true, className: "pfext-quick-start-catalog-filter__flex" }, children));
1939
1944
 
1940
- const QuickStartCloseModal = ({ isOpen, onConfirm, onCancel, }) => {
1941
- const { getResource } = React.useContext(QuickStartContext);
1942
- return (React.createElement(Modal, { className: "pfext-quick-start-drawer__modal pfext-quick-start__base", isOpen: isOpen, variant: ModalVariant.small, showClose: false, "data-test": "leave-quickstart", title: getResource('Leave quick start?'), footer: React.createElement(Flex, null,
1943
- React.createElement(FlexItem, { align: { default: 'alignRight' } },
1944
- React.createElement(Button, { variant: "secondary", "data-test": "cancel button", onClick: onCancel }, getResource('Cancel'))),
1945
- React.createElement(FlexItem, null,
1946
- React.createElement(Button, { variant: "primary", "data-test": "leave button", onClick: onConfirm }, getResource('Leave')))), isFullScreen: true }, getResource('Your progress will be saved.')));
1947
- };
1948
-
1949
- const TaskIcon = ({ taskIndex, taskStatus }) => {
1950
- const { getResource } = React.useContext(QuickStartContext);
1951
- const success = taskStatus === QuickStartTaskStatus.SUCCESS;
1952
- const failed = taskStatus === QuickStartTaskStatus.FAILED;
1953
- const classNames = css('pfext-icon-and-text__icon', {
1954
- 'pfext-quick-start-task-header__task-icon-init': !failed && !success,
1955
- });
1956
- let content;
1957
- if (success) {
1958
- content = (React.createElement(Icon, { size: "md" },
1959
- React.createElement(CheckCircleIcon, { className: "pfext-quick-start-task-header__task-icon-success" }),
1960
- ' '));
1961
- }
1962
- else if (failed) {
1963
- content = (React.createElement(Icon, { size: "md" },
1964
- React.createElement(ExclamationCircleIcon, { className: "pfext-quick-start-task-header__task-icon-failed" })));
1965
- }
1966
- else {
1967
- content = getResource('{{taskIndex, number}}', taskIndex).replace('{{taskIndex, number}}', taskIndex);
1968
- }
1969
- return React.createElement("span", { className: classNames }, content);
1970
- };
1971
- const QuickStartTaskHeader = ({ title, taskIndex, subtitle, taskStatus, size, isActiveTask, onTaskSelect, children, }) => {
1972
- const titleRef = React.useRef(null);
1973
- React.useEffect(() => {
1974
- if (isActiveTask) {
1975
- // Focus the WizardNavItem button element that contains the title
1976
- titleRef.current.parentNode.focus();
1977
- }
1978
- }, [isActiveTask]);
1979
- const classNames = css('pfext-quick-start-task-header__title', {
1980
- 'pfext-quick-start-task-header__title-success': taskStatus === QuickStartTaskStatus.SUCCESS,
1981
- 'pfext-quick-start-task-header__title-failed': taskStatus === (QuickStartTaskStatus.FAILED || QuickStartTaskStatus.VISITED),
1982
- });
1983
- // const notCompleted = taskStatus === QuickStartTaskStatus.VISITED;
1984
- // const skippedReview = taskStatus === QuickStartTaskStatus.REVIEW;
1985
- const failedReview = taskStatus === QuickStartTaskStatus.FAILED;
1986
- // TODO: toned down when this is shown, investigate further when we should display it
1987
- // related: https://github.com/patternfly/patternfly-quickstarts/issues/104
1988
- const tryAgain = failedReview && (React.createElement(React.Fragment, null,
1989
- React.createElement("div", null),
1990
- React.createElement("div", { className: "pfext-quick-start-task-header__tryagain" }, "Try the steps again.")));
1991
- const content = (React.createElement("div", { className: "pfext-quick-start-task-header", ref: titleRef },
1992
- React.createElement(TaskIcon, { taskIndex: taskIndex, taskStatus: taskStatus }),
1993
- React.createElement(Title, { headingLevel: "h3", size: size, className: classNames },
1994
- React.createElement("span", { dangerouslySetInnerHTML: { __html: removeParagraphWrap(markdownConvert(title)) } }),
1995
- isActiveTask && subtitle && (React.createElement("span", { className: "pfext-quick-start-task-header__subtitle", "data-test-id": "quick-start-task-subtitle" },
1996
- ' ',
1997
- subtitle))),
1998
- tryAgain));
1999
- return (React.createElement(WizardNavItem, { content: content, stepIndex: taskIndex, onClick: () => onTaskSelect(taskIndex - 1), component: "button", isCurrent: isActiveTask }, children));
1945
+ const QuickStartCloseModal = ({ isOpen, onConfirm, onCancel, }) => {
1946
+ const { getResource } = React.useContext(QuickStartContext);
1947
+ return (React.createElement(Modal, { className: "pfext-quick-start-drawer__modal pfext-quick-start__base", isOpen: isOpen, variant: ModalVariant.small, showClose: false, "data-test": "leave-quickstart", title: getResource('Leave quick start?'), footer: React.createElement(Flex, null,
1948
+ React.createElement(FlexItem, { align: { default: 'alignRight' } },
1949
+ React.createElement(Button, { variant: "secondary", "data-test": "cancel button", onClick: onCancel }, getResource('Cancel'))),
1950
+ React.createElement(FlexItem, null,
1951
+ React.createElement(Button, { variant: "primary", "data-test": "leave button", onClick: onConfirm }, getResource('Leave')))), isFullScreen: true }, getResource('Your progress will be saved.')));
1952
+ };
1953
+
1954
+ const TaskIcon = ({ taskIndex, taskStatus }) => {
1955
+ const { getResource } = React.useContext(QuickStartContext);
1956
+ const success = taskStatus === QuickStartTaskStatus.SUCCESS;
1957
+ const failed = taskStatus === QuickStartTaskStatus.FAILED;
1958
+ const classNames = css('pfext-icon-and-text__icon', {
1959
+ 'pfext-quick-start-task-header__task-icon-init': !failed && !success,
1960
+ });
1961
+ let content;
1962
+ if (success) {
1963
+ content = (React.createElement(Icon, { size: "md" },
1964
+ React.createElement(CheckCircleIcon, { className: "pfext-quick-start-task-header__task-icon-success" }),
1965
+ ' '));
1966
+ }
1967
+ else if (failed) {
1968
+ content = (React.createElement(Icon, { size: "md" },
1969
+ React.createElement(ExclamationCircleIcon, { className: "pfext-quick-start-task-header__task-icon-failed" })));
1970
+ }
1971
+ else {
1972
+ content = getResource('{{taskIndex, number}}', taskIndex).replace('{{taskIndex, number}}', taskIndex);
1973
+ }
1974
+ return React.createElement("span", { className: classNames }, content);
1975
+ };
1976
+ const QuickStartTaskHeader = ({ title, taskIndex, subtitle, taskStatus, size, isActiveTask, onTaskSelect, children, }) => {
1977
+ const titleRef = React.useRef(null);
1978
+ React.useEffect(() => {
1979
+ if (isActiveTask) {
1980
+ // Focus the WizardNavItem button element that contains the title
1981
+ titleRef.current.parentNode.focus();
1982
+ }
1983
+ }, [isActiveTask]);
1984
+ const classNames = css('pfext-quick-start-task-header__title', {
1985
+ 'pfext-quick-start-task-header__title-success': taskStatus === QuickStartTaskStatus.SUCCESS,
1986
+ 'pfext-quick-start-task-header__title-failed': taskStatus === (QuickStartTaskStatus.FAILED || QuickStartTaskStatus.VISITED),
1987
+ });
1988
+ // const notCompleted = taskStatus === QuickStartTaskStatus.VISITED;
1989
+ // const skippedReview = taskStatus === QuickStartTaskStatus.REVIEW;
1990
+ const failedReview = taskStatus === QuickStartTaskStatus.FAILED;
1991
+ // TODO: toned down when this is shown, investigate further when we should display it
1992
+ // related: https://github.com/patternfly/patternfly-quickstarts/issues/104
1993
+ const tryAgain = failedReview && (React.createElement(React.Fragment, null,
1994
+ React.createElement("div", null),
1995
+ React.createElement("div", { className: "pfext-quick-start-task-header__tryagain" }, "Try the steps again.")));
1996
+ const content = (React.createElement("div", { className: "pfext-quick-start-task-header", ref: titleRef },
1997
+ React.createElement(TaskIcon, { taskIndex: taskIndex, taskStatus: taskStatus }),
1998
+ React.createElement(Title, { headingLevel: "h3", size: size, className: classNames },
1999
+ React.createElement("span", { dangerouslySetInnerHTML: { __html: removeParagraphWrap(markdownConvert(title)) } }),
2000
+ isActiveTask && subtitle && (React.createElement("span", { className: "pfext-quick-start-task-header__subtitle", "data-test-id": "quick-start-task-subtitle" },
2001
+ ' ',
2002
+ subtitle))),
2003
+ tryAgain));
2004
+ return (React.createElement(WizardNavItem, { content: content, stepIndex: taskIndex, onClick: () => onTaskSelect(taskIndex - 1), component: "button", isCurrent: isActiveTask }, children));
2000
2005
  };
2001
2006
 
2002
2007
  const QuickStartTaskHeaderList = ({ tasks, allTaskStatuses, onTaskSelect, }) => tasks.length > 0 ? (React.createElement(List, { className: "pfext-quick-start-task-header__list" }, tasks.map((task, index) => (React.createElement(QuickStartTaskHeader, { key: task.title, title: task.title, taskIndex: index + 1, size: "md", taskStatus: allTaskStatuses[index], onTaskSelect: onTaskSelect }))))) : null;
2003
2008
 
2004
- const QuickStartConclusion = ({ tasks, conclusion, allTaskStatuses, nextQuickStarts, onQuickStartChange, onTaskSelect, }) => {
2005
- const hasFailedTask = allTaskStatuses.includes(QuickStartTaskStatus.FAILED);
2006
- const { getResource } = React.useContext(QuickStartContext);
2007
- return (React.createElement(React.Fragment, null,
2008
- React.createElement(QuickStartTaskHeaderList, { tasks: tasks, allTaskStatuses: allTaskStatuses, onTaskSelect: onTaskSelect }),
2009
- React.createElement(QuickStartMarkdownView, { content: hasFailedTask
2010
- ? getResource('One or more verifications did not pass during this quick start. Revisit the tasks or the help links, and then try again.')
2011
- : conclusion }),
2012
- !hasFailedTask &&
2013
- nextQuickStarts &&
2014
- nextQuickStarts.length > 0 &&
2015
- nextQuickStarts.map((nextQuickStart, index) => {
2016
- var _a;
2017
- return (React.createElement(Button, { variant: "link", onClick: () => onQuickStartChange(nextQuickStart.metadata.name), isInline: true, isBlock: true, key: index },
2018
- getResource('Start {{nextQSDisplayName}} quick start').replace('{{nextQSDisplayName}}', (_a = nextQuickStart === null || nextQuickStart === void 0 ? void 0 : nextQuickStart.spec) === null || _a === void 0 ? void 0 : _a.displayName),
2019
- ' ',
2020
- React.createElement(ArrowRightIcon, { style: { marginLeft: 'var(--pf-v5-global--spacer--xs)', verticalAlign: 'middle' } })));
2021
- })));
2022
- };
2023
-
2024
- const QuickStartIntroduction = ({ tasks, introduction, allTaskStatuses, prerequisites, onTaskSelect, }) => {
2025
- const { getResource } = React.useContext(QuickStartContext);
2026
- const prereqs = prerequisites === null || prerequisites === void 0 ? void 0 : prerequisites.filter((p) => p);
2027
- const [isPrereqsExpanded, setIsPrereqsExpanded] = React.useState(false);
2028
- const prereqList = (prereqs === null || prereqs === void 0 ? void 0 : prereqs.length) > 0 && (React.createElement(ExpandableSection, { toggleText: getResource('View Prerequisites ({{totalPrereqs}})').replace('{{totalPrereqs}}', prereqs.length), onToggle: () => setIsPrereqsExpanded(!isPrereqsExpanded), className: "pfext-quick-start-intro__prereq" },
2029
- React.createElement(List, { className: "pfext-quick-start-intro__prereq-list" }, prereqs.map((pr) => (React.createElement(ListItem, { key: pr, className: "pfext-quick-start-intro__prereq-list__item" },
2030
- React.createElement("span", { className: "pfext-quick-start-intro__prereq-list__item-content" },
2031
- React.createElement(QuickStartMarkdownView, { content: pr }))))))));
2032
- return (React.createElement(React.Fragment, null,
2033
- React.createElement(QuickStartMarkdownView, { content: introduction }),
2034
- prereqList,
2035
- React.createElement("p", { style: { marginBottom: 'var(--pf-v5-global--spacer--md)' } },
2036
- getResource('In this quick start, you will complete {{count, number}} task', tasks.length).replace('{{count, number}}', tasks.length),
2037
- ":"),
2038
- React.createElement(QuickStartTaskHeaderList, { tasks: tasks, allTaskStatuses: allTaskStatuses, onTaskSelect: onTaskSelect })));
2039
- };
2040
-
2041
- const getAlertVariant = (status) => {
2042
- switch (status) {
2043
- case QuickStartTaskStatus.SUCCESS:
2044
- return 'success';
2045
- case QuickStartTaskStatus.FAILED:
2046
- return 'danger';
2047
- default:
2048
- return 'info';
2049
- }
2050
- };
2051
- const QuickStartTaskReview = ({ review, taskStatus, onTaskReview, }) => {
2052
- const { instructions, failedTaskHelp: taskHelp } = review;
2053
- const { getResource } = React.useContext(QuickStartContext);
2054
- const alertClassNames = css('pfext-quick-start-task-review', {
2055
- 'pfext-quick-start-task-review--success': taskStatus === QuickStartTaskStatus.SUCCESS,
2056
- 'pfext-quick-start-task-review--failed': taskStatus === QuickStartTaskStatus.FAILED,
2057
- });
2058
- const title = React.createElement("span", { className: alertClassNames }, getResource('Check your work'));
2059
- return (React.createElement(Alert, { className: "pfext-quick-start-task-review-alert", variant: getAlertVariant(taskStatus), title: title, isInline: true, role: "alert" },
2060
- React.createElement(QuickStartMarkdownView, { content: instructions }),
2061
- React.createElement("span", { className: "pfext-quick-start-task-review__actions" },
2062
- React.createElement(Radio, { id: "review-success", name: "review-success", "data-testid": "qs-drawer-check-yes", label: getResource('Yes'), className: "pfext-quick-start-task-review__radio", isChecked: taskStatus === QuickStartTaskStatus.SUCCESS, onChange: () => onTaskReview(QuickStartTaskStatus.SUCCESS) }),
2063
- React.createElement(Radio, { id: "review-failed", name: "review-failed", "data-testid": "qs-drawer-check-no", label: getResource('No'), className: "pfext-quick-start-task-review__radio", isChecked: taskStatus === QuickStartTaskStatus.FAILED, onChange: () => onTaskReview(QuickStartTaskStatus.FAILED) })),
2064
- taskStatus === QuickStartTaskStatus.FAILED && taskHelp && (React.createElement(QuickStartMarkdownView, { content: taskHelp, exactHeight: true }))));
2065
- };
2066
-
2067
- const QuickStartTasks = ({ tasks, taskNumber, allTaskStatuses, onTaskReview, onTaskSelect, }) => {
2068
- const { getResource, alwaysShowTaskReview } = React.useContext(QuickStartContext);
2069
- return (React.createElement("div", { className: "pfext-quick-start-tasks__list" },
2070
- React.createElement("ul", null, tasks
2071
- .filter((_, index) => allTaskStatuses[index] !== QuickStartTaskStatus.INIT)
2072
- .map((task, index) => {
2073
- const { title, description, review } = task;
2074
- const isActiveTask = index === taskNumber;
2075
- const taskStatus = allTaskStatuses[index];
2076
- const shouldShowTaskReview = (!QUICKSTART_TASKS_INITIAL_STATES.includes(taskStatus) || alwaysShowTaskReview) &&
2077
- review;
2078
- return (React.createElement(React.Fragment, { key: title },
2079
- React.createElement(QuickStartTaskHeader, { taskIndex: index + 1, title: title, size: "md", subtitle: getResource('{{index, number}} of {{tasks, number}}')
2080
- .replace('{{index, number}}', index + 1)
2081
- .replace('{{tasks, number}}', tasks.length), taskStatus: taskStatus, isActiveTask: isActiveTask, onTaskSelect: onTaskSelect }, isActiveTask && (React.createElement("div", { className: "pfext-quick-start-task__content" },
2082
- React.createElement(QuickStartMarkdownView, { content: description }),
2083
- shouldShowTaskReview && (React.createElement(QuickStartTaskReview, { review: review, taskStatus: taskStatus, onTaskReview: onTaskReview })))))));
2084
- }))));
2085
- };
2086
-
2087
- const QuickStartContent = React.forwardRef(({ quickStart, nextQuickStarts = [], taskNumber, allTaskStatuses, onTaskSelect, onTaskReview, onQuickStartChange, }, ref) => {
2088
- const { spec: { introduction, tasks, conclusion, prerequisites }, } = quickStart;
2089
- const totalTasks = tasks.length;
2090
- return (React.createElement("div", { className: "pfext-quick-start-content", ref: ref },
2091
- taskNumber === -1 && (React.createElement(QuickStartIntroduction, { tasks: tasks, allTaskStatuses: allTaskStatuses, introduction: introduction, prerequisites: prerequisites, onTaskSelect: onTaskSelect })),
2092
- taskNumber > -1 && taskNumber < totalTasks && (React.createElement(QuickStartTasks, { tasks: tasks, taskNumber: taskNumber, allTaskStatuses: allTaskStatuses, onTaskReview: onTaskReview, onTaskSelect: onTaskSelect })),
2093
- taskNumber === totalTasks && (React.createElement(QuickStartConclusion, { tasks: tasks, conclusion: conclusion, allTaskStatuses: allTaskStatuses, nextQuickStarts: nextQuickStarts, onQuickStartChange: onQuickStartChange, onTaskSelect: onTaskSelect }))));
2009
+ const QuickStartConclusion = ({ tasks, conclusion, allTaskStatuses, nextQuickStarts, onQuickStartChange, onTaskSelect, }) => {
2010
+ const hasFailedTask = allTaskStatuses.includes(QuickStartTaskStatus.FAILED);
2011
+ const { getResource } = React.useContext(QuickStartContext);
2012
+ return (React.createElement(React.Fragment, null,
2013
+ React.createElement(QuickStartTaskHeaderList, { tasks: tasks, allTaskStatuses: allTaskStatuses, onTaskSelect: onTaskSelect }),
2014
+ React.createElement(QuickStartMarkdownView, { content: hasFailedTask
2015
+ ? getResource('One or more verifications did not pass during this quick start. Revisit the tasks or the help links, and then try again.')
2016
+ : conclusion }),
2017
+ !hasFailedTask &&
2018
+ nextQuickStarts &&
2019
+ nextQuickStarts.length > 0 &&
2020
+ nextQuickStarts.map((nextQuickStart, index) => {
2021
+ var _a;
2022
+ return (React.createElement(Button, { variant: "link", onClick: () => onQuickStartChange(nextQuickStart.metadata.name), isInline: true, isBlock: true, key: index },
2023
+ getResource('Start {{nextQSDisplayName}} quick start').replace('{{nextQSDisplayName}}', (_a = nextQuickStart === null || nextQuickStart === void 0 ? void 0 : nextQuickStart.spec) === null || _a === void 0 ? void 0 : _a.displayName),
2024
+ ' ',
2025
+ React.createElement(ArrowRightIcon, { style: { marginLeft: 'var(--pf-v5-global--spacer--xs)', verticalAlign: 'middle' } })));
2026
+ })));
2027
+ };
2028
+
2029
+ const QuickStartIntroduction = ({ tasks, introduction, allTaskStatuses, prerequisites, onTaskSelect, }) => {
2030
+ const { getResource } = React.useContext(QuickStartContext);
2031
+ const prereqs = prerequisites === null || prerequisites === void 0 ? void 0 : prerequisites.filter((p) => p);
2032
+ const [isPrereqsExpanded, setIsPrereqsExpanded] = React.useState(false);
2033
+ const prereqList = (prereqs === null || prereqs === void 0 ? void 0 : prereqs.length) > 0 && (React.createElement(ExpandableSection, { toggleText: getResource('View Prerequisites ({{totalPrereqs}})').replace('{{totalPrereqs}}', prereqs.length), onToggle: () => setIsPrereqsExpanded(!isPrereqsExpanded), className: "pfext-quick-start-intro__prereq" },
2034
+ React.createElement(List, { className: "pfext-quick-start-intro__prereq-list" }, prereqs.map((pr) => (React.createElement(ListItem, { key: pr, className: "pfext-quick-start-intro__prereq-list__item" },
2035
+ React.createElement("span", { className: "pfext-quick-start-intro__prereq-list__item-content" },
2036
+ React.createElement(QuickStartMarkdownView, { content: pr }))))))));
2037
+ return (React.createElement(React.Fragment, null,
2038
+ React.createElement(QuickStartMarkdownView, { content: introduction }),
2039
+ prereqList,
2040
+ React.createElement("p", { style: { marginBottom: 'var(--pf-v5-global--spacer--md)' } },
2041
+ getResource('In this quick start, you will complete {{count, number}} task', tasks.length).replace('{{count, number}}', tasks.length),
2042
+ ":"),
2043
+ React.createElement(QuickStartTaskHeaderList, { tasks: tasks, allTaskStatuses: allTaskStatuses, onTaskSelect: onTaskSelect })));
2044
+ };
2045
+
2046
+ const getAlertVariant = (status) => {
2047
+ switch (status) {
2048
+ case QuickStartTaskStatus.SUCCESS:
2049
+ return 'success';
2050
+ case QuickStartTaskStatus.FAILED:
2051
+ return 'danger';
2052
+ default:
2053
+ return 'info';
2054
+ }
2055
+ };
2056
+ const QuickStartTaskReview = ({ review, taskStatus, onTaskReview, }) => {
2057
+ const { instructions, failedTaskHelp: taskHelp } = review;
2058
+ const { getResource } = React.useContext(QuickStartContext);
2059
+ const alertClassNames = css('pfext-quick-start-task-review', {
2060
+ 'pfext-quick-start-task-review--success': taskStatus === QuickStartTaskStatus.SUCCESS,
2061
+ 'pfext-quick-start-task-review--failed': taskStatus === QuickStartTaskStatus.FAILED,
2062
+ });
2063
+ const title = React.createElement("span", { className: alertClassNames }, getResource('Check your work'));
2064
+ return (React.createElement(Alert, { className: "pfext-quick-start-task-review-alert", variant: getAlertVariant(taskStatus), title: title, isInline: true, role: "alert" },
2065
+ React.createElement(QuickStartMarkdownView, { content: instructions }),
2066
+ React.createElement("span", { className: "pfext-quick-start-task-review__actions" },
2067
+ React.createElement(Radio, { id: "review-success", name: "review-success", "data-testid": "qs-drawer-check-yes", label: getResource('Yes'), className: "pfext-quick-start-task-review__radio", isChecked: taskStatus === QuickStartTaskStatus.SUCCESS, onChange: () => onTaskReview(QuickStartTaskStatus.SUCCESS) }),
2068
+ React.createElement(Radio, { id: "review-failed", name: "review-failed", "data-testid": "qs-drawer-check-no", label: getResource('No'), className: "pfext-quick-start-task-review__radio", isChecked: taskStatus === QuickStartTaskStatus.FAILED, onChange: () => onTaskReview(QuickStartTaskStatus.FAILED) })),
2069
+ taskStatus === QuickStartTaskStatus.FAILED && taskHelp && (React.createElement(QuickStartMarkdownView, { content: taskHelp, exactHeight: true }))));
2070
+ };
2071
+
2072
+ const QuickStartTasks = ({ tasks, taskNumber, allTaskStatuses, onTaskReview, onTaskSelect, }) => {
2073
+ const { getResource, alwaysShowTaskReview } = React.useContext(QuickStartContext);
2074
+ return (React.createElement("div", { className: "pfext-quick-start-tasks__list" },
2075
+ React.createElement("ul", null, tasks
2076
+ .filter((_, index) => allTaskStatuses[index] !== QuickStartTaskStatus.INIT)
2077
+ .map((task, index) => {
2078
+ const { title, description, review } = task;
2079
+ const isActiveTask = index === taskNumber;
2080
+ const taskStatus = allTaskStatuses[index];
2081
+ const shouldShowTaskReview = (!QUICKSTART_TASKS_INITIAL_STATES.includes(taskStatus) || alwaysShowTaskReview) &&
2082
+ review;
2083
+ return (React.createElement(React.Fragment, { key: title },
2084
+ React.createElement(QuickStartTaskHeader, { taskIndex: index + 1, title: title, size: "md", subtitle: getResource('{{index, number}} of {{tasks, number}}')
2085
+ .replace('{{index, number}}', index + 1)
2086
+ .replace('{{tasks, number}}', tasks.length), taskStatus: taskStatus, isActiveTask: isActiveTask, onTaskSelect: onTaskSelect }, isActiveTask && (React.createElement("div", { className: "pfext-quick-start-task__content" },
2087
+ React.createElement(QuickStartMarkdownView, { content: description }),
2088
+ shouldShowTaskReview && (React.createElement(QuickStartTaskReview, { review: review, taskStatus: taskStatus, onTaskReview: onTaskReview })))))));
2089
+ }))));
2090
+ };
2091
+
2092
+ const QuickStartContent = React.forwardRef(({ quickStart, nextQuickStarts = [], taskNumber, allTaskStatuses, onTaskSelect, onTaskReview, onQuickStartChange, }, ref) => {
2093
+ const { spec: { introduction, tasks, conclusion, prerequisites }, } = quickStart;
2094
+ const totalTasks = tasks.length;
2095
+ return (React.createElement("div", { className: "pfext-quick-start-content", ref: ref },
2096
+ taskNumber === -1 && (React.createElement(QuickStartIntroduction, { tasks: tasks, allTaskStatuses: allTaskStatuses, introduction: introduction, prerequisites: prerequisites, onTaskSelect: onTaskSelect })),
2097
+ taskNumber > -1 && taskNumber < totalTasks && (React.createElement(QuickStartTasks, { tasks: tasks, taskNumber: taskNumber, allTaskStatuses: allTaskStatuses, onTaskReview: onTaskReview, onTaskSelect: onTaskSelect })),
2098
+ taskNumber === totalTasks && (React.createElement(QuickStartConclusion, { tasks: tasks, conclusion: conclusion, allTaskStatuses: allTaskStatuses, nextQuickStarts: nextQuickStarts, onQuickStartChange: onQuickStartChange, onTaskSelect: onTaskSelect }))));
2094
2099
  });
2095
2100
 
2096
- const QuickStartFooter = ({ status, taskNumber, totalTasks, onNext, onBack, footerClass, quickStartId, }) => {
2097
- const { restartQuickStart, getResource } = React.useContext(QuickStartContext);
2098
- const PrimaryButtonText = React.useMemo(() => ({
2099
- START: getResource('Start'),
2100
- CONTINUE: getResource('Continue'),
2101
- NEXT: getResource('Next'),
2102
- CLOSE: getResource('Close'),
2103
- }), [getResource]);
2104
- const SecondaryButtonText = React.useMemo(() => ({
2105
- BACK: getResource('Back'),
2106
- RESTART: getResource('Restart'),
2107
- }), [getResource]);
2108
- const onRestart = React.useCallback((e) => {
2109
- e.preventDefault();
2110
- e.stopPropagation();
2111
- restartQuickStart(quickStartId, totalTasks);
2112
- }, [quickStartId, restartQuickStart, totalTasks]);
2113
- const getPrimaryButtonText = React.useMemo(() => {
2114
- if (status === QuickStartStatus.NOT_STARTED) {
2115
- return PrimaryButtonText.START;
2116
- }
2117
- if (taskNumber === totalTasks) {
2118
- return PrimaryButtonText.CLOSE;
2119
- }
2120
- if (taskNumber > -1 && taskNumber < totalTasks) {
2121
- return PrimaryButtonText.NEXT;
2122
- }
2123
- return PrimaryButtonText.CONTINUE;
2124
- }, [taskNumber, totalTasks, PrimaryButtonText, status]);
2125
- const getPrimaryButton = React.useMemo(() => (React.createElement(Button, { variant: "primary", className: "pfext-quick-start-footer__actionbtn", onClick: onNext, "data-testid": `qs-drawer-${camelize(getPrimaryButtonText)}`, "data-test": `${getPrimaryButtonText} button` }, getPrimaryButtonText)), [getPrimaryButtonText, onNext]);
2126
- const getSecondaryButton = React.useMemo(() => taskNumber === -1 && status !== QuickStartStatus.NOT_STARTED ? (React.createElement(Button, { variant: "secondary", onClick: onRestart, "data-testid": "qs-drawer-restart" }, SecondaryButtonText.RESTART)) : (taskNumber > -1 && (React.createElement(Button, { variant: "secondary", onClick: onBack, "data-testid": "qs-drawer-back" }, SecondaryButtonText.BACK))), [onRestart, onBack, SecondaryButtonText, status, taskNumber]);
2127
- const getSideNoteAction = React.useMemo(() => taskNumber !== -1 && (React.createElement(Button, { variant: "link", className: "pfext-quick-start-footer__restartbtn", onClick: onRestart, "data-testid": "qs-drawer-side-note-action" }, SecondaryButtonText.RESTART)), [taskNumber, onRestart, SecondaryButtonText.RESTART]);
2128
- return (React.createElement("div", { className: `pfext-quick-start-footer ${footerClass}` },
2129
- getPrimaryButton,
2130
- getSecondaryButton,
2131
- getSideNoteAction));
2132
- };
2133
-
2134
- const QuickStartController = ({ quickStart, nextQuickStarts, contentRef, footerClass, }) => {
2135
- const { metadata: { name }, spec: { tasks = [] }, } = quickStart;
2136
- const totalTasks = tasks === null || tasks === void 0 ? void 0 : tasks.length;
2137
- const { activeQuickStartState, setActiveQuickStart, setQuickStartTaskNumber, setQuickStartTaskStatus, nextStep, previousStep, } = React.useContext(QuickStartContext);
2138
- const status = activeQuickStartState === null || activeQuickStartState === void 0 ? void 0 : activeQuickStartState.status;
2139
- const taskNumber = activeQuickStartState === null || activeQuickStartState === void 0 ? void 0 : activeQuickStartState.taskNumber;
2140
- const allTaskStatuses = tasks.map((task, index) => activeQuickStartState[`taskStatus${index}`]);
2141
- const handleQuickStartChange = React.useCallback((quickStartId) => setActiveQuickStart(quickStartId), [setActiveQuickStart]);
2142
- const handleTaskStatusChange = React.useCallback((newTaskStatus) => setQuickStartTaskStatus(newTaskStatus), [setQuickStartTaskStatus]);
2143
- const getQuickStartActiveTask = React.useCallback(() => {
2144
- let activeTaskNumber = 0;
2145
- while (activeTaskNumber !== totalTasks &&
2146
- activeQuickStartState[`taskStatus${activeTaskNumber}`] !== QuickStartTaskStatus.INIT) {
2147
- activeTaskNumber++;
2148
- }
2149
- return activeTaskNumber;
2150
- }, [totalTasks, activeQuickStartState]);
2151
- const handleQuickStartContinue = React.useCallback(() => {
2152
- const activeTaskNumber = getQuickStartActiveTask();
2153
- setQuickStartTaskNumber(name, activeTaskNumber);
2154
- }, [getQuickStartActiveTask, setQuickStartTaskNumber, name]);
2155
- const handleNext = React.useCallback(() => {
2156
- if (status === QuickStartStatus.COMPLETE && taskNumber === totalTasks) {
2157
- return handleQuickStartChange('');
2158
- }
2159
- if (status !== QuickStartStatus.NOT_STARTED && taskNumber === -1) {
2160
- return handleQuickStartContinue();
2161
- }
2162
- return nextStep(totalTasks);
2163
- }, [handleQuickStartChange, nextStep, status, taskNumber, totalTasks, handleQuickStartContinue]);
2164
- const handleBack = React.useCallback(() => previousStep(), [previousStep]);
2165
- const handleTaskSelect = React.useCallback((selectedTaskNumber) => {
2166
- setQuickStartTaskNumber(name, selectedTaskNumber);
2167
- }, [name, setQuickStartTaskNumber]);
2168
- return (React.createElement(React.Fragment, null,
2169
- React.createElement(QuickStartContent, { quickStart: quickStart, nextQuickStarts: nextQuickStarts, taskNumber: taskNumber, allTaskStatuses: allTaskStatuses, onTaskSelect: handleTaskSelect, onTaskReview: handleTaskStatusChange, onQuickStartChange: handleQuickStartChange, ref: contentRef }),
2170
- React.createElement(QuickStartFooter, { status: status, taskNumber: taskNumber, totalTasks: totalTasks, onNext: handleNext, onBack: handleBack, footerClass: footerClass, quickStartId: quickStart.metadata.name })));
2171
- };
2172
-
2173
- const getElement = (appendTo) => {
2174
- if (typeof appendTo === 'function') {
2175
- return appendTo();
2176
- }
2177
- return appendTo;
2178
- };
2179
- const useScrollTopOnTaskNumberChange = (node, taskNumber) => {
2180
- React.useEffect(() => {
2181
- if (node) {
2182
- node.scrollTo({ top: 0, behavior: 'smooth' });
2183
- }
2184
- }, [taskNumber, node]);
2185
- };
2186
- const QuickStartPanelContent = (_a) => {
2187
- var { quickStarts = [], handleClose, activeQuickStartID, appendTo, isResizable = true, showClose = true, headerVariant = '' } = _a, props = __rest(_a, ["quickStarts", "handleClose", "activeQuickStartID", "appendTo", "isResizable", "showClose", "headerVariant"]);
2188
- const titleRef = React.useRef(null);
2189
- const { getResource, activeQuickStartState } = React.useContext(QuickStartContext);
2190
- const [contentRef, setContentRef] = React.useState();
2191
- const shadows = useScrollShadows(contentRef);
2192
- const quickStart = quickStarts.find((qs) => qs.metadata.name === activeQuickStartID);
2193
- const taskNumber = activeQuickStartState === null || activeQuickStartState === void 0 ? void 0 : activeQuickStartState.taskNumber;
2194
- useScrollTopOnTaskNumberChange(contentRef, taskNumber);
2195
- const nextQuickStarts = quickStarts.filter((qs) => { var _a; return (_a = quickStart === null || quickStart === void 0 ? void 0 : quickStart.spec.nextQuickStart) === null || _a === void 0 ? void 0 : _a.includes(qs.metadata.name); });
2196
- const headerClasses = css('pfext-quick-start-panel-content__header', {
2197
- 'pfext-quick-start-panel-content__header__shadow': shadows === Shadows.top || shadows === Shadows.both,
2198
- 'pfext-quick-start-panel-content__header--blue-white': headerVariant === 'blue-white',
2199
- });
2200
- const footerClass = css({
2201
- 'pfext-quick-start-panel-content__footer__shadow': shadows === Shadows.bottom || shadows === Shadows.both,
2202
- });
2203
- const getStep = () => {
2204
- const tasks = quickStart.spec.tasks.length;
2205
- if (Number.parseInt(taskNumber) === -1) {
2206
- return 'intro';
2207
- }
2208
- if (Number.parseInt(taskNumber) === tasks) {
2209
- return 'conclusion';
2210
- }
2211
- return Number.parseInt(taskNumber) + 1;
2212
- };
2213
- React.useEffect(() => {
2214
- if (quickStart) {
2215
- titleRef.current.focus();
2216
- }
2217
- }, [quickStart]);
2218
- const content = quickStart ? (React.createElement(DrawerPanelContent, Object.assign({ isResizable: isResizable, className: "pfext-quick-start__base", "data-testid": `qs-drawer-${camelize(quickStart.spec.displayName)}`, "data-qs": `qs-step-${getStep()}`, "data-test": "quickstart drawer" }, props),
2219
- React.createElement("div", { className: headerClasses },
2220
- React.createElement(DrawerHead, null,
2221
- React.createElement("div", { className: "pfext-quick-start-panel-content__title", tabIndex: -1, ref: titleRef },
2222
- React.createElement(Title, { headingLevel: "h2", size: "xl", className: "pfext-quick-start-panel-content__name", style: { marginRight: 'var(--pf-v5-global--spacer--md)' } },
2223
- React.createElement("span", { dangerouslySetInnerHTML: {
2224
- __html: removeParagraphWrap(markdownConvert(quickStart === null || quickStart === void 0 ? void 0 : quickStart.spec.displayName)),
2225
- } }),
2226
- ' ',
2227
- React.createElement("small", { className: "pfext-quick-start-panel-content__duration" }, (quickStart === null || quickStart === void 0 ? void 0 : quickStart.spec.durationMinutes)
2228
- ? getResource('{{type}} • {{duration, number}} minutes', quickStart === null || quickStart === void 0 ? void 0 : quickStart.spec.durationMinutes)
2229
- .replace('{{duration, number}}', quickStart === null || quickStart === void 0 ? void 0 : quickStart.spec.durationMinutes)
2230
- .replace('{{type}}', getResource('Type'))
2231
- : getResource('Type')))),
2232
- showClose && (React.createElement(DrawerActions, null,
2233
- React.createElement(DrawerCloseButton, { onClick: handleClose, className: "pfext-quick-start-panel-content__close-button", "data-testid": "qs-drawer-close" }))))),
2234
- React.createElement(DrawerPanelBody, { hasNoPadding: true, className: "pfext-quick-start-panel-content__body", "data-test": "content" },
2235
- React.createElement(QuickStartController, { quickStart: quickStart, nextQuickStarts: nextQuickStarts, footerClass: footerClass, contentRef: setContentRef })))) : null;
2236
- if (appendTo) {
2237
- return ReactDOM.createPortal(content, getElement(appendTo));
2238
- }
2239
- return content;
2240
- };
2241
-
2242
- const QuickStartContainer = (_a) => {
2243
- var { quickStarts, children, activeQuickStartID, allQuickStartStates, setActiveQuickStartID, setAllQuickStartStates, appendTo, fullWidth, onCloseInProgress, onCloseNotInProgress, resourceBundle, showCardFooters, useLegacyHeaderColors, language, loading = false, useQueryParams = true, markdown, contextProps, alwaysShowTaskReview = true } = _a, props = __rest(_a, ["quickStarts", "children", "activeQuickStartID", "allQuickStartStates", "setActiveQuickStartID", "setAllQuickStartStates", "appendTo", "fullWidth", "onCloseInProgress", "onCloseNotInProgress", "resourceBundle", "showCardFooters", "useLegacyHeaderColors", "language", "loading", "useQueryParams", "markdown", "contextProps", "alwaysShowTaskReview"]);
2244
- const valuesForQuickstartContext = useValuesForQuickStartContext(Object.assign({ allQuickStarts: quickStarts, activeQuickStartID,
2245
- setActiveQuickStartID,
2246
- allQuickStartStates,
2247
- setAllQuickStartStates, footer: {
2248
- show: showCardFooters,
2249
- }, useLegacyHeaderColors,
2250
- language, resourceBundle: Object.assign({}, resourceBundle), loading,
2251
- useQueryParams,
2252
- markdown,
2253
- alwaysShowTaskReview }, contextProps));
2254
- React.useEffect(() => {
2255
- if (quickStarts &&
2256
- JSON.stringify(quickStarts) !== JSON.stringify(valuesForQuickstartContext.allQuickStarts)) {
2257
- valuesForQuickstartContext.setAllQuickStarts(quickStarts);
2258
- }
2259
- }, [quickStarts, valuesForQuickstartContext]);
2260
- React.useEffect(() => {
2261
- if (loading !== valuesForQuickstartContext.loading) {
2262
- valuesForQuickstartContext.setLoading(loading);
2263
- }
2264
- }, [loading, valuesForQuickstartContext]);
2265
- const drawerProps = Object.assign({ appendTo,
2266
- fullWidth,
2267
- onCloseInProgress,
2268
- onCloseNotInProgress }, props);
2269
- return (React.createElement(QuickStartContext.Provider, { value: valuesForQuickstartContext },
2270
- React.createElement(QuickStartDrawer, Object.assign({}, drawerProps), children)));
2271
- };
2272
- const QuickStartDrawer = (_a) => {
2273
- var { quickStarts = [], children, appendTo, fullWidth, onCloseInProgress, onCloseNotInProgress } = _a, props = __rest(_a, ["quickStarts", "children", "appendTo", "fullWidth", "onCloseInProgress", "onCloseNotInProgress"]);
2274
- const { activeQuickStartID, setActiveQuickStart, allQuickStarts = [], activeQuickStartState, allQuickStartStates, setAllQuickStartStates, useLegacyHeaderColors, } = React.useContext(QuickStartContext);
2275
- const combinedQuickStarts = allQuickStarts.concat(quickStarts);
2276
- React.useEffect(() => {
2277
- const params = new URLSearchParams(window.location.search);
2278
- // if there is a quick start param, but the quick start is not active, set it
2279
- // this can happen if a new browser session is opened or an incognito window for example
2280
- const quickStartIdFromParam = params.get(QUICKSTART_ID_FILTER_KEY) || '';
2281
- if (quickStartIdFromParam && activeQuickStartID !== quickStartIdFromParam) {
2282
- const activeQuickStart = getQuickStartByName(quickStartIdFromParam, combinedQuickStarts);
2283
- // don't try to load a quick start that is actually just an external resource (spec.link)
2284
- if (combinedQuickStarts.length > 0 && activeQuickStart && !activeQuickStart.spec.link) {
2285
- setActiveQuickStart(quickStartIdFromParam);
2286
- }
2287
- }
2288
- }, [activeQuickStartID, combinedQuickStarts, setActiveQuickStart]);
2289
- React.useEffect(() => {
2290
- // If activeQuickStartID was changed through prop from QuickStartContainer, need to init the state if it does not exist yet
2291
- if (activeQuickStartID && !allQuickStartStates[activeQuickStartID]) {
2292
- setAllQuickStartStates(Object.assign(Object.assign({}, allQuickStartStates), { [activeQuickStartID]: getDefaultQuickStartState() }));
2293
- }
2294
- }, [activeQuickStartID, allQuickStartStates, setAllQuickStartStates]);
2295
- const [modalOpen, setModalOpen] = React.useState(false);
2296
- const activeQuickStartStatus = activeQuickStartState === null || activeQuickStartState === void 0 ? void 0 : activeQuickStartState.status;
2297
- const onClose = () => setActiveQuickStart('');
2298
- const handleClose = () => {
2299
- if (activeQuickStartStatus === QuickStartStatus.IN_PROGRESS) {
2300
- if (onCloseInProgress) {
2301
- onCloseInProgress();
2302
- }
2303
- else {
2304
- setModalOpen(true);
2305
- }
2306
- }
2307
- else if (onCloseNotInProgress) {
2308
- onCloseNotInProgress();
2309
- }
2310
- else {
2311
- onClose();
2312
- }
2313
- };
2314
- const onModalConfirm = () => {
2315
- setModalOpen(false);
2316
- onClose();
2317
- };
2318
- const onModalCancel = () => setModalOpen(false);
2319
- const fullWidthPanelStyle = fullWidth
2320
- ? {
2321
- style: {
2322
- flex: 1,
2323
- },
2324
- }
2325
- : {};
2326
- const fullWidthBodyStyle = fullWidth
2327
- ? {
2328
- style: {
2329
- display: activeQuickStartID ? 'none' : 'flex',
2330
- },
2331
- }
2332
- : {};
2333
- const panelContent = (React.createElement(QuickStartPanelContent, Object.assign({ quickStarts: combinedQuickStarts, handleClose: handleClose, activeQuickStartID: activeQuickStartID, appendTo: appendTo, isResizable: !fullWidth, headerVariant: useLegacyHeaderColors ? '' : 'blue-white' }, fullWidthPanelStyle)));
2334
- return (React.createElement(React.Fragment, null,
2335
- React.createElement(Drawer, Object.assign({ isExpanded: !!activeQuickStartID, isInline: true }, props), children ? (React.createElement(DrawerContent, Object.assign({ panelContent: panelContent }, fullWidthBodyStyle),
2336
- React.createElement(DrawerContentBody, { className: "pfext-quick-start-drawer__body" }, children))) : (React.createElement("div", { className: "pf-v5-c-drawer__main" }, panelContent))),
2337
- React.createElement(QuickStartCloseModal, { isOpen: modalOpen, onConfirm: onModalConfirm, onCancel: onModalCancel })));
2338
- };
2339
-
2340
- const HelpTopicContextDefaults = {
2341
- helpTopics: [],
2342
- setHelpTopics: () => { },
2343
- activeHelpTopic: null,
2344
- setActiveHelpTopicByName: () => { },
2345
- filteredHelpTopics: [],
2346
- setFilteredHelpTopics: () => { },
2347
- loading: false,
2348
- };
2349
- const HelpTopicContext = React__default.createContext(HelpTopicContextDefaults);
2350
- const useValuesForHelpTopicContext = (value = {}) => {
2351
- const combinedValue = Object.assign(Object.assign({}, HelpTopicContextDefaults), value);
2352
- const [loading, setLoading] = React__default.useState(combinedValue.loading);
2353
- // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
2354
- const [helpTopics, setHelpTopics] = React__default.useState(combinedValue.helpTopics || []);
2355
- const [activeHelpTopic, setActiveHelpTopic] = React__default.useState(combinedValue.activeHelpTopic || null);
2356
- const setActiveHelpTopicByName = React__default.useCallback((helpTopicName) => {
2357
- const topic = helpTopics.find((t) => t.name === helpTopicName);
2358
- if (!helpTopicName) {
2359
- setActiveHelpTopic(null);
2360
- return;
2361
- }
2362
- setActiveHelpTopic(topic);
2363
- }, [helpTopics]);
2364
- const [filteredHelpTopics, setFilteredHelpTopics] = React__default.useState(combinedValue.filteredHelpTopics || []);
2365
- return {
2366
- helpTopics,
2367
- setHelpTopics,
2368
- activeHelpTopic,
2369
- setActiveHelpTopicByName,
2370
- filteredHelpTopics,
2371
- setFilteredHelpTopics,
2372
- loading,
2373
- setLoading,
2374
- };
2375
- };
2376
-
2377
- const HelpTopicPanelContent = (_a) => {
2378
- var _b, _c;
2379
- var { activeHelpTopic = null, filteredHelpTopics = [], isResizable = true, onClose } = _a, props = __rest(_a, ["activeHelpTopic", "filteredHelpTopics", "isResizable", "onClose"]);
2380
- const { setActiveHelpTopicByName } = React.useContext(HelpTopicContext);
2381
- const [isHelpTopicMenuOpen, setIsHelpTopicMenuOpen] = React.useState(false);
2382
- const toggleHelpTopicMenu = () => {
2383
- setIsHelpTopicMenuOpen(!isHelpTopicMenuOpen);
2384
- };
2385
- const onSelectHelpTopic = (_event, value) => {
2386
- const topicName = value;
2387
- setActiveHelpTopicByName(topicName.toString());
2388
- toggleHelpTopicMenu();
2389
- };
2390
- const helpTopicOptions = filteredHelpTopics.length > 1 &&
2391
- filteredHelpTopics.map((topic) => (React.createElement(SelectOption, { key: topic.name, value: topic.name }, topic.title)));
2392
- const paddingContainer = (children) => React.createElement("div", { style: { padding: '24px' } }, children);
2393
- const panelBodyItems = (React.createElement(React.Fragment, null,
2394
- paddingContainer(React.createElement(QuickStartMarkdownView, { content: activeHelpTopic === null || activeHelpTopic === void 0 ? void 0 : activeHelpTopic.content })),
2395
- !!((_b = activeHelpTopic === null || activeHelpTopic === void 0 ? void 0 : activeHelpTopic.links) === null || _b === void 0 ? void 0 : _b.length) && React.createElement(Divider, null),
2396
- paddingContainer(React.createElement(Stack, { hasGutter: true }, (_c = activeHelpTopic === null || activeHelpTopic === void 0 ? void 0 : activeHelpTopic.links) === null || _c === void 0 ? void 0 : _c.map(({ href, text, newTab, isExternal }, index) => (React.createElement(StackItem, { key: index },
2397
- React.createElement(Button, { component: "a", href: href, target: newTab ? '_blank' : '', rel: "noopener noreferrer", variant: "link", "aria-label": `Open documentation in new window`, isInline: true, icon: isExternal ? React.createElement(ExternalLinkAltIcon, null) : null, iconPosition: "right", style: { fontSize: 'inherit' } }, text || href))))))));
2398
- const content = (React.createElement(DrawerPanelContent, Object.assign({ isResizable: isResizable, className: "pfext-quick-start__base" }, props),
2399
- React.createElement("div", null,
2400
- React.createElement(DrawerHead, null,
2401
- React.createElement("div", { className: "pfext-quick-start-panel-content__title" },
2402
- helpTopicOptions && (React.createElement(Select, { isPlain: true, id: "help-topics-select", selected: activeHelpTopic, isOpen: isHelpTopicMenuOpen, onSelect: onSelectHelpTopic, onOpenChange: (isOpen) => setIsHelpTopicMenuOpen(isOpen), toggle: (toggleRef) => (React.createElement(MenuToggle, { isFullWidth: true, ref: toggleRef, icon: React.createElement(BarsIcon, null), onClick: toggleHelpTopicMenu, isExpanded: isHelpTopicMenuOpen }, activeHelpTopic === null || activeHelpTopic === void 0 ? void 0 : activeHelpTopic.title)) },
2403
- React.createElement(SelectList, null, helpTopicOptions))),
2404
- React.createElement(Title, { headingLevel: "h1", size: "xl", className: "pfext-quick-start-panel-content__name", style: { marginRight: 'var(--pf-v5-global--spacer--md)' } }, activeHelpTopic === null || activeHelpTopic === void 0 ? void 0 : activeHelpTopic.title)),
2405
- React.createElement(DrawerActions, null,
2406
- React.createElement(DrawerCloseButton, { onClick: onClose, className: "pfext-quick-start-panel-content__close-button", "data-testid": "qs-drawer-close" }))),
2407
- React.createElement(Divider, null),
2408
- React.createElement(DrawerPanelBody, { hasNoPadding: true, className: "pfext-quick-start-panel-content__body", "data-test": "content" }, panelBodyItems))));
2409
- return content;
2410
- };
2411
-
2412
- const HelpTopicContainer = (_a) => {
2413
- var { helpTopics, children, resourceBundle, language, loading = false, markdown, contextProps } = _a, props = __rest(_a, ["helpTopics", "children", "resourceBundle", "language", "loading", "markdown", "contextProps"]);
2414
- const valuesForHelpTopicContext = useValuesForHelpTopicContext(Object.assign({ helpTopics,
2415
- language, resourceBundle: Object.assign({}, resourceBundle), loading,
2416
- markdown }, contextProps));
2417
- React.useEffect(() => {
2418
- if (loading !== valuesForHelpTopicContext.loading) {
2419
- valuesForHelpTopicContext.setLoading(loading);
2420
- }
2421
- }, [loading, valuesForHelpTopicContext]);
2422
- React.useEffect(() => {
2423
- if (helpTopics &&
2424
- JSON.stringify(helpTopics) !== JSON.stringify(valuesForHelpTopicContext.helpTopics)) {
2425
- valuesForHelpTopicContext.setHelpTopics(helpTopics);
2426
- }
2427
- }, [helpTopics, valuesForHelpTopicContext]);
2428
- return (React.createElement(HelpTopicContext.Provider, { value: valuesForHelpTopicContext },
2429
- React.createElement(HelpTopicDrawer, Object.assign({}, props), children)));
2430
- };
2431
- const HelpTopicDrawer = (_a) => {
2432
- var { children } = _a, props = __rest(_a, ["children"]);
2433
- const { activeHelpTopic, filteredHelpTopics, setActiveHelpTopicByName } = React.useContext(HelpTopicContext);
2434
- const onClose = () => {
2435
- setActiveHelpTopicByName('');
2436
- };
2437
- const panelContent = (React.createElement(HelpTopicPanelContent, { activeHelpTopic: activeHelpTopic, filteredHelpTopics: filteredHelpTopics, onClose: onClose }));
2438
- return (React.createElement(React.Fragment, null,
2439
- React.createElement(Drawer, Object.assign({ isExpanded: !!activeHelpTopic, isInline: true }, props), children ? (React.createElement(DrawerContent, { panelContent: panelContent },
2440
- React.createElement(DrawerContentBody, { className: "pfext-quick-start-drawer__body" }, children))) : (React.createElement("div", { className: "pf-v5-c-drawer__main" }, panelContent)))));
2441
- };
2442
-
2443
- const useLocalStorage = (key, initialValue) => {
2444
- // State to store our value
2445
- // Pass initial state function to useState so logic is only executed once
2446
- const [storedValue, setStoredValue] = useState(() => {
2447
- try {
2448
- // Get from local storage by key
2449
- const item = window.localStorage.getItem(key);
2450
- // Parse stored json or if none return initialValue
2451
- return item ? JSON.parse(item) : initialValue;
2452
- }
2453
- catch (error) {
2454
- // If error also return initialValue
2455
- // eslint-disable-next-line no-console
2456
- console.log(error);
2457
- return initialValue;
2458
- }
2459
- });
2460
- // Return a wrapped version of useState's setter function that ...
2461
- // ... persists the new value to localStorage.
2462
- const setValue = (value) => {
2463
- try {
2464
- // Allow value to be a function so we have same API as useState
2465
- const valueToStore = value instanceof Function ? value(storedValue) : value;
2466
- // Save state
2467
- setStoredValue(valueToStore);
2468
- // Save to local storage
2469
- window.localStorage.setItem(key, JSON.stringify(valueToStore));
2470
- }
2471
- catch (error) {
2472
- // A more advanced implementation would handle the error case
2473
- // eslint-disable-next-line no-console
2474
- console.log(error);
2475
- }
2476
- };
2477
- return [storedValue, setValue];
2478
- };
2479
-
2480
- /* eslint-disable */
2481
- // Brought in from dev to publish this with QS module
2482
- // Dev now imports from here
2483
- const ProcQuickStartParser = (quickStart, environmentVariables) => {
2484
- var _a;
2485
- const replaceEnvironmentVariables = (s) => s === null || s === void 0 ? void 0 : s.replace(/\${(\w+)}/, (substring, name) => {
2486
- return environmentVariables ? ([name] ? environmentVariables[name] : substring) : substring;
2487
- });
2488
- quickStart.spec.tasks = (_a = quickStart.spec.tasks) === null || _a === void 0 ? void 0 : _a.map((task, index) => {
2489
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
2490
- let proc;
2491
- let answer;
2492
- if (typeof task === 'string') {
2493
- proc = task;
2494
- answer = {};
2495
- }
2496
- else {
2497
- proc = task.proc;
2498
- answer = task;
2499
- delete task.proc;
2500
- }
2501
- let description = '', procedure, verification, title, summaryFailed, success, reviewFailed, prerequisites;
2502
- if (proc) {
2503
- const taskDOM = document.createElement('div');
2504
- taskDOM.innerHTML = proc;
2505
- // remove the screencapture images
2506
- taskDOM.querySelectorAll('.imageblock.screencapture').forEach((node) => {
2507
- var _a;
2508
- (_a = node.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(node);
2509
- });
2510
- title = (_a = taskDOM
2511
- .querySelector('h1:first-child,h2:first-child,h3:first-child,h4:first-child,h5:first-child')) === null || _a === void 0 ? void 0 : _a.innerHTML.trim();
2512
- let sectionBody = taskDOM.querySelector('.sectionbody');
2513
- if (!(sectionBody === null || sectionBody === void 0 ? void 0 : sectionBody.hasChildNodes())) {
2514
- // possibly in other templates, where we want to look for article
2515
- sectionBody = taskDOM.querySelector('article');
2516
- }
2517
- if (sectionBody) {
2518
- for (let i = 0; i < sectionBody.children.length || 0; i++) {
2519
- /**
2520
- child typically looks like:
2101
+ const QuickStartFooter = ({ status, taskNumber, totalTasks, onNext, onBack, footerClass, quickStartId, }) => {
2102
+ const { restartQuickStart, getResource } = React.useContext(QuickStartContext);
2103
+ const PrimaryButtonText = React.useMemo(() => ({
2104
+ START: getResource('Start'),
2105
+ CONTINUE: getResource('Continue'),
2106
+ NEXT: getResource('Next'),
2107
+ CLOSE: getResource('Close'),
2108
+ }), [getResource]);
2109
+ const SecondaryButtonText = React.useMemo(() => ({
2110
+ BACK: getResource('Back'),
2111
+ RESTART: getResource('Restart'),
2112
+ }), [getResource]);
2113
+ const onRestart = React.useCallback((e) => {
2114
+ e.preventDefault();
2115
+ e.stopPropagation();
2116
+ restartQuickStart(quickStartId, totalTasks);
2117
+ }, [quickStartId, restartQuickStart, totalTasks]);
2118
+ const getPrimaryButtonText = React.useMemo(() => {
2119
+ if (status === QuickStartStatus.NOT_STARTED) {
2120
+ return PrimaryButtonText.START;
2121
+ }
2122
+ if (taskNumber === totalTasks) {
2123
+ return PrimaryButtonText.CLOSE;
2124
+ }
2125
+ if (taskNumber > -1 && taskNumber < totalTasks) {
2126
+ return PrimaryButtonText.NEXT;
2127
+ }
2128
+ return PrimaryButtonText.CONTINUE;
2129
+ }, [taskNumber, totalTasks, PrimaryButtonText, status]);
2130
+ const getPrimaryButton = React.useMemo(() => (React.createElement(Button, { variant: "primary", className: "pfext-quick-start-footer__actionbtn", onClick: onNext, "data-testid": `qs-drawer-${camelize(getPrimaryButtonText)}`, "data-test": `${getPrimaryButtonText} button` }, getPrimaryButtonText)), [getPrimaryButtonText, onNext]);
2131
+ const getSecondaryButton = React.useMemo(() => taskNumber === -1 && status !== QuickStartStatus.NOT_STARTED ? (React.createElement(Button, { variant: "secondary", onClick: onRestart, "data-testid": "qs-drawer-restart" }, SecondaryButtonText.RESTART)) : (taskNumber > -1 && (React.createElement(Button, { variant: "secondary", onClick: onBack, "data-testid": "qs-drawer-back" }, SecondaryButtonText.BACK))), [onRestart, onBack, SecondaryButtonText, status, taskNumber]);
2132
+ const getSideNoteAction = React.useMemo(() => taskNumber !== -1 && (React.createElement(Button, { variant: "link", className: "pfext-quick-start-footer__restartbtn", onClick: onRestart, "data-testid": "qs-drawer-side-note-action" }, SecondaryButtonText.RESTART)), [taskNumber, onRestart, SecondaryButtonText.RESTART]);
2133
+ return (React.createElement("div", { className: `pfext-quick-start-footer ${footerClass}` },
2134
+ getPrimaryButton,
2135
+ getSecondaryButton,
2136
+ getSideNoteAction));
2137
+ };
2138
+
2139
+ const QuickStartController = ({ quickStart, nextQuickStarts, contentRef, footerClass, }) => {
2140
+ const { metadata: { name }, spec: { tasks = [] }, } = quickStart;
2141
+ const totalTasks = tasks === null || tasks === void 0 ? void 0 : tasks.length;
2142
+ const { activeQuickStartState, setActiveQuickStart, setQuickStartTaskNumber, setQuickStartTaskStatus, nextStep, previousStep, } = React.useContext(QuickStartContext);
2143
+ const status = activeQuickStartState === null || activeQuickStartState === void 0 ? void 0 : activeQuickStartState.status;
2144
+ const taskNumber = activeQuickStartState === null || activeQuickStartState === void 0 ? void 0 : activeQuickStartState.taskNumber;
2145
+ const allTaskStatuses = tasks.map((task, index) => activeQuickStartState[`taskStatus${index}`]);
2146
+ const handleQuickStartChange = React.useCallback((quickStartId) => setActiveQuickStart(quickStartId), [setActiveQuickStart]);
2147
+ const handleTaskStatusChange = React.useCallback((newTaskStatus) => setQuickStartTaskStatus(newTaskStatus), [setQuickStartTaskStatus]);
2148
+ const getQuickStartActiveTask = React.useCallback(() => {
2149
+ let activeTaskNumber = 0;
2150
+ while (activeTaskNumber !== totalTasks &&
2151
+ activeQuickStartState[`taskStatus${activeTaskNumber}`] !== QuickStartTaskStatus.INIT) {
2152
+ activeTaskNumber++;
2153
+ }
2154
+ return activeTaskNumber;
2155
+ }, [totalTasks, activeQuickStartState]);
2156
+ const handleQuickStartContinue = React.useCallback(() => {
2157
+ const activeTaskNumber = getQuickStartActiveTask();
2158
+ setQuickStartTaskNumber(name, activeTaskNumber);
2159
+ }, [getQuickStartActiveTask, setQuickStartTaskNumber, name]);
2160
+ const handleNext = React.useCallback(() => {
2161
+ if (status === QuickStartStatus.COMPLETE && taskNumber === totalTasks) {
2162
+ return handleQuickStartChange('');
2163
+ }
2164
+ if (status !== QuickStartStatus.NOT_STARTED && taskNumber === -1) {
2165
+ return handleQuickStartContinue();
2166
+ }
2167
+ return nextStep(totalTasks);
2168
+ }, [handleQuickStartChange, nextStep, status, taskNumber, totalTasks, handleQuickStartContinue]);
2169
+ const handleBack = React.useCallback(() => previousStep(), [previousStep]);
2170
+ const handleTaskSelect = React.useCallback((selectedTaskNumber) => {
2171
+ setQuickStartTaskNumber(name, selectedTaskNumber);
2172
+ }, [name, setQuickStartTaskNumber]);
2173
+ return (React.createElement(React.Fragment, null,
2174
+ React.createElement(QuickStartContent, { quickStart: quickStart, nextQuickStarts: nextQuickStarts, taskNumber: taskNumber, allTaskStatuses: allTaskStatuses, onTaskSelect: handleTaskSelect, onTaskReview: handleTaskStatusChange, onQuickStartChange: handleQuickStartChange, ref: contentRef }),
2175
+ React.createElement(QuickStartFooter, { status: status, taskNumber: taskNumber, totalTasks: totalTasks, onNext: handleNext, onBack: handleBack, footerClass: footerClass, quickStartId: quickStart.metadata.name })));
2176
+ };
2177
+
2178
+ const getElement = (appendTo) => {
2179
+ if (typeof appendTo === 'function') {
2180
+ return appendTo();
2181
+ }
2182
+ return appendTo;
2183
+ };
2184
+ const useScrollTopOnTaskNumberChange = (node, taskNumber) => {
2185
+ React.useEffect(() => {
2186
+ if (node) {
2187
+ node.scrollTo({ top: 0, behavior: 'smooth' });
2188
+ }
2189
+ }, [taskNumber, node]);
2190
+ };
2191
+ const QuickStartPanelContent = (_a) => {
2192
+ var { quickStarts = [], handleClose, activeQuickStartID, appendTo, isResizable = true, showClose = true, headerVariant = '' } = _a, props = __rest(_a, ["quickStarts", "handleClose", "activeQuickStartID", "appendTo", "isResizable", "showClose", "headerVariant"]);
2193
+ const titleRef = React.useRef(null);
2194
+ const { getResource, activeQuickStartState } = React.useContext(QuickStartContext);
2195
+ const [contentRef, setContentRef] = React.useState();
2196
+ const shadows = useScrollShadows(contentRef);
2197
+ const quickStart = quickStarts.find((qs) => qs.metadata.name === activeQuickStartID);
2198
+ const taskNumber = activeQuickStartState === null || activeQuickStartState === void 0 ? void 0 : activeQuickStartState.taskNumber;
2199
+ useScrollTopOnTaskNumberChange(contentRef, taskNumber);
2200
+ const nextQuickStarts = quickStarts.filter((qs) => { var _a; return (_a = quickStart === null || quickStart === void 0 ? void 0 : quickStart.spec.nextQuickStart) === null || _a === void 0 ? void 0 : _a.includes(qs.metadata.name); });
2201
+ const headerClasses = css('pfext-quick-start-panel-content__header', {
2202
+ 'pfext-quick-start-panel-content__header__shadow': shadows === Shadows.top || shadows === Shadows.both,
2203
+ 'pfext-quick-start-panel-content__header--blue-white': headerVariant === 'blue-white',
2204
+ });
2205
+ const footerClass = css({
2206
+ 'pfext-quick-start-panel-content__footer__shadow': shadows === Shadows.bottom || shadows === Shadows.both,
2207
+ });
2208
+ const getStep = () => {
2209
+ const tasks = quickStart.spec.tasks.length;
2210
+ if (Number.parseInt(taskNumber) === -1) {
2211
+ return 'intro';
2212
+ }
2213
+ if (Number.parseInt(taskNumber) === tasks) {
2214
+ return 'conclusion';
2215
+ }
2216
+ return Number.parseInt(taskNumber) + 1;
2217
+ };
2218
+ React.useEffect(() => {
2219
+ if (quickStart) {
2220
+ titleRef.current.focus();
2221
+ }
2222
+ }, [quickStart]);
2223
+ const content = quickStart ? (React.createElement(DrawerPanelContent, Object.assign({ isResizable: isResizable, className: "pfext-quick-start__base", "data-testid": `qs-drawer-${camelize(quickStart.spec.displayName)}`, "data-qs": `qs-step-${getStep()}`, "data-test": "quickstart drawer" }, props),
2224
+ React.createElement("div", { className: headerClasses },
2225
+ React.createElement(DrawerHead, null,
2226
+ React.createElement("div", { className: "pfext-quick-start-panel-content__title", tabIndex: -1, ref: titleRef },
2227
+ React.createElement(Title, { headingLevel: "h2", size: "xl", className: "pfext-quick-start-panel-content__name", style: { marginRight: 'var(--pf-v5-global--spacer--md)' } },
2228
+ React.createElement("span", { dangerouslySetInnerHTML: {
2229
+ __html: removeParagraphWrap(markdownConvert(quickStart === null || quickStart === void 0 ? void 0 : quickStart.spec.displayName)),
2230
+ } }),
2231
+ ' ',
2232
+ React.createElement("small", { className: "pfext-quick-start-panel-content__duration" }, (quickStart === null || quickStart === void 0 ? void 0 : quickStart.spec.durationMinutes)
2233
+ ? getResource('{{type}} • {{duration, number}} minutes', quickStart === null || quickStart === void 0 ? void 0 : quickStart.spec.durationMinutes)
2234
+ .replace('{{duration, number}}', quickStart === null || quickStart === void 0 ? void 0 : quickStart.spec.durationMinutes)
2235
+ .replace('{{type}}', getResource('Type'))
2236
+ : getResource('Type')))),
2237
+ showClose && (React.createElement(DrawerActions, null,
2238
+ React.createElement(DrawerCloseButton, { onClick: handleClose, className: "pfext-quick-start-panel-content__close-button", "data-testid": "qs-drawer-close" }))))),
2239
+ React.createElement(DrawerPanelBody, { hasNoPadding: true, className: "pfext-quick-start-panel-content__body", "data-test": "content" },
2240
+ React.createElement(QuickStartController, { quickStart: quickStart, nextQuickStarts: nextQuickStarts, footerClass: footerClass, contentRef: setContentRef })))) : null;
2241
+ if (appendTo) {
2242
+ return ReactDOM.createPortal(content, getElement(appendTo));
2243
+ }
2244
+ return content;
2245
+ };
2246
+
2247
+ const QuickStartContainer = (_a) => {
2248
+ var { quickStarts, children, activeQuickStartID, allQuickStartStates, setActiveQuickStartID, setAllQuickStartStates, appendTo, fullWidth, onCloseInProgress, onCloseNotInProgress, resourceBundle, showCardFooters, useLegacyHeaderColors, language, loading = false, useQueryParams = true, markdown, contextProps, alwaysShowTaskReview = true } = _a, props = __rest(_a, ["quickStarts", "children", "activeQuickStartID", "allQuickStartStates", "setActiveQuickStartID", "setAllQuickStartStates", "appendTo", "fullWidth", "onCloseInProgress", "onCloseNotInProgress", "resourceBundle", "showCardFooters", "useLegacyHeaderColors", "language", "loading", "useQueryParams", "markdown", "contextProps", "alwaysShowTaskReview"]);
2249
+ const valuesForQuickstartContext = useValuesForQuickStartContext(Object.assign({ allQuickStarts: quickStarts, activeQuickStartID,
2250
+ setActiveQuickStartID,
2251
+ allQuickStartStates,
2252
+ setAllQuickStartStates, footer: {
2253
+ show: showCardFooters,
2254
+ }, useLegacyHeaderColors,
2255
+ language, resourceBundle: Object.assign({}, resourceBundle), loading,
2256
+ useQueryParams,
2257
+ markdown,
2258
+ alwaysShowTaskReview }, contextProps));
2259
+ React.useEffect(() => {
2260
+ if (quickStarts &&
2261
+ JSON.stringify(quickStarts) !== JSON.stringify(valuesForQuickstartContext.allQuickStarts)) {
2262
+ valuesForQuickstartContext.setAllQuickStarts(quickStarts);
2263
+ }
2264
+ }, [quickStarts, valuesForQuickstartContext]);
2265
+ React.useEffect(() => {
2266
+ if (loading !== valuesForQuickstartContext.loading) {
2267
+ valuesForQuickstartContext.setLoading(loading);
2268
+ }
2269
+ }, [loading, valuesForQuickstartContext]);
2270
+ const drawerProps = Object.assign({ appendTo,
2271
+ fullWidth,
2272
+ onCloseInProgress,
2273
+ onCloseNotInProgress }, props);
2274
+ return (React.createElement(QuickStartContext.Provider, { value: valuesForQuickstartContext },
2275
+ React.createElement(QuickStartDrawer, Object.assign({}, drawerProps), children)));
2276
+ };
2277
+ const QuickStartDrawer = (_a) => {
2278
+ var { quickStarts = [], children, appendTo, fullWidth, onCloseInProgress, onCloseNotInProgress } = _a, props = __rest(_a, ["quickStarts", "children", "appendTo", "fullWidth", "onCloseInProgress", "onCloseNotInProgress"]);
2279
+ const { activeQuickStartID, setActiveQuickStart, allQuickStarts = [], activeQuickStartState, allQuickStartStates, setAllQuickStartStates, useLegacyHeaderColors, } = React.useContext(QuickStartContext);
2280
+ const combinedQuickStarts = allQuickStarts.concat(quickStarts);
2281
+ React.useEffect(() => {
2282
+ const params = new URLSearchParams(window.location.search);
2283
+ // if there is a quick start param, but the quick start is not active, set it
2284
+ // this can happen if a new browser session is opened or an incognito window for example
2285
+ const quickStartIdFromParam = params.get(QUICKSTART_ID_FILTER_KEY) || '';
2286
+ if (quickStartIdFromParam && activeQuickStartID !== quickStartIdFromParam) {
2287
+ const activeQuickStart = getQuickStartByName(quickStartIdFromParam, combinedQuickStarts);
2288
+ // don't try to load a quick start that is actually just an external resource (spec.link)
2289
+ if (combinedQuickStarts.length > 0 && activeQuickStart && !activeQuickStart.spec.link) {
2290
+ setActiveQuickStart(quickStartIdFromParam);
2291
+ }
2292
+ }
2293
+ }, [activeQuickStartID, combinedQuickStarts, setActiveQuickStart]);
2294
+ React.useEffect(() => {
2295
+ // If activeQuickStartID was changed through prop from QuickStartContainer, need to init the state if it does not exist yet
2296
+ if (activeQuickStartID && !allQuickStartStates[activeQuickStartID]) {
2297
+ setAllQuickStartStates(Object.assign(Object.assign({}, allQuickStartStates), { [activeQuickStartID]: getDefaultQuickStartState() }));
2298
+ }
2299
+ }, [activeQuickStartID, allQuickStartStates, setAllQuickStartStates]);
2300
+ const [modalOpen, setModalOpen] = React.useState(false);
2301
+ const activeQuickStartStatus = activeQuickStartState === null || activeQuickStartState === void 0 ? void 0 : activeQuickStartState.status;
2302
+ const onClose = () => setActiveQuickStart('');
2303
+ const handleClose = () => {
2304
+ if (activeQuickStartStatus === QuickStartStatus.IN_PROGRESS) {
2305
+ if (onCloseInProgress) {
2306
+ onCloseInProgress();
2307
+ }
2308
+ else {
2309
+ setModalOpen(true);
2310
+ }
2311
+ }
2312
+ else if (onCloseNotInProgress) {
2313
+ onCloseNotInProgress();
2314
+ }
2315
+ else {
2316
+ onClose();
2317
+ }
2318
+ };
2319
+ const onModalConfirm = () => {
2320
+ setModalOpen(false);
2321
+ onClose();
2322
+ };
2323
+ const onModalCancel = () => setModalOpen(false);
2324
+ const fullWidthPanelStyle = fullWidth
2325
+ ? {
2326
+ style: {
2327
+ flex: 1,
2328
+ },
2329
+ }
2330
+ : {};
2331
+ const fullWidthBodyStyle = fullWidth
2332
+ ? {
2333
+ style: {
2334
+ display: activeQuickStartID ? 'none' : 'flex',
2335
+ },
2336
+ }
2337
+ : {};
2338
+ const panelContent = (React.createElement(QuickStartPanelContent, Object.assign({ quickStarts: combinedQuickStarts, handleClose: handleClose, activeQuickStartID: activeQuickStartID, appendTo: appendTo, isResizable: !fullWidth, headerVariant: useLegacyHeaderColors ? '' : 'blue-white' }, fullWidthPanelStyle)));
2339
+ return (React.createElement(React.Fragment, null,
2340
+ React.createElement(Drawer, Object.assign({ isExpanded: !!activeQuickStartID, isInline: true }, props), children ? (React.createElement(DrawerContent, Object.assign({ panelContent: panelContent }, fullWidthBodyStyle),
2341
+ React.createElement(DrawerContentBody, { className: "pfext-quick-start-drawer__body" }, children))) : (React.createElement("div", { className: "pf-v5-c-drawer__main" }, panelContent))),
2342
+ React.createElement(QuickStartCloseModal, { isOpen: modalOpen, onConfirm: onModalConfirm, onCancel: onModalCancel })));
2343
+ };
2344
+
2345
+ const HelpTopicContextDefaults = {
2346
+ helpTopics: [],
2347
+ setHelpTopics: () => { },
2348
+ activeHelpTopic: null,
2349
+ setActiveHelpTopicByName: () => { },
2350
+ filteredHelpTopics: [],
2351
+ setFilteredHelpTopics: () => { },
2352
+ loading: false,
2353
+ };
2354
+ const HelpTopicContext = React__default.createContext(HelpTopicContextDefaults);
2355
+ const useValuesForHelpTopicContext = (value = {}) => {
2356
+ const combinedValue = Object.assign(Object.assign({}, HelpTopicContextDefaults), value);
2357
+ const [loading, setLoading] = React__default.useState(combinedValue.loading);
2358
+ // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
2359
+ const [helpTopics, setHelpTopics] = React__default.useState(combinedValue.helpTopics || []);
2360
+ const [activeHelpTopic, setActiveHelpTopic] = React__default.useState(combinedValue.activeHelpTopic || null);
2361
+ const setActiveHelpTopicByName = React__default.useCallback((helpTopicName) => {
2362
+ const topic = helpTopics.find((t) => t.name === helpTopicName);
2363
+ if (!helpTopicName) {
2364
+ setActiveHelpTopic(null);
2365
+ return;
2366
+ }
2367
+ setActiveHelpTopic(topic);
2368
+ }, [helpTopics]);
2369
+ const [filteredHelpTopics, setFilteredHelpTopics] = React__default.useState(combinedValue.filteredHelpTopics || []);
2370
+ return {
2371
+ helpTopics,
2372
+ setHelpTopics,
2373
+ activeHelpTopic,
2374
+ setActiveHelpTopicByName,
2375
+ filteredHelpTopics,
2376
+ setFilteredHelpTopics,
2377
+ loading,
2378
+ setLoading,
2379
+ };
2380
+ };
2381
+
2382
+ const HelpTopicPanelContent = (_a) => {
2383
+ var _b, _c;
2384
+ var { activeHelpTopic = null, filteredHelpTopics = [], isResizable = true, onClose } = _a, props = __rest(_a, ["activeHelpTopic", "filteredHelpTopics", "isResizable", "onClose"]);
2385
+ const { setActiveHelpTopicByName } = React.useContext(HelpTopicContext);
2386
+ const [isHelpTopicMenuOpen, setIsHelpTopicMenuOpen] = React.useState(false);
2387
+ const toggleHelpTopicMenu = () => {
2388
+ setIsHelpTopicMenuOpen(!isHelpTopicMenuOpen);
2389
+ };
2390
+ const onSelectHelpTopic = (_event, value) => {
2391
+ const topicName = value;
2392
+ setActiveHelpTopicByName(topicName.toString());
2393
+ toggleHelpTopicMenu();
2394
+ };
2395
+ const helpTopicOptions = filteredHelpTopics.length > 1 &&
2396
+ filteredHelpTopics.map((topic) => (React.createElement(SelectOption, { key: topic.name, value: topic.name }, topic.title)));
2397
+ const paddingContainer = (children) => React.createElement("div", { style: { padding: '24px' } }, children);
2398
+ const panelBodyItems = (React.createElement(React.Fragment, null,
2399
+ paddingContainer(React.createElement(QuickStartMarkdownView, { content: activeHelpTopic === null || activeHelpTopic === void 0 ? void 0 : activeHelpTopic.content })),
2400
+ !!((_b = activeHelpTopic === null || activeHelpTopic === void 0 ? void 0 : activeHelpTopic.links) === null || _b === void 0 ? void 0 : _b.length) && React.createElement(Divider, null),
2401
+ paddingContainer(React.createElement(Stack, { hasGutter: true }, (_c = activeHelpTopic === null || activeHelpTopic === void 0 ? void 0 : activeHelpTopic.links) === null || _c === void 0 ? void 0 : _c.map(({ href, text, newTab, isExternal }, index) => (React.createElement(StackItem, { key: index },
2402
+ React.createElement(Button, { component: "a", href: href, target: newTab ? '_blank' : '', rel: "noopener noreferrer", variant: "link", "aria-label": `Open documentation in new window`, isInline: true, icon: isExternal ? React.createElement(ExternalLinkAltIcon, null) : null, iconPosition: "right", style: { fontSize: 'inherit' } }, text || href))))))));
2403
+ const content = (React.createElement(DrawerPanelContent, Object.assign({ isResizable: isResizable, className: "pfext-quick-start__base" }, props),
2404
+ React.createElement("div", null,
2405
+ React.createElement(DrawerHead, null,
2406
+ React.createElement("div", { className: "pfext-quick-start-panel-content__title" },
2407
+ helpTopicOptions && (React.createElement(Select, { isPlain: true, id: "help-topics-select", selected: activeHelpTopic, isOpen: isHelpTopicMenuOpen, onSelect: onSelectHelpTopic, onOpenChange: (isOpen) => setIsHelpTopicMenuOpen(isOpen), toggle: (toggleRef) => (React.createElement(MenuToggle, { isFullWidth: true, ref: toggleRef, icon: React.createElement(BarsIcon, null), onClick: toggleHelpTopicMenu, isExpanded: isHelpTopicMenuOpen }, activeHelpTopic === null || activeHelpTopic === void 0 ? void 0 : activeHelpTopic.title)) },
2408
+ React.createElement(SelectList, null, helpTopicOptions))),
2409
+ React.createElement(Title, { headingLevel: "h1", size: "xl", className: "pfext-quick-start-panel-content__name", style: { marginRight: 'var(--pf-v5-global--spacer--md)' } }, activeHelpTopic === null || activeHelpTopic === void 0 ? void 0 : activeHelpTopic.title)),
2410
+ React.createElement(DrawerActions, null,
2411
+ React.createElement(DrawerCloseButton, { onClick: onClose, className: "pfext-quick-start-panel-content__close-button", "data-testid": "qs-drawer-close" }))),
2412
+ React.createElement(Divider, null),
2413
+ React.createElement(DrawerPanelBody, { hasNoPadding: true, className: "pfext-quick-start-panel-content__body", "data-test": "content" }, panelBodyItems))));
2414
+ return content;
2415
+ };
2416
+
2417
+ const HelpTopicContainer = (_a) => {
2418
+ var { helpTopics, children, resourceBundle, language, loading = false, markdown, contextProps } = _a, props = __rest(_a, ["helpTopics", "children", "resourceBundle", "language", "loading", "markdown", "contextProps"]);
2419
+ const valuesForHelpTopicContext = useValuesForHelpTopicContext(Object.assign({ helpTopics,
2420
+ language, resourceBundle: Object.assign({}, resourceBundle), loading,
2421
+ markdown }, contextProps));
2422
+ React.useEffect(() => {
2423
+ if (loading !== valuesForHelpTopicContext.loading) {
2424
+ valuesForHelpTopicContext.setLoading(loading);
2425
+ }
2426
+ }, [loading, valuesForHelpTopicContext]);
2427
+ React.useEffect(() => {
2428
+ if (helpTopics &&
2429
+ JSON.stringify(helpTopics) !== JSON.stringify(valuesForHelpTopicContext.helpTopics)) {
2430
+ valuesForHelpTopicContext.setHelpTopics(helpTopics);
2431
+ }
2432
+ }, [helpTopics, valuesForHelpTopicContext]);
2433
+ return (React.createElement(HelpTopicContext.Provider, { value: valuesForHelpTopicContext },
2434
+ React.createElement(HelpTopicDrawer, Object.assign({}, props), children)));
2435
+ };
2436
+ const HelpTopicDrawer = (_a) => {
2437
+ var { children } = _a, props = __rest(_a, ["children"]);
2438
+ const { activeHelpTopic, filteredHelpTopics, setActiveHelpTopicByName } = React.useContext(HelpTopicContext);
2439
+ const onClose = () => {
2440
+ setActiveHelpTopicByName('');
2441
+ };
2442
+ const panelContent = (React.createElement(HelpTopicPanelContent, { activeHelpTopic: activeHelpTopic, filteredHelpTopics: filteredHelpTopics, onClose: onClose }));
2443
+ return (React.createElement(React.Fragment, null,
2444
+ React.createElement(Drawer, Object.assign({ isExpanded: !!activeHelpTopic, isInline: true }, props), children ? (React.createElement(DrawerContent, { panelContent: panelContent },
2445
+ React.createElement(DrawerContentBody, { className: "pfext-quick-start-drawer__body" }, children))) : (React.createElement("div", { className: "pf-v5-c-drawer__main" }, panelContent)))));
2446
+ };
2447
+
2448
+ const useLocalStorage = (key, initialValue) => {
2449
+ // State to store our value
2450
+ // Pass initial state function to useState so logic is only executed once
2451
+ const [storedValue, setStoredValue] = useState(() => {
2452
+ try {
2453
+ // Get from local storage by key
2454
+ const item = window.localStorage.getItem(key);
2455
+ // Parse stored json or if none return initialValue
2456
+ return item ? JSON.parse(item) : initialValue;
2457
+ }
2458
+ catch (error) {
2459
+ // If error also return initialValue
2460
+ // eslint-disable-next-line no-console
2461
+ console.log(error);
2462
+ return initialValue;
2463
+ }
2464
+ });
2465
+ // Return a wrapped version of useState's setter function that ...
2466
+ // ... persists the new value to localStorage.
2467
+ const setValue = (value) => {
2468
+ try {
2469
+ // Allow value to be a function so we have same API as useState
2470
+ const valueToStore = value instanceof Function ? value(storedValue) : value;
2471
+ // Save state
2472
+ setStoredValue(valueToStore);
2473
+ // Save to local storage
2474
+ window.localStorage.setItem(key, JSON.stringify(valueToStore));
2475
+ }
2476
+ catch (error) {
2477
+ // A more advanced implementation would handle the error case
2478
+ // eslint-disable-next-line no-console
2479
+ console.log(error);
2480
+ }
2481
+ };
2482
+ return [storedValue, setValue];
2483
+ };
2484
+
2485
+ /* eslint-disable */
2486
+ // Brought in from dev to publish this with QS module
2487
+ // Dev now imports from here
2488
+ const ProcQuickStartParser = (quickStart, environmentVariables) => {
2489
+ var _a;
2490
+ const replaceEnvironmentVariables = (s) => s === null || s === void 0 ? void 0 : s.replace(/\${(\w+)}/, (substring, name) => {
2491
+ return environmentVariables ? ([name] ? environmentVariables[name] : substring) : substring;
2492
+ });
2493
+ quickStart.spec.tasks = (_a = quickStart.spec.tasks) === null || _a === void 0 ? void 0 : _a.map((task, index) => {
2494
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
2495
+ let proc;
2496
+ let answer;
2497
+ if (typeof task === 'string') {
2498
+ proc = task;
2499
+ answer = {};
2500
+ }
2501
+ else {
2502
+ proc = task.proc;
2503
+ answer = task;
2504
+ delete task.proc;
2505
+ }
2506
+ let description = '', procedure, verification, title, summaryFailed, success, reviewFailed, prerequisites;
2507
+ if (proc) {
2508
+ const taskDOM = document.createElement('div');
2509
+ taskDOM.innerHTML = proc;
2510
+ // remove the screencapture images
2511
+ taskDOM.querySelectorAll('.imageblock.screencapture').forEach((node) => {
2512
+ var _a;
2513
+ (_a = node.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(node);
2514
+ });
2515
+ title = (_a = taskDOM
2516
+ .querySelector('h1:first-child,h2:first-child,h3:first-child,h4:first-child,h5:first-child')) === null || _a === void 0 ? void 0 : _a.innerHTML.trim();
2517
+ let sectionBody = taskDOM.querySelector('.sectionbody');
2518
+ if (!(sectionBody === null || sectionBody === void 0 ? void 0 : sectionBody.hasChildNodes())) {
2519
+ // possibly in other templates, where we want to look for article
2520
+ sectionBody = taskDOM.querySelector('article');
2521
+ }
2522
+ if (sectionBody) {
2523
+ for (let i = 0; i < sectionBody.children.length || 0; i++) {
2524
+ /**
2525
+ child typically looks like:
2521
2526
 
2522
- <div class="paragraph|olist|ulist|admonitionblock">
2523
- <div class="title">Procedure|Prerequisites|Verification|Note|Warning</div>
2524
- <ol|ul class="arabic">
2525
- <li>
2526
- <li>...
2527
- </ol|ul>
2528
- </div>
2527
+ <div class="paragraph|olist|ulist|admonitionblock">
2528
+ <div class="title">Procedure|Prerequisites|Verification|Note|Warning</div>
2529
+ <ol|ul class="arabic">
2530
+ <li>
2531
+ <li>...
2532
+ </ol|ul>
2533
+ </div>
2529
2534
 
2530
- And the below code extracts the <ol> or <ul>
2531
- Except for when there is no <div class="title|heading"/>, then the description is extracted
2532
- in the else if below
2533
- */
2534
- const child = sectionBody.children.item(i);
2535
- // find the title
2536
- const sectionTitle = child === null || child === void 0 ? void 0 : child.querySelector('.heading,.title');
2537
- // should this section be assigned to a specific section
2538
- const sectionTitleText = (_b = sectionTitle === null || sectionTitle === void 0 ? void 0 : sectionTitle.textContent) === null || _b === void 0 ? void 0 : _b.trim();
2539
- const isKnownSection = ['Procedure', 'Verification', 'Prerequisites'].includes((_c = sectionTitle === null || sectionTitle === void 0 ? void 0 : sectionTitle.textContent) === null || _c === void 0 ? void 0 : _c.trim());
2540
- if (isKnownSection) {
2541
- switch (sectionTitleText) {
2542
- case 'Procedure':
2543
- procedure = (_d = child === null || child === void 0 ? void 0 : child.querySelector(':not(.heading):not(.title)')) === null || _d === void 0 ? void 0 : _d.outerHTML.trim();
2544
- break;
2545
- case 'Verification':
2546
- verification = (_e = child === null || child === void 0 ? void 0 : child.querySelector(':not(.heading):not(.title)')) === null || _e === void 0 ? void 0 : _e.outerHTML.trim();
2547
- break;
2548
- case 'Prerequisites':
2549
- prerequisites = (_f = child === null || child === void 0 ? void 0 : child.querySelector(':not(.heading):not(.title)')) === null || _f === void 0 ? void 0 : _f.outerHTML.trim();
2550
- break;
2551
- }
2552
- }
2553
- else if (!procedure) {
2554
- // Otherwise if it comes before a procedure it's part of the description
2555
- description = description + (child === null || child === void 0 ? void 0 : child.outerHTML.trim());
2556
- }
2557
- }
2558
- }
2559
- success = (_g = taskDOM.querySelector('.qs-summary.success')) === null || _g === void 0 ? void 0 : _g.innerHTML.trim();
2560
- reviewFailed = (_h = taskDOM.querySelector('.qs-review.failed')) === null || _h === void 0 ? void 0 : _h.innerHTML.trim();
2561
- summaryFailed = (_j = taskDOM.querySelector('.qs-summary.failed')) === null || _j === void 0 ? void 0 : _j.innerHTML.trim();
2562
- }
2563
- answer.title = replaceEnvironmentVariables(answer.title || title);
2564
- answer.description = replaceEnvironmentVariables(answer.description || `${description} ${prerequisites || ''} ${procedure}`);
2565
- answer.review = answer.review || {};
2566
- answer.review.instructions = replaceEnvironmentVariables(((_k = answer.review) === null || _k === void 0 ? void 0 : _k.instructions) || verification || 'Have you completed these steps?');
2567
- answer.review.failedTaskHelp = replaceEnvironmentVariables(answer.review.failedTaskHelp ||
2568
- reviewFailed ||
2569
- 'This task isn’t verified yet. Try the task again.');
2570
- answer.summary = answer.summary || {};
2571
- answer.summary.success = replaceEnvironmentVariables(answer.summary.success || success || 'You have completed this task!');
2572
- answer.summary.failed = replaceEnvironmentVariables(answer.summary.failed || summaryFailed || 'Try the steps again.');
2573
- return answer;
2574
- });
2575
- return quickStart;
2535
+ And the below code extracts the <ol> or <ul>
2536
+ Except for when there is no <div class="title|heading"/>, then the description is extracted
2537
+ in the else if below
2538
+ */
2539
+ const child = sectionBody.children.item(i);
2540
+ // find the title
2541
+ const sectionTitle = child === null || child === void 0 ? void 0 : child.querySelector('.heading,.title');
2542
+ // should this section be assigned to a specific section
2543
+ const sectionTitleText = (_b = sectionTitle === null || sectionTitle === void 0 ? void 0 : sectionTitle.textContent) === null || _b === void 0 ? void 0 : _b.trim();
2544
+ const isKnownSection = ['Procedure', 'Verification', 'Prerequisites'].includes((_c = sectionTitle === null || sectionTitle === void 0 ? void 0 : sectionTitle.textContent) === null || _c === void 0 ? void 0 : _c.trim());
2545
+ if (isKnownSection) {
2546
+ switch (sectionTitleText) {
2547
+ case 'Procedure':
2548
+ procedure = (_d = child === null || child === void 0 ? void 0 : child.querySelector(':not(.heading):not(.title)')) === null || _d === void 0 ? void 0 : _d.outerHTML.trim();
2549
+ break;
2550
+ case 'Verification':
2551
+ verification = (_e = child === null || child === void 0 ? void 0 : child.querySelector(':not(.heading):not(.title)')) === null || _e === void 0 ? void 0 : _e.outerHTML.trim();
2552
+ break;
2553
+ case 'Prerequisites':
2554
+ prerequisites = (_f = child === null || child === void 0 ? void 0 : child.querySelector(':not(.heading):not(.title)')) === null || _f === void 0 ? void 0 : _f.outerHTML.trim();
2555
+ break;
2556
+ }
2557
+ }
2558
+ else if (!procedure) {
2559
+ // Otherwise if it comes before a procedure it's part of the description
2560
+ description = description + (child === null || child === void 0 ? void 0 : child.outerHTML.trim());
2561
+ }
2562
+ }
2563
+ }
2564
+ success = (_g = taskDOM.querySelector('.qs-summary.success')) === null || _g === void 0 ? void 0 : _g.innerHTML.trim();
2565
+ reviewFailed = (_h = taskDOM.querySelector('.qs-review.failed')) === null || _h === void 0 ? void 0 : _h.innerHTML.trim();
2566
+ summaryFailed = (_j = taskDOM.querySelector('.qs-summary.failed')) === null || _j === void 0 ? void 0 : _j.innerHTML.trim();
2567
+ }
2568
+ answer.title = replaceEnvironmentVariables(answer.title || title);
2569
+ answer.description = replaceEnvironmentVariables(answer.description || `${description} ${prerequisites || ''} ${procedure}`);
2570
+ answer.review = answer.review || {};
2571
+ answer.review.instructions = replaceEnvironmentVariables(((_k = answer.review) === null || _k === void 0 ? void 0 : _k.instructions) || verification || 'Have you completed these steps?');
2572
+ answer.review.failedTaskHelp = replaceEnvironmentVariables(answer.review.failedTaskHelp ||
2573
+ reviewFailed ||
2574
+ 'This task isn’t verified yet. Try the task again.');
2575
+ answer.summary = answer.summary || {};
2576
+ answer.summary.success = replaceEnvironmentVariables(answer.summary.success || success || 'You have completed this task!');
2577
+ answer.summary.failed = replaceEnvironmentVariables(answer.summary.failed || summaryFailed || 'Try the steps again.');
2578
+ return answer;
2579
+ });
2580
+ return quickStart;
2576
2581
  };
2577
2582
 
2578
2583
  export { Box, CamelCaseWrap, EmptyBox, HELP_TOPIC_NAME_KEY, HelpTopicContainer, HelpTopicContext, HelpTopicContextDefaults, HelpTopicDrawer, Loading, LoadingBox, ProcQuickStartParser, QUICKSTART_ID_FILTER_KEY, QUICKSTART_SEARCH_FILTER_KEY, QUICKSTART_STATUS_FILTER_KEY, QUICKSTART_TASKS_INITIAL_STATES, QUICK_START_NAME, QuickStartCatalog, QuickStartCatalogEmptyState, QuickStartCatalogFilter, QuickStartCatalogFilterCount, QuickStartCatalogFilterCountWrapper, QuickStartCatalogFilterSearch, QuickStartCatalogFilterSearchWrapper, QuickStartCatalogFilterSelect, QuickStartCatalogFilterStatusWrapper, QuickStartCatalogHeader, QuickStartCatalogPage, QuickStartCatalogSection, QuickStartCatalogToolbar, QuickStartCloseModal, QuickStartContainer, QuickStartContext, QuickStartContextDefaults, QuickStartContextProvider, QuickStartDrawer, QuickStartPanelContent, QuickStartStatus, QuickStartTaskStatus, QuickStartTile, QuickStartTileDescription, QuickStartTileFooter, QuickStartTileFooterExternal, QuickStartTileHeader, camelize, clearFilterParams, equalsIgnoreOrder, filterQuickStarts, getDefaultQuickStartState, getDisabledQuickStarts, getQuickStartByName, getQuickStartStatus, getQuickStartStatusCount, getResource, getTaskStatusKey, history, isDisabledQuickStart, removeQueryArgument, setQueryArgument, useLocalStorage, useValuesForHelpTopicContext, useValuesForQuickStartContext };