@gitlab/ui 74.4.0 → 74.6.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 +19 -0
- package/dist/components/base/form/form_fields/form_fields.js +11 -1
- package/dist/components/experimental/duo/chat/duo_chat.js +2 -2
- package/dist/tokens/css/tokens.css +1 -1
- package/dist/tokens/css/tokens.dark.css +1 -1
- package/dist/tokens/js/tokens.dark.js +1 -1
- package/dist/tokens/js/tokens.js +1 -1
- package/dist/tokens/scss/_tokens.dark.scss +1 -1
- package/dist/tokens/scss/_tokens.scss +1 -1
- package/dist/utils/play_utils.js +1 -1
- package/package.json +16 -18
- package/src/components/base/filtered_search/filtered_search.stories.js +1 -2
- package/src/components/base/filtered_search/filtered_search_suggestion_list.stories.js +1 -1
- package/src/components/base/form/form_combobox/form_combobox.stories.js +1 -2
- package/src/components/base/form/form_fields/form_fields.spec.js +16 -0
- package/src/components/base/form/form_fields/form_fields.stories.js +26 -3
- package/src/components/base/form/form_fields/form_fields.vue +12 -1
- package/src/components/base/sorting/sorting.stories.js +1 -2
- package/src/components/base/toast/toast.stories.js +1 -2
- package/src/components/base/token_selector/token_selector.stories.js +1 -2
- package/src/components/base/tooltip/tooltip.stories.js +1 -2
- package/src/components/experimental/duo/chat/duo_chat.spec.js +0 -2
- package/src/components/experimental/duo/chat/duo_chat.stories.js +0 -9
- package/src/components/experimental/duo/chat/duo_chat.vue +7 -9
- package/src/utils/play_utils.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
# [74.6.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v74.5.0...v74.6.0) (2024-02-14)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **GlFormFields:** Add prop for server field validations ([6c23b37](https://gitlab.com/gitlab-org/gitlab-ui/commit/6c23b37773d0944953d9068de2bcec00a0e74a8f))
|
|
7
|
+
|
|
8
|
+
# [74.5.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v74.4.0...v74.5.0) (2024-02-12)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **DuoChat:** Move global error to header ([7d026ef](https://gitlab.com/gitlab-org/gitlab-ui/commit/7d026effca6cf9fb9a352e09784da401936285c5))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
* **DuoChat:** Remove unused hero header ([30ab50c](https://gitlab.com/gitlab-org/gitlab-ui/commit/30ab50c30e72f10cca8600d21b5f71238a4dd2c4))
|
|
19
|
+
|
|
1
20
|
# [74.4.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v74.3.1...v74.4.0) (2024-02-09)
|
|
2
21
|
|
|
3
22
|
|
|
@@ -50,6 +50,16 @@ var script = {
|
|
|
50
50
|
formId: {
|
|
51
51
|
type: String,
|
|
52
52
|
required: true
|
|
53
|
+
},
|
|
54
|
+
/**
|
|
55
|
+
* Validation errors from the server. Generally passed to the component after making an API call.
|
|
56
|
+
*/
|
|
57
|
+
serverValidations: {
|
|
58
|
+
type: Object,
|
|
59
|
+
required: false,
|
|
60
|
+
default() {
|
|
61
|
+
return {};
|
|
62
|
+
}
|
|
53
63
|
}
|
|
54
64
|
},
|
|
55
65
|
data() {
|
|
@@ -64,7 +74,7 @@ var script = {
|
|
|
64
74
|
},
|
|
65
75
|
fieldValidationProps() {
|
|
66
76
|
return mapValues(this.fields, (_, fieldName) => {
|
|
67
|
-
const invalidFeedback = this.fieldValidations[fieldName] || '';
|
|
77
|
+
const invalidFeedback = this.serverValidations[fieldName] || this.fieldValidations[fieldName] || '';
|
|
68
78
|
return {
|
|
69
79
|
invalidFeedback,
|
|
70
80
|
state: invalidFeedback ? false : null
|
|
@@ -343,11 +343,11 @@ var script = {
|
|
|
343
343
|
const __vue_script__ = script;
|
|
344
344
|
|
|
345
345
|
/* template */
|
|
346
|
-
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return (!_vm.isHidden)?_c('aside',{ref:"drawer",staticClass:"markdown-code-block gl-drawer gl-drawer-default gl-max-h-full gl-bottom-0 gl-shadow-none gl-border-l gl-border-t duo-chat",attrs:{"id":"chat-component","role":"complementary","data-testid":"chat-component"},on:{"scroll":_vm.handleScrollingTrottled}},[(_vm.showHeader)?_c('header',{staticClass:"gl-drawer-header gl-drawer-header-sticky gl-z-index-200 gl-p-0! gl-border-b-0",attrs:{"data-testid":"chat-header"}},[_c('div',{staticClass:"drawer-title gl-display-flex gl-justify-content-start gl-align-items-center gl-p-5"},[_c('h3',{staticClass:"gl-my-0 gl-font-size-h2"},[_vm._v(_vm._s(_vm.title))]),_vm._v(" "),_c('gl-experiment-badge',{attrs:{"help-page-url":_vm.badgeHelpPageUrl,"type":_vm.badgeType,"container-id":"chat-component"}}),_vm._v(" "),_c('gl-button',{staticClass:"gl-p-0! gl-ml-auto",attrs:{"category":"tertiary","variant":"default","icon":"close","size":"small","data-testid":"chat-close-button","aria-label":_vm.$options.i18n.CHAT_CLOSE_LABEL},on:{"click":_vm.hideChat}})],1),_vm._v(" "),_c('gl-alert',{staticClass:"gl-text-center gl-border-t gl-p-4 gl-text-gray-700 gl-bg-gray-50 legal-warning gl-max-w-full",attrs:{"dismissible":false,"variant":"tip","show-icon":false,"role":"alert","data-testid":"chat-legal-warning"}},[_vm._v(_vm._s(_vm.$options.i18n.CHAT_LEGAL_GENERATED_BY_AI))]),_vm._v(" "),_vm._t("subheader")
|
|
346
|
+
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return (!_vm.isHidden)?_c('aside',{ref:"drawer",staticClass:"markdown-code-block gl-drawer gl-drawer-default gl-max-h-full gl-bottom-0 gl-shadow-none gl-border-l gl-border-t duo-chat",attrs:{"id":"chat-component","role":"complementary","data-testid":"chat-component"},on:{"scroll":_vm.handleScrollingTrottled}},[(_vm.showHeader)?_c('header',{staticClass:"gl-drawer-header gl-drawer-header-sticky gl-z-index-200 gl-p-0! gl-border-b-0",attrs:{"data-testid":"chat-header"}},[_c('div',{staticClass:"drawer-title gl-display-flex gl-justify-content-start gl-align-items-center gl-p-5"},[_c('h3',{staticClass:"gl-my-0 gl-font-size-h2"},[_vm._v(_vm._s(_vm.title))]),_vm._v(" "),_c('gl-experiment-badge',{attrs:{"help-page-url":_vm.badgeHelpPageUrl,"type":_vm.badgeType,"container-id":"chat-component"}}),_vm._v(" "),_c('gl-button',{staticClass:"gl-p-0! gl-ml-auto",attrs:{"category":"tertiary","variant":"default","icon":"close","size":"small","data-testid":"chat-close-button","aria-label":_vm.$options.i18n.CHAT_CLOSE_LABEL},on:{"click":_vm.hideChat}})],1),_vm._v(" "),_c('gl-alert',{staticClass:"gl-text-center gl-border-t gl-p-4 gl-text-gray-700 gl-bg-gray-50 legal-warning gl-max-w-full",attrs:{"dismissible":false,"variant":"tip","show-icon":false,"role":"alert","data-testid":"chat-legal-warning"}},[_vm._v(_vm._s(_vm.$options.i18n.CHAT_LEGAL_GENERATED_BY_AI))]),_vm._v(" "),_vm._t("subheader"),_vm._v(" "),(_vm.error)?_c('gl-alert',{key:"error",staticClass:"gl-pl-9!",attrs:{"dismissible":false,"variant":"danger","role":"alert","data-testid":"chat-error"}},[_c('span',{directives:[{name:"safe-html",rawName:"v-safe-html",value:(_vm.error),expression:"error"}]})]):_vm._e()],2):_vm._e(),_vm._v(" "),_c('div',{staticClass:"gl-drawer-body gl-display-flex gl-flex-direction-column"},[_c('section',{staticClass:"duo-chat-history gl-display-flex gl-flex-direction-column gl-justify-content-end gl-flex-grow-1 gl-border-b-0 gl-bg-gray-10"},[_c('transition-group',{staticClass:"gl-display-flex gl-flex-direction-column gl-justify-content-end",class:[
|
|
347
347
|
{
|
|
348
348
|
'gl-h-full': !_vm.hasMessages,
|
|
349
349
|
'gl-h-auto': _vm.hasMessages,
|
|
350
|
-
} ],attrs:{"tag":"div","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('div',{key:"empty-state",staticClass:"gl-display-flex gl-flex-grow-1 gl-mr-auto gl-ml-auto"},[_c('gl-empty-state',{staticClass:"gl-align-self-center",attrs:{"svg-path":_vm.$options.emptySvg,"svg-height":145,"title":_vm.emptyStateTitle,"description":_vm.emptyStateDescription}})],1),_vm._v(" "),_c('gl-duo-chat-predefined-prompts',{key:"predefined-prompts",attrs:{"prompts":_vm.predefinedPrompts},on:{"click":_vm.sendPredefinedPrompt}})]:_vm._e()],2),_vm._v(" "),_c('transition',{attrs:{"name":"loader"}},[(_vm.isLoading)?_c('gl-duo-chat-loader',{staticClass:"gl-px-0!",attrs:{"tool-name":_vm.toolName}}):_vm._e()],1),_vm._v(" "),_c('div',{ref:"anchor",staticClass:"scroll-anchor"})],1)]
|
|
350
|
+
} ],attrs:{"tag":"div","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('div',{key:"empty-state",staticClass:"gl-display-flex gl-flex-grow-1 gl-mr-auto gl-ml-auto"},[_c('gl-empty-state',{staticClass:"gl-align-self-center",attrs:{"svg-path":_vm.$options.emptySvg,"svg-height":145,"title":_vm.emptyStateTitle,"description":_vm.emptyStateDescription}})],1),_vm._v(" "),_c('gl-duo-chat-predefined-prompts',{key:"predefined-prompts",attrs:{"prompts":_vm.predefinedPrompts},on:{"click":_vm.sendPredefinedPrompt}})]:_vm._e()],2),_vm._v(" "),_c('transition',{attrs:{"name":"loader"}},[(_vm.isLoading)?_c('gl-duo-chat-loader',{staticClass:"gl-px-0!",attrs:{"tool-name":_vm.toolName}}):_vm._e()],1),_vm._v(" "),_c('div',{ref:"anchor",staticClass:"scroll-anchor"})],1)]),_vm._v(" "),(_vm.isChatAvailable)?_c('footer',{staticClass:"gl-drawer-footer gl-drawer-footer-sticky gl-p-5 gl-border-t gl-bg-gray-10",class:{ 'gl-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 [_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","aria-label":_vm.$options.i18n.CHAT_SUBMIT_LABEL,"disabled":_vm.isLoading}})]},proxy:true}],null,false,2232229068)},[_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,"disabled":_vm.isLoading,"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()};
|
|
351
351
|
var __vue_staticRenderFns__ = [];
|
|
352
352
|
|
|
353
353
|
/* style */
|
package/dist/tokens/js/tokens.js
CHANGED
package/dist/utils/play_utils.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gitlab/ui",
|
|
3
|
-
"version": "74.
|
|
3
|
+
"version": "74.6.0",
|
|
4
4
|
"description": "GitLab UI Components",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"markdownlint": "markdownlint '**/*.md' --ignore node_modules --ignore CHANGELOG.md",
|
|
62
62
|
"markdownlint:fix": "yarn markdownlint --fix",
|
|
63
63
|
"lint": "run-p prettier eslint stylelint markdownlint",
|
|
64
|
-
"lint:fix": "run-s
|
|
64
|
+
"lint:fix": "run-s eslint:fix prettier:fix stylelint:fix markdownlint:fix",
|
|
65
65
|
"generate:component": "plop",
|
|
66
66
|
"translations:collect": "make translations.json",
|
|
67
67
|
"tailwind-config-viewer": "tailwind-config-viewer -o"
|
|
@@ -101,26 +101,24 @@
|
|
|
101
101
|
"@cypress/grep": "^4.0.1",
|
|
102
102
|
"@gitlab/eslint-plugin": "19.4.0",
|
|
103
103
|
"@gitlab/fonts": "^1.3.0",
|
|
104
|
-
"@gitlab/stylelint-config": "
|
|
104
|
+
"@gitlab/stylelint-config": "6.1.0",
|
|
105
105
|
"@gitlab/svgs": "3.83.0",
|
|
106
106
|
"@rollup/plugin-commonjs": "^11.1.0",
|
|
107
107
|
"@rollup/plugin-node-resolve": "^7.1.3",
|
|
108
108
|
"@rollup/plugin-replace": "^2.3.2",
|
|
109
|
-
"@storybook/addon-a11y": "7.6.
|
|
110
|
-
"@storybook/addon-docs": "7.6.
|
|
111
|
-
"@storybook/addon-essentials": "7.6.
|
|
112
|
-
"@storybook/addon-interactions": "7.6.
|
|
113
|
-
"@storybook/addon-viewport": "7.6.
|
|
114
|
-
"@storybook/builder-webpack5": "7.6.
|
|
115
|
-
"@storybook/
|
|
109
|
+
"@storybook/addon-a11y": "7.6.14",
|
|
110
|
+
"@storybook/addon-docs": "7.6.14",
|
|
111
|
+
"@storybook/addon-essentials": "7.6.14",
|
|
112
|
+
"@storybook/addon-interactions": "7.6.14",
|
|
113
|
+
"@storybook/addon-viewport": "7.6.14",
|
|
114
|
+
"@storybook/builder-webpack5": "7.6.14",
|
|
115
|
+
"@storybook/test": "7.6.14",
|
|
116
116
|
"@storybook/test-runner": "0.16.0",
|
|
117
|
-
"@storybook/
|
|
118
|
-
"@storybook/
|
|
119
|
-
"@storybook/vue": "7.6.
|
|
120
|
-
"@storybook/
|
|
121
|
-
"@storybook/vue3": "7.6.
|
|
122
|
-
"@storybook/vue3-webpack5": "7.6.12",
|
|
123
|
-
"@types/jest": "^29.5.11",
|
|
117
|
+
"@storybook/theming": "7.6.14",
|
|
118
|
+
"@storybook/vue": "7.6.14",
|
|
119
|
+
"@storybook/vue-webpack5": "7.6.14",
|
|
120
|
+
"@storybook/vue3": "7.6.14",
|
|
121
|
+
"@storybook/vue3-webpack5": "7.6.14",
|
|
124
122
|
"@types/jest-image-snapshot": "^6.4.0",
|
|
125
123
|
"@vue/compat": "^3.2.40",
|
|
126
124
|
"@vue/compiler-sfc": "^3.2.40",
|
|
@@ -172,7 +170,7 @@
|
|
|
172
170
|
"sass-loader": "^10.2.0",
|
|
173
171
|
"sass-true": "^6.1.0",
|
|
174
172
|
"start-server-and-test": "^1.10.6",
|
|
175
|
-
"storybook": "7.6.
|
|
173
|
+
"storybook": "7.6.14",
|
|
176
174
|
"storybook-dark-mode": "3.0.3",
|
|
177
175
|
"style-dictionary": "^3.8.0",
|
|
178
176
|
"stylelint": "15.10.2",
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import last from 'lodash/last';
|
|
2
|
-
import { userEvent, within, waitFor } from '@storybook/
|
|
3
|
-
import { expect } from '@storybook/jest';
|
|
2
|
+
import { userEvent, within, waitFor, expect } from '@storybook/test';
|
|
4
3
|
import GlLoadingIcon from '../loading_icon/loading_icon.vue';
|
|
5
4
|
import GlIcon from '../icon/icon.vue';
|
|
6
5
|
import GlToken from '../token/token.vue';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { userEvent, within } from '@storybook/
|
|
1
|
+
import { userEvent, within } from '@storybook/test';
|
|
2
2
|
import GlFilteredSearchSuggestionList from './filtered_search_suggestion_list.vue';
|
|
3
3
|
import GlFilteredSearchSuggestion from './filtered_search_suggestion.vue';
|
|
4
4
|
import { provide } from './common_story_options';
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { userEvent, within, waitFor } from '@storybook/
|
|
2
|
-
import { expect } from '@storybook/jest';
|
|
1
|
+
import { userEvent, within, waitFor, expect } from '@storybook/test';
|
|
3
2
|
import { makeContainer } from '../../../../utils/story_decorators/container';
|
|
4
3
|
import { stringTokenList, labelText, objectTokenList, actionsList } from './constants';
|
|
5
4
|
import readme from './form_combobox.md';
|
|
@@ -345,6 +345,22 @@ describe('GlFormFields', () => {
|
|
|
345
345
|
});
|
|
346
346
|
}
|
|
347
347
|
);
|
|
348
|
+
|
|
349
|
+
describe('when there is a server validation message', () => {
|
|
350
|
+
beforeEach(async () => {
|
|
351
|
+
await submitForm();
|
|
352
|
+
|
|
353
|
+
wrapper.setProps({
|
|
354
|
+
serverValidations: { username: 'Username has already been taken.' },
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
it('renders error message', () => {
|
|
359
|
+
expect(
|
|
360
|
+
findFormGroupFromLabel(TEST_FIELDS.username.label).attributes('invalid-feedback')
|
|
361
|
+
).toBe('Username has already been taken.');
|
|
362
|
+
});
|
|
363
|
+
});
|
|
348
364
|
});
|
|
349
365
|
|
|
350
366
|
describe('with scoped slot', () => {
|
|
@@ -3,6 +3,7 @@ import omit from 'lodash/omit';
|
|
|
3
3
|
import GlModal from '../../modal/modal.vue';
|
|
4
4
|
import GlButton from '../../button/button.vue';
|
|
5
5
|
import GlListbox from '../../new_dropdowns/listbox/listbox.vue';
|
|
6
|
+
import { setStoryTimeout } from '../../../../utils/test_utils';
|
|
6
7
|
import GlFormFields from './form_fields.vue';
|
|
7
8
|
import readme from './form_fields.md';
|
|
8
9
|
import { required } from './validators';
|
|
@@ -49,6 +50,8 @@ const Template = () => ({
|
|
|
49
50
|
},
|
|
50
51
|
formValues: {},
|
|
51
52
|
testFormId: uniqueId('form_fields_story_'),
|
|
53
|
+
serverValidations: {},
|
|
54
|
+
loading: false,
|
|
52
55
|
};
|
|
53
56
|
},
|
|
54
57
|
computed: {
|
|
@@ -61,7 +64,27 @@ const Template = () => ({
|
|
|
61
64
|
},
|
|
62
65
|
},
|
|
63
66
|
methods: {
|
|
64
|
-
|
|
67
|
+
onInputField({ name }) {
|
|
68
|
+
this.$delete(this.serverValidations, name);
|
|
69
|
+
},
|
|
70
|
+
async onSubmit() {
|
|
71
|
+
this.loading = true;
|
|
72
|
+
|
|
73
|
+
// Simulate waiting for API request to resolve
|
|
74
|
+
await new Promise((resolve) => {
|
|
75
|
+
setStoryTimeout(resolve, 1000);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
this.loading = false;
|
|
79
|
+
|
|
80
|
+
// Manually checking field and validating for this example.
|
|
81
|
+
// In practice this error message would come from the API response.
|
|
82
|
+
if (this.formValues.USERNAME === 'FOO') {
|
|
83
|
+
this.$set(this.serverValidations, 'USERNAME', 'Username has already been taken.');
|
|
84
|
+
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
65
88
|
this.$refs.modal.show();
|
|
66
89
|
},
|
|
67
90
|
},
|
|
@@ -69,7 +92,7 @@ const Template = () => ({
|
|
|
69
92
|
<div>
|
|
70
93
|
<h3>Fields</h3>
|
|
71
94
|
<form :id="testFormId" @submit.prevent>
|
|
72
|
-
<gl-form-fields :fields="fields" v-model="formValues" :form-id="testFormId" @submit="onSubmit">
|
|
95
|
+
<gl-form-fields :fields="fields" v-model="formValues" :form-id="testFormId" :server-validations="serverValidations" @input-field="onInputField" @submit="onSubmit">
|
|
73
96
|
<template #input(custom)="{ id, value, input, blur }">
|
|
74
97
|
<button :id="id" @click="input(value + 1)" @blur="blur" type="button">{{value}}</button>
|
|
75
98
|
</template>
|
|
@@ -77,7 +100,7 @@ const Template = () => ({
|
|
|
77
100
|
<gl-listbox :id="id" :items="$options.ITEMS" :selected="value" @select="input" @hidden="blur" />
|
|
78
101
|
</template>
|
|
79
102
|
</gl-form-fields>
|
|
80
|
-
<gl-button type="submit" category="primary">Submit</gl-button>
|
|
103
|
+
<gl-button type="submit" category="primary" :loading="loading">Submit</gl-button>
|
|
81
104
|
</form>
|
|
82
105
|
<gl-modal ref="modal" modal-id="submission-modal" title="Form submission"><pre>{{ valuesJSON }}</pre></gl-modal>
|
|
83
106
|
</div>
|
|
@@ -51,6 +51,16 @@ export default {
|
|
|
51
51
|
type: String,
|
|
52
52
|
required: true,
|
|
53
53
|
},
|
|
54
|
+
/**
|
|
55
|
+
* Validation errors from the server. Generally passed to the component after making an API call.
|
|
56
|
+
*/
|
|
57
|
+
serverValidations: {
|
|
58
|
+
type: Object,
|
|
59
|
+
required: false,
|
|
60
|
+
default() {
|
|
61
|
+
return {};
|
|
62
|
+
},
|
|
63
|
+
},
|
|
54
64
|
},
|
|
55
65
|
data() {
|
|
56
66
|
return {
|
|
@@ -64,7 +74,8 @@ export default {
|
|
|
64
74
|
},
|
|
65
75
|
fieldValidationProps() {
|
|
66
76
|
return mapValues(this.fields, (_, fieldName) => {
|
|
67
|
-
const invalidFeedback =
|
|
77
|
+
const invalidFeedback =
|
|
78
|
+
this.serverValidations[fieldName] || this.fieldValidations[fieldName] || '';
|
|
68
79
|
|
|
69
80
|
return {
|
|
70
81
|
invalidFeedback,
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { userEvent, within, waitFor } from '@storybook/
|
|
2
|
-
import { expect } from '@storybook/jest';
|
|
1
|
+
import { userEvent, within, waitFor, expect } from '@storybook/test';
|
|
3
2
|
import { makeContainer } from '../../../utils/story_decorators/container';
|
|
4
3
|
import GlSorting from './sorting.vue';
|
|
5
4
|
import readme from './sorting.md';
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { userEvent, within, waitFor } from '@storybook/
|
|
2
|
-
import { expect } from '@storybook/jest';
|
|
1
|
+
import { userEvent, within, waitFor, expect } from '@storybook/test';
|
|
3
2
|
import Vue from 'vue';
|
|
4
3
|
import GlButton from '../button/button.vue';
|
|
5
4
|
import GlToast from './toast';
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { userEvent, within, waitFor } from '@storybook/
|
|
2
|
-
import { expect } from '@storybook/jest';
|
|
1
|
+
import { userEvent, within, waitFor, expect } from '@storybook/test';
|
|
3
2
|
import readme from './token_selector.md';
|
|
4
3
|
import GlTokenSelector from './token_selector.vue';
|
|
5
4
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { userEvent, within, waitFor } from '@storybook/
|
|
2
|
-
import { expect } from '@storybook/jest';
|
|
1
|
+
import { userEvent, within, waitFor, expect } from '@storybook/test';
|
|
3
2
|
import { GlTooltipDirective } from '../../../directives/tooltip';
|
|
4
3
|
import GlButton from '../button/button.vue';
|
|
5
4
|
import GlTooltip from './tooltip.vue';
|
|
@@ -191,8 +191,6 @@ describe('GlDuoChat', () => {
|
|
|
191
191
|
|
|
192
192
|
it.each`
|
|
193
193
|
slot | content | isChatAvailable
|
|
194
|
-
${'hero'} | ${slotContent} | ${true}
|
|
195
|
-
${'hero'} | ${slotContent} | ${false}
|
|
196
194
|
${'subheader'} | ${slotContent} | ${false}
|
|
197
195
|
${'subheader'} | ${slotContent} | ${true}
|
|
198
196
|
`(
|
|
@@ -215,15 +215,6 @@ export const Slots = (args, { argTypes }) => ({
|
|
|
215
215
|
:empty-state-title="emptyStateTitle"
|
|
216
216
|
:empty-state-description="emptyStateDescription"
|
|
217
217
|
:chat-prompt-placeholder="chatPromptPlaceholder">
|
|
218
|
-
|
|
219
|
-
<template #hero>
|
|
220
|
-
<pre class="code-block rounded code highlight gl-border-b gl-rounded-0! gl-mb-0 gl-overflow-y-auto solarized-light" style="max-height: 20rem; overflow-y: auto;">
|
|
221
|
-
if (firstUserPromptIndex >= 0 && lastUserPromptIndex > firstUserPromptIndex) {
|
|
222
|
-
messages.splice(firstUserPromptIndex, 1);
|
|
223
|
-
return truncateChatPrompt(messages);
|
|
224
|
-
}
|
|
225
|
-
</pre>
|
|
226
|
-
</template>
|
|
227
218
|
<template #subheader>
|
|
228
219
|
<gl-alert
|
|
229
220
|
:dismissible="false"
|
|
@@ -401,24 +401,22 @@ export default {
|
|
|
401
401
|
@slot Subheader to be rendered right after the title. It is sticky and stays on top of the chat no matter the number of messages.
|
|
402
402
|
-->
|
|
403
403
|
<slot name="subheader"></slot>
|
|
404
|
-
</header>
|
|
405
|
-
|
|
406
|
-
<div class="gl-drawer-body gl-display-flex gl-flex-direction-column">
|
|
407
|
-
<!-- @slot 'Hero' information to be rendered at the top of the chat before any message. It gets pushed away from the view by incomming messages
|
|
408
|
-
-->
|
|
409
|
-
<slot name="hero"></slot>
|
|
410
404
|
|
|
405
|
+
<!-- Ensure that the global error is not scrolled away -->
|
|
411
406
|
<gl-alert
|
|
412
407
|
v-if="error"
|
|
413
408
|
key="error"
|
|
414
409
|
:dismissible="false"
|
|
415
410
|
variant="danger"
|
|
416
|
-
class="gl-
|
|
411
|
+
class="gl-pl-9!"
|
|
417
412
|
role="alert"
|
|
418
413
|
data-testid="chat-error"
|
|
419
|
-
|
|
420
|
-
|
|
414
|
+
>
|
|
415
|
+
<span v-safe-html="error"></span>
|
|
416
|
+
</gl-alert>
|
|
417
|
+
</header>
|
|
421
418
|
|
|
419
|
+
<div class="gl-drawer-body gl-display-flex gl-flex-direction-column">
|
|
422
420
|
<section
|
|
423
421
|
class="duo-chat-history gl-display-flex gl-flex-direction-column gl-justify-content-end gl-flex-grow-1 gl-border-b-0 gl-bg-gray-10"
|
|
424
422
|
>
|
package/src/utils/play_utils.js
CHANGED