@patternfly/chatbot 2.2.0-prerelease.7 → 2.2.0-prerelease.9

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 (63) hide show
  1. package/dist/cjs/Message/ListMessage/OrderedListMessage.d.ts +1 -1
  2. package/dist/cjs/Message/ListMessage/OrderedListMessage.js +2 -2
  3. package/dist/cjs/Message/Message.d.ts +14 -0
  4. package/dist/cjs/Message/Message.js +4 -2
  5. package/dist/cjs/Message/Message.test.js +51 -0
  6. package/dist/cjs/Message/QuickStarts/FallbackImg.d.ts +13 -0
  7. package/dist/cjs/Message/QuickStarts/FallbackImg.js +34 -0
  8. package/dist/cjs/Message/QuickStarts/QuickStartTile.d.ts +27 -0
  9. package/dist/cjs/Message/QuickStarts/QuickStartTile.js +82 -0
  10. package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.d.ts +23 -0
  11. package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.js +64 -0
  12. package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.test.d.ts +1 -0
  13. package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.test.js +76 -0
  14. package/dist/cjs/Message/QuickStarts/QuickStartTileHeader.d.ts +11 -0
  15. package/dist/cjs/Message/QuickStarts/QuickStartTileHeader.js +30 -0
  16. package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.d.ts +30 -0
  17. package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.js +77 -0
  18. package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart.d.ts +30 -0
  19. package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart.js +77 -0
  20. package/dist/cjs/Message/QuickStarts/types.d.ts +132 -0
  21. package/dist/cjs/Message/QuickStarts/types.js +17 -0
  22. package/dist/css/main.css +19 -0
  23. package/dist/css/main.css.map +1 -1
  24. package/dist/esm/Message/ListMessage/OrderedListMessage.d.ts +1 -1
  25. package/dist/esm/Message/ListMessage/OrderedListMessage.js +2 -2
  26. package/dist/esm/Message/Message.d.ts +14 -0
  27. package/dist/esm/Message/Message.js +4 -2
  28. package/dist/esm/Message/Message.test.js +51 -0
  29. package/dist/esm/Message/QuickStarts/FallbackImg.d.ts +13 -0
  30. package/dist/esm/Message/QuickStarts/FallbackImg.js +9 -0
  31. package/dist/esm/Message/QuickStarts/QuickStartTile.d.ts +27 -0
  32. package/dist/esm/Message/QuickStarts/QuickStartTile.js +52 -0
  33. package/dist/esm/Message/QuickStarts/QuickStartTileDescription.d.ts +23 -0
  34. package/dist/esm/Message/QuickStarts/QuickStartTileDescription.js +35 -0
  35. package/dist/esm/Message/QuickStarts/QuickStartTileDescription.test.d.ts +1 -0
  36. package/dist/esm/Message/QuickStarts/QuickStartTileDescription.test.js +48 -0
  37. package/dist/esm/Message/QuickStarts/QuickStartTileHeader.d.ts +11 -0
  38. package/dist/esm/Message/QuickStarts/QuickStartTileHeader.js +5 -0
  39. package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.d.ts +30 -0
  40. package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.js +74 -0
  41. package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart.d.ts +30 -0
  42. package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart.js +74 -0
  43. package/dist/esm/Message/QuickStarts/types.d.ts +132 -0
  44. package/dist/esm/Message/QuickStarts/types.js +14 -0
  45. package/dist/tsconfig.tsbuildinfo +1 -1
  46. package/package.json +1 -7
  47. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithQuickStart.tsx +31 -0
  48. package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +12 -1
  49. package/patternfly-docs/content/extensions/chatbot/examples/Messages/explore-pipeline-quickstart.ts +65 -0
  50. package/patternfly-docs/content/extensions/chatbot/examples/UI/SquareChatbotToggle.tsx +1 -1
  51. package/src/Message/ListMessage/OrderedListMessage.tsx +2 -2
  52. package/src/Message/Message.test.tsx +76 -0
  53. package/src/Message/Message.tsx +28 -1
  54. package/src/Message/QuickStarts/FallbackImg.tsx +24 -0
  55. package/src/Message/QuickStarts/QuickStartTile.scss +25 -0
  56. package/src/Message/QuickStarts/QuickStartTile.tsx +147 -0
  57. package/src/Message/QuickStarts/QuickStartTileDescription.test.tsx +57 -0
  58. package/src/Message/QuickStarts/QuickStartTileDescription.tsx +81 -0
  59. package/src/Message/QuickStarts/QuickStartTileHeader.tsx +21 -0
  60. package/src/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.ts +75 -0
  61. package/src/Message/QuickStarts/monitor-sampleapp-quickstart.ts +75 -0
  62. package/src/Message/QuickStarts/types.ts +154 -0
  63. package/src/main.scss +1 -0
