@patternfly/chatbot 2.1.0 → 2.2.0-prerelease.10

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 (177) hide show
  1. package/dist/cjs/Chatbot/Chatbot.js +0 -9
  2. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +5 -1
  3. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +4 -4
  4. package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +3 -3
  5. package/dist/cjs/ChatbotHeader/ChatbotHeaderCloseButton.d.ts +17 -0
  6. package/dist/cjs/ChatbotHeader/ChatbotHeaderCloseButton.js +14 -0
  7. package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.d.ts +2 -0
  8. package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.js +2 -2
  9. package/dist/cjs/ChatbotHeader/index.d.ts +1 -0
  10. package/dist/cjs/ChatbotHeader/index.js +1 -0
  11. package/dist/cjs/CodeModal/CodeModal.js +2 -12
  12. package/dist/cjs/Message/ListMessage/OrderedListMessage.d.ts +1 -1
  13. package/dist/cjs/Message/ListMessage/OrderedListMessage.js +2 -2
  14. package/dist/cjs/Message/Message.d.ts +16 -6
  15. package/dist/cjs/Message/Message.js +6 -6
  16. package/dist/cjs/Message/Message.test.js +51 -0
  17. package/dist/cjs/Message/QuickResponse/QuickResponse.d.ts +15 -0
  18. package/dist/cjs/Message/QuickResponse/QuickResponse.js +33 -0
  19. package/dist/cjs/Message/QuickStarts/FallbackImg.d.ts +13 -0
  20. package/dist/cjs/Message/QuickStarts/FallbackImg.js +34 -0
  21. package/dist/cjs/Message/QuickStarts/QuickStartTile.d.ts +27 -0
  22. package/dist/cjs/Message/QuickStarts/QuickStartTile.js +82 -0
  23. package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.d.ts +23 -0
  24. package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.js +64 -0
  25. package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.test.d.ts +1 -0
  26. package/dist/cjs/Message/QuickStarts/QuickStartTileDescription.test.js +76 -0
  27. package/dist/cjs/Message/QuickStarts/QuickStartTileHeader.d.ts +11 -0
  28. package/dist/cjs/Message/QuickStarts/QuickStartTileHeader.js +30 -0
  29. package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.d.ts +30 -0
  30. package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.js +77 -0
  31. package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart.d.ts +30 -0
  32. package/dist/cjs/Message/QuickStarts/monitor-sampleapp-quickstart.js +77 -0
  33. package/dist/cjs/Message/QuickStarts/types.d.ts +132 -0
  34. package/dist/cjs/Message/QuickStarts/types.js +17 -0
  35. package/dist/cjs/MessageBar/SendButton.js +1 -1
  36. package/dist/cjs/ResponseActions/ResponseActionButton.d.ts +6 -0
  37. package/dist/cjs/ResponseActions/ResponseActionButton.js +10 -2
  38. package/dist/cjs/ResponseActions/ResponseActionButton.test.d.ts +1 -0
  39. package/dist/cjs/ResponseActions/ResponseActionButton.test.js +54 -0
  40. package/dist/cjs/ResponseActions/ResponseActions.d.ts +4 -0
  41. package/dist/cjs/ResponseActions/ResponseActions.js +26 -9
  42. package/dist/cjs/ResponseActions/ResponseActions.test.js +79 -5
  43. package/dist/cjs/Settings/SettingsForm.d.ts +13 -0
  44. package/dist/cjs/Settings/SettingsForm.js +27 -0
  45. package/dist/cjs/Settings/index.d.ts +2 -0
  46. package/dist/cjs/Settings/index.js +23 -0
  47. package/dist/cjs/TermsOfUse/TermsOfUse.d.ts +34 -0
  48. package/dist/cjs/TermsOfUse/TermsOfUse.js +49 -0
  49. package/dist/cjs/TermsOfUse/TermsOfUse.test.d.ts +1 -0
  50. package/dist/cjs/TermsOfUse/TermsOfUse.test.js +79 -0
  51. package/dist/cjs/TermsOfUse/index.d.ts +2 -0
  52. package/dist/cjs/TermsOfUse/index.js +23 -0
  53. package/dist/cjs/index.d.ts +4 -0
  54. package/dist/cjs/index.js +7 -1
  55. package/dist/css/main.css +191 -30
  56. package/dist/css/main.css.map +1 -1
  57. package/dist/dynamic/Settings/package.json +1 -0
  58. package/dist/dynamic/TermsOfUse/package.json +1 -0
  59. package/dist/esm/Chatbot/Chatbot.js +0 -9
  60. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +5 -1
  61. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +4 -4
  62. package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +3 -3
  63. package/dist/esm/ChatbotHeader/ChatbotHeaderCloseButton.d.ts +17 -0
  64. package/dist/esm/ChatbotHeader/ChatbotHeaderCloseButton.js +8 -0
  65. package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.d.ts +2 -0
  66. package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.js +2 -2
  67. package/dist/esm/ChatbotHeader/index.d.ts +1 -0
  68. package/dist/esm/ChatbotHeader/index.js +1 -0
  69. package/dist/esm/CodeModal/CodeModal.js +2 -12
  70. package/dist/esm/Message/ListMessage/OrderedListMessage.d.ts +1 -1
  71. package/dist/esm/Message/ListMessage/OrderedListMessage.js +2 -2
  72. package/dist/esm/Message/Message.d.ts +16 -6
  73. package/dist/esm/Message/Message.js +7 -7
  74. package/dist/esm/Message/Message.test.js +51 -0
  75. package/dist/esm/Message/QuickResponse/QuickResponse.d.ts +15 -0
  76. package/dist/esm/Message/QuickResponse/QuickResponse.js +26 -0
  77. package/dist/esm/Message/QuickStarts/FallbackImg.d.ts +13 -0
  78. package/dist/esm/Message/QuickStarts/FallbackImg.js +9 -0
  79. package/dist/esm/Message/QuickStarts/QuickStartTile.d.ts +27 -0
  80. package/dist/esm/Message/QuickStarts/QuickStartTile.js +52 -0
  81. package/dist/esm/Message/QuickStarts/QuickStartTileDescription.d.ts +23 -0
  82. package/dist/esm/Message/QuickStarts/QuickStartTileDescription.js +35 -0
  83. package/dist/esm/Message/QuickStarts/QuickStartTileDescription.test.d.ts +1 -0
  84. package/dist/esm/Message/QuickStarts/QuickStartTileDescription.test.js +48 -0
  85. package/dist/esm/Message/QuickStarts/QuickStartTileHeader.d.ts +11 -0
  86. package/dist/esm/Message/QuickStarts/QuickStartTileHeader.js +5 -0
  87. package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.d.ts +30 -0
  88. package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.js +74 -0
  89. package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart.d.ts +30 -0
  90. package/dist/esm/Message/QuickStarts/monitor-sampleapp-quickstart.js +74 -0
  91. package/dist/esm/Message/QuickStarts/types.d.ts +132 -0
  92. package/dist/esm/Message/QuickStarts/types.js +14 -0
  93. package/dist/esm/MessageBar/SendButton.js +1 -1
  94. package/dist/esm/ResponseActions/ResponseActionButton.d.ts +6 -0
  95. package/dist/esm/ResponseActions/ResponseActionButton.js +10 -2
  96. package/dist/esm/ResponseActions/ResponseActionButton.test.d.ts +1 -0
  97. package/dist/esm/ResponseActions/ResponseActionButton.test.js +49 -0
  98. package/dist/esm/ResponseActions/ResponseActions.d.ts +4 -0
  99. package/dist/esm/ResponseActions/ResponseActions.js +26 -9
  100. package/dist/esm/ResponseActions/ResponseActions.test.js +79 -5
  101. package/dist/esm/Settings/SettingsForm.d.ts +13 -0
  102. package/dist/esm/Settings/SettingsForm.js +20 -0
  103. package/dist/esm/Settings/index.d.ts +2 -0
  104. package/dist/esm/Settings/index.js +2 -0
  105. package/dist/esm/TermsOfUse/TermsOfUse.d.ts +34 -0
  106. package/dist/esm/TermsOfUse/TermsOfUse.js +42 -0
  107. package/dist/esm/TermsOfUse/TermsOfUse.test.d.ts +1 -0
  108. package/dist/esm/TermsOfUse/TermsOfUse.test.js +74 -0
  109. package/dist/esm/TermsOfUse/index.d.ts +2 -0
  110. package/dist/esm/TermsOfUse/index.js +2 -0
  111. package/dist/esm/index.d.ts +4 -0
  112. package/dist/esm/index.js +4 -0
  113. package/dist/tsconfig.tsbuildinfo +1 -1
  114. package/package.json +7 -13
  115. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithCustomResponseActions.tsx +4 -0
  116. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithQuickStart.tsx +31 -0
  117. package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +26 -4
  118. package/patternfly-docs/content/extensions/chatbot/examples/Messages/explore-pipeline-quickstart.ts +65 -0
  119. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotFooter.tsx +1 -1
  120. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotFootnote.tsx +2 -2
  121. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawer.tsx +2 -2
  122. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerNavigation.tsx +67 -0
  123. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerWithSelection.tsx +78 -0
  124. package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotMessageBarDisabled.tsx +26 -0
  125. package/patternfly-docs/content/extensions/chatbot/examples/UI/PF-TermsAndConditionsHeader.svg +148 -0
  126. package/patternfly-docs/content/extensions/chatbot/examples/UI/Settings.tsx +289 -0
  127. package/patternfly-docs/content/extensions/chatbot/examples/UI/SquareChatbotToggle.tsx +1 -1
  128. package/patternfly-docs/content/extensions/chatbot/examples/UI/TermsOfUse.tsx +147 -0
  129. package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +56 -0
  130. package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.md +2 -2
  131. package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.tsx +2 -2
  132. package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotAttachment.tsx +20 -19
  133. package/patternfly-docs/content/extensions/chatbot/examples/demos/ChatbotAttachmentMenu.tsx +1 -1
  134. package/patternfly-docs/content/extensions/chatbot/examples/demos/EmbeddedChatbot.tsx +2 -2
  135. package/src/Chatbot/Chatbot.scss +0 -10
  136. package/src/Chatbot/Chatbot.tsx +0 -9
  137. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +14 -0
  138. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx +3 -3
  139. package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx +11 -3
  140. package/src/ChatbotFooter/ChatbotFooter.scss +2 -1
  141. package/src/ChatbotHeader/ChatbotHeaderCloseButton.tsx +51 -0
  142. package/src/ChatbotHeader/ChatbotHeaderMenu.tsx +5 -2
  143. package/src/ChatbotHeader/index.ts +1 -0
  144. package/src/CodeModal/CodeModal.scss +8 -0
  145. package/src/CodeModal/CodeModal.tsx +2 -13
  146. package/src/FileDropZone/__snapshots__/FileDropZone.test.tsx.snap +1 -1
  147. package/src/Message/ListMessage/OrderedListMessage.tsx +2 -2
  148. package/src/Message/Message.scss +0 -14
  149. package/src/Message/Message.test.tsx +76 -0
  150. package/src/Message/Message.tsx +35 -26
  151. package/src/Message/QuickResponse/QuickResponse.scss +33 -0
  152. package/src/Message/QuickResponse/QuickResponse.tsx +50 -0
  153. package/src/Message/QuickStarts/FallbackImg.tsx +24 -0
  154. package/src/Message/QuickStarts/QuickStartTile.scss +25 -0
  155. package/src/Message/QuickStarts/QuickStartTile.tsx +147 -0
  156. package/src/Message/QuickStarts/QuickStartTileDescription.test.tsx +57 -0
  157. package/src/Message/QuickStarts/QuickStartTileDescription.tsx +81 -0
  158. package/src/Message/QuickStarts/QuickStartTileHeader.tsx +21 -0
  159. package/src/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.ts +75 -0
  160. package/src/Message/QuickStarts/monitor-sampleapp-quickstart.ts +75 -0
  161. package/src/Message/QuickStarts/types.ts +154 -0
  162. package/src/MessageBar/SendButton.scss +24 -0
  163. package/src/MessageBar/SendButton.tsx +1 -1
  164. package/src/ResponseActions/ResponseActionButton.test.tsx +52 -0
  165. package/src/ResponseActions/ResponseActionButton.tsx +46 -27
  166. package/src/ResponseActions/ResponseActions.scss +10 -8
  167. package/src/ResponseActions/ResponseActions.test.tsx +103 -5
  168. package/src/ResponseActions/ResponseActions.tsx +54 -7
  169. package/src/Settings/Settings.scss +34 -0
  170. package/src/Settings/SettingsForm.tsx +25 -0
  171. package/src/Settings/index.ts +3 -0
  172. package/src/TermsOfUse/TermsOfUse.scss +66 -0
  173. package/src/TermsOfUse/TermsOfUse.test.tsx +138 -0
  174. package/src/TermsOfUse/TermsOfUse.tsx +117 -0
  175. package/src/TermsOfUse/index.ts +3 -0
  176. package/src/index.ts +6 -0
  177. package/src/main.scss +7 -3
