@gitlab/ui 85.2.0 → 85.2.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [85.2.2](https://gitlab.com/gitlab-org/gitlab-ui/compare/v85.2.1...v85.2.2) (2024-06-26)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **duochat:** Wait for another enter to send on IME ([ed2a1e7](https://gitlab.com/gitlab-org/gitlab-ui/commit/ed2a1e7694805a3e72e78b1e4e9a6feac7f22c8b))
7
+
8
+ ## [85.2.1](https://gitlab.com/gitlab-org/gitlab-ui/compare/v85.2.0...v85.2.1) (2024-06-25)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **DuoChat:** don't show loading indicator on canceled messages ([4a3847b](https://gitlab.com/gitlab-org/gitlab-ui/commit/4a3847b3dad27300de170e8e2bdc42cfa937b8dd))
14
+
1
15
  # [85.2.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v85.1.0...v85.2.0) (2024-06-25)
2
16
 
3
17
 
@@ -23,6 +23,10 @@ var script = {
23
23
  default: () => [],
24
24
  validator: itemsValidator
25
25
  },
26
+ canceledRequestIds: {
27
+ type: Array,
28
+ required: true
29
+ },
26
30
  /**
27
31
  * Whether to show the delimiter before this conversation
28
32
  */
@@ -48,7 +52,7 @@ var script = {
48
52
  const __vue_script__ = script;
49
53
 
50
54
  /* template */
51
- var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"gl-display-flex gl-flex-direction-column gl-justify-content-end"},[(_vm.showDelimiter)?_c('div',{staticClass:"gl-my-5 gl-display-flex gl-align-items-center gl-text-gray-500 gl-gap-4",attrs:{"data-testid":"conversation-delimiter"}},[_c('hr',{staticClass:"gl-flex-grow-1"}),_vm._v(" "),_c('span',[_vm._v(_vm._s(_vm.$options.i18n.CONVERSATION_NEW_CHAT))]),_vm._v(" "),_c('hr',{staticClass:"gl-flex-grow-1"})]):_vm._e(),_vm._v(" "),_vm._l((_vm.messages),function(msg,index){return _c('gl-duo-chat-message',{key:((msg.role) + "-" + index),attrs:{"message":msg},on:{"track-feedback":_vm.onTrackFeedback}})})],2)};
55
+ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"gl-display-flex gl-flex-direction-column gl-justify-content-end"},[(_vm.showDelimiter)?_c('div',{staticClass:"gl-my-5 gl-display-flex gl-align-items-center gl-text-gray-500 gl-gap-4",attrs:{"data-testid":"conversation-delimiter"}},[_c('hr',{staticClass:"gl-flex-grow-1"}),_vm._v(" "),_c('span',[_vm._v(_vm._s(_vm.$options.i18n.CONVERSATION_NEW_CHAT))]),_vm._v(" "),_c('hr',{staticClass:"gl-flex-grow-1"})]):_vm._e(),_vm._v(" "),_vm._l((_vm.messages),function(msg,index){return _c('gl-duo-chat-message',{key:((msg.role) + "-" + index),attrs:{"message":msg,"is-cancelled":_vm.canceledRequestIds.includes(msg.requestId)},on:{"track-feedback":_vm.onTrackFeedback}})})],2)};
52
56
  var __vue_staticRenderFns__ = [];
53
57
 
54
58
  /* style */
@@ -70,6 +70,10 @@ var script = {
70
70
  message: {
71
71
  type: Object,
72
72
  required: true
73
+ },
74
+ isCancelled: {
75
+ type: Boolean,
76
+ required: true
73
77
  }
74
78
  },