@@ -1,4 +1,4 @@
1
1
  import React from 'react';
2
2
  import { ExtraProps } from 'react-markdown';
3
- declare const OrderedListMessage: ({ children }: JSX.IntrinsicElements["ol"] & ExtraProps) => React.JSX.Element;
3
+ declare const OrderedListMessage: ({ children, start }: JSX.IntrinsicElements["ol"] & ExtraProps) => React.JSX.Element;
4
4
  export default OrderedListMessage;
@@ -8,6 +8,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  const react_1 = __importDefault(require("react"));
10
10
  const react_core_1 = require("@patternfly/react-core");
11
- const OrderedListMessage = ({ children }) => (react_1.default.createElement("div", { className: "pf-chatbot__message-ordered-list" },
12
- react_1.default.createElement(react_core_1.List, { component: react_core_1.ListComponent.ol, type: react_core_1.OrderType.number }, children)));
11
+ const OrderedListMessage = ({ children, start }) => (react_1.default.createElement("div", { className: "pf-chatbot__message-ordered-list" },
12
+ react_1.default.createElement(react_core_1.List, { component: react_core_1.ListComponent.ol, type: react_core_1.OrderType.number, start: start }, children)));
13
13
  exports.default = OrderedListMessage;
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import { AvatarProps, LabelGroupProps, LabelProps } from '@patternfly/react-core';
3
3
  import { ActionProps } from '../ResponseActions/ResponseActions';
4
4
  import { SourcesCardProps } from '../SourcesCard';
5
+ import { QuickStart, QuickstartAction } from './QuickStarts/types';
5
6
  export interface QuickResponse extends Omit<LabelProps, 'children'> {
6
7
  content: string;
7
8
  id: string;
@@ -64,6 +65,19 @@ export interface MessageProps extends Omit<React.HTMLProps<HTMLDivElement>, 'rol
64
65
  hasRoundAvatar?: boolean;
65
66
  /** Any additional props applied to the avatar, for additional customization */
66
67
  avatarProps?: Omit<AvatarProps, 'alt'>;
68
+ /** Props for QuickStart card */
69
+ quickStarts?: {
70
+ quickStart: QuickStart;
71
+ onSelectQuickStart: (id?: string) => void;
72
+ minuteWord?: string;
73
+ minuteWordPlural?: string;
74
+ prerequisiteWord?: string;
75
+ prerequisiteWordPlural?: string;
76
+ quickStartButtonAriaLabel?: string;
77
+ className?: string;
78
+ onClick?: () => void;
79
+ action?: QuickstartAction;
80
+ };
67
81
  }
68
82
  export declare const Message: React.FunctionComponent<MessageProps>;
69
83
  export default Message;
@@ -31,8 +31,9 @@ const SourcesCard_1 = __importDefault(require("../SourcesCard"));
31
31
  const ListItemMessage_1 = __importDefault(require("./ListMessage/ListItemMessage"));
32
32
  const UnorderedListMessage_1 = __importDefault(require("./ListMessage/UnorderedListMessage"));
33
33
  const OrderedListMessage_1 = __importDefault(require("./ListMessage/OrderedListMessage"));
34
+ const QuickStartTile_1 = __importDefault(require("./QuickStarts/QuickStartTile"));
34
35
  const Message = (_a) => {
35
- var { role, content, name, avatar, timestamp, isLoading, actions, sources, botWord = 'AI', loadingWord = 'Loading message', codeBlockProps, quickResponses, quickResponseContainerProps = { numLabels: 5 }, attachments, hasRoundAvatar = true, avatarProps } = _a, props = __rest(_a, ["role", "content", "name", "avatar", "timestamp", "isLoading", "actions", "sources", "botWord", "loadingWord", "codeBlockProps", "quickResponses", "quickResponseContainerProps", "attachments", "hasRoundAvatar", "avatarProps"]);
36
+ var { role, content, name, avatar, timestamp, isLoading, actions, sources, botWord = 'AI', loadingWord = 'Loading message', codeBlockProps, quickResponses, quickResponseContainerProps = { numLabels: 5 }, attachments, hasRoundAvatar = true, avatarProps, quickStarts } = _a, props = __rest(_a, ["role", "content", "name", "avatar", "timestamp", "isLoading", "actions", "sources", "botWord", "loadingWord", "codeBlockProps", "quickResponses", "quickResponseContainerProps", "attachments", "hasRoundAvatar", "avatarProps", "quickStarts"]);
36
37
  let avatarClassName;
37
38
  if (avatarProps && 'className' in avatarProps) {
38
39
  const { className } = avatarProps, rest = __rest(avatarProps, ["className"]);
@@ -56,10 +57,11 @@ const Message = (_a) => {
56
57
  p: TextMessage_1.default,
57
58
  code: ({ children }) => react_1.default.createElement(CodeBlockMessage_1.default, Object.assign({}, codeBlockProps), children),
58
59
  ul: UnorderedListMessage_1.default,
59
- ol: OrderedListMessage_1.default,
60
+ ol: (props) => react_1.default.createElement(OrderedListMessage_1.default, Object.assign({}, props)),
60
61
  li: ListItemMessage_1.default
61
62
  }, remarkPlugins: [remark_gfm_1.default] }, content)),
