@patternfly/quickstarts 1.2.1 → 1.4.0

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.
package/dist/index.js CHANGED
@@ -178,6 +178,7 @@ var en = {
178
178
  "{{count, number}} item": "{{count, number}} item",
179
179
  "{{count, number}} item_plural": "{{count, number}} items",
180
180
  "Prerequisites ({{totalPrereqs}})": "Prerequisites ({{totalPrereqs}})",
181
+ "View Prerequisites ({{totalPrereqs}})": "View Prerequisites ({{totalPrereqs}})",
181
182
  Prerequisites: Prerequisites,
182
183
  "Show prerequisites": "Show prerequisites",
183
184
  Complete: Complete,
@@ -617,6 +618,7 @@ const QuickStartContextDefaults = {
617
618
  footer: null,
618
619
  markdown: null,
619
620
  loading: false,
621
+ alwaysShowTaskReview: false,
620
622
  };
621
623
  const QuickStartContext = React.createContext(QuickStartContextDefaults);
622
624
  const getResource = (resource, options, resourceBundle, lng) => {
@@ -644,6 +646,7 @@ const useValuesForQuickStartContext = (value = {}) => {
644
646
  return getResource(resource, count !== undefined ? { count } : null, resourceBundle, language);
645
647
  }, [resourceBundle, language]);
646
648
  const [loading, setLoading] = React__default['default'].useState(combinedValue.loading);
649
+ const [alwaysShowTaskReview, setAlwaysShowTaskReview] = React__default['default'].useState(combinedValue.alwaysShowTaskReview);
647
650
  const initialSearchParams = new URLSearchParams(window.location.search);
648
651
  const initialSearchQuery = initialSearchParams.get(QUICKSTART_SEARCH_FILTER_KEY) || '';
649
652
  const initialStatusFilters = ((_a = initialSearchParams.get(QUICKSTART_STATUS_FILTER_KEY)) === null || _a === void 0 ? void 0 : _a.split(',')) || [];
@@ -714,6 +717,10 @@ const useValuesForQuickStartContext = (value = {}) => {
714
717
  });
715
718
  setAllQuickStartStates((qs) => (Object.assign(Object.assign({}, qs), { [quickStartId]: getDefaultQuickStartState(totalTasks, exports.QuickStartStatus.IN_PROGRESS) })));
716
719
  }, [setActiveQuickStartID, setAllQuickStartStates, useQueryParams]);
720
+ // When alwaysShowTaskReview preference is enabled, skip visited step and go directly to review
721
+ const stepAfterInitial = alwaysShowTaskReview
722
+ ? exports.QuickStartTaskStatus.REVIEW
723
+ : exports.QuickStartTaskStatus.VISITED;
717
724
  const nextStep = React.useCallback((totalTasks) => {
718
725
  if (!activeQuickStartID) {
719
726
  return;
@@ -740,19 +747,19 @@ const useValuesForQuickStartContext = (value = {}) => {
740
747
  if (taskNumber < totalTasks && !updatedTaskStatus) {
741
748
  updatedTaskNumber = taskNumber + 1;
742
749
  }
743
- const markInitialStepVisited = updatedTaskNumber > -1 &&
750
+ const markInitialStepVisitedOrReview = updatedTaskNumber > -1 &&
744
751
  quickStart[getTaskStatusKey(updatedTaskNumber)] === exports.QuickStartTaskStatus.INIT
745
- ? exports.QuickStartTaskStatus.VISITED
752
+ ? stepAfterInitial
746
753
  : quickStart[getTaskStatusKey(updatedTaskNumber)];
747
754
  const newState = Object.assign(Object.assign({}, qs), { [activeQuickStartID]: Object.assign(Object.assign(Object.assign(Object.assign({}, quickStart), (updatedStatus ? { status: updatedStatus } : {})), (updatedTaskNumber > -1
748
755
  ? {
749
756
  taskNumber: updatedTaskNumber,
750
- [getTaskStatusKey(updatedTaskNumber)]: markInitialStepVisited,
757
+ [getTaskStatusKey(updatedTaskNumber)]: markInitialStepVisitedOrReview,
751
758
  }
752
759
  : {})), (updatedTaskStatus ? { [getTaskStatusKey(taskNumber)]: updatedTaskStatus } : {})) });
753
760
  return newState;
754
761
  });
755
- }, [activeQuickStartID, setAllQuickStartStates]);
762
+ }, [activeQuickStartID, setAllQuickStartStates, stepAfterInitial]);
756
763
  const previousStep = React.useCallback(() => {
757
764
  setAllQuickStartStates((qs) => {
758
765
  const quickStart = qs[activeQuickStartID];
@@ -774,7 +781,7 @@ const useValuesForQuickStartContext = (value = {}) => {
774
781
  let updatedTaskStatus = {};
775
782
  for (let taskIndex = 0; taskIndex <= taskNumber; taskIndex++) {
776
783
  const taskStatus = quickStart[getTaskStatusKey(taskIndex)];
777
- const newTaskStatus = taskStatus === exports.QuickStartTaskStatus.INIT ? exports.QuickStartTaskStatus.VISITED : undefined;
784
+ const newTaskStatus = taskStatus === exports.QuickStartTaskStatus.INIT ? stepAfterInitial : undefined;
778
785
  if (newTaskStatus) {
779
786
  updatedTaskStatus = Object.assign(Object.assign({}, updatedTaskStatus), { [getTaskStatusKey(taskIndex)]: newTaskStatus });
780
787
  }
@@ -782,7 +789,7 @@ const useValuesForQuickStartContext = (value = {}) => {
782
789
  const updatedQuickStart = Object.assign(Object.assign(Object.assign(Object.assign({}, quickStart), (updatedStatus ? { status: updatedStatus } : {})), { taskNumber }), updatedTaskStatus);
783
790
  return Object.assign(Object.assign({}, qs), { [quickStartId]: updatedQuickStart });
784
791
  });
785
- }, [setAllQuickStartStates]);
792
+ }, [setAllQuickStartStates, stepAfterInitial]);
786
793
  const setQuickStartTaskStatus = React.useCallback((taskStatus) => {
787
794
  const quickStart = allQuickStartStates[activeQuickStartID];
788
795
  const { taskNumber } = quickStart;
@@ -828,6 +835,8 @@ const useValuesForQuickStartContext = (value = {}) => {
828
835
  setFilter,
829
836
  loading,
830
837
  setLoading,
838
+ alwaysShowTaskReview,
839
+ setAlwaysShowTaskReview,
831
840
  };
832
841
  };
833
842
  const QuickStartContextProvider = ({ children, value }) => {
@@ -993,7 +1002,7 @@ const SimplePopper = ({ children }) => {
993
1002
  }
994
1003
  }, [destroy, isOpen]);
995
1004
  return isOpen ? (React__namespace.createElement(Portal, null,
996
- React__namespace.createElement("div", { ref: nodeRefCallback, style: { zIndex: 9999, position: 'absolute', top: 0, left: 0 } }, children))) : null;
1005
+ React__namespace.createElement("div", { ref: nodeRefCallback, style: { zIndex: 9999, position: 'absolute', top: 0, left: 0 }, className: "pfext-quick-start__base" }, children))) : null;
997
1006
  };