@@ -0,0 +1,75 @@
1
+ export const monitorSampleAppQuickStart = {
2
+ apiVersion: 'console.openshift.io/v1',
3
+ kind: 'QuickStarts',
4
+ metadata: {
5
+ name: 'monitor-sampleapp'
6
+ },
7
+ spec: {
8
+ version: 4.7,
9
+ displayName: 'Monitoring your sample application',
10
+ durationMinutes: 10,
11
+ icon: '',
12
+ description: `Now that you’ve created a sample application and added health checks, let’s monitor your application.`,
13
+ prerequisites: [`You completed the "Getting started with a sample" quick start.`],
14
+ introduction: `### This quick start shows you how to monitor your sample application.
15
+ 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.`,
16
+ tasks: [
17
+ {
18
+ title: `Viewing the monitoring details of your sample application`,
19
+ description: `### To view the details of your sample application:
20
+ 1. Go to the project your sample application was created in.
21
+ 2. In the **</> Developer** perspective, go to **Topology** view.
22
+ 3. Click on the **nodejs-sample** deployment to view its details.
23
+ 4. Click on the **Monitoring** tab in the side panel.
24
+ You can see context sensitive metrics and alerts in the **Monitoring** tab.`,
25
+ review: {
26
+ instructions: `#### To verify you can view the monitoring information:
27
+ 1. Do you see a **Metrics** accordion in the side panel?
28
+ 2. Do you see a **View monitoring dashboard** link in the **Metrics** accordion?
29
+ 3. Do you see three charts in the **Metrics** accordion: **CPU Usage**, **Memory Usage** and **Receive Bandwidth**?`,
30
+ failedTaskHelp: `This task isn’t verified yet. Try the task again.`
31
+ },
32
+ summary: {
33
+ success: `You have learned how you can monitor your sample app!`,
34
+ failed: `Try the steps again.`
35
+ }
36
+ },
37
+ {
38
+ title: `Viewing your project monitoring dashboard`,
39
+ description: `### To view the project monitoring dashboard in the context of **nodejs-sample**:
40
+ 1. Click on the **View monitoring dashboard** link in the side panel.
41
+ 2. You can change the **Time Range** and **Refresh Interval** of the dashboard.
42
+ 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.`,
43
+ review: {
44
+ instructions: `#### To verify that you are able to view the monitoring dashboard:
45
+ Do you see metrics charts in the dashboard?`,
46
+ failedTaskHelp: `This task isn’t verified yet. Try the task again.`
47
+ },
48
+ summary: {
49
+ success: `You have learned how to view the dashboard in the context of your sample app!`,
50
+ failed: `Try the steps again.`
51
+ }
52
+ },
53
+ {
54
+ title: `Viewing custom metrics`,
55
+ description: `### To view custom metrics:
56
+ 1. Click on the **Metrics** tab of the **Monitoring** page.
57
+ 2. Click the **Select Query** drop-down list to see the available queries.
58
+ 3. Click on **Filesystem Usage** from the list to run the query.`,
59
+ review: {
60
+ instructions: `#### Verify you can see the chart associated with the query:
61
+ 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.
62
+ `,
63
+ failedTaskHelp: `This task isn’t verified yet. Try the task again.`
64
+ },
65
+ summary: {
66
+ success: `You have learned how to run a query!`,
67
+ failed: `Try the steps again.`
68
+ }
69
+ }
70
+ ],
71
+ conclusion: `You have learned how to access workload monitoring and metrics!`,
72
+
73
+ nextQuickStart: [``]
74
+ }
75
+ };
@@ -0,0 +1,154 @@
1
+ import { ButtonProps } from '@patternfly/react-core';
2
+
3
+ // These types are all from the QuickStart extension.
4
+ // We want to ensure parity, so be careful when adjusting these.
5
+ export interface AccessReviewResourceAttributes {
6
+ group?: string;
7
+ resource?: string;
8
+ subresource?: string;
9
+ verb?: K8sVerb;
10
+ name?: string;
11
+ namespace?: string;
12
+ }
13
+
14
+ export type K8sVerb = 'create' | 'get' | 'list' | 'update' | 'patch' | 'delete' | 'deletecollection' | 'watch';
15
+
16
+ export interface QuickStart {
17
+ apiVersion?: string;
18
+ kind?: string;
19
+ metadata: ObjectMetadata;
20
+ spec: QuickStartSpec;
21
+ }
22
+
23
+ export interface ObjectMetadata {
24
+ name: string;
25
+ annotations?: { [key: string]: string };
26
+ clusterName?: string;
27
+ creationTimestamp?: string;
28
+ deletionGracePeriodSeconds?: number;
29
+ deletionTimestamp?: string;
30
+ finalizers?: string[];
31
+ generateName?: string;
32
+ generation?: number;
33
+ labels?: { [key: string]: string };
34
+ managedFields?: any[];
35
+ namespace?: string;
36
+ ownerReferences?: OwnerReference[];
37
+ resourceVersion?: string;
38
+ uid?: string;
39
+ // language can be: en
40
+ language?: string;
41
+ // country can be: US
42
+ country?: string;
43
+ // locale is a combination of language and country, for example: en_US
44
+ locale?: string;
45
+ // anything else to custom define
46
+ [key: string]: any;
47
+ }
48
+
49
+ export interface OwnerReference {
50
+ name: string;
51
+ kind: string;
52
+ uid: string;
53
+ apiVersion: string;
54
+ controller?: boolean;
55
+ blockOwnerDeletion?: boolean;
56
+ }
57
+
58
+ export interface QuickStartTask {
59
+ title?: string;
60
+ description?: string;
61
+ review?: QuickStartTaskReview;
62
+ summary?: QuickStartTaskSummary;
63
+ proc?: string;
64
+ }
65
+
66
+ export interface QuickStartTaskReview {
67
+ instructions?: string;
68
+ failedTaskHelp?: string;
69
+ }
70
+
71
+ export interface QuickStartTaskSummary {
72
+ success?: string;
73
+ failed?: string;
74
+ }
75
+
76
+ export interface QuickstartAction {
77
+ /** Screen reader aria label. */
78
+ 'aria-label': string;
79
+ /** Icon to be rendered as a plain button, by default Bookmark outlined will be used. */
80
+ icon?: React.ComponentType<unknown>;
81
+ /** Callback with synthetic event parameter. */
82
+ onClick?: (e: React.SyntheticEvent) => void;
83
+ /** Additional button props to be rendered as extra props. */
84
+ buttonProps?: ButtonProps;
85
+ }
86
+
87
+ export interface QuickStart {
88
+ apiVersion?: string;
89
+ kind?: string;
90
+ metadata: ObjectMetadata;
91
+ spec: QuickStartSpec;
92
+ }
93
+
94
+ export interface QuickStartSpec {
95
+ version?: number;
96
+ displayName: string;
97
+ durationMinutes?: number;
98
+ icon: React.ReactNode;
99
+ description: string;
100
+ prerequisites?: string[];
101
+ introduction?: string;
102
+ tasks?: QuickStartTask[];
103
+ conclusion?: string;
104
+ nextQuickStart?: string[];
105
+ accessReviewResources?: AccessReviewResourceAttributes[];
106
+ link?: QuickStartExternal;
107
+ type?: QuickStartType;
108
+ }
109
+
110
+ export interface QuickStartTask {
111
+ title?: string;
112
+ description?: string;
113
+ review?: QuickStartTaskReview;
114
+ summary?: QuickStartTaskSummary;
115
+ proc?: string;
116
+ }
117
+
118
+ export interface QuickStartTaskReview {
119
+ instructions?: string;
120
+ failedTaskHelp?: string;
121
+ }
122
+
123
+ export interface QuickStartTaskSummary {
124
+ success?: string;
125
+ failed?: string;
126
+ }
127
+
128
+ export type AllQuickStartStates = Record<string, QuickStartState>;
129
+
130
+ export type QuickStartState = Record<string, string | number | QuickStartStatus>;
131
+
132
+ export enum QuickStartStatus {
133
+ COMPLETE = 'Complete',
134
+ IN_PROGRESS = 'In Progress',
135
+ NOT_STARTED = 'Not started'
136
+ }
137
+
138
+ export enum QuickStartTaskStatus {
139
+ INIT = 'Initial',
140
+ VISITED = 'Visited',
141
+ REVIEW = 'Review',
142
+ SUCCESS = 'Success',
143
+ FAILED = 'Failed'
144
+ }
145
+
146
+ export interface QuickStartExternal {
147
+ href: string;
148
+ text?: string;
149
+ }
150
+
151
+ export interface QuickStartType {
152
+ text: string;
153
+ color?: 'green' | 'purple' | 'grey' | 'blue' | 'orange' | 'red' | 'teal' | 'orangered' | 'yellow';
154
+ }
@@ -7,9 +7,14 @@
7
7
  width: 3rem;
