@bildvitta/quasar-ui-asteroid 3.5.0-beta.0 → 3.5.0-beta.2
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/package.json +2 -2
- package/src/components/actions-menu/QasActionsMenu.vue +86 -37
- package/src/components/actions-menu/QasActionsMenu.yml +6 -6
- package/src/components/app-menu/QasAppMenu.vue +1 -1
- package/src/components/copy/QasCopy.vue +1 -1
- package/src/components/delete/QasDelete.vue +12 -5
- package/src/components/field/QasField.vue +7 -0
- package/src/components/form-generator/QasFormGenerator.yml +1 -1
- package/src/components/form-view/QasFormView.vue +14 -7
- package/src/components/form-view/QasFormView.yml +2 -2
- package/src/components/grid-generator/QasGridGenerator.yml +1 -1
- package/src/components/list-view/QasListView.vue +67 -8
- package/src/components/list-view/QasListView.yml +4 -0
- package/src/components/nested-fields/QasNestedFields.vue +101 -41
- package/src/components/nested-fields/QasNestedFields.yml +30 -10
- package/src/components/page-header/QasPageHeader.vue +1 -10
- package/src/components/pagination/QasPagination.vue +27 -0
- package/src/components/pagination/QasPagination.yml +4 -0
- package/src/components/select/QasSelect.vue +2 -4
- package/src/components/table-generator/QasTableGenerator.vue +10 -2
- package/src/components/table-generator/QasTableGenerator.yml +14 -0
- package/src/components/text-truncate/QasTextTruncate.vue +1 -1
- package/src/css/components/item.scss +4 -0
- package/src/css/plugins/index.scss +1 -0
- package/src/css/plugins/notify.scss +41 -0
- package/src/css/variables/spacing.scss +5 -5
- package/src/helpers/set-scroll-on-grab.js +13 -4
- package/src/index.scss +4 -1
- package/src/mixins/generator.js +1 -1
- package/src/mixins/view.js +5 -2
- package/src/plugins/notify-error/NotifyError.js +7 -5
- package/src/plugins/notify-success/NotifySuccess.js +7 -5
- package/src/shared/notify-config.js +7 -0
- package/src/vue-plugin.js +3 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bildvitta/quasar-ui-asteroid",
|
|
3
3
|
"description": "Asteroid",
|
|
4
|
-
"version": "3.5.0-beta.
|
|
4
|
+
"version": "3.5.0-beta.2",
|
|
5
5
|
"author": "Bild & Vitta <systemteam@bild.com.br>",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"main": "dist/asteroid.cjs.min.js",
|
|
@@ -64,4 +64,4 @@
|
|
|
64
64
|
"tags": "dist/vetur/asteroid-tags.json",
|
|
65
65
|
"attributes": "dist/vetur/asteroid-attributes.json"
|
|
66
66
|
}
|
|
67
|
-
}
|
|
67
|
+
}
|
|
@@ -1,49 +1,45 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
<q-
|
|
5
|
-
<
|
|
6
|
-
<
|
|
7
|
-
<
|
|
8
|
-
<
|
|
9
|
-
<q-icon :name="item.icon"
|
|
2
|
+
<div v-if="hasActions">
|
|
3
|
+
<component :is="component.is" flat v-bind="component.props" :use-label-on-small-screen="useLabelOnSmallScreen" @click="onClick()">
|
|
4
|
+
<q-menu v-if="hasMoreThanOneAction" auto-close class="q-py-xs">
|
|
5
|
+
<q-list>
|
|
6
|
+
<slot v-for="(item, key) in actions" :item="item" :name="key">
|
|
7
|
+
<component :is="getComponent(key)" v-bind="item.props" :key="key" clickable @click="onClick(item)">
|
|
8
|
+
<q-item-section avatar>
|
|
9
|
+
<q-icon :name="item.icon" />
|
|
10
|
+
</q-item-section>
|
|
11
|
+
|
|
12
|
+
<q-item-section>
|
|
10
13
|
<div>{{ item.label }}</div>
|
|
11
|
-
</
|
|
12
|
-
</
|
|
13
|
-
</
|
|
14
|
-
</
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
<div class="flex items-center justify-center q-gutter-x-sm">
|
|
19
|
-
<q-icon :name="deleteIcon" size="sm" />
|
|
20
|
-
<div>{{ deleteLabel }}</div>
|
|
21
|
-
</div>
|
|
22
|
-
</q-item-section>
|
|
23
|
-
</qas-delete>
|
|
24
|
-
</q-list>
|
|
25
|
-
</q-menu>
|
|
26
|
-
</qas-btn>
|
|
14
|
+
</q-item-section>
|
|
15
|
+
</component>
|
|
16
|
+
</slot>
|
|
17
|
+
</q-list>
|
|
18
|
+
</q-menu>
|
|
19
|
+
</component>
|
|
20
|
+
</div>
|
|
27
21
|
</template>
|
|
28
22
|
|
|
29
23
|
<script>
|
|
30
24
|
import QasBtn from '../btn/QasBtn.vue'
|
|
25
|
+
import QasDelete from '../delete/QasDelete.vue'
|
|
31
26
|
|
|
32
27
|
export default {
|
|
33
28
|
name: 'QasActionsMenu',
|
|
34
29
|
|
|
35
30
|
components: {
|
|
36
|
-
QasBtn
|
|
31
|
+
QasBtn,
|
|
32
|
+
QasDelete
|
|
37
33
|
},
|
|
38
34
|
|
|
39
35
|
props: {
|
|
40
36
|
icon: {
|
|
41
|
-
default: '
|
|
37
|
+
default: 'o_more_vert',
|
|
42
38
|
type: String
|
|
43
39
|
},
|
|
44
40
|
|
|
45
41
|
label: {
|
|
46
|
-
default: '
|
|
42
|
+
default: 'Opções',
|
|
47
43
|
type: String
|
|
48
44
|
},
|
|
49
45
|
|
|
@@ -65,17 +61,79 @@ export default {
|
|
|
65
61
|
deleteProps: {
|
|
66
62
|
default: () => ({}),
|
|
67
63
|
type: Object
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
useLabelOnSmallScreen: {
|
|
67
|
+
default: true,
|
|
68
|
+
type: Boolean
|
|
68
69
|
}
|
|
69
70
|
},
|
|
70
71
|
|
|
71
72
|
computed: {
|
|
73
|
+
actions () {
|
|
74
|
+
return {
|
|
75
|
+
...this.list,
|
|
76
|
+
...(this.hasDelete && {
|
|
77
|
+
delete: {
|
|
78
|
+
icon: this.deleteIcon,
|
|
79
|
+
label: this.deleteLabel,
|
|
80
|
+
props: {
|
|
81
|
+
...this.deleteProps,
|
|
82
|
+
tag: this.hasMoreThanOneAction ? 'q-item' : 'qas-btn'
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
component () {
|
|
90
|
+
const props = {}
|
|
91
|
+
|
|
92
|
+
if (this.hasMoreThanOneAction) {
|
|
93
|
+
props.label = 'Opções'
|
|
94
|
+
props.iconRight = this.icon
|
|
95
|
+
props.textColor = 'dark'
|
|
96
|
+
} else {
|
|
97
|
+
props.icon = this.actions[this.firstItemKey]?.icon
|
|
98
|
+
props.label = this.actions[this.firstItemKey]?.label
|
|
99
|
+
props.color = 'primary'
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
this.hasDelete && Object.assign(props, this.deleteProps)
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
is: this.hasMoreThanOneAction || !this.hasDelete ? 'qas-btn' : 'qas-delete',
|
|
106
|
+
props
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
firstItemKey () {
|
|
111
|
+
return Object.keys(this.actions)?.[0]
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
hasActions () {
|
|
115
|
+
return !!Object.keys(this.actions).length
|
|
116
|
+
},
|
|
117
|
+
|
|
72
118
|
hasDelete () {
|
|
73
119
|
return !!Object.keys(this.deleteProps).length
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
hasMoreThanOneAction () {
|
|
123
|
+
return Object.keys(this.actions || {}).length > 1
|
|
74
124
|
}
|
|
75
125
|
},
|
|
76
126
|
|
|
77
127
|
methods: {
|
|
78
|
-
|
|
128
|
+
getComponent (key) {
|
|
129
|
+
return key === 'delete' ? 'qas-delete' : 'q-item'
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
onClick (item = {}) {
|
|
133
|
+
if (!this.hasMoreThanOneAction) {
|
|
134
|
+
item = this.actions[this.firstItemKey]
|
|
135
|
+
}
|
|
136
|
+
|
|
79
137
|
if (typeof item.handler === 'function') {
|
|
80
138
|
const { handler, ...filtered } = item
|
|
81
139
|
item.handler(filtered)
|
|
@@ -84,12 +142,3 @@ export default {
|
|
|
84
142
|
}
|
|
85
143
|
}
|
|
86
144
|
</script>
|
|
87
|
-
|
|
88
|
-
<style lang="scss">
|
|
89
|
-
.qas-actions-menu {
|
|
90
|
-
&__list {
|
|
91
|
-
width: 265px;
|
|
92
|
-
z-index: 1;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
</style>
|
|
@@ -21,15 +21,10 @@ props:
|
|
|
21
21
|
|
|
22
22
|
icon:
|
|
23
23
|
desc: Ícone do botão.
|
|
24
|
-
default:
|
|
24
|
+
default: o_more_vert
|
|
25
25
|
type: String
|
|
26
26
|
examples: [start, end, between, around, center]
|
|
27
27
|
|
|
28
|
-
label:
|
|
29
|
-
desc: Rotulo do botão.
|
|
30
|
-
default: Configurações
|
|
31
|
-
type: String
|
|
32
|
-
|
|
33
28
|
list:
|
|
34
29
|
desc: Lista de items que vão ser criados dentro do menu de ações.
|
|
35
30
|
default: '{}'
|
|
@@ -44,6 +39,11 @@ props:
|
|
|
44
39
|
}"
|
|
45
40
|
]
|
|
46
41
|
|
|
42
|
+
use-label-on-small-screen:
|
|
43
|
+
desc: Esconde o rótulo (label) do botão quando o tamanho da tela for pequeno (esta propriedade só funciona se o "rotulo") for passado via propriedade "label".
|
|
44
|
+
default: true
|
|
45
|
+
type: Boolean
|
|
46
|
+
|
|
47
47
|
slots:
|
|
48
48
|
'[nome-da-chave]':
|
|
49
49
|
desc: 'Slot dinâmico gerado a partir das chaves dentro do objeto da prop "list"'
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<span>
|
|
3
3
|
<slot>{{ text }}</slot>
|
|
4
4
|
|
|
5
|
-
<qas-btn class="q-ml-xs" color="grey-7" flat :icon="icon" :loading="isLoading" round :size="size" @click="copy">
|
|
5
|
+
<qas-btn class="q-ml-xs" color="grey-7" flat :icon="icon" :loading="isLoading" round :size="size" @click.stop="copy">
|
|
6
6
|
<q-tooltip>Copiar</q-tooltip>
|
|
7
7
|
</qas-btn>
|
|
8
8
|
</span>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<component v-bind="$attrs" :is="tag" @click="openConfirmDialog">
|
|
2
|
+
<component v-bind="$attrs" :is="tag" @click.stop="openConfirmDialog">
|
|
3
3
|
<template v-for="(_, name) in $slots" #[name]="context">
|
|
4
4
|
<slot :name="name" v-bind="context || {}" />
|
|
5
5
|
</template>
|
|
@@ -92,6 +92,13 @@ export default {
|
|
|
92
92
|
|
|
93
93
|
id () {
|
|
94
94
|
return this.customId || this.$route.params.id
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
defaultNotifyMessages () {
|
|
98
|
+
return {
|
|
99
|
+
error: 'Não conseguimos excluir as informações. Por favor, tente novamente em alguns minutos.',
|
|
100
|
+
success: 'Informações excluídas com sucesso.'
|
|
101
|
+
}
|
|
95
102
|
}
|
|
96
103
|
},
|
|
97
104
|
|
|
@@ -105,8 +112,6 @@ export default {
|
|
|
105
112
|
this.$emit('update:deleting', true)
|
|
106
113
|
|
|
107
114
|
try {
|
|
108
|
-
const { destroyRoutes, history } = useHistory()
|
|
109
|
-
|
|
110
115
|
const payload = { id: this.id, url: this.url }
|
|
111
116
|
|
|
112
117
|
this.$qas.logger.group(
|
|
@@ -119,9 +124,11 @@ export default {
|
|
|
119
124
|
payload
|
|
120
125
|
})
|
|
121
126
|
|
|
122
|
-
NotifySuccess(
|
|
127
|
+
NotifySuccess(this.defaultNotifyMessages.success)
|
|
123
128
|
|
|
124
129
|
if (this.useAutoDeleteRoute) {
|
|
130
|
+
const { destroyRoutes, history } = useHistory()
|
|
131
|
+
|
|
125
132
|
// remove todas rotas que possuem o id do item excluído.
|
|
126
133
|
const routesToBeDeleted = this.getRoutesToBeDeletedById(history.list)
|
|
127
134
|
destroyRoutes(routesToBeDeleted)
|
|
@@ -134,7 +141,7 @@ export default {
|
|
|
134
141
|
|
|
135
142
|
this.$qas.logger.info('QasDelete - destroy -> item deletado com sucesso!')
|
|
136
143
|
} catch (error) {
|
|
137
|
-
NotifyError(
|
|
144
|
+
NotifyError(this.defaultNotifyMessages.error)
|
|
138
145
|
this.$emit('error', error)
|
|
139
146
|
|
|
140
147
|
this.$qas.logger.group(
|
|
@@ -159,11 +159,18 @@ export default {
|
|
|
159
159
|
// This computed will change the key name when the server sends different key.
|
|
160
160
|
formattedField () {
|
|
161
161
|
const field = {}
|
|
162
|
+
const nonRequiredFieldsLabel = ['boolean', 'checkbox', 'radio']
|
|
162
163
|
|
|
163
164
|
for (const key in this.field) {
|
|
164
165
|
field[attributesProfile[key] || key] = this.field[key]
|
|
165
166
|
}
|
|
166
167
|
|
|
168
|
+
const { label, required, type } = field
|
|
169
|
+
|
|
170
|
+
if (required && label && !nonRequiredFieldsLabel.includes(type)) {
|
|
171
|
+
field.label = `${label}*`
|
|
172
|
+
}
|
|
173
|
+
|
|
167
174
|
return field
|
|
168
175
|
},
|
|
169
176
|
|
|
@@ -58,7 +58,7 @@ export default {
|
|
|
58
58
|
|
|
59
59
|
props: {
|
|
60
60
|
cancelButtonLabel: {
|
|
61
|
-
default: '
|
|
61
|
+
default: 'Voltar',
|
|
62
62
|
type: String
|
|
63
63
|
},
|
|
64
64
|
|
|
@@ -196,6 +196,14 @@ export default {
|
|
|
196
196
|
|
|
197
197
|
isCancelButtonDisabled () {
|
|
198
198
|
return this.disable || this.isSubmitting
|
|
199
|
+
},
|
|
200
|
+
|
|
201
|
+
defaultNotifyMessages () {
|
|
202
|
+
return {
|
|
203
|
+
validationError: 'Existem campos no formulário que ainda não foram preenchidos. Complete todas as informações para avançar.',
|
|
204
|
+
error: 'Não conseguimos salvar as informações. Por favor, tente novamente em alguns minutos.',
|
|
205
|
+
success: 'Informações salvas com sucesso.'
|
|
206
|
+
}
|
|
199
207
|
}
|
|
200
208
|
},
|
|
201
209
|
|
|
@@ -420,7 +428,7 @@ export default {
|
|
|
420
428
|
}
|
|
421
429
|
|
|
422
430
|
this.mx_setErrors()
|
|
423
|
-
NotifySuccess(response.data.status.text ||
|
|
431
|
+
NotifySuccess(response.data.status.text || this.defaultNotifyMessages.success)
|
|
424
432
|
this.$emit('submit-success', response, this.modelValue)
|
|
425
433
|
|
|
426
434
|
this.$qas.logger.group(
|
|
@@ -429,16 +437,15 @@ export default {
|
|
|
429
437
|
} catch (error) {
|
|
430
438
|
const errors = error?.response?.data?.errors
|
|
431
439
|
const message = error?.response?.data?.status?.text
|
|
432
|
-
const exceptionResponse = error?.response?.data?.exception
|
|
433
440
|
|
|
434
|
-
const
|
|
435
|
-
?
|
|
436
|
-
:
|
|
441
|
+
const defaultMessage = error
|
|
442
|
+
? this.defaultNotifyMessages.validationError
|
|
443
|
+
: this.defaultNotifyMessages.error
|
|
437
444
|
|
|
438
445
|
this.mx_setErrors(errors)
|
|
439
446
|
this.$emit('update:errors', this.mx_errors)
|
|
440
447
|
|
|
441
|
-
NotifyError(message ||
|
|
448
|
+
NotifyError(message || defaultMessage)
|
|
442
449
|
|
|
443
450
|
this.$emit('submit-error', error)
|
|
444
451
|
|
|
@@ -16,9 +16,8 @@
|
|
|
16
16
|
|
|
17
17
|
<div v-else-if="!mx_isFetching">
|
|
18
18
|
<slot name="empty-results">
|
|
19
|
-
<div class="q-my-
|
|
20
|
-
|
|
21
|
-
<div class="text-grey-7">Nenhum item encontrado.</div>
|
|
19
|
+
<div class="q-my-lg text-body1 text-grey-7">
|
|
20
|
+
Não há itens para serem exibidos.
|
|
22
21
|
</div>
|
|
23
22
|
</slot>
|
|
24
23
|
</div>
|
|
@@ -27,8 +26,8 @@
|
|
|
27
26
|
<q-spinner color="grey" size="3em" />
|
|
28
27
|
</div>
|
|
29
28
|
|
|
30
|
-
<div v-if="hasPages" class="
|
|
31
|
-
<
|
|
29
|
+
<div v-if="hasPages" class="flex items-center q-mt-sm" :class="paginationClasses">
|
|
30
|
+
<qas-pagination v-model="page" :max="totalPages" @click="changePage" />
|
|
32
31
|
</div>
|
|
33
32
|
|
|
34
33
|
<q-inner-loading :showing="hasResults && mx_isFetching">
|
|
@@ -44,12 +43,14 @@
|
|
|
44
43
|
<script>
|
|
45
44
|
import { viewMixin, contextMixin } from '../../mixins'
|
|
46
45
|
import QasFilters from '../filters/QasFilters.vue'
|
|
46
|
+
import QasPagination from '../pagination/QasPagination.vue'
|
|
47
47
|
import { extend } from 'quasar'
|
|
48
48
|
import { getState, getAction } from '@bildvitta/store-adapter'
|
|
49
49
|
|
|
50
50
|
export default {
|
|
51
51
|
components: {
|
|
52
|
-
QasFilters
|
|
52
|
+
QasFilters,
|
|
53
|
+
QasPagination
|
|
53
54
|
},
|
|
54
55
|
|
|
55
56
|
mixins: [contextMixin, viewMixin],
|
|
@@ -65,6 +66,10 @@ export default {
|
|
|
65
66
|
type: Array
|
|
66
67
|
},
|
|
67
68
|
|
|
69
|
+
useAutoHandleOnDelete: {
|
|
70
|
+
type: Boolean
|
|
71
|
+
},
|
|
72
|
+
|
|
68
73
|
useRefresh: {
|
|
69
74
|
default: true,
|
|
70
75
|
type: Boolean
|
|
@@ -89,7 +94,8 @@ export default {
|
|
|
89
94
|
|
|
90
95
|
data () {
|
|
91
96
|
return {
|
|
92
|
-
page: 1
|
|
97
|
+
page: 1,
|
|
98
|
+
resultsQuantity: 0
|
|
93
99
|
}
|
|
94
100
|
},
|
|
95
101
|
|
|
@@ -116,6 +122,10 @@ export default {
|
|
|
116
122
|
|
|
117
123
|
showResults () {
|
|
118
124
|
return this.hasResults || this.useResultsAreaOnly
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
paginationClasses () {
|
|
128
|
+
return this.$qas.screen.isSmall ? 'justify-center column' : 'justify-end'
|
|
119
129
|
}
|
|
120
130
|
},
|
|
121
131
|
|
|
@@ -142,6 +152,18 @@ export default {
|
|
|
142
152
|
this.setCurrentPage()
|
|
143
153
|
},
|
|
144
154
|
|
|
155
|
+
mounted () {
|
|
156
|
+
if (!this.useAutoHandleOnDelete) return
|
|
157
|
+
|
|
158
|
+
window.addEventListener('delete-success', this.onDeleteResult)
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
unmounted () {
|
|
162
|
+
if (!this.useAutoHandleOnDelete) return
|
|
163
|
+
|
|
164
|
+
window.removeEventListener('delete-success', this.onDeleteResult)
|
|
165
|
+
},
|
|
166
|
+
|
|
145
167
|
methods: {
|
|
146
168
|
changePage () {
|
|
147
169
|
const query = { ...this.$route.query, page: this.page }
|
|
@@ -168,7 +190,8 @@ export default {
|
|
|
168
190
|
payload
|
|
169
191
|
})
|
|
170
192
|
|
|
171
|
-
const { errors, fields, metadata } = response.data
|
|
193
|
+
const { errors, fields, metadata, results } = response.data
|
|
194
|
+
this.resultsQuantity = results.length
|
|
172
195
|
|
|
173
196
|
this.mx_setErrors(errors)
|
|
174
197
|
this.mx_setFields(fields)
|
|
@@ -210,6 +233,42 @@ export default {
|
|
|
210
233
|
|
|
211
234
|
setCurrentPage () {
|
|
212
235
|
this.page = parseInt(this.$route.query.page || 1)
|
|
236
|
+
},
|
|
237
|
+
|
|
238
|
+
onDeleteResult ({ detail: { entity } }) {
|
|
239
|
+
const { page } = this.mx_context
|
|
240
|
+
|
|
241
|
+
/*
|
|
242
|
+
* - se a entidade que estiver sendo excluída for diferente da entidade da listagem, ignora.
|
|
243
|
+
* - se a ultima pagina da paginação for igual a pagina atual e tiver mais de um resultado, ignora.
|
|
244
|
+
* - se não existir paginação (somente 1), ignora.
|
|
245
|
+
*/
|
|
246
|
+
const skipRefreshList = [
|
|
247
|
+
(entity !== this.entity),
|
|
248
|
+
(this.totalPages === page && this.resultsQuantity > 1),
|
|
249
|
+
(this.totalPages === 1)
|
|
250
|
+
]
|
|
251
|
+
|
|
252
|
+
this.resultsQuantity -= 1
|
|
253
|
+
|
|
254
|
+
if (skipRefreshList.find(Boolean)) return
|
|
255
|
+
|
|
256
|
+
/*
|
|
257
|
+
* caso eu remova o ultimo item da ultima pagina eu volto ele para a pagina anterior
|
|
258
|
+
* ex: estou na pagina 3 que é a ultima pagina, e removo o ultimo item dela, eu volto o usuário para pagina 2
|
|
259
|
+
*/
|
|
260
|
+
if (this.resultsQuantity === 1 || !this.resultsQuantity) {
|
|
261
|
+
const { path, query } = this.$route
|
|
262
|
+
|
|
263
|
+
this.$router.replace({ path, query: { ...query, page: query.page - 1 } })
|
|
264
|
+
return
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/*
|
|
268
|
+
* caso remova algo de uma pagina que não seja a ultima, chama o método fetchList novamente
|
|
269
|
+
* ex: estou na pagina 2 e existem 3 paginas, removo um item da pagina 2, então chamo o método fetchList
|
|
270
|
+
*/
|
|
271
|
+
this.mx_fetchHandler({ ...this.mx_context, url: this.url }, this.fetchList)
|
|
213
272
|
}
|
|
214
273
|
}
|
|
215
274
|
}
|
|
@@ -58,6 +58,10 @@ props:
|
|
|
58
58
|
desc: Envia como parâmetro para a action "fetchList" do modulo correspondente a "entity".
|
|
59
59
|
type: String
|
|
60
60
|
|
|
61
|
+
use-auto-handle-on-delete:
|
|
62
|
+
desc: Controla se o componente vai lidar automaticamente quando acontecer algum delete compatível com a listagem.
|
|
63
|
+
type: Boolean
|
|
64
|
+
|
|
61
65
|
use-boundary:
|
|
62
66
|
desc: Controla o limite que o FormView terá, quando é "false", a tag pai deixa de ser um "QPage" para ser uma "div" e é removido as classes "container" e "spaced", comumente utilizando quando precisa usar o QasFormView dentro de um dialog.
|
|
63
67
|
default: true
|
|
@@ -11,11 +11,7 @@
|
|
|
11
11
|
<div>
|
|
12
12
|
<div class="flex items-center justify-between q-py-xs">
|
|
13
13
|
<qas-label v-if="!useSingleLabel" :label="getRowLabel(index)" />
|
|
14
|
-
|
|
15
|
-
<div v-if="hasBlockActions(row)" class="q-gutter-x-sm">
|
|
16
|
-
<qas-btn v-if="useDuplicate" v-bind="buttonDuplicateProps" @click="add(row)" />
|
|
17
|
-
<qas-btn v-if="showDestroyBtn" v-bind="buttonDestroyProps" @click="destroy(index, row)" />
|
|
18
|
-
</div>
|
|
14
|
+
<qas-actions-menu v-if="hasBlockActions(row)" :list="getActionsList(index, row)" :use-label-on-small-screen="false" />
|
|
19
15
|
</div>
|
|
20
16
|
|
|
21
17
|
<div ref="formGenerator" class="col-12 justify-between q-col-gutter-x-md row">
|
|
@@ -28,12 +24,7 @@
|
|
|
28
24
|
</slot>
|
|
29
25
|
|
|
30
26
|
<div v-if="hasInlineActions(row)" class="flex items-center qas-nested-fields__actions">
|
|
31
|
-
<
|
|
32
|
-
<qas-btn v-if="useDuplicate" color="primary" flat icon="o_content_copy" round @click="add(row)" />
|
|
33
|
-
</div>
|
|
34
|
-
<div class="col-auto">
|
|
35
|
-
<qas-btn v-if="showDestroyBtn" color="negative" flat icon="o_cancel" round @click="destroy(index, row)" />
|
|
36
|
-
</div>
|
|
27
|
+
<qas-actions-menu :list="getActionsList(index, row)" :use-label-on-small-screen="false" />
|
|
37
28
|
</div>
|
|
38
29
|
</div>
|
|
39
30
|
|
|
@@ -47,18 +38,22 @@
|
|
|
47
38
|
|
|
48
39
|
<div v-if="useAdd" class="q-mt-md">
|
|
49
40
|
<slot :add="add" name="add-input">
|
|
50
|
-
<div v-if="
|
|
41
|
+
<div v-if="showAddFirstInputButton" class="text-left">
|
|
42
|
+
<qas-btn class="q-px-sm" color="dark" flat @click="add()">{{ addFirstInputLabel }}</qas-btn>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<div v-else-if="useInlineActions" class="cursor-pointer items-center q-col-gutter-x-md q-mt-md row" @click="add()">
|
|
51
46
|
<div class="col">
|
|
52
47
|
<qas-input class="disabled no-pointer-events" hide-bottom-space :label="addInputLabel" outlined @focus="add()" />
|
|
53
48
|
</div>
|
|
54
49
|
|
|
55
50
|
<div class="col-auto">
|
|
56
|
-
<qas-btn color="
|
|
51
|
+
<qas-btn color="dark" flat icon="o_add_circle_outline" round />
|
|
57
52
|
</div>
|
|
58
53
|
</div>
|
|
59
54
|
|
|
60
|
-
<div v-else class="
|
|
61
|
-
<qas-btn class="
|
|
55
|
+
<div v-else class="text-left">
|
|
56
|
+
<qas-btn class="q-px-sm" color="dark" flat icon="o_add" @click="add()">{{ addInputLabel }}</qas-btn>
|
|
62
57
|
</div>
|
|
63
58
|
</slot>
|
|
64
59
|
</div>
|
|
@@ -67,6 +62,7 @@
|
|
|
67
62
|
</template>
|
|
68
63
|
|
|
69
64
|
<script>
|
|
65
|
+
import QasActionsMenu from '../actions-menu/QasActionsMenu.vue'
|
|
70
66
|
import QasBtn from '../btn/QasBtn.vue'
|
|
71
67
|
import QasFormGenerator from '../form-generator/QasFormGenerator.vue'
|
|
72
68
|
import QasInput from '../input/QasInput.vue'
|
|
@@ -80,27 +76,38 @@ export default {
|
|
|
80
76
|
name: 'QasNestedFields',
|
|
81
77
|
|
|
82
78
|
components: {
|
|
79
|
+
QasActionsMenu,
|
|
83
80
|
QasBtn,
|
|
84
81
|
QasFormGenerator,
|
|
85
82
|
QasInput,
|
|
86
83
|
QasLabel,
|
|
87
84
|
|
|
88
|
-
//
|
|
85
|
+
// Vue
|
|
89
86
|
TransitionGroup
|
|
90
87
|
},
|
|
91
88
|
|
|
92
89
|
props: {
|
|
90
|
+
actionsMenuProps: {
|
|
91
|
+
type: Object,
|
|
92
|
+
default: () => ({})
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
addFirstInputLabel: {
|
|
96
|
+
type: String,
|
|
97
|
+
default: 'Clique aqui para adicionar'
|
|
98
|
+
},
|
|
99
|
+
|
|
93
100
|
addInputLabel: {
|
|
94
101
|
type: String,
|
|
95
|
-
default: '
|
|
102
|
+
default: 'Adicionar'
|
|
96
103
|
},
|
|
97
104
|
|
|
98
105
|
buttonDestroyProps: {
|
|
99
106
|
type: Object,
|
|
100
107
|
default: () => {
|
|
101
108
|
return {
|
|
102
|
-
label: '
|
|
103
|
-
icon: '
|
|
109
|
+
label: 'Excluir',
|
|
110
|
+
icon: 'o_delete',
|
|
104
111
|
flat: true,
|
|
105
112
|
dense: true
|
|
106
113
|
}
|
|
@@ -190,7 +197,8 @@ export default {
|
|
|
190
197
|
},
|
|
191
198
|
|
|
192
199
|
useDestroyAlways: {
|
|
193
|
-
type: Boolean
|
|
200
|
+
type: Boolean,
|
|
201
|
+
default: undefined
|
|
194
202
|
},
|
|
195
203
|
|
|
196
204
|
useDuplicate: {
|
|
@@ -198,6 +206,11 @@ export default {
|
|
|
198
206
|
default: true
|
|
199
207
|
},
|
|
200
208
|
|
|
209
|
+
useFirstInputButton: {
|
|
210
|
+
type: Boolean,
|
|
211
|
+
default: true
|
|
212
|
+
},
|
|
213
|
+
|
|
201
214
|
useIndexLabel: {
|
|
202
215
|
type: Boolean
|
|
203
216
|
},
|
|
@@ -215,6 +228,11 @@ export default {
|
|
|
215
228
|
default: true
|
|
216
229
|
},
|
|
217
230
|
|
|
231
|
+
useStartsEmpty: {
|
|
232
|
+
default: true,
|
|
233
|
+
type: Boolean
|
|
234
|
+
},
|
|
235
|
+
|
|
218
236
|
modelValue: {
|
|
219
237
|
type: Array,
|
|
220
238
|
default: () => []
|
|
@@ -225,25 +243,35 @@ export default {
|
|
|
225
243
|
|
|
226
244
|
data () {
|
|
227
245
|
return {
|
|
228
|
-
nested: []
|
|
246
|
+
nested: [],
|
|
247
|
+
hasDestroyAlways: true
|
|
229
248
|
}
|
|
230
249
|
},
|
|
231
250
|
|
|
232
251
|
computed: {
|
|
233
|
-
|
|
234
|
-
return this.field?.
|
|
252
|
+
children () {
|
|
253
|
+
return this.field?.children
|
|
235
254
|
},
|
|
236
255
|
|
|
237
|
-
|
|
238
|
-
return this.
|
|
256
|
+
componentTag () {
|
|
257
|
+
return this.useAnimation ? 'transition-group' : 'div'
|
|
239
258
|
},
|
|
240
259
|
|
|
241
|
-
|
|
242
|
-
|
|
260
|
+
componentProps () {
|
|
261
|
+
if (!this.useAnimation) return {}
|
|
262
|
+
|
|
263
|
+
return {
|
|
264
|
+
tag: 'div',
|
|
265
|
+
enterActiveClass: 'animated slideInDown'
|
|
266
|
+
}
|
|
243
267
|
},
|
|
244
268
|
|
|
245
|
-
|
|
246
|
-
return this.
|
|
269
|
+
fieldLabel () {
|
|
270
|
+
return this.field?.label
|
|
271
|
+
},
|
|
272
|
+
|
|
273
|
+
fieldName () {
|
|
274
|
+
return this.field?.name
|
|
247
275
|
},
|
|
248
276
|
|
|
249
277
|
formClasses () {
|
|
@@ -253,21 +281,16 @@ export default {
|
|
|
253
281
|
}
|
|
254
282
|
},
|
|
255
283
|
|
|
256
|
-
|
|
257
|
-
return
|
|
284
|
+
showDestroyButton () {
|
|
285
|
+
return this.nested.filter(item => !item[this.destroyKey]).length > 1 || this.hasDestroyAlways
|
|
258
286
|
},
|
|
259
287
|
|
|
260
|
-
|
|
261
|
-
return this.
|
|
288
|
+
transformedErrors () {
|
|
289
|
+
return Array.isArray(this.errors) ? this.errors : constructObject(this.fieldName, this.errors)
|
|
262
290
|
},
|
|
263
291
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
return {
|
|
268
|
-
tag: 'div',
|
|
269
|
-
enterActiveClass: 'animated slideInDown'
|
|
270
|
-
}
|
|
292
|
+
showAddFirstInputButton () {
|
|
293
|
+
return this.useFirstInputButton && !this.nested.length
|
|
271
294
|
}
|
|
272
295
|
},
|
|
273
296
|
|
|
@@ -282,13 +305,49 @@ export default {
|
|
|
282
305
|
|
|
283
306
|
rowObject: {
|
|
284
307
|
handler () {
|
|
285
|
-
|
|
308
|
+
this.setDefaultNestedValue()
|
|
309
|
+
},
|
|
310
|
+
immediate: true
|
|
311
|
+
},
|
|
312
|
+
|
|
313
|
+
useDestroyAlways: {
|
|
314
|
+
handler (value) {
|
|
315
|
+
this.hasDestroyAlways = value ?? this.useStartsEmpty
|
|
286
316
|
},
|
|
287
317
|
immediate: true
|
|
288
318
|
}
|
|
289
319
|
},
|
|
290
320
|
|
|
291
321
|
methods: {
|
|
322
|
+
getActionsList (index, row) {
|
|
323
|
+
const list = {}
|
|
324
|
+
|
|
325
|
+
if (this.useDuplicate) {
|
|
326
|
+
list.duplicate = {
|
|
327
|
+
...this.buttonDuplicateProps,
|
|
328
|
+
handler: () => this.add(row)
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
if (this.showDestroyButton) {
|
|
333
|
+
list.destroy = {
|
|
334
|
+
...this.buttonDestroyProps,
|
|
335
|
+
handler: () => this.destroy(index, row)
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
for (const key in this.actionsMenuProps.list) {
|
|
340
|
+
const { handler, ...content } = this.actionsMenuProps.list[key] || {}
|
|
341
|
+
|
|
342
|
+
list[key] = {
|
|
343
|
+
handler: payload => handler?.({ payload, row, index }),
|
|
344
|
+
...content
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
return list
|
|
349
|
+
},
|
|
350
|
+
|
|
292
351
|
add (row = {}) {
|
|
293
352
|
const payload = { ...this.rowObject, ...row }
|
|
294
353
|
const hasIdentifierKey = payload[this.identifierItemKey]
|
|
@@ -345,6 +404,7 @@ export default {
|
|
|
345
404
|
},
|
|
346
405
|
|
|
347
406
|
setDefaultNestedValue () {
|
|
407
|
+
if (this.nested.length || this.useStartsEmpty) return
|
|
348
408
|
this.nested.splice(0, 0, { ...this.rowObject })
|
|
349
409
|
},
|
|
350
410
|
|
|
@@ -4,14 +4,24 @@ meta:
|
|
|
4
4
|
desc: Componente para gerar dinamicamente campos nested.
|
|
5
5
|
|
|
6
6
|
props:
|
|
7
|
+
actions-menu-props:
|
|
8
|
+
desc: Repassa as propriedades para o componente QasActionsMenu.
|
|
9
|
+
default: {}
|
|
10
|
+
type: Object
|
|
11
|
+
|
|
12
|
+
add-first-input-label:
|
|
13
|
+
desc: Rótulo do input para adicionar o primeiro campo.
|
|
14
|
+
default: Clique aqui para adicionar
|
|
15
|
+
type: String
|
|
16
|
+
|
|
7
17
|
add-input-label:
|
|
8
18
|
desc: Rótulo do input de adicionar novos campos.
|
|
9
|
-
default:
|
|
10
|
-
type:
|
|
19
|
+
default: Adicionar
|
|
20
|
+
type: String
|
|
11
21
|
|
|
12
22
|
button-destroy-props:
|
|
13
23
|
desc: Props do botão de excluir linha contendo os campos.
|
|
14
|
-
default: "{ label: '
|
|
24
|
+
default: "{ label: 'Excluir', icon: 'o_delete', flat: true, dense: true }"
|
|
15
25
|
debugger: true
|
|
16
26
|
type: Object
|
|
17
27
|
|
|
@@ -76,17 +86,17 @@ props:
|
|
|
76
86
|
model: true
|
|
77
87
|
|
|
78
88
|
row-label:
|
|
79
|
-
desc: Rótulo entre cada linha
|
|
89
|
+
desc: Rótulo entre cada linha.
|
|
80
90
|
type: String
|
|
81
91
|
|
|
82
92
|
row-object:
|
|
83
|
-
desc: Objeto contendo valores iniciais do model de cada linha
|
|
93
|
+
desc: Objeto contendo valores iniciais do model de cada linha.
|
|
84
94
|
default: {}
|
|
85
95
|
type: Object
|
|
86
96
|
examples: ["{ name: '', cities: [] }"]
|
|
87
97
|
|
|
88
98
|
use-add:
|
|
89
|
-
desc: Controla quando vai ter seção de "adicionar" novas
|
|
99
|
+
desc: Controla quando vai ter seção de "adicionar" novas linhas.
|
|
90
100
|
default: true
|
|
91
101
|
type: Boolean
|
|
92
102
|
|
|
@@ -96,7 +106,7 @@ props:
|
|
|
96
106
|
type: Boolean
|
|
97
107
|
|
|
98
108
|
use-destroy-always:
|
|
99
|
-
desc: Controla o botão de remover em todas linhas
|
|
109
|
+
desc: Controla o botão de remover em todas linhas, incluindo a primeira.
|
|
100
110
|
type: Boolean
|
|
101
111
|
|
|
102
112
|
use-duplicate:
|
|
@@ -104,20 +114,30 @@ props:
|
|
|
104
114
|
default: true
|
|
105
115
|
type: Boolean
|
|
106
116
|
|
|
117
|
+
use-first-input-button:
|
|
118
|
+
desc: Controla se vai ter um botão diferente para adicionar o primeiro campo.
|
|
119
|
+
default: true
|
|
120
|
+
type: Boolean
|
|
121
|
+
|
|
107
122
|
use-index-label:
|
|
108
123
|
desc: Se tiver "rowLabel" esta prop controla se cada label da linha vai ter o index como sufixo.
|
|
109
124
|
type: Boolean
|
|
110
125
|
|
|
111
126
|
use-inline-actions:
|
|
112
|
-
desc: Controla o comportamento referente aos estilos das ações de duplicar/adicionar/remover
|
|
127
|
+
desc: Controla o comportamento referente aos estilos das ações de duplicar/adicionar/remover.
|
|
113
128
|
type: Boolean
|
|
114
129
|
|
|
115
130
|
use-single-label:
|
|
116
|
-
desc:
|
|
131
|
+
desc: Exibe apenas uma label referente a todas linhas, e não uma por linha.
|
|
117
132
|
type: Boolean
|
|
118
133
|
|
|
119
134
|
use-remove-on-destroy:
|
|
120
|
-
desc:
|
|
135
|
+
desc: O valor do model será removido senão será adicionar uma flag como `destroyed` por exemplo.
|
|
136
|
+
default: true
|
|
137
|
+
type: Boolean
|
|
138
|
+
|
|
139
|
+
use-starts-empty:
|
|
140
|
+
desc: O componente iniciará sem nenhuma linha.
|
|
121
141
|
default: true
|
|
122
142
|
type: Boolean
|
|
123
143
|
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
<q-toolbar class="justify-between q-mb-lg q-px-none">
|
|
3
3
|
<div class="ellipsis">
|
|
4
4
|
<q-toolbar-title v-if="title" class="text-bold text-h5">
|
|
5
|
-
<q-icon v-if="hasPreviousRoute" class="cursor-pointer vertical-baseline" name="o_arrow_back" size="18px" @click="back" />
|
|
6
5
|
{{ title }}
|
|
7
6
|
</q-toolbar-title>
|
|
8
7
|
|
|
@@ -19,7 +18,7 @@ import { castArray } from 'lodash-es'
|
|
|
19
18
|
import { useHistory } from '../../composables'
|
|
20
19
|
import { createMetaMixin } from 'quasar'
|
|
21
20
|
|
|
22
|
-
const {
|
|
21
|
+
const { history } = useHistory()
|
|
23
22
|
|
|
24
23
|
export default {
|
|
25
24
|
name: 'QasPageHeader',
|
|
@@ -55,10 +54,6 @@ export default {
|
|
|
55
54
|
},
|
|
56
55
|
|
|
57
56
|
computed: {
|
|
58
|
-
hasPreviousRoute () {
|
|
59
|
-
return hasPreviousRoute.value
|
|
60
|
-
},
|
|
61
|
-
|
|
62
57
|
transformedBreadcrumbs () {
|
|
63
58
|
const list = [...castArray(this.breadcrumbs || this.title)]
|
|
64
59
|
this.root && list.unshift(this.root)
|
|
@@ -85,10 +80,6 @@ export default {
|
|
|
85
80
|
},
|
|
86
81
|
|
|
87
82
|
methods: {
|
|
88
|
-
back () {
|
|
89
|
-
this.$router.push(getPreviousRoute(this.$route))
|
|
90
|
-
},
|
|
91
|
-
|
|
92
83
|
getBreadcrumbsClass (index) {
|
|
93
84
|
const lastIndex = this.transformedBreadcrumbs.length - 1
|
|
94
85
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<q-pagination v-bind="defaultProps" />
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script>
|
|
6
|
+
export default {
|
|
7
|
+
name: 'QasPagination',
|
|
8
|
+
|
|
9
|
+
computed: {
|
|
10
|
+
defaultProps () {
|
|
11
|
+
const { modelValue, ...attributes } = this.$attrs
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
activeColor: 'primary',
|
|
15
|
+
activeDesign: 'flat',
|
|
16
|
+
boundaryNumbers: true,
|
|
17
|
+
color: 'grey-7',
|
|
18
|
+
directionLinks: true,
|
|
19
|
+
maxPages: modelValue < 3 ? 3 : 6,
|
|
20
|
+
modelValue,
|
|
21
|
+
|
|
22
|
+
...attributes
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
</script>
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<q-select v-model="model" v-bind="attributes">
|
|
3
|
-
<template #
|
|
4
|
-
<
|
|
5
|
-
<q-icon v-if="isSearchable" name="o_search" />
|
|
6
|
-
</slot>
|
|
3
|
+
<template v-if="isSearchable" #prepend>
|
|
4
|
+
<q-icon name="o_search" />
|
|
7
5
|
</template>
|
|
8
6
|
|
|
9
7
|
<template #no-option>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<qas-box class="q-
|
|
2
|
+
<qas-box class="q-px-lg q-py-md">
|
|
3
3
|
<q-table ref="table" class="bg-transparent qas-table-generator" :class="tableClass" v-bind="attributes">
|
|
4
4
|
<template v-for="(_, name) in $slots" #[name]="context">
|
|
5
5
|
<slot v-if="hasBodySlot" name="body" :props="context" />
|
|
@@ -70,7 +70,10 @@ export default {
|
|
|
70
70
|
flat: true,
|
|
71
71
|
hideBottom: true,
|
|
72
72
|
pagination: { rowsPerPage: 0 },
|
|
73
|
-
rowKey: this.rowKey
|
|
73
|
+
rowKey: this.rowKey,
|
|
74
|
+
|
|
75
|
+
// Eventos.
|
|
76
|
+
onRowClick: this.$attrs.onRowClick && this.onRowClick
|
|
74
77
|
}
|
|
75
78
|
|
|
76
79
|
return attributes
|
|
@@ -220,6 +223,11 @@ export default {
|
|
|
220
223
|
}
|
|
221
224
|
},
|
|
222
225
|
|
|
226
|
+
onRowClick () {
|
|
227
|
+
if (this.hasScrollOnGrab && this.scrollOnGrab.haveMoved()) return
|
|
228
|
+
this.$attrs.onRowClick(...arguments)
|
|
229
|
+
},
|
|
230
|
+
|
|
223
231
|
setObserver () {
|
|
224
232
|
this.elementToObserve = this.getTableElement()
|
|
225
233
|
this.resizeObserver = new ResizeObserver(entries => {
|
|
@@ -44,3 +44,17 @@ slots:
|
|
|
44
44
|
desc: Payload da linha da tabela.
|
|
45
45
|
default: {}
|
|
46
46
|
type: Object
|
|
47
|
+
|
|
48
|
+
events:
|
|
49
|
+
'@row-click -> function(event, row, index)':
|
|
50
|
+
desc: Dispara ao clicar em uma linha. Não funciona usando slots personalizados (body, row e item).
|
|
51
|
+
params:
|
|
52
|
+
event:
|
|
53
|
+
desc: Evento do click.
|
|
54
|
+
type: Event
|
|
55
|
+
row:
|
|
56
|
+
desc: Payload da linha da tabela.
|
|
57
|
+
type: Object
|
|
58
|
+
index:
|
|
59
|
+
desc: Índice da linha.
|
|
60
|
+
type: Number
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<div ref="truncate" :class="truncateTextClass">
|
|
5
5
|
<slot>{{ text }}</slot>
|
|
6
6
|
</div>
|
|
7
|
-
<div v-if="isTruncated" class="cursor-pointer text-primary" @click="toggleDialog">{{ seeMoreLabel }}</div>
|
|
7
|
+
<div v-if="isTruncated" class="cursor-pointer text-primary" @click.stop="toggleDialog">{{ seeMoreLabel }}</div>
|
|
8
8
|
</div>
|
|
9
9
|
|
|
10
10
|
<qas-dialog v-model="showDialog" v-bind="defaultDialogProps">
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import './notify';
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
.q-notification {
|
|
2
|
+
margin-top: 80px;
|
|
3
|
+
max-width: 560px;
|
|
4
|
+
|
|
5
|
+
&__content {
|
|
6
|
+
.q-icon {
|
|
7
|
+
margin-right: var(--qas-spacing-sm);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
&__actions {
|
|
12
|
+
align-self: start;
|
|
13
|
+
padding-top: var(--qas-spacing-xs);
|
|
14
|
+
|
|
15
|
+
.q-btn {
|
|
16
|
+
color: white;
|
|
17
|
+
height: var(--qas-spacing-md);
|
|
18
|
+
min-height: auto;
|
|
19
|
+
min-width: auto;
|
|
20
|
+
padding: 0;
|
|
21
|
+
text-align: center;
|
|
22
|
+
text-transform: none;
|
|
23
|
+
width: var(--qas-spacing-md);
|
|
24
|
+
|
|
25
|
+
&__content {
|
|
26
|
+
height: var(--qas-spacing-md);
|
|
27
|
+
|
|
28
|
+
span {
|
|
29
|
+
align-self: center;
|
|
30
|
+
height: var(--qas-spacing-md);
|
|
31
|
+
line-height: 0.9;
|
|
32
|
+
width: var(--qas-spacing-md);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@media (max-width: $breakpoint-xs) {
|
|
39
|
+
margin-top: 40px;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -27,15 +27,15 @@ $space-md: (
|
|
|
27
27
|
y: $space-y-base
|
|
28
28
|
);
|
|
29
29
|
|
|
30
|
-
// O tamanho original seria "16px * 1.5" ou "24px", alterado para ter "32px"
|
|
31
30
|
$space-lg: (
|
|
32
|
-
x: ($space-x-base *
|
|
33
|
-
y: ($space-y-base *
|
|
31
|
+
x: ($space-x-base * 1.5),
|
|
32
|
+
y: ($space-y-base * 1.5)
|
|
34
33
|
);
|
|
35
34
|
|
|
35
|
+
// O tamanho original seria "16px * 3" ou "48px", alterado para ter "32px"
|
|
36
36
|
$space-xl: (
|
|
37
|
-
x: ($space-x-base *
|
|
38
|
-
y: ($space-y-base *
|
|
37
|
+
x: ($space-x-base * 2),
|
|
38
|
+
y: ($space-y-base * 2)
|
|
39
39
|
);
|
|
40
40
|
|
|
41
41
|
$spaces: (
|
|
@@ -2,6 +2,7 @@ export default function (element) {
|
|
|
2
2
|
setStyle()
|
|
3
3
|
|
|
4
4
|
let isDown = false
|
|
5
|
+
let moved = false
|
|
5
6
|
let startX
|
|
6
7
|
let scrollLeft
|
|
7
8
|
|
|
@@ -12,35 +13,38 @@ export default function (element) {
|
|
|
12
13
|
|
|
13
14
|
function onMouseDown (event) {
|
|
14
15
|
isDown = true
|
|
16
|
+
moved = false
|
|
17
|
+
|
|
15
18
|
element.classList.add('active')
|
|
19
|
+
|
|
16
20
|
startX = event.pageX - element.offsetLeft
|
|
17
21
|
scrollLeft = element.scrollLeft
|
|
18
22
|
}
|
|
19
23
|
|
|
20
24
|
function onMouseLeave () {
|
|
21
25
|
isDown = false
|
|
22
|
-
element.classList.remove('active')
|
|
23
26
|
|
|
27
|
+
element.classList.remove('active')
|
|
24
28
|
setStyle()
|
|
25
29
|
}
|
|
26
30
|
|
|
27
31
|
function onMouseUp () {
|
|
28
32
|
isDown = false
|
|
29
|
-
element.classList.remove('active')
|
|
30
33
|
|
|
34
|
+
element.classList.remove('active')
|
|
31
35
|
setStyle()
|
|
32
36
|
}
|
|
33
37
|
|
|
34
38
|
function onMouseMove (event) {
|
|
39
|
+
if (event) event.preventDefault()
|
|
35
40
|
if (!isDown) return
|
|
36
41
|
|
|
37
|
-
event.preventDefault()
|
|
38
|
-
|
|
39
42
|
setStyle('grabbing')
|
|
40
43
|
|
|
41
44
|
const x = event.pageX - element.offsetLeft
|
|
42
45
|
const walk = (x - startX) * 3 // scroll-fast
|
|
43
46
|
element.scrollLeft = scrollLeft - walk
|
|
47
|
+
moved = true
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
function setStyle (model = 'grab') {
|
|
@@ -54,8 +58,13 @@ export default function (element) {
|
|
|
54
58
|
element.removeEventListener('mousemove', onMouseMove)
|
|
55
59
|
}
|
|
56
60
|
|
|
61
|
+
function haveMoved () {
|
|
62
|
+
return moved
|
|
63
|
+
}
|
|
64
|
+
|
|
57
65
|
return {
|
|
58
66
|
element,
|
|
67
|
+
haveMoved,
|
|
59
68
|
destroyEvents
|
|
60
69
|
}
|
|
61
70
|
}
|
package/src/index.scss
CHANGED
|
@@ -22,8 +22,11 @@ $generic-border-radius: var(--qas-generic-border-radius);
|
|
|
22
22
|
// components
|
|
23
23
|
@import './css/components/index';
|
|
24
24
|
|
|
25
|
+
// plugins
|
|
26
|
+
@import './css/plugins/index';
|
|
27
|
+
|
|
25
28
|
// utils
|
|
26
29
|
@import './css/utils/index';
|
|
27
30
|
|
|
28
31
|
// mixins
|
|
29
|
-
@import './css/mixins/index'
|
|
32
|
+
@import './css/mixins/index';
|
package/src/mixins/generator.js
CHANGED
package/src/mixins/view.js
CHANGED
|
@@ -81,13 +81,16 @@ export default {
|
|
|
81
81
|
|
|
82
82
|
mx_hasHeaderSlot () {
|
|
83
83
|
return !!(this.$slots.header)
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
mx_fetchErrorMessage () {
|
|
87
|
+
return 'Ops… Não conseguimos acessar as informações. Por favor, tente novamente em alguns minutos.'
|
|
84
88
|
}
|
|
85
89
|
},
|
|
86
90
|
|
|
87
91
|
methods: {
|
|
88
92
|
mx_fetchError (error) {
|
|
89
93
|
const { response } = error
|
|
90
|
-
const exception = response?.data?.exception || error.message
|
|
91
94
|
|
|
92
95
|
const status = response?.status
|
|
93
96
|
|
|
@@ -102,7 +105,7 @@ export default {
|
|
|
102
105
|
return
|
|
103
106
|
}
|
|
104
107
|
|
|
105
|
-
this.$qas.error(
|
|
108
|
+
this.$qas.error(this.mx_fetchErrorMessage)
|
|
106
109
|
},
|
|
107
110
|
|
|
108
111
|
mx_setErrors (errors = {}) {
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { Notify } from 'quasar'
|
|
2
|
+
import notifyConfig from '../../shared/notify-config.js'
|
|
2
3
|
|
|
3
|
-
Notify.registerType('error', {
|
|
4
|
-
color: 'negative',
|
|
5
|
-
progress: true
|
|
6
|
-
})
|
|
4
|
+
Notify.registerType('error', { icon: 'o_cancel', ...notifyConfig })
|
|
7
5
|
|
|
8
6
|
export default (message, caption) => {
|
|
9
|
-
Notify.create({
|
|
7
|
+
Notify.create({
|
|
8
|
+
caption,
|
|
9
|
+
message,
|
|
10
|
+
type: 'error'
|
|
11
|
+
})
|
|
10
12
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { Notify } from 'quasar'
|
|
2
|
+
import notifyConfig from '../../shared/notify-config.js'
|
|
2
3
|
|
|
3
|
-
Notify.registerType('success', {
|
|
4
|
-
icon: 'o_check',
|
|
5
|
-
progress: true
|
|
6
|
-
})
|
|
4
|
+
Notify.registerType('success', { icon: 'o_check_circle', ...notifyConfig })
|
|
7
5
|
|
|
8
6
|
export default (message, caption) => {
|
|
9
|
-
Notify
|
|
7
|
+
Notify.create({
|
|
8
|
+
caption,
|
|
9
|
+
message,
|
|
10
|
+
type: 'success'
|
|
11
|
+
})
|
|
10
12
|
}
|
package/src/vue-plugin.js
CHANGED
|
@@ -31,6 +31,7 @@ import QasNestedFields from './components/nested-fields/QasNestedFields.vue'
|
|
|
31
31
|
import QasNumericInput from './components/numeric-input/QasNumericInput.vue'
|
|
32
32
|
import QasOptionGroup from './components/option-group/QasOptionGroup.vue'
|
|
33
33
|
import QasPageHeader from './components/page-header/QasPageHeader.vue'
|
|
34
|
+
import QasPagination from './components/pagination/QasPagination.vue'
|
|
34
35
|
import QasPasswordInput from './components/password-input/QasPasswordInput.vue'
|
|
35
36
|
import QasPasswordStrengthChecker from './components/password-strength-checker/QasPasswordStrengthChecker.vue'
|
|
36
37
|
import QasProfile from './components/profile/QasProfile.vue'
|
|
@@ -102,6 +103,7 @@ function install (app) {
|
|
|
102
103
|
app.component('QasNumericInput', QasNumericInput)
|
|
103
104
|
app.component('QasOptionGroup', QasOptionGroup)
|
|
104
105
|
app.component('QasPageHeader', QasPageHeader)
|
|
106
|
+
app.component('QasPagination', QasPagination)
|
|
105
107
|
app.component('QasPasswordInput', QasPasswordInput)
|
|
106
108
|
app.component('QasPasswordStrengthChecker', QasPasswordStrengthChecker)
|
|
107
109
|
app.component('QasProfile', QasProfile)
|
|
@@ -174,6 +176,7 @@ export {
|
|
|
174
176
|
QasNumericInput,
|
|
175
177
|
QasOptionGroup,
|
|
176
178
|
QasPageHeader,
|
|
179
|
+
QasPagination,
|
|
177
180
|
QasPasswordInput,
|
|
178
181
|
QasPasswordStrengthChecker,
|
|
179
182
|
QasProfile,
|