75
79
  data() {
@@ -85,6 +89,12 @@ var script = {
85
89
  isChunk() {
86
90
  return typeof this.message.chunkId === 'number';
87
91
  },
92
+ isNotChunkOrCancelled() {
93
+ return !this.isChunk || this.isCancelled;
94
+ },
95
+ isChunkAndNotCancelled() {
96
+ return this.isChunk && !this.isCancelled;
97
+ },
88
98
  isAssistantMessage() {
89
99
  return this.message.role.toLowerCase() === MESSAGE_MODEL_ROLES.assistant;
90
100
  },
@@ -184,7 +194,7 @@ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=
184
194
  _vm.isAssistantMessage,
185
195
  'gl-bg-white': _vm.isAssistantMessage && !_vm.error,
186
196
  'gl-bg-red-50 gl-border-none!': _vm.error,
187
- }},[(_vm.error)?_c('gl-icon',{staticClass:"gl-text-red-600 gl-border gl-border-red-500 gl-rounded-full gl-mr-3 gl-flex-shrink-0 error-icon",attrs:{"aria-label":_vm.$options.i18n.MESSAGE_ERROR,"name":"status_warning_borderless","size":16,"data-testid":"error"}}):_vm._e(),_vm._v(" "),_c('div',{ref:"content-wrapper",class:{ 'has-error': _vm.error }},[(_vm.error)?_c('div',{ref:"error-message"},[_vm._v(_vm._s(_vm.error))]):_c('div',[_c('div',{directives:[{name:"safe-html",rawName:"v-safe-html:[$options.safeHtmlConfigExtension]",value:(_vm.messageContent),expression:"messageContent",arg:_vm.$options.safeHtmlConfigExtension}],ref:"content"}),_vm._v(" "),(_vm.isAssistantMessage)?[(_vm.sources)?_c('documentation-sources',{attrs:{"sources":_vm.sources}}):_vm._e(),_vm._v(" "),_c('div',{staticClass:"gl-display-flex gl-align-items-flex-end gl-mt-4 duo-chat-message-feedback"},[(_vm.isChunk)?_c('gl-loading-icon',{staticClass:"gl-pt-4",attrs:{"variant":"dots","inline":""}}):_vm._e(),_vm._v(" "),(!_vm.isChunk)?_c('gl-duo-user-feedback',{attrs:{"feedback-received":_vm.hasFeedback,"modal-title":_vm.$options.i18n.MODAL.TITLE,"modal-alert":_vm.$options.i18n.MODAL.ALERT_TEXT},on:{"feedback":_vm.logEvent},scopedSlots:_vm._u([{key:"feedback-extra-fields",fn:function(){return [_c('gl-form-group',{attrs:{"label":_vm.$options.i18n.MODAL.DID_WHAT,"optional":""}},[_c('gl-form-textarea',{attrs:{"placeholder":_vm.$options.i18n.MODAL.INTERACTION},model:{value:(_vm.didWhat),callback:function ($$v) {_vm.didWhat=$$v;},expression:"didWhat"}})],1),_vm._v(" "),_c('gl-form-group',{attrs:{"label":_vm.$options.i18n.MODAL.IMPROVE_WHAT,"optional":""}},[_c('gl-form-textarea',{attrs:{"placeholder":_vm.$options.i18n.MODAL.BETTER_RESPONSE},model:{value:(_vm.improveWhat),callback:function ($$v) {_vm.improveWhat=$$v;},expression:"improveWhat"}})],1)]},proxy:true}],null,false,419229417)}):_vm._e()],1)]:_vm._e()],2)])],1)};
197
+ }},[(_vm.error)?_c('gl-icon',{staticClass:"gl-text-red-600 gl-border gl-border-red-500 gl-rounded-full gl-mr-3 gl-flex-shrink-0 error-icon",attrs:{"aria-label":_vm.$options.i18n.MESSAGE_ERROR,"name":"status_warning_borderless","size":16,"data-testid":"error"}}):_vm._e(),_vm._v(" "),_c('div',{ref:"content-wrapper",class:{ 'has-error': _vm.error }},[(_vm.error)?_c('div',{ref:"error-message"},[_vm._v(_vm._s(_vm.error))]):_c('div',[_c('div',{directives:[{name:"safe-html",rawName:"v-safe-html:[$options.safeHtmlConfigExtension]",value:(_vm.messageContent),expression:"messageContent",arg:_vm.$options.safeHtmlConfigExtension}],ref:"content"}),_vm._v(" "),(_vm.isAssistantMessage)?[(_vm.sources)?_c('documentation-sources',{attrs:{"sources":_vm.sources}}):_vm._e(),_vm._v(" "),_c('div',{staticClass:"gl-display-flex gl-align-items-flex-end gl-mt-4 duo-chat-message-feedback"},[(_vm.isChunkAndNotCancelled)?_c('gl-loading-icon',{staticClass:"gl-pt-4",attrs:{"variant":"dots","inline":""}}):_vm._e(),_vm._v(" "),(_vm.isNotChunkOrCancelled)?_c('gl-duo-user-feedback',{attrs:{"feedback-received":_vm.hasFeedback,"modal-title":_vm.$options.i18n.MODAL.TITLE,"modal-alert":_vm.$options.i18n.MODAL.ALERT_TEXT},on:{"feedback":_vm.logEvent},scopedSlots:_vm._u([{key:"feedback-extra-fields",fn:function(){return [_c('gl-form-group',{attrs:{"label":_vm.$options.i18n.MODAL.DID_WHAT,"optional":""}},[_c('gl-form-textarea',{attrs:{"placeholder":_vm.$options.i18n.MODAL.INTERACTION},model:{value:(_vm.didWhat),callback:function ($$v) {_vm.didWhat=$$v;},expression:"didWhat"}})],1),_vm._v(" "),_c('gl-form-group',{attrs:{"label":_vm.$options.i18n.MODAL.IMPROVE_WHAT,"optional":""}},[_c('gl-form-textarea',{attrs:{"placeholder":_vm.$options.i18n.MODAL.BETTER_RESPONSE},model:{value:(_vm.improveWhat),callback:function ($$v) {_vm.improveWhat=$$v;},expression:"improveWhat"}})],1)]},proxy:true}],null,false,419229417)}):_vm._e()],1)]:_vm._e()],2)])],1)};
188
198
  var __vue_staticRenderFns__ = [];
