@gitlab/duo-ui 0.4.0 → 1.0.0

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 (39) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/components/chat/components/duo_chat_context/constants.js +2 -1
  3. package/dist/components/chat/components/duo_chat_context/duo_chat_context_item_details_modal/duo_chat_context_item_details_modal.js +36 -9
  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_context/duo_chat_context_item_menu/duo_chat_context_item_menu_search_item.js +8 -16
  6. package/dist/components/chat/components/duo_chat_context/duo_chat_context_item_menu/duo_chat_context_item_menu_search_items_loading.js +1 -1
  7. package/dist/components/chat/components/duo_chat_context/duo_chat_context_item_popover/duo_chat_context_item_popover.js +12 -8
  8. package/dist/components/chat/components/duo_chat_context/duo_chat_context_item_selections/duo_chat_context_item_selections.js +2 -2
  9. package/dist/components/chat/components/duo_chat_context/mock_context_data.js +118 -9
  10. package/dist/components/chat/components/duo_chat_context/utils.js +28 -2
  11. package/dist/components/chat/components/duo_chat_conversation/duo_chat_conversation.js +1 -1
  12. package/dist/components/chat/components/duo_chat_loader/duo_chat_loader.js +1 -1
  13. package/dist/components/chat/duo_chat.js +4 -4
  14. package/dist/components/workflow/components/duo_workflow_panel/duo_workflow_panel.js +1 -1
  15. package/dist/components/workflow/components/duo_workflow_prompt/duo_workflow_prompt.js +1 -1
  16. package/dist/components.css +1 -1
  17. package/dist/components.css.map +1 -1
  18. package/dist/tailwind.css +1 -1
  19. package/dist/tailwind.css.map +1 -1
  20. package/dist/utils/i18n.js +63 -0
  21. package/package.json +2 -2
  22. package/src/components/chat/components/duo_chat_context/constants.js +1 -0
  23. package/src/components/chat/components/duo_chat_context/duo_chat_context_item_details_modal/duo_chat_context_item_details_modal.vue +61 -6
  24. package/src/components/chat/components/duo_chat_context/duo_chat_context_item_menu/duo_chat_context_item_menu.md +35 -0
  25. package/src/components/chat/components/duo_chat_context/duo_chat_context_item_menu/duo_chat_context_item_menu.vue +1 -1
  26. package/src/components/chat/components/duo_chat_context/duo_chat_context_item_menu/duo_chat_context_item_menu_search_item.vue +17 -25
  27. package/src/components/chat/components/duo_chat_context/duo_chat_context_item_menu/duo_chat_context_item_menu_search_items_loading.vue +1 -1
  28. package/src/components/chat/components/duo_chat_context/duo_chat_context_item_popover/duo_chat_context_item_popover.vue +20 -15
  29. package/src/components/chat/components/duo_chat_context/duo_chat_context_item_selections/duo_chat_context_item_selections.vue +10 -4
  30. package/src/components/chat/components/duo_chat_context/mock_context_data.js +148 -9
  31. package/src/components/chat/components/duo_chat_context/utils.js +32 -1
  32. package/src/components/chat/components/duo_chat_conversation/duo_chat_conversation.vue +1 -1
  33. package/src/components/chat/components/duo_chat_loader/duo_chat_loader.vue +1 -1
  34. package/src/components/chat/duo_chat.scss +19 -8
  35. package/src/components/chat/duo_chat.vue +15 -11
  36. package/src/components/workflow/components/duo_workflow_panel/duo_workflow_panel.vue +1 -1
  37. package/src/components/workflow/components/duo_workflow_prompt/duo_workflow_prompt.vue +1 -1
  38. package/src/utils/i18n.js +62 -0
  39. package/translations.js +2 -1
@@ -1,25 +1,18 @@
1
1
  <script>
2
- import { GlIcon, GlTruncate } from '@gitlab/ui';
2
+ import { GlIcon, GlTruncate, GlBadge } from '@gitlab/ui';
3
3
  import GlDuoChatContextItemPopover from '../duo_chat_context_item_popover/duo_chat_context_item_popover.vue';
4
4
 
5
5
  import {
6
6
  categoryValidator,
7
7
  contextItemValidator,
8
- formatGitItemSecondaryText,
9
- formatIssueId,
10
- formatMergeRequestId,
11
8
  getContextItemIcon,
9
+ getContextItemSecondaryText,
10
+ getContextItemSource,
12
11
  } from '../utils';