998
1007
 
999
1008
  const isInViewport = (elementToCheck) => {
@@ -1236,7 +1245,7 @@ const CopyClipboard = ({ element, rootSelector, docContext, }) => {
1236
1245
  useEventListener(element, 'mouseleave', React__namespace.useCallback(() => {
1237
1246
  setShowSuccessContent(false);
1238
1247
  }, []));
1239
- return showSuccessContent ? (React__namespace.createElement(reactCore.Tooltip, { key: "after-copy", isVisible: true, reference: () => element, content: getResource('Successfully copied to clipboard!') })) : (React__namespace.createElement(reactCore.Tooltip, { key: "before-copy", reference: () => element, content: getResource('Copy to clipboard') }));
1248
+ return showSuccessContent ? (React__namespace.createElement(reactCore.Tooltip, { key: "after-copy", isVisible: true, reference: () => element, content: getResource('Successfully copied to clipboard!'), className: "pfext-quick-start__base" })) : (React__namespace.createElement(reactCore.Tooltip, { key: "before-copy", reference: () => element, content: getResource('Copy to clipboard'), className: "pfext-quick-start__base" }));
1240
1249
  };
1241
1250
  const MarkdownCopyClipboard = ({ docContext, rootSelector, }) => {
1242
1251
  const elements = docContext.querySelectorAll(`${rootSelector} [${MARKDOWN_COPY_BUTTON_ID}]`);
@@ -1561,10 +1570,11 @@ const QuickStartTileDescription = ({ description, prerequisites, }) => {
1561
1570
  React__namespace.createElement(reactCore.Text, { component: reactCore.TextVariants.h5, className: "pfext-quick-start-tile-prerequisites__text" },
1562
1571
  getResource('Prerequisites ({{totalPrereqs}})').replace('{{totalPrereqs}}', prereqs.length),
1563
1572
  ' '),
1564
- React__namespace.createElement(reactCore.Popover, { "aria-label": getResource('Prerequisites'), headerContent: getResource('Prerequisites'), className: "pfext-page-layout__base", bodyContent: React__namespace.createElement(reactCore.TextList, { "aria-label": getResource('Prerequisites'), className: "pfext-quick-start-tile-prerequisites-list" }, prereqs.map((prerequisite, index) => (
1565
- // eslint-disable-next-line react/no-array-index-key
1566
- React__namespace.createElement(reactCore.TextListItem, { key: index },
1567
- React__namespace.createElement(QuickStartMarkdownView, { content: prerequisite }))))) },
1573
+ React__namespace.createElement(reactCore.Popover, { "aria-label": getResource('Prerequisites'), headerContent: getResource('Prerequisites'), className: "pfext-quick-start__base", bodyContent: React__namespace.createElement("div", { className: "pfext-popover__base" },
1574
+ React__namespace.createElement(reactCore.TextList, { "aria-label": getResource('Prerequisites'), className: "pfext-quick-start-tile-prerequisites-list" }, prereqs.map((prerequisite, index) => (
1575
+ // eslint-disable-next-line react/no-array-index-key
1576
+ React__namespace.createElement(reactCore.TextListItem, { key: index },
1577
+ React__namespace.createElement(QuickStartMarkdownView, { content: prerequisite })))))) },
1568
1578
  React__namespace.createElement(reactCore.Button, { variant: "link", isInline: true, className: "pfext-quick-start-tile-prerequisites__icon", "data-testid": "qs-card-prereqs", onClick: (e) => {
1569
1579
  e.preventDefault();
1570
1580
  e.stopPropagation();
@@ -1587,20 +1597,20 @@ const QuickStartTileFooter = ({ quickStartId, status, totalTasks, }) => {
1587
1597
  }, [quickStartId, restartQuickStart, totalTasks]);
1588
1598
  return (React__namespace.createElement(reactCore.Flex, { justifyContent: { default: 'justifyContentSpaceBetween' } },
1589
1599
  status === exports.QuickStartStatus.NOT_STARTED && (React__namespace.createElement(reactCore.FlexItem, null,
1590
- React__namespace.createElement(reactCore.Button, { onClick: start, variant: "link", isInline: true, "data-testid": "qs-card-notStarted-start" }, getResource('Start')))),
1600
+ React__namespace.createElement(reactCore.Button, { onClick: start, variant: "link", isInline: true, "data-testid": "qs-card-notStarted-start", id: `${quickStartId}-start`, "aria-labelledby": `${quickStartId}-start ${quickStartId}` }, getResource('Start')))),
1591
1601
  status === exports.QuickStartStatus.IN_PROGRESS && activeQuickStartID !== quickStartId && (React__namespace.createElement(reactCore.FlexItem, null,
1592
- React__namespace.createElement(reactCore.Button, { variant: "link", isInline: true, "data-testid": "qs-card-inProgress-resume" }, getResource('Continue')))),
1602
+ React__namespace.createElement(reactCore.Button, { variant: "link", isInline: true, "data-testid": "qs-card-inProgress-resume", id: `${quickStartId}-continue`, "aria-labelledby": `${quickStartId}-continue ${quickStartId}` }, getResource('Continue')))),
1593
1603
  status === exports.QuickStartStatus.COMPLETE && (React__namespace.createElement(reactCore.FlexItem, null,
1594
- React__namespace.createElement(reactCore.Button, { onClick: restart, variant: "link", isInline: true, "data-testid": "qs-card-complete-restart" }, getResource('Start')))),
1604
+ React__namespace.createElement(reactCore.Button, { onClick: restart, variant: "link", isInline: true, "data-testid": "qs-card-complete-restart", id: `${quickStartId}-restart`, "aria-labelledby": `${quickStartId}-restart ${quickStartId}` }, getResource('Restart')))),
1595
1605
  status === exports.QuickStartStatus.IN_PROGRESS && (React__namespace.createElement(reactCore.FlexItem, null,
1596
- React__namespace.createElement(reactCore.Button, { onClick: restart, variant: "link", isInline: true, "data-testid": "qs-card-inProgress-restart" }, getResource('Restart'))))));
1606
+ React__namespace.createElement(reactCore.Button, { onClick: restart, variant: "link", isInline: true, "data-testid": "qs-card-inProgress-restart", id: `${quickStartId}-restart`, "aria-labelledby": `${quickStartId}-restart ${quickStartId}` }, getResource('Restart'))))));
1597
1607
  };
