@gitlab/duo-ui 10.11.0 → 10.12.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.
Files changed (36) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/components/agentic_chat/agentic_duo_chat.js +3 -3
  3. package/dist/components/agentic_chat/components/agentic_tool_approval_flow/agentic_tool_approval_modal/agentic_tool_approval_modal.js +1 -1
  4. package/dist/components/chat/components/duo_chat_context/duo_chat_context_item_menu/duo_chat_context_item_menu.js +1 -1
  5. package/dist/components/chat/components/duo_chat_header/duo_chat_header.js +1 -1
  6. package/dist/components/chat/components/duo_chat_message/duo_chat_message.js +4 -4
  7. package/dist/components/chat/components/duo_chat_message/message_types/message_base.js +1 -1
  8. package/dist/components/chat/components/duo_chat_message/message_types/message_tool.js +1 -1
  9. package/dist/components/chat/components/duo_chat_message/message_types/message_user.js +1 -1
  10. package/dist/components/chat/components/duo_chat_message_tool_approval/message_tool_approval.js +1 -1
  11. package/dist/components/chat/components/duo_chat_predefined_prompts/duo_chat_predefined_prompts.js +1 -1
  12. package/dist/components/chat/components/duo_chat_threads/duo_chat_threads.js +6 -3
  13. package/dist/components/chat/components/duo_chat_threads/duo_chat_threads_empty.js +1 -1
  14. package/dist/components/chat/duo_chat.js +2 -2
  15. package/dist/components/chat/mock_data.js +112 -1
  16. package/dist/components/ui/duo_navigation_bar/duo_navigation_bar.js +1 -1
  17. package/dist/components/ui/duo_recent_collapsible/duo_recent_collapsible.js +1 -1
  18. package/dist/components/ui/duo_terminal_command/duo_terminal_command.js +1 -1
  19. package/package.json +2 -1
  20. package/src/components/agentic_chat/agentic_duo_chat.vue +9 -10
  21. package/src/components/agentic_chat/components/agentic_tool_approval_flow/agentic_tool_approval_modal/agentic_tool_approval_modal.vue +2 -2
  22. package/src/components/chat/components/duo_chat_context/duo_chat_context_item_menu/duo_chat_context_item_menu.vue +2 -2
  23. package/src/components/chat/components/duo_chat_header/duo_chat_header.vue +2 -2
  24. package/src/components/chat/components/duo_chat_message/duo_chat_message.vue +4 -4
  25. package/src/components/chat/components/duo_chat_message/message_types/message_base.vue +1 -1
  26. package/src/components/chat/components/duo_chat_message/message_types/message_tool.vue +4 -4
  27. package/src/components/chat/components/duo_chat_message/message_types/message_user.vue +1 -1
  28. package/src/components/chat/components/duo_chat_message_tool_approval/message_tool_approval.vue +6 -6
  29. package/src/components/chat/components/duo_chat_predefined_prompts/duo_chat_predefined_prompts.vue +0 -1
  30. package/src/components/chat/components/duo_chat_threads/duo_chat_threads.vue +11 -7
  31. package/src/components/chat/components/duo_chat_threads/duo_chat_threads_empty.vue +2 -2
  32. package/src/components/chat/duo_chat.vue +4 -4
  33. package/src/components/chat/mock_data.js +133 -0
  34. package/src/components/ui/duo_navigation_bar/duo_navigation_bar.vue +1 -1
  35. package/src/components/ui/duo_recent_collapsible/duo_recent_collapsible.vue +1 -1
  36. package/src/components/ui/duo_terminal_command/duo_terminal_command.vue +4 -4
