@gitlab/ui 60.2.0 → 61.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.
- package/CHANGELOG.md +31 -0
- package/dist/components/base/banner/banner.js +11 -1
- package/dist/components/base/filtered_search/filtered_search.js +1 -4
- package/dist/components/base/filtered_search/filtered_search_suggestion.js +1 -1
- package/dist/components/base/filtered_search/filtered_search_suggestion_list.js +30 -16
- package/dist/components/base/filtered_search/filtered_search_term.js +4 -6
- package/dist/components/base/filtered_search/filtered_search_token.js +16 -17
- package/dist/components/base/filtered_search/filtered_search_token_segment.js +23 -14
- package/dist/components/base/filtered_search/filtered_search_utils.js +78 -1
- package/dist/utils/number_utils.js +22 -1
- package/package.json +1 -1
- package/src/components/base/banner/banner.vue +11 -9
- package/src/components/base/filtered_search/__snapshots__/filtered_search_term.spec.js.snap +2 -0
- package/src/components/base/filtered_search/filtered_search.md +5 -3
- package/src/components/base/filtered_search/filtered_search.stories.js +8 -5
- package/src/components/base/filtered_search/filtered_search.vue +1 -11
- package/src/components/base/filtered_search/filtered_search_suggestion.md +8 -2
- package/src/components/base/filtered_search/filtered_search_suggestion.vue +1 -0
- package/src/components/base/filtered_search/filtered_search_suggestion_list.spec.js +61 -64
- package/src/components/base/filtered_search/filtered_search_suggestion_list.vue +39 -20
- package/src/components/base/filtered_search/filtered_search_term.spec.js +11 -28
- package/src/components/base/filtered_search/filtered_search_term.vue +6 -17
- package/src/components/base/filtered_search/filtered_search_token.spec.js +3 -22
- package/src/components/base/filtered_search/filtered_search_token.vue +8 -16
- package/src/components/base/filtered_search/filtered_search_token_segment.spec.js +18 -1
- package/src/components/base/filtered_search/filtered_search_token_segment.stories.js +9 -0
- package/src/components/base/filtered_search/filtered_search_token_segment.vue +35 -12
- package/src/components/base/filtered_search/filtered_search_utils.js +69 -0
- package/src/components/base/filtered_search/filtered_search_utils.spec.js +32 -1
- package/src/utils/number_utils.js +21 -0
- package/src/utils/number_utils.spec.js +42 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,34 @@
|
|
|
1
|
+
# [61.1.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v61.0.0...v61.1.0) (2023-04-13)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **Banner:** Use CloseButton ([f4ddd66](https://gitlab.com/gitlab-org/gitlab-ui/commit/f4ddd66771f46607ff657f2bf4bc268f666c51ec))
|
|
7
|
+
* **Banner:** Use CloseButton ([d173aed](https://gitlab.com/gitlab-org/gitlab-ui/commit/d173aed03b4400196aa9711e118b57047e707a14))
|
|
8
|
+
|
|
9
|
+
# [61.0.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v60.2.0...v61.0.0) (2023-04-12)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
* **GlFilteredSearch:** Don't prevent tabbing past component ([27cdbf3](https://gitlab.com/gitlab-org/gitlab-ui/commit/27cdbf3d67cebebc9b6a2177d3ed664ac44ddee7))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* **GlFilteredSearch:** Improve option interactions ([d2ada9d](https://gitlab.com/gitlab-org/gitlab-ui/commit/d2ada9d7c179d255e4845e7b237740d1471166b4))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### BREAKING CHANGES
|
|
23
|
+
|
|
24
|
+
* **GlFilteredSearch:** `GlFilteredSearch`/`GlFilteredSearchTerm`'s `title`
|
|
25
|
+
slot and `GlFilteredSearchToken`'s `title-option` slot have been
|
|
26
|
+
removed. Similar functionality is available by setting the
|
|
27
|
+
`optionComponent` property on the given token object passed to
|
|
28
|
+
`GlFilteredSearch`'s `available-tokens` prop. The component will be
|
|
29
|
+
given an `option` prop, which will be the option object representing the
|
|
30
|
+
token.
|
|
31
|
+
|
|
1
32
|
# [60.2.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v60.1.0...v60.2.0) (2023-04-12)
|
|
2
33
|
|
|
3
34
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { bannerVariants } from '../../../utils/constants';
|
|
2
|
+
import CloseButton from '../../shared_components/close_button/close_button';
|
|
2
3
|
import GlButton from '../button/button';
|
|
3
4
|
import GlCard from '../card/card';
|
|
4
5
|
import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
|
|
@@ -6,6 +7,7 @@ import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
|
|
|
6
7
|
var script = {
|
|
7
8
|
name: 'GlBanner',
|
|
8
9
|
components: {
|
|
10
|
+
CloseButton,
|
|
9
11
|
GlButton,
|
|
10
12
|
GlCard
|
|
11
13
|
},
|
|
@@ -51,6 +53,14 @@ var script = {
|
|
|
51
53
|
return bannerVariants.includes(value);
|
|
52
54
|
}
|
|
53
55
|
},
|
|
56
|
+
/**
|
|
57
|
+
* Dismiss button's aria-label.
|
|
58
|
+
*/
|
|
59
|
+
dismissLabel: {
|
|
60
|
+
type: String,
|
|
61
|
+
required: false,
|
|
62
|
+
default: 'Dismiss'
|
|
63
|
+
},
|
|
54
64
|
/**
|
|
55
65
|
* Removes the border for banners embedded in content.
|
|
56
66
|
*/
|
|
@@ -91,7 +101,7 @@ var script = {
|
|
|
91
101
|
const __vue_script__ = script;
|
|
92
102
|
|
|
93
103
|
/* template */
|
|
94
|
-
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('gl-card',{staticClass:"gl-px-8 gl-py-6 gl-line-height-20",class:{ 'gl-banner-introduction': _vm.isIntroducing, 'gl-border-none!': _vm.embedded },attrs:{"body-class":"gl-display-flex gl-p-0!"}},[(_vm.svgPath)?_c('div',{staticClass:"gl-banner-illustration"},[_c('img',{attrs:{"src":_vm.svgPath,"alt":""}})]):_vm._e(),_vm._v(" "),_c('div',{staticClass:"gl-banner-content"},[_c('h2',{staticClass:"gl-banner-title"},[_vm._v(_vm._s(_vm.title))]),_vm._v(" "),_vm._t("default"),_vm._v(" "),_c('gl-button',{attrs:{"variant":"confirm","category":"primary","data-testid":"gl-banner-primary-button","href":_vm.buttonLink},on:{"click":_vm.primaryButtonClicked}},[_vm._v(_vm._s(_vm.buttonText))]),_vm._v(" "),_vm._t("actions")],2),_vm._v(" "),_c('
|
|
104
|
+
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('gl-card',{staticClass:"gl-px-8 gl-py-6 gl-line-height-20",class:{ 'gl-banner-introduction': _vm.isIntroducing, 'gl-border-none!': _vm.embedded },attrs:{"body-class":"gl-display-flex gl-p-0!"}},[(_vm.svgPath)?_c('div',{staticClass:"gl-banner-illustration"},[_c('img',{attrs:{"src":_vm.svgPath,"alt":""}})]):_vm._e(),_vm._v(" "),_c('div',{staticClass:"gl-banner-content"},[_c('h2',{staticClass:"gl-banner-title"},[_vm._v(_vm._s(_vm.title))]),_vm._v(" "),_vm._t("default"),_vm._v(" "),_c('gl-button',{attrs:{"variant":"confirm","category":"primary","data-testid":"gl-banner-primary-button","href":_vm.buttonLink},on:{"click":_vm.primaryButtonClicked}},[_vm._v(_vm._s(_vm.buttonText))]),_vm._v(" "),_vm._t("actions")],2),_vm._v(" "),_c('close-button',{staticClass:"gl-banner-close",attrs:{"label":_vm.dismissLabel},on:{"click":_vm.handleClose}})],1)};
|
|
95
105
|
var __vue_staticRenderFns__ = [];
|
|
96
106
|
|
|
97
107
|
/* style */
|
|
@@ -323,9 +323,6 @@ var script = {
|
|
|
323
323
|
* @property {array} tokens
|
|
324
324
|
*/
|
|
325
325
|
this.$emit('submit', normalizeTokens(cloneDeep(this.tokens)));
|
|
326
|
-
},
|
|
327
|
-
hasTitleSlot() {
|
|
328
|
-
return Boolean(this.$scopedSlots.title);
|
|
329
326
|
}
|
|
330
327
|
}
|
|
331
328
|
};
|
|
@@ -334,7 +331,7 @@ var script = {
|
|
|
334
331
|
const __vue_script__ = script;
|
|
335
332
|
|
|
336
333
|
/* template */
|
|
337
|
-
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('gl-search-box-by-click',_vm._b({attrs:{"value":_vm.tokens,"history-items":_vm.historyItems,"clearable":_vm.hasValue,"search-button-attributes":_vm.searchButtonAttributes,"disabled":_vm.viewOnly,"data-testid":"filtered-search-input"},on:{"submit":_vm.submit,"input":_vm.applyNewValue,"history-item-selected":function($event){return _vm.$emit('history-item-selected', $event)},"clear":function($event){return _vm.$emit('clear')},"clear-history":function($event){return _vm.$emit('clear-history')}},scopedSlots:_vm._u([{key:"history-item",fn:function(slotScope){return [_vm._t("history-item",null,null,slotScope)]}},{key:"input",fn:function(){return [_c('div',{staticClass:"gl-filtered-search-scrollable",class:{ 'gl-bg-gray-10! gl-inset-border-1-gray-100!': _vm.viewOnly }},_vm._l((_vm.tokens),function(token,idx){return _c(_vm.getTokenComponent(token.type),{key:token.id,ref:"tokens",refInFor:true,tag:"component",class:_vm.getTokenClassList(idx),attrs:{"config":_vm.getTokenEntry(token.type),"active":_vm.activeTokenIdx === idx,"cursor-position":_vm.intendedCursorPosition,"available-tokens":_vm.currentAvailableTokens,"current-value":_vm.tokens,"index":idx,"placeholder":_vm.termPlaceholder,"show-friendly-text":_vm.showFriendlyText,"search-input-attributes":_vm.searchInputAttributes,"view-only":_vm.viewOnly,"is-last-token":_vm.isLastToken(idx)},on:{"activate":function($event){return _vm.activate(idx)},"deactivate":function($event){return _vm.deactivate(token)},"destroy":function($event){return _vm.destroyToken(idx, $event)},"replace":function($event){return _vm.replaceToken(idx, $event)},"complete":_vm.completeToken,"submit":_vm.submit,"split":function($event){return _vm.createTokens(idx, $event)},"previous":_vm.activatePreviousToken,"next":_vm.activateNextToken},
|
|
334
|
+
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('gl-search-box-by-click',_vm._b({attrs:{"value":_vm.tokens,"history-items":_vm.historyItems,"clearable":_vm.hasValue,"search-button-attributes":_vm.searchButtonAttributes,"disabled":_vm.viewOnly,"data-testid":"filtered-search-input"},on:{"submit":_vm.submit,"input":_vm.applyNewValue,"history-item-selected":function($event){return _vm.$emit('history-item-selected', $event)},"clear":function($event){return _vm.$emit('clear')},"clear-history":function($event){return _vm.$emit('clear-history')}},scopedSlots:_vm._u([{key:"history-item",fn:function(slotScope){return [_vm._t("history-item",null,null,slotScope)]}},{key:"input",fn:function(){return [_c('div',{staticClass:"gl-filtered-search-scrollable",class:{ 'gl-bg-gray-10! gl-inset-border-1-gray-100!': _vm.viewOnly }},_vm._l((_vm.tokens),function(token,idx){return _c(_vm.getTokenComponent(token.type),{key:token.id,ref:"tokens",refInFor:true,tag:"component",class:_vm.getTokenClassList(idx),attrs:{"config":_vm.getTokenEntry(token.type),"active":_vm.activeTokenIdx === idx,"cursor-position":_vm.intendedCursorPosition,"available-tokens":_vm.currentAvailableTokens,"current-value":_vm.tokens,"index":idx,"placeholder":_vm.termPlaceholder,"show-friendly-text":_vm.showFriendlyText,"search-input-attributes":_vm.searchInputAttributes,"view-only":_vm.viewOnly,"is-last-token":_vm.isLastToken(idx)},on:{"activate":function($event){return _vm.activate(idx)},"deactivate":function($event){return _vm.deactivate(token)},"destroy":function($event){return _vm.destroyToken(idx, $event)},"replace":function($event){return _vm.replaceToken(idx, $event)},"complete":_vm.completeToken,"submit":_vm.submit,"split":function($event){return _vm.createTokens(idx, $event)},"previous":_vm.activatePreviousToken,"next":_vm.activateNextToken},model:{value:(token.value),callback:function ($$v) {_vm.$set(token, "value", $$v);},expression:"token.value"}})}),1),_vm._v(" "),_c('portal-target',{key:_vm.activeTokenIdx,ref:"menu",style:(_vm.suggestionsStyle),attrs:{"name":_vm.portalName,"slim":""}})]},proxy:true}],null,true)},'gl-search-box-by-click',_vm.$attrs,false))};
|
|
338
335
|
var __vue_staticRenderFns__ = [];
|
|
339
336
|
|
|
340
337
|
/* style */
|
|
@@ -54,7 +54,7 @@ var script = {
|
|
|
54
54
|
const __vue_script__ = script;
|
|
55
55
|
|
|
56
56
|
/* template */
|
|
57
|
-
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('gl-dropdown-item',_vm._b({ref:"item",staticClass:"gl-filtered-search-suggestion",class:{ 'gl-filtered-search-suggestion-active': _vm.isActive },attrs:{"data-testid":"filtered-search-suggestion","href":"#"},nativeOn:{"mousedown":function($event){$event.preventDefault();return _vm.emitValue.apply(null, arguments)}}},'gl-dropdown-item',_vm.$attrs,false),[_vm._t("default")],2)};
|
|
57
|
+
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('gl-dropdown-item',_vm._b({ref:"item",staticClass:"gl-filtered-search-suggestion",class:{ 'gl-filtered-search-suggestion-active': _vm.isActive },attrs:{"data-testid":"filtered-search-suggestion","tabindex":"-1","href":"#"},nativeOn:{"mousedown":function($event){$event.preventDefault();return _vm.emitValue.apply(null, arguments)}}},'gl-dropdown-item',_vm.$attrs,false),[_vm._t("default")],2)};
|
|
58
58
|
var __vue_staticRenderFns__ = [];
|
|
59
59
|
|
|
60
60
|
/* style */
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { stepIndexAndWrap } from './filtered_search_utils';
|
|
1
2
|
import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
|
|
2
3
|
|
|
4
|
+
const DEFER_TO_INITIAL_VALUE = -1;
|
|
5
|
+
const NO_ACTIVE_ITEM = -2;
|
|
3
6
|
var script = {
|
|
4
7
|
name: 'GlFilteredSearchSuggestionList',
|
|
5
8
|
inject: ['suggestionsListClass'],
|
|
@@ -20,21 +23,29 @@ var script = {
|
|
|
20
23
|
},
|
|
21
24
|
data() {
|
|
22
25
|
return {
|
|
23
|
-
activeIdx:
|
|
26
|
+
activeIdx: DEFER_TO_INITIAL_VALUE,
|
|
24
27
|
registeredItems: []
|
|
25
28
|
};
|
|
26
29
|
},
|
|
27
30
|
computed: {
|
|
31
|
+
initialActiveIdx() {
|
|
32
|
+
return this.registeredItems.findIndex(item => this.valuesMatch(item.value, this.initialValue));
|
|
33
|
+
},
|
|
34
|
+
initialActiveItem() {
|
|
35
|
+
return this.registeredItems[this.initialActiveIdx];
|
|
36
|
+
},
|
|
28
37
|
activeItem() {
|
|
29
|
-
|
|
38
|
+
if (this.activeIdx === NO_ACTIVE_ITEM) return null;
|
|
39
|
+
if (this.activeIdx === DEFER_TO_INITIAL_VALUE) return this.initialActiveItem;
|
|
40
|
+
return this.registeredItems[this.activeIdx];
|
|
30
41
|
},
|
|
31
42
|
listClasses() {
|
|
32
43
|
return [this.suggestionsListClass(), 'dropdown-menu gl-filtered-search-suggestion-list'];
|
|
33
44
|
}
|
|
34
45
|
},
|
|
35
46
|
watch: {
|
|
36
|
-
initialValue(
|
|
37
|
-
this.activeIdx =
|
|
47
|
+
initialValue() {
|
|
48
|
+
this.activeIdx = DEFER_TO_INITIAL_VALUE;
|
|
38
49
|
}
|
|
39
50
|
},
|
|
40
51
|
methods: {
|
|
@@ -44,31 +55,34 @@ var script = {
|
|
|
44
55
|
},
|
|
45
56
|
register(item) {
|
|
46
57
|
this.registeredItems.push(item);
|
|
47
|
-
if (this.valuesMatch(item.value, this.initialValue)) {
|
|
48
|
-
this.activeIdx = this.registeredItems.length - 1;
|
|
49
|
-
}
|
|
50
58
|
},
|
|
51
59
|
unregister(item) {
|
|
52
60
|
const idx = this.registeredItems.indexOf(item);
|
|
53
61
|
if (idx !== -1) {
|
|
54
62
|
this.registeredItems.splice(idx, 1);
|
|
55
63
|
if (idx === this.activeIdx) {
|
|
56
|
-
this.activeIdx =
|
|
64
|
+
this.activeIdx = DEFER_TO_INITIAL_VALUE;
|
|
57
65
|
}
|
|
58
66
|
}
|
|
59
67
|
},
|
|
60
68
|
nextItem() {
|
|
61
|
-
|
|
62
|
-
this.activeIdx += 1;
|
|
63
|
-
} else {
|
|
64
|
-
this.activeIdx = 0;
|
|
65
|
-
}
|
|
69
|
+
this.stepItem(1, this.registeredItems.length - 1);
|
|
66
70
|
},
|
|
67
71
|
prevItem() {
|
|
68
|
-
|
|
69
|
-
|
|
72
|
+
this.stepItem(-1, 0);
|
|
73
|
+
},
|
|
74
|
+
stepItem(direction, endIdx) {
|
|
75
|
+
if (this.activeIdx === endIdx || this.activeIdx === DEFER_TO_INITIAL_VALUE && this.initialActiveIdx === endIdx) {
|
|
76
|
+
// The user wants to move past the end of the list, so ensure nothing is selected.
|
|
77
|
+
this.activeIdx = NO_ACTIVE_ITEM;
|
|
70
78
|
} else {
|
|
71
|
-
|
|
79
|
+
const index = this.activeIdx === DEFER_TO_INITIAL_VALUE ?
|
|
80
|
+
// Currently active item is set by initialValue (i.e., text input matching),
|
|
81
|
+
// so step relative to that.
|
|
82
|
+
this.initialActiveIdx :
|
|
83
|
+
// Otherwise, step relative to the explicitly (via up/down arrows) activated item.
|
|
84
|
+
this.activeIdx;
|
|
85
|
+
this.activeIdx = stepIndexAndWrap(index, direction, this.registeredItems.length);
|
|
72
86
|
}
|
|
73
87
|
},
|
|
74
88
|
getValue() {
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import GlFilteredSearchSuggestion from './filtered_search_suggestion';
|
|
2
1
|
import GlFilteredSearchTokenSegment from './filtered_search_token_segment';
|
|
3
|
-
import { INTENT_ACTIVATE_PREVIOUS } from './filtered_search_utils';
|
|
2
|
+
import { match, tokenToOption, INTENT_ACTIVATE_PREVIOUS } from './filtered_search_utils';
|
|
4
3
|
import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
|
|
5
4
|
|
|
6
5
|
var script = {
|
|
7
6
|
name: 'GlFilteredSearchTerm',
|
|
8
7
|
components: {
|
|
9
|
-
GlFilteredSearchTokenSegment
|
|
10
|
-
GlFilteredSearchSuggestion
|
|
8
|
+
GlFilteredSearchTokenSegment
|
|
11
9
|
},
|
|
12
10
|
inheritAttrs: false,
|
|
13
11
|
props: {
|
|
@@ -79,7 +77,7 @@ var script = {
|
|
|
79
77
|
},
|
|
80
78
|
computed: {
|
|
81
79
|
suggestedTokens() {
|
|
82
|
-
return this.availableTokens.filter(
|
|
80
|
+
return this.availableTokens.filter(token => match(token.title, this.value.data)).map(tokenToOption);
|
|
83
81
|
},
|
|
84
82
|
internalValue: {
|
|
85
83
|
get() {
|
|
@@ -118,7 +116,7 @@ var script = {
|
|
|
118
116
|
const __vue_script__ = script;
|
|
119
117
|
|
|
120
118
|
/* template */
|
|
121
|
-
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"gl-h-auto gl-filtered-search-term",attrs:{"data-testid":"filtered-search-term"}},[_c('gl-filtered-search-token-segment',{ref:"segment",staticClass:"gl-filtered-search-term-token",attrs:{"active":_vm.active,"cursor-position":_vm.cursorPosition,"search-input-attributes":_vm.searchInputAttributes,"is-last-token":_vm.isLastToken,"current-value":_vm.currentValue,"view-only":_vm.viewOnly},on:{"activate":function($event){return _vm.$emit('activate')},"deactivate":function($event){return _vm.$emit('deactivate')},"complete":function($event){return _vm.$emit('replace', { type: $event })},"backspace":_vm.onBackspace,"submit":function($event){return _vm.$emit('submit')},"split":function($event){return _vm.$emit('split', $event)},"previous":function($event){return _vm.$emit('previous')},"next":function($event){return _vm.$emit('next')}},scopedSlots:_vm._u([{key:"
|
|
119
|
+
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"gl-h-auto gl-filtered-search-term",attrs:{"data-testid":"filtered-search-term"}},[_c('gl-filtered-search-token-segment',{ref:"segment",staticClass:"gl-filtered-search-term-token",attrs:{"is-term":"","active":_vm.active,"cursor-position":_vm.cursorPosition,"search-input-attributes":_vm.searchInputAttributes,"is-last-token":_vm.isLastToken,"current-value":_vm.currentValue,"view-only":_vm.viewOnly,"options":_vm.suggestedTokens},on:{"activate":function($event){return _vm.$emit('activate')},"deactivate":function($event){return _vm.$emit('deactivate')},"complete":function($event){return _vm.$emit('replace', { type: $event })},"backspace":_vm.onBackspace,"submit":function($event){return _vm.$emit('submit')},"split":function($event){return _vm.$emit('split', $event)},"previous":function($event){return _vm.$emit('previous')},"next":function($event){return _vm.$emit('next')}},scopedSlots:_vm._u([{key:"view",fn:function(){return [(_vm.placeholder)?_c('input',_vm._b({staticClass:"gl-filtered-search-term-input",class:{ 'gl-bg-gray-10': _vm.viewOnly },attrs:{"placeholder":_vm.placeholder,"aria-label":_vm.placeholder,"readonly":_vm.viewOnly,"data-testid":"filtered-search-term-input"},on:{"focusin":function($event){return _vm.$emit('activate')},"focusout":function($event){return _vm.$emit('deactivate')}}},'input',_vm.searchInputAttributes,false)):[_vm._v(_vm._s(_vm.value.data))]]},proxy:true}]),model:{value:(_vm.internalValue),callback:function ($$v) {_vm.internalValue=$$v;},expression:"internalValue"}})],1)};
|
|
122
120
|
var __vue_staticRenderFns__ = [];
|
|
123
121
|
|
|
124
122
|
/* style */
|
|
@@ -2,7 +2,7 @@ import cloneDeep from 'lodash/cloneDeep';
|
|
|
2
2
|
import { COMMA } from '../../../utils/constants';
|
|
3
3
|
import GlToken from '../token/token';
|
|
4
4
|
import GlFilteredSearchTokenSegment from './filtered_search_token_segment';
|
|
5
|
-
import { createTerm } from './filtered_search_utils';
|
|
5
|
+
import { tokenToOption, createTerm } from './filtered_search_utils';
|
|
6
6
|
import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
|
|
7
7
|
|
|
8
8
|
const SEGMENT_TITLE = 'TYPE';
|
|
@@ -12,7 +12,7 @@ const TOKEN_CLOSE_SELECTOR = '.gl-token-close';
|
|
|
12
12
|
const DEFAULT_OPERATORS = [{
|
|
13
13
|
value: '=',
|
|
14
14
|
description: 'is',
|
|
15
|
-
default:
|
|
15
|
+
default: true
|
|
16
16
|
}, {
|
|
17
17
|
value: '!=',
|
|
18
18
|
description: 'is not'
|
|
@@ -99,10 +99,7 @@ var script = {
|
|
|
99
99
|
return this.tokenValue.data !== '' || this.isSegmentActive(SEGMENT_DATA);
|
|
100
100
|
},
|
|
101
101
|
availableTokensWithSelf() {
|
|
102
|
-
return [this.config, ...this.availableTokens.filter(
|
|
103
|
-
...t,
|
|
104
|
-
value: t.title
|
|
105
|
-
}));
|
|
102
|
+
return [this.config, ...this.availableTokens.filter(token => token !== this.config)].map(tokenToOption);
|
|
106
103
|
},
|
|
107
104
|
operatorDescription() {
|
|
108
105
|
const operator = this.operators.find(op => op.value === this.tokenValue.operator);
|
|
@@ -210,8 +207,13 @@ var script = {
|
|
|
210
207
|
this.$emit('replace', createTerm(this.config.title));
|
|
211
208
|
}
|
|
212
209
|
},
|
|
213
|
-
replaceToken(
|
|
214
|
-
const newTokenConfig = this.availableTokens.find(
|
|
210
|
+
replaceToken(newType) {
|
|
211
|
+
const newTokenConfig = this.availableTokens.find(_ref => {
|
|
212
|
+
let {
|
|
213
|
+
type
|
|
214
|
+
} = _ref;
|
|
215
|
+
return type === newType;
|
|
216
|
+
});
|
|
215
217
|
if (newTokenConfig === this.config) {
|
|
216
218
|
this.$nextTick(() => {
|
|
217
219
|
/**
|
|
@@ -233,12 +235,12 @@ var script = {
|
|
|
233
235
|
});
|
|
234
236
|
}
|
|
235
237
|
},
|
|
236
|
-
handleOperatorKeydown(evt,
|
|
238
|
+
handleOperatorKeydown(evt, _ref2) {
|
|
237
239
|
let {
|
|
238
240
|
inputValue,
|
|
239
241
|
suggestedValue,
|
|
240
242
|
applySuggestion
|
|
241
|
-
} =
|
|
243
|
+
} = _ref2;
|
|
242
244
|
const {
|
|
243
245
|
key
|
|
244
246
|
} = evt;
|
|
@@ -247,10 +249,10 @@ var script = {
|
|
|
247
249
|
return;
|
|
248
250
|
}
|
|
249
251
|
const potentialValue = `${inputValue}${key}`;
|
|
250
|
-
if (key.length === 1 && !this.operators.find(
|
|
252
|
+
if (key.length === 1 && !this.operators.find(_ref3 => {
|
|
251
253
|
let {
|
|
252
254
|
value
|
|
253
|
-
} =
|
|
255
|
+
} = _ref3;
|
|
254
256
|
return value.startsWith(potentialValue);
|
|
255
257
|
})) {
|
|
256
258
|
if (this.tokenValue.data === '') {
|
|
@@ -305,9 +307,6 @@ var script = {
|
|
|
305
307
|
event.stopPropagation();
|
|
306
308
|
this.$emit('destroy');
|
|
307
309
|
}
|
|
308
|
-
},
|
|
309
|
-
hasTitleOptionSlot() {
|
|
310
|
-
return Boolean(this.$scopedSlots['title-option']);
|
|
311
310
|
}
|
|
312
311
|
}
|
|
313
312
|
};
|
|
@@ -322,9 +321,9 @@ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=
|
|
|
322
321
|
'gl-cursor-default': _vm.viewOnly,
|
|
323
322
|
},attrs:{"data-testid":"filtered-search-token"}},[_c('gl-filtered-search-token-segment',{key:"title-segment",attrs:{"value":_vm.config.title,"active":_vm.isSegmentActive(_vm.$options.segments.SEGMENT_TITLE),"cursor-position":_vm.intendedCursorPosition,"options":_vm.availableTokensWithSelf,"view-only":_vm.viewOnly},on:{"activate":function($event){return _vm.activateSegment(_vm.$options.segments.SEGMENT_TITLE)},"deactivate":function($event){return _vm.$emit('deactivate')},"complete":_vm.replaceToken,"backspace":function($event){return _vm.$emit('destroy')},"submit":function($event){return _vm.$emit('submit')},"previous":function($event){return _vm.$emit('previous')},"next":_vm.activateNextOperatorSegment},scopedSlots:_vm._u([{key:"view",fn:function(ref){
|
|
324
323
|
var inputValue = ref.inputValue;
|
|
325
|
-
return [_c('gl-token',{staticClass:"gl-filtered-search-token-type",class:_vm.getAdditionalSegmentClasses(_vm.$options.segments.SEGMENT_TITLE),attrs:{"view-only":""}},[_vm._v("\n "+_vm._s(inputValue)+"\n ")])]}}
|
|
324
|
+
return [_c('gl-token',{staticClass:"gl-filtered-search-token-type",class:_vm.getAdditionalSegmentClasses(_vm.$options.segments.SEGMENT_TITLE),attrs:{"view-only":""}},[_vm._v("\n "+_vm._s(inputValue)+"\n ")])]}}])}),_vm._v(" "),_c('gl-filtered-search-token-segment',{key:"operator-segment",attrs:{"active":_vm.isSegmentActive(_vm.$options.segments.SEGMENT_OPERATOR),"cursor-position":_vm.intendedCursorPosition,"options":_vm.operators,"option-text-field":"value","custom-input-keydown-handler":_vm.handleOperatorKeydown,"view-only":_vm.viewOnly},on:{"activate":function($event){return _vm.activateSegment(_vm.$options.segments.SEGMENT_OPERATOR)},"backspace":_vm.replaceWithTermIfEmpty,"complete":function($event){return _vm.activateSegment(_vm.$options.segments.SEGMENT_DATA)},"deactivate":function($event){return _vm.$emit('deactivate')},"previous":_vm.activatePreviousTitleSegment,"next":_vm.activateNextDataSegment},scopedSlots:_vm._u([{key:"view",fn:function(){return [_c('gl-token',{staticClass:"gl-filtered-search-token-operator",class:_vm.getAdditionalSegmentClasses(_vm.$options.segments.SEGMENT_OPERATOR),attrs:{"variant":"search-value","view-only":""}},[_vm._v("\n "+_vm._s(_vm.operatorDescription)+"\n ")])]},proxy:true},{key:"option",fn:function(ref){
|
|
326
325
|
var option = ref.option;
|
|
327
|
-
return [_c('div',{staticClass:"gl-display-flex"},[_vm._v("\n "+_vm._s(_vm.showFriendlyText ? option.description : option.value)+"\n "),(option.description)?_c('span',{staticClass:"gl-filtered-search-token-operator-description"},[_vm._v("\n "+_vm._s(_vm.showFriendlyText ? option.value : option.description)+"\n ")]):_vm._e()])]}}]),model:{value:(_vm.tokenValue.operator),callback:function ($$v) {_vm.$set(_vm.tokenValue, "operator", $$v);},expression:"tokenValue.operator"}}),_vm._v(" "),(_vm.hasDataOrDataSegmentIsCurrentlyActive)?_c('gl-filtered-search-token-segment',{key:"data-segment",attrs:{"active":_vm.isSegmentActive(_vm.$options.segments.SEGMENT_DATA),"cursor-position":_vm.intendedCursorPosition,"multi-select":_vm.config.multiSelect,"options":_vm.config.options,"view-only":_vm.viewOnly
|
|
326
|
+
return [_c('div',{staticClass:"gl-display-flex"},[_vm._v("\n "+_vm._s(_vm.showFriendlyText ? option.description : option.value)+"\n "),(option.description)?_c('span',{staticClass:"gl-filtered-search-token-operator-description"},[_vm._v("\n "+_vm._s(_vm.showFriendlyText ? option.value : option.description)+"\n ")]):_vm._e()])]}}]),model:{value:(_vm.tokenValue.operator),callback:function ($$v) {_vm.$set(_vm.tokenValue, "operator", $$v);},expression:"tokenValue.operator"}}),_vm._v(" "),(_vm.hasDataOrDataSegmentIsCurrentlyActive)?_c('gl-filtered-search-token-segment',{key:"data-segment",attrs:{"active":_vm.isSegmentActive(_vm.$options.segments.SEGMENT_DATA),"cursor-position":_vm.intendedCursorPosition,"multi-select":_vm.config.multiSelect,"options":_vm.config.options,"view-only":_vm.viewOnly},on:{"activate":_vm.activateDataSegment,"backspace":function($event){return _vm.activateSegment(_vm.$options.segments.SEGMENT_OPERATOR)},"complete":_vm.handleComplete,"select":function($event){return _vm.$emit('select', $event)},"submit":function($event){return _vm.$emit('submit')},"deactivate":function($event){return _vm.$emit('deactivate')},"split":function($event){return _vm.$emit('split', $event)},"previous":_vm.activatePreviousOperatorSegment,"next":function($event){return _vm.$emit('next')}},scopedSlots:_vm._u([{key:"suggestions",fn:function(){return [_vm._t("suggestions")]},proxy:true},{key:"view",fn:function(ref){
|
|
328
327
|
var inputValue = ref.inputValue;
|
|
329
328
|
return [_vm._t("view-token",function(){return [_c('gl-token',_vm._g({staticClass:"gl-filtered-search-token-data",class:_vm.getAdditionalSegmentClasses(_vm.$options.segments.SEGMENT_DATA),attrs:{"variant":"search-value","view-only":_vm.viewOnly}},_vm.eventListeners),[_c('span',{staticClass:"gl-filtered-search-token-data-content"},[_vm._t("view",function(){return [_vm._v(_vm._s(inputValue))]},null,{ inputValue: inputValue })],2)])]},null,{
|
|
330
329
|
inputValue: inputValue,
|
|
@@ -3,7 +3,7 @@ import { Portal } from 'portal-vue';
|
|
|
3
3
|
import { COMMA, LEFT_MOUSE_BUTTON } from '../../../utils/constants';
|
|
4
4
|
import GlFilteredSearchSuggestion from './filtered_search_suggestion';
|
|
5
5
|
import GlFilteredSearchSuggestionList from './filtered_search_suggestion_list';
|
|
6
|
-
import { splitOnQuotes, wrapTokenInQuotes } from './filtered_search_utils';
|
|
6
|
+
import { splitOnQuotes, match, wrapTokenInQuotes } from './filtered_search_utils';
|
|
7
7
|
import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
|
|
8
8
|
|
|
9
9
|
// We need some helpers to ensure @vue/compat compatibility
|
|
@@ -60,6 +60,11 @@ var script = {
|
|
|
60
60
|
required: false,
|
|
61
61
|
default: false
|
|
62
62
|
},
|
|
63
|
+
isTerm: {
|
|
64
|
+
type: Boolean,
|
|
65
|
+
required: false,
|
|
66
|
+
default: false
|
|
67
|
+
},
|
|
63
68
|
label: {
|
|
64
69
|
type: String,
|
|
65
70
|
required: false,
|
|
@@ -78,7 +83,7 @@ var script = {
|
|
|
78
83
|
optionTextField: {
|
|
79
84
|
type: String,
|
|
80
85
|
required: false,
|
|
81
|
-
default: '
|
|
86
|
+
default: 'title'
|
|
82
87
|
},
|
|
83
88
|
customInputKeydownHandler: {
|
|
84
89
|
type: Function,
|
|
@@ -140,16 +145,18 @@ var script = {
|
|
|
140
145
|
},
|
|
141
146
|
inputValue: {
|
|
142
147
|
get() {
|
|
148
|
+
if (this.isTerm) {
|
|
149
|
+
return this.nonMultipleValue;
|
|
150
|
+
}
|
|
143
151
|
return this.matchingOption ? this.matchingOption[this.optionTextField] : this.nonMultipleValue;
|
|
144
152
|
},
|
|
145
|
-
set(
|
|
146
|
-
var _this$getMatchingOpti, _this$getMatchingOpti2;
|
|
153
|
+
set(inputValue) {
|
|
147
154
|
/**
|
|
148
155
|
* Emitted when this token segment's value changes.
|
|
149
156
|
*
|
|
150
157
|
* @type {object} option The current option.
|
|
151
158
|
*/
|
|
152
|
-
this.$emit('input',
|
|
159
|
+
this.$emit('input', inputValue);
|
|
153
160
|
}
|
|
154
161
|
},
|
|
155
162
|
hasOptionsOrSuggestions() {
|
|
@@ -158,7 +165,7 @@ var script = {
|
|
|
158
165
|
return ((_this$options2 = this.options) === null || _this$options2 === void 0 ? void 0 : _this$options2.length) || isSlotNotEmpty(this.$slots.suggestions);
|
|
159
166
|
},
|
|
160
167
|
defaultSuggestedValue() {
|
|
161
|
-
var
|
|
168
|
+
var _this$options$;
|
|
162
169
|
if (!this.options) {
|
|
163
170
|
return this.nonMultipleValue;
|
|
164
171
|
}
|
|
@@ -168,8 +175,11 @@ var script = {
|
|
|
168
175
|
});
|
|
169
176
|
return option === null || option === void 0 ? void 0 : option.value;
|
|
170
177
|
}
|
|
171
|
-
const
|
|
172
|
-
|
|
178
|
+
const defaultOption = this.options.find(op => op.default);
|
|
179
|
+
if (defaultOption) {
|
|
180
|
+
return defaultOption.value;
|
|
181
|
+
}
|
|
182
|
+
return this.isTerm ? undefined : (_this$options$ = this.options[0]) === null || _this$options$ === void 0 ? void 0 : _this$options$.value;
|
|
173
183
|
},
|
|
174
184
|
containerAttributes() {
|
|
175
185
|
return this.isLastToken && !this.active && this.currentValue.length > 1 && this.searchInputAttributes;
|
|
@@ -187,13 +197,12 @@ var script = {
|
|
|
187
197
|
}
|
|
188
198
|
},
|
|
189
199
|
inputValue(newValue) {
|
|
190
|
-
var _this$getMatchingOpti3, _this$getMatchingOpti4;
|
|
191
200
|
const hasUnclosedQuote = newValue.split('"').length % 2 === 0;
|
|
192
201
|
if (newValue.indexOf(' ') === -1 || hasUnclosedQuote) {
|
|
193
202
|
return;
|
|
194
203
|
}
|
|
195
204
|
const [firstWord, ...otherWords] = splitOnQuotes(newValue).filter((w, idx, arr) => Boolean(w) || idx === arr.length - 1);
|
|
196
|
-
this.$emit('input',
|
|
205
|
+
this.$emit('input', firstWord);
|
|
197
206
|
if (otherWords.length) {
|
|
198
207
|
/**
|
|
199
208
|
* Emitted when Space appears in token segment value
|
|
@@ -213,14 +222,14 @@ var script = {
|
|
|
213
222
|
e.preventDefault();
|
|
214
223
|
}
|
|
215
224
|
},
|
|
216
|
-
getMatchingOptionForInputValue(
|
|
225
|
+
getMatchingOptionForInputValue(inputValue) {
|
|
217
226
|
var _this$options3;
|
|
218
227
|
let {
|
|
219
228
|
loose
|
|
220
229
|
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
|
|
221
230
|
loose: false
|
|
222
231
|
};
|
|
223
|
-
return (_this$options3 = this.options) === null || _this$options3 === void 0 ? void 0 : _this$options3.find(
|
|
232
|
+
return (_this$options3 = this.options) === null || _this$options3 === void 0 ? void 0 : _this$options3.find(option => loose ? match(option[this.optionTextField], inputValue) : option[this.optionTextField] === inputValue);
|
|
224
233
|
},
|
|
225
234
|
activate() {
|
|
226
235
|
this.fallbackValue = this.value;
|
|
@@ -243,7 +252,7 @@ var script = {
|
|
|
243
252
|
},
|
|
244
253
|
deactivate() {
|
|
245
254
|
var _this$matchingOption;
|
|
246
|
-
if (!this.options) {
|
|
255
|
+
if (!this.options || this.isTerm) {
|
|
247
256
|
return;
|
|
248
257
|
}
|
|
249
258
|
if (((_this$matchingOption = this.matchingOption) === null || _this$matchingOption === void 0 ? void 0 : _this$matchingOption.value) !== this.value) {
|
|
@@ -359,7 +368,7 @@ const __vue_script__ = script;
|
|
|
359
368
|
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',_vm._g(_vm._b({staticClass:"gl-filtered-search-token-segment",class:{
|
|
360
369
|
'gl-filtered-search-token-segment-active': _vm.active,
|
|
361
370
|
'gl-cursor-text!': _vm.viewOnly,
|
|
362
|
-
},attrs:{"data-testid":"filtered-search-token-segment"}},'div',_vm.containerAttributes,false),_vm.viewOnly ? {} : { mousedown: _vm.emitIfInactive }),[(_vm.active)?[(((_vm.searchInputAttributes).type)==='checkbox')?_c('input',_vm._b({directives:[{name:"model",rawName:"v-model",value:(_vm.inputValue),expression:"inputValue"}],ref:"input",staticClass:"gl-filtered-search-token-segment-input",attrs:{"data-testid":"filtered-search-token-segment-input","aria-label":_vm.label,"readonly":_vm.viewOnly,"type":"checkbox"},domProps:{"checked":Array.isArray(_vm.inputValue)?_vm._i(_vm.inputValue,null)>-1:(_vm.inputValue)},on:{"keydown":_vm.handleInputKeydown,"blur":_vm.handleBlur,"change":function($event){var $$a=_vm.inputValue,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.inputValue=$$a.concat([$$v]));}else {$$i>-1&&(_vm.inputValue=$$a.slice(0,$$i).concat($$a.slice($$i+1)));}}else {_vm.inputValue=$$c;}}}},'input',_vm.searchInputAttributes,false)):(((_vm.searchInputAttributes).type)==='radio')?_c('input',_vm._b({directives:[{name:"model",rawName:"v-model",value:(_vm.inputValue),expression:"inputValue"}],ref:"input",staticClass:"gl-filtered-search-token-segment-input",attrs:{"data-testid":"filtered-search-token-segment-input","aria-label":_vm.label,"readonly":_vm.viewOnly,"type":"radio"},domProps:{"checked":_vm._q(_vm.inputValue,null)},on:{"keydown":_vm.handleInputKeydown,"blur":_vm.handleBlur,"change":function($event){_vm.inputValue=null;}}},'input',_vm.searchInputAttributes,false)):_c('input',_vm._b({directives:[{name:"model",rawName:"v-model",value:(_vm.inputValue),expression:"inputValue"}],ref:"input",staticClass:"gl-filtered-search-token-segment-input",attrs:{"data-testid":"filtered-search-token-segment-input","aria-label":_vm.label,"readonly":_vm.viewOnly,"type":(_vm.searchInputAttributes).type},domProps:{"value":(_vm.inputValue)},on:{"keydown":_vm.handleInputKeydown,"blur":_vm.handleBlur,"input":function($event){if($event.target.composing){ return; }_vm.inputValue=$event.target.value;}}},'input',_vm.searchInputAttributes,false)),_vm._v(" "),_c('portal',{key:("operator-" + _vm._uid),attrs:{"to":_vm.portalName}},[(_vm.hasOptionsOrSuggestions)?_c('gl-filtered-search-suggestion-list',{key:("operator-" + _vm._uid),ref:"suggestions",attrs:{"initial-value":_vm.defaultSuggestedValue},on:{"suggestion":_vm.applySuggestion}},[(_vm.options)?_vm._l((_vm.options),function(option,idx){return _c('gl-filtered-search-suggestion',{key:((option.value) + "-" + idx),attrs:{"value":option.value,"icon-name":option.icon}},[_vm._t("option",function(){return [_vm._v("
|
|
371
|
+
},attrs:{"data-testid":"filtered-search-token-segment"}},'div',_vm.containerAttributes,false),_vm.viewOnly ? {} : { mousedown: _vm.emitIfInactive }),[(_vm.active)?[(((_vm.searchInputAttributes).type)==='checkbox')?_c('input',_vm._b({directives:[{name:"model",rawName:"v-model",value:(_vm.inputValue),expression:"inputValue"}],ref:"input",staticClass:"gl-filtered-search-token-segment-input",attrs:{"data-testid":"filtered-search-token-segment-input","aria-label":_vm.label,"readonly":_vm.viewOnly,"type":"checkbox"},domProps:{"checked":Array.isArray(_vm.inputValue)?_vm._i(_vm.inputValue,null)>-1:(_vm.inputValue)},on:{"keydown":_vm.handleInputKeydown,"blur":_vm.handleBlur,"change":function($event){var $$a=_vm.inputValue,$$el=$event.target,$$c=$$el.checked?(true):(false);if(Array.isArray($$a)){var $$v=null,$$i=_vm._i($$a,$$v);if($$el.checked){$$i<0&&(_vm.inputValue=$$a.concat([$$v]));}else {$$i>-1&&(_vm.inputValue=$$a.slice(0,$$i).concat($$a.slice($$i+1)));}}else {_vm.inputValue=$$c;}}}},'input',_vm.searchInputAttributes,false)):(((_vm.searchInputAttributes).type)==='radio')?_c('input',_vm._b({directives:[{name:"model",rawName:"v-model",value:(_vm.inputValue),expression:"inputValue"}],ref:"input",staticClass:"gl-filtered-search-token-segment-input",attrs:{"data-testid":"filtered-search-token-segment-input","aria-label":_vm.label,"readonly":_vm.viewOnly,"type":"radio"},domProps:{"checked":_vm._q(_vm.inputValue,null)},on:{"keydown":_vm.handleInputKeydown,"blur":_vm.handleBlur,"change":function($event){_vm.inputValue=null;}}},'input',_vm.searchInputAttributes,false)):_c('input',_vm._b({directives:[{name:"model",rawName:"v-model",value:(_vm.inputValue),expression:"inputValue"}],ref:"input",staticClass:"gl-filtered-search-token-segment-input",attrs:{"data-testid":"filtered-search-token-segment-input","aria-label":_vm.label,"readonly":_vm.viewOnly,"type":(_vm.searchInputAttributes).type},domProps:{"value":(_vm.inputValue)},on:{"keydown":_vm.handleInputKeydown,"blur":_vm.handleBlur,"input":function($event){if($event.target.composing){ return; }_vm.inputValue=$event.target.value;}}},'input',_vm.searchInputAttributes,false)),_vm._v(" "),_c('portal',{key:("operator-" + _vm._uid),attrs:{"to":_vm.portalName}},[(_vm.hasOptionsOrSuggestions)?_c('gl-filtered-search-suggestion-list',{key:("operator-" + _vm._uid),ref:"suggestions",attrs:{"initial-value":_vm.defaultSuggestedValue},on:{"suggestion":_vm.applySuggestion}},[(_vm.options)?_vm._l((_vm.options),function(option,idx){return _c('gl-filtered-search-suggestion',{key:((option.value) + "-" + idx),attrs:{"value":option.value,"icon-name":option.icon}},[_vm._t("option",function(){return [(option.component)?[_c(option.component,{tag:"component",attrs:{"option":option}})]:[_vm._v("\n "+_vm._s(option[_vm.optionTextField])+"\n ")]]},null,{ option: option })],2)}):_vm._t("suggestions")],2):_vm._e()],1)]:_vm._t("view",function(){return [_vm._v(_vm._s(_vm.inputValue))]},null,{ inputValue: _vm.inputValue })],2)};
|
|
363
372
|
var __vue_staticRenderFns__ = [];
|
|
364
373
|
|
|
365
374
|
/* style */
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import first from 'lodash/first';
|
|
2
2
|
import last from 'lodash/last';
|
|
3
3
|
import isString from 'lodash/isString';
|
|
4
|
+
import { modulo } from '../../../utils/number_utils';
|
|
4
5
|
|
|
5
6
|
const TERM_TOKEN_TYPE = 'filtered-search-term';
|
|
6
7
|
const INTENT_ACTIVATE_PREVIOUS = 'intent-activate-previous';
|
|
@@ -37,6 +38,69 @@ function needDenormalization(tokens) {
|
|
|
37
38
|
assertValidTokens(tokens);
|
|
38
39
|
return tokens.some(t => typeof t === 'string' || !t.id);
|
|
39
40
|
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Given an initial index, step size and array length, returns an index that is
|
|
44
|
+
* within the array bounds (unless step is 0; see † below).
|
|
45
|
+
*
|
|
46
|
+
* The step can be any positive or negative integer, including zero.
|
|
47
|
+
*
|
|
48
|
+
* An out-of-bounds index is considered 'uninitialised', and is handled
|
|
49
|
+
* specially. For instance, the 'next' index of 'uninitialised' is the first
|
|
50
|
+
* index:
|
|
51
|
+
*
|
|
52
|
+
* stepIndexAndWrap(-1, 1, 5) === 0
|
|
53
|
+
*
|
|
54
|
+
* The 'previous' index of 'uninitialised' is the last index:
|
|
55
|
+
*
|
|
56
|
+
* stepIndexAndWrap(-1, -1, 5) === 4
|
|
57
|
+
*
|
|
58
|
+
* †: If step is 0, the index is returned as-is, which may be out-of-bounds.
|
|
59
|
+
*
|
|
60
|
+
* @param {number} index The initial index.
|
|
61
|
+
* @param {number} step The amount to step by (positive or negative).
|
|
62
|
+
* @param {number} length The length of the array.
|
|
63
|
+
* @returns {number}
|
|
64
|
+
*/
|
|
65
|
+
function stepIndexAndWrap(index, step, length) {
|
|
66
|
+
if (step === 0) return index;
|
|
67
|
+
let start;
|
|
68
|
+
const indexInRange = index >= 0 && index < length;
|
|
69
|
+
if (indexInRange) {
|
|
70
|
+
// Step from the valid index.
|
|
71
|
+
start = index;
|
|
72
|
+
} else if (step > 0) {
|
|
73
|
+
// Step forwards from the beginning of the array.
|
|
74
|
+
start = -1;
|
|
75
|
+
} else {
|
|
76
|
+
// Step backwards from the end of the array.
|
|
77
|
+
start = length;
|
|
78
|
+
}
|
|
79
|
+
return modulo(start + step, length);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Transforms a given token definition to an option definition.
|
|
84
|
+
*
|
|
85
|
+
* @param {Object} token A token definition (see GlFilteredSearch's
|
|
86
|
+
* availableTokens prop).
|
|
87
|
+
* @returns {Object} A option definition (see GlFilteredSearchTokenSegment's
|
|
88
|
+
* options prop).
|
|
89
|
+
*/
|
|
90
|
+
function tokenToOption(_ref) {
|
|
91
|
+
let {
|
|
92
|
+
icon,
|
|
93
|
+
title,
|
|
94
|
+
type,
|
|
95
|
+
optionComponent
|
|
96
|
+
} = _ref;
|
|
97
|
+
return {
|
|
98
|
+
icon,
|
|
99
|
+
title,
|
|
100
|
+
value: type,
|
|
101
|
+
component: optionComponent
|
|
102
|
+
};
|
|
103
|
+
}
|
|
40
104
|
let tokenIdCounter = 0;
|
|
41
105
|
const getTokenId = () => {
|
|
42
106
|
const tokenId = `token-${tokenIdCounter}`;
|
|
@@ -86,6 +150,19 @@ function denormalizeTokens(inputTokens) {
|
|
|
86
150
|
});
|
|
87
151
|
return result;
|
|
88
152
|
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Returns `true` if `text` contains `query` (case insensitive).
|
|
156
|
+
*
|
|
157
|
+
* This is used in `filter` and `find` array methods for token segment options.
|
|
158
|
+
*
|
|
159
|
+
* @param {string} text The string to look within.
|
|
160
|
+
* @param {string} query The string to find inside the text.
|
|
161
|
+
* @returns {boolean}
|
|
162
|
+
*/
|
|
163
|
+
function match(text, query) {
|
|
164
|
+
return text.toLowerCase().includes(query.toLowerCase());
|
|
165
|
+
}
|
|
89
166
|
function splitOnQuotes(str) {
|
|
90
167
|
if (first(str) === "'" && last(str) === "'") {
|
|
91
168
|
return [str];
|
|
@@ -151,4 +228,4 @@ function wrapTokenInQuotes(token) {
|
|
|
151
228
|
return `"${token}"`;
|
|
152
229
|
}
|
|
153
230
|
|
|
154
|
-
export { INTENT_ACTIVATE_PREVIOUS, TERM_TOKEN_TYPE, createTerm, denormalizeTokens, ensureTokenId, isEmptyTerm, needDenormalization, normalizeTokens, splitOnQuotes, wrapTokenInQuotes };
|
|
231
|
+
export { INTENT_ACTIVATE_PREVIOUS, TERM_TOKEN_TYPE, createTerm, denormalizeTokens, ensureTokenId, isEmptyTerm, match, needDenormalization, normalizeTokens, splitOnQuotes, stepIndexAndWrap, tokenToOption, wrapTokenInQuotes };
|
|
@@ -24,6 +24,27 @@ const average = function () {
|
|
|
24
24
|
return sum(...arguments) / arguments.length;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Returns the modulo of n for a divisor.
|
|
29
|
+
*
|
|
30
|
+
* Maps the integer n into the range [0, divisor) when the divisor is positive,
|
|
31
|
+
* and (divisor, 0] when the divisor is negative.
|
|
32
|
+
*
|
|
33
|
+
* This is useful when indexing into an array, to ensure you always stay within
|
|
34
|
+
* the array bounds.
|
|
35
|
+
*
|
|
36
|
+
* See https://2ality.com/2019/08/remainder-vs-modulo.html.
|
|
37
|
+
*
|
|
38
|
+
* @param {number} n The number to mod.
|
|
39
|
+
* @param {number} divisor The divisor (e.g., the length of an array).
|
|
40
|
+
* @returns {number}
|
|
41
|
+
*/
|
|
42
|
+
function modulo(n, divisor) {
|
|
43
|
+
const result = (n % divisor + divisor) % divisor;
|
|
44
|
+
// Never return -0.
|
|
45
|
+
return result === 0 ? 0 : result;
|
|
46
|
+
}
|
|
47
|
+
|
|
27
48
|
/**
|
|
28
49
|
* Convert number to engineering format, using SI suffix
|
|
29
50
|
* @param {Number|String} value - Number or Number-convertible String
|
|
@@ -75,4 +96,4 @@ const engineeringNotation = function (value) {
|
|
|
75
96
|
return `${scaledMantissa}${allYourBase[scaledPower]}`;
|
|
76
97
|
};
|
|
77
98
|
|
|
78
|
-
export { addition, average, engineeringNotation, sum };
|
|
99
|
+
export { addition, average, engineeringNotation, modulo, sum };
|