62
63
  !isLoading && sources && react_1.default.createElement(SourcesCard_1.default, Object.assign({}, sources)),
64
+ quickStarts && quickStarts.quickStart && (react_1.default.createElement(QuickStartTile_1.default, { quickStart: quickStarts.quickStart, onSelectQuickStart: quickStarts.onSelectQuickStart, minuteWord: quickStarts.minuteWord, minuteWordPlural: quickStarts.minuteWordPlural, prerequisiteWord: quickStarts.prerequisiteWord, prerequisiteWordPlural: quickStarts.prerequisiteWordPlural, quickStartButtonAriaLabel: quickStarts.quickStartButtonAriaLabel })),
63
65
  !isLoading && actions && react_1.default.createElement(ResponseActions_1.default, { actions: actions }),
64
66
  !isLoading && quickResponses && (react_1.default.createElement(react_core_1.LabelGroup, Object.assign({ className: `pf-chatbot__message-quick-response ${quickResponseContainerProps === null || quickResponseContainerProps === void 0 ? void 0 : quickResponseContainerProps.className}` }, quickResponseContainerProps), quickResponses.map((_a) => {
65
67
  var { id, onClick, content } = _a, props = __rest(_a, ["id", "onClick", "content"]);
@@ -17,6 +17,8 @@ const react_2 = require("@testing-library/react");
17
17
  require("@testing-library/jest-dom");
18
18
  const Message_1 = __importDefault(require("./Message"));
19
19
  const user_event_1 = __importDefault(require("@testing-library/user-event"));
20
+ const monitor_sampleapp_quickstart_1 = require("./QuickStarts/monitor-sampleapp-quickstart");
21
+ const monitor_sampleapp_quickstart_with_image_1 = require("./QuickStarts/monitor-sampleapp-quickstart-with-image");
20
22
  const ALL_ACTIONS = [
21
23
  { label: /Good response/i },
22
24
  { label: /Bad response/i },
@@ -60,6 +62,21 @@ spec:
60
62
  url: https://raw.githubusercontent.com/Azure-Samples/helm-charts/master/docs
61
63
  `;
62
64
  const INLINE_CODE = `Here is an inline code - \`() => void\``;
65
+ const ORDERED_LIST_WITH_CODE = `
66
+ 1. Item 1
67
+ 2. Item 2
68
+
69
+ \`\`\`yaml
70
+ - name: Hello World Playbook
71
+ hosts: localhost
72
+ tasks:
73
+ - name: Print Hello World
74
+ ansible.builtin.debug:
75
+ msg: "Hello, World!"
76
+ \`\`\`
77
+
78
+ 3. Item 3
79
+ `;
63
80
  const checkListItemsRendered = () => {
64
81
  const items = ['Item 1', 'Item 2', 'Item 3'];
65
82
  expect(react_2.screen.getAllByRole('listitem')).toHaveLength(3);
@@ -280,6 +297,12 @@ describe('Message', () => {
280
297
  expect(react_2.screen.getByText('Here is an ordered list:')).toBeTruthy();
281
298
  checkListItemsRendered();
282
299
  });
300
+ it('should render ordered lists correctly if there is interstitial content', () => {
301
+ (0, react_2.render)(react_1.default.createElement(Message_1.default, { avatar: "./img", role: "user", name: "User", content: ORDERED_LIST_WITH_CODE }));
302
+ checkListItemsRendered();
303
+ const list = react_2.screen.getAllByRole('list')[1];
304
+ expect(list).toHaveAttribute('start', '3');
305
+ });
283
306
  it('should render inline code', () => {
284
307
  (0, react_2.render)(react_1.default.createElement(Message_1.default, { avatar: "./img", role: "user", name: "User", content: INLINE_CODE }));
285
308
  expect(react_2.screen.getByText(/() => void/i)).toBeTruthy();
@@ -332,4 +355,32 @@ describe('Message', () => {
332
355
  expect(react_2.screen.getByRole('img')).toHaveClass('test');
333
356
  expect(react_2.screen.getByRole('img')).toHaveClass('pf-chatbot__message-avatar');
334
357
  });
358
+ it('should handle QuickStart tile correctly', () => {
359
+ (0, react_2.render)(react_1.default.createElement(Message_1.default, { avatar: "./img", role: "user", name: "User", content: "Hi", quickStarts: {
360
+ quickStart: monitor_sampleapp_quickstart_1.monitorSampleAppQuickStart,
361
+ onSelectQuickStart: (id) => alert(id)
362
+ } }));
363
+ expect(react_2.screen.getByRole('button', { name: 'Monitoring your sample application' })).toBeTruthy();
364
+ expect(react_2.screen.getByRole('heading', { name: '1 Prerequisite' })).toBeTruthy();
365
+ expect(react_2.screen.getByRole('button', { name: 'Show prerequisites' })).toBeTruthy();
366
+ expect(react_2.screen.getByRole('button', { name: 'Start' })).toBeTruthy();
367
+ });
368
+ it('should handle click on QuickStart tile correctly', () => __awaiter(void 0, void 0, void 0, function* () {
369
+ const spy = jest.fn();
370
+ (0, react_2.render)(react_1.default.createElement(Message_1.default, { avatar: "./img", role: "user", name: "User", content: "Hi", quickStarts: {
371
+ quickStart: monitor_sampleapp_quickstart_1.monitorSampleAppQuickStart,
372
+ onSelectQuickStart: (id) => spy(id)
373
+ } }));
374
+ yield user_event_1.default.click(react_2.screen.getByRole('button', { name: 'Monitoring your sample application' }));
375
+ expect(spy).toHaveBeenCalledTimes(1);
376
+ expect(spy).toHaveBeenCalledWith(monitor_sampleapp_quickstart_1.monitorSampleAppQuickStart.metadata.name);
377
+ }));
378
+ it('should handle QuickStart tile with image correctly', () => __awaiter(void 0, void 0, void 0, function* () {
379
+ const spy = jest.fn();
380
+ (0, react_2.render)(react_1.default.createElement(Message_1.default, { avatar: "./img", role: "user", name: "User", content: "Hi", quickStarts: {
381
+ quickStart: monitor_sampleapp_quickstart_with_image_1.monitorSampleAppQuickStartWithImage,
382
+ onSelectQuickStart: (id) => spy(id)
383
+ } }));
384
+ expect(react_2.screen.getAllByRole('img')[1]).toHaveAttribute('src', 'test.png');
385
+ }));
335
386
  });
@@ -0,0 +1,13 @@
1
+ import * as React from 'react';
2
+ interface FallbackImgProps {
3
+ /** Image source */
4
+ src: string;
5
+ /** Alt text for image */
6
+ alt?: string;
7
+ /** ClassName applied to image */
8
+ className?: string;
9
+ /** Fallback */
10
+ fallback?: React.ReactNode;
11
+ }
12
+ declare const FallbackImg: React.FC<FallbackImgProps>;
13
+ export default FallbackImg;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ const React = __importStar(require("react"));
27
+ const FallbackImg = ({ src, alt, className, fallback }) => {
28
+ const [isSrcValid, setIsSrcValid] = React.useState(true);
29
+ if (src && isSrcValid) {
30
+ return React.createElement("img", { className: className, src: src, alt: alt, onError: () => setIsSrcValid(false) });
31
+ }
32
+ return React.createElement(React.Fragment, null, fallback);
33
+ };
34
+ exports.default = FallbackImg;
@@ -0,0 +1,27 @@
1
+ import * as React from 'react';
2
+ import { QuickStart, QuickstartAction } from './types';
3
+ export declare const camelize: (str: string) => string;
4
+ export interface QuickStartTileProps {
5
+ /** ClassName applied to the card */
6
+ className?: string;
7
+ /** The quickstart object triggered by this tile */
8
+ quickStart: QuickStart;
9
+ /** Event handler attached to the tile */
10
+ onClick?: () => void;
11
+ /** Action config for button rendered next to title */
12
+ action?: QuickstartAction;
13
+ /** Callback that returns active quick start value when clicked */
14
+ onSelectQuickStart: (id?: string) => void;
15
+ /** Label for the English word "minute". */
16
+ minuteWord?: string;
17
+ /** Label for the English word "minutes". */
18
+ minuteWordPlural?: string;
19
+ /** Label for the English word "Prerequisite" */
20
+ prerequisiteWord?: string;
21
+ /** Label for the English word "Prerequisites" */
22
+ prerequisiteWordPlural?: string;
23
+ /** Aria-label for the quick start description button */
24
+ quickStartButtonAriaLabel?: string;
25
+ }
26
+ declare const QuickStartTile: React.FC<QuickStartTileProps>;
27
+ export default QuickStartTile;
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.camelize = void 0;
30
+ const React = __importStar(require("react"));
31
+ const rocket_icon_1 = __importDefault(require("@patternfly/react-icons/dist/js/icons/rocket-icon"));
32
+ const outlined_bookmark_icon_1 = __importDefault(require("@patternfly/react-icons/dist/js/icons/outlined-bookmark-icon"));
33
+ const react_core_1 = require("@patternfly/react-core");
34
+ const outlined_clock_icon_1 = __importDefault(require("@patternfly/react-icons/dist/js/icons/outlined-clock-icon"));
35
+ const QuickStartTileHeader_1 = __importDefault(require("./QuickStartTileHeader"));
36
+ const QuickStartTileDescription_1 = __importDefault(require("./QuickStartTileDescription"));
37
+ const FallbackImg_1 = __importDefault(require("./FallbackImg"));
38
+ const camelize = (str) => str.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, function (match, index) {
39
+ if (+match === 0) {
40
+ return '';
41
+ } // or if (/\s+/.test(match)) for white spaces
42
+ return index === 0 ? match.toLowerCase() : match.toUpperCase();
43
+ });
44
+ exports.camelize = camelize;
45
+ const QuickStartTile = ({ className, quickStart, onClick, onSelectQuickStart, minuteWord = 'minute', minuteWordPlural = 'minutes', prerequisiteWord, prerequisiteWordPlural, quickStartButtonAriaLabel, action }) => {
46
+ const { metadata: { name: id }, spec: { icon, displayName, description, durationMinutes, prerequisites, link, type } } = quickStart;
47
+ let quickStartIcon;
48
+ if (typeof icon === 'object') {
49
+ quickStartIcon = React.createElement(react_core_1.Icon, { size: "2xl" }, icon);
50
+ }
51
+ else {
52
+ quickStartIcon = (React.createElement(react_core_1.Icon, { size: "2xl" },
53
+ React.createElement(FallbackImg_1.default, { src: icon, alt: "", className: "pfext-catalog-item-icon__img", fallback: React.createElement(rocket_icon_1.default, null) })));
54
+ }
55
+ const onSelect = () => {
56
+ if (!link) {
57
+ onSelectQuickStart(id);
58
+ }
59
+ else {
60
+ window.open(link.href, '_blank', 'noopener,noreferrer');
61
+ }
62
+ onClick && onClick();
63
+ };
64
+ const ActionIcon = (action === null || action === void 0 ? void 0 : action.icon) || outlined_bookmark_icon_1.default;
65
+ const additionalAction = action ? (React.createElement(react_core_1.Button, Object.assign({ "aria-label": action['aria-label'], icon: React.createElement(ActionIcon, null), variant: "plain", onClick: action.onClick }, action.buttonProps))) : undefined;
66
+ return (React.createElement(react_core_1.Card, { className: `pf-chatbot__quickstarts-tile ${className ? className : ''}`, id: `${id}-chatbot-qs-tile`, style: { height: '100%' }, "data-testid": `chatbot-qs-card-${(0, exports.camelize)(displayName)}` },
67
+ React.createElement(react_core_1.CardHeader, Object.assign({}, (action && {
68
+ actions: { actions: additionalAction }
69
+ })), quickStartIcon),
70
+ React.createElement(react_core_1.CardTitle, null,
71
+ React.createElement(QuickStartTileHeader_1.default, { name: displayName, onSelect: onSelect, quickStartId: id })),
72
+ React.createElement(react_core_1.CardBody, null,
73
+ React.createElement(react_core_1.Stack, { hasGutter: true },
74
+ React.createElement(react_core_1.Flex, { spaceItems: { default: 'spaceItemsSm' } },
75
+ type && React.createElement(react_core_1.Label, { color: type.color }, type.text),
76
+ durationMinutes && (React.createElement(react_core_1.Label, { variant: "outline", "data-test": "duration", icon: React.createElement(outlined_clock_icon_1.default, null) }, (0, react_core_1.pluralize)(durationMinutes, minuteWord, minuteWordPlural)))),
77
+ React.createElement(QuickStartTileDescription_1.default, { description: description, prerequisites: prerequisites, prerequisiteWord: prerequisiteWord, prerequisiteWordPlural: prerequisiteWordPlural, quickStartButtonAriaLabel: quickStartButtonAriaLabel }))),
78
+ React.createElement(react_core_1.CardFooter, null,
79
+ React.createElement(react_core_1.Button, { variant: "link", isInline: true, onClick: onSelect },
80
+ React.createElement("span", { className: "pf-v6-c-button__text" }, "Start")))));
81
+ };
82
+ exports.default = QuickStartTile;
@@ -0,0 +1,23 @@
1
+ import * as React from 'react';
2
+ interface QuickStartTileDescriptionProps {
3
+ /** QuickStart description */
4
+ description: string;
5
+ /** QuickStart prerequisites */
6
+ prerequisites?: string[];
7
+ /** Label for the English word "Prerequisite" */
8
+ prerequisiteWord?: string;
9
+ /** Label for the English word "Prerequisites" */
10
+ prerequisiteWordPlural?: string;
11
+ /** Aria-label for the quick start button */
12
+ quickStartButtonAriaLabel?: string;
13
+ }
14
+ /** This function is a helper for pluralizing strings stolen from React.
15
+ *
16
+ * @param {number} i The quantity of the string you want to pluralize
17
+ * @param {string} singular The singular version of the string
18
+ * @param {string} plural The change to the string that should occur if the quantity is not equal to 1.
19
+ * Defaults to adding an 's'.
20
+ */
21
+ export declare function pluralizeWord(i: number, singular: string, plural?: string): string;
22
+ declare const QuickStartTileDescription: React.FC<QuickStartTileDescriptionProps>;
23
+ export default QuickStartTileDescription;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.pluralizeWord = pluralizeWord;
30
+ const React = __importStar(require("react"));
31
+ const react_core_1 = require("@patternfly/react-core");
32
+ const info_circle_icon_1 = __importDefault(require("@patternfly/react-icons/dist/js/icons/info-circle-icon"));
33
+ /** This function is a helper for pluralizing strings stolen from React.
34
+ *
35
+ * @param {number} i The quantity of the string you want to pluralize
36
+ * @param {string} singular The singular version of the string
37
+ * @param {string} plural The change to the string that should occur if the quantity is not equal to 1.
38
+ * Defaults to adding an 's'.
39
+ */
40
+ function pluralizeWord(i, singular, plural) {
41
+ if (!plural) {
42
+ plural = `${singular}s`;
43
+ }
44
+ return `${i === 1 ? singular : plural}`;
45
+ }
46
+ const QuickStartTileDescription = ({ description, prerequisites, prerequisiteWord = 'Prerequisite', prerequisiteWordPlural = 'Prerequisites', quickStartButtonAriaLabel = 'Show prerequisites' }) => {
47
+ const prereqs = prerequisites === null || prerequisites === void 0 ? void 0 : prerequisites.filter((p) => p);
48
+ const buttonRef = React.useRef(null);
49
+ const pluralizedPrereq = pluralizeWord((prereqs === null || prereqs === void 0 ? void 0 : prereqs.length) || 0, prerequisiteWord, prerequisiteWordPlural);
50
+ return (React.createElement(React.Fragment, null,
51
+ description,
52
+ prereqs && prereqs.length > 0 && (React.createElement(react_core_1.Flex, { spaceItems: { default: 'spaceItemsSm' } },
53
+ React.createElement("h5", null, (0, react_core_1.pluralize)(prereqs.length, prerequisiteWord, prerequisiteWordPlural)),
54
+ React.createElement(react_core_1.Button, { variant: "link", isInline: true, "data-testid": "qs-card-prereqs", ref: buttonRef, onClick: (e) => {
55
+ e.preventDefault();
56
+ e.stopPropagation();
57
+ }, "aria-label": quickStartButtonAriaLabel },
58
+ React.createElement(info_circle_icon_1.default, null)),
59
+ React.createElement(react_core_1.Popover, { "aria-label": pluralizedPrereq, headerContent: pluralizedPrereq, triggerRef: buttonRef, bodyContent: React.createElement("div", null,
60
+ React.createElement("ul", { "aria-label": pluralizedPrereq }, prereqs.map((prerequisite, index) => (
61
+ // eslint-disable-next-line react/no-array-index-key
62
+ React.createElement("li", { key: index }, prerequisite))))) })))));
63
+ };
64
+ exports.default = QuickStartTileDescription;
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ var __importDefault = (this && this.__importDefault) || function (mod) {
35
+ return (mod && mod.__esModule) ? mod : { "default": mod };
36
+ };
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ const react_1 = __importDefault(require("react"));
39
+ const react_2 = require("@testing-library/react");
40
+ require("@testing-library/jest-dom");
41
+ const user_event_1 = __importDefault(require("@testing-library/user-event"));
42
+ const monitor_sampleapp_quickstart_1 = require("./monitor-sampleapp-quickstart");
43
+ const QuickStartTileDescription_1 = __importStar(require("./QuickStartTileDescription"));
44
+ describe('pluralizeWord function', () => {
45
+ it('should render no plural correctly', () => {
46
+ expect((0, QuickStartTileDescription_1.pluralizeWord)(2, 'pizza')).toBe('pizzas');
47
+ });
48
+ });
49
+ describe('QuickStart tile description', () => {
50
+ it('should render no prereqs correctly', () => {
51
+ (0, react_2.render)(react_1.default.createElement(QuickStartTileDescription_1.default, { description: monitor_sampleapp_quickstart_1.monitorSampleAppQuickStart.spec.description }));
52
+ expect(react_2.screen.queryByRole('heading')).toBeFalsy();
53
+ });
54
+ it('should render singular prereq correctly', () => {
55
+ (0, react_2.render)(react_1.default.createElement(QuickStartTileDescription_1.default, { description: monitor_sampleapp_quickstart_1.monitorSampleAppQuickStart.spec.description, prerequisites: [`You completed the "Getting started with a sample" quick start.`] }));
56
+ expect(react_2.screen.getByRole('heading', { name: /1 Prerequisite/i })).toBeTruthy();
57
+ expect(react_2.screen.getByRole('button', { name: /Show prerequisite/i })).toBeTruthy();
58
+ });
59
+ it('should render plural prereq correctly', () => {
60
+ (0, react_2.render)(react_1.default.createElement(QuickStartTileDescription_1.default, { description: monitor_sampleapp_quickstart_1.monitorSampleAppQuickStart.spec.description, prerequisites: [
61
+ `You completed the "Getting started with a sample" quick start.`,
62
+ `You completed the app quick start`
63
+ ] }));
64
+ expect(react_2.screen.getByRole('heading', { name: /2 Prerequisites/i })).toBeTruthy();
65
+ expect(react_2.screen.getByRole('button', { name: /Show prerequisites/i })).toBeTruthy();
66
+ });
67
+ it('should be able to click prereqs link', () => __awaiter(void 0, void 0, void 0, function* () {
68
+ (0, react_2.render)(react_1.default.createElement(QuickStartTileDescription_1.default, { description: monitor_sampleapp_quickstart_1.monitorSampleAppQuickStart.spec.description, prerequisites: [`You completed the "Getting started with a sample" quick start.`] }));
69
+ const button = react_2.screen.getByRole('button', { name: /Show prerequisites/i });
70
+ expect(react_2.screen.queryByRole('dialog', { name: /Prerequisite/i })).toBeFalsy();
71
+ yield user_event_1.default.click(button);
72
+ expect(react_2.screen.getByRole('dialog', { name: /Prerequisite/i })).toBeTruthy();
73
+ expect(react_2.screen.getByRole('button', { name: /Close/i })).toBeTruthy();
74
+ expect(react_2.screen.getByText(/You completed the "Getting started with a sample" quick start./i)).toBeTruthy();
75
+ }));
76
+ });
@@ -0,0 +1,11 @@
1
+ import * as React from 'react';
2
+ interface QuickStartTileHeaderProps {
3
+ /** Name for the header */
4
+ name: string;
5
+ /** Id for the QuickStart */
6
+ quickStartId?: string;
7
+ /** Callback for when the name of the QuickStart is clicked */
8
+ onSelect: (e: React.FormEvent<HTMLInputElement> | React.MouseEvent<Element, MouseEvent>) => void;
9
+ }
10
+ declare const QuickStartTileHeader: React.FC<QuickStartTileHeaderProps>;
11
+ export default QuickStartTileHeader;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ const React = __importStar(require("react"));
27
+ const react_core_1 = require("@patternfly/react-core");
28
+ const QuickStartTileHeader = ({ name, quickStartId, onSelect }) => (React.createElement(react_core_1.Flex, { flexWrap: { default: 'nowrap' } },
29
+ React.createElement(react_core_1.Button, { "data-test": "title", id: quickStartId, variant: "link", isInline: true, onClick: onSelect }, name)));
30
+ exports.default = QuickStartTileHeader;
@@ -0,0 +1,30 @@
1
+ export declare const monitorSampleAppQuickStartWithImage: {
2
+ apiVersion: string;
3
+ kind: string;
4
+ metadata: {
5
+ name: string;
6
+ };
7
+ spec: {
8
+ icon: string;
9
+ version: number;
10
+ displayName: string;
11
+ durationMinutes: number;
12
+ description: string;
13
+ prerequisites: string[];
14
+ introduction: string;
15
+ tasks: {
16
+ title: string;
17
+ description: string;
18
+ review: {
19
+ instructions: string;
20
+ failedTaskHelp: string;
21
+ };
22
+ summary: {
23
+ success: string;
24
+ failed: string;
25
+ };
26
+ }[];
27
+ conclusion: string;
28
+ nextQuickStart: string[];
29
+ };
30
+ };
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.monitorSampleAppQuickStartWithImage = void 0;
4
+ exports.monitorSampleAppQuickStartWithImage = {
5
+ apiVersion: 'console.openshift.io/v1',
6
+ kind: 'QuickStarts',
7
+ metadata: {
8
+ name: 'monitor-sampleapp'
9
+ },
10
+ spec: {
11
+ icon: 'test.png', // this is only difference
12
+ version: 4.7,
13
+ displayName: 'Monitoring your sample application',
14
+ durationMinutes: 10,
15
+ description: `Now that you’ve created a sample application and added health checks, let’s monitor your application.`,
16
+ prerequisites: [`You completed the "Getting started with a sample" quick start.`],
17
+ introduction: `### This quick start shows you how to monitor your sample application.
18
+ You should have previously created the **sample-app** application and **nodejs-sample** deployment via the **Get started with a sample** quick start. If you haven't, you may be able to follow these tasks with any existing deployment.`,
19
+ tasks: [
20
+ {
21
+ title: `Viewing the monitoring details of your sample application`,
22
+ description: `### To view the details of your sample application:
23
+ 1. Go to the project your sample application was created in.
24
+ 2. In the **</> Developer** perspective, go to **Topology** view.
25
+ 3. Click on the **nodejs-sample** deployment to view its details.
26
+ 4. Click on the **Monitoring** tab in the side panel.
27
+ You can see context sensitive metrics and alerts in the **Monitoring** tab.`,
28
+ review: {
29
+ instructions: `#### To verify you can view the monitoring information:
30
+ 1. Do you see a **Metrics** accordion in the side panel?
31
+ 2. Do you see a **View monitoring dashboard** link in the **Metrics** accordion?
32
+ 3. Do you see three charts in the **Metrics** accordion: **CPU Usage**, **Memory Usage** and **Receive Bandwidth**?`,
33
+ failedTaskHelp: `This task isn’t verified yet. Try the task again.`
34
+ },
35
+ summary: {
36
+ success: `You have learned how you can monitor your sample app!`,
37
+ failed: `Try the steps again.`
38
+ }
39
+ },
40
+ {
41
+ title: `Viewing your project monitoring dashboard`,
42
+ description: `### To view the project monitoring dashboard in the context of **nodejs-sample**:
43
+ 1. Click on the **View monitoring dashboard** link in the side panel.
44
+ 2. You can change the **Time Range** and **Refresh Interval** of the dashboard.
45
+ 3. You can change the context of the dashboard as well by clicking on the drop-down list. Select a specific workload or **All Workloads** to view the dashboard in the context of the entire project.`,
46
+ review: {
47
+ instructions: `#### To verify that you are able to view the monitoring dashboard:
48
+ Do you see metrics charts in the dashboard?`,
49
+ failedTaskHelp: `This task isn’t verified yet. Try the task again.`
50
+ },
51
+ summary: {
52
+ success: `You have learned how to view the dashboard in the context of your sample app!`,
53
+ failed: `Try the steps again.`
54
+ }
55
+ },
56
+ {
57
+ title: `Viewing custom metrics`,
58
+ description: `### To view custom metrics:
59
+ 1. Click on the **Metrics** tab of the **Monitoring** page.
60
+ 2. Click the **Select Query** drop-down list to see the available queries.
61
+ 3. Click on **Filesystem Usage** from the list to run the query.`,
62
+ review: {
63
+ instructions: `#### Verify you can see the chart associated with the query:
64
+ Do you see a chart displayed with filesystem usage for your project? Note: select **Custom Query** from the dropdown to create and run a custom query utilizing PromQL.
65
+ `,
66
+ failedTaskHelp: `This task isn’t verified yet. Try the task again.`
67
+ },
68
+ summary: {
69
+ success: `You have learned how to run a query!`,
70
+ failed: `Try the steps again.`
71
+ }
72
+ }
73
+ ],
74
+ conclusion: `You have learned how to access workload monitoring and metrics!`,
75
+ nextQuickStart: [``]
76
+ }
77
+ };