1598
1608
 
1599
- const QuickStartTileFooterExternal = ({ link }) => {
1609
+ const QuickStartTileFooterExternal = ({ link, quickStartId, }) => {
1600
1610
  const { href, text } = link;
1601
1611
  return (React__namespace.createElement(reactCore.Flex, { justifyContent: { default: 'justifyContentSpaceBetween' } },
1602
1612
  React__namespace.createElement(reactCore.FlexItem, null,
1603
- React__namespace.createElement(reactCore.Button, { component: "a", href: href, target: "_blank", rel: "noopener noreferrer", variant: "link", "aria-label": `Open documentation in new window`, isInline: true, icon: React__namespace.createElement(ExternalLinkAltIcon__default['default'], null), iconPosition: "right" }, text || href))));
1613
+ React__namespace.createElement(reactCore.Button, { component: "a", href: href, target: "_blank", rel: "noopener noreferrer", variant: "link", "aria-label": `Open documentation in new window`, isInline: true, icon: React__namespace.createElement(ExternalLinkAltIcon__default['default'], null), iconPosition: "right", id: quickStartId, "aria-labelledby": `${quickStartId}-external ${quickStartId}` }, text || href))));
1604
1614
  };
1605
1615
 
1606
1616
  const statusColorMap = {
@@ -1608,7 +1618,7 @@ const statusColorMap = {
1608
1618
  [exports.QuickStartStatus.IN_PROGRESS]: 'purple',
1609
1619
  [exports.QuickStartStatus.NOT_STARTED]: 'grey',
1610
1620
  };
1611
- const QuickStartTileHeader = ({ status, duration, name, type, }) => {
1621
+ const QuickStartTileHeader = ({ status, duration, name, type, quickStartId, }) => {
1612
1622
  const { getResource } = React__namespace.useContext(QuickStartContext);
1613
1623
  const statusLocaleMap = {
1614
1624
  [exports.QuickStartStatus.COMPLETE]: getResource('Complete'),
@@ -1616,7 +1626,7 @@ const QuickStartTileHeader = ({ status, duration, name, type, }) => {
1616
1626
  [exports.QuickStartStatus.NOT_STARTED]: getResource('Not started'),
1617
1627
  };
1618
1628
  return (React__namespace.createElement("div", { className: "pfext-quick-start-tile-header" },
1619
- React__namespace.createElement(reactCore.Title, { headingLevel: "h3", "data-test": "title" }, name),
1629
+ React__namespace.createElement(reactCore.Title, { headingLevel: "h3", "data-test": "title", id: quickStartId }, name),
1620
1630
  React__namespace.createElement("div", { className: "pfext-quick-start-tile-header__status" },
1621
1631
  type && (React__namespace.createElement(reactCore.Label, { className: "pfext-quick-start-tile-header--margin", color: type.color }, type.text)),
1622
1632
  duration && (React__namespace.createElement(reactCore.Label, { variant: "outline", "data-test": "duration", icon: React__namespace.createElement(OutlinedClockIcon__default['default'], null), className: "pfext-quick-start-tile-header--margin" }, getResource('{{duration, number}} minutes', duration).replace('{{duration, number}}', duration))),
@@ -1627,8 +1637,14 @@ const QuickStartTile = ({ quickStart, status, isActive, onClick = () => { }, })
1627
1637
  const { metadata: { name: id }, spec: { icon, tasks, displayName, description, durationMinutes, prerequisites, link, type }, } = quickStart;
1628
1638
  const { setActiveQuickStart, footer } = React__namespace.useContext(QuickStartContext);
1629
1639
  const ref = React__namespace.useRef(null);
1630
- const quickStartIcon = (React__namespace.createElement(FallbackImg, { className: "pfext-catalog-item-icon__img--large", src: icon, alt: "", fallback: React__namespace.createElement(RocketIcon__default['default'], null) }));
1631
- const footerComponent = footer && footer.show === false ? null : link ? (React__namespace.createElement(QuickStartTileFooterExternal, { link: link })) : (React__namespace.createElement(QuickStartTileFooter, { quickStartId: id, status: status, totalTasks: tasks === null || tasks === void 0 ? void 0 : tasks.length }));
1640
+ let quickStartIcon;
1641
+ if (typeof icon === 'object') {
1642
+ quickStartIcon = icon;
1643
+ }
1644
+ else {
1645
+ quickStartIcon = (React__namespace.createElement(FallbackImg, { className: "pfext-catalog-item-icon__img--large", src: icon, alt: "", fallback: React__namespace.createElement(RocketIcon__default['default'], null) }));
1646
+ }
1647
+ const footerComponent = footer && footer.show === false ? null : link ? (React__namespace.createElement(QuickStartTileFooterExternal, { link: link, quickStartId: id })) : (React__namespace.createElement(QuickStartTileFooter, { quickStartId: id, status: status, totalTasks: tasks === null || tasks === void 0 ? void 0 : tasks.length }));
1632
1648
  const handleClick = (e) => {
1633
1649
  var _a;
1634
1650
  if ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.contains(e.target)) {
@@ -1648,7 +1664,7 @@ const QuickStartTile = ({ quickStart, status, isActive, onClick = () => { }, })
1648
1664
  // @ts-ignore
1649
1665
  component: "div", style: {
1650
1666
  cursor: 'pointer',
1651
- }, icon: quickStartIcon, className: "pfext-quick-start-tile", "data-testid": `qs-card-${camelize(displayName)}`, featured: isActive, title: React__namespace.createElement(QuickStartTileHeader, { name: displayName, status: status, duration: durationMinutes, type: type }), onClick: handleClick, "data-test": `tile ${id}`, description: React__namespace.createElement(QuickStartTileDescription, { description: description, prerequisites: prerequisites }), footer: footerComponent })));
1667
+ }, icon: quickStartIcon, className: "pfext-quick-start-tile", "data-testid": `qs-card-${camelize(displayName)}`, featured: isActive, title: React__namespace.createElement(QuickStartTileHeader, { name: displayName, status: status, duration: durationMinutes, type: type, quickStartId: id }), onClick: handleClick, "data-test": `tile ${id}`, description: React__namespace.createElement(QuickStartTileDescription, { description: description, prerequisites: prerequisites }), footer: footerComponent })));
1652
1668
  };
