@gitlab/ui 80.13.0 → 80.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (277) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/components/base/filtered_search/filtered_search.js +3 -2
  3. package/dist/components/experimental/experiment_badge/experiment_badge.js +6 -6
  4. package/package.json +19 -13
  5. package/src/components/base/filtered_search/filtered_search.vue +3 -2
  6. package/src/components/experimental/experiment_badge/experiment_badge.vue +12 -11
  7. package/src/components/base/accordion/accordion.spec.js +0 -58
  8. package/src/components/base/accordion/accordion.stories.js +0 -59
  9. package/src/components/base/accordion/accordion_item.spec.js +0 -131
  10. package/src/components/base/accordion/accordion_item.stories.js +0 -57
  11. package/src/components/base/alert/alert.spec.js +0 -229
  12. package/src/components/base/alert/alert.stories.js +0 -166
  13. package/src/components/base/avatar/avatar.spec.js +0 -91
  14. package/src/components/base/avatar/avatar.stories.js +0 -160
  15. package/src/components/base/avatar_labeled/avatar_labeled.spec.js +0 -109
  16. package/src/components/base/avatar_labeled/avatar_labeled.stories.js +0 -187
  17. package/src/components/base/avatar_link/avatar_link.stories.js +0 -86
  18. package/src/components/base/avatars_inline/avatars_inline.spec.js +0 -124
  19. package/src/components/base/avatars_inline/avatars_inline.stories.js +0 -83
  20. package/src/components/base/badge/badge.spec.js +0 -83
  21. package/src/components/base/badge/badge.stories.js +0 -184
  22. package/src/components/base/banner/banner.spec.js +0 -112
  23. package/src/components/base/banner/banner.stories.js +0 -103
  24. package/src/components/base/breadcrumb/breadcrumb.spec.js +0 -240
  25. package/src/components/base/breadcrumb/breadcrumb.stories.js +0 -100
  26. package/src/components/base/breadcrumb/breadcrumb_item.spec.js +0 -45
  27. package/src/components/base/broadcast_message/broadcast_message.spec.js +0 -32
  28. package/src/components/base/broadcast_message/broadcast_message.stories.js +0 -112
  29. package/src/components/base/button/button.spec.js +0 -225
  30. package/src/components/base/button/button.stories.js +0 -529
  31. package/src/components/base/button_group/button_group.stories.js +0 -132
  32. package/src/components/base/card/card.spec.js +0 -139
  33. package/src/components/base/card/card.stories.js +0 -48
  34. package/src/components/base/carousel/carousel.spec.js +0 -24
  35. package/src/components/base/carousel/carousel.stories.js +0 -51
  36. package/src/components/base/collapse/collapse.spec.js +0 -24
  37. package/src/components/base/collapse/collapse.stories.js +0 -42
  38. package/src/components/base/datepicker/datepicker.spec.js +0 -431
  39. package/src/components/base/datepicker/datepicker.stories.js +0 -141
  40. package/src/components/base/daterange_picker/daterange_picker.spec.js +0 -307
  41. package/src/components/base/daterange_picker/daterange_picker.stories.js +0 -145
  42. package/src/components/base/drawer/drawer.spec.js +0 -136
  43. package/src/components/base/drawer/drawer.stories.js +0 -272
  44. package/src/components/base/dropdown/dropdown.spec.js +0 -457
  45. package/src/components/base/dropdown/dropdown.stories.js +0 -574
  46. package/src/components/base/dropdown/dropdown_form.spec.js +0 -9
  47. package/src/components/base/dropdown/dropdown_item.spec.js +0 -67
  48. package/src/components/base/dropdown/dropdown_item.stories.js +0 -113
  49. package/src/components/base/filtered_search/__snapshots__/filtered_search_term.spec.js.snap +0 -31
  50. package/src/components/base/filtered_search/filtered_search.spec.js +0 -891
  51. package/src/components/base/filtered_search/filtered_search.stories.js +0 -678
  52. package/src/components/base/filtered_search/filtered_search_suggestion.spec.js +0 -67
  53. package/src/components/base/filtered_search/filtered_search_suggestion.stories.js +0 -33
  54. package/src/components/base/filtered_search/filtered_search_suggestion_list.spec.js +0 -337
  55. package/src/components/base/filtered_search/filtered_search_suggestion_list.stories.js +0 -53
  56. package/src/components/base/filtered_search/filtered_search_term.spec.js +0 -212
  57. package/src/components/base/filtered_search/filtered_search_term.stories.js +0 -60
  58. package/src/components/base/filtered_search/filtered_search_token.spec.js +0 -461
  59. package/src/components/base/filtered_search/filtered_search_token.stories.js +0 -199
  60. package/src/components/base/filtered_search/filtered_search_token_segment.spec.js +0 -393
  61. package/src/components/base/filtered_search/filtered_search_token_segment.stories.js +0 -110
  62. package/src/components/base/filtered_search/filtered_search_utils.spec.js +0 -82
  63. package/src/components/base/form/form.stories.js +0 -101
  64. package/src/components/base/form/form_checkbox/form_checkbox.stories.js +0 -55
  65. package/src/components/base/form/form_checkbox_tree/form_checkbox_tree.spec.js +0 -265
  66. package/src/components/base/form/form_checkbox_tree/form_checkbox_tree.stories.js +0 -134
  67. package/src/components/base/form/form_combobox/form_combobox.spec.js +0 -301
  68. package/src/components/base/form/form_combobox/form_combobox.stories.js +0 -114
  69. package/src/components/base/form/form_date/form_date.spec.js +0 -85
  70. package/src/components/base/form/form_date/form_date.stories.js +0 -108
  71. package/src/components/base/form/form_fields/form_field_validator.spec.js +0 -51
  72. package/src/components/base/form/form_fields/form_fields.spec.js +0 -531
  73. package/src/components/base/form/form_fields/form_fields.stories.js +0 -150
  74. package/src/components/base/form/form_fields/mappers.spec.js +0 -17
  75. package/src/components/base/form/form_fields/validators.spec.js +0 -56
  76. package/src/components/base/form/form_group/form_group.spec.js +0 -110
  77. package/src/components/base/form/form_group/form_group.stories.js +0 -123
  78. package/src/components/base/form/form_input/form_input.spec.js +0 -130
  79. package/src/components/base/form/form_input/form_input.stories.js +0 -128
  80. package/src/components/base/form/form_input_group/form_input_group.spec.js +0 -121
  81. package/src/components/base/form/form_input_group/form_input_group.stories.js +0 -86
  82. package/src/components/base/form/form_radio/form_radio.spec.js +0 -116
  83. package/src/components/base/form/form_radio/form_radio.stories.js +0 -70
  84. package/src/components/base/form/form_radio_group/form_radio_group.spec.js +0 -86
  85. package/src/components/base/form/form_radio_group/form_radio_group.stories.js +0 -79
  86. package/src/components/base/form/form_select/form_select.spec.js +0 -69
  87. package/src/components/base/form/form_select/form_select.stories.js +0 -156
  88. package/src/components/base/form/form_text/form_text.stories.js +0 -27
  89. package/src/components/base/form/form_textarea/form_textarea.spec.js +0 -242
  90. package/src/components/base/form/form_textarea/form_textarea.stories.js +0 -68
  91. package/src/components/base/form/input_group_text/input_group_text.spec.js +0 -9
  92. package/src/components/base/form/input_group_text/input_group_text.stories.js +0 -30
  93. package/src/components/base/icon/__snapshots__/icon.spec.js.snap +0 -14
  94. package/src/components/base/icon/icon.spec.js +0 -92
  95. package/src/components/base/icon/icon.stories.js +0 -56
  96. package/src/components/base/infinite_scroll/infinite_scroll.spec.js +0 -182
  97. package/src/components/base/infinite_scroll/infinite_scroll.stories.js +0 -94
  98. package/src/components/base/keyset_pagination/keyset_pagination.spec.js +0 -313
  99. package/src/components/base/keyset_pagination/keyset_pagination.stories.js +0 -66
  100. package/src/components/base/label/label.spec.js +0 -257
  101. package/src/components/base/label/label.stories.js +0 -76
  102. package/src/components/base/link/link.spec.js +0 -88
  103. package/src/components/base/link/link.stories.js +0 -64
  104. package/src/components/base/loading_icon/loading_icon.spec.js +0 -109
  105. package/src/components/base/loading_icon/loading_icon.stories.js +0 -60
  106. package/src/components/base/markdown/markdown.spec.js +0 -24
  107. package/src/components/base/markdown/markdown.stories.js +0 -33
  108. package/src/components/base/modal/modal.spec.js +0 -265
  109. package/src/components/base/modal/modal.stories.js +0 -159
  110. package/src/components/base/nav/nav.spec.js +0 -19
  111. package/src/components/base/nav/nav.stories.js +0 -57
  112. package/src/components/base/nav/nav_item.spec.js +0 -16
  113. package/src/components/base/nav/nav_item_dropdown.spec.js +0 -58
  114. package/src/components/base/navbar/navbar.spec.js +0 -21
  115. package/src/components/base/navbar/navbar.stories.js +0 -28
  116. package/src/components/base/new_dropdowns/base_dropdown/base_dropdown.spec.js +0 -566
  117. package/src/components/base/new_dropdowns/disclosure/disclosure_dropdown.spec.js +0 -452
  118. package/src/components/base/new_dropdowns/disclosure/disclosure_dropdown.stories.js +0 -345
  119. package/src/components/base/new_dropdowns/disclosure/disclosure_dropdown_group.spec.js +0 -84
  120. package/src/components/base/new_dropdowns/disclosure/disclosure_dropdown_item.spec.js +0 -200
  121. package/src/components/base/new_dropdowns/disclosure/utils.spec.js +0 -74
  122. package/src/components/base/new_dropdowns/listbox/listbox.spec.js +0 -950
  123. package/src/components/base/new_dropdowns/listbox/listbox.stories.js +0 -840
  124. package/src/components/base/new_dropdowns/listbox/listbox_group.spec.js +0 -61
  125. package/src/components/base/new_dropdowns/listbox/listbox_item.spec.js +0 -129
  126. package/src/components/base/new_dropdowns/listbox/listbox_search_input.spec.js +0 -62
  127. package/src/components/base/new_dropdowns/listbox/utils.spec.js +0 -58
  128. package/src/components/base/paginated_list/__snapshots__/paginated_list.spec.js.snap +0 -922
  129. package/src/components/base/paginated_list/paginated_list.spec.js +0 -212
  130. package/src/components/base/paginated_list/paginated_list.stories.js +0 -207
  131. package/src/components/base/pagination/pagination.spec.js +0 -401
  132. package/src/components/base/pagination/pagination.stories.js +0 -129
  133. package/src/components/base/path/__snapshots__/path.spec.js.snap +0 -586
  134. package/src/components/base/path/path.spec.js +0 -237
  135. package/src/components/base/path/path.stories.js +0 -84
  136. package/src/components/base/popover/popover.spec.js +0 -104
  137. package/src/components/base/popover/popover.stories.js +0 -109
  138. package/src/components/base/progress_bar/progress_bar.stories.js +0 -34
  139. package/src/components/base/search_box_by_click/search_box_by_click.spec.js +0 -209
  140. package/src/components/base/search_box_by_click/search_box_by_click.stories.js +0 -100
  141. package/src/components/base/search_box_by_type/search_box_by_type.spec.js +0 -164
  142. package/src/components/base/search_box_by_type/search_box_by_type.stories.js +0 -63
  143. package/src/components/base/segmented_control/segmented_control.spec.js +0 -135
  144. package/src/components/base/segmented_control/segmented_control.stories.js +0 -59
  145. package/src/components/base/skeleton_loader/skeleton_loader.spec.js +0 -151
  146. package/src/components/base/skeleton_loader/skeleton_loader.stories.js +0 -86
  147. package/src/components/base/sorting/sorting.spec.js +0 -170
  148. package/src/components/base/sorting/sorting.stories.js +0 -98
  149. package/src/components/base/table/table.spec.js +0 -192
  150. package/src/components/base/table/table.stories.js +0 -186
  151. package/src/components/base/table_lite/table_lite.spec.js +0 -40
  152. package/src/components/base/table_lite/table_lite.stories.js +0 -74
  153. package/src/components/base/tabs/tab/tab.spec.js +0 -34
  154. package/src/components/base/tabs/tabs/scrollable_tabs.spec.js +0 -260
  155. package/src/components/base/tabs/tabs/tabs.spec.js +0 -366
  156. package/src/components/base/tabs/tabs/tabs.stories.js +0 -209
  157. package/src/components/base/toast/toast.spec.js +0 -72
  158. package/src/components/base/toast/toast.stories.js +0 -87
  159. package/src/components/base/toggle/toggle.spec.js +0 -168
  160. package/src/components/base/toggle/toggle.stories.js +0 -106
  161. package/src/components/base/token/token.spec.js +0 -48
  162. package/src/components/base/token/token.stories.js +0 -58
  163. package/src/components/base/token_selector/helpers.spec.js +0 -40
  164. package/src/components/base/token_selector/token_container.spec.js +0 -306
  165. package/src/components/base/token_selector/token_selector.spec.js +0 -653
  166. package/src/components/base/token_selector/token_selector.stories.js +0 -114
  167. package/src/components/base/token_selector/token_selector_dropdown.spec.js +0 -347
  168. package/src/components/base/tooltip/tooltip.spec.js +0 -27
  169. package/src/components/base/tooltip/tooltip.stories.js +0 -69
  170. package/src/components/charts/area/area.spec.js +0 -286
  171. package/src/components/charts/area/area.stories.js +0 -208
  172. package/src/components/charts/bar/__snapshots__/bar.spec.js.snap +0 -82
  173. package/src/components/charts/bar/bar.spec.js +0 -92
  174. package/src/components/charts/bar/bar.stories.js +0 -72
  175. package/src/components/charts/chart/chart.spec.js +0 -167
  176. package/src/components/charts/chart/chart.stories.js +0 -111
  177. package/src/components/charts/column/__snapshots__/column_chart.spec.js.snap +0 -323
  178. package/src/components/charts/column/column.stories.js +0 -111
  179. package/src/components/charts/column/column_chart.spec.js +0 -223
  180. package/src/components/charts/discrete_scatter/discrete_scatter.spec.js +0 -173
  181. package/src/components/charts/discrete_scatter/discrete_scatter.stories.js +0 -64
  182. package/src/components/charts/gauge/gauge.spec.js +0 -280
  183. package/src/components/charts/gauge/gauge.stories.js +0 -97
  184. package/src/components/charts/heatmap/heatmap.spec.js +0 -103
  185. package/src/components/charts/heatmap/heatmap.stories.js +0 -78
  186. package/src/components/charts/legend/legend.spec.js +0 -274
  187. package/src/components/charts/legend/legend.stories.js +0 -174
  188. package/src/components/charts/line/line.spec.js +0 -278
  189. package/src/components/charts/line/line.stories.js +0 -238
  190. package/src/components/charts/series_label/series_label.stories.js +0 -78
  191. package/src/components/charts/single_stat/single_stat.spec.js +0 -217
  192. package/src/components/charts/single_stat/single_stat.stories.js +0 -103
  193. package/src/components/charts/sparkline/sparkline.spec.js +0 -220
  194. package/src/components/charts/sparkline/sparkline.stories.js +0 -85
  195. package/src/components/charts/stacked_column/__snapshots__/stacked_column.spec.js.snap +0 -905
  196. package/src/components/charts/stacked_column/stacked_column.spec.js +0 -194
  197. package/src/components/charts/stacked_column/stacked_column.stories.js +0 -130
  198. package/src/components/charts/tooltip/tooltip.spec.js +0 -282
  199. package/src/components/charts/tooltip/tooltip.stories.js +0 -90
  200. package/src/components/experimental/duo/chat/components/duo_chat_conversation/duo_chat_conversation.spec.js +0 -46
  201. package/src/components/experimental/duo/chat/components/duo_chat_conversation/duo_chat_conversation.stories.js +0 -62
  202. package/src/components/experimental/duo/chat/components/duo_chat_loader/duo_chat_loader.spec.js +0 -70
  203. package/src/components/experimental/duo/chat/components/duo_chat_loader/duo_chat_loader.stories.js +0 -31
  204. package/src/components/experimental/duo/chat/components/duo_chat_message/copy_code_element.spec.js +0 -64
  205. package/src/components/experimental/duo/chat/components/duo_chat_message/duo_chat_message.spec.js +0 -534
  206. package/src/components/experimental/duo/chat/components/duo_chat_message/duo_chat_message.stories.js +0 -55
  207. package/src/components/experimental/duo/chat/components/duo_chat_message/utils.spec.js +0 -24
  208. package/src/components/experimental/duo/chat/components/duo_chat_message_sources/duo_chat_message_sources.spec.js +0 -93
  209. package/src/components/experimental/duo/chat/components/duo_chat_message_sources/duo_chat_message_sources.stories.js +0 -32
  210. package/src/components/experimental/duo/chat/components/duo_chat_predefined_prompts/duo_chat_predefined_prompts.spec.js +0 -35
  211. package/src/components/experimental/duo/chat/components/duo_chat_predefined_prompts/duo_chat_predefined_prompts.stories.js +0 -36
  212. package/src/components/experimental/duo/chat/duo_chat.spec.js +0 -828
  213. package/src/components/experimental/duo/chat/duo_chat.stories.js +0 -240
  214. package/src/components/experimental/duo/chat/markdown_renderer.spec.js +0 -55
  215. package/src/components/experimental/duo/user_feedback/user_feedback.spec.js +0 -100
  216. package/src/components/experimental/duo/user_feedback/user_feedback.stories.js +0 -107
  217. package/src/components/experimental/duo/user_feedback/user_feedback_modal.spec.js +0 -134
  218. package/src/components/experimental/experiment_badge/experiment_badge.spec.js +0 -77
  219. package/src/components/experimental/experiment_badge/experiment_badge.stories.js +0 -58
  220. package/src/components/regions/dashboard_skeleton/dashboard_skeleton.stories.js +0 -29
  221. package/src/components/regions/empty_state/empty_state.spec.js +0 -293
  222. package/src/components/regions/empty_state/empty_state.stories.js +0 -160
  223. package/src/components/shared_components/charts/tooltip_default_format.spec.js +0 -69
  224. package/src/components/shared_components/clear_icon_button/__snapshots__/clear_icon_button.spec.js.snap +0 -15
  225. package/src/components/shared_components/clear_icon_button/clear_icon_button.spec.js +0 -23
  226. package/src/components/shared_components/close_button/__snapshots__/close_button.spec.js.snap +0 -12
  227. package/src/components/shared_components/close_button/close_button.spec.js +0 -22
  228. package/src/components/utilities/animated_number/animated_number.spec.js +0 -133
  229. package/src/components/utilities/animated_number/animated_number.stories.js +0 -63
  230. package/src/components/utilities/friendly_wrap/friendly_wrap.spec.js +0 -123
  231. package/src/components/utilities/friendly_wrap/friendly_wrap.stories.js +0 -56
  232. package/src/components/utilities/intersection_observer/intersection_observer.spec.js +0 -116
  233. package/src/components/utilities/intersection_observer/intersection_observer.stories.js +0 -162
  234. package/src/components/utilities/intersperse/intersperse.spec.js +0 -115
  235. package/src/components/utilities/intersperse/intersperse.stories.js +0 -53
  236. package/src/components/utilities/sprintf/sprintf.spec.js +0 -337
  237. package/src/components/utilities/sprintf/sprintf.stories.js +0 -104
  238. package/src/components/utilities/truncate/truncate.spec.js +0 -125
  239. package/src/components/utilities/truncate/truncate.stories.js +0 -50
  240. package/src/components/utilities/truncate_text/truncate_text.spec.js +0 -150
  241. package/src/components/utilities/truncate_text/truncate_text.stories.js +0 -45
  242. package/src/directives/hover_load/hover_load.spec.js +0 -64
  243. package/src/directives/hover_load/hover_load.stories.js +0 -51
  244. package/src/directives/outside/outside.spec.js +0 -338
  245. package/src/directives/outside/outside.stories.js +0 -35
  246. package/src/directives/resize_observer/resize_observer.spec.js +0 -125
  247. package/src/directives/resize_observer/resize_observer.stories.js +0 -76
  248. package/src/directives/safe_html/safe_html.spec.js +0 -149
  249. package/src/directives/safe_html/safe_html.stories.js +0 -60
  250. package/src/directives/safe_link/safe_link.spec.js +0 -135
  251. package/src/directives/safe_link/safe_link.stories.js +0 -39
  252. package/src/internal/color_contrast/color_contrast.spec.js +0 -34
  253. package/src/internal/color_contrast/color_contrast.stories.js +0 -41
  254. package/src/scss/functions.spec.scss +0 -54
  255. package/src/scss/mixins.spec.scss +0 -93
  256. package/src/scss/run_scss_tests.spec.js +0 -26
  257. package/src/scss/typescale/typescale.stories.js +0 -61
  258. package/src/tokens/color.constant.tokens.stories.js +0 -19
  259. package/src/tokens/color.dark.tokens.stories.js +0 -26
  260. package/src/tokens/color.data_viz.dark.tokens.stories.js +0 -19
  261. package/src/tokens/color.data_viz.tokens.stories.js +0 -19
  262. package/src/tokens/color.theme.dark.tokens.stories.js +0 -21
  263. package/src/tokens/color.theme.tokens.stories.js +0 -21
  264. package/src/tokens/color.tokens.stories.js +0 -26
  265. package/src/tokens/color.transparency.tokens.stories.js +0 -14
  266. package/src/tokens/text.dark.tokens.stories.js +0 -18
  267. package/src/tokens/text.tokens.stories.js +0 -17
  268. package/src/tokens/tokens.stories.js +0 -16
  269. package/src/utils/breakpoints.spec.js +0 -26
  270. package/src/utils/charts/config.spec.js +0 -478
  271. package/src/utils/charts/utils.spec.js +0 -106
  272. package/src/utils/datetime_utility.spec.js +0 -98
  273. package/src/utils/is_slot_empty.spec.js +0 -73
  274. package/src/utils/number_utils.spec.js +0 -110
  275. package/src/utils/stories_utils.spec.js +0 -18
  276. package/src/utils/string_utils.spec.js +0 -56
  277. package/src/utils/utils.spec.js +0 -156
