@gitlab/ui 78.8.1 → 78.9.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [78.9.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v78.8.1...v78.9.0) (2024-04-04)
2
+
3
+
4
+ ### Features
5
+
6
+ * **DuoChat:** add mandatory field indicator on DuoChat Feedback Modal ([df7d4a5](https://gitlab.com/gitlab-org/gitlab-ui/commit/df7d4a55e799695c9d972ba029758136c0892990))
7
+
1
8
  ## [78.8.1](https://gitlab.com/gitlab-org/gitlab-ui/compare/v78.8.0...v78.8.1) (2024-04-04)
2
9
 
3
10
 
@@ -17,6 +17,7 @@ const i18n = {
17
17
  IMPROVEMENT_SUGGESTION_PLACEHOLDER: 'How the response might better meet your needs.',
18
18
  MORE_LABEL: 'More information',
19
19
  MORE_PLACEHOLDER: 'How could the content be improved?',
20
+ REQUIRED_VALIDATION_ERROR: 'Select at least one option.',
20
21
  FEEDBACK_OPTIONS: {
21
22
  helpful: 'Helpful',
22
23
  unhelpful: 'Unhelpful or irrelevant',
@@ -70,23 +71,34 @@ var script = {
70
71
  data() {
71
72
  return {
72
73
  selectedFeedbackOptions: [],
73
- extendedFeedback: ''
74
+ extendedFeedback: '',
75
+ isValid: null
74
76
  };
75
77
  },
78
+ watch: {
79
+ selectedFeedbackOptions(options) {
80
+ this.isValid = options.length > 0;
81
+ }
82
+ },
76
83
  methods: {
84
+ close() {
85
+ this.$refs.feedbackModal.hide();
86
+ },
77
87
  show() {
78
88
  this.$refs.feedbackModal.show();
79
89
  },
80
- onFeedbackSubmit() {
90
+ onFeedbackSubmit(e) {
81
91
  if (this.selectedFeedbackOptions.length) {
82
92
  this.$emit('feedback-submitted', {
83
93
  feedbackChoices: this.selectedFeedbackOptions,
84
94
  extendedTextFeedback: this.extendedFeedback
85
95
  });
96
+ this.close();
97
+ this.isValid = null;
98
+ } else {
99
+ e === null || e === void 0 ? void 0 : e.preventDefault();
100
+ this.isValid = false;
86
101
  }
87
- },
88
- onFeedbackCanceled() {
89
- this.$refs.feedbackModal.hide();
90
102
  }
91
103
  },
92
104
  actions: {
@@ -105,7 +117,7 @@ var script = {
105
117
  const __vue_script__ = script;
106
118
 
107
119
  /* template */
108
- var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('gl-modal',{ref:"feedbackModal",attrs:{"modal-id":"feedbackModal","title":_vm.modalTitle,"action-primary":_vm.$options.actions.primary,"action-cancel":_vm.$options.actions.cancel,"visible":false,"size":"sm"},on:{"primary":_vm.onFeedbackSubmit,"canceled":_vm.onFeedbackCanceled}},[_c('p',[_vm._v(_vm._s(_vm.$options.i18n.MODAL.DESCRIPTION))]),_vm._v(" "),_c('gl-form-group',{attrs:{"label":_vm.$options.i18n.MODAL.OPTIONS_LABEL,"optional":false,"data-testid":"feedback-options"}},[_c('gl-form-checkbox-group',{attrs:{"options":_vm.$options.feedbackOptions},model:{value:(_vm.selectedFeedbackOptions),callback:function ($$v) {_vm.selectedFeedbackOptions=$$v;},expression:"selectedFeedbackOptions"}})],1),_vm._v(" "),_c('gl-alert',{staticClass:"gl-mb-5",attrs:{"dismissible":false}},[_vm._v(_vm._s(_vm.modalAlert))]),_vm._v(" "),_vm._t("feedback-extra-fields",function(){return [_c('gl-form-group',{attrs:{"label":_vm.$options.i18n.MODAL.MORE_LABEL,"optional":""}},[_c('gl-form-textarea',{attrs:{"placeholder":_vm.$options.i18n.MODAL.MORE_PLACEHOLDER},model:{value:(_vm.extendedFeedback),callback:function ($$v) {_vm.extendedFeedback=$$v;},expression:"extendedFeedback"}})],1)]})],2)};
120
+ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('gl-modal',{ref:"feedbackModal",attrs:{"modal-id":"feedbackModal","title":_vm.modalTitle,"action-primary":_vm.$options.actions.primary,"action-cancel":_vm.$options.actions.cancel,"visible":false,"size":"sm"},on:{"primary":_vm.onFeedbackSubmit,"canceled":_vm.close}},[_c('p',[_vm._v(_vm._s(_vm.$options.i18n.MODAL.DESCRIPTION))]),_vm._v(" "),_c('gl-form-group',{attrs:{"invalid-feedback":_vm.$options.i18n.MODAL.REQUIRED_VALIDATION_ERROR,"state":_vm.isValid,"label":_vm.$options.i18n.MODAL.OPTIONS_LABEL,"data-testid":"feedback-options"}},[_c('gl-form-checkbox-group',{attrs:{"options":_vm.$options.feedbackOptions},model:{value:(_vm.selectedFeedbackOptions),callback:function ($$v) {_vm.selectedFeedbackOptions=$$v;},expression:"selectedFeedbackOptions"}})],1),_vm._v(" "),_c('gl-alert',{staticClass:"gl-mb-5",attrs:{"dismissible":false}},[_vm._v(_vm._s(_vm.modalAlert))]),_vm._v(" "),_vm._t("feedback-extra-fields",function(){return [_c('gl-form-group',{attrs:{"label":_vm.$options.i18n.MODAL.MORE_LABEL,"optional":""}},[_c('gl-form-textarea',{attrs:{"placeholder":_vm.$options.i18n.MODAL.MORE_PLACEHOLDER},model:{value:(_vm.extendedFeedback),callback:function ($$v) {_vm.extendedFeedback=$$v;},expression:"extendedFeedback"}})],1)]})],2)};
109
121
  var __vue_staticRenderFns__ = [];
110
122
 
111
123
  /* style */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Thu, 04 Apr 2024 18:24:00 GMT
3
+ * Generated on Thu, 04 Apr 2024 20:52:08 GMT
4
4
  */
5
5
 
6
6
  :root {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Thu, 04 Apr 2024 18:24:00 GMT
3
+ * Generated on Thu, 04 Apr 2024 20:52:08 GMT
4
4
  */
5
5
 
6
6
  :root.gl-dark {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Thu, 04 Apr 2024 18:24:00 GMT
3
+ * Generated on Thu, 04 Apr 2024 20:52:08 GMT
4
4
  */
5
5
 
6
6
  export const DATA_VIZ_GREEN_50 = "#133a03";
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Thu, 04 Apr 2024 18:24:00 GMT
3
+ * Generated on Thu, 04 Apr 2024 20:52:08 GMT
4
4
  */
5
5
 
6
6
  export const DATA_VIZ_GREEN_50 = "#ddfab7";
@@ -1,6 +1,6 @@
1
1
 
2
2
  // Do not edit directly
3
- // Generated on Thu, 04 Apr 2024 18:24:00 GMT
3
+ // Generated on Thu, 04 Apr 2024 20:52:08 GMT
4
4
 
5
5
  $gl-text-tertiary: #737278 !default;
6
6
  $gl-text-secondary: #89888d !default;
@@ -1,6 +1,6 @@
1
1
 
2
2
  // Do not edit directly
3
- // Generated on Thu, 04 Apr 2024 18:24:00 GMT
3
+ // Generated on Thu, 04 Apr 2024 20:52:08 GMT
4
4
 
5
5
  $gl-text-tertiary: #89888d !default;
6
6
  $gl-text-secondary: #737278 !default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitlab/ui",
3
- "version": "78.8.1",
3
+ "version": "78.9.0",
4
4
  "description": "GitLab UI Components",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -74,9 +74,7 @@ export const Slots = (args, { argTypes }) => ({
74
74
  @feedback="logEvent">
75
75
  <template #feedback-extra-fields>
76
76
  <div class="gl-mb-5">
77
- <gl-alert variant="info" :dismissible="false">
78
- GitLab team members can not see your conversation. Please be as descriptive as possible.
79
- </gl-alert>
77
+ Example slot content: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
80
78
  </div>
81
79
  <gl-form-group label="What were you doing?" optional>
82
80
  <gl-form-textarea placeholder="The situation in which you interacted with GitLab Duo Chat." v-model="didWhat" />
@@ -12,10 +12,12 @@ const DummyComponent = {
12
12
 
13
13
  describe('FeedbackModal', () => {
14
14
  let wrapper;
15
+ const findByTestId = (testId) => wrapper.find(`[data-testid="${testId}"]`);
15
16
  const findModal = () => wrapper.findComponent(GlModal);
16
- const findOptions = () => wrapper.findComponent('[data-testid="feedback-options"]');
17
+ const findOptions = () => findByTestId('feedback-options');
17
18
  const findOptionsCheckboxes = () => findOptions().findAllComponents(GlFormCheckbox);
18
19
  const findTextarea = () => wrapper.findComponent(GlFormTextarea);
20
+
19
21
  const selectOption = (index = 0) => {
20
22
  wrapper
21
23
  .findAllComponents(GlFormCheckboxGroup)
@@ -31,6 +33,9 @@ describe('FeedbackModal', () => {
31
33
  },
32
34
  provide: options.injections,
33
35
  });
36
+
37
+ wrapper.vm.close = jest.fn();
38
+ return wrapper;
34
39
  };
35
40
 
36
41
  describe('inputs', () => {
@@ -56,7 +61,7 @@ describe('FeedbackModal', () => {
56
61
  createComponent();
57
62
  });
58
63
 
59
- it('emits the feedback event when the submit button is clicked', () => {
64
+ it('emits the feedback event when the submit button is clicked and closes the modal', () => {
60
65
  selectOption();
61
66
  findModal().vm.$emit('primary');
62
67
  expect(wrapper.emitted('feedback-submitted')).toEqual([
@@ -67,9 +72,20 @@ describe('FeedbackModal', () => {
67
72
  },
68
73
  ],
69
74
  ]);
75
+
76
+ expect(wrapper.vm.close).toHaveBeenCalledTimes(1);
70
77
  });
71
- it('does not emit event if there is no option selected', () => {
78
+
79
+ it('does not render validation error by default', () => {
80
+ expect(findOptions().vm.$attrs.state).not.toBe(false);
81
+ });
82
+
83
+ it('renders validation error when submit was triggered without selected a required option', async () => {
72
84
  findModal().vm.$emit('primary');
85
+ await wrapper.vm.$nextTick();
86
+
87
+ expect(findOptions().vm.$attrs.state).toBe(false);
88
+ expect(findOptions().vm.$attrs['invalid-feedback']).toBe('Select at least one option.');
73
89
  expect(wrapper.emitted('feedback-submitted')).toBeUndefined();
74
90
  });
75
91
  });
@@ -18,6 +18,7 @@ export const i18n = {
18
18
  IMPROVEMENT_SUGGESTION_PLACEHOLDER: 'How the response might better meet your needs.',
19
19
  MORE_LABEL: 'More information',
20
20
  MORE_PLACEHOLDER: 'How could the content be improved?',
21
+ REQUIRED_VALIDATION_ERROR: 'Select at least one option.',
21
22
  FEEDBACK_OPTIONS: {
22
23
  helpful: 'Helpful',
23
24
  unhelpful: 'Unhelpful or irrelevant',
@@ -81,23 +82,34 @@ export default {
81
82
  return {
82
83
  selectedFeedbackOptions: [],
83
84
  extendedFeedback: '',
85
+ isValid: null,
84
86
  };
85
87
  },
88
+ watch: {
89
+ selectedFeedbackOptions(options) {
90
+ this.isValid = options.length > 0;
91
+ },
92
+ },
86
93
  methods: {
94
+ close() {
95
+ this.$refs.feedbackModal.hide();
96
+ },
87
97
  show() {
88
98
  this.$refs.feedbackModal.show();
89
99
  },
90
- onFeedbackSubmit() {
100
+ onFeedbackSubmit(e) {
91
101
  if (this.selectedFeedbackOptions.length) {
92
102
  this.$emit('feedback-submitted', {
93
103
  feedbackChoices: this.selectedFeedbackOptions,
94
104
  extendedTextFeedback: this.extendedFeedback,
95
105
  });
106
+ this.close();
107
+ this.isValid = null;
108
+ } else {
109
+ e?.preventDefault();
110
+ this.isValid = false;
96
111
  }
97
112
  },
98
- onFeedbackCanceled() {
99
- this.$refs.feedbackModal.hide();
100
- },
101
113
  },
102
114
  actions: {
103
115
  primary: {
@@ -121,12 +133,13 @@ export default {
121
133
  :visible="false"
122
134
  size="sm"
123
135
  @primary="onFeedbackSubmit"
124
- @canceled="onFeedbackCanceled"
136
+ @canceled="close"
125
137
  >
126
138
  <p>{{ $options.i18n.MODAL.DESCRIPTION }}</p>
127
139
  <gl-form-group
140
+ :invalid-feedback="$options.i18n.MODAL.REQUIRED_VALIDATION_ERROR"
141
+ :state="isValid"
128
142
  :label="$options.i18n.MODAL.OPTIONS_LABEL"
129
- :optional="false"
130
143
  data-testid="feedback-options"
131
144
  >
132
145
  <gl-form-checkbox-group