@@ -40,7 +40,7 @@ var script = {
40
40
  const __vue_script__ = script;
41
41
 
42
42
  /* template */
43
- var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"gl-flex gl-gap-1 gl-justify-end"},[_vm._l((_vm.navigationItems),function(item){return _c('gl-link',{key:item.routeName,staticClass:"navigation-link nav-bar-link gl-p-2",attrs:{"to":item.to},on:{"click":function($event){return _vm.$emit('navigation-item-selected', item)}}},[_c('gl-icon',{attrs:{"name":item.iconName}})],1)}),_vm._v(" "),_vm._t("custom-content"),_vm._v(" "),(_vm.showDropdown)?_c('gl-dropdown',{attrs:{"text":"More actions","text-sr-only":"","category":"tertiary","variant":"default","size":"medium","icon":"ellipsis_h","block":false,"no-caret":""}},_vm._l((_vm.dropdownItems),function(item){return _c('gl-dropdown-item',{key:item.id,on:{"click":function($event){return _vm.$emit('dropdown-item-selected', item)}}},[_vm._v("\n "+_vm._s(item.text)+"\n ")])}),1):_vm._e()],2)};
43
+ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"gl-flex gl-justify-end gl-gap-1"},[_vm._l((_vm.navigationItems),function(item){return _c('gl-link',{key:item.routeName,staticClass:"navigation-link nav-bar-link gl-p-2",attrs:{"to":item.to},on:{"click":function($event){return _vm.$emit('navigation-item-selected', item)}}},[_c('gl-icon',{attrs:{"name":item.iconName}})],1)}),_vm._v(" "),_vm._t("custom-content"),_vm._v(" "),(_vm.showDropdown)?_c('gl-dropdown',{attrs:{"text":"More actions","text-sr-only":"","category":"tertiary","variant":"default","size":"medium","icon":"ellipsis_h","block":false,"no-caret":""}},_vm._l((_vm.dropdownItems),function(item){return _c('gl-dropdown-item',{key:item.id,on:{"click":function($event){return _vm.$emit('dropdown-item-selected', item)}}},[_vm._v("\n "+_vm._s(item.text)+"\n ")])}),1):_vm._e()],2)};
44
44
  var __vue_staticRenderFns__ = [];
45
45
 
46
46
  /* style */
@@ -82,7 +82,7 @@ var script = {
82
82
  const __vue_script__ = script;
83
83
 
84
84
  /* template */
85
- var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('gl-accordion',{attrs:{"auto-collapse":false,"header-level":3}},[(_vm.showViewAllButton)?_c('gl-link',{staticClass:"gl-flex gl-items-center gl-text-sm gl-absolute gl-right-3 gl-mt-2",attrs:{"data-testid":"view-all-toggle"},on:{"click":function($event){return _vm.$emit('view-all-clicked')}}},[_c('span',[_vm._v(_vm._s(_vm.viewAllText))])]):_vm._e(),_vm._v(" "),_c('gl-accordion-item',{class:_vm.wrapperClasses,attrs:{"title":_vm.accordionTitle,"header-class":'gl-flex gl-mb-n3'},model:{value:(_vm.expanded),callback:function ($$v) {_vm.expanded=$$v;},expression:"expanded"}},[_vm._t("default")],2)],1)};
85
+ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('gl-accordion',{attrs:{"auto-collapse":false,"header-level":3}},[(_vm.showViewAllButton)?_c('gl-link',{staticClass:"gl-absolute gl-right-3 gl-mt-2 gl-flex gl-items-center gl-text-sm",attrs:{"data-testid":"view-all-toggle"},on:{"click":function($event){return _vm.$emit('view-all-clicked')}}},[_c('span',[_vm._v(_vm._s(_vm.viewAllText))])]):_vm._e(),_vm._v(" "),_c('gl-accordion-item',{class:_vm.wrapperClasses,attrs:{"title":_vm.accordionTitle,"header-class":'gl-flex gl-mb-n3'},model:{value:(_vm.expanded),callback:function ($$v) {_vm.expanded=$$v;},expression:"expanded"}},[_vm._t("default")],2)],1)};
86
86
  var __vue_staticRenderFns__ = [];
87
87
 
88
88
  /* style */