189
199
 
190
200
  /* style */
@@ -76,6 +76,11 @@ var script = {
76
76
  default: () => [],
77
77
  validator: itemsValidator
78
78
  },
79
+ canceledRequestIds: {
80
+ type: Array,
81
+ required: false,
82
+ default: () => []
83
+ },
79
84
  /**
80
85
  * A non-recoverable error message to display in the chat.
81
86
  */
@@ -181,7 +186,8 @@ var script = {
181
186
  prompt: '',
182
187
  scrolledToBottom: true,
183
188
  activeCommandIndex: 0,
184
- displaySubmitButton: true
189
+ displaySubmitButton: true,
190
+ compositionJustEnded: false
185
191
  };
186
192
  },
187
193
  computed: {
@@ -257,6 +263,9 @@ var script = {
257
263
  this.scrollToBottom();
258
264
  },
259
265
  methods: {
266
+ compositionEnd() {
267
+ this.compositionJustEnded = true;
268
+ },
260
269
  hideChat() {
261
270
  this.isHidden = true;
262
271
  /**
@@ -318,7 +327,7 @@ var script = {
318
327
  */
319
328
  this.$emit('track-feedback', event);
320
329
  },
321
- onInputKeyup(e) {
330
+ sendChatPromptOnEnter(e) {
322
331
  const {
323
332
  metaKey,
324
333
  ctrlKey,
@@ -326,21 +335,29 @@ var script = {
326
335
  shiftKey,
327
336
  isComposing
328
337
  } = e;
338
+ const isModifierKey = metaKey || ctrlKey || altKey || shiftKey;
339
+ return !(isModifierKey || isComposing || this.compositionJustEnded);
340
+ },
341
+ onInputKeyup(e) {
342
+ const {
343
+ key
344
+ } = e;
329
345
  if (this.shouldShowSlashCommands) {
330
346
  e.preventDefault();
331
- if (e.key === 'Enter') {
347
+ if (key === 'Enter') {
332
348
  this.selectSlashCommand(this.activeCommandIndex);
333
- } else if (e.key === 'ArrowUp') {
349
+ } else if (key === 'ArrowUp') {
334
350
  this.prevCommand();
335
- } else if (e.key === 'ArrowDown') {
351
+ } else if (key === 'ArrowDown') {
336
352
  this.nextCommand();
337
353
  } else {
338
354
  this.activeCommandIndex = 0;
339
355
  }
340
- } else if (e.key === 'Enter' && !isComposing && !(metaKey || ctrlKey || altKey || shiftKey)) {
356
+ } else if (key === 'Enter' && this.sendChatPromptOnEnter(e)) {
341
357
  e.preventDefault();
342
358
  this.sendChatPrompt();
343
359
  }
360
+ this.compositionJustEnded = false;
344
361
  },
345
362
  prevCommand() {
346
363
  this.activeCommandIndex -= 1;
@@ -385,7 +402,7 @@ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=
385
402
  {
386
403
  'gl-h-full': !_vm.hasMessages,
387
404
  'force-scroll-bar': _vm.hasMessages,
388
- } ],attrs:{"tag":"section","name":"message"}},[_vm._l((_vm.conversations),function(conversation,index){return _c('gl-duo-chat-conversation',{key:("conversation-" + index),attrs:{"messages":conversation,"show-delimiter":index > 0},on:{"track-feedback":_vm.onTrackFeedback}})}),_vm._v(" "),(!_vm.hasMessages && !_vm.isLoading)?[_c('gl-empty-state',{key:"empty-state",staticClass:"gl-flex-grow gl-justify-content-center",attrs:{"svg-path":_vm.$options.emptySvg,"svg-height":145,"title":_vm.emptyStateTitle,"description":_vm.emptyStateDescription}}),_vm._v(" "),_c('gl-duo-chat-predefined-prompts',{key:"predefined-prompts",attrs:{"prompts":_vm.predefinedPrompts},on:{"click":_vm.sendPredefinedPrompt}})]:_vm._e(),_vm._v(" "),(_vm.isLoading)?_c('gl-duo-chat-loader',{key:"loader",attrs:{"tool-name":_vm.toolName}}):_vm._e(),_vm._v(" "),_c('div',{key:"anchor",ref:"anchor",staticClass:"scroll-anchor"})],2)],1),_vm._v(" "),(_vm.isChatAvailable)?_c('footer',{staticClass:"duo-chat-drawer-footer duo-chat-drawer-footer-sticky gl-p-5 gl-border-t gl-bg-gray-10",class:{ 'duo-chat-drawer-body-scrim-on-footer': !_vm.scrolledToBottom },attrs:{"data-testid":"chat-footer"}},[_c('gl-form',{attrs:{"data-testid":"chat-prompt-form"},on:{"submit":function($event){$event.stopPropagation();$event.preventDefault();return _vm.sendChatPrompt.apply(null, arguments)}}},[_c('gl-form-input-group',{scopedSlots:_vm._u([{key:"append",fn:function(){return [(_vm.displaySubmitButton)?_c('gl-button',{staticClass:"!gl-absolute gl-bottom-2 gl-right-2 gl-rounded-base!",attrs:{"icon":"paper-airplane","category":"primary","variant":"confirm","type":"submit","data-testid":"chat-prompt-submit-button","aria-label":_vm.$options.i18n.CHAT_SUBMIT_LABEL}}):_c('gl-button',{staticClass:"!gl-absolute gl-bottom-2 gl-right-2 gl-rounded-base!",attrs:{"icon":"stop","category":"primary","variant":"default","data-testid":"chat-prompt-cancel-button","aria-label":_vm.$options.i18n.CHAT_CANCEL_LABEL},on:{"click":_vm.cancelPrompt}})]},proxy:true}],null,false,2711323372)},[_c('div',{staticClass:"duo-chat-input gl-flex-grow-1 gl-vertical-align-top gl-max-w-full gl-min-h-8 gl-inset-border-1-gray-400 gl-rounded-base gl-bg-white",attrs:{"data-value":_vm.prompt}},[(_vm.shouldShowSlashCommands)?_c('gl-card',{ref:"commands",staticClass:"slash-commands !gl-absolute gl-translate-y-n100 gl-list-style-none gl-pl-0 gl-w-full gl-shadow-md",attrs:{"body-class":"gl-p-2!"}},_vm._l((_vm.filteredSlashCommands),function(command,index){return _c('gl-dropdown-item',{key:command.name,class:{ 'active-command': index === _vm.activeCommandIndex },on:{"click":function($event){return _vm.selectSlashCommand(index)}},nativeOn:{"mouseenter":function($event){_vm.activeCommandIndex = index;}}},[_c('span',{staticClass:"gl-display-flex gl-justify-content-space-between"},[_c('span',{staticClass:"gl-display-block"},[_vm._v(_vm._s(command.name))]),_vm._v(" "),_c('small',{staticClass:"gl-text-gray-500 gl-font-style-italic gl-text-right gl-pl-3"},[_vm._v(_vm._s(command.description))])])])}),1):_vm._e(),_vm._v(" "),_c('gl-form-textarea',{ref:"prompt",staticClass:"gl-absolute gl-h-full! gl-py-4! gl-bg-transparent! gl-rounded-top-right-none gl-rounded-bottom-right-none gl-shadow-none!",class:{ 'gl-text-truncate': !_vm.prompt },attrs:{"data-testid":"chat-prompt-input","placeholder":_vm.inputPlaceholder,"autofocus":""},nativeOn:{"keydown":function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"enter",13,$event.key,"Enter")){ return null; }if($event.ctrlKey||$event.shiftKey||$event.altKey||$event.metaKey){ return null; }$event.preventDefault();},"keyup":function($event){return _vm.onInputKeyup.apply(null, arguments)}},model:{value:(_vm.prompt),callback:function ($$v) {_vm.prompt=$$v;},expression:"prompt"}})],1)]),_vm._v(" "),_c('gl-form-text',{staticClass:"gl-text-gray-400 gl-line-height-20 gl-mt-3",attrs:{"data-testid":"chat-legal-disclaimer"}},[_vm._v(_vm._s(_vm.$options.i18n.CHAT_LEGAL_DISCLAIMER))])],1)],1):_vm._e()]):_vm._e()};
405
+ } ],attrs:{"tag":"section","name":"message"}},[_vm._l((_vm.conversations),function(conversation,index){return _c('gl-duo-chat-conversation',{key:("conversation-" + index),attrs:{"messages":conversation,"canceled-request-ids":_vm.canceledRequestIds,"show-delimiter":index > 0},on:{"track-feedback":_vm.onTrackFeedback}})}),_vm._v(" "),(!_vm.hasMessages && !_vm.isLoading)?[_c('gl-empty-state',{key:"empty-state",staticClass:"gl-flex-grow gl-justify-content-center",attrs:{"svg-path":_vm.$options.emptySvg,"svg-height":145,"title":_vm.emptyStateTitle,"description":_vm.emptyStateDescription}}),_vm._v(" "),_c('gl-duo-chat-predefined-prompts',{key:"predefined-prompts",attrs:{"prompts":_vm.predefinedPrompts},on:{"click":_vm.sendPredefinedPrompt}})]:_vm._e(),_vm._v(" "),(_vm.isLoading)?_c('gl-duo-chat-loader',{key:"loader",attrs:{"tool-name":_vm.toolName}}):_vm._e(),_vm._v(" "),_c('div',{key:"anchor",ref:"anchor",staticClass:"scroll-anchor"})],2)],1),_vm._v(" "),(_vm.isChatAvailable)?_c('footer',{staticClass:"duo-chat-drawer-footer duo-chat-drawer-footer-sticky gl-p-5 gl-border-t gl-bg-gray-10",class:{ 'duo-chat-drawer-body-scrim-on-footer': !_vm.scrolledToBottom },attrs:{"data-testid":"chat-footer"}},[_c('gl-form',{attrs:{"data-testid":"chat-prompt-form"},on:{"submit":function($event){$event.stopPropagation();$event.preventDefault();return _vm.sendChatPrompt.apply(null, arguments)}}},[_c('gl-form-input-group',{scopedSlots:_vm._u([{key:"append",fn:function(){return [(_vm.displaySubmitButton)?_c('gl-button',{staticClass:"!gl-absolute gl-bottom-2 gl-right-2 gl-rounded-base!",attrs:{"icon":"paper-airplane","category":"primary","variant":"confirm","type":"submit","data-testid":"chat-prompt-submit-button","aria-label":_vm.$options.i18n.CHAT_SUBMIT_LABEL}}):_c('gl-button',{staticClass:"!gl-absolute gl-bottom-2 gl-right-2 gl-rounded-base!",attrs:{"icon":"stop","category":"primary","variant":"default","data-testid":"chat-prompt-cancel-button","aria-label":_vm.$options.i18n.CHAT_CANCEL_LABEL},on:{"click":_vm.cancelPrompt}})]},proxy:true}],null,false,2711323372)},[_c('div',{staticClass:"duo-chat-input gl-flex-grow-1 gl-vertical-align-top gl-max-w-full gl-min-h-8 gl-inset-border-1-gray-400 gl-rounded-base gl-bg-white",attrs:{"data-value":_vm.prompt}},[(_vm.shouldShowSlashCommands)?_c('gl-card',{ref:"commands",staticClass:"slash-commands !gl-absolute gl-translate-y-n100 gl-list-style-none gl-pl-0 gl-w-full gl-shadow-md",attrs:{"body-class":"gl-p-2!"}},_vm._l((_vm.filteredSlashCommands),function(command,index){return _c('gl-dropdown-item',{key:command.name,class:{ 'active-command': index === _vm.activeCommandIndex },on:{"click":function($event){return _vm.selectSlashCommand(index)}},nativeOn:{"mouseenter":function($event){_vm.activeCommandIndex = index;}}},[_c('span',{staticClass:"gl-display-flex gl-justify-content-space-between"},[_c('span',{staticClass:"gl-display-block"},[_vm._v(_vm._s(command.name))]),_vm._v(" "),_c('small',{staticClass:"gl-text-gray-500 gl-font-style-italic gl-text-right gl-pl-3"},[_vm._v(_vm._s(command.description))])])])}),1):_vm._e(),_vm._v(" "),_c('gl-form-textarea',{ref:"prompt",staticClass:"gl-absolute gl-h-full! gl-py-4! gl-bg-transparent! gl-rounded-top-right-none gl-rounded-bottom-right-none gl-shadow-none!",class:{ 'gl-text-truncate': !_vm.prompt },attrs:{"data-testid":"chat-prompt-input","placeholder":_vm.inputPlaceholder,"autofocus":""},on:{"compositionend":_vm.compositionEnd},nativeOn:{"keydown":function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"enter",13,$event.key,"Enter")){ return null; }if($event.ctrlKey||$event.shiftKey||$event.altKey||$event.metaKey){ return null; }$event.preventDefault();},"keyup":function($event){return _vm.onInputKeyup.apply(null, arguments)}},model:{value:(_vm.prompt),callback:function ($$v) {_vm.prompt=$$v;},expression:"prompt"}})],1)]),_vm._v(" "),_c('gl-form-text',{staticClass:"gl-text-gray-400 gl-line-height-20 gl-mt-3",attrs:{"data-testid":"chat-legal-disclaimer"}},[_vm._v(_vm._s(_vm.$options.i18n.CHAT_LEGAL_DISCLAIMER))])],1)],1):_vm._e()]):_vm._e()};
389
406
  var __vue_staticRenderFns__ = [];