1653
1669
 
1654
1670
  const QuickStartCatalog = ({ quickStarts }) => {
@@ -1841,7 +1857,7 @@ const QuickStartCatalogPage = ({ quickStarts, showFilter, sortFnc = (q1, q2) =>
1841
1857
  if (!allQuickStarts || allQuickStarts.length === 0) {
1842
1858
  return React__namespace.createElement(EmptyBox, { label: getResource('Quick Starts') });
1843
1859
  }
1844
- return (React__namespace.createElement(React__namespace.Fragment, null,
1860
+ return (React__namespace.createElement("div", { className: "pfext-quick-start__base" },
1845
1861
  showTitle && (React__namespace.createElement("div", { className: "pfext-page-layout__header" },
1846
1862
  React__namespace.createElement(reactCore.Text, { component: "h1", className: "pfext-page-layout__title", "data-test": "page-title" }, title || getResource('Quick Starts')),
1847
1863
  hint && React__namespace.createElement("div", { className: "pfext-page-layout__hint" }, hint))),
@@ -1862,65 +1878,89 @@ const QuickStartCatalogToolbar = ({ children }) => (React__namespace.createEleme
1862
1878
 
1863
1879
  const QuickStartCloseModal = ({ isOpen, onConfirm, onCancel, }) => {
1864
1880
  const { getResource } = React__namespace.useContext(QuickStartContext);
1865
- return (React__namespace.createElement(Modal, { className: "pfext-quick-start-drawer__modal", isOpen: isOpen, variant: reactCore.ModalVariant.small, showClose: false, "data-test": "leave-quickstart", title: getResource('Leave quick start?'), footer: React__namespace.createElement(reactCore.Flex, null,
1881
+ return (React__namespace.createElement(Modal, { className: "pfext-quick-start-drawer__modal pfext-quick-start__base", isOpen: isOpen, variant: reactCore.ModalVariant.small, showClose: false, "data-test": "leave-quickstart", title: getResource('Leave quick start?'), footer: React__namespace.createElement(reactCore.Flex, null,
1866
1882
  React__namespace.createElement(reactCore.FlexItem, { align: { default: 'alignRight' } },
1867
1883
  React__namespace.createElement(reactCore.Button, { variant: "secondary", "data-test": "cancel button", onClick: onCancel }, getResource('Cancel'))),
1868
1884
  React__namespace.createElement(reactCore.FlexItem, null,
1869
1885
  React__namespace.createElement(reactCore.Button, { variant: "primary", "data-test": "leave button", onClick: onConfirm }, getResource('Leave')))), isFullScreen: true }, getResource('Your progress will be saved.')));
1870
1886
  };
1871
1887
 
1872
- const TaskIcon = ({ taskIndex, taskStatus, }) => {
1888
+ const TaskIcon = ({ taskIndex, taskStatus }) => {
1873
1889
  const { getResource } = React__namespace.useContext(QuickStartContext);
1874
- switch (taskStatus) {
1875
- case exports.QuickStartTaskStatus.SUCCESS:
1876
- return (React__namespace.createElement("span", { className: "pfext-icon-and-text__icon" },
1877
- React__namespace.createElement(CheckCircleIcon__default['default'], { size: "md", className: "pfext-quick-start-task-header__task-icon-success" })));
1878
- case exports.QuickStartTaskStatus.FAILED:
1879
- return (React__namespace.createElement("span", { className: "pfext-icon-and-text__icon" },
1880
- React__namespace.createElement(ExclamationCircleIcon__default['default'], { size: "md", className: "pfext-quick-start-task-header__task-icon-failed" })));
1881
- default:
1882
- return (React__namespace.createElement("span", { className: "pfext-icon-and-text__icon pfext-quick-start-task-header__task-icon-init" }, getResource('{{taskIndex, number}}', taskIndex).replace('{{taskIndex, number}}', taskIndex)));
1890
+ const success = taskStatus === exports.QuickStartTaskStatus.SUCCESS;
1891
+ const failed = taskStatus === exports.QuickStartTaskStatus.FAILED;
1892
+ const classNames = reactStyles.css('pfext-icon-and-text__icon', {
1893
+ 'pfext-quick-start-task-header__task-icon-init': !failed && !success,
1894
+ });
1895
+ let content;
1896
+ if (success) {
1897
+ content = (React__namespace.createElement(CheckCircleIcon__default['default'], { size: "md", className: "pfext-quick-start-task-header__task-icon-success" }));
1883
1898
  }
1899
+ else if (failed) {
1900
+ content = (React__namespace.createElement(ExclamationCircleIcon__default['default'], { size: "md", className: "pfext-quick-start-task-header__task-icon-failed" }));
1901
+ }
1902
+ else {
1903
+ content = getResource('{{taskIndex, number}}', taskIndex).replace('{{taskIndex, number}}', taskIndex);
1904
+ }
1905
+ return React__namespace.createElement("span", { className: classNames }, content);
1884
1906
  };
1885
1907
  const QuickStartTaskHeader = ({ title, taskIndex, subtitle, taskStatus, size, isActiveTask, onTaskSelect, }) => {
1886
1908
  const classNames = reactStyles.css('pfext-quick-start-task-header__title', {
1887
1909
  'pfext-quick-start-task-header__title-success': taskStatus === exports.QuickStartTaskStatus.SUCCESS,
1888
- 'pfext-quick-start-task-header__title-failed': taskStatus === exports.QuickStartTaskStatus.FAILED,
1910
+ 'pfext-quick-start-task-header__title-failed': taskStatus === (exports.QuickStartTaskStatus.FAILED || exports.QuickStartTaskStatus.VISITED),
1889
1911
  });
1890
- const content = (React__namespace.createElement("span", { className: "pfext-quick-start-task-header" },
1891
- React__namespace.createElement(reactCore.Title, { headingLevel: "h3", size: size, className: classNames },
1892
- React__namespace.createElement(TaskIcon, { taskIndex: taskIndex, taskStatus: taskStatus }),
1893
- React__namespace.createElement("span", { dangerouslySetInnerHTML: { __html: removeParagraphWrap(markdownConvert(title)) } }),
1894
- isActiveTask && subtitle && (React__namespace.createElement(React__namespace.Fragment, null,
1895
- ' ',
1896
- React__namespace.createElement("span", { className: "pfext-quick-start-task-header__subtitle text-secondary", "data-test-id": "quick-start-task-subtitle" }, subtitle))))));
1897
- return (React__namespace.createElement(reactCore.WizardNavItem, { content: content, step: taskIndex, onNavItemClick: () => onTaskSelect(taskIndex - 1), navItemComponent: "button" }));
1912
+ const notCompleted = taskStatus === exports.QuickStartTaskStatus.VISITED;
1913
+ const skippedReviewOrFailed = taskStatus === exports.QuickStartTaskStatus.REVIEW || taskStatus === exports.QuickStartTaskStatus.FAILED;
1914
+ const tryAgain = !isActiveTask && (skippedReviewOrFailed || notCompleted) && (React__namespace.createElement(reactCore.FlexItem, null,
1915
+ React__namespace.createElement(reactCore.Title, { headingLevel: "h4", className: "pfext-quick-start-task-header__tryagain" }, "Try the steps again.")));
1916
+ const content = (React__namespace.createElement(reactCore.Flex, { className: "pfext-quick-start-task-header", direction: { default: 'column' }, spaceItems: { default: 'spaceItemsXs' } },
1917
+ React__namespace.createElement(reactCore.FlexItem, null,
1918
+ React__namespace.createElement(reactCore.Title, { headingLevel: "h3", size: size, className: classNames },
1919
+ React__namespace.createElement(TaskIcon, { taskIndex: taskIndex, taskStatus: taskStatus }),
1920
+ React__namespace.createElement("span", { dangerouslySetInnerHTML: { __html: removeParagraphWrap(markdownConvert(title)) } }),
1921
+ isActiveTask && subtitle && (React__namespace.createElement(React__namespace.Fragment, null,
1922
+ ' ',
1923
+ React__namespace.createElement("span", { className: "pfext-quick-start-task-header__subtitle", "data-test-id": "quick-start-task-subtitle" }, subtitle))))),
1924
+ tryAgain));
1925
+ return (React__namespace.createElement(reactCore.WizardNavItem, { content: content, step: taskIndex, onNavItemClick: () => onTaskSelect(taskIndex - 1), navItemComponent: "button", isCurrent: isActiveTask }));
1898
1926
  };
1899
1927
 
1900
1928
  const QuickStartTaskHeaderList = ({ tasks, allTaskStatuses, onTaskSelect, }) => {
1901
1929
  return tasks.length > 0 ? (React__namespace.createElement(reactCore.List, { className: "pfext-quick-start-task-header__list" }, tasks.map((task, index) => (React__namespace.createElement(QuickStartTaskHeader, { key: task.title, title: task.title, taskIndex: index + 1, size: "md", taskStatus: allTaskStatuses[index], onTaskSelect: onTaskSelect }))))) : null;
1902
1930
  };
1903
1931
 
1904
- const QuickStartConclusion = ({ tasks, conclusion, allTaskStatuses, nextQuickStart, onQuickStartChange, onTaskSelect, }) => {
1905
- var _a;
1932
+ const QuickStartConclusion = ({ tasks, conclusion, allTaskStatuses, nextQuickStarts, onQuickStartChange, onTaskSelect, }) => {
1906
1933
  const hasFailedTask = allTaskStatuses.includes(exports.QuickStartTaskStatus.FAILED);
1907
- const nextQSDisplayName = (_a = nextQuickStart === null || nextQuickStart === void 0 ? void 0 : nextQuickStart.spec) === null || _a === void 0 ? void 0 : _a.displayName;
1908
1934
  const { getResource } = React__namespace.useContext(QuickStartContext);
1909
1935
  return (React__namespace.createElement(React__namespace.Fragment, null,
1910
1936
  React__namespace.createElement(QuickStartTaskHeaderList, { tasks: tasks, allTaskStatuses: allTaskStatuses, onTaskSelect: onTaskSelect }),
1911
1937
  React__namespace.createElement(QuickStartMarkdownView, { content: hasFailedTask
1912
1938
  ? getResource('One or more verifications did not pass during this quick start. Revisit the tasks or the help links, and then try again.')
1913
1939
  : conclusion }),
1914
- nextQuickStart && !hasFailedTask && (React__namespace.createElement(reactCore.Button, { variant: "link", onClick: () => onQuickStartChange(nextQuickStart.metadata.name), isInline: true },
1915
- getResource('Start {{nextQSDisplayName}} quick start').replace('{{nextQSDisplayName}}', nextQSDisplayName),
1916
- ' ',
1917
- React__namespace.createElement(ArrowRightIcon__default['default'], { style: { marginLeft: 'var(--pf-global--spacer--xs)', verticalAlign: 'middle' } })))));
1940
+ !hasFailedTask &&
1941
+ nextQuickStarts &&
1942
+ nextQuickStarts.length > 0 &&
1943
+ nextQuickStarts.map((nextQuickStart, index) => {
1944
+ var _a;
1945
+ return (React__namespace.createElement(reactCore.Button, { variant: "link", onClick: () => onQuickStartChange(nextQuickStart.metadata.name), isInline: true, isBlock: true, key: index },
1946
+ 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),
1947
+ ' ',
1948
+ React__namespace.createElement(ArrowRightIcon__default['default'], { style: { marginLeft: 'var(--pf-global--spacer--xs)', verticalAlign: 'middle' } })));
1949
+ })));
1918
1950
  };
1919
1951
 
1920
- const QuickStartIntroduction = ({ tasks, introduction, allTaskStatuses, onTaskSelect, }) => {
1952
+ const QuickStartIntroduction = ({ tasks, introduction, allTaskStatuses, prerequisites, onTaskSelect, }) => {
1921
1953
  const { getResource } = React__namespace.useContext(QuickStartContext);
1954
+ const prereqs = prerequisites === null || prerequisites === void 0 ? void 0 : prerequisites.filter((p) => p);
1955
+ const [isPrereqsExpanded, setIsPrereqsExpanded] = React__namespace.useState(false);
1956
+ const prereqList = (prereqs === null || prereqs === void 0 ? void 0 : prereqs.length) > 0 && (React__namespace.createElement(reactCore.ExpandableSection, { toggleText: getResource('View Prerequisites ({{totalPrereqs}})').replace('{{totalPrereqs}}', prereqs.length), onToggle: () => setIsPrereqsExpanded(!isPrereqsExpanded), className: "pfext-quick-start-intro__prereq" },
1957
+ React__namespace.createElement(reactCore.List, { className: "pfext-quick-start-intro__prereq-list" }, prereqs.map((pr) => {
1958
+ return (React__namespace.createElement(reactCore.ListItem, { key: pr, className: "pfext-quick-start-intro__prereq-list__item" },
1959
+ React__namespace.createElement("span", { className: "pfext-quick-start-intro__prereq-list__item-content" }, pr)));
1960
+ }))));
1922
1961
  return (React__namespace.createElement(React__namespace.Fragment, null,
1923
1962
  React__namespace.createElement(QuickStartMarkdownView, { content: introduction }),
1963
+ prereqList,
1924
1964
  React__namespace.createElement("p", { style: { marginBottom: 'var(--pf-global--spacer--md)' } },
1925
1965
  getResource('In this quick start, you will complete {{count, number}} task', tasks.length).replace('{{count, number}}', tasks.length),
1926
1966
  ":"),
@@ -1945,7 +1985,7 @@ const QuickStartTaskReview = ({ review, taskStatus, onTaskReview, }) => {
1945
1985
  'pfext-quick-start-task-review--failed': taskStatus === exports.QuickStartTaskStatus.FAILED,
1946
1986
  });
1947
1987
  const title = React__namespace.createElement("span", { className: alertClassNames }, getResource('Check your work'));
1948
- return (React__namespace.createElement(reactCore.Alert, { variant: getAlertVariant(taskStatus), title: title, isInline: true },
1988
+ return (React__namespace.createElement(reactCore.Alert, { className: "pfext-quick-start-task-review-alert", variant: getAlertVariant(taskStatus), title: title, isInline: true },
1949
1989
  React__namespace.createElement(QuickStartMarkdownView, { content: instructions }),
1950
1990
  React__namespace.createElement("span", { className: "pfext-quick-start-task-review__actions" },
1951
1991
  React__namespace.createElement(reactCore.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 === exports.QuickStartTaskStatus.SUCCESS, onChange: () => onTaskReview(exports.QuickStartTaskStatus.SUCCESS) }),
@@ -1954,31 +1994,32 @@ const QuickStartTaskReview = ({ review, taskStatus, onTaskReview, }) => {
1954
1994
  };
1955
1995
 
1956
1996
  const QuickStartTasks = ({ tasks, taskNumber, allTaskStatuses, onTaskReview, onTaskSelect, }) => {
1957
- const { getResource } = React__namespace.useContext(QuickStartContext);
1997
+ const { getResource, alwaysShowTaskReview } = React__namespace.useContext(QuickStartContext);
1958
1998
  return (React__namespace.createElement("div", { className: "pfext-quick-start-tasks__list" }, tasks
1959
1999
  .filter((_, index) => allTaskStatuses[index] !== exports.QuickStartTaskStatus.INIT)
1960
2000
  .map((task, index) => {
1961
2001
  const { title, description, review } = task;
1962
2002
  const isActiveTask = index === taskNumber;
1963
2003
  const taskStatus = allTaskStatuses[index];
2004
+ const shouldShowTaskReview = (!QUICKSTART_TASKS_INITIAL_STATES.includes(taskStatus) || alwaysShowTaskReview) &&
2005
+ review;
1964
2006
  return (React__namespace.createElement(React__namespace.Fragment, { key: title },
1965
2007
  React__namespace.createElement(QuickStartTaskHeader, { taskIndex: index + 1, title: title, size: "md", subtitle: getResource('{{index, number}} of {{tasks, number}}')
1966
2008
  .replace('{{index, number}}', index + 1)
1967
2009
  .replace('{{tasks, number}}', tasks.length), taskStatus: taskStatus, isActiveTask: isActiveTask, onTaskSelect: onTaskSelect }),
1968
2010
  isActiveTask && (React__namespace.createElement("div", { style: { marginBottom: 'var(--pf-global--spacer--md)' } },
1969
2011
  React__namespace.createElement(QuickStartMarkdownView, { content: description }),
1970
- !QUICKSTART_TASKS_INITIAL_STATES.includes(taskStatus) && review && (React__namespace.createElement(QuickStartTaskReview, { review: review, taskStatus: taskStatus, onTaskReview: onTaskReview }))))));
2012
+ shouldShowTaskReview && (React__namespace.createElement(QuickStartTaskReview, { review: review, taskStatus: taskStatus, onTaskReview: onTaskReview }))))));
1971
2013
  })));
1972
2014
  };
1973
2015
 
1974
2016
  const QuickStartContent = React__namespace.forwardRef(({ quickStart, nextQuickStarts = [], taskNumber, allTaskStatuses, onTaskSelect, onTaskReview, onQuickStartChange, }, ref) => {
1975
- const { spec: { introduction, tasks, conclusion }, } = quickStart;
2017
+ const { spec: { introduction, tasks, conclusion, prerequisites }, } = quickStart;
1976
2018
  const totalTasks = tasks.length;
1977
- const nextQS = nextQuickStarts.length > 0 && nextQuickStarts[0];
1978
2019
  return (React__namespace.createElement("div", { className: "pfext-quick-start-content", ref: ref },
1979
- taskNumber === -1 && (React__namespace.createElement(QuickStartIntroduction, { tasks: tasks, allTaskStatuses: allTaskStatuses, introduction: introduction, onTaskSelect: onTaskSelect })),
2020
+ taskNumber === -1 && (React__namespace.createElement(QuickStartIntroduction, { tasks: tasks, allTaskStatuses: allTaskStatuses, introduction: introduction, prerequisites: prerequisites, onTaskSelect: onTaskSelect })),
1980
2021
  taskNumber > -1 && taskNumber < totalTasks && (React__namespace.createElement(QuickStartTasks, { tasks: tasks, taskNumber: taskNumber, allTaskStatuses: allTaskStatuses, onTaskReview: onTaskReview, onTaskSelect: onTaskSelect })),
1981
- taskNumber === totalTasks && (React__namespace.createElement(QuickStartConclusion, { tasks: tasks, conclusion: conclusion, allTaskStatuses: allTaskStatuses, nextQuickStart: nextQS, onQuickStartChange: onQuickStartChange, onTaskSelect: onTaskSelect }))));
2022
+ taskNumber === totalTasks && (React__namespace.createElement(QuickStartConclusion, { tasks: tasks, conclusion: conclusion, allTaskStatuses: allTaskStatuses, nextQuickStarts: nextQuickStarts, onQuickStartChange: onQuickStartChange, onTaskSelect: onTaskSelect }))));
1982
2023
  });
1983
2024
 
1984
2025
  const QuickStartFooter = ({ status, taskNumber, totalTasks, onNext, onBack, footerClass, quickStartId, }) => {
@@ -2016,8 +2057,7 @@ const QuickStartFooter = ({ status, taskNumber, totalTasks, onNext, onBack, foot
2016
2057
  }, [taskNumber, totalTasks, PrimaryButtonText, status]);
2017
2058
  const getPrimaryButton = React__namespace.useMemo(() => (React__namespace.createElement(reactCore.Button, { variant: "primary", className: "pfext-quick-start-footer__actionbtn", onClick: onNext, "data-testid": `qs-drawer-${camelize(getPrimaryButtonText)}`, "data-test": `${getPrimaryButtonText} button` }, getPrimaryButtonText)), [getPrimaryButtonText, onNext]);
2018
2059
  const getSecondaryButton = React__namespace.useMemo(() => taskNumber === -1 && status !== exports.QuickStartStatus.NOT_STARTED ? (React__namespace.createElement(reactCore.Button, { variant: "secondary", onClick: onRestart, "data-testid": "qs-drawer-restart" }, SecondaryButtonText.RESTART)) : (taskNumber > -1 && (React__namespace.createElement(reactCore.Button, { variant: "secondary", onClick: onBack, "data-testid": "qs-drawer-back" }, SecondaryButtonText.BACK))), [onRestart, onBack, SecondaryButtonText, status, taskNumber]);
2019
- const getSideNoteAction = React__namespace.useMemo(() => status === exports.QuickStartStatus.COMPLETE &&
2020
- taskNumber === totalTasks && (React__namespace.createElement(reactCore.Button, { variant: "link", className: "pfext-quick-start-footer__restartbtn", onClick: onRestart, "data-testid": "qs-drawer-side-note-action" }, SecondaryButtonText.RESTART)), [status, SecondaryButtonText, onRestart, taskNumber, totalTasks]);
2060
+ const getSideNoteAction = React__namespace.useMemo(() => taskNumber !== -1 && (React__namespace.createElement(reactCore.Button, { variant: "link", className: "pfext-quick-start-footer__restartbtn", onClick: onRestart, "data-testid": "qs-drawer-side-note-action" }, SecondaryButtonText.RESTART)), [taskNumber, onRestart, SecondaryButtonText.RESTART]);
2021
2061
  return (React__namespace.createElement("div", { className: `pfext-quick-start-footer ${footerClass}` },
2022
2062
  getPrimaryButton,
2023
2063
  getSecondaryButton,
@@ -2071,6 +2111,13 @@ const getElement = (appendTo) => {
2071
2111
  }
2072
2112
  return appendTo;
2073
2113
  };
2114
+ const useScrollTopOnTaskNumberChange = (node, taskNumber) => {
2115
+ React__namespace.useEffect(() => {
2116
+ if (node) {
2117
+ node.scrollTo({ top: 0, behavior: 'smooth' });
2118
+ }
2119
+ }, [taskNumber, node]);
2120
+ };
2074
2121
  const QuickStartPanelContent = (_a) => {
2075
2122
  var { quickStarts = [], handleClose, activeQuickStartID, appendTo, isResizable = true, showClose = true } = _a, props = tslib.__rest(_a, ["quickStarts", "handleClose", "activeQuickStartID", "appendTo", "isResizable", "showClose"]);
2076
2123
  const { getResource } = React__namespace.useContext(QuickStartContext);
@@ -2079,6 +2126,7 @@ const QuickStartPanelContent = (_a) => {
2079
2126
  const quickStart = quickStarts.find((qs) => qs.metadata.name === activeQuickStartID);
2080
2127
  const { activeQuickStartState } = React__namespace.useContext(QuickStartContext);
2081
2128
  const taskNumber = activeQuickStartState === null || activeQuickStartState === void 0 ? void 0 : activeQuickStartState.taskNumber;
2129
+ useScrollTopOnTaskNumberChange(contentRef, taskNumber);
2082
2130
  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); });
2083
2131
  const headerClasses = reactStyles.css('pfext-quick-start-panel-content__header', {
2084
2132
  'pfext-quick-start-panel-content__header__shadow': shadows === Shadows.top || shadows === Shadows.both,
@@ -2096,7 +2144,7 @@ const QuickStartPanelContent = (_a) => {
2096
2144
  }
2097
2145
  return Number.parseInt(taskNumber, 10) + 1;
2098
2146
  };
2099
- const content = quickStart ? (React__namespace.createElement(reactCore.DrawerPanelContent, Object.assign({ isResizable: isResizable, className: "pfext-quick-start-panel-content", "data-testid": `qs-drawer-${camelize(quickStart.spec.displayName)}`, "data-qs": `qs-step-${getStep()}`, "data-test": "quickstart drawer" }, props),
2147
+ const content = quickStart ? (React__namespace.createElement(reactCore.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),
2100
2148
  React__namespace.createElement("div", { className: headerClasses },
2101
2149
  React__namespace.createElement(reactCore.DrawerHead, null,
2102
2150
  React__namespace.createElement("div", { className: "pfext-quick-start-panel-content__title" },
@@ -2115,7 +2163,7 @@ const QuickStartPanelContent = (_a) => {
2115
2163
  };
2116
2164
 
2117
2165
  const QuickStartContainer = (_a) => {
2118
- var { quickStarts, children, activeQuickStartID, allQuickStartStates, setActiveQuickStartID, setAllQuickStartStates, appendTo, fullWidth, onCloseInProgress, onCloseNotInProgress, resourceBundle, showCardFooters, language, loading = false, useQueryParams = true, markdown, contextProps } = _a, props = tslib.__rest(_a, ["quickStarts", "children", "activeQuickStartID", "allQuickStartStates", "setActiveQuickStartID", "setAllQuickStartStates", "appendTo", "fullWidth", "onCloseInProgress", "onCloseNotInProgress", "resourceBundle", "showCardFooters", "language", "loading", "useQueryParams", "markdown", "contextProps"]);
2166
+ var { quickStarts, children, activeQuickStartID, allQuickStartStates, setActiveQuickStartID, setAllQuickStartStates, appendTo, fullWidth, onCloseInProgress, onCloseNotInProgress, resourceBundle, showCardFooters, language, loading = false, useQueryParams = true, markdown, contextProps, alwaysShowTaskReview = false } = _a, props = tslib.__rest(_a, ["quickStarts", "children", "activeQuickStartID", "allQuickStartStates", "setActiveQuickStartID", "setAllQuickStartStates", "appendTo", "fullWidth", "onCloseInProgress", "onCloseNotInProgress", "resourceBundle", "showCardFooters", "language", "loading", "useQueryParams", "markdown", "contextProps", "alwaysShowTaskReview"]);
2119
2167
  const valuesForQuickstartContext = useValuesForQuickStartContext(Object.assign({ allQuickStarts: quickStarts, activeQuickStartID,
2120
2168
  setActiveQuickStartID,
2121
2169
  allQuickStartStates,
@@ -2123,7 +2171,8 @@ const QuickStartContainer = (_a) => {
2123
2171
  show: showCardFooters,
2124
2172
  }, language, resourceBundle: Object.assign({}, resourceBundle), loading,
2125
2173
  useQueryParams,
2126
- markdown }, contextProps));
2174
+ markdown,
2175
+ alwaysShowTaskReview }, contextProps));
2127
2176
  React__namespace.useEffect(() => {
2128
2177
  if (quickStarts &&
2129
2178
  JSON.stringify(quickStarts) !== JSON.stringify(valuesForQuickstartContext.allQuickStarts)) {