@@ -63,7 +63,7 @@ var script = {
63
63
  const __vue_script__ = script;
64
64
 
65
65
  /* template */
66
- var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"gl-border-solid gl-border-neutral-600"},[_c('div',{staticClass:"gl-w-full gl-flex gl-justify-between gl-items-center gl-px-3 gl-py-2"},[_c('span',{staticClass:"gl-flex gl-items-center",attrs:{"data-testid":"terminal-command-header"}},[_c('gl-icon',{staticClass:"gl-mr-3",attrs:{"name":"terminal"}}),_vm._v("\n "+_vm._s(_vm.commandHeader)+"\n ")],1),_vm._v(" "),(_vm.isCommandOutputAvailable)?_c('gl-button',{attrs:{"text":"Toggle visibility","icon":_vm.toggleIcon,"data-testid":"toggle-visibility-button","category":"tertiary"},on:{"click":_vm.toggleVisibility}}):_vm._e()],1),_vm._v(" "),_c('div',{staticClass:"gl-border-t gl-p-3 gl-flex gl-flex-col gl-leading-22"},[_c('code',{staticClass:"gl-text-subtle",attrs:{"data-testid":"terminal-working-directory"}},[_vm._v(_vm._s(_vm.workingDirectory)+" >")]),_vm._v(" "),_c('code',{staticClass:"gl-text-default",attrs:{"data-testid":"terminal-command-action"}},[_vm._v(_vm._s(_vm.commandAction))])]),_vm._v(" "),(_vm.isCommandOutputAvailable)?_c('gl-collapse',{attrs:{"visible":_vm.isVisible}},[_c('div',{staticClass:"gl-p-3 gl-bg-black"},[_c('code',[_vm._v(_vm._s(_vm.commandOutput))])])]):_vm._e(),_vm._v(" "),(_vm.$scopedSlots.actions)?_c('div',{staticClass:"gl-p-3 gl-border-t"},[_vm._t("actions")],2):_vm._e()],1)};
66
+ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"gl-border-solid gl-border-neutral-600"},[_c('div',{staticClass:"gl-flex gl-w-full gl-items-center gl-justify-between gl-px-3 gl-py-2"},[_c('span',{staticClass:"gl-flex gl-items-center",attrs:{"data-testid":"terminal-command-header"}},[_c('gl-icon',{staticClass:"gl-mr-3",attrs:{"name":"terminal"}}),_vm._v("\n "+_vm._s(_vm.commandHeader)+"\n ")],1),_vm._v(" "),(_vm.isCommandOutputAvailable)?_c('gl-button',{attrs:{"text":"Toggle visibility","icon":_vm.toggleIcon,"data-testid":"toggle-visibility-button","category":"tertiary"},on:{"click":_vm.toggleVisibility}}):_vm._e()],1),_vm._v(" "),_c('div',{staticClass:"gl-leading-22 gl-border-t gl-flex gl-flex-col gl-p-3"},[_c('code',{staticClass:"gl-text-subtle",attrs:{"data-testid":"terminal-working-directory"}},[_vm._v(_vm._s(_vm.workingDirectory)+" >")]),_vm._v(" "),_c('code',{staticClass:"gl-text-default",attrs:{"data-testid":"terminal-command-action"}},[_vm._v(_vm._s(_vm.commandAction))])]),_vm._v(" "),(_vm.isCommandOutputAvailable)?_c('gl-collapse',{attrs:{"visible":_vm.isVisible}},[_c('div',{staticClass:"gl-bg-black gl-p-3"},[_c('code',[_vm._v(_vm._s(_vm.commandOutput))])])]):_vm._e(),_vm._v(" "),(_vm.$scopedSlots.actions)?_c('div',{staticClass:"gl-border-t gl-p-3"},[_vm._t("actions")],2):_vm._e()],1)};
67
67
  var __vue_staticRenderFns__ = [];
68
68
 
69
69
  /* style */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitlab/duo-ui",
3
- "version": "10.11.0",
3
+ "version": "10.12.1",
4
4
  "description": "Duo UI Components",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -86,6 +86,7 @@
86
86
  "vue": "^2.7.16"
87
87
  },