390
407
 
391
408
  /* style */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitlab/ui",
3
- "version": "85.2.0",
3
+ "version": "85.2.2",
4
4
  "description": "GitLab UI Components",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -188,7 +188,7 @@
188
188
  "sass-true": "^6.1.0",
189
189
  "start-server-and-test": "^1.10.6",
190
190
  "storybook": "^7.6.19",
191
- "storybook-dark-mode": "4.0.1",
191
+ "storybook-dark-mode": "4.0.2",
192
192
  "style-dictionary": "^3.8.0",
193
193
  "stylelint": "15.10.2",
194
194
  "tailwind-config-viewer": "1.7.3",
@@ -25,6 +25,10 @@ export default {
25
25
  default: () => [],
26
26
  validator: itemsValidator,
27
27
  },
28
+ canceledRequestIds: {
29
+ type: Array,
30
+ required: true,
31
+ },
28
32
  /**
29
33
  * Whether to show the delimiter before this conversation
30
34
  */
@@ -57,11 +61,11 @@ export default {
57
61
  <span>{{ $options.i18n.CONVERSATION_NEW_CHAT }}</span>
58
62
  <hr class="gl-flex-grow-1" />
59
63
  </div>
60
-
61
64
  <gl-duo-chat-message
62
65
  v-for="(msg, index) in messages"
63
66
  :key="`${msg.role}-${index}`"
64
67
  :message="msg"
68
+ :is-cancelled="canceledRequestIds.includes(msg.requestId)"
65
69
  @track-feedback="onTrackFeedback"
66
70
  />
67
71
  </div>
@@ -74,6 +74,10 @@ export default {
74
74
  type: Object,
75
75
  required: true,
76
76
  },
77
+ isCancelled: {
78
+ type: Boolean,
79
+ required: true,
80
+ },
77
81
  },
