@tagplus/components 4.7.12 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tp.common.js +2 -1
- package/dist/tp.common.js.LICENSE.txt +9 -0
- package/dist/tp.common.js.map +1 -1
- package/dist/tp.common.lang-en-js.js +2 -0
- package/dist/tp.common.lang-en-js.js.map +1 -0
- package/dist/tp.css +11 -167
- package/dist/tp.umd.js +2 -1
- package/dist/tp.umd.js.LICENSE.txt +9 -0
- package/dist/tp.umd.js.map +1 -1
- package/dist/tp.umd.lang-en-js.js +2 -0
- package/dist/tp.umd.lang-en-js.js.map +1 -0
- package/dist/tp.umd.min.js +2 -1
- package/dist/tp.umd.min.js.LICENSE.txt +9 -0
- package/dist/tp.umd.min.js.map +1 -1
- package/dist/tp.umd.min.lang-en-js.js +2 -0
- package/dist/tp.umd.min.lang-en-js.js.map +1 -0
- package/package.json +51 -50
- package/src/assets/scss/_fonts.scss +24 -23
- package/src/assets/scss/_helpers.scss +4 -0
- package/src/assets/scss/_mixins.scss +2 -2
- package/src/assets/scss/_overrides.scss +5 -52
- package/src/assets/scss/_resass.scss +21 -12
- package/src/assets/scss/_variables.scss +0 -1
- package/src/assets/scss/index.scss +1 -4
- package/src/components/Autosuggest/Autosuggest.vue +340 -767
- package/src/components/Autosuggest/Multisuggest.vue +22 -0
- package/src/components/Autosuggest/autosuggest-props.js +210 -0
- package/src/components/Autosuggest/autosuggest-style.scss +127 -0
- package/src/components/Autosuggest/core.js +63 -0
- package/src/components/Autosuggest/index.js +2 -0
- package/src/components/Autosuggest/multisuggest-props.js +9 -0
- package/src/components/Autosuggest/option.vue +136 -0
- package/src/components/Autosuggest/select-dropdown.vue +64 -0
- package/src/components/Autosuggest/useOption.js +120 -0
- package/src/components/Autosuggest/useSelect.js +1133 -0
- package/src/components/AutosuggestTest.vue +56 -0
- package/src/components/CardExemplo.vue +49 -0
- package/src/components/CodeSample.vue +78 -0
- package/src/components/Inline/Inline.vue +24 -32
- package/src/components/InputNumber/InputNumber.vue +329 -378
- package/src/components/InputNumber/input-number.js +135 -0
- package/src/components/Loader/Loader.vue +42 -53
- package/src/components/Loader/animations.scss +13 -0
- package/src/components/Money/Money.vue +11 -20
- package/src/components/Multisuggest/index.js +2 -3
- package/src/components/MultisuggestTest.vue +56 -0
- package/src/components/OptionsList/OptionsList.vue +7 -6
- package/src/components/OptionsListItem/OptionsListItem.vue +46 -42
- package/src/components/Percent/Percent.vue +8 -14
- package/src/components/Skeleton/Skeleton.vue +16 -11
- package/src/components/Step/Step.vue +42 -35
- package/src/components/Steps/Steps.vue +4 -7
- package/src/components/TesteToCurrency.vue +171 -0
- package/src/components/Tip/Tip.vue +45 -30
- package/src/components/ValueSelector.vue +60 -0
- package/src/components/autosuggestMixin.js +301 -0
- package/src/components/index.js +4 -1
- package/src/locale/i18n.js +114 -0
- package/src/locale/lang/en.js +3 -2
- package/src/locale/lang/pt-br.js +3 -2
- package/src/main.js +9 -14
- package/src/mixins/floatFormatter.js +12 -16
- package/src/plugins/currency.js +100 -0
- package/src/utils/browser.js +6 -0
- package/src/utils/constants.js +3 -0
- package/src/utils/error.js +22 -0
- package/src/utils/filters.js +1 -14
- package/src/utils/helpers.js +41 -0
- package/src/utils/i18n.js +2 -0
- package/src/utils/icon.js +35 -0
- package/src/utils/index.js +20 -0
- package/src/utils/objects.js +17 -0
- package/src/utils/runtime.js +86 -0
- package/src/utils/scroll.js +100 -0
- package/src/utils/strings.js +17 -0
- package/src/utils/style.js +80 -0
- package/src/utils/types.js +39 -0
- package/src/utils/use-derived-namespace.js +112 -0
- package/src/utils/use-form-common-props.js +41 -0
- package/src/utils/use-form-item.js +80 -0
- package/src/utils/use-id.js +40 -0
- package/src/utils/use-input.js +33 -0
- package/src/components/Dialog/Dialog.vue +0 -253
- package/src/components/Dialog/index.js +0 -3
- package/src/components/Multisuggest/Multisuggest.vue +0 -858
- package/src/locale/index.js +0 -78
- package/src/mixins/locale.js +0 -9
- package/src/utils/currency.js +0 -180
|
@@ -1,858 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div
|
|
3
|
-
v-clickoutside="handleClose"
|
|
4
|
-
class="el-select tp-multisuggest"
|
|
5
|
-
:class="[selectSize ? 'el-select--' + selectSize : '']"
|
|
6
|
-
@click.stop="toggleMenu"
|
|
7
|
-
>
|
|
8
|
-
<div
|
|
9
|
-
ref="tags"
|
|
10
|
-
class="el-select__tags"
|
|
11
|
-
>
|
|
12
|
-
<div
|
|
13
|
-
style="visibility: hidden;"
|
|
14
|
-
class="el-input-group__prepend"
|
|
15
|
-
>
|
|
16
|
-
<em class="far fa-search" />
|
|
17
|
-
</div>
|
|
18
|
-
<span v-if="collapseTags && selected.length">
|
|
19
|
-
<el-tooltip placement="top">
|
|
20
|
-
<div slot="content">
|
|
21
|
-
{{ selectedLabels }}
|
|
22
|
-
</div>
|
|
23
|
-
<el-tag
|
|
24
|
-
:closable="false"
|
|
25
|
-
:size="collapseTagSize"
|
|
26
|
-
type="info"
|
|
27
|
-
disable-transitions
|
|
28
|
-
>
|
|
29
|
-
<span
|
|
30
|
-
:id="`${_id}-tags`"
|
|
31
|
-
class="el-select__tags-text"
|
|
32
|
-
>Itens: {{ selected.length }}
|
|
33
|
-
</span>
|
|
34
|
-
</el-tag>
|
|
35
|
-
</el-tooltip>
|
|
36
|
-
</span>
|
|
37
|
-
|
|
38
|
-
<transition-group
|
|
39
|
-
v-if="!collapseTags"
|
|
40
|
-
@after-leave="resetInputHeight"
|
|
41
|
-
>
|
|
42
|
-
<el-tag
|
|
43
|
-
v-for="item in selected"
|
|
44
|
-
:key="getValueKey(item)"
|
|
45
|
-
:closable="!selectDisabled"
|
|
46
|
-
:size="collapseTagSize"
|
|
47
|
-
:hit="item.hitState"
|
|
48
|
-
type="info"
|
|
49
|
-
disable-transitions
|
|
50
|
-
@close="deleteTag($event, item)"
|
|
51
|
-
>
|
|
52
|
-
<span
|
|
53
|
-
:id="`${_id}-tags`"
|
|
54
|
-
class="el-select__tags-text"
|
|
55
|
-
>{{ item.currentLabel }}
|
|
56
|
-
</span>
|
|
57
|
-
</el-tag>
|
|
58
|
-
</transition-group>
|
|
59
|
-
|
|
60
|
-
<input
|
|
61
|
-
v-if="filterable"
|
|
62
|
-
:id="`${_id}-input-search`"
|
|
63
|
-
ref="input"
|
|
64
|
-
v-model="query"
|
|
65
|
-
:for="name"
|
|
66
|
-
type="text"
|
|
67
|
-
class="el-select__input"
|
|
68
|
-
:class="selected.length ? 'tag' : ''"
|
|
69
|
-
:disabled="selectDisabled"
|
|
70
|
-
:autocomplete="autoComplete || autocomplete"
|
|
71
|
-
:style="{ 'flex-grow': '1', width: inputLength / (inputWidth - 32) + '%', 'max-width': inputWidth - 42 + 'px', 'padding-right':'10px' }"
|
|
72
|
-
@focus="handleFocus"
|
|
73
|
-
@blur="softFocus = false"
|
|
74
|
-
@keyup="managePlaceholder"
|
|
75
|
-
@keydown="resetInputState"
|
|
76
|
-
@keydown.down.prevent="navigateOptions('next')"
|
|
77
|
-
@keydown.up.prevent="navigateOptions('prev')"
|
|
78
|
-
@keydown.enter.prevent="selectOption"
|
|
79
|
-
@keydown.esc.stop.prevent="visible = false"
|
|
80
|
-
@keydown.delete="deletePrevTag"
|
|
81
|
-
@keydown.tab="visible = false"
|
|
82
|
-
@compositionstart="handleComposition"
|
|
83
|
-
@compositionupdate="handleComposition"
|
|
84
|
-
@compositionend="handleComposition"
|
|
85
|
-
@input="debouncedQueryChange"
|
|
86
|
-
>
|
|
87
|
-
</div>
|
|
88
|
-
<el-input
|
|
89
|
-
:id="`${_id}-input`"
|
|
90
|
-
ref="reference"
|
|
91
|
-
v-model="selectedLabel"
|
|
92
|
-
type="text"
|
|
93
|
-
:placeholder="currentPlaceholder"
|
|
94
|
-
:name="name"
|
|
95
|
-
:autocomplete="autoComplete || autocomplete"
|
|
96
|
-
:size="selectSize"
|
|
97
|
-
:disabled="selectDisabled"
|
|
98
|
-
:readonly="readonly"
|
|
99
|
-
:validate-event="false"
|
|
100
|
-
:class="{ 'is-focus': visible }"
|
|
101
|
-
:tabindex="(multiple && filterable) ? '-1' : null"
|
|
102
|
-
@focus="handleFocus"
|
|
103
|
-
@blur="handleBlur"
|
|
104
|
-
@keyup.native="debouncedOnInputChange"
|
|
105
|
-
@keydown.native.down.stop.prevent="navigateOptions('next')"
|
|
106
|
-
@keydown.native.up.stop.prevent="navigateOptions('prev')"
|
|
107
|
-
@keydown.native.enter.prevent="selectOption"
|
|
108
|
-
@keydown.native.esc.stop.prevent="visible = false"
|
|
109
|
-
@keydown.native.tab="visible = false"
|
|
110
|
-
@paste.native="debouncedOnInputChange"
|
|
111
|
-
@mouseenter.native="inputHovering = true"
|
|
112
|
-
@mouseleave.native="inputHovering = false"
|
|
113
|
-
>
|
|
114
|
-
<template v-if="prepend">
|
|
115
|
-
<template
|
|
116
|
-
v-if="$slots.prepend || typeof(prepend) == 'string'"
|
|
117
|
-
slot="prepend"
|
|
118
|
-
>
|
|
119
|
-
<slot name="prepend">
|
|
120
|
-
{{ prepend }}
|
|
121
|
-
</slot>
|
|
122
|
-
</template>
|
|
123
|
-
<template
|
|
124
|
-
v-else
|
|
125
|
-
slot="prepend"
|
|
126
|
-
>
|
|
127
|
-
<em class="far fa-search" />
|
|
128
|
-
</template>
|
|
129
|
-
</template>
|
|
130
|
-
<template
|
|
131
|
-
v-if="$slots.prefix"
|
|
132
|
-
slot="prefix"
|
|
133
|
-
>
|
|
134
|
-
<slot name="prefix" />
|
|
135
|
-
</template>
|
|
136
|
-
<template slot="append">
|
|
137
|
-
<el-row
|
|
138
|
-
type="flex"
|
|
139
|
-
:justify="selected.length ? 'space-between' : 'end'"
|
|
140
|
-
align="middle"
|
|
141
|
-
>
|
|
142
|
-
<em
|
|
143
|
-
v-if="selected.length && !selectDisabled"
|
|
144
|
-
:id="`${_id}-btn-clear`"
|
|
145
|
-
class="fa fa-times-circle icon-close"
|
|
146
|
-
@click="clearTags"
|
|
147
|
-
/>
|
|
148
|
-
<el-row
|
|
149
|
-
align="middle"
|
|
150
|
-
type="flex"
|
|
151
|
-
justify="space-around"
|
|
152
|
-
class="rightContent"
|
|
153
|
-
>
|
|
154
|
-
<el-divider
|
|
155
|
-
direction="vertical"
|
|
156
|
-
class="dividerSuggest"
|
|
157
|
-
/>
|
|
158
|
-
|
|
159
|
-
<em
|
|
160
|
-
v-show="!showClose && !selectDisabled"
|
|
161
|
-
:id="`${_id}-btn-close`"
|
|
162
|
-
:class="['el-select__caret', 'el-input__icon', 'el-icon-' + iconClass]"
|
|
163
|
-
/>
|
|
164
|
-
</el-row>
|
|
165
|
-
</el-row>
|
|
166
|
-
</template>
|
|
167
|
-
</el-input>
|
|
168
|
-
<transition
|
|
169
|
-
name="el-zoom-in-top"
|
|
170
|
-
@before-enter="handleMenuEnter"
|
|
171
|
-
@after-leave="doDestroy"
|
|
172
|
-
>
|
|
173
|
-
<el-select-menu
|
|
174
|
-
v-show="visible && emptyText !== false"
|
|
175
|
-
:id="`${_id}-select`"
|
|
176
|
-
ref="popper"
|
|
177
|
-
:append-to-body="popperAppendToBody"
|
|
178
|
-
>
|
|
179
|
-
<el-scrollbar
|
|
180
|
-
v-show="options.length > 0 && !loading"
|
|
181
|
-
:id="`${_id}-scrollbar`"
|
|
182
|
-
ref="scrollbar"
|
|
183
|
-
tag="ul"
|
|
184
|
-
wrap-class="tp-select-dropdown__wrap el-select-dropdown__wrap"
|
|
185
|
-
view-class="tp-select-dropdown__list el-select-dropdown__list"
|
|
186
|
-
:class="{ 'is-empty': !allowCreate && query && filteredOptionsCount === 0 }"
|
|
187
|
-
>
|
|
188
|
-
<el-option
|
|
189
|
-
v-for="(item, i) in suggestionsList"
|
|
190
|
-
:id="`${_id}-option-${i}`"
|
|
191
|
-
:key="i"
|
|
192
|
-
:label="item[labelKey]"
|
|
193
|
-
:value="item[valueKey]"
|
|
194
|
-
:created="item.created"
|
|
195
|
-
:class="{'created': item.created}"
|
|
196
|
-
>
|
|
197
|
-
<template v-if="item.created">
|
|
198
|
-
<a :id="`${_id}-btn-create`"><em class="far fa-plus" /> Cadastrar {{ query ? `"${query}"` : "novo item" }}</a>
|
|
199
|
-
</template>
|
|
200
|
-
<slot
|
|
201
|
-
v-else
|
|
202
|
-
:item="item"
|
|
203
|
-
/>
|
|
204
|
-
</el-option>
|
|
205
|
-
</el-scrollbar>
|
|
206
|
-
<template v-if="emptyText && (!allowCreate || loading || (allowCreate && options.length === 0 ))">
|
|
207
|
-
<slot
|
|
208
|
-
v-if="$slots.empty"
|
|
209
|
-
name="empty"
|
|
210
|
-
/>
|
|
211
|
-
<p
|
|
212
|
-
v-else-if="loading"
|
|
213
|
-
class="tp-autosuggest-loading"
|
|
214
|
-
>
|
|
215
|
-
<tp-skeleton :count="4" />
|
|
216
|
-
</p>
|
|
217
|
-
<p
|
|
218
|
-
v-else
|
|
219
|
-
class="el-select-dropdown__empty"
|
|
220
|
-
>
|
|
221
|
-
{{ emptyText }}
|
|
222
|
-
</p>
|
|
223
|
-
</template>
|
|
224
|
-
</el-select-menu>
|
|
225
|
-
</transition>
|
|
226
|
-
</div>
|
|
227
|
-
</template>
|
|
228
|
-
|
|
229
|
-
<script>
|
|
230
|
-
import { Select } from 'element-ui'
|
|
231
|
-
import { getValueByPath, valueEquals } from 'element-ui/src/utils/util'
|
|
232
|
-
import debounce from 'throttle-debounce/debounce'
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Cria um select com opções obtidas de forma assíncrona e remota.
|
|
236
|
-
* Basicamente um atalho de configurações
|
|
237
|
-
* Vide documentação ElementUI: https://element.eleme.io/#/en-US/component/select
|
|
238
|
-
*/
|
|
239
|
-
export default {
|
|
240
|
-
name: 'TpMultisuggest',
|
|
241
|
-
|
|
242
|
-
extends: Select,
|
|
243
|
-
|
|
244
|
-
props: {
|
|
245
|
-
collapseTags: {
|
|
246
|
-
type: Boolean,
|
|
247
|
-
default: true
|
|
248
|
-
},
|
|
249
|
-
|
|
250
|
-
multiple: {
|
|
251
|
-
type: Boolean,
|
|
252
|
-
default: true
|
|
253
|
-
},
|
|
254
|
-
|
|
255
|
-
value: {
|
|
256
|
-
type: [Boolean, String, Object, Number, Array],
|
|
257
|
-
required: false,
|
|
258
|
-
default: ''
|
|
259
|
-
},
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Substituição do valor padrão em relação ao ElementUi
|
|
263
|
-
*/
|
|
264
|
-
remote: {
|
|
265
|
-
type: Boolean,
|
|
266
|
-
required: false,
|
|
267
|
-
default: true
|
|
268
|
-
},
|
|
269
|
-
/**
|
|
270
|
-
* Lista ou Objeto contendo conjunto de itens como opções ou sugestões do componente
|
|
271
|
-
*/
|
|
272
|
-
suggestions: {
|
|
273
|
-
type: [Array, Object],
|
|
274
|
-
required: true
|
|
275
|
-
},
|
|
276
|
-
/**
|
|
277
|
-
* Informa o campo correspondente em cada item referente ao valor sendo selecionado
|
|
278
|
-
*/
|
|
279
|
-
valueKey: {
|
|
280
|
-
type: String,
|
|
281
|
-
default: 'id'
|
|
282
|
-
},
|
|
283
|
-
/**
|
|
284
|
-
* Identificação do campo correspondente em cada item referente ao texto de exibição.
|
|
285
|
-
* Quando utilizado o slot de itens, este campo passa a não ser utilizado
|
|
286
|
-
*/
|
|
287
|
-
labelKey: {
|
|
288
|
-
type: String,
|
|
289
|
-
default: 'label'
|
|
290
|
-
},
|
|
291
|
-
/**
|
|
292
|
-
* Indica quando o campo pode ser utilizado como filtro.
|
|
293
|
-
* Sobrescreve valor padrão do atributo no Select do ElementUI
|
|
294
|
-
*/
|
|
295
|
-
filterable: {
|
|
296
|
-
type: Boolean,
|
|
297
|
-
required: false,
|
|
298
|
-
default: true
|
|
299
|
-
},
|
|
300
|
-
/**
|
|
301
|
-
* Sobrescreve valor padrão do atributo no Select do ElementUI
|
|
302
|
-
*/
|
|
303
|
-
reserveKeyword: {
|
|
304
|
-
type: Boolean,
|
|
305
|
-
required: false,
|
|
306
|
-
default: true
|
|
307
|
-
},
|
|
308
|
-
/**
|
|
309
|
-
* Sobrescreve valor padrão do atributo no Select do ElementUI
|
|
310
|
-
*/
|
|
311
|
-
defaultFirstOption: {
|
|
312
|
-
type: Boolean,
|
|
313
|
-
required: false,
|
|
314
|
-
default: true
|
|
315
|
-
},
|
|
316
|
-
/**
|
|
317
|
-
* Sobrescreve valor padrão do atributo no Select do ElementUI
|
|
318
|
-
*/
|
|
319
|
-
loadOnCreate: {
|
|
320
|
-
type: Boolean,
|
|
321
|
-
required: false,
|
|
322
|
-
default: true
|
|
323
|
-
},
|
|
324
|
-
|
|
325
|
-
/**
|
|
326
|
-
* Quando Boolean: identifica se exibe ou não o ícone de lupa. "False" oculta prepend.
|
|
327
|
-
* Quando String: Informa o texto a ser inserido no prepend
|
|
328
|
-
*/
|
|
329
|
-
prepend: {
|
|
330
|
-
type: [Boolean, String],
|
|
331
|
-
required: false,
|
|
332
|
-
default: true
|
|
333
|
-
},
|
|
334
|
-
|
|
335
|
-
/**
|
|
336
|
-
* Método que realiza a busca dos registros remotos para as opções.
|
|
337
|
-
*
|
|
338
|
-
* *IMPORTANTE*: deve considerar o "valueKey" nas consultas
|
|
339
|
-
* pois o valor selecionado será baseado nas opções remotas carregadas ao criar o componente.
|
|
340
|
-
*/
|
|
341
|
-
remoteMethod: {
|
|
342
|
-
type: Function,
|
|
343
|
-
required: true
|
|
344
|
-
}
|
|
345
|
-
},
|
|
346
|
-
|
|
347
|
-
data () {
|
|
348
|
-
return {
|
|
349
|
-
selectedLabelsArray: [],
|
|
350
|
-
selectedLabels: ''
|
|
351
|
-
}
|
|
352
|
-
},
|
|
353
|
-
|
|
354
|
-
computed: {
|
|
355
|
-
_id () {
|
|
356
|
-
return this.id || this.$options.name
|
|
357
|
-
},
|
|
358
|
-
|
|
359
|
-
/**
|
|
360
|
-
* Trata o caso que o autosuggest recebe um objeto com o valueKey e labelKey
|
|
361
|
-
*/
|
|
362
|
-
formatedValue () {
|
|
363
|
-
let newVal = ''
|
|
364
|
-
if (typeof this.value === 'boolean') {
|
|
365
|
-
newVal = ''
|
|
366
|
-
} else if (Array.isArray(this.value)) {
|
|
367
|
-
this.value.forEach((item) => {
|
|
368
|
-
if (!item[this.valueKey] && item[this.valueKey] !== '') {
|
|
369
|
-
if (process.env.DEBUG === 'true') {
|
|
370
|
-
console.error(`Multisuggest '${this.$options.name}' option doesn't have a valueKey '${this.valueKey}' key`)
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
})
|
|
374
|
-
|
|
375
|
-
newVal = this.value
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
return newVal
|
|
379
|
-
},
|
|
380
|
-
iconClass () {
|
|
381
|
-
return this.visible ? 'arrow-up is-reverse' : 'arrow-up'
|
|
382
|
-
},
|
|
383
|
-
showNewOption () {
|
|
384
|
-
const hasExistingOption = this.options
|
|
385
|
-
.filter(option => !option.created)
|
|
386
|
-
.some(option => option.currentLabel === this.query)
|
|
387
|
-
|
|
388
|
-
return this.filterable && this.allowCreate && !hasExistingOption
|
|
389
|
-
},
|
|
390
|
-
// Monta a lista com ou sem "Cadastrar Novo Item"
|
|
391
|
-
suggestionsList () {
|
|
392
|
-
if (this.loading) return []
|
|
393
|
-
|
|
394
|
-
// transformando em Array
|
|
395
|
-
const list =
|
|
396
|
-
typeof this.suggestions === 'object'
|
|
397
|
-
? Object.values(this.suggestions)
|
|
398
|
-
: this.suggestions
|
|
399
|
-
|
|
400
|
-
if (this.allowCreate) {
|
|
401
|
-
const createdSuggestion = { created: true }
|
|
402
|
-
|
|
403
|
-
createdSuggestion[this.valueKey] = this.query !== '' ? this.query : null
|
|
404
|
-
createdSuggestion[this.labelKey] = ''
|
|
405
|
-
list.push(createdSuggestion)
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
return list
|
|
409
|
-
},
|
|
410
|
-
|
|
411
|
-
emptyText () {
|
|
412
|
-
if (this.loading) {
|
|
413
|
-
return this.loadingText || this.t('el.select.loading')
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
if (this.remote && this.query === '' && this.options.length === 0) {
|
|
417
|
-
return this.noDataText || this.$tpI18n.t('autosuggests.sem_dados')
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
if (this.filterable && this.query && this.options.length > 0 && this.filteredOptionsCount === 0) {
|
|
421
|
-
return this.noMatchText || this.t('el.select.noMatch')
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
if (this.options.length === 0) {
|
|
425
|
-
return this.noDataText || this.$tpI18n.t('autosuggests.sem_dados')
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
return null
|
|
429
|
-
}
|
|
430
|
-
},
|
|
431
|
-
|
|
432
|
-
watch: {
|
|
433
|
-
// eslint-disable-next-line no-unused-vars
|
|
434
|
-
value (newValue, oldValue) {
|
|
435
|
-
// Se limpou com o X
|
|
436
|
-
if (!Array.isArray(newValue)) {
|
|
437
|
-
this.selectedLabelsArray = []
|
|
438
|
-
} else if (newValue.length > oldValue.length) {
|
|
439
|
-
const novoItem = newValue.filter(x => !oldValue.includes(x))
|
|
440
|
-
|
|
441
|
-
this.suggestionsList.forEach(item => {
|
|
442
|
-
if (item[this.valueKey] === novoItem[0]) {
|
|
443
|
-
this.selectedLabelsArray.push(item)
|
|
444
|
-
}
|
|
445
|
-
})
|
|
446
|
-
} else if (newValue && Object.keys(oldValue).length) {
|
|
447
|
-
let itemApagado = []
|
|
448
|
-
if (Array.isArray(oldValue)) {
|
|
449
|
-
itemApagado = oldValue.filter(x => !newValue?.includes(x))
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
this.selectedLabelsArray.forEach((item, index) => {
|
|
453
|
-
if (item[this.valueKey] === itemApagado[0]) {
|
|
454
|
-
this.selectedLabelsArray.splice(index, 1)
|
|
455
|
-
}
|
|
456
|
-
})
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
this.selectedLabels = this.selectedLabelsArray
|
|
460
|
-
.map(item => {
|
|
461
|
-
return item[this.labelKey]
|
|
462
|
-
})
|
|
463
|
-
.join(', ')
|
|
464
|
-
},
|
|
465
|
-
|
|
466
|
-
suggestionsList (_newValue, _oldValue) {
|
|
467
|
-
this.setSelectedLabel()
|
|
468
|
-
}
|
|
469
|
-
},
|
|
470
|
-
|
|
471
|
-
created () {
|
|
472
|
-
this.debouncedQueryChange = debounce(this.debounce, e => {
|
|
473
|
-
if (e.isComposing) {
|
|
474
|
-
// Se está apagando
|
|
475
|
-
if (e.target.value === '') {
|
|
476
|
-
this.query = this.query.slice(0, -1)
|
|
477
|
-
} else {
|
|
478
|
-
// Pega valor ignorando composition mode
|
|
479
|
-
this.query = e.target.value
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
this.handleQueryChange(this.query)
|
|
483
|
-
} else {
|
|
484
|
-
let forceBusca = false
|
|
485
|
-
|
|
486
|
-
// Quando clica fora enquanto está editando refaz a busca
|
|
487
|
-
if (!this.query && !e.target.value) {
|
|
488
|
-
forceBusca = true
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
this.query = e.target.value
|
|
492
|
-
this.handleQueryChange(e.target.value, forceBusca)
|
|
493
|
-
}
|
|
494
|
-
})
|
|
495
|
-
|
|
496
|
-
this.setSelectedLabel()
|
|
497
|
-
},
|
|
498
|
-
|
|
499
|
-
beforeMount () {
|
|
500
|
-
this.doRequest = false
|
|
501
|
-
|
|
502
|
-
if (this.loadOnCreate) {
|
|
503
|
-
this.previousQuery = false
|
|
504
|
-
// Chama função do element-ui select que faz o remote method
|
|
505
|
-
this.handleQueryChange('', true)
|
|
506
|
-
} else {
|
|
507
|
-
// Marca para fazer a requisição no primeiro clique
|
|
508
|
-
this.doRequest = true
|
|
509
|
-
}
|
|
510
|
-
},
|
|
511
|
-
|
|
512
|
-
methods: {
|
|
513
|
-
emitChange (val) {
|
|
514
|
-
if (!valueEquals(this.formatedValue, val)) {
|
|
515
|
-
this.$nextTick(() => {
|
|
516
|
-
this.$emit('change', val, this.createdSelected)
|
|
517
|
-
})
|
|
518
|
-
}
|
|
519
|
-
},
|
|
520
|
-
|
|
521
|
-
setSelectedLabel () {
|
|
522
|
-
if (Array.isArray(this.value)) {
|
|
523
|
-
this.value.forEach((item, key) => {
|
|
524
|
-
this.suggestionsList.forEach(suggestion => {
|
|
525
|
-
// Valida se o item passado e o suggest são iguais e se a label ja nao foi adicionada
|
|
526
|
-
if (item === suggestion[this.valueKey] && !this.selectedLabelsArray.includes(suggestion)) {
|
|
527
|
-
this.selectedLabelsArray.push(suggestion)
|
|
528
|
-
}
|
|
529
|
-
})
|
|
530
|
-
})
|
|
531
|
-
} else if (process.env.DEBUG === 'true') {
|
|
532
|
-
console.log(`'${this.$options.name}' recebeu valor em formato inválido.`)
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
this.selectedLabels = this.selectedLabelsArray
|
|
536
|
-
.map(item => {
|
|
537
|
-
return item[this.labelKey]
|
|
538
|
-
})
|
|
539
|
-
.join(', ')
|
|
540
|
-
},
|
|
541
|
-
|
|
542
|
-
// eslint-disable-next-line no-unused-vars
|
|
543
|
-
clearTags (event) {
|
|
544
|
-
// Faz uma requisição limpa
|
|
545
|
-
this.query = ''
|
|
546
|
-
this.doRequest = true
|
|
547
|
-
this.previousQuery = ''
|
|
548
|
-
this.handleQueryChange(this.query)
|
|
549
|
-
|
|
550
|
-
this.selectedLabels = []
|
|
551
|
-
this.selectedLabelsArray = []
|
|
552
|
-
// Eventos ao limpar
|
|
553
|
-
this.$emit('input', [])
|
|
554
|
-
this.$emit('change', [], this.value)
|
|
555
|
-
},
|
|
556
|
-
|
|
557
|
-
/**
|
|
558
|
-
* Sobrescreve o getOption do select para mostrar o labelValue em vez do idValue
|
|
559
|
-
*/
|
|
560
|
-
getOption (val) {
|
|
561
|
-
let value = ''
|
|
562
|
-
let initialLabel = false
|
|
563
|
-
if (typeof this.value === 'boolean') {
|
|
564
|
-
value = ''
|
|
565
|
-
} else if (Array.isArray(this.value)) {
|
|
566
|
-
value = val
|
|
567
|
-
} else if (val && typeof val === 'object') {
|
|
568
|
-
if (!Object.keys(val).length) { return {} }
|
|
569
|
-
// Se val for Object converte para outro tipo
|
|
570
|
-
if (!this.value[this.valueKey] && this.value[this.valueKey] !== '') {
|
|
571
|
-
console.error(`Multisuggest '${this.$options.name}' option doesn't have a valueKey '${this.valueKey}' key`)
|
|
572
|
-
} else {
|
|
573
|
-
// Se mandou a label no objeto value
|
|
574
|
-
if (val[this.labelKey]) {
|
|
575
|
-
initialLabel = val[this.labelKey]
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
value = val
|
|
579
|
-
}
|
|
580
|
-
} else {
|
|
581
|
-
value = val
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
let option
|
|
585
|
-
const isObject =
|
|
586
|
-
Object.prototype.toString.call(value).toLowerCase() ===
|
|
587
|
-
'[object object]'
|
|
588
|
-
const isNull =
|
|
589
|
-
Object.prototype.toString.call(value).toLowerCase() === '[object null]'
|
|
590
|
-
const isUndefined =
|
|
591
|
-
Object.prototype.toString.call(value).toLowerCase() ===
|
|
592
|
-
'[object undefined]'
|
|
593
|
-
|
|
594
|
-
for (let i = 0; i <= this.cachedOptions.length - 1; i++) {
|
|
595
|
-
const cachedOption = this.cachedOptions[i]
|
|
596
|
-
const isEqual = isObject
|
|
597
|
-
? getValueByPath(cachedOption.value, this.valueKey) ===
|
|
598
|
-
getValueByPath(value, this.valueKey)
|
|
599
|
-
: cachedOption.value === value
|
|
600
|
-
|
|
601
|
-
if (isEqual) {
|
|
602
|
-
option = cachedOption
|
|
603
|
-
break
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
if (option) return option
|
|
608
|
-
|
|
609
|
-
const label = !isObject && !isNull && !isUndefined ? value : ''
|
|
610
|
-
const newOption = {
|
|
611
|
-
value,
|
|
612
|
-
currentLabel: initialLabel || label
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
if (this.multiple) {
|
|
616
|
-
newOption.hitState = false
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
return newOption
|
|
620
|
-
},
|
|
621
|
-
checkDefaultFirstOption () {
|
|
622
|
-
this.$nextTick(() => {
|
|
623
|
-
this.hoverIndex = -1
|
|
624
|
-
|
|
625
|
-
for (let i = 0; i !== this.options.length; ++i) {
|
|
626
|
-
const option = this.options[i]
|
|
627
|
-
|
|
628
|
-
if (this.query) {
|
|
629
|
-
// highlight first options that passes the filter
|
|
630
|
-
if (!option.disabled && !option.groupDisabled && option.visible) {
|
|
631
|
-
this.hoverIndex = i
|
|
632
|
-
break
|
|
633
|
-
}
|
|
634
|
-
} else {
|
|
635
|
-
// highlight currently selected option
|
|
636
|
-
if (option.itemSelected) {
|
|
637
|
-
this.hoverIndex = i
|
|
638
|
-
break
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
})
|
|
643
|
-
},
|
|
644
|
-
/**
|
|
645
|
-
* Sobrescreve a função de abrir menu do select para fazer a busca quando loadOnCreate = false
|
|
646
|
-
*/
|
|
647
|
-
toggleMenu () {
|
|
648
|
-
if (!this.selectDisabled) {
|
|
649
|
-
// Se mantem visivel quando clica nele aberto
|
|
650
|
-
if (this.menuVisibleOnFocus) {
|
|
651
|
-
this.menuVisibleOnFocus = false
|
|
652
|
-
} else {
|
|
653
|
-
this.visible = !this.visible
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
if (this.doRequest) {
|
|
657
|
-
this.handleQueryChange(this.query, true)
|
|
658
|
-
this.doRequest = false
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
(this.$refs.input || this.$refs.reference).focus()
|
|
662
|
-
}
|
|
663
|
-
},
|
|
664
|
-
|
|
665
|
-
handleClose () {
|
|
666
|
-
this.selectedLabelsArray = []
|
|
667
|
-
this.visible && this.$emit('closeSelect')
|
|
668
|
-
this.visible = false
|
|
669
|
-
// Limpa busca quando fecha
|
|
670
|
-
this.doRequest = true
|
|
671
|
-
},
|
|
672
|
-
|
|
673
|
-
/**
|
|
674
|
-
* Sobrescreve função do select
|
|
675
|
-
*/
|
|
676
|
-
handleQueryChange (val, forceBusca = false) {
|
|
677
|
-
const _this6 = this
|
|
678
|
-
|
|
679
|
-
// Correção aqui para forçar primeira request com createOnLoad = false
|
|
680
|
-
// Não considera isOnComposition mais
|
|
681
|
-
if (!this.doRequest && this.previousQuery === val) return
|
|
682
|
-
|
|
683
|
-
if (!forceBusca) {
|
|
684
|
-
if (
|
|
685
|
-
this.previousQuery === null &&
|
|
686
|
-
(typeof this.filterMethod === 'function' ||
|
|
687
|
-
typeof this.remoteMethod === 'function')
|
|
688
|
-
) {
|
|
689
|
-
this.previousQuery = val
|
|
690
|
-
|
|
691
|
-
return
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
this.previousQuery = val
|
|
696
|
-
this.$nextTick(() => {
|
|
697
|
-
if (_this6.visible) _this6.broadcast('ElSelectDropdown', 'updatePopper')
|
|
698
|
-
})
|
|
699
|
-
this.hoverIndex = -1
|
|
700
|
-
|
|
701
|
-
if (this.multiple && this.filterable) {
|
|
702
|
-
this.$nextTick(() => {
|
|
703
|
-
const length = _this6.$refs.input.value.length * 15 + 20
|
|
704
|
-
|
|
705
|
-
_this6.inputLength = _this6.collapseTags
|
|
706
|
-
? Math.min(50, length)
|
|
707
|
-
: length
|
|
708
|
-
_this6.managePlaceholder()
|
|
709
|
-
_this6.resetInputHeight()
|
|
710
|
-
})
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
if (this.remote && typeof this.remoteMethod === 'function') {
|
|
714
|
-
this.hoverIndex = -1
|
|
715
|
-
this.remoteMethod(val)
|
|
716
|
-
} else if (typeof this.filterMethod === 'function') {
|
|
717
|
-
this.filterMethod(val)
|
|
718
|
-
this.broadcast('ElOptionGroup', 'queryChange')
|
|
719
|
-
} else {
|
|
720
|
-
this.filteredOptionsCount = this.optionsCount
|
|
721
|
-
this.broadcast('ElOption', 'queryChange', val)
|
|
722
|
-
this.broadcast('ElOptionGroup', 'queryChange')
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
if (
|
|
726
|
-
this.defaultFirstOption &&
|
|
727
|
-
(this.filterable || this.remote) &&
|
|
728
|
-
this.filteredOptionsCount
|
|
729
|
-
) {
|
|
730
|
-
this.checkDefaultFirstOption()
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
</script>
|
|
736
|
-
|
|
737
|
-
<style lang="scss" scoped>
|
|
738
|
-
:deep(){
|
|
739
|
-
.el-input-group__append {
|
|
740
|
-
padding: 0px 6px 0px 0px;
|
|
741
|
-
border: 0px;
|
|
742
|
-
width: 58px;
|
|
743
|
-
max-width: 58px;
|
|
744
|
-
.rightContent {
|
|
745
|
-
width: 40px;
|
|
746
|
-
max-width: 40px;
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
input.el-input__inner {
|
|
752
|
-
margin-right: 0px;
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
.el-input__icon {
|
|
756
|
-
width: auto;
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
.icon-close {
|
|
760
|
-
color: #606266;
|
|
761
|
-
cursor: pointer;
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
.el-select .el-input__inner {
|
|
765
|
-
padding-right: 15px;
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
.dividerSuggest {
|
|
769
|
-
height: 33.59px;
|
|
770
|
-
margin: 0px;
|
|
771
|
-
}
|
|
772
|
-
|
|
773
|
-
.tp-multisuggest.el-select {
|
|
774
|
-
> .el-input {
|
|
775
|
-
display: inline-table;
|
|
776
|
-
}
|
|
777
|
-
.el-input__suffix {
|
|
778
|
-
cursor: pointer;
|
|
779
|
-
}
|
|
780
|
-
.el-select__tags {
|
|
781
|
-
width: calc(100% - 64px);
|
|
782
|
-
}
|
|
783
|
-
.el-tag:hover {
|
|
784
|
-
cursor: pointer;
|
|
785
|
-
}
|
|
786
|
-
.el-tag.el-tag--info {
|
|
787
|
-
word-wrap: break-word;
|
|
788
|
-
white-space: -moz-pre-wrap;
|
|
789
|
-
white-space: pre-wrap;
|
|
790
|
-
height: auto;
|
|
791
|
-
margin-left: 30px;
|
|
792
|
-
}
|
|
793
|
-
.el-select__input {
|
|
794
|
-
margin-right: 0px;
|
|
795
|
-
width: 100%;
|
|
796
|
-
margin-left: 30px;
|
|
797
|
-
height: auto;
|
|
798
|
-
background: transparent;
|
|
799
|
-
padding-left: 0px;
|
|
800
|
-
&.tag {
|
|
801
|
-
margin-left: 5px;
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
.tp-multisuggest-loading {
|
|
807
|
-
text-align: center;
|
|
808
|
-
font-size: 1.5em;
|
|
809
|
-
padding: 10px;
|
|
810
|
-
margin: 0;
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
.tp-select-dropdown__list.el-select-dropdown__list {
|
|
814
|
-
li.el-select-dropdown__item {
|
|
815
|
-
line-height: 1.5em;
|
|
816
|
-
height: auto;
|
|
817
|
-
padding: $--popover-padding;
|
|
818
|
-
position: relative;
|
|
819
|
-
transition: 100ms all linear;
|
|
820
|
-
|
|
821
|
-
&.hover {
|
|
822
|
-
background-color: #f5f7fa;
|
|
823
|
-
font-weight: bold;
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
&.selected {
|
|
827
|
-
color: #2d6eda;
|
|
828
|
-
padding-left: 30px;
|
|
829
|
-
background-color: #f0f3f9;
|
|
830
|
-
border-radius: 5px;
|
|
831
|
-
font-weight: none;
|
|
832
|
-
|
|
833
|
-
&::before {
|
|
834
|
-
position: absolute;
|
|
835
|
-
left: 7px;
|
|
836
|
-
font-family: element-icons;
|
|
837
|
-
content: "\e6da";
|
|
838
|
-
font-size: 15px;
|
|
839
|
-
}
|
|
840
|
-
&::after {
|
|
841
|
-
content: "";
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
&.created a {
|
|
845
|
-
color: $--color-primary;
|
|
846
|
-
font-weight: normal;
|
|
847
|
-
border-bottom: 1px solid $--color-primary;
|
|
848
|
-
line-height: 1.5em;
|
|
849
|
-
display: inline-block;
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
small {
|
|
853
|
-
font-size: $--font-size-base;
|
|
854
|
-
color: mix($--color-white, $--color-text-secondary, 40%);
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
}
|
|
858
|
-
</style>
|