@gitlab/ui 90.5.0 → 91.1.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 (46) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/components/base/path/path.js +2 -15
  3. package/dist/components/experimental/duo/chat/components/duo_chat_context/constants.js +5 -0
  4. package/dist/components/experimental/duo/chat/components/duo_chat_context/duo_chat_context_item_popover/duo_chat_context_item_popover.js +93 -0
  5. package/dist/components/experimental/duo/chat/components/duo_chat_context/duo_chat_context_item_selections/duo_chat_context_item_selections.js +91 -0
  6. package/dist/components/experimental/duo/chat/components/duo_chat_context/mock_context_data.js +121 -0
  7. package/dist/components/experimental/duo/chat/components/duo_chat_message/duo_chat_message.js +24 -1
  8. package/dist/components/experimental/duo/chat/mock_data.js +9 -3
  9. package/dist/index.css +2 -2
  10. package/dist/index.css.map +1 -1
  11. package/dist/tailwind.css +1 -1
  12. package/dist/tailwind.css.map +1 -1
  13. package/dist/tokens/build/js/tokens.dark.js +13 -1
  14. package/dist/tokens/build/js/tokens.js +13 -1
  15. package/dist/tokens/css/tokens.css +12 -0
  16. package/dist/tokens/css/tokens.dark.css +12 -0
  17. package/dist/tokens/js/tokens.dark.js +12 -0
  18. package/dist/tokens/js/tokens.js +12 -0
  19. package/dist/tokens/json/tokens.dark.json +278 -0
  20. package/dist/tokens/json/tokens.json +278 -0
  21. package/dist/tokens/scss/_tokens.dark.scss +12 -0
  22. package/dist/tokens/scss/_tokens.scss +12 -0
  23. package/dist/tokens/scss/_tokens_custom_properties.scss +12 -0
  24. package/dist/utils/constants.js +1 -2
  25. package/package.json +1 -1
  26. package/src/components/base/path/path.scss +44 -62
  27. package/src/components/base/path/path.vue +2 -15
  28. package/src/components/experimental/duo/chat/components/duo_chat_context/constants.js +3 -0
  29. package/src/components/experimental/duo/chat/components/duo_chat_context/duo_chat_context_item_popover/duo_chat_context_item_popover.vue +111 -0
  30. package/src/components/experimental/duo/chat/components/duo_chat_context/duo_chat_context_item_selections/duo_chat_context_item_selections.vue +94 -0
  31. package/src/components/experimental/duo/chat/components/duo_chat_context/mock_context_data.js +137 -0
  32. package/src/components/experimental/duo/chat/components/duo_chat_message/duo_chat_message.md +5 -0
  33. package/src/components/experimental/duo/chat/components/duo_chat_message/duo_chat_message.vue +43 -0
  34. package/src/components/experimental/duo/chat/mock_data.js +8 -2
  35. package/src/tokens/action.tokens.json +86 -0
  36. package/src/tokens/build/css/tokens.css +12 -0
  37. package/src/tokens/build/css/tokens.dark.css +12 -0
  38. package/src/tokens/build/js/tokens.dark.js +12 -0
  39. package/src/tokens/build/js/tokens.js +12 -0
  40. package/src/tokens/build/json/tokens.dark.json +278 -0
  41. package/src/tokens/build/json/tokens.json +278 -0
  42. package/src/tokens/build/scss/_tokens.dark.scss +12 -0
  43. package/src/tokens/build/scss/_tokens.scss +12 -0
  44. package/src/tokens/build/scss/_tokens_custom_properties.scss +12 -0
  45. package/src/utils/constants.js +0 -2
  46. package/translations.js +3 -0
@@ -26,7 +26,6 @@ const CONTRAST_LEVELS = [{
26
26
  }];
27
27
  const HEX_REGEX = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
28
28
  const LEFT_MOUSE_BUTTON = 0;