8
8
  height: 3rem;
9
9
 
10
+ .pf-v6-c-button__icon {
11
+ --pf-v6-c-button__icon--Color: var(--pf-t--global--color--brand--default);
12
+ }
13
+
10
14
  &:hover,
11
15
  &:focus {
12
16
  background-color: var(--pf-t--chatbot--blue-icon--background--color--hover);
17
+ color: var(--pf-t--global--color--brand--hover);
13
18
 
14
19
  .pf-v6-c-button__icon {
15
20
  color: var(--pf-t--chatbot--blue-icon--fill--hover);
@@ -17,6 +22,25 @@
17
22
  }
18
23
  }
19
24
 
25
+ .pf-v6-theme-dark {
26
+ .pf-v6-c-button.pf-chatbot__button--send {
27
+ background-color: var(--pf-t--global--color--brand--default);
28
+ .pf-v6-c-button__icon {
29
+ --pf-v6-c-button__icon--Color: var(--pf-t--global--icon--color--inverse);
30
+ }
31
+ }
32
+
33
+ .pf-v6-c-button:disabled.pf-chatbot__button--send:disabled {
34
+ --pf-v6-c-button--disabled--Color: var(--pf-t--global--icon--color--disabled);
35
+ background-color: var(--pf-t--global--background--color--disabled--default);
36
+ }
37
+
38
+ .pf-v6-c-button.pf-chatbot__button--send:hover,
39
+ .pf-v6-c-button.pf-chatbot__button--send:focus {
40
+ background-color: var(--pf-t--chatbot--blue-icon--background--color--hover);
41
+ }
42
+ }
43
+
20
44
  @keyframes motionSendButton {
21
45
  0% {
22
46
  opacity: 0;
@@ -37,8 +37,8 @@ export const SendButton: React.FunctionComponent<SendButtonProps> = ({
37
37
  {...tooltipProps}
38
38
  >
39
39
  <Button
40
+ variant="plain"
40
41
  className={`pf-chatbot__button--send ${className ?? ''}`}
41
- variant="link"
42
42
  aria-label={props['aria-label'] || 'Send button'}
43
43
  onClick={onClick}
44
44
  icon={
@@ -0,0 +1,52 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import '@testing-library/jest-dom';
4
+ import userEvent from '@testing-library/user-event';
5
+ import { DownloadIcon } from '@patternfly/react-icons';
6
+ import ResponseActionButton from './ResponseActionButton';
7
+
8
+ describe('ResponseActionButton', () => {
9
+ it('renders aria-label correctly if not clicked', () => {
10
+ render(<ResponseActionButton icon={<DownloadIcon />} ariaLabel="Download" clickedAriaLabel="Downloaded" />);
11
+ expect(screen.getByRole('button', { name: 'Download' })).toBeTruthy();
12
+ });
13
+ it('renders aria-label correctly if clicked', () => {
14
+ render(
15
+ <ResponseActionButton icon={<DownloadIcon />} ariaLabel="Download" clickedAriaLabel="Downloaded" isClicked />
16
+ );
17
+ expect(screen.getByRole('button', { name: 'Downloaded' })).toBeTruthy();
18
+ });
19
+ it('renders tooltip correctly if not clicked', async () => {
20
+ render(
21
+ <ResponseActionButton icon={<DownloadIcon />} tooltipContent="Download" clickedTooltipContent="Downloaded" />
22
+ );
23
+ expect(screen.getByRole('button', { name: 'Download' })).toBeTruthy();
24
+ // clicking here just triggers the tooltip; in this button, the logic is divorced from whether it is actually clicked
25
+ await userEvent.click(screen.getByRole('button', { name: 'Download' }));
26
+ expect(screen.getByRole('tooltip', { name: 'Download' })).toBeTruthy();
27
+ });
28
+ it('renders tooltip correctly if clicked', async () => {
29
+ render(
30
+ <ResponseActionButton
31
+ icon={<DownloadIcon />}
32
+ tooltipContent="Download"
33
+ clickedTooltipContent="Downloaded"
34
+ isClicked
35
+ />
36
+ );
37
+ expect(screen.getByRole('button', { name: 'Downloaded' })).toBeTruthy();
38
+ // clicking here just triggers the tooltip; in this button, the logic is divorced from whether it is actually clicked
39
+ await userEvent.click(screen.getByRole('button', { name: 'Downloaded' }));
40
+ expect(screen.getByRole('tooltip', { name: 'Downloaded' })).toBeTruthy();
41
+ });
42
+ it('if clicked variant for tooltip is not supplied, it uses the default', async () => {
43
+ render(<ResponseActionButton icon={<DownloadIcon />} tooltipContent="Download" isClicked />);
44
+ // clicking here just triggers the tooltip; in this button, the logic is divorced from whether it is actually clicked
45
+ await userEvent.click(screen.getByRole('button', { name: 'Download' }));
46
+ expect(screen.getByRole('button', { name: 'Download' })).toBeTruthy();
47
+ });
48
+ it('if clicked variant for aria label is not supplied, it uses the default', async () => {
49
+ render(<ResponseActionButton icon={<DownloadIcon />} ariaLabel="Download" isClicked />);
50
+ expect(screen.getByRole('button', { name: 'Download' })).toBeTruthy();
51
+ });
52
+ });
@@ -4,6 +4,8 @@ import { Button, Icon, Tooltip, TooltipProps } from '@patternfly/react-core';
4
4
  export interface ResponseActionButtonProps {
5
5
  /** Aria-label for the button. Defaults to the value of the tooltipContent if none provided */
6
6
  ariaLabel?: string;
7
+ /** Aria-label for the button, shown when the button is clicked. Defaults to the value of ariaLabel or tooltipContent if not provided. */
8
+ clickedAriaLabel?: string;
7
9
  /** Icon for the button */
8
10
  icon: React.ReactNode;
9
11
  /** On-click handler for the button */
@@ -14,43 +16,60 @@ export interface ResponseActionButtonProps {
14
16
  isDisabled?: boolean;
15
17
  /** Content shown in the tooltip */
16
18
  tooltipContent?: string;
19
+ /** Content shown in the tooltip when the button is clicked. Defaults to the value of tooltipContent if not provided. */
20
+ clickedTooltipContent?: string;
17
21
  /** Props to control the PF Tooltip component */
18
22
  tooltipProps?: TooltipProps;
23
+ /** Whether button is in clicked state */
24
+ isClicked?: boolean;
19
25
  }
20
26
 
21
27
  export const ResponseActionButton: React.FunctionComponent<ResponseActionButtonProps> = ({
22
28
  ariaLabel,
29
+ clickedAriaLabel = ariaLabel,
23
30
  className,
24
31
  icon,
25
32
  isDisabled,
26
33
  onClick,
27
34
  tooltipContent,
28
- tooltipProps
29
- }) => (
30
- <Tooltip
31
- id={`pf-chatbot__tooltip-response-action-${tooltipContent}`}
32
- content={tooltipContent}
33
- position="bottom"
34
- entryDelay={tooltipProps?.entryDelay || 0}
35
- exitDelay={tooltipProps?.exitDelay || 0}
36
- distance={tooltipProps?.distance || 8}
37
- animationDuration={tooltipProps?.animationDuration || 0}
38
- {...tooltipProps}
39
- >
40
- <Button
41
- variant="plain"
42
- className={`pf-chatbot__button--response-action ${className ?? ''}`}
43
- aria-label={ariaLabel ?? tooltipContent}
44
- icon={
45
- <Icon isInline size="lg">
46
- {icon}
47
- </Icon>
48
- }
49
- isDisabled={isDisabled}
50
- onClick={onClick}
51
- size="sm"
52
- ></Button>
53
- </Tooltip>
54
- );
35
+ clickedTooltipContent = tooltipContent,
36
+ tooltipProps,
37
+ isClicked = false
38
+ }) => {
39
+ const generateAriaLabel = () => {
40
+ if (ariaLabel) {
41
+ return isClicked ? clickedAriaLabel : ariaLabel;
42
+ }
43
+ return isClicked ? clickedTooltipContent : tooltipContent;
44
+ };
45
+
46
+ return (
47
+ <Tooltip
48
+ id={`pf-chatbot__tooltip-response-action-${tooltipContent}`}
49
+ content={isClicked ? clickedTooltipContent : tooltipContent}
50
+ aria-live="polite"
51
+ position="bottom"
52
+ entryDelay={tooltipProps?.entryDelay || 0}
53
+ exitDelay={tooltipProps?.exitDelay || 0}
54
+ distance={tooltipProps?.distance || 8}
55
+ animationDuration={tooltipProps?.animationDuration || 0}
56
+ {...tooltipProps}
57
+ >
58
+ <Button
59
+ variant="plain"
60
+ className={`pf-chatbot__button--response-action ${isClicked ? 'pf-chatbot__button--response-action-clicked' : ''} ${className ?? ''}`}
61
+ aria-label={generateAriaLabel()}
62
+ icon={
63
+ <Icon isInline size="lg">
64
+ {icon}
65
+ </Icon>
66
+ }
67
+ isDisabled={isDisabled}
68
+ onClick={onClick}
69
+ size="sm"
70
+ ></Button>
71
+ </Tooltip>
72
+ );
73
+ };
55
74
 
56
75
  export default ResponseActionButton;
@@ -4,6 +4,7 @@
4
4
  grid-template-columns: repeat(auto-fit, minmax(0, max-content));
5
5
 
6
6
  .pf-v6-c-button {
7
+ --pf-v6-c-button__icon--Color: var(--pf-t--global--icon--color--subtle);
7
8
  border-radius: var(--pf-t--global--border--radius--pill);
8
9
  width: 2.3125rem;
9
10
  height: 2.3125rem;
@@ -11,16 +12,17 @@
11
12
  align-items: center;
12
13
  justify-content: center;
13
14
 
14
- .pf-v6-c-button__icon {
15
- color: var(--pf-t--global--icon--color--subtle);
15
+ &:hover {
16
+ --pf-v6-c-button__icon--Color: var(--pf-t--global--icon--color--subtle);
16
17
  }
17
-
18
- // Interactive states
19
- &:hover,
20
18
  &:focus {
21
- .pf-v6-c-button__icon {
22
- color: var(--pf-t--global--icon--color--subtle);
23
- }
19
+ --pf-v6-c-button--hover--BackgroundColor: var(--pf-t--global--background--color--action--plain--alt--clicked);
20
+ --pf-v6-c-button__icon--Color: var(--pf-t--global--icon--color--regular);
24
21
  }
25
22
  }
26
23
  }
24
+
25
+ .pf-v6-c-button.pf-chatbot__button--response-action-clicked {
26
+ --pf-v6-c-button--m-plain--BackgroundColor: var(--pf-t--global--background--color--action--plain--alt--clicked);
27
+ --pf-v6-c-button__icon--Color: var(--pf-t--global--icon--color--regular);
28
+ }
@@ -4,27 +4,32 @@ import '@testing-library/jest-dom';
4
4
  import ResponseActions from './ResponseActions';
5
5
  import userEvent from '@testing-library/user-event';
6
6
  import { DownloadIcon, InfoCircleIcon, RedoIcon } from '@patternfly/react-icons';
7
+ import Message from '../Message';
7
8
 
8
9
  const ALL_ACTIONS = [
9
- { type: 'positive', label: 'Good response' },
10
- { type: 'negative', label: 'Bad response' },
11
- { type: 'copy', label: 'Copy' },
12
- { type: 'share', label: 'Share' },
13
- { type: 'listen', label: 'Listen' }
10
+ { type: 'positive', label: 'Good response', clickedLabel: 'Response recorded' },
11
+ { type: 'negative', label: 'Bad response', clickedLabel: 'Response recorded' },
12
+ { type: 'copy', label: 'Copy', clickedLabel: 'Copied' },
13
+ { type: 'share', label: 'Share', clickedLabel: 'Shared' },
14
+ { type: 'listen', label: 'Listen', clickedLabel: 'Listening' }
14
15
  ];
15
16
 
16
17
  const CUSTOM_ACTIONS = [
17
18
  {
18
19
  regenerate: {
19
20
  ariaLabel: 'Regenerate',
21
+ clickedAriaLabel: 'Regenerated',
20
22
  onClick: jest.fn(),
21
23
  tooltipContent: 'Regenerate',
24
+ clickedTooltipContent: 'Regenerated',
22
25
  icon: <RedoIcon />
23
26
  },
24
27
  download: {
25
28
  ariaLabel: 'Download',
29
+ clickedAriaLabel: 'Downloaded',
26
30
  onClick: jest.fn(),
27
31
  tooltipContent: 'Download',
32
+ clickedTooltipContent: 'Downloaded',
28
33
  icon: <DownloadIcon />
29
34
  },
30
35
  info: {
@@ -37,6 +42,81 @@ const CUSTOM_ACTIONS = [
37
42
  ];
38
43
 
39
44
  describe('ResponseActions', () => {
45
+ afterEach(() => {
46
+ jest.clearAllMocks();
47
+ });
48
+ it('should handle click within group of buttons correctly', async () => {
49
+ render(
50
+ <ResponseActions
51
+ actions={{
52
+ positive: { onClick: jest.fn() },
53
+ negative: { onClick: jest.fn() },
54
+ copy: { onClick: jest.fn() },
55
+ share: { onClick: jest.fn() },
56
+ listen: { onClick: jest.fn() }
57
+ }}
58
+ />
59
+ );
60
+ const goodBtn = screen.getByRole('button', { name: 'Good response' });
61
+ const badBtn = screen.getByRole('button', { name: 'Bad response' });
62
+ const copyBtn = screen.getByRole('button', { name: 'Copy' });
63
+ const shareBtn = screen.getByRole('button', { name: 'Share' });
64
+ const listenBtn = screen.getByRole('button', { name: 'Listen' });
65
+ const buttons = [goodBtn, badBtn, copyBtn, shareBtn, listenBtn];
66
+ buttons.forEach((button) => {
67
+ expect(button).toBeTruthy();
68
+ });
69
+ await userEvent.click(goodBtn);
70
+ expect(screen.getByRole('button', { name: 'Response recorded' })).toHaveClass(
71
+ 'pf-chatbot__button--response-action-clicked'
72
+ );
73
+ let unclickedButtons = buttons.filter((button) => button !== goodBtn);
74
+ unclickedButtons.forEach((button) => {
75
+ expect(button).not.toHaveClass('pf-chatbot__button--response-action-clicked');
76
+ });
77
+ await userEvent.click(badBtn);
78
+ expect(screen.getByRole('button', { name: 'Response recorded' })).toHaveClass(
79
+ 'pf-chatbot__button--response-action-clicked'
80
+ );
81
+ unclickedButtons = buttons.filter((button) => button !== badBtn);
82
+ unclickedButtons.forEach((button) => {
83
+ expect(button).not.toHaveClass('pf-chatbot__button--response-action-clicked');
84
+ });
85
+ });
86
+ it('should handle click outside of group of buttons correctly', async () => {
87
+ // using message just so we have something outside the group that's rendered
88
+ render(
89
+ <Message
90
+ name="Bot"
91
+ role="bot"
92
+ avatar=""
93
+ content="Example with all prebuilt actions"
94
+ actions={{
95
+ positive: {},
96
+ negative: {}
97
+ }}
98
+ />
99
+ );
100
+ const goodBtn = screen.getByRole('button', { name: 'Good response' });
101
+ const badBtn = screen.getByRole('button', { name: 'Bad response' });
102
+ expect(goodBtn).toBeTruthy();
103
+ expect(badBtn).toBeTruthy();
104
+
105
+ await userEvent.click(goodBtn);
106
+ expect(screen.getByRole('button', { name: 'Response recorded' })).toHaveClass(
107
+ 'pf-chatbot__button--response-action-clicked'
108
+ );
109
+ expect(badBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked');
110
+
111
+ await userEvent.click(badBtn);
112
+ expect(screen.getByRole('button', { name: 'Response recorded' })).toHaveClass(
113
+ 'pf-chatbot__button--response-action-clicked'
114
+ );
115
+ expect(goodBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked');
116
+ await userEvent.click(screen.getByText('Example with all prebuilt actions'));
117
+ expect(goodBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked');
118
+ expect(badBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked');
119
+ });
40
120
  it('should render buttons correctly', () => {
41
121
  ALL_ACTIONS.forEach(({ type, label }) => {
42
122
  render(<ResponseActions actions={{ [type]: { onClick: jest.fn() } }} />);
@@ -53,6 +133,24 @@ describe('ResponseActions', () => {
53
133
  });
54
134
  });
55
135
 
136
+ it('should swap clicked and non-clicked aria labels on click', async () => {
137
+ ALL_ACTIONS.forEach(async ({ type, label, clickedLabel }) => {
138
+ render(<ResponseActions actions={{ [type]: { onClick: jest.fn() } }} />);
139
+ expect(screen.getByRole('button', { name: label })).toBeTruthy();
140
+ await userEvent.click(screen.getByRole('button', { name: label }));
141
+ expect(screen.getByRole('button', { name: clickedLabel })).toBeTruthy();
142
+ });
143
+ });
144
+
145
+ it('should swap clicked and non-clicked tooltips on click', async () => {
146
+ ALL_ACTIONS.forEach(async ({ type, label, clickedLabel }) => {
147
+ render(<ResponseActions actions={{ [type]: { onClick: jest.fn() } }} />);
148
+ expect(screen.getByRole('button', { name: label })).toBeTruthy();
149
+ await userEvent.click(screen.getByRole('button', { name: label }));
150
+ expect(screen.getByRole('tooltip', { name: clickedLabel })).toBeTruthy();
151
+ });
152
+ });
153
+
56
154
  it('should be able to change aria labels', () => {
57
155
  const actions = [
58
156
  { type: 'positive', ariaLabel: 'Thumbs up' },