13
- import {
14
- CONTEXT_ITEM_CATEGORY_FILE,
15
- CONTEXT_ITEM_CATEGORY_ISSUE,
16
- CONTEXT_ITEM_CATEGORY_LOCAL_GIT,
17
- CONTEXT_ITEM_CATEGORY_MERGE_REQUEST,
18
- } from '../constants';
19
12
 
20
13
  export default {
21
14
  name: 'GlDuoChatContextItemMenuSearchItem',
22
- components: { GlTruncate, GlIcon, GlDuoChatContextItemPopover },
15
+ components: { GlBadge, GlTruncate, GlIcon, GlDuoChatContextItemPopover },
23
16
  props: {
24
17
  category: {
25
18
  type: Object,
@@ -37,22 +30,14 @@ export default {
37
30
  return this.contextItem.metadata?.title || '';
38
31
  },
39
32
  secondaryText() {
40
- switch (this.category.value) {
41
- case CONTEXT_ITEM_CATEGORY_FILE:
42
- return this.contextItem.metadata.relativePath;
43
- case CONTEXT_ITEM_CATEGORY_ISSUE:
44
- return formatIssueId(this.contextItem.metadata.iid);
45
- case CONTEXT_ITEM_CATEGORY_MERGE_REQUEST:
46
- return formatMergeRequestId(this.contextItem.metadata.iid);
47
- case CONTEXT_ITEM_CATEGORY_LOCAL_GIT:
48
- return formatGitItemSecondaryText(this.contextItem);
49
- default:
50
- return '';
51
- }
33
+ return getContextItemSecondaryText(this.contextItem);
52
34
  },
53
35
  icon() {
54
36
  return getContextItemIcon(this.contextItem, this.category);
55
37
  },
38
+ itemSource() {
39
+ return getContextItemSource(this.contextItem);
40
+ },
56
41
  },
57
42
  };
58
43
  </script>
@@ -75,10 +60,17 @@ export default {
75
60
  </div>
76
61
  <div
77
62
  v-if="secondaryText"
78
- class="gl-mt-1 gl-shrink-0 gl-whitespace-nowrap gl-text-secondary"
63
+ class="gl-align-items-center gl-mt-1 gl-flex gl-shrink-0 gl-whitespace-nowrap gl-text-secondary"
79
64
  data-testid="item-secondary-text"
80
65
  >
81
- <gl-truncate :text="secondaryText" />
66
+ <gl-badge
67
+ v-if="itemSource"
68
+ variant="neutral"
69
+ class="gl-mr-1"
70
+ data-testid="context-item-source"
71
+ >{{ itemSource }}</gl-badge
72
+ >
73
+ <gl-truncate class="gl-min-w-0" position="middle" :text="secondaryText" />
82
74
  </div>
83
75
  </div>
84
76
  </template>
@@ -1,5 +1,5 @@
1
1
  <script>
2
- import { translate } from '@gitlab/ui/dist/utils/i18n';
2
+ import { translate } from '../../../../../utils/i18n';
3
3
 
4
4
  export default {
5
5
  name: 'GlDuoChatContextItemMenuSearchItemsLoading',
@@ -1,24 +1,25 @@
1
1
  <script>
2
- import { GlAlert, GlIcon, GlPopover, GlTruncate } from '@gitlab/ui';
3
- import { translate } from '@gitlab/ui/dist/utils/i18n';
2
+ import { GlAlert, GlIcon, GlPopover, GlTruncate, GlBadge } from '@gitlab/ui';
3
+ import { translate } from '../../../../../utils/i18n';
4
4
 
5
5
  import {
6
6
  CONTEXT_ITEM_CATEGORY_FILE,
7
7
  CONTEXT_ITEM_CATEGORY_ISSUE,
8
- CONTEXT_ITEM_CATEGORY_LOCAL_GIT,
9
8
  CONTEXT_ITEM_CATEGORY_MERGE_REQUEST,
10
9
  } from '../constants';
11
10
  import {
12
- formatGitItemSecondaryText,
13
11
  formatIssueId,
14
12
  formatMergeRequestId,
15
13
  getContextItemIcon,
14
+ getContextItemSecondaryText,
15
+ getContextItemSource,
16
16
  getContextItemTypeLabel,
17
17
  } from '../utils';
18
18
 
19
19
  export default {
20
20
  name: 'DuoChatContextItemPopover',
21
21
  components: {
22
+ GlBadge,
22
23
  GlTruncate,
23
24
  GlAlert,
24
25
  GlIcon,
@@ -76,11 +77,6 @@ export default {
76
77
  filePathArray() {
77
78
  return this.filePath?.split('/');
78
79
  },
79
- gitDetails() {
80
- return this.contextItem.category === CONTEXT_ITEM_CATEGORY_LOCAL_GIT
81
- ? formatGitItemSecondaryText(this.contextItem)
82
- : null;
83
- },
84
80
  isEnabled() {
85
81
  return this.contextItem.metadata.enabled !== false;
86
82
  },
@@ -96,6 +92,12 @@ export default {
96
92
  itemTypeLabel() {
97
93
  return getContextItemTypeLabel(this.contextItem);
98
94
  },
95
+ secondaryText() {
96
+ return getContextItemSecondaryText(this.contextItem);
97
+ },
98
+ itemSource() {
99
+ return getContextItemSource(this.contextItem);
100
+ },
99
101
  },
100
102
  methods: {
101
103
  translate,
@@ -118,21 +120,24 @@ export default {
118
120
  >
119
121
  {{ title }}
120
122
  </div>
121
- <div v-if="itemTypeLabel" class="gl-font-normal gl-text-subtle">{{ itemTypeLabel }}</div>
123
+ <div v-if="itemTypeLabel" class="gl-flex gl-items-center gl-font-normal gl-text-subtle">
124
+ <gl-truncate :text="itemTypeLabel" class="gl-min-w-0" />
125
+ </div>
122
126
  </div>
123
127
  </template>
124
128
  <div>
125
- <div v-if="filePath">
129
+ <div v-if="secondaryText" class="gl-flex gl-items-center">
130
+ <gl-icon :name="iconName" :size="12" variant="subtle" class="gl-mr-1 gl-shrink-0" />
131
+ <gl-badge v-if="itemSource" class="gl-mr-1">{{ itemSource }}</gl-badge>
132
+ <gl-truncate :text="secondaryText" class="gl-min-w-0" />
133
+ </div>
134
+ <div v-else-if="filePath">
126
135
  <gl-icon name="document" :size="12" variant="subtle" />
127
136
  <span class="gl-break-all">{{ contextItem.metadata.project }}</span>
128
137
  <span v-for="(pathPart, index) in filePathArray" :key="pathPart" class="gl-break-all"
129
138
  >{{ pathPart }}{{ index + 1 < filePathArray.length ? '/' : '' }}</span
130
139
  >
131
140
  </div>
132
- <div v-else-if="gitDetails" class="gl-flex gl-items-center" data-testid="git-details">
133
- <gl-icon :name="iconName" :size="12" variant="subtle" class="gl-mr-1 gl-shrink-0" />
134
- <gl-truncate :text="gitDetails" class="gl-min-w-0" />
135
- </div>
136
141
  <div v-else>
137
142
  <gl-icon v-if="iconName" :name="iconName" :size="12" variant="subtle" />
138
143
  <span class="gl-break-all">{{ contextItem.metadata.project }}</span>
@@ -3,7 +3,11 @@ import uniqueId from 'lodash/uniqueId';
3
3
  import { GlIcon, GlToken, GlTruncate } from '@gitlab/ui';
4
4
 
5
5
  import GlDuoChatContextItemPopover from '../duo_chat_context_item_popover/duo_chat_context_item_popover.vue';
6
- import { CONTEXT_ITEM_CATEGORY_FILE, CONTEXT_ITEM_CATEGORY_LOCAL_GIT } from '../constants';
6
+ import {
7
+ CONTEXT_ITEM_CATEGORY_DEPENDENCY,
8
+ CONTEXT_ITEM_CATEGORY_FILE,
9
+ CONTEXT_ITEM_CATEGORY_LOCAL_GIT,
10
+ } from '../constants';
7
11
  import GlDuoChatContextItemDetailsModal from '../duo_chat_context_item_details_modal/duo_chat_context_item_details_modal.vue';
8
12
  import { contextItemsValidator, getContextItemIcon } from '../utils';
9
13
 
@@ -109,9 +113,11 @@ export default {
109
113
  this.previewContextItemId = contextItem.id;
110
114
  },
111
115
  canOpen(contextItem) {
112
- return [CONTEXT_ITEM_CATEGORY_LOCAL_GIT, CONTEXT_ITEM_CATEGORY_FILE].includes(
113
- contextItem.category
114
- );
116
+ return [
117
+ CONTEXT_ITEM_CATEGORY_LOCAL_GIT,
118
+ CONTEXT_ITEM_CATEGORY_FILE,
119
+ CONTEXT_ITEM_CATEGORY_DEPENDENCY,
120
+ ].includes(contextItem.category);
115
121
  },
116
122
  onClosePreview() {
117
123
  this.previewContextItemId = null;
@@ -1,8 +1,9 @@
1
1
  import {
2
- CONTEXT_ITEM_CATEGORY_ISSUE,
3
- CONTEXT_ITEM_CATEGORY_MERGE_REQUEST,
2
+ CONTEXT_ITEM_CATEGORY_DEPENDENCY,
4
3
  CONTEXT_ITEM_CATEGORY_FILE,
4
+ CONTEXT_ITEM_CATEGORY_ISSUE,
5
5
  CONTEXT_ITEM_CATEGORY_LOCAL_GIT,
6
+ CONTEXT_ITEM_CATEGORY_MERGE_REQUEST,
6
7
  } from './constants';
7
8
 
8
9
  export const MOCK_CATEGORIES = [
@@ -10,6 +11,7 @@ export const MOCK_CATEGORIES = [
10
11
  { label: 'Local Git', value: CONTEXT_ITEM_CATEGORY_LOCAL_GIT, icon: 'git' },
11
12
  { label: 'Issues', value: CONTEXT_ITEM_CATEGORY_ISSUE, icon: 'issues' },
12
13
  { label: 'Merge Requests', value: CONTEXT_ITEM_CATEGORY_MERGE_REQUEST, icon: 'merge-request' },
14
+ { label: 'Dependencies', value: CONTEXT_ITEM_CATEGORY_DEPENDENCY, icon: 'package' },
13
15
  ];
14
16
 
15
17
  export function getMockCategory(categoryValue) {
@@ -37,6 +39,9 @@ export const MOCK_CONTEXT_ITEM_FILE = {
37
39
  metadata: {
38
40
  enabled: true,
39
41
  title: 'strawberry.ts',
42
+ secondaryText: 'src/plants/strawberry.ts',
43
+ subTypeLabel: 'Project file',
44
+ icon: 'document',
40
45
  project: 'example/garden',
41
46
  relativePath: 'src/plants/strawberry.ts',
42
47
  },
@@ -48,6 +53,9 @@ export const MOCK_CONTEXT_ITEM_FILE_DISABLED = {
48
53
  metadata: {
49
54
  enabled: false,
50
55
  title: 'motorbike.cs',
56
+ secondaryText: '/src/VehicleFoo/motorbike.cs',
57
+ subTypeLabel: 'Project file',
58
+ icon: 'document',
51
59
  project: 'example/vehicles',
52
60
  relativePath: '/src/VehicleFoo/motorbike.cs',
53
61
  },
@@ -60,6 +68,9 @@ const mockFiles = [
60
68
  metadata: {
61
69
  enabled: true,
62
70
  title: 'potato.ts',
71
+ secondaryText: '/src/plants/potato.ts',
72
+ subTypeLabel: 'Project file',
73
+ icon: 'document',
63
74
  project: 'example/garden',
64
75
  relativePath: '/src/plants/potato.ts',
65
76
  },
@@ -73,7 +84,9 @@ export const MOCK_CONTEXT_ITEM_ISSUE = {
73
84
  metadata: {
74
85
  enabled: true,
75
86
  title: 'Implement watering schedule',
76
- project: 'example/garden',
87
+ secondaryText: 'example/garden#1234',
88
+ subTypeLabel: 'Issue',
89
+ icon: 'issues',
77
90
  iid: 1234,
78
91
  },
79
92
  };
@@ -85,7 +98,9 @@ export const MOCK_CONTEXT_ITEM_ISSUE_DISABLED = {
85
98
  enabled: false,
86
99
  disabledReasons: ['This foo is not available to bar', 'Lorem something something wow?'],
87
100
  title: `Fix vehicle colours and make them look real nice and colourful won't that be wonderful wow this issue title is really long I sure hope it's gonna wrap OK`,
88
- project: 'example/vehicle',
101
+ secondaryText: 'example/vehicle#91011',
102
+ subTypeLabel: 'Issue',
103
+ icon: 'issues',
89
104
  iid: 91011,
90
105
  },
91
106
  };
@@ -98,7 +113,9 @@ const mockIssues = [
98
113
  metadata: {
99
114
  enabled: true,
100
115
  title: 'Refactor plant growth rates',
101
- project: 'example/garden',
116
+ secondaryText: 'example/garden#5678',
117
+ subTypeLabel: 'Issue',
118
+ icon: 'issues',
102
119
  iid: 5678,
103
120
  },
104
121
  },
@@ -111,7 +128,9 @@ export const MOCK_CONTEXT_ITEM_MERGE_REQUEST = {
111
128
  metadata: {
112
129
  enabled: true,
113
130
  title: 'Improve database performance',
114
- project: 'example/garden',
131
+ secondaryText: 'example/garden!1122',
132
+ subTypeLabel: 'Merge request',
133
+ icon: 'merge-request',
115
134
  iid: 1122,
116
135
  },
117
136
  };
@@ -122,7 +141,9 @@ export const MOCK_CONTEXT_ITEM_MERGE_REQUEST_DISABLED = {
122
141
  enabled: false,
123
142
  disabledReasons: ['This foo is not available to bar', 'Lorem something something wow?'],
124
143
  title: 'Fix broken layout at small viewports',
125
- project: 'example/vehicle',
144
+ secondaryText: 'example/vehicle!5566',
145
+ subTypeLabel: 'Merge request',
146
+ icon: 'merge-request',
126
147
  iid: 5566,
127
148
  },
128
149
  };
@@ -136,7 +157,9 @@ const mockMergeRequests = [
136
157
  enabled: false,
137
158
  disabledReasons: ['This foo is not available to bar', 'Lorem something something wow?'],
138
159
  title: 'Add vehicle registration details',
139
- project: 'example/vehicle',
160
+ secondaryText: 'example/vehicle!3344',
161
+ subTypeLabel: 'Merge request',
162
+ icon: 'merge-request',
140
163
  iid: 3344,
141
164
  },
142
165
  },
@@ -149,6 +172,10 @@ export const MOCK_CONTEXT_ITEM_GIT_DIFF = {
149
172
  metadata: {
150
173
  enabled: true,
151
174
  title: 'Current working changes',
175
+ secondaryText: 'main',
176
+ subType: 'local_git',
177
+ subTypeLabel: 'Local Git repository diff',
178
+ icon: 'comparison',
152
179
  commitId: 'main',
153
180
  repositoryName: 'example/garden',
154
181
  gitType: 'diff',
@@ -160,6 +187,10 @@ export const MOCK_CONTEXT_ITEM_GIT_COMMIT = {
160
187
  metadata: {
161
188
  enabled: true,
162
189
  title: 'fix: some bug fix commit',
190
+ secondaryText: '20f8caf94cb8f5e5f9dbd1a9ac32702321de201b',
191
+ subType: 'local_git',
192
+ subTypeLabel: 'Local Git repository commit',
193
+ icon: 'commit',
163
194
  commitId: '20f8caf94cb8f5e5f9dbd1a9ac32702321de201b',
164
195
  repositoryName: 'example/garden',
165
196
  gitType: 'commit',
@@ -174,6 +205,9 @@ const mockGitItems = [
174
205
  metadata: {
175
206
  enabled: true,
176
207
  title: 'Diff from default branch',
208
+ secondaryText: 'main',
209
+ subTypeLabel: 'Local Git repository diff',
210
+ icon: 'comparison',
177
211
  commitId: 'main',
178
212
  repositoryName: 'example/garden',
179
213
  gitType: 'diff',
@@ -186,6 +220,9 @@ const mockGitItems = [
186
220
  metadata: {
187
221
  enabled: true,
188
222
  title: 'feat: add cool new feature',
223
+ secondaryText: '32b9b56b6de75b32909986755fbc470f20fb6fc0',
224
+ subTypeLabel: 'Local Git repository commit',
225
+ icon: 'commit',
189
226
  commitId: '32b9b56b6de75b32909986755fbc470f20fb6fc0',
190
227
  repositoryName: 'example/garden',
191
228
  gitType: 'commit',
@@ -197,6 +234,9 @@ const mockGitItems = [
197
234
  metadata: {
198
235
  enabled: true,
199
236
  title: 'fix: stop foo from bar when baz because customers ding',
237
+ secondaryText: '775d7efdce25c1af48c55abcadbefd1f181b92ce',
238
+ subTypeLabel: 'Local Git repository commit',
239
+ icon: 'commit',
200
240
  commitId: '775d7efdce25c1af48c55abcadbefd1f181b92ce',
201
241
  repositoryName: 'example/garden',
202
242
  gitType: 'commit',
@@ -204,8 +244,107 @@ const mockGitItems = [
204
244
  },
205
245
  ];
206
246
 
247
+ export const MOCK_CONTEXT_ITEM_DEPENDENCY = {
248
+ id: '823e4567-e89b-12d3-a456-426614174007',
249
+ category: CONTEXT_ITEM_CATEGORY_DEPENDENCY,
250
+ content: JSON.stringify([
251
+ {
252
+ javascript: [
253
+ '@types/node@16.11.7',
254
+ '@vue/compiler-sfc@3.2.37',
255
+ 'typescript@4.5.5',
256
+ 'vue@3.2.37',
257
+ ],
258
+ },
259
+ ]),
260
+ metadata: {
261
+ enabled: true,
262
+ title: 'example/garden',
263
+ secondaryText: 'package.json',
264
+ icon: 'package',
265
+ subType: 'dependency',
266
+ subTypeLabel: 'Project dependencies',
267
+ project: 'example/garden',
268
+ },
269
+ };
270
+
271
+ export const MOCK_CONTEXT_ITEM_DEPENDENCY_DISABLED = {
272
+ id: '923e4567-e89b-12d3-a456-426614174008',
273
+ category: CONTEXT_ITEM_CATEGORY_DEPENDENCY,
274
+ content: JSON.stringify([
275
+ {
276
+ javascript: [
277
+ '@types/node@16.11.7',
278
+ '@vue/compiler-sfc@3.2.37',
279
+ 'typescript@4.5.5',
280
+ 'vue@3.2.37',
281
+ ],
282
+ csharp: ['newtonsoft.json@13.0.1', 'microsoft.net.test.sdk@16.11.0'],
283
+ },
284
+ ]),
285
+ metadata: {
286
+ enabled: false,
287
+ disabledReasons: ['Dependencies are not available for this project', 'Access restricted'],
288
+ title: 'example/vehicle',
289
+ secondaryText: 'package.json, vehicle.csproj',
290
+ icon: 'package',
291
+ subType: 'dependency',
292
+ subTypeLabel: 'Project dependencies',
293
+ project: 'example/vehicle',
294
+ },
295
+ };
296
+
297
+ const mockDependencies = [
298
+ MOCK_CONTEXT_ITEM_DEPENDENCY,
299
+ MOCK_CONTEXT_ITEM_DEPENDENCY_DISABLED,
300
+ {
301
+ id: 'b23e4567-e89b-12d3-a456-426614174010',
302
+ category: CONTEXT_ITEM_CATEGORY_DEPENDENCY,
303
+ content: JSON.stringify([
304
+ {
305
+ python: ['django@3.2.9', 'djangorestframework@3.12.4', 'psycopg2@2.9.2', 'celery@5.2.1'],
306
+ csharp: ['newtonsoft.json@13.0.1', 'microsoft.net.test.sdk@16.11.0'],
307
+ },
308
+ ]),
309
+ metadata: {
310
+ enabled: true,
311
+ title: 'example/backend',
312
+ secondaryText: 'requirements.txt, some.backend.csproj',
313
+ icon: 'package',
314
+ subType: 'dependency',
315
+ subTypeLabel: 'Project dependencies',
316
+ project: 'example/backend',
317
+ },
318
+ },
319
+ {
320
+ id: 'c23e4567-e89b-12d3-a456-426614174011',
321
+ category: CONTEXT_ITEM_CATEGORY_DEPENDENCY,
322
+ content: JSON.stringify([
323
+ {
324
+ javascript: ['jquery@3.5.1', 'backbone@1.4.0', 'underscore@1.13.1', 'moment@2.29.1'],
325
+ },
326
+ ]),
327
+ metadata: {
328
+ enabled: false,
329
+ disabledReasons: ['Project is archived'],
330
+ title: 'example/legacy',
331
+ secondaryText: 'bower.json',
332
+ icon: 'package',
333
+ subType: 'dependency',
334
+ subTypeLabel: 'Project dependencies',
335
+ project: 'example/legacy',
336
+ },
337
+ },
338
+ ];
339
+
207
340
  export const getMockContextItems = () => {
208
- const allItems = [...mockFiles, ...mockGitItems, ...mockIssues, ...mockMergeRequests];
341
+ const allItems = [
342
+ ...mockFiles,
343
+ ...mockGitItems,
344
+ ...mockIssues,
345
+ ...mockMergeRequests,
346
+ ...mockDependencies,
347
+ ];
209
348
 
210
349
  // put disabled items in the back
211
350
  const disabledItems = allItems.filter((item) => !item.metadata.enabled);
@@ -1,4 +1,4 @@
1
- import { translate } from '@gitlab/ui/dist/utils/i18n';
1
+ import { translate } from '../../../../utils/i18n';
2
2
  import {
3
3
  CONTEXT_ITEM_CATEGORY_FILE,
4
4
  CONTEXT_ITEM_CATEGORY_ISSUE,
@@ -52,6 +52,10 @@ export function formatMergeRequestId(iid) {
52
52
  return `!${iid}`;
53
53
  }
54
54
 
55
+ export function getContextItemSource(contextItem) {
56
+ return contextItem.metadata.repositoryName || contextItem.metadata.project || null;
57
+ }
58
+
55
59
  function getGitItemIcon(contextItem) {
56
60
  const iconMap = {
57
61
  [CONTEXT_ITEM_LOCAL_GIT_COMMIT]: 'commit',
@@ -65,6 +69,10 @@ function getGitItemIcon(contextItem) {
65
69
  * Gets the icon name for a given contextItem.
66
70
  */
67
71
  export function getContextItemIcon(contextItem, category = { icon: null }) {
72
+ if (contextItem.metadata.icon) {
73
+ return contextItem.metadata.icon;
74
+ }
75
+
68
76
  if (contextItem.category === CONTEXT_ITEM_CATEGORY_LOCAL_GIT) {
69
77
  const gitIcon = getGitItemIcon(contextItem);
70
78
  if (gitIcon) return gitIcon;
@@ -85,6 +93,10 @@ export function getContextItemIcon(contextItem, category = { icon: null }) {
85
93
  }
86
94
 
87
95
  export function getContextItemTypeLabel(contextItem) {
96
+ if (contextItem.metadata.subTypeLabel) {
97
+ return contextItem.metadata.subTypeLabel;
98
+ }
99
+
88
100
  if (contextItem.category === CONTEXT_ITEM_CATEGORY_LOCAL_GIT) {
89
101
  switch (contextItem.metadata.gitType) {
90
102
  case CONTEXT_ITEM_LOCAL_GIT_DIFF:
@@ -117,6 +129,25 @@ export function formatGitItemSecondaryText(contextItem) {
117
129
  return `${repositoryName}${separator}${commitId || ''}`;
118
130
  }
119
131
 
132
+ export function getContextItemSecondaryText(contextItem) {
133
+ if (contextItem.metadata.secondaryText) {
134
+ return contextItem.metadata.secondaryText;
135
+ }
136
+
137
+ switch (contextItem.category) {
138
+ case CONTEXT_ITEM_CATEGORY_FILE:
139
+ return contextItem.metadata.relativePath;
140
+ case CONTEXT_ITEM_CATEGORY_ISSUE:
141
+ return formatIssueId(contextItem.metadata.iid);
142
+ case CONTEXT_ITEM_CATEGORY_MERGE_REQUEST:
143
+ return formatMergeRequestId(contextItem.metadata.iid);
144
+ case CONTEXT_ITEM_CATEGORY_LOCAL_GIT:
145
+ return formatGitItemSecondaryText(contextItem);
146
+ default:
147
+ return '';
148
+ }
149
+ }
150
+
120
151
  /**
121
152
  * Calculates a new index within a range. If the new index would fall out of bounds, wraps to the start/end of the range.
122
153
  * @param {number} currentIndex - The starting index.
@@ -1,5 +1,5 @@
1
1
  <script>
2
- import { translate } from '@gitlab/ui/dist/utils/i18n';
2
+ import { translate } from '../../../../utils/i18n';
3
3
  import GlDuoChatMessage from '../duo_chat_message/duo_chat_message.vue';
4
4
 
5
5
  const i18n = {
@@ -1,6 +1,6 @@
1
1
  <script>
2
- import { translate } from '@gitlab/ui/dist/utils/i18n';
3
2
  import { GlSprintf } from '@gitlab/ui';
3
+ import { translate } from '../../../../utils/i18n';
4
4
  import { LOADING_TRANSITION_DURATION } from '../../constants';
5
5
 
6
6
  export const i18n = {
@@ -40,7 +40,9 @@ $duo-chat-scrim-gradient: linear-gradient(to bottom, rgba($gray-10, 0), $gray-10
40
40
  @apply gl-transition-all;
41
41
  position: fixed;
42
42
  @apply gl-h-full;
43
+ @apply gl-w-full;
43
44
  @apply gl-overflow-y-auto;
45
+ @apply gl-shadow-lg;
44
46
  @apply gl-text-base;
45
47
  @apply gl-leading-normal;
46
48
  @apply gl-flex;
@@ -48,13 +50,13 @@ $duo-chat-scrim-gradient: linear-gradient(to bottom, rgba($gray-10, 0), $gray-10
48
50
  }
49
51
 
50
52
  .duo-chat-drawer-header {
51
- @apply gl-border-b-solid gl-border-b-gray-100 gl-border-b-1;
53
+ @apply gl-border-b;
52
54
  }
53
55
 
54
56
  .duo-chat-drawer-header-sticky {
55
57
  top: 0;
56
58
  position: sticky;
57
- @apply gl-border-b-solid gl-border-b-gray-100 gl-border-b-1;
59
+ @apply gl-border-b;
58
60
  }
59
61
 
60
62
  .duo-chat-drawer-body {
@@ -63,14 +65,17 @@ $duo-chat-scrim-gradient: linear-gradient(to bottom, rgba($gray-10, 0), $gray-10
63
65
  // above the drawer when hovering interactive elements
64
66
  // see https://gitlab.com/gitlab-org/gitlab/-/issues/366558
65
67
  background-color: inherit;
68
+ // prevent scroll behind the chat
69
+ overscroll-behavior: contain;
66
70
  }
67
71
 
68
72
  .duo-chat-drawer-footer {
69
- @apply gl-border-t-solid gl-border-t-gray-100 gl-border-t-1;
73
+ @apply gl-border-t;
70
74
  @apply gl-p-5;
71
75
  }
72
76
 
73
77
  .duo-chat-drawer-footer-sticky {
78
+ @apply gl-bg-white;
74
79
  bottom: 0;
75
80
  position: sticky;
76
81
  }
@@ -78,14 +83,14 @@ $duo-chat-scrim-gradient: linear-gradient(to bottom, rgba($gray-10, 0), $gray-10
78
83
  .duo-chat-drawer-body-scrim-on-footer {
79
84
  &::before {
80
85
  background: $duo-chat-scrim-gradient;
81
- top: -$gl-border-size-1;
86
+ top: 0;
82
87
  @apply -gl-translate-y-full;
83
88
  content: '';
84
89
  left: 0;
85
90
  position: absolute;
86
91
  @apply gl-pointer-events-none;
87
92
  @apply gl-w-full;
88
- @apply gl-h-7;
93
+ @apply gl-h-5;
89
94
  }
90
95
  }
91
96
 
@@ -125,9 +130,12 @@ $duo-chat-scrim-gradient: linear-gradient(to bottom, rgba($gray-10, 0), $gray-10
125
130
  @apply gl-flex-col;
126
131
  max-height: 240px;
127
132
  overflow: hidden;
133
+ background: var(--gl-control-background-color-default);
134
+ box-shadow: inset 0 0 0 $gl-border-size-1 var(--gl-control-border-color-default);
135
+ border-radius: px-to-rem(20px);
128
136
 
129
137
  &:focus-within {
130
- @include gl-focus($color: $gray-900);
138
+ @include gl-focus($color: var(--gl-control-border-color-focus));
131
139
  }
132
140
 
133
141
  .gl-form-textarea.form-control {
@@ -135,13 +143,16 @@ $duo-chat-scrim-gradient: linear-gradient(to bottom, rgba($gray-10, 0), $gray-10
135
143
  resize: none;
136
144
  max-height: 240px;
137
145
  padding-right: 40px;
146
+ border-radius: px-to-rem(20px);
138
147
  }
139
148
 
140
149
  &::after {
141
150
  content: attr(data-value) ' ';
142
151
  @apply gl-invisible;
143
- @apply gl-whitespace-pre-wrap;
144
- @apply gl-py-4;
152
+ @apply gl-p-4;
153
+ @apply gl-font-regular;
154
+ padding-right: 40px;
155
+ word-break: break-word;
145
156
  }
146
157
  }
147
158