29
- const glThemes = ['indigo', 'blue', 'light-blue', 'green', 'red', 'light-red'];
30
29
  const variantOptions = {
31
30
  primary: 'primary',
32
31
  secondary: 'secondary',
@@ -306,4 +305,4 @@ const loadingIconVariants = {
306
305
  dots: 'dots'
307
306
  };
308
307
 
309
- export { COMMA, CONTRAST_LEVELS, HEX_REGEX, LEFT_MOUSE_BUTTON, alertVariantIconMap, alertVariantOptions, alignOptions, avatarShapeOptions, avatarSizeOptions, avatarsInlineSizeOptions, badgeForButtonOptions, badgeIconSizeOptions, badgeSizeOptions, badgeVariantOptions, bannerVariants, buttonCategoryOptions, buttonSizeOptions, buttonVariantOptions, colorThemes, columnOptions, datepickerWidthOptionsMap, defaultDateFormat, drawerVariants, dropdownAllowedAutoPlacements, dropdownPlacements, dropdownVariantOptions, focusableTags, formInputWidths, formStateOptions, glThemes, iconSizeOptions, iconVariantOptions, keyboard, labelColorOptions, loadingIconSizes, loadingIconVariants, maxZIndex, modalButtonDefaults, modalSizeOptions, popoverPlacements, resizeDebounceTime, tabsButtonDefaults, targetOptions, toggleLabelPosition, tokenVariants, tooltipActionEvents, tooltipDelay, tooltipPlacements, triggerVariantOptions, truncateOptions, variantCssColorMap, variantOptions, variantOptionsWithNoDefault, viewModeOptions };
308
+ export { COMMA, CONTRAST_LEVELS, HEX_REGEX, LEFT_MOUSE_BUTTON, alertVariantIconMap, alertVariantOptions, alignOptions, avatarShapeOptions, avatarSizeOptions, avatarsInlineSizeOptions, badgeForButtonOptions, badgeIconSizeOptions, badgeSizeOptions, badgeVariantOptions, bannerVariants, buttonCategoryOptions, buttonSizeOptions, buttonVariantOptions, colorThemes, columnOptions, datepickerWidthOptionsMap, defaultDateFormat, drawerVariants, dropdownAllowedAutoPlacements, dropdownPlacements, dropdownVariantOptions, focusableTags, formInputWidths, formStateOptions, iconSizeOptions, iconVariantOptions, keyboard, labelColorOptions, loadingIconSizes, loadingIconVariants, maxZIndex, modalButtonDefaults, modalSizeOptions, popoverPlacements, resizeDebounceTime, tabsButtonDefaults, targetOptions, toggleLabelPosition, tokenVariants, tooltipActionEvents, tooltipDelay, tooltipPlacements, triggerVariantOptions, truncateOptions, variantCssColorMap, variantOptions, variantOptionsWithNoDefault, viewModeOptions };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitlab/ui",
3
- "version": "90.5.0",
3
+ "version": "91.1.0",
4
4
  "description": "GitLab UI Components",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -6,25 +6,14 @@ $path-chevron-dimension: px-to-rem(24px);
6
6
  $path-chevron-border-radius: px-to-rem(10px);
7
7
  $path-chevron-tip-border-radius: px-to-rem(2px);
8
8
  $path-button-right-padding: 1.25 * $grid-size;
9
- $path-chevron-drop-shadow: drop-shadow(0 0 px-to-rem(1px) $white)
10
- drop-shadow(0 0 px-to-rem(2px) $blue-500);
11
9
  $path-chevron-transformation: rotate(45deg) skew(14deg, 14deg);
12
10
  $path-chevron-right-margin: px-to-rem(14px);
13
11
 
14
12
  // Mixins
15
- @mixin gl-path-active-item-color($color) {
16
- @include gl-text-contrast-light;
17
- background-color: $color;
18
-
19
- &::after {
20
- background-color: $color;
21
- }
22
- }
23
-
24
13
  @mixin gl-path-chevron {
14
+ @include gl-reset-bg;
25
15
  content: '';
26
16
  position: absolute;
27
- @include gl-reset-bg;
28
17
  top: $path-chevron-top;
29
18
  right: $path-chevron-right;
30
19
  width: $path-chevron-dimension;
@@ -34,6 +23,7 @@ $path-chevron-right-margin: px-to-rem(14px);
34
23
  border-top-left-radius: $path-chevron-border-radius;
35
24
  border-bottom-right-radius: $path-chevron-border-radius;
36
25
  border-top-right-radius: $path-chevron-tip-border-radius;
26
+ clip-path: polygon(100% 0, 0 0, 100% 100%);
37
27
  }
38
28
 
39
29
  .gl-path-nav {
@@ -43,11 +33,11 @@ $path-chevron-right-margin: px-to-rem(14px);
43
33
  .gl-path-nav-list {
44
34
  @include gl-p-1;
45
35
  @include gl-m-0;
46
- position: relative;
47
36
  @include gl-list-style-none;
48
37
  @include gl-display-inline-flex;
49
38
  @include gl-overflow-hidden;
50
39
  margin-left: -1px;
40
+ position: relative;
51
41
  }
52
42
 
53
43
  .gl-path-nav-list-item {
@@ -65,18 +55,18 @@ $path-chevron-right-margin: px-to-rem(14px);
65
55
  @include gl-pl-5;
66
56
  @include gl-py-3;
67
57
  @include gl-display-flex;
68
- position: relative;
69
58
  @include gl-font-base;
70
59
  @include gl-z-index-0;
71
- @apply gl-border-none;
72
- @include gl-text-gray-500;
73
60
  @include gl-font-weight-bold;
74
61
  @include gl-line-height-normal;
75
62
  @include gl-rounded-top-left-base;
76
63
  @include gl-rounded-bottom-left-base;
77
- background-color: var(--path-bg-color);
78
- padding-right: $path-button-right-padding;
64
+ @apply gl-border-none;
65
+ background-color: var(--gl-action-neutral-background-color-default);
66
+ color: var(--gl-action-neutral-foreground-color-default);
79
67
  margin-right: $path-chevron-right-margin;
68
+ padding-right: $path-button-right-padding;
69
+ position: relative;
80
70
 
81
71
  &::before,
82
72
  &::after {
@@ -85,47 +75,69 @@ $path-chevron-right-margin: px-to-rem(14px);
85
75
 
86
76
  // Pseudo focus element
87
77
  &::before {
78
+ background-color: var(--gl-color-alpha-0);
88
79
  display: none;
89
80
  z-index: 2;
90
81
  right: calc(-0.75rem + 1px);
91
- box-shadow: 0 0 0 1px $white, 0.5px -0.5px 0 2.5px $blue-400;
82
+ box-shadow: 0 0 0 1px var(--gl-focus-ring-inner-color), 0.5px -0.5px 0 2.5px var(--gl-focus-ring-outer-color);
92
83
  clip-path: polygon(0% 0%, 0% -30%, 160% 0%, 75% 130%, 100% 100%);
93
84
  transform: rotate(45deg) skew(14deg, 14deg) scale(0.99);
94
85
  }
95
86
 
96
- &[disabled] {
97
- color: $gl-text-color-disabled;
98
- @include gl-cursor-not-allowed;
87
+ &:hover {
88
+ background-color: var(--gl-action-neutral-background-color-hover);
89
+ color: var(--gl-action-neutral-foreground-color-hover);
90
+ }
91
+
92
+ &:focus {
93
+ background-color: var(--gl-action-neutral-background-color-focus);
94
+ color: var(--gl-action-neutral-foreground-color-focus);
99
95
  }
100
96
 
101
- &:not([disabled]):hover {
102
- @include gl-path-active-item-color($gray-100);
103
- color: $gl-text-color;
97
+ &:active {
98
+ background-color: var(--gl-action-neutral-background-color-active);
99
+ color: var(--gl-action-neutral-foreground-color-active);
104
100
  }
105
101
 
106
102
  &:active,
107
103
  &:focus,
108
104
  &:focus:active {
109
- // Custom focus
105
+ // Custom focus to account for path shape
106
+ box-shadow: 5px -3px 0 -2px var(--gl-focus-ring-inner-color), 5px 3px 0 -2px var(--gl-focus-ring-inner-color), 0 0 0 1px var(--gl-focus-ring-inner-color),
107
+ 0 0 0 3px var(--gl-focus-ring-outer-color);
108
+ outline: none;
110
109
  border-top-right-radius: 1px;
111
110
  border-bottom-right-radius: 1px;
112
- box-shadow: 5px -3px 0 -2px $white, 5px 3px 0 -2px $white, 0 0 0 1px $white,
113
- 0 0 0 3px $blue-400;
114
- outline: none;
115
111
 
116
112
  &::before {
117
113
  display: block;
118
114
  }
119
115
  }
116
+
117
+ &.gl-path-active-item {
118
+ background-color: var(--gl-action-selected-background-color-default);
119
+ color: var(--gl-action-selected-foreground-color-default);
120
+ }
121
+
122
+ &:disabled {
123
+ @include gl-cursor-not-allowed;
124
+ background-color: var(--gl-color-alpha-0);
125
+ box-shadow: none;
126
+ color: var(--gl-action-disabled-foreground-color);
127
+
128
+ &::before {
129
+ box-shadow: none;
130
+ }
131
+ }
120
132
  }
121
133
 
122
134
  .gl-path-fade {
123
135
  @include gl-w-8;
124
136
  @include gl-h-full;
137
+ @include gl-z-index-2;
125
138
  bottom: 0;
139
+ color: var(--gl-text-color-subtle);
126
140
  position: absolute;
127
- @include gl-z-index-2;
128
- @include gl-text-gray-500;
129
141
 
130
142
  &-left {
131
143
  left: 0;
@@ -141,41 +153,11 @@ $path-chevron-right-margin: px-to-rem(14px);
141
153
 
142
154
  .gl-clear-icon-button {
143
155
  @include gl-p-0;
144
- @include gl-text-gray-400;
145
156
  @include gl-h-full;
157
+ color: var(--gl-icon-color-subtle);
146
158
 
147
159
  .gl-icon {
148
160
  @include gl-vertical-align-middle;
149
161
  }
150
162
  }
151
-
152
- .gl-path-active-item-indigo,
153
- .gl-path-active-item-indigo:hover {
154
- @include gl-path-active-item-color($theme-indigo-700);
155
- }
156
-
157
- .gl-path-active-item-blue,
158
- .gl-path-active-item-blue:hover {
159
- @include gl-path-active-item-color($theme-blue-500);
160
- }
161
-
162
- .gl-path-active-item-light-blue,
163
- .gl-path-active-item-light-blue:hover {
164
- @include gl-path-active-item-color($theme-light-blue-500);
165
- }
166
-
167
- .gl-path-active-item-red,
168
- .gl-path-active-item-red:hover {
169
- @include gl-path-active-item-color($theme-red-500);
170
- }
171
-
172
- .gl-path-active-item-light-red,
173
- .gl-path-active-item-light-red:hover {
174
- @include gl-path-active-item-color($theme-light-red-500);
175
- }
176
-
177
- .gl-path-active-item-green,
178
- .gl-path-active-item-green:hover {
179
- @include gl-path-active-item-color($theme-green-500);
180
- }
181
163
  }
@@ -4,12 +4,11 @@ import iconSpriteInfo from '@gitlab/svgs/dist/icons.json';
4
4
  import uniqueId from 'lodash/uniqueId';
5
5
  import findLast from 'lodash/findLast';
6
6
  import { GlResizeObserverDirective } from '../../../directives/resize_observer/resize_observer';
7
- import { glThemes } from '../../../utils/constants';
8
7
  import GlIcon from '../icon/icon.vue';
9
8
 
10
9
  const BOUNDARY_WIDTH = 40;
11
10
  const PATH_ITEM_CLASS = 'gl-path-button';
12
- const PATH_ACTIVE_ITEM_PREFIX = 'gl-path-active-item';
11
+ const PATH_ACTIVE_ITEM_CLASS = 'gl-path-active-item';
13
12
 
14
13
  export default {
15
14
  name: 'GlPath',
@@ -36,15 +35,6 @@ export default {
36
35
  required: false,
37
36
  default: () => [],
38
37
  },
39
- /**
40
- * The color theme to be used.
41
- */
42
- theme: {
43
- type: String,
44
- required: false,
45
- default: 'indigo',
46
- validator: (theme) => glThemes.includes(theme),
47
- },
48
38
  /**
49
39
  * The items' background color.
50
40
  */
@@ -62,9 +52,6 @@ export default {
62
52
  };
63
53
  },
64
54
  computed: {
65
- activeClass() {
66
- return `${PATH_ACTIVE_ITEM_PREFIX}-${this.theme}`;
67
- },
68
55
  entireListVisible() {
69
56
  return this.width >= this.getScrollWidth();
70
57
  },
@@ -97,7 +84,7 @@ export default {
97
84
  methods: {
98
85
  pathItemClass(index) {
99
86
  return index === this.selectedIndex
100
- ? `${PATH_ITEM_CLASS} ${this.activeClass}`
87
+ ? `${PATH_ITEM_CLASS} ${PATH_ACTIVE_ITEM_CLASS}`
101
88
  : PATH_ITEM_CLASS;
102
89
  },
103
90
  onItemClicked(selectedIndex) {
@@ -0,0 +1,3 @@
1
+ export const CONTEXT_ITEM_TYPE_ISSUE = 'issue';
2
+ export const CONTEXT_ITEM_TYPE_MERGE_REQUEST = 'merge_request';
3
+ export const CONTEXT_ITEM_TYPE_PROJECT_FILE = 'project_file';
@@ -0,0 +1,111 @@
1
+ <script>
2
+ import GlPopover from '../../../../../../base/popover/popover.vue';
3
+ import { translate } from '../../../../../../../utils/i18n';
4
+ import {
5
+ CONTEXT_ITEM_TYPE_ISSUE,
6
+ CONTEXT_ITEM_TYPE_MERGE_REQUEST,
7
+ CONTEXT_ITEM_TYPE_PROJECT_FILE,
8
+ } from '../constants';
9
+
10
+ const ID_PREFIXES = {
11
+ issue: '#',
12
+ merge_request: '!',
13
+ };
14
+
15
+ export default {
16
+ name: 'DuoChatContextItemPopover',
17
+ components: {
18
+ GlPopover,
19
+ },
20
+ props: {
21
+ item: {
22
+ type: Object,
23
+ required: true,
24
+ },
25
+ target: {
26
+ type: String,
27
+ required: true,
28
+ },
29
+ placement: {
30
+ type: String,
31
+ default: 'bottom',
32
+ required: false,
33
+ },
34
+ },
35
+ computed: {
36
+ itemInfo() {
37
+ return this.item.metadata?.info || {};
38
+ },
39
+ id() {
40
+ const isIssuable =
41
+ this.item.type === CONTEXT_ITEM_TYPE_ISSUE ||
42
+ this.item.type === CONTEXT_ITEM_TYPE_MERGE_REQUEST;
43
+ return isIssuable ? this.itemInfo.iid || '' : null;
44
+ },
45
+ idPrefix() {
46
+ return ID_PREFIXES[this.item.type] || '';
47
+ },
48
+ filePath() {
49
+ return this.item.type === CONTEXT_ITEM_TYPE_PROJECT_FILE
50
+ ? this.itemInfo.relFilePath || ''
51
+ : null;
52
+ },
53
+ isEnabled() {
54
+ return this.item.isEnabled !== false;
55
+ },
56
+ disabledMessage() {
57
+ return Array.isArray(this.item.disabledReasons) && this.item.disabledReasons.length > 0
58
+ ? this.item.disabledReasons.join(', ')
59
+ : translate('DuoChatContextItemPopover.DisabledReason', 'This item is disabled');
60
+ },
61
+ },
62
+ methods: {
63
+ translate,
64
+ },
65
+ };
66
+ </script>
67
+ <template>
68
+ <gl-popover
69
+ :target="target"
70
+ triggers="hover focus"
71
+ :placement="placement"
72
+ :title="item.metadata.name"
73
+ custom-class="gl-duo-chat-item-popover"
74
+ >
75
+ <template #title>
76
+ <span class="gl-text-sm gl-text-gray-500" data-testid="chat-context-popover-title">{{
77
+ item.metadata.name
78
+ }}</span>
79
+ </template>
80
+ <div class="gl-p-3">
81
+ <div class="gl-mb-2">
82
+ <strong class="gl-mr-1">{{
83
+ translate('DuoChatContextItemPopover.ProjectLabel', 'Project:')
84
+ }}</strong>
85
+ <span>{{ itemInfo.project }}</span>
86
+ </div>
87
+ <div v-if="filePath !== null" class="gl-mb-2">
88
+ <strong class="gl-mr-1">{{
89
+ translate('DuoChatContextItemPopover.PathLabel', 'Path:')
90
+ }}</strong>
91
+ <span>{{ filePath }}</span>
92
+ </div>
93
+ <div v-if="id !== null" class="gl-mb-2">
94
+ <strong class="gl-mr-1">{{ translate('DuoChatContextItemPopover.IdLabel', 'ID:') }}</strong>
95
+ <span>{{ idPrefix }}{{ id }}</span>
96
+ </div>
97
+ <div class="gl-mb-2">
98
+ <strong class="gl-mr-1">{{
99
+ translate('DuoChatContextItemPopover.TypeLabel', 'Type:')
100
+ }}</strong>
101
+ <span>{{ item.type }}</span>
102
+ </div>
103
+ <div v-if="!isEnabled" class="gl-text-red-500" data-testid="chat-context-popover-disabled">
104
+ <strong class="gl-mr-1">{{
105
+ translate('DuoChatContextItemPopover.DisabledMessageLabel', 'Note:')
106
+ }}</strong>
107
+ <span>{{ disabledMessage }}</span>
108
+ </div>
109
+ </div>
110
+ </gl-popover>
111
+ </template>
@@ -0,0 +1,94 @@
1
+ <script>
2
+ import uniqueId from 'lodash/uniqueId';
3
+ import GlIcon from '../../../../../../base/icon/icon.vue';
4
+ import GlToken from '../../../../../../base/token/token.vue';
5
+ import GlDuoChatContextItemPopover from '../duo_chat_context_item_popover/duo_chat_context_item_popover.vue';
6
+ import {
7
+ CONTEXT_ITEM_TYPE_ISSUE,
8
+ CONTEXT_ITEM_TYPE_MERGE_REQUEST,
9
+ CONTEXT_ITEM_TYPE_PROJECT_FILE,
10
+ } from '../constants';
11
+
12
+ export default {
13
+ name: 'GlDuoChatContextItemSelections',
14
+ components: {
15
+ GlIcon,
16
+ GlDuoChatContextItemPopover,
17
+ GlToken,
18
+ },
19
+ props: {
20
+ selections: {
21
+ type: Array,
22
+ required: true,
23
+ },
24
+ title: {
25
+ type: String,
26
+ required: true,
27
+ },
28
+ defaultCollapsed: {
29
+ type: Boolean,
30
+ required: true,
31
+ },
32
+ },
33
+ data() {
34
+ return {
35
+ isCollapsed: this.defaultCollapsed,
36
+ selectionsId: uniqueId(),
37
+ };
38
+ },
39
+ computed: {
40
+ collapseIconName() {
41
+ return this.isCollapsed ? 'chevron-right' : 'chevron-down';
42
+ },
43
+ },
44
+ methods: {
45
+ getIconName(type) {
46
+ const iconMap = {
47
+ [CONTEXT_ITEM_TYPE_PROJECT_FILE]: 'document',
48
+ [CONTEXT_ITEM_TYPE_ISSUE]: 'issues',
49
+ [CONTEXT_ITEM_TYPE_MERGE_REQUEST]: 'merge-request',
50
+ };
51
+ return iconMap[type] || 'document';
52
+ },
53
+ toggleCollapse() {
54
+ this.isCollapsed = !this.isCollapsed;
55
+ },
56
+ },
57
+ };
58
+ </script>
59
+
60
+ <template>
61
+ <div class="gl-mb-3 gl-flex gl-flex-col">
62
+ <button
63
+ class="gl-flex gl-w-full gl-items-center gl-border-0 gl-bg-transparent gl-p-0 gl-text-left gl-text-xs gl-lowercase gl-text-gray-500"
64
+ data-testid="chat-context-selections-title"
65
+ @click="toggleCollapse"
66
+ >
67
+ <gl-icon :name="collapseIconName" data-testid="chat-context-collapse-icon" /> {{ title }}
68
+ </button>
69
+
70
+ <div
71
+ v-show="!isCollapsed"
72
+ class="gl-mt-1 gl-flex gl-grow gl-flex-wrap"
73
+ data-testid="chat-context-tokens-wrapper"
74
+ >
75
+ <gl-token
76
+ v-for="item in selections"
77
+ :key="item.id"
78
+ :view-only="true"
79
+ variant="default"
80
+ class="gl-mb-2 gl-mr-2"
81
+ >
82
+ <div :id="`context-item-${item.id}-${selectionsId}`" class="gl-flex gl-items-center">
83
+ <gl-icon :name="getIconName(item.type)" :size="12" class="gl-mr-1" />
84
+ {{ item.metadata.name }}
85
+ </div>
86
+ <gl-duo-chat-context-item-popover
87
+ :item="item"
88
+ :target="`context-item-${item.id}-${selectionsId}`"
89
+ placement="bottom"
90
+ />
91
+ </gl-token>
92
+ </div>
93
+ </div>
94
+ </template>
@@ -0,0 +1,137 @@
1
+ export const MOCK_CONTEXT_ITEM_FILE = {
2
+ id: '123e4567-e89b-12d3-a456-426614174000',
3
+ isEnabled: true,
4
+ metadata: {
5
+ name: 'strawberry.ts',
6
+ info: {
7
+ project: 'example/garden',
8
+ relFilePath: 'src/plants/strawberry.ts',
9
+ },
10
+ },
11
+ type: 'project_file',
12
+ };
13
+
14
+ export const MOCK_CONTEXT_ITEM_FILE_DISABLED = {
15
+ id: '323e4567-e89b-12d3-a456-426614174002',
16
+ isEnabled: false,
17
+ metadata: {
18
+ name: 'motorbike.cs',
19
+ info: {
20
+ project: 'example/vehicles',
21
+ relFilePath: '/src/VehicleFoo/motorbike.cs',
22
+ },
23
+ },
24
+ type: 'project_file',
25
+ };
26
+ const mockFiles = [
27
+ MOCK_CONTEXT_ITEM_FILE,
28
+ {
29
+ id: '223e4567-e89b-12d3-a456-426614174001',
30
+ isEnabled: true,
31
+ metadata: {
32
+ name: 'potato.ts',
33
+ info: {
34
+ project: 'example/garden',
35
+ relFilePath: '/src/plants/potato.ts',
36
+ },
37
+ },
38
+ type: 'project_file',
39
+ },
40
+ MOCK_CONTEXT_ITEM_FILE_DISABLED,
41
+ ];
42
+
43
+ export const MOCK_CONTEXT_ITEM_ISSUE = {
44
+ id: '423e4567-e89b-12d3-a456-426614174003',
45
+ isEnabled: true,
46
+ metadata: {
47
+ name: 'Implement watering schedule',
48
+ info: {
49
+ project: 'example/garden',
50
+ iid: 1234,
51
+ },
52
+ },
53
+ type: 'issue',
54
+ };
55
+ export const MOCK_CONTEXT_ITEM_ISSUE_DISABLED = {
56
+ id: 'c463fb31-2a4c-4f8e-a609-97230ac48ae5',
57
+ isEnabled: false,
58
+ metadata: {
59
+ name: 'Fix vehicle colours',
60
+ info: {
61
+ project: 'example/vehicle',
62
+ iid: 91011,
63
+ },
64
+ },
65
+ disabledReasons: ['This foo is not available to bar', 'Lorem something something wow?'],
66
+ type: 'issue',
67
+ };
68
+
69
+ const mockIssues = [
70
+ MOCK_CONTEXT_ITEM_ISSUE,
71
+ {
72
+ id: '523e4567-e89b-12d3-a456-426614174004',
73
+ isEnabled: true,
74
+ metadata: {
75
+ name: 'Refactor plant growth rates',
76
+ info: {
77
+ project: 'example/garden',
78
+ iid: 5678,
79
+ },
80
+ },
81
+ type: 'issue',
82
+ },
83
+ MOCK_CONTEXT_ITEM_ISSUE_DISABLED,
84
+ ];
85
+
86
+ export const MOCK_CONTEXT_ITEM_MERGE_REQUEST = {
87
+ id: '623e4567-e89b-12d3-a456-426614174005',
88
+ isEnabled: true,
89
+ metadata: {
90
+ name: 'Improve database performance',
91
+ info: {
92
+ project: 'example/garden',
93
+ iid: 1122,
94
+ },
95
+ },
96
+ type: 'merge_request',
97
+ };
98
+ export const MOCK_CONTEXT_ITEM_MERGE_REQUEST_DISABLED = {
99
+ id: '4eb665fc-e5e1-49b0-9789-2a16964e461a',
100
+ isEnabled: false,
101
+ metadata: {
102
+ name: 'Fix broken layout at small viewports',
103
+ info: {
104
+ project: 'example/vehicle',
105
+ iid: 5566,
106
+ },
107
+ },
108
+ disabledReasons: ['This foo is not available to bar', 'Lorem something something wow?'],
109
+ type: 'merge_request',
110
+ };
111
+
112
+ const mockMergeRequests = [
113
+ MOCK_CONTEXT_ITEM_MERGE_REQUEST,
114
+ {
115
+ id: '723e4567-e89b-12d3-a456-426614174006',
116
+ isEnabled: false,
117
+ metadata: {
118
+ name: 'Add vehicle registration details',
119
+ info: {
120
+ project: 'example/vehicle',
121
+ iid: 3344,
122
+ },
123
+ },
124
+ disabledReasons: ['This foo is not available to bar', 'Lorem something something wow?'],
125
+ type: 'merge_request',
126
+ },
127
+ MOCK_CONTEXT_ITEM_MERGE_REQUEST_DISABLED,
128
+ ];
129
+
130
+ export const getMockContextItems = () => {
131
+ const allItems = [...mockFiles, ...mockIssues, ...mockMergeRequests];
132
+
133
+ // put disabled items in the back
134
+ const disabledItems = allItems.filter((item) => !item.isEnabled);
135
+ const enabledItems = allItems.filter((item) => item.isEnabled);
136
+ return [...enabledItems, ...disabledItems];
137
+ };
@@ -62,3 +62,8 @@ The component emits the `track-feedback` event, a proxy of the `feedback` event
62
62
  the `GlDuoUserFeedback` component. Please refer to
63
63
  [the documentation on that component](/story/experimental-duo-user-feedback--docs#listening-to-the-feedback-form-submission)
64
64
  when processing feedback from users.
65
+
66
+ ## Included context references
67
+
68
+ Messages will display any included context references (files, issues merge requests etc.) when
69
+ the message `meta.contextItems` array contains valid items.