@gitlab/ui 78.2.0 → 78.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## [78.2.1](https://gitlab.com/gitlab-org/gitlab-ui/compare/v78.2.0...v78.2.1) (2024-03-19)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **GlDuoChat:** clear prompt after /clean ([d3fcd9f](https://gitlab.com/gitlab-org/gitlab-ui/commit/d3fcd9f5aa20db65162cebf5ce0f52445725c87c))
7
+
1
8
  # [78.2.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v78.1.2...v78.2.0) (2024-03-14)
2
9
 
3
10
 
@@ -1,4 +1,5 @@
1
1
  const CHAT_RESET_MESSAGE = '/reset';
2
+ const CHAT_CLEAN_MESSAGE = '/clean';
2
3
  const LOADING_TRANSITION_DURATION = 7500;
3
4
  const DOCUMENTATION_SOURCE_TYPES = {
4
5
  HANDBOOK: {
@@ -20,4 +21,4 @@ const MESSAGE_MODEL_ROLES = {
20
21
  assistant: 'assistant'
21
22
  };
22
23
 
23
- export { CHAT_RESET_MESSAGE, DOCUMENTATION_SOURCE_TYPES, LOADING_TRANSITION_DURATION, MESSAGE_MODEL_ROLES };
24
+ export { CHAT_CLEAN_MESSAGE, CHAT_RESET_MESSAGE, DOCUMENTATION_SOURCE_TYPES, LOADING_TRANSITION_DURATION, MESSAGE_MODEL_ROLES };
@@ -237,13 +237,9 @@ var script = {
237
237
  }
238
238
  },
239
239
  watch: {
240
- isLoading(newVal) {
240
+ isLoading() {
241
241
  this.isHidden = false;
242
242
  this.scrollToBottom();
243
- if (newVal) {
244
- // We reset the prompt when we start getting the response and focus in the prompt field
245
- this.setPromptAndFocus();
246
- }
247
243
  }
248
244
  },
249
245
  created() {
@@ -274,6 +270,7 @@ var script = {
274
270
  * @param {String} prompt The user prompt to send.
275
271
  */
276
272
  this.$emit('send-chat-prompt', this.prompt);
273
+ this.setPromptAndFocus();
277
274
  }
278
275
  },
279
276
  sendPredefinedPrompt(prompt) {
@@ -1,5 +1,5 @@
1
1
  import { setStoryTimeout } from '../../../../utils/test_utils';
2
- import { DOCUMENTATION_SOURCE_TYPES, MESSAGE_MODEL_ROLES } from './constants';
2
+ import { DOCUMENTATION_SOURCE_TYPES, MESSAGE_MODEL_ROLES, CHAT_RESET_MESSAGE, CHAT_CLEAN_MESSAGE } from './constants';
3
3
 
4
4
  const MOCK_SOURCES = [{
5
5
  title: 'GitLab Handbook',
@@ -116,5 +116,23 @@ const renderGFM = el => {
116
116
  block === null || block === void 0 ? void 0 : block.classList.add('gl-markdown', 'gl-compact-markdown');
117
117
  });
118
118
  };
119
+ const SLASH_COMMANDS = [{
120
+ name: CHAT_RESET_MESSAGE,
121
+ shouldSubmit: true,
122
+ description: 'Reset conversation, ignore the previous messages.'
123
+ }, {
124
+ name: CHAT_CLEAN_MESSAGE,
125
+ shouldSubmit: true,
126
+ description: 'Delete all messages in this conversation.'
127
+ }, {
128
+ name: '/tests',
129
+ description: 'Write tests for the selected snippet.'
130
+ }, {
131
+ name: '/refactor',
132
+ description: 'Refactor the selected snippet.'
133
+ }, {
134
+ name: '/explain',
135
+ description: 'Explain the selected snippet.'
136
+ }];
119
137
 
120
- export { MOCK_RESPONSE_MESSAGE, MOCK_RESPONSE_MESSAGE_FOR_STREAMING, MOCK_USER_PROMPT_MESSAGE, generateMockResponseChunks, renderGFM, renderMarkdown };
138
+ export { MOCK_RESPONSE_MESSAGE, MOCK_RESPONSE_MESSAGE_FOR_STREAMING, MOCK_USER_PROMPT_MESSAGE, SLASH_COMMANDS, generateMockResponseChunks, renderGFM, renderMarkdown };
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Thu, 14 Mar 2024 18:11:11 GMT
3
+ * Generated on Tue, 19 Mar 2024 05:26:52 GMT
4
4
  */
5
5
 
6
6
  :root {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Thu, 14 Mar 2024 18:11:11 GMT
3
+ * Generated on Tue, 19 Mar 2024 05:26:52 GMT
4
4
  */
5
5
 
6
6
  :root.gl-dark {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Thu, 14 Mar 2024 18:11:11 GMT
3
+ * Generated on Tue, 19 Mar 2024 05:26:52 GMT
4
4
  */
5
5
 
6
6
  export const DATA_VIZ_GREEN_50 = "#133a03";
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Thu, 14 Mar 2024 18:11:11 GMT
3
+ * Generated on Tue, 19 Mar 2024 05:26:52 GMT
4
4
  */
5
5
 
6
6
  export const DATA_VIZ_GREEN_50 = "#ddfab7";
@@ -1,6 +1,6 @@
1
1
 
2
2
  // Do not edit directly
3
- // Generated on Thu, 14 Mar 2024 18:11:11 GMT
3
+ // Generated on Tue, 19 Mar 2024 05:26:52 GMT
4
4
 
5
5
  $gl-text-tertiary: #737278 !default;
6
6
  $gl-text-secondary: #89888d !default;
@@ -1,6 +1,6 @@
1
1
 
2
2
  // Do not edit directly
3
- // Generated on Thu, 14 Mar 2024 18:11:11 GMT
3
+ // Generated on Tue, 19 Mar 2024 05:26:52 GMT
4
4
 
5
5
  $gl-text-tertiary: #89888d !default;
6
6
  $gl-text-secondary: #737278 !default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitlab/ui",
3
- "version": "78.2.0",
3
+ "version": "78.2.1",
4
4
  "description": "GitLab UI Components",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -113,7 +113,7 @@
113
113
  "@storybook/addon-viewport": "^7.6.17",
114
114
  "@storybook/builder-webpack5": "^7.6.17",
115
115
  "@storybook/test": "^7.6.17",
116
- "@storybook/test-runner": "0.16.0",
116
+ "@storybook/test-runner": "0.17.0",
117
117
  "@storybook/theming": "^7.6.17",
118
118
  "@storybook/vue": "^7.6.17",
119
119
  "@storybook/vue-webpack5": "^7.6.17",
@@ -131,7 +131,7 @@
131
131
  "babel-jest": "29.0.1",
132
132
  "babel-loader": "^8.0.5",
133
133
  "bootstrap": "4.6.2",
134
- "cypress": "13.6.6",
134
+ "cypress": "13.7.0",
135
135
  "cypress-axe": "^1.4.0",
136
136
  "cypress-real-events": "^1.11.0",
137
137
  "dompurify": "^3.0.0",
@@ -171,7 +171,7 @@
171
171
  "sass-true": "^6.1.0",
172
172
  "start-server-and-test": "^1.10.6",
173
173
  "storybook": "^7.6.17",
174
- "storybook-dark-mode": "3.0.3",
174
+ "storybook-dark-mode": "4.0.0",
175
175
  "style-dictionary": "^3.8.0",
176
176
  "stylelint": "15.10.2",
177
177
  "tailwind-config-viewer": "1.7.3",
@@ -1,4 +1,5 @@
1
1
  export const CHAT_RESET_MESSAGE = '/reset';
2
+ export const CHAT_CLEAN_MESSAGE = '/clean';
2
3
 
3
4
  export const LOADING_TRANSITION_DURATION = 7500;
4
5
 
@@ -8,30 +8,14 @@ import DuoChatLoader from './components/duo_chat_loader/duo_chat_loader.vue';
8
8
  import DuoChatPredefinedPrompts from './components/duo_chat_predefined_prompts/duo_chat_predefined_prompts.vue';
9
9
  import DuoChatConversation from './components/duo_chat_conversation/duo_chat_conversation.vue';
10
10
  import GlDuoChat from './duo_chat.vue';
11
- import { MOCK_RESPONSE_MESSAGE, MOCK_USER_PROMPT_MESSAGE } from './mock_data';
11
+ import {
12
+ MOCK_RESPONSE_MESSAGE,
13
+ MOCK_USER_PROMPT_MESSAGE,
14
+ SLASH_COMMANDS as slashCommands,
15
+ } from './mock_data';
12
16
 
13
17
  import { MESSAGE_MODEL_ROLES, CHAT_RESET_MESSAGE } from './constants';
14
18
 
15
- const slashCommands = [
16
- {
17
- name: '/reset',
18
- shouldSubmit: true,
19
- description: 'Reset conversation, ignore the previous messages.',
20
- },
21
- {
22
- name: '/tests',
23
- description: 'Write tests for the selected snippet.',
24
- },
25
- {
26
- name: '/refactor',
27
- description: 'Refactor the selected snippet.',
28
- },
29
- {
30
- name: '/explain',
31
- description: 'Explain the selected snippet.',
32
- },
33
- ];
34
-
35
19
  const invalidSlashCommands = [
36
20
  {
37
21
  name: '/foo',
@@ -373,6 +357,28 @@ describe('GlDuoChat', () => {
373
357
  clickSubmit();
374
358
  expect(wrapper.emitted('send-chat-prompt')).toBe(undefined);
375
359
  });
360
+
361
+ it('resets the prompt after form submission', async () => {
362
+ const prompt = 'foo';
363
+ createComponent({ data: { prompt } });
364
+ expect(findChatInput().props('value')).toBe(prompt);
365
+ clickSubmit();
366
+ await nextTick();
367
+ expect(findChatInput().props('value')).toBe('');
368
+ });
369
+
370
+ it('focuses on prompt after form submission', async () => {
371
+ const focusSpy = jest.fn();
372
+ jest.spyOn(HTMLElement.prototype, 'focus').mockImplementation(function focusMockImpl() {
373
+ focusSpy(this);
374
+ });
375
+ createComponent({ data: { prompt: 'TEST!' } });
376
+
377
+ clickSubmit();
378
+ await nextTick();
379
+
380
+ expect(focusSpy).toHaveBeenCalledWith(findChatInput().element);
381
+ });
376
382
  });
377
383
 
378
384
  describe('reset', () => {
@@ -456,20 +462,6 @@ describe('GlDuoChat', () => {
456
462
  expect(findChatComponent().exists()).toBe(true);
457
463
  });
458
464
 
459
- it('resets the prompt when a message is loaded', async () => {
460
- const prompt = 'foo';
461
- createComponent({ data: { prompt } });
462
- expect(findChatInput().props('value')).toBe(prompt);
463
- // setProps is justified here because we are testing the component's
464
- // reactive behavior which consistutes an exception
465
- // See https://docs.gitlab.com/ee/development/fe_guide/style/vue.html#setting-component-state
466
- wrapper.setProps({
467
- isLoading: true,
468
- });
469
- await nextTick();
470
- expect(findChatInput().props('value')).toBe('');
471
- });
472
-
473
465
  it('renders custom loader when isLoading', () => {
474
466
  createComponent({ propsData: { isLoading: true } });
475
467
  expect(findCustomLoader().exists()).toBe(true);
@@ -773,7 +765,6 @@ describe('GlDuoChat', () => {
773
765
  expect(findSelectedSlashCommand().text()).toContain(command);
774
766
  findChatInput().trigger('keyup', { key: 'Enter' });
775
767
  await nextTick();
776
- expect(findChatInput().props('value')).toBe(`${command}`);
777
768
  expect(wrapper.emitted('send-chat-prompt')).toEqual([[command]]);
778
769
  });
779
770
  });
@@ -827,7 +818,6 @@ describe('GlDuoChat', () => {
827
818
  findSelectedSlashCommand().vm.$emit('click');
828
819
  await nextTick();
829
820
 
830
- expect(findChatInput().props('value')).toBe(slashCommandsNames[commandIndex]);
831
821
  expect(wrapper.emitted('send-chat-prompt')).toEqual([
832
822
  [slashCommandsNames[commandIndex]],
833
823
  ]);
@@ -3,33 +3,15 @@ import GlAlert from '../../../base/alert/alert.vue';
3
3
  import { makeContainer } from '../../../../utils/story_decorators/container';
4
4
  import GlDuoChat from './duo_chat.vue';
5
5
  import readme from './duo_chat.md';
6
+ import { CHAT_CLEAN_MESSAGE } from './constants';
6
7
  import {
7
8
  MOCK_RESPONSE_MESSAGE,
8
9
  MOCK_USER_PROMPT_MESSAGE,
10
+ SLASH_COMMANDS as slashCommands,
9
11
  generateMockResponseChunks,
10
12
  renderGFM,
11
13
  } from './mock_data';
12
14
 
13
- const slashCommands = [
14
- {
15
- name: '/reset',
16
- shouldSubmit: true,
17
- description: 'Reset conversation, ignore the previous messages.',
18
- },
19
- {
20
- name: '/tests',
21
- description: 'Write tests for the selected snippet.',
22
- },
23
- {
24
- name: '/refactor',
25
- description: 'Refactor the selected snippet.',
26
- },
27
- {
28
- name: '/explain',
29
- description: 'Explain the selected snippet.',
30
- },
31
- ];
32
-
33
15
  const defaultValue = (prop) =>
34
16
  typeof GlDuoChat.props[prop].default === 'function'
35
17
  ? GlDuoChat.props[prop].default()
@@ -120,8 +102,12 @@ export const Interactive = (args, { argTypes }) => ({
120
102
  requestId: this.requestId,
121
103
  };
122
104
  this.loggerInfo += `New prompt: ${JSON.stringify(newPrompt)}\n\n`;
123
- this.msgs.push(newPrompt);
124
- this.promptInFlight = true;
105
+ if (prompt === CHAT_CLEAN_MESSAGE) {
106
+ this.msgs = [];
107
+ } else {
108
+ this.msgs.push(newPrompt);
109
+ this.promptInFlight = true;
110
+ }
125
111
  },
126
112
  onChatHidden() {
127
113
  this.isHidden = true;
@@ -204,6 +190,8 @@ export const Interactive = (args, { argTypes }) => ({
204
190
  :empty-state-title="emptyStateTitle"
205
191
  :empty-state-description="emptyStateDescription"
206
192
  :chat-prompt-placeholder="chatPromptPlaceholder"
193
+ :slash-commands="slashCommands"
194
+ class="gl-drawer-default"
207
195
  @send-chat-prompt="onSendChatPrompt"
208
196
  @chat-hidden="onChatHidden"
209
197
  />
@@ -253,6 +241,7 @@ export const Slots = (args, { argTypes }) => ({
253
241
  </div>
254
242
  `,
255
243
  });
244
+ Slots.args = generateProps();
256
245
  Slots.decorators = [makeContainer({ height: '800px' })];
257
246
 
258
247
  export default {
@@ -253,13 +253,9 @@ export default {
253
253
  },
254
254
  },
255
255
  watch: {
256
- isLoading(newVal) {
256
+ isLoading() {
257
257
  this.isHidden = false;
258
258
  this.scrollToBottom();
259
- if (newVal) {
260
- // We reset the prompt when we start getting the response and focus in the prompt field
261
- this.setPromptAndFocus();
262
- }
263
259
  },
264
260
  },
265
261
  created() {
@@ -290,6 +286,7 @@ export default {
290
286
  * @param {String} prompt The user prompt to send.
291
287
  */
292
288
  this.$emit('send-chat-prompt', this.prompt);
289
+ this.setPromptAndFocus();
293
290
  }
294
291
  },
295
292
  sendPredefinedPrompt(prompt) {
@@ -1,5 +1,10 @@
1
1
  import { setStoryTimeout } from '../../../../utils/test_utils';
2
- import { DOCUMENTATION_SOURCE_TYPES, MESSAGE_MODEL_ROLES } from './constants';
2
+ import {
3
+ DOCUMENTATION_SOURCE_TYPES,
4
+ MESSAGE_MODEL_ROLES,
5
+ CHAT_RESET_MESSAGE,
6
+ CHAT_CLEAN_MESSAGE,
7
+ } from './constants';
3
8
 
4
9
  const MOCK_SOURCES = [
5
10
  {
@@ -119,3 +124,28 @@ export const renderGFM = (el) => {
119
124
  block?.classList.add('gl-markdown', 'gl-compact-markdown');
120
125
  });
121
126
  };
127
+
128
+ export const SLASH_COMMANDS = [
129
+ {
130
+ name: CHAT_RESET_MESSAGE,
131
+ shouldSubmit: true,
132
+ description: 'Reset conversation, ignore the previous messages.',
133
+ },
134
+ {
135
+ name: CHAT_CLEAN_MESSAGE,
136
+ shouldSubmit: true,
137
+ description: 'Delete all messages in this conversation.',
138
+ },
139
+ {
140
+ name: '/tests',
141
+ description: 'Write tests for the selected snippet.',
142
+ },
143
+ {
144
+ name: '/refactor',
145
+ description: 'Refactor the selected snippet.',
146
+ },
147
+ {
148
+ name: '/explain',
149
+ description: 'Explain the selected snippet.',
150
+ },
151
+ ];