78
82
  data() {
79
83
  return {
@@ -87,6 +91,12 @@ export default {
87
91
  isChunk() {
88
92
  return typeof this.message.chunkId === 'number';
89
93
  },
94
+ isNotChunkOrCancelled() {
95
+ return !this.isChunk || this.isCancelled;
96
+ },
97
+ isChunkAndNotCancelled() {
98
+ return this.isChunk && !this.isCancelled;
99
+ },
90
100
  isAssistantMessage() {
91
101
  return this.message.role.toLowerCase() === MESSAGE_MODEL_ROLES.assistant;
92
102
  },
@@ -201,9 +211,9 @@ export default {
201
211
  <documentation-sources v-if="sources" :sources="sources" />
202
212
 
203
213
  <div class="gl-display-flex gl-align-items-flex-end gl-mt-4 duo-chat-message-feedback">
204
- <gl-loading-icon v-if="isChunk" class="gl-pt-4" variant="dots" inline />
214
+ <gl-loading-icon v-if="isChunkAndNotCancelled" class="gl-pt-4" variant="dots" inline />
205
215
  <gl-duo-user-feedback
206
- v-if="!isChunk"
216
+ v-if="isNotChunkOrCancelled"
207
217
  :feedback-received="hasFeedback"
208
218
  :modal-title="$options.i18n.MODAL.TITLE"
209
219
  :modal-alert="$options.i18n.MODAL.ALERT_TEXT"
@@ -84,6 +84,11 @@ export default {
84
84
  default: () => [],
85
85
  validator: itemsValidator,
86
86
  },
87
+ canceledRequestIds: {
88
+ type: Array,
89
+ required: false,
90
+ default: () => [],
91
+ },
87
92
  /**
88
93
  * A non-recoverable error message to display in the chat.
89
94
  */
@@ -190,6 +195,7 @@ export default {
190
195
  scrolledToBottom: true,
191
196
  activeCommandIndex: 0,
192
197
  displaySubmitButton: true,
198
+ compositionJustEnded: false,
193
199
  };
194
200
  },
195
201
  computed: {
@@ -275,6 +281,9 @@ export default {
275
281
  this.scrollToBottom();
276
282
  },
277
283
  methods: {
284
+ compositionEnd() {
285
+ this.compositionJustEnded = true;
286
+ },
278
287
  hideChat() {
279
288
  this.isHidden = true;
280
289
  /**
@@ -333,26 +342,34 @@ export default {
333
342
  */
334
343
  this.$emit('track-feedback', event);
335
344
  },
336
- onInputKeyup(e) {
345
+ sendChatPromptOnEnter(e) {
337
346
  const { metaKey, ctrlKey, altKey, shiftKey, isComposing } = e;
347
+ const isModifierKey = metaKey || ctrlKey || altKey || shiftKey;
348
+
349
+ return !(isModifierKey || isComposing || this.compositionJustEnded);
350
+ },
351
+ onInputKeyup(e) {
352
+ const { key } = e;
338
353
 
339
354
  if (this.shouldShowSlashCommands) {
340
355
  e.preventDefault();
341
356
 
342
- if (e.key === 'Enter') {
357
+ if (key === 'Enter') {
343
358
  this.selectSlashCommand(this.activeCommandIndex);
344
- } else if (e.key === 'ArrowUp') {
359
+ } else if (key === 'ArrowUp') {
345
360
  this.prevCommand();
346
- } else if (e.key === 'ArrowDown') {
361
+ } else if (key === 'ArrowDown') {
347
362
  this.nextCommand();
348
363
  } else {
349
364
  this.activeCommandIndex = 0;
350
365
  }
351
- } else if (e.key === 'Enter' && !isComposing && !(metaKey || ctrlKey || altKey || shiftKey)) {
366
+ } else if (key === 'Enter' && this.sendChatPromptOnEnter(e)) {
352
367
  e.preventDefault();
353
368
 
354
369
  this.sendChatPrompt();
355
370
  }
371
+
372
+ this.compositionJustEnded = false;
356
373
  },
357
374
  prevCommand() {
358
375
  this.activeCommandIndex -= 1;
@@ -468,6 +485,7 @@ export default {
468
485
  v-for="(conversation, index) in conversations"
469
486
  :key="`conversation-${index}`"
470
487
  :messages="conversation"
488
+ :canceled-request-ids="canceledRequestIds"
471
489
  :show-delimiter="index > 0"
472
490
  @track-feedback="onTrackFeedback"
473
491
  />
@@ -534,6 +552,7 @@ export default {
534
552
  autofocus
535
553
  @keydown.enter.exact.native.prevent
536
554
  @keyup.native="onInputKeyup"
555
+ @compositionend="compositionEnd"
537
556
  />
538
557
  </div>
539
558
  <template #append>