@@ -1,240 +0,0 @@
1
- import GlButton from '../../../base/button/button.vue';
2
- import GlAlert from '../../../base/alert/alert.vue';
3
- import { makeContainer } from '../../../../utils/story_decorators/container';
4
- import GlDuoChat from './duo_chat.vue';
5
- import readme from './duo_chat.md';
6
- import { CHAT_CLEAN_MESSAGE } from './constants';
7
- import {
8
- MOCK_RESPONSE_MESSAGE,
9
- MOCK_USER_PROMPT_MESSAGE,
10
- SLASH_COMMANDS as slashCommands,
11
- generateMockResponseChunks,
12
- renderGFM,
13
- } from './mock_data';
14
-
15
- const defaultValue = (prop) =>
16
- typeof GlDuoChat.props[prop].default === 'function'
17
- ? GlDuoChat.props[prop].default()
18
- : GlDuoChat.props[prop].default;
19
-
20
- const generateProps = ({
21
- title = defaultValue('title'),
22
- messages = defaultValue('messages'),
23
- error = defaultValue('error'),
24
- isLoading = defaultValue('isLoading'),
25
- isChatAvailable = defaultValue('isChatAvailable'),
26
- predefinedPrompts = defaultValue('predefinedPrompts'),
27
- badgeHelpPageUrl = defaultValue('badgeHelpPageUrl'),
28
- badgeType = defaultValue('badgeType'),
29
- toolName = defaultValue('toolName'),
30
- showHeader = defaultValue('showHeader'),
31
- emptyStateTitle = defaultValue('emptyStateTitle'),
32
- emptyStateDescription = defaultValue('emptyStateDescription'),
33
- chatPromptPlaceholder = defaultValue('chatPromptPlaceholder'),
34
- } = {}) => ({
35
- title,
36
- messages,
37
- error,
38
- isLoading,
39
- isChatAvailable,
40
- predefinedPrompts,
41
- badgeHelpPageUrl,
42
- badgeType,
43
- toolName,
44
- slashCommands,
45
- showHeader,
46
- emptyStateTitle,
47
- emptyStateDescription,
48
- chatPromptPlaceholder,
49
- });
50
-
51
- export const Default = (args, { argTypes }) => ({
52
- components: { GlDuoChat },
53
- props: Object.keys(argTypes),
54
- provide: {
55
- renderGFM,
56
- },
57
- template: `
58
- <gl-duo-chat
59
- :title="title"
60
- :messages="messages"
61
- :error="error"
62
- :is-loading="isLoading"
63
- :is-chat-available="isChatAvailable"
64
- :predefined-prompts="predefinedPrompts"
65
- :badge-help-page-url="badgeHelpPageUrl"
66
- :badge-type="badgeType"
67
- :tool-name="toolName"
68
- :show-header="showHeader"
69
- :empty-state-title="emptyStateTitle"
70
- :empty-state-description="emptyStateDescription"
71
- :chat-prompt-placeholder="chatPromptPlaceholder"
72
- />`,
73
- });
74
- Default.args = generateProps({
75
- messages: [MOCK_USER_PROMPT_MESSAGE, MOCK_RESPONSE_MESSAGE],
76
- });
77
- Default.decorators = [makeContainer({ height: '800px' })];
78
-
79
- export const Interactive = (args, { argTypes }) => ({
80
- components: { GlDuoChat, GlButton },
81
- props: Object.keys(argTypes),
82
- provide: {
83
- renderGFM,
84
- },
85
- data() {
86
- return {
87
- isHidden: false,
88
- loggerInfo: '',
89
- promptInFlight: false,
90
- msgs: args.messages,
91
- chunks: [],
92
- timeout: null,
93
- requestId: 1,
94
- };
95
- },
96
- methods: {
97
- onSendChatPrompt(prompt) {
98
- const newPrompt = {
99
- ...MOCK_USER_PROMPT_MESSAGE,
100
- contentHtml: '',
101
- content: prompt,
102
- requestId: this.requestId,
103
- };
104
- this.loggerInfo += `New prompt: ${JSON.stringify(newPrompt)}\n\n`;
105
- if (prompt === CHAT_CLEAN_MESSAGE) {
106
- this.msgs = [];
107
- } else {
108
- this.msgs.push(newPrompt);
109
- this.promptInFlight = true;
110
- }
111
- },
112
- onChatHidden() {
113
- this.isHidden = true;
114
- this.loggerInfo += `Chat closed\n\n`;
115
- },
116
- showChat() {
117
- this.isHidden = false;
118
- this.loggerInfo += `Chat opened\n\n`;
119
- },
120
- async onResponseRequested() {
121
- this.timeout = null;
122
- await this.mockResponseFromAi();
123
- this.requestId += 1;
124
- },
125
- async mockResponseFromAi() {
126
- const generator = generateMockResponseChunks(this.requestId);
127
-
128
- for await (const newResponse of generator) {
129
- const existingMessageIndex = this.msgs.findIndex(
130
- (msg) => msg.requestId === newResponse.requestId && msg.role === newResponse.role
131
- );
132
- const existingMessage = this.msgs[existingMessageIndex];
133
- if (existingMessage) {
134
- this.updateExistingMessage(newResponse, existingMessageIndex);
135
- } else {
136
- this.addNewMessage(newResponse);
137
- }
138
- }
139
- },
140
- addNewMessage(msg) {
141
- this.promptInFlight = false;
142
- this.$set(this.msgs, this.msgs.length, msg);
143
- },
144
- updateExistingMessage(newResponse, existingMessageIndex) {
145
- const existingMessage = this.msgs[existingMessageIndex];
146
- this.$set(this.msgs, existingMessageIndex, {
147
- ...existingMessage,
148
- ...newResponse,
149
- });
150
- },
151
- },
152
- template: `
153
- <div style="height: 800px">
154
- <div id="logger" class="gl-w-half">
155
- <pre class="gl-font-sm" style="text-wrap: wrap">
156
- <code>{{ loggerInfo }}</code>
157
- </pre>
158
- <gl-button v-if="promptInFlight" @click="onResponseRequested">Mock the response</gl-button>
159
- </div>
160
- <gl-button v-if="isHidden" @click="showChat">Show chat</gl-button>
161
- <gl-duo-chat
162
- v-if="!isHidden"
163
- :title="title"
164
- :messages="msgs"
165
- :error="error"
166
- :is-loading="promptInFlight"
167
- :is-chat-available="isChatAvailable"
168
- :predefined-prompts="predefinedPrompts"
169
- :badge-help-page-url="badgeHelpPageUrl"
170
- :badge-type="badgeType"
171
- :tool-name="toolName"
172
- :show-header="showHeader"
173
- :empty-state-title="emptyStateTitle"
174
- :empty-state-description="emptyStateDescription"
175
- :chat-prompt-placeholder="chatPromptPlaceholder"
176
- :slash-commands="slashCommands"
177
- class="gl-drawer-default"
178
- @send-chat-prompt="onSendChatPrompt"
179
- @chat-hidden="onChatHidden"
180
- />
181
- </div>`,
182
- });
183
- Interactive.args = generateProps({});
184
-
185
- export const Slots = (args, { argTypes }) => ({
186
- components: { GlDuoChat, GlAlert },
187
- props: Object.keys(argTypes),
188
- provide: {
189
- renderMarkdown: (md) => `THIS IS ALTERED MARKDOWN: ${md}`,
190
- renderGFM,
191
- },
192
- template: `
193
- <div>
194
- <gl-duo-chat
195
- :title="title"
196
- :messages="messages"
197
- :error="error"
198
- :is-loading="isLoading"
199
- :is-chat-available="isChatAvailable"
200
- :predefined-prompts="predefinedPrompts"
201
- :badge-help-page-url="badgeHelpPageUrl"
202
- :badge-type="badgeType"
203
- :tool-name="toolName"
204
- :show-header="showHeader"
205
- :empty-state-title="emptyStateTitle"
206
- :empty-state-description="emptyStateDescription"
207
- :chat-prompt-placeholder="chatPromptPlaceholder">
208
- <template #subheader>
209
- <gl-alert
210
- :dismissible="false"
211
- variant="warning"
212
- class="gl-font-sm gl-border-t"
213
- role="alert"
214
- data-testid="chat-legal-warning-gitlab-usage"
215
- primary-button-link="https://internal-handbook.gitlab.io/handbook/product/ai-strategy/ai-integration-effort/legal_restrictions/"
216
- primary-button-text="Read more"
217
- >
218
- <p>
219
- You are not allowed to copy any part of this output into issues, comments, GitLab source code, commit messages, merge requests or any other user interface in the <code>/gitlab-org</code> or <code>/gitlab-com</code> groups.
220
- </p>
221
- </gl-alert>
222
- </template>
223
- </gl-duo-chat>
224
- </div>
225
- `,
226
- });
227
- Slots.args = generateProps();
228
- Slots.decorators = [makeContainer({ height: '800px' })];
229
-
230
- export default {
231
- title: 'experimental/duo/chat/duo-chat',
232
- component: GlDuoChat,
233
- parameters: {
234
- docs: {
235
- description: {
236
- component: readme,
237
- },
238
- },
239
- },
240
- };
@@ -1,55 +0,0 @@
1
- import { Parser } from 'marked';
2
- import { renderDuoChatMarkdownPreview } from './markdown_renderer';
3
-
4
- describe('Duo Chat Markdown renderer', () => {
5
- afterEach(() => {
6
- jest.restoreAllMocks();
7
- });
8
-
9
- it('renders a few edge cases', () => {
10
- expect(renderDuoChatMarkdownPreview('')).toEqual('');
11
- expect(renderDuoChatMarkdownPreview(null)).toEqual('');
12
- expect(renderDuoChatMarkdownPreview(undefined)).toEqual('');
13
- expect(renderDuoChatMarkdownPreview(5)).toEqual('<p>5</p>\n');
14
- });
15
-
16
- it('renders a simple paragraph', () => {
17
- expect(renderDuoChatMarkdownPreview('Hello world')).toEqual('<p>Hello world</p>\n');
18
- });
19
-
20
- it('auto-closes an open code block', () => {
21
- expect(renderDuoChatMarkdownPreview('```yaml\n# comment')).toEqual(
22
- '<pre><code class="language-yaml"># comment\n</code></pre>\n'
23
- );
24
- });
25
-
26
- it('renders standard markdown syntax', () => {
27
- expect(renderDuoChatMarkdownPreview('*italic*')).toEqual(`<p><em>italic</em></p>\n`);
28
- expect(renderDuoChatMarkdownPreview('_italic_')).toEqual(`<p><em>italic</em></p>\n`);
29
- expect(renderDuoChatMarkdownPreview('**bold**')).toEqual(`<p><strong>bold</strong></p>\n`);
30
- expect(renderDuoChatMarkdownPreview('~~strike~~')).toEqual(`<p><del>strike</del></p>\n`);
31
- expect(renderDuoChatMarkdownPreview('https://example.org')).toEqual(
32
- `<p><a href="https://example.org">https://example.org</a></p>\n`
33
- );
34
- expect(renderDuoChatMarkdownPreview('[example](https://example.org)')).toEqual(
35
- `<p><a href="https://example.org">example</a></p>\n`
36
- );
37
- expect(renderDuoChatMarkdownPreview('1. first\n2. second')).toEqual(
38
- `<ol>\n<li>first</li>\n<li>second</li>\n</ol>\n`
39
- );
40
- expect(renderDuoChatMarkdownPreview('- first\n- second')).toEqual(
41
- `<ul>\n<li>first</li>\n<li>second</li>\n</ul>\n`
42
- );
43
- expect(renderDuoChatMarkdownPreview('* first\n* second')).toEqual(
44
- `<ul>\n<li>first</li>\n<li>second</li>\n</ul>\n`
45
- );
46
- });
47
-
48
- it('returns content as-is if marked throws', () => {
49
- jest.spyOn(Parser.prototype, 'parse').mockImplementationOnce(() => {
50
- throw new Error('I am a broken parser');
51
- });
52
-
53
- expect(renderDuoChatMarkdownPreview('Hello world')).toEqual('Hello world');
54
- });
55
- });
@@ -1,100 +0,0 @@
1
- import { shallowMount } from '@vue/test-utils';
2
- import GlButton from '../../../base/button/button.vue';
3
- import FeedbackModal from './user_feedback_modal.vue';
4
- import UserFeedback, { i18n } from './user_feedback.vue';
5
-
6
- const DummyComponent = {
7
- template: '<p>dummy</p>',
8
- };
9
-
10
- describe('UserFeedback', () => {
11
- let wrapper;
12
- const eventName = 'test_event_name';
13
-
14
- const createComponent = ({ props, data = {}, slots = {} } = {}) => {
15
- wrapper = shallowMount(UserFeedback, {
16
- data() {
17
- return data;
18
- },
19
- propsData: {
20
- eventName,
21
- ...props,
22
- },
23
- stubs: {
24
- FeedbackModal,
25
- },
26
- slots,
27
- });
28
- };
29
-
30
- const findButton = () => wrapper.findComponent(GlButton);
31
- const findModal = () => wrapper.findComponent(FeedbackModal);
32
-
33
- describe('rendering with no feedback registered', () => {
34
- beforeEach(() => {
35
- createComponent();
36
- });
37
-
38
- it('renders a button to provide feedback', () => {
39
- expect(findButton().exists()).toBe(true);
40
- });
41
-
42
- it('renders the feedback modal', () => {
43
- expect(findModal().exists()).toBe(true);
44
- });
45
- });
46
-
47
- it.each`
48
- feedbackLinkText | expectedButtonText
49
- ${'Foo'} | ${'Foo'}
50
- ${undefined} | ${i18n.FEEDBACK_LINK_TEXT}
51
- `(
52
- 'renders "$expectedButtonText" as button text when "$feedbackLinkText" is passed as the feedback link text',
53
- ({ feedbackLinkText, expectedButtonText } = {}) => {
54
- createComponent({ props: { feedbackLinkText } });
55
- expect(findButton().text()).toBe(expectedButtonText);
56
- }
57
- );
58
-
59
- it('does not render the modal if custom URL is passed for the feedback link', () => {
60
- const feedbackLinkUrl = 'https://example.com';
61
- createComponent({ props: { feedbackLinkUrl } });
62
- expect(findButton().attributes('href')).toBe(feedbackLinkUrl);
63
- expect(findModal().exists()).toBe(false);
64
- });
65
-
66
- describe('event handling', () => {
67
- const passedFeedback = { feedbackOptions: ['helpful'], extendedFeedback: 'Foo bar' };
68
-
69
- it('emits the event, containing the form data, when modal emits', () => {
70
- createComponent();
71
- findModal().vm.$emit('feedback-submitted', passedFeedback);
72
- expect(wrapper.emitted('feedback')).toHaveLength(1);
73
- });
74
-
75
- it('renders the thank you text instead of a button', async () => {
76
- createComponent({ props: { feedbackReceived: true } });
77
-
78
- expect(findButton().exists()).toBe(false);
79
- expect(wrapper.text()).toContain(i18n.FEEDBACK_THANKS);
80
- });
81
-
82
- it('does not render the modal after feedback submitted', async () => {
83
- createComponent({ props: { feedbackReceived: true } });
84
- expect(findModal().exists()).toBe(false);
85
- });
86
- });
87
-
88
- describe('slots', () => {
89
- beforeEach(() => {
90
- createComponent();
91
- });
92
-
93
- it('renders the `feedback-extra-fields` slot', () => {
94
- expect(wrapper.findComponent(DummyComponent).exists()).toBe(false);
95
- wrapper.destroy();
96
- createComponent({ slots: { 'feedback-extra-fields': DummyComponent } });
97
- expect(wrapper.findComponent(DummyComponent).exists()).toBe(true);
98
- });
99
- });
100
- });
@@ -1,107 +0,0 @@
1
- import GlAlert from '../../../base/alert/alert.vue';
2
- import GlFormGroup from '../../../base/form/form_group/form_group.vue';
3
- import GlFormTextarea from '../../../base/form/form_textarea/form_textarea.vue';
4
- import GlDuoUserFeedback from './user_feedback.vue';
5
- import readme from './user_feedback.md';
6
-
7
- const generateProps = ({ feedbackLinkText, feedbackLinkUrl } = {}) => ({
8
- feedbackLinkText,
9
- feedbackLinkUrl,
10
- });
11
-
12
- export const Default = (args, { argTypes }) => ({
13
- components: {
14
- GlDuoUserFeedback,
15
- GlAlert,
16
- GlFormGroup,
17
- GlFormTextarea,
18
- },
19
- props: Object.keys(argTypes),
20
- data() {
21
- return {
22
- eventOutput: '',
23
- };
24
- },
25
- methods: {
26
- logEvent(event) {
27
- this.eventOutput = JSON.stringify(event);
28
- },
29
- },
30
- template: `
31
- <div>
32
- <gl-duo-user-feedback
33
- :feedback-link-text="feedbackLinkText"
34
- :feedback-link-url="feedbackLinkUrl"
35
- @feedback="logEvent"/>
36
- <p v-if="eventOutput"><code>{{ eventOutput }}</code></p>
37
- </div>
38
- `,
39
- });
40
- Default.args = generateProps();
41
-
42
- export const Slots = (args, { argTypes }) => ({
43
- components: {
44
- GlDuoUserFeedback,
45
- GlAlert,
46
- GlFormGroup,
47
- GlFormTextarea,
48
- },
49
- props: Object.keys(argTypes),
50
- data() {
51
- return {
52
- eventOutput: '',
53
- didWhat: '',
54
- expectedWhat: '',
55
- improveWhat: '',
56
- };
57
- },
58
- methods: {
59
- logEvent(event) {
60
- const { feedbackChoices } = event;
61
- this.eventOutput = JSON.stringify({
62
- feedbackChoices,
63
- didWhat: this.didWhat,
64
- expectedWhat: this.expectedWhat,
65
- improveWhat: this.improveWhat,
66
- });
67
- },
68
- },
69
- template: `
70
- <div>
71
- <gl-duo-user-feedback
72
- :feedback-link-text="feedbackLinkText"
73
- :feedback-link-url="feedbackLinkUrl"
74
- @feedback="logEvent">
75
- <template #feedback-extra-fields>
76
- <div class="gl-mb-5">
77
- Example slot content: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
78
- </div>
79
- <gl-form-group label="What were you doing?" optional>
80
- <gl-form-textarea placeholder="The situation in which you interacted with GitLab Duo Chat." v-model="didWhat" />
81
- </gl-form-group>
82
- <gl-form-group label="What were you expecting from the response?" optional>
83
- <gl-form-textarea placeholder="What kind of information or assistance were you hoping to receive?" v-model="expectedWhat" />
84
- </gl-form-group>
85
- <gl-form-group label="How could the response be improved?" optional>
86
- <gl-form-textarea placeholder="How the response might better meet your needs."v-model="improveWhat" />
87
- </gl-form-group>
88
- </template>
89
- </gl-duo-user-feedback>
90
- <p v-if="eventOutput"><code>{{ eventOutput }}</code></p>
91
- </div>
92
- `,
93
- });
94
- Slots.parameters = { controls: { disable: true } };
95
-
96
- export default {
97
- title: 'experimental/duo/duo-user-feedback',
98
- component: GlDuoUserFeedback,
99
- tags: ['skip-visual-test'],
100
- parameters: {
101
- docs: {
102
- description: {
103
- component: readme,
104
- },
105
- },
106
- },
107
- };
@@ -1,134 +0,0 @@
1
- import { shallowMount } from '@vue/test-utils';
2
- import GlModal from '../../../base/modal/modal.vue';
3
- import GlAlert from '../../../base/alert/alert.vue';
4
- import GlFormCheckbox from '../../../base/form/form_checkbox/form_checkbox.vue';
5
- import GlFormCheckboxGroup from '../../../base/form/form_checkbox/form_checkbox_group.vue';
6
- import GlFormTextarea from '../../../base/form/form_textarea/form_textarea.vue';
7
- import FeedbackModal, { feedbackOptions } from './user_feedback_modal.vue';
8
-
9
- const DummyComponent = {
10
- template: '<p>dummy</p>',
11
- };
12
-
13
- describe('FeedbackModal', () => {
14
- let wrapper;
15
- const findByTestId = (testId) => wrapper.find(`[data-testid="${testId}"]`);
16
- const findModal = () => wrapper.findComponent(GlModal);
17
- const findOptions = () => findByTestId('feedback-options');
18
- const findOptionsCheckboxes = () => findOptions().findAllComponents(GlFormCheckbox);
19
- const findTextarea = () => wrapper.findComponent(GlFormTextarea);
20
-
21
- const selectOption = (index = 0) => {
22
- wrapper
23
- .findAllComponents(GlFormCheckboxGroup)
24
- .at(index)
25
- .vm.$emit('input', [feedbackOptions[index].value]);
26
- };
27
- const createComponent = (options = {}) => {
28
- wrapper = shallowMount(FeedbackModal, {
29
- ...options,
30
- stubs: {
31
- GlModal,
32
- GlFormCheckboxGroup,
33
- },
34
- provide: options.injections,
35
- });
36
-
37
- wrapper.vm.close = jest.fn();
38
- return wrapper;
39
- };
40
-
41
- describe('inputs', () => {
42
- beforeEach(() => {
43
- createComponent();
44
- });
45
-
46
- it('renders the feedback options', () => {
47
- const checkboxes = findOptionsCheckboxes();
48
- feedbackOptions.forEach((option, index) => {
49
- expect(checkboxes.at(index).text()).toBe(option.text);
50
- expect(checkboxes.at(index).attributes('value')).toBe(option.value);
51
- });
52
- });
53
-
54
- it('renders the textarea field for additional feedback', () => {
55
- expect(findTextarea().exists()).toBe(true);
56
- });
57
- });
58
-
59
- describe('interaction', () => {
60
- beforeEach(() => {
61
- createComponent();
62
- });
63
-
64
- it('emits the feedback event when the submit button is clicked and closes the modal', () => {
65
- selectOption();
66
- findModal().vm.$emit('primary');
67
- expect(wrapper.emitted('feedback-submitted')).toEqual([
68
- [
69
- {
70
- feedbackChoices: [feedbackOptions[0].value],
71
- extendedTextFeedback: '',
72
- },
73
- ],
74
- ]);
75
-
76
- expect(wrapper.vm.close).toHaveBeenCalledTimes(1);
77
- });
78
-
79
- it('does not render validation error by default', () => {
80
- expect(findOptions().vm.$attrs.state).not.toBe(false);
81
- });
82
-
83
- it('renders validation error when submit was triggered without selected a required option', async () => {
84
- findModal().vm.$emit('primary');
85
- await wrapper.vm.$nextTick();
86
-
87
- expect(findOptions().vm.$attrs.state).toBe(false);
88
- expect(findOptions().vm.$attrs['invalid-feedback']).toBe('Select at least one option.');
89
- expect(wrapper.emitted('feedback-submitted')).toBeUndefined();
90
- });
91
- });
92
-
93
- describe('slots', () => {
94
- beforeEach(() => {
95
- createComponent();
96
- });
97
-
98
- it('renders the `feedback-extra-fields` slot with default content', () => {
99
- expect(wrapper.findComponent(DummyComponent).exists()).toBe(false);
100
- expect(findTextarea().exists()).toBe(true);
101
- wrapper.destroy();
102
-
103
- createComponent({ slots: { 'feedback-extra-fields': DummyComponent } });
104
- expect(wrapper.findComponent(DummyComponent).exists()).toBe(true);
105
- expect(findTextarea().exists()).toBe(false);
106
- });
107
- });
108
-
109
- describe('injections', () => {
110
- it('should pass modalTitle when set as injection', () => {
111
- const customTitle = 'Custom Feedback Title';
112
- createComponent({ injections: { modalTitle: customTitle } });
113
- expect(findModal().props('title')).toBe(customTitle);
114
- });
115
-
116
- it('should pass modalTitle default when injection not set', () => {
117
- createComponent();
118
- expect(findModal().props('title')).toBe('Give feedback on GitLab Duo');
119
- });
120
-
121
- it('should pass modalAlert when set as injection', () => {
122
- const customAlert = 'Custom Alert Message';
123
- createComponent({ injections: { modalAlert: customAlert } });
124
- expect(wrapper.findComponent(GlAlert).text()).toBe(customAlert);
125
- });
126
-
127
- it('should render modalAlert default when injection not set', () => {
128
- createComponent();
129
- expect(wrapper.findComponent(GlAlert).text()).toBe(
130
- 'GitLab team members cannot see the AI content. Please be as descriptive as possible.'
131
- );
132
- });
133
- });
134
- });