88
88
  "resolutions": {
89
+ "stylus": "npm:@gitlab/noop@1.0.1",
89
90
  "chokidar": "^3.5.2",
90
91
  "sane": "^5.0.1",
91
92
  "jackspeak": "2.1.1"
@@ -78,12 +78,11 @@ const itemsValidator = (items) => items.every(isMessage);
78
78
  const slashCommandsValidator = (commands) => commands.every(isSlashCommand);
79
79
 
80
80
  const isThread = (thread) =>
81
- typeof thread === 'object' &&
82
- typeof thread.id === 'string' &&
83
- typeof thread.lastUpdatedAt === 'string' &&
84
- typeof thread.createdAt === 'string' &&
85
- typeof thread.conversationType === 'string' &&
86
- (thread.title === null || typeof thread.title === 'string');
81
+ (typeof thread === 'object' &&
82
+ typeof thread.id === 'string' &&
83
+ typeof thread.lastUpdatedAt === 'string') ||
84
+ (typeof thread.updatedAt === 'string' &&
85
+ (thread.title === null || typeof thread.title === 'string' || typeof thread.goal === 'string'));
87
86
 
88
87
  // eslint-disable-next-line unicorn/no-array-callback-reference
89
88
  const threadListValidator = (threads) => threads.every(isThread);
@@ -728,7 +727,7 @@ export default {
728
727
  'resizable-content': shouldRenderResizable,
729
728
  'duo-chat-drawer': !shouldRenderResizable,
730
729
  }"
731
- class="markdown-code-block duo-chat gl-bottom-0 gl-max-h-full gl-flex gl-flex-col"
730
+ class="markdown-code-block duo-chat gl-bottom-0 gl-flex gl-max-h-full gl-flex-col"
732
731
  role="complementary"
733
732
  data-testid="chat-component"
734
733
  >
@@ -755,7 +754,7 @@ export default {
755
754
  </duo-chat-header>
756
755
 
757
756
  <div
758
- class="gl-overflow-y-auto gl-flex gl-flex-col gl-flex-1 gl-flex-grow gl-bg-inherit gl-overscroll-contain"
757
+ class="gl-flex gl-flex-1 gl-flex-grow gl-flex-col gl-overflow-y-auto gl-overscroll-contain gl-bg-inherit"
759
758
  data-testid="chat-history"
760
759
  @scroll="handleScrollingThrottled"
761
760
  >
@@ -773,7 +772,7 @@ export default {
773
772
  mode="out-in"
774
773
  tag="section"
775
774
  name="message"
776
- class="duo-chat-history gl-p-5 gl-mt-auto"
775
+ class="duo-chat-history gl-mt-auto gl-p-5"
777
776
  >
778
777
  <duo-chat-conversation
779
778
  v-for="(conversation, index) in conversations"
@@ -815,7 +814,7 @@ export default {
815
814
  <footer
816
815
  v-if="isChatAvailable && !shouldShowThreadList"
817
816
  data-testid="chat-footer"
818
- class="duo-chat-drawer-footer gl-border-0 gl-bg-default gl-pb-3 gl-shrink-0 gl-relative gl-z-2"
817
+ class="duo-chat-drawer-footer gl-relative gl-z-2 gl-shrink-0 gl-border-0 gl-bg-default gl-pb-3"
819
818
  :class="{ 'duo-chat-drawer-body-scrim-on-footer': !scrolledToBottom }"
820
819
  >
821
820
  <gl-form data-testid="chat-prompt-form" @submit.stop.prevent="sendChatPrompt">
@@ -122,13 +122,13 @@ export default {
122
122
 
123
123
  <div
124
124
  v-if="toolDetails"
125
- class="gl-bg-gray-10 gl-p-3 gl-rounded-base gl-mb-3"
125
+ class="gl-mb-3 gl-rounded-base gl-bg-gray-10 gl-p-3"
126
126
  data-testid="tool-details"
127
127
  >
128
128
  <strong>{{ $options.i18n.TOOL_LABEL }} {{ toolName }}</strong>
129
129
  <pre
130
130
  v-if="toolDetails.parameters"
131
- class="gl-mt-2 gl-mb-0 gl-text-inherit"
131
+ class="gl-mb-0 gl-mt-2 gl-text-inherit"
132
132
  data-testid="tool-parameters"
133
133
  >{{ JSON.stringify(toolDetails.parameters, null, 2) }}</pre
134
134
  >
@@ -257,7 +257,7 @@ export default {
257
257
  body-class="!gl-p-2"
258
258
  data-testid="context-item-menu"
259
259
  >
260
- <div class="gl-flex gl-mb-2">
260
+ <div class="gl-mb-2 gl-flex">
261
261
  <gl-button
262
262
  v-if="selectedCategory"
263
263
  size="small"
@@ -302,7 +302,7 @@ export default {
302
302
  :removable="true"
303
303
  :title="$options.i18n.selectedContextItemsTitle"
304
304
  :default-collapsed="false"
305
- class="gl-mt-2 !gl-mb-0 gl-max-h-13 gl-overflow-y-auto"
305
+ class="!gl-mb-0 gl-mt-2 gl-max-h-13 gl-overflow-y-auto"
306
306
  data-testid="in-menu-context-item-selections"
307
307
  @remove="removeItem"
308
308
  @get-content="onGetContextItemContent"
@@ -82,7 +82,7 @@ export default {
82
82
  </script>
83
83
 
84
84
  <template>
85
- <header data-testid="chat-header" class="gl-border-b gl-bg-default gl-p-0 gl-shrink-0">
85
+ <header data-testid="chat-header" class="gl-border-b gl-shrink-0 gl-bg-default gl-p-0">
86
86
  <div class="drawer-title gl-flex gl-items-center gl-justify-start gl-p-5">
87
87
  <div class="gl-flex-1 gl-overflow-hidden">
88
88
  <div class="gl-flex gl-items-center">
@@ -91,7 +91,7 @@ export default {
91
91
  </div>
92
92
  <h4
93
93
  v-if="subtitle"
94
- class="gl-whitespace-nowrap gl-overflow-hidden gl-text-ellipsis gl-font-normal gl-text-subtle gl-mb-0 gl-text-sm gl-pr-3"
94
+ class="gl-mb-0 gl-overflow-hidden gl-text-ellipsis gl-whitespace-nowrap gl-pr-3 gl-text-sm gl-font-normal gl-text-subtle"
95
95
  data-testid="chat-subtitle"
96
96
  >
97
97
  {{ subtitle }}
@@ -319,7 +319,7 @@ export default {
319
319
  </script>
320
320
  <template>
321
321
  <div
322
- class="gl-flex gl-flex-row gl-items-end duo-chat-message-container"
322
+ class="duo-chat-message-container gl-flex gl-flex-row gl-items-end"
323
323
  @mouseenter="hovered = true"
324
324
  @mouseleave="
325
325
  hovered = false;
@@ -328,9 +328,9 @@ export default {
328
328
  >
329
329
  <template v-if="isAssistantMessage || isUserMessage">
330
330
  <div
331
- class="duo-chat-message gl-leading-20 gl-break-anywhere md gl-w-full"
331
+ class="duo-chat-message md gl-w-full gl-leading-20 gl-break-anywhere"
332
332
  :class="{
333
- 'gl-ml-auto gl-p-3 gl-bg-feedback-info gl-text-feedback-info': isUserMessage,
333
+ 'gl-ml-auto gl-bg-feedback-info gl-p-3 gl-text-feedback-info': isUserMessage,
334
334
  'gl-text-default': isAssistantMessage && !error,
335
335
  'duo-chat-message-with-error gl-bg-feedback-danger gl-p-3': error,
336
336
  }"
@@ -404,7 +404,7 @@ export default {
404
404
  <transition name="duo-chat-message-actions">
405
405
  <div
406
406
  v-if="shouldShowCopyAction"
407
- class="gl-bg-subtle duo-chat-message-actions gl-rounded-tr-lg gl-rounded-br-lg"
407
+ class="duo-chat-message-actions gl-rounded-br-lg gl-rounded-tr-lg gl-bg-subtle"
408
408
  >
409
409
  <gl-button
410
410
  v-gl-tooltip.hover
@@ -70,7 +70,7 @@ export default {
70
70
  <div
71
71
  class="duo-chat-message gl-leading-20 gl-break-anywhere"
72
72
  :class="{
73
- 'gl-flex gl-items-top': hasError,
73
+ 'gl-items-top gl-flex': hasError,
74
74
  }"
75
75
  >
76
76
  <gl-icon
@@ -135,7 +135,7 @@ export default {
135
135
  <div
136
136
  v-for="(action, index) in toolArgs.actions"
137
137
  :key="index"
138
- class="gl-ml-4 gl-mb-3 gl-p-3 gl-border gl-border-subtle gl-rounded"
138
+ class="gl-rounded gl-border gl-mb-3 gl-ml-4 gl-border-subtle gl-p-3"
139
139
  data-testid="tool-message-action-item"
140
140
  >
141
141
  <div class="gl-mb-2">
@@ -147,7 +147,7 @@ export default {
147
147
  <div v-if="action.file_path" class="gl-mb-2">
148
148
  <span class="gl-font-weight-bold">{{ $options.i18n.FILE_PATH_LABEL }}:</span>
149
149
  <gl-link
150
- class="gl-ml-2 gl-markdown file-path-link gl-break-all"
150
+ class="gl-markdown file-path-link gl-ml-2 gl-break-all"
151
151
  data-testid="tool-message-action-file-path-link"
152
152
  @click.prevent="onOpenFilePath(action.file_path)"
153
153
  >
@@ -158,7 +158,7 @@ export default {
158
158
  <div v-if="action.content" class="gl-mb-2" data-testid="tool-message-action-content">
159
159
  <span class="gl-font-weight-bold">{{ $options.i18n.CONTENT_LABEL }}:</span>
160
160
  <pre
161
- class="gl-mt-2 gl-p-2 gl-bg-subtle gl-rounded gl-text-sm gl-overflow-auto"
161
+ class="gl-rounded gl-mt-2 gl-overflow-auto gl-bg-subtle gl-p-2 gl-text-sm"
162
162
  data-testid="tool-message-action-content-text"
163
163
  >{{ action.content }}</pre
164
164
  >
@@ -169,7 +169,7 @@ export default {
169
169
  <div v-else-if="messageFilePath" class="gl-mb-2">
170
170
  <span class="gl-font-weight-bold">{{ $options.i18n.FILE_PATH_LABEL }}:</span>
171
171
  <gl-link
172
- class="gl-ml-2 gl-markdown file-path-link gl-break-all"
172
+ class="gl-markdown file-path-link gl-ml-2 gl-break-all"
173
173
  data-testid="tool-message-file-path-link"
174
174
  @click.prevent="onOpenFilePath(messageFilePath)"
175
175
  >
@@ -15,5 +15,5 @@ export default {
15
15
  };
16
16
  </script>
17
17
  <template>
18
- <base-message :message="message" class="gl-ml-auto gl-bg-blue-100 gl-text-blue-900 gl-p-4" />
18
+ <base-message :message="message" class="gl-ml-auto gl-bg-blue-100 gl-p-4 gl-text-blue-900" />
19
19
  </template>
@@ -132,24 +132,24 @@ export default {
132
132
 
133
133
  <template>
134
134
  <div
135
- class="gl-border gl-border-transparent gl-p-4 gl-leading-20 gl-break-anywhere md gl-rounded-bl-none gl-border-1 gl-border-solid gl-text-default gl-bg-subtle"
135
+ class="md gl-border gl-rounded-bl-none gl-border-1 gl-border-solid gl-border-transparent gl-bg-subtle gl-p-4 gl-leading-20 gl-text-default gl-break-anywhere"
136
136
  >
137
- <p class="gl-text-gray-700 gl-mb-3">
137
+ <p class="gl-mb-3 gl-text-gray-700">
138
138
  {{ $options.i18n.TOOL_APPROVAL_TITLE }}
139
139
  </p>
140
140
 
141
- <div class="gl-flex gl-items-center gl-gap-2 gl-mb-3">
141
+ <div class="gl-mb-3 gl-flex gl-items-center gl-gap-2">
142
142
  <gl-icon name="work-item-maintenance" class="gl-text-gray-500" />
143
143
  <strong>{{ toolName }}</strong>
144
144
  </div>
145
145
 
146
- <div class="gl-border gl-border-gray-200 gl-rounded-base gl-bg-gray-50 gl-p-3 gl-mb-4">
147
- <p class="gl-text-sm gl-text-gray-500 gl-mb-1">
146
+ <div class="gl-border gl-mb-4 gl-rounded-base gl-border-gray-200 gl-bg-gray-50 gl-p-3">
147
+ <p class="gl-mb-1 gl-text-sm gl-text-gray-500">
148
148
  {{ $options.i18n.REQUEST_TEXT }}
149
149
  </p>
150
150
  <code
151
151
  v-if="hasToolParameters"
152
- class="gl-text-sm gl-font-monospace gl-whitespace-pre-wrap gl-text-default"
152
+ class="gl-whitespace-pre-wrap gl-text-sm gl-text-default gl-font-monospace"
153
153
  data-testid="tool-parameters"
154
154
  >{{ JSON.stringify(toolParameters, null, 2) }}</code
155
155
  >
@@ -32,7 +32,6 @@ export default {
32
32
  :key="`question-${index}`"
33
33
  category="secondary"
34
34
  variant="default"
35
- icon="question-o"
36
35
  class="duo-chat-suggestion-button gl-text-left"
37
36
  @click="handleClick(prompt)"
38
37
  ><span class="gl-whitespace-normal">{{ prompt }}</span></gl-button
@@ -40,9 +40,11 @@ export default {
40
40
 
41
41
  return this.threads
42
42
  .slice()
43
+ .sort((a, b) => this.compareThreadDates(b.updatedAt, a.updatedAt))
43
44
  .sort((a, b) => this.compareThreadDates(b.lastUpdatedAt, a.lastUpdatedAt))
44
45
  .reduce((grouped, thread) => {
45
- const dateKey = this.getDateKey(thread.lastUpdatedAt);
46
+ const dateField = thread.updatedAt || thread.lastUpdatedAt;
47
+ const dateKey = this.getDateKey(dateField);
46
48
  return {
47
49
  ...grouped,
48
50
  [dateKey]: [...(grouped[dateKey] || []), thread],
@@ -88,7 +90,7 @@ export default {
88
90
  <div class="gl-p-5">
89
91
  <div
90
92
  data-testid="chat-threads-info-banner"
91
- class="gl-bg-gray-50 gl-text-gray-500 gl-p-4 gl-mb-5 gl-rounded-base"
93
+ class="gl-mb-5 gl-rounded-base gl-bg-gray-50 gl-p-4 gl-text-gray-500"
92
94
  >
93
95
  <p class="gl-m-0 gl-flex">
94
96
  {{ $options.i18n.CHAT_HISTORY_INFO }}
@@ -97,22 +99,24 @@ export default {
97
99
 
98
100
  <template v-if="hasThreads">
99
101
  <div v-for="(threadsForDate, date) in groupedThreads" :key="date">
100
- <div data-testid="chat-threads-date-header" class="gl-font-bold gl-neutral-900 gl-my-4">
102
+ <div data-testid="chat-threads-date-header" class="gl-neutral-900 gl-my-4 gl-font-bold">
101
103
  {{ formattedLocalDate(date) }}
102
104
  </div>
103
105
 
104
106
  <div>
105
- <div v-for="thread in threadsForDate" :key="thread.id" class="gl-flex gl-align-center">
107
+ <div v-for="thread in threadsForDate" :key="thread.id" class="gl-align-center gl-flex">
106
108
  <gl-button
107
109
  data-testid="chat-threads-thread-box"
108
110
  category="tertiary"
109
- class="hover:gl-bg-gray-50 gl-text-ellipsis !gl-text-default justify-content-start gl-overflow-hidden gl-rounded-base gl-p-4 gl-w-full gl-whitespace-nowrap"
111
+ class="justify-content-start gl-w-full gl-overflow-hidden gl-text-ellipsis gl-whitespace-nowrap gl-rounded-base gl-p-4 !gl-text-default hover:gl-bg-gray-50"
110
112
  :aria-label="
111
- sprintf($options.i18n.OPEN_CHAT_LABEL, { title: thread.title || 'Untitled Chat' })
113
+ sprintf($options.i18n.OPEN_CHAT_LABEL, {
114
+ title: thread.title || thread.goal || 'Untitled Chat',
115
+ })
112
116
  "
113
117
  @click="onSelectThread(thread)"
114
118
  >
115
- {{ thread.title || 'Untitled Chat' }}
119
+ {{ thread.title || thread.goal || 'Untitled Chat' }}
116
120
  </gl-button>
117
121
 
118
122
  <gl-button
@@ -23,14 +23,14 @@ export default {
23
23
  </script>
24
24
 
25
25
  <template>
26
- <div class="gl-h-full gl-flex gl-flex-col gl-align-center gl-items-center gl-justify-center">
26
+ <div class="gl-align-center gl-flex gl-h-full gl-flex-col gl-items-center gl-justify-center">
27
27
  <img
28
28
  :src="$options.ScheduleIllustration"
29
29
  :alt="$options.i18n.EMPTY_HISTORY_ALT"
30
30
  class="gl-mb-5"
31
31
  data-testid="empty-state-illustration"
32
32
  />
33
- <h3 class="gl-font-bold gl-neutral-900 gl-mb-4" data-testid="empty-state-title">
33
+ <h3 class="gl-neutral-900 gl-mb-4 gl-font-bold" data-testid="empty-state-title">
34
34
  {{ $options.i18n.EMPTY_HISTORY_TITLE }}
35
35
  </h3>
36
36
  <p class="gl-align-center" data-testid="empty-state-description">
@@ -718,7 +718,7 @@ export default {
718
718
  'resizable-content': shouldRenderResizable,
719
719
  'duo-chat-drawer': !shouldRenderResizable,
720
720
  }"
721
- class="markdown-code-block duo-chat gl-bottom-0 gl-max-h-full gl-flex gl-flex-col"
721
+ class="markdown-code-block duo-chat gl-bottom-0 gl-flex gl-max-h-full gl-flex-col"
722
722
  role="complementary"
723
723
  data-testid="chat-component"
724
724
  >
@@ -745,7 +745,7 @@ export default {
745
745
  </duo-chat-header>
746
746
 
747
747
  <div
748
- class="gl-overflow-y-auto gl-flex gl-flex-col gl-flex-1 gl-flex-grow gl-bg-inherit gl-overscroll-contain"
748
+ class="gl-flex gl-flex-1 gl-flex-grow gl-flex-col gl-overflow-y-auto gl-overscroll-contain gl-bg-inherit"
749
749
  data-testid="chat-history"
750
750
  @scroll="handleScrollingThrottled"
751
751
  >
@@ -763,7 +763,7 @@ export default {
763
763
  mode="out-in"
764
764
  tag="section"
765
765
  name="message"
766
- class="duo-chat-history gl-p-5 gl-mt-auto"
766
+ class="duo-chat-history gl-mt-auto gl-p-5"
767
767
  >
768
768
  <duo-chat-conversation
769
769
  v-for="(conversation, index) in conversations"
@@ -803,7 +803,7 @@ export default {
803
803
  <footer
804
804
  v-if="isChatAvailable && !shouldShowThreadList"
805
805
  data-testid="chat-footer"
806
- class="duo-chat-drawer-footer gl-border-0 gl-bg-default gl-pb-3 gl-shrink-0 gl-relative gl-z-2"
806
+ class="duo-chat-drawer-footer gl-relative gl-z-2 gl-shrink-0 gl-border-0 gl-bg-default gl-pb-3"
807
807
  :class="{ 'duo-chat-drawer-body-scrim-on-footer': !scrolledToBottom }"
808
808
  >
809
809
  <gl-form data-testid="chat-prompt-form" @submit.stop.prevent="sendChatPrompt">