@bildvitta/quasar-ui-asteroid 3.20.0-beta.2 → 3.20.0-beta.21
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 +3 -3
- package/src/asteroid.js +8 -1
- package/src/components/actions/QasActions.vue +12 -2
- package/src/components/actions-menu/QasActionsMenu.vue +18 -5
- package/src/components/alert/QasAlert.vue +89 -64
- package/src/components/app-user/QasAppUser.vue +2 -1
- package/src/components/board-generator/QasBoardGenerator.vue +883 -162
- package/src/components/board-generator/QasBoardGenerator.yml +83 -2
- package/src/components/board-generator/private/PvBoardGeneratorCardsContainer.vue +25 -0
- package/src/components/box/QasBox.vue +16 -3
- package/src/components/box/QasBox.yml +10 -0
- package/src/components/btn/QasBtn.vue +27 -5
- package/src/components/btn/QasBtn.yml +10 -1
- package/src/components/btn-dropdown/QasBtnDropdown.vue +13 -1
- package/src/components/card/QasCard.vue +97 -25
- package/src/components/card/QasCard.yml +10 -0
- package/src/components/card-image/QasCardImage.vue +10 -1
- package/src/components/card-image/QasCardImage.yml +5 -0
- package/src/components/chart-view/QasChartView.vue +4 -3
- package/src/components/chart-view/QasChartView.yml +5 -0
- package/src/components/checkbox/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/src/components/copy/QasCopy.vue +6 -1
- package/src/components/copy/QasCopy.yml +5 -0
- package/src/components/date-time-input/QasDateTimeInput.vue +30 -6
- package/src/components/dialog/QasDialog.vue +308 -91
- package/src/components/dialog/QasDialog.yml +51 -23
- package/src/components/dialog/composables/use-cancel.js +1 -1
- package/src/components/dialog/composables/use-dynamic-components.js +2 -2
- package/src/components/dialog/composables/use-ok.js +1 -0
- package/src/components/dialog-router/QasDialogRouter.vue +1 -1
- package/src/components/drawer/QasDrawer.vue +76 -26
- package/src/components/drawer/QasDrawer.yml +10 -0
- package/src/components/expansion-item/QasExpansionItem.yml +5 -0
- package/src/components/filters/QasFilters.vue +2 -1
- package/src/components/filters/private/PvFiltersActions.vue +79 -13
- package/src/components/form-generator/QasFormGenerator.vue +8 -1
- package/src/components/form-generator/QasFormGenerator.yml +10 -0
- package/src/components/form-view/QasFormView.vue +20 -11
- package/src/components/form-view/QasFormView.yml +6 -0
- package/src/components/gallery/composables/use-delete.js +2 -3
- package/src/components/gallery/private/PvGalleryCarouselDialog.vue +8 -7
- package/src/components/grid-item/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/src/components/header/QasHeader.vue +66 -11
- package/src/components/header/QasHeader.yml +16 -1
- package/src/components/infinite-scroll/QasInfiniteScroll.vue +1 -1
- package/src/components/label/QasLabel.vue +3 -1
- package/src/components/layout/QasLayout.vue +16 -1
- package/src/components/layout/private/PvLayoutNotificationsDrawer.vue +2 -1
- package/src/components/layout/private/PvLayoutOverlayDrawer.vue +4 -2
- package/src/components/lazy-loading-components/QasLazyLoadingComponents.vue +262 -0
- package/src/components/lazy-loading-components/QasLazyLoadingComponents.yml +49 -0
- package/src/components/list-view/QasListView.vue +12 -4
- package/src/components/list-view/QasListView.yml +12 -0
- package/src/components/page-header/QasPageHeader.vue +49 -3
- package/src/components/page-header/QasPageHeader.yml +5 -0
- package/src/components/router-link/QasRouterLink.vue +72 -0
- package/src/components/router-link/QasRouterLink.yml +24 -0
- package/src/components/search-box/QasSearchBox.vue +1 -1
- package/src/components/select/QasSelect.vue +8 -1
- package/src/components/select-list-dialog/QasSelectListDialog.vue +40 -20
- package/src/components/select-list-dialog/QasSelectListDialog.yml +14 -2
- package/src/components/signature-uploader/QasSignatureUploader.vue +5 -18
- package/src/components/single-view/QasSingleView.vue +2 -2
- package/src/components/skeleton/QasSkeleton.vue +139 -0
- package/src/components/skeleton/QasSkeleton.yml +48 -0
- package/src/components/sortable/QasSortable.vue +1 -1
- package/src/components/stepper/QasStepper.vue +24 -2
- package/src/components/table-generator/QasTableGenerator.vue +186 -35
- package/src/components/table-generator/QasTableGenerator.yml +6 -1
- package/src/components/tabs-generator/QasTabsGenerator.vue +14 -3
- package/src/components/tabs-generator/QasTabsGenerator.yml +5 -1
- package/src/components/text-truncate/QasTextTruncate.vue +61 -12
- package/src/components/text-truncate/QasTextTruncate.yml +5 -0
- package/src/components/toggle-visibility/QasToggleVisibility.vue +2 -1
- package/src/components/tooltip/QasTooltip.vue +6 -1
- package/src/components/tree-generator/QasTreeGenerator.vue +4 -6
- package/src/components/uploader/QasUploader.vue +12 -2
- package/src/composables/private/use-view.js +1 -1
- package/src/composables/use-overlay-navigation.js +116 -10
- package/src/composables/use-screen.js +17 -1
- package/src/css/components/button.scss +82 -3
- package/src/css/components/item.scss +6 -0
- package/src/css/utils/background.scss +5 -0
- package/src/css/utils/border.scss +6 -0
- package/src/css/utils/container.scss +4 -3
- package/src/css/utils/text.scss +9 -0
- package/src/helpers/copy-to-clipboard.js +2 -1
- package/src/helpers/filters.js +1 -1
- package/src/helpers/promise-handler.js +2 -1
- package/src/helpers/set-scroll-gradient.js +31 -8
- package/src/helpers/set-scroll-on-grab.js +10 -3
- package/src/index.scss +1 -0
- package/src/mixins/search-filter.js +7 -1
- package/src/plugins/delete/Delete.js +7 -9
- package/src/plugins/delete/Delete.yml +1 -1
- package/src/plugins/dialog/Dialog.yml +1 -1
- package/src/plugins/notify-error/NotifyError.yml +1 -1
- package/src/plugins/notify-success/NotifySuccess.yml +1 -1
- package/src/plugins/screen/Screen.js +17 -1
- package/src/plugins/screen/Screen.yml +5 -1
- package/src/vue-plugin.js +5 -7
- package/src/plugins/index.js +0 -5
|
@@ -5,29 +5,49 @@
|
|
|
5
5
|
</slot>
|
|
6
6
|
|
|
7
7
|
<q-table v-show="hasResults" ref="table" v-bind="attributes" v-model:selected="selectedModel" class="bg-white text-grey-8">
|
|
8
|
-
<template v-
|
|
9
|
-
<
|
|
8
|
+
<template v-if="skeleton" #header-cell="props">
|
|
9
|
+
<q-th :props="props">
|
|
10
|
+
<qas-skeleton v-bind="getThSkeletonProps()" />
|
|
11
|
+
</q-th>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<template v-for="(column, index) in columnsWithTooltip" :key="index" #[`header-cell-${column.name}`]="context">
|
|
15
|
+
<q-th :props="context">
|
|
16
|
+
{{ context.col.label }}
|
|
17
|
+
|
|
18
|
+
<qas-tip class="q-pl-xs" :text="column.tooltip" />
|
|
19
|
+
</q-th>
|
|
10
20
|
</template>
|
|
11
21
|
|
|
12
22
|
<!-- Necessário para sobrescrever o QCheckbox e usar o QasCheckbox. -->
|
|
13
23
|
<template #header-selection="props">
|
|
14
|
-
<
|
|
24
|
+
<qas-skeleton v-if="skeleton" type="QasCheckbox" />
|
|
25
|
+
|
|
26
|
+
<div v-else class="qas-table-generator__cancel-mouse-target" data-table-ignore-tr-hover>
|
|
15
27
|
<qas-checkbox v-model="props.selected" />
|
|
16
28
|
</div>
|
|
17
29
|
</template>
|
|
18
30
|
|
|
19
31
|
<!-- Necessário para sobrescrever o QCheckbox e usar o QasCheckbox. -->
|
|
20
32
|
<template #body-selection="props">
|
|
21
|
-
<
|
|
33
|
+
<qas-skeleton v-if="skeleton" type="QasCheckbox" />
|
|
34
|
+
|
|
35
|
+
<div v-else class="qas-table-generator__cancel-mouse-target" data-table-ignore-tr-hover>
|
|
22
36
|
<qas-checkbox v-model="props.selected" />
|
|
23
37
|
</div>
|
|
24
38
|
</template>
|
|
25
39
|
|
|
40
|
+
<template v-for="(_, name) in slots" #[name]="context">
|
|
41
|
+
<slot :name="name" v-bind="context" />
|
|
42
|
+
</template>
|
|
43
|
+
|
|
26
44
|
<template v-for="(fieldName, index) in bodyCellNameSlots" :key="index" #[`body-cell-${fieldName}`]="context">
|
|
27
45
|
<q-td :class="getTdClasses(context.row)">
|
|
28
|
-
<
|
|
46
|
+
<qas-skeleton v-if="skeleton" v-bind="getTgSkeletonProps(fieldName, context.row)" />
|
|
47
|
+
|
|
48
|
+
<component :is="tdChildComponent(context.row)" v-else class="qas-table-generator__td-item" v-bind="getTdChildComponentProps(context.row)">
|
|
29
49
|
<slot :name="`body-cell-${fieldName}`" v-bind="context || {}">
|
|
30
|
-
<pv-table-generator-td v-if="getFieldsProps(context.row, context.rowIndex)[fieldName]" :component-data="getFieldsProps(context.row, context.rowIndex)[fieldName]" :label="
|
|
50
|
+
<pv-table-generator-td v-if="getFieldsProps(context.row, context.rowIndex)[fieldName]" :component-data="getFieldsProps(context.row, context.rowIndex)[fieldName]" :label="normalizedFields[fieldName]?.label" :name="fieldName" :row="context.row" />
|
|
31
51
|
|
|
32
52
|
<template v-else>
|
|
33
53
|
{{ context.row?.[fieldName] }}
|
|
@@ -36,14 +56,6 @@
|
|
|
36
56
|
</component>
|
|
37
57
|
</q-td>
|
|
38
58
|
</template>
|
|
39
|
-
|
|
40
|
-
<template v-for="(column, index) in columnsWithTooltip" :key="index" #[`header-cell-${column.name}`]="context">
|
|
41
|
-
<q-th :props="context">
|
|
42
|
-
{{ context.col.label }}
|
|
43
|
-
|
|
44
|
-
<qas-tip class="q-pl-xs" :text="column.tooltip" />
|
|
45
|
-
</q-th>
|
|
46
|
-
</template>
|
|
47
59
|
</q-table>
|
|
48
60
|
|
|
49
61
|
<qas-empty-result-text v-if="!hasResults" />
|
|
@@ -57,6 +69,7 @@ import QasCheckbox from '../checkbox/QasCheckbox.vue'
|
|
|
57
69
|
import QasEmptyResultText from '../empty-result-text/QasEmptyResultText.vue'
|
|
58
70
|
import QasHeader from '../header/QasHeader.vue'
|
|
59
71
|
import QasTip from '../tip/QasTip.vue'
|
|
72
|
+
import QasSkeleton from '../skeleton/QasSkeleton.vue'
|
|
60
73
|
|
|
61
74
|
import { isEmpty, humanize, setScrollOnGrab, setScrollGradient } from '../../helpers'
|
|
62
75
|
|
|
@@ -71,16 +84,26 @@ export default {
|
|
|
71
84
|
QasEmptyResultText,
|
|
72
85
|
QasHeader,
|
|
73
86
|
QasCheckbox,
|
|
74
|
-
QasTip
|
|
87
|
+
QasTip,
|
|
88
|
+
QasSkeleton
|
|
75
89
|
},
|
|
76
90
|
|
|
77
91
|
provide () {
|
|
78
92
|
return {
|
|
93
|
+
isTableGenerator: true,
|
|
94
|
+
|
|
79
95
|
/**
|
|
80
96
|
* @see QasBtn.vue - Injetando os valores padrões para o QasBtn.
|
|
81
97
|
*/
|
|
82
98
|
btnPropsDefaults: {
|
|
83
99
|
size: 'sm'
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @see QasTextTruncate.vue - Injetando os valores padrões para o QasTextTruncate.
|
|
104
|
+
*/
|
|
105
|
+
textTruncatePropsDefaults: {
|
|
106
|
+
typography: 'body2'
|
|
84
107
|
}
|
|
85
108
|
}
|
|
86
109
|
},
|
|
@@ -142,6 +165,10 @@ export default {
|
|
|
142
165
|
type: Array
|
|
143
166
|
},
|
|
144
167
|
|
|
168
|
+
skeleton: {
|
|
169
|
+
type: Boolean
|
|
170
|
+
},
|
|
171
|
+
|
|
145
172
|
useBox: {
|
|
146
173
|
type: Boolean,
|
|
147
174
|
default: true
|
|
@@ -190,10 +217,49 @@ export default {
|
|
|
190
217
|
},
|
|
191
218
|
|
|
192
219
|
computed: {
|
|
193
|
-
|
|
194
|
-
if (this.
|
|
220
|
+
normalizedFields () {
|
|
221
|
+
if (this.skeleton) {
|
|
222
|
+
const fields = {}
|
|
223
|
+
|
|
224
|
+
this.normalizedColumns.forEach(column => {
|
|
225
|
+
const columnName = column?.name || column
|
|
226
|
+
|
|
227
|
+
fields[columnName] = {
|
|
228
|
+
name: columnName,
|
|
229
|
+
label: columnName.charAt(0).toUpperCase() + columnName.slice(1),
|
|
230
|
+
type: 'text'
|
|
231
|
+
}
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
return fields
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return this.fields
|
|
238
|
+
},
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Caso esteja em skeleton, retorna uma lista de resultados vazios com a mesma estrutura das colunas.
|
|
242
|
+
* Isso é necessário para que o QasTableGenerator renderize as linhas de skeleton corretamente.
|
|
243
|
+
* Cada resultado terá chaves correspondentes aos nomes das colunas, todas com valores vazios.
|
|
244
|
+
*/
|
|
245
|
+
normalizedResults () {
|
|
246
|
+
if (this.skeleton) {
|
|
247
|
+
return Array.from({ length: 24 }).map(() => {
|
|
248
|
+
const result = {}
|
|
249
|
+
|
|
250
|
+
this.normalizedColumns.forEach(column => {
|
|
251
|
+
const columnName = column?.name || column
|
|
195
252
|
|
|
196
|
-
|
|
253
|
+
result[columnName] = ''
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
result.default = result
|
|
257
|
+
|
|
258
|
+
return result
|
|
259
|
+
})
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return this.results
|
|
197
263
|
},
|
|
198
264
|
|
|
199
265
|
bodyCellNameSlots () {
|
|
@@ -201,7 +267,7 @@ export default {
|
|
|
201
267
|
|
|
202
268
|
return this.normalizedColumns.length
|
|
203
269
|
? this.normalizedColumns.map(column => typeof column === 'object' ? column.name : column)
|
|
204
|
-
: Object.keys(this.
|
|
270
|
+
: Object.keys(this.normalizedFields)
|
|
205
271
|
},
|
|
206
272
|
|
|
207
273
|
slots () {
|
|
@@ -273,8 +339,8 @@ export default {
|
|
|
273
339
|
|
|
274
340
|
// Automatic columns.
|
|
275
341
|
if (!this.normalizedColumns.length) {
|
|
276
|
-
for (const index in this.
|
|
277
|
-
columnByField(this.
|
|
342
|
+
for (const index in this.normalizedFields) {
|
|
343
|
+
columnByField(this.normalizedFields[index])
|
|
278
344
|
}
|
|
279
345
|
|
|
280
346
|
return columns
|
|
@@ -284,9 +350,9 @@ export default {
|
|
|
284
350
|
this.normalizedColumns.forEach(column => {
|
|
285
351
|
if (column instanceof Object) {
|
|
286
352
|
// repassa as props e mergeia com as do field
|
|
287
|
-
columnByField({ ...column, ...this.
|
|
288
|
-
} else if (this.
|
|
289
|
-
columnByField(this.
|
|
353
|
+
columnByField({ ...column, ...this.normalizedFields[column.name] })
|
|
354
|
+
} else if (this.normalizedFields[column]) {
|
|
355
|
+
columnByField(this.normalizedFields[column])
|
|
290
356
|
}
|
|
291
357
|
})
|
|
292
358
|
|
|
@@ -305,17 +371,23 @@ export default {
|
|
|
305
371
|
},
|
|
306
372
|
|
|
307
373
|
columnsWithTooltip () {
|
|
374
|
+
// quando estiver em skeleton, não precisa processar as colunas com tooltip
|
|
375
|
+
if (this.skeleton) return []
|
|
376
|
+
|
|
308
377
|
return this.normalizedColumns.filter(column => column.tooltip)
|
|
309
378
|
},
|
|
310
379
|
|
|
311
380
|
hasFields () {
|
|
312
|
-
return Object.keys(this.
|
|
381
|
+
return Object.keys(this.normalizedFields).length
|
|
313
382
|
},
|
|
314
383
|
|
|
315
384
|
resultsByFields () {
|
|
316
|
-
if (!Object.keys(this.
|
|
385
|
+
if (!Object.keys(this.normalizedFields).length) return []
|
|
317
386
|
|
|
318
|
-
|
|
387
|
+
// Validação necessária para evitar processamento sem necessidade quando estiver em skeleton.
|
|
388
|
+
if (this.skeleton) return this.normalizedResults
|
|
389
|
+
|
|
390
|
+
const results = extend(true, [], this.normalizedResults)
|
|
319
391
|
|
|
320
392
|
const mappedResults = results.map((result, index) => {
|
|
321
393
|
for (const key in result) {
|
|
@@ -323,10 +395,10 @@ export default {
|
|
|
323
395
|
continue
|
|
324
396
|
}
|
|
325
397
|
|
|
326
|
-
const humanizedResult = humanize(this.
|
|
398
|
+
const humanizedResult = humanize(this.normalizedFields[key], result[key])
|
|
327
399
|
const formattedResult = isEmpty({ value: humanizedResult }) ? this.emptyResultText : humanizedResult
|
|
328
400
|
|
|
329
|
-
result.default = this.
|
|
401
|
+
result.default = this.normalizedResults[index]
|
|
330
402
|
result[key] = formattedResult
|
|
331
403
|
}
|
|
332
404
|
|
|
@@ -337,7 +409,7 @@ export default {
|
|
|
337
409
|
},
|
|
338
410
|
|
|
339
411
|
rowsPerPage () {
|
|
340
|
-
return this.
|
|
412
|
+
return this.normalizedResults.length
|
|
341
413
|
},
|
|
342
414
|
|
|
343
415
|
tableClasses () {
|
|
@@ -498,18 +570,28 @@ export default {
|
|
|
498
570
|
this.resizeObserver.unobserve(this.elementToObserve)
|
|
499
571
|
},
|
|
500
572
|
|
|
501
|
-
|
|
573
|
+
/**
|
|
574
|
+
* Valida se o valor retornado para a row é um route.
|
|
575
|
+
*
|
|
576
|
+
* @param {Object} row - Objeto referente ao row da tabela.
|
|
577
|
+
*
|
|
578
|
+
* @returns {boolean}
|
|
579
|
+
*/
|
|
580
|
+
hasRowRoute (row) {
|
|
502
581
|
const routePayload = this.rowRouteFn?.(row)
|
|
503
582
|
const isRoutePayloadObject = typeof routePayload === 'object'
|
|
504
|
-
const hasRoutePayload = isRoutePayloadObject ? !!Object.keys(routePayload).length : !!routePayload
|
|
505
583
|
|
|
584
|
+
return isRoutePayloadObject ? !!Object.keys(routePayload).length : !!routePayload
|
|
585
|
+
},
|
|
586
|
+
|
|
587
|
+
getTdClasses (row) {
|
|
506
588
|
return {
|
|
507
|
-
'qas-table-generator__td--has-action': this.
|
|
589
|
+
'qas-table-generator__td--has-action': this.hasRowRoute(row)
|
|
508
590
|
}
|
|
509
591
|
},
|
|
510
592
|
|
|
511
593
|
getTdChildComponentProps (row) {
|
|
512
|
-
if (!this.
|
|
594
|
+
if (!this.hasRowRoute(row) || this.skeleton) return
|
|
513
595
|
|
|
514
596
|
return {
|
|
515
597
|
class: [
|
|
@@ -527,9 +609,17 @@ export default {
|
|
|
527
609
|
},
|
|
528
610
|
|
|
529
611
|
onRowClick () {
|
|
612
|
+
if (this.skeleton) return
|
|
613
|
+
|
|
530
614
|
this.$attrs.onRowClick(...arguments)
|
|
531
615
|
},
|
|
532
616
|
|
|
617
|
+
tdChildComponent (row) {
|
|
618
|
+
if (this.useExternalLink) return 'a'
|
|
619
|
+
|
|
620
|
+
return this.hasRowRoute(row) ? 'router-link' : 'span'
|
|
621
|
+
},
|
|
622
|
+
|
|
533
623
|
getFieldsProps (row, index) {
|
|
534
624
|
const isFieldsPropsFunction = typeof this.fieldsProps === 'function'
|
|
535
625
|
|
|
@@ -547,6 +637,62 @@ export default {
|
|
|
547
637
|
}
|
|
548
638
|
})
|
|
549
639
|
}
|
|
640
|
+
},
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* Retorna propriedades para o componente QasSkeleton usado nas células do QasTableGenerator
|
|
644
|
+
*
|
|
645
|
+
* @param {string} column - nome da coluna
|
|
646
|
+
* @param {Object} row - dados da linha
|
|
647
|
+
*/
|
|
648
|
+
getTgSkeletonProps (column, row) {
|
|
649
|
+
const normalizedFieldsProps = typeof this.fieldsProps === 'function'
|
|
650
|
+
? this.fieldsProps(row)
|
|
651
|
+
: this.fieldsProps || {}
|
|
652
|
+
|
|
653
|
+
const columnFieldProps = normalizedFieldsProps[column]
|
|
654
|
+
|
|
655
|
+
const min = 100
|
|
656
|
+
const max = 160
|
|
657
|
+
|
|
658
|
+
// Gera uma largura aleatória entre min e max entre 100 e 160 pixels
|
|
659
|
+
const width = Math.floor(Math.random() * (max - min + 1)) + min
|
|
660
|
+
|
|
661
|
+
const isActions = column === 'actions'
|
|
662
|
+
|
|
663
|
+
// Define o tipo do skeleton baseado na configuração da coluna
|
|
664
|
+
const type = (
|
|
665
|
+
(isActions ? 'QasActionsMenu' : undefined) ||
|
|
666
|
+
columnFieldProps?.component ||
|
|
667
|
+
(this.useMultiline ? undefined : 'text')
|
|
668
|
+
)
|
|
669
|
+
|
|
670
|
+
return {
|
|
671
|
+
type,
|
|
672
|
+
|
|
673
|
+
// se for multiline e não for actions, define a altura do skeleton
|
|
674
|
+
height: this.useMultiline && !isActions ? '68px' : undefined,
|
|
675
|
+
|
|
676
|
+
// Define a largura do skeleton
|
|
677
|
+
width: columnFieldProps?.component || isActions ? undefined : `${width + 20}px`
|
|
678
|
+
}
|
|
679
|
+
},
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* Retorna propriedades para o componente QasSkeleton usado nos cabeçalhos do QasTableGenerator
|
|
683
|
+
*/
|
|
684
|
+
getThSkeletonProps () {
|
|
685
|
+
const min = 60
|
|
686
|
+
const max = 120
|
|
687
|
+
|
|
688
|
+
// Gera uma largura aleatória entre min e max entre 60 e 120 pixels
|
|
689
|
+
const width = Math.floor(Math.random() * (max - min + 1)) + min
|
|
690
|
+
|
|
691
|
+
return {
|
|
692
|
+
type: 'text',
|
|
693
|
+
useContrast: true,
|
|
694
|
+
width: `${width}px`
|
|
695
|
+
}
|
|
550
696
|
}
|
|
551
697
|
}
|
|
552
698
|
}
|
|
@@ -577,10 +723,11 @@ export default {
|
|
|
577
723
|
}
|
|
578
724
|
}
|
|
579
725
|
|
|
726
|
+
line-height: 100% !important;
|
|
580
727
|
padding-bottom: var(--qas-spacing-sm);;
|
|
581
728
|
padding-left: 0;
|
|
582
|
-
padding-top: 0;
|
|
583
729
|
padding-right: var(--qas-spacing-md);
|
|
730
|
+
padding-top: 0;
|
|
584
731
|
}
|
|
585
732
|
|
|
586
733
|
td,
|
|
@@ -601,6 +748,10 @@ export default {
|
|
|
601
748
|
z-index: 0;
|
|
602
749
|
padding-right: var(--qas-spacing-md);
|
|
603
750
|
|
|
751
|
+
* {
|
|
752
|
+
line-height: 100% !important;
|
|
753
|
+
}
|
|
754
|
+
|
|
604
755
|
&::before {
|
|
605
756
|
position: absolute;
|
|
606
757
|
content: '';
|
|
@@ -70,7 +70,7 @@ props:
|
|
|
70
70
|
row-route-fn:
|
|
71
71
|
desc: Usado quando há a necessidade de alteração de rota ao clicar em um item da tabela(a linha passa ser um <a> habilitando a opção de abrir em uma nova aba).
|
|
72
72
|
type: Function
|
|
73
|
-
examples: ["
|
|
73
|
+
examples: ["row => ({ path: 'table-generator', params: { id: row.uuid } })", "row => undefined", "row => {}"]
|
|
74
74
|
|
|
75
75
|
selected:
|
|
76
76
|
desc: Usado como model das linhas selecionadas.
|
|
@@ -79,6 +79,11 @@ props:
|
|
|
79
79
|
model: true
|
|
80
80
|
examples: ["['uuid1', 'uuid2']"]
|
|
81
81
|
|
|
82
|
+
skeleton:
|
|
83
|
+
desc: Exibe um esqueleto de carregamento no lugar do conteúdo.
|
|
84
|
+
default: false
|
|
85
|
+
type: Boolean
|
|
86
|
+
|
|
82
87
|
use-box:
|
|
83
88
|
desc: Controla se o componente vai usar QasBox ou div.
|
|
84
89
|
default: true
|
|
@@ -6,10 +6,16 @@
|
|
|
6
6
|
<slot :item="tab" :name="`tab-after-${tab.value}`">
|
|
7
7
|
<q-icon v-if="tab.icon" :name="tab.icon" size="sm" />
|
|
8
8
|
|
|
9
|
-
<
|
|
9
|
+
<div v-if="tab.status">
|
|
10
|
+
<qas-status :color="tab.status" />
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<div class="flex items-center no-wrap q-ml-xs">
|
|
14
|
+
<span>
|
|
15
|
+
{{ getFormattedLabel(tab) }}
|
|
16
|
+
</span>
|
|
10
17
|
|
|
11
|
-
|
|
12
|
-
{{ getFormattedLabel(tab) }}
|
|
18
|
+
<qas-skeleton v-if="props.skeleton && !tab.counter" class="q-ml-sm" height="22px" type="text" width="25px" />
|
|
13
19
|
</div>
|
|
14
20
|
</slot>
|
|
15
21
|
</component>
|
|
@@ -20,6 +26,7 @@
|
|
|
20
26
|
|
|
21
27
|
<script setup>
|
|
22
28
|
import QasStatus from '../status/QasStatus.vue'
|
|
29
|
+
import QasSkeleton from '../skeleton/QasSkeleton.vue'
|
|
23
30
|
|
|
24
31
|
import { decimal } from '../../helpers'
|
|
25
32
|
|
|
@@ -35,6 +42,10 @@ const props = defineProps({
|
|
|
35
42
|
type: Object
|
|
36
43
|
},
|
|
37
44
|
|
|
45
|
+
skeleton: {
|
|
46
|
+
type: Boolean
|
|
47
|
+
},
|
|
48
|
+
|
|
38
49
|
modelValue: {
|
|
39
50
|
default: '',
|
|
40
51
|
type: [String, Number]
|
|
@@ -13,7 +13,6 @@ props:
|
|
|
13
13
|
type: Object
|
|
14
14
|
examples: ["{ all: 24 }"]
|
|
15
15
|
|
|
16
|
-
|
|
17
16
|
querySlug:
|
|
18
17
|
desc: Nome da query string para alterar o model via URL, toda vez que a tab for alterada a query será atualizada e vice-versa.
|
|
19
18
|
type: String
|
|
@@ -25,6 +24,11 @@ props:
|
|
|
25
24
|
type: [String, Number]
|
|
26
25
|
model: true
|
|
27
26
|
|
|
27
|
+
skeleton:
|
|
28
|
+
desc: Exibe um esqueleto de carregamento no lugar do conteúdo.
|
|
29
|
+
default: false
|
|
30
|
+
type: Boolean
|
|
31
|
+
|
|
28
32
|
tabs:
|
|
29
33
|
desc: Objeto ou Array contendo todas as tabs a serem geradas.
|
|
30
34
|
default: {}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div ref="parent" :class="classes">
|
|
3
|
-
<div class="no-wrap row text-no-wrap">
|
|
3
|
+
<div class="items-center no-wrap row text-no-wrap">
|
|
4
4
|
<!-- "data-table-hover" habilita o hover no texto dentro do QasTableGenerator -->
|
|
5
5
|
<div ref="truncate" class="ellipsis" data-table-hover>
|
|
6
6
|
<slot>
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
<qas-btn v-if="hasButton" class="q-ml-xs" :label="buttonLabel" @click.stop.prevent="toggle" />
|
|
20
20
|
</div>
|
|
21
21
|
|
|
22
|
-
<qas-dialog v-model="show" v-bind="defaultProps" aria-label="Diálogo de texto completo"
|
|
23
|
-
<template v-if="
|
|
22
|
+
<qas-dialog v-model="show" v-bind="defaultProps" aria-label="Diálogo de texto completo" role="dialog" size="md">
|
|
23
|
+
<template v-if="showDescriptionSlot" #description>
|
|
24
24
|
<component :is="dialogComponent.is" v-bind="dialogComponent.props" v-model:results="searchModel">
|
|
25
25
|
<q-list separator>
|
|
26
26
|
<q-item v-for="(item, index) in dialogComponent.list" :key="index" class="q-px-none">
|
|
@@ -51,6 +51,8 @@ import {
|
|
|
51
51
|
onMounted,
|
|
52
52
|
onUnmounted,
|
|
53
53
|
ref,
|
|
54
|
+
inject,
|
|
55
|
+
isRef,
|
|
54
56
|
watch
|
|
55
57
|
} from 'vue'
|
|
56
58
|
|
|
@@ -100,7 +102,7 @@ const props = defineProps({
|
|
|
100
102
|
|
|
101
103
|
typography: {
|
|
102
104
|
type: String,
|
|
103
|
-
default:
|
|
105
|
+
default: undefined
|
|
104
106
|
},
|
|
105
107
|
|
|
106
108
|
list: {
|
|
@@ -108,6 +110,10 @@ const props = defineProps({
|
|
|
108
110
|
default: () => []
|
|
109
111
|
},
|
|
110
112
|
|
|
113
|
+
useAlwaysSeeMore: {
|
|
114
|
+
type: Boolean
|
|
115
|
+
},
|
|
116
|
+
|
|
111
117
|
useBadge: {
|
|
112
118
|
type: Boolean
|
|
113
119
|
},
|
|
@@ -121,6 +127,9 @@ const props = defineProps({
|
|
|
121
127
|
}
|
|
122
128
|
})
|
|
123
129
|
|
|
130
|
+
// globals
|
|
131
|
+
const injectedDefaults = inject('textTruncatePropsDefaults', {}) // Inject reativo ou não reativo com fallback vazio
|
|
132
|
+
|
|
124
133
|
// template refs
|
|
125
134
|
const truncate = ref(null)
|
|
126
135
|
const parent = ref(null)
|
|
@@ -142,6 +151,7 @@ const {
|
|
|
142
151
|
const {
|
|
143
152
|
defaultProps,
|
|
144
153
|
dialogComponent,
|
|
154
|
+
hasDialogDescription,
|
|
145
155
|
show,
|
|
146
156
|
searchModel,
|
|
147
157
|
toggle
|
|
@@ -158,30 +168,65 @@ const {
|
|
|
158
168
|
useMutationObserver({ truncate, callbackFn: truncateText })
|
|
159
169
|
|
|
160
170
|
// computeds
|
|
161
|
-
|
|
171
|
+
/**
|
|
172
|
+
* Seta os valores padrões, dando prioridade:
|
|
173
|
+
* 1. Props
|
|
174
|
+
* 2. Injetado (pode ser reativo ou não reativo)
|
|
175
|
+
* 3. Caso esteja dentro do QasBox, seta o size para 'sm' se for primary ou secondary.
|
|
176
|
+
* 4. Hardcoded (tertiary, md, primary)
|
|
177
|
+
*/
|
|
178
|
+
const textTruncatePropsDefaults = computed(() => {
|
|
179
|
+
const defaultProps = isRef(injectedDefaults) ? injectedDefaults.value : injectedDefaults
|
|
180
|
+
|
|
181
|
+
return {
|
|
182
|
+
typography: 'body1',
|
|
183
|
+
...defaultProps
|
|
184
|
+
}
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
const defaultTypography = computed(() => props.typography || textTruncatePropsDefaults.value.typography)
|
|
188
|
+
|
|
189
|
+
const classes = computed(() => [`text-${props.color}`, `text-${defaultTypography.value}`])
|
|
162
190
|
|
|
163
191
|
const formattedText = computed(() => props.list.length || props.text ? displayText.value : props.emptyText)
|
|
164
192
|
|
|
193
|
+
/**
|
|
194
|
+
* Se estiver em modo contador (list prop preenchida) e não houver descrição
|
|
195
|
+
* personalizada no diálogo, então mostra o slot de descrição.
|
|
196
|
+
*/
|
|
197
|
+
const showDescriptionSlot = computed(() => isCounterMode.value && !hasDialogDescription?.value)
|
|
198
|
+
|
|
165
199
|
// composable functions
|
|
166
200
|
function useDialog ({ props, textContent }) {
|
|
167
201
|
// reactive vars
|
|
168
202
|
const show = ref(false)
|
|
169
203
|
const searchModel = ref([])
|
|
170
204
|
|
|
171
|
-
//
|
|
172
|
-
const
|
|
205
|
+
// computeds
|
|
206
|
+
const hasDialogDescription = computed(() => !!props.dialogProps?.description)
|
|
207
|
+
|
|
208
|
+
const description = computed(() => {
|
|
209
|
+
// Se dialogProps.description estiver setado, usa ele
|
|
210
|
+
if (hasDialogDescription.value) {
|
|
211
|
+
return props.dialogProps.description
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Senão, usa o comportamento padrão
|
|
215
|
+
return props.text || textContent.value
|
|
216
|
+
})
|
|
173
217
|
|
|
174
218
|
const defaultProps = computed(() => {
|
|
175
219
|
return {
|
|
176
220
|
cancel: false,
|
|
177
221
|
ok: false,
|
|
178
222
|
|
|
223
|
+
useFullMaxWidth: true,
|
|
224
|
+
maxWidth: '500px',
|
|
225
|
+
|
|
179
226
|
...props.dialogProps,
|
|
180
227
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
description: description.value
|
|
184
|
-
}
|
|
228
|
+
title: props.dialogTitle,
|
|
229
|
+
description: description.value
|
|
185
230
|
}
|
|
186
231
|
})
|
|
187
232
|
|
|
@@ -218,6 +263,7 @@ function useDialog ({ props, textContent }) {
|
|
|
218
263
|
return {
|
|
219
264
|
defaultProps,
|
|
220
265
|
dialogComponent,
|
|
266
|
+
hasDialogDescription,
|
|
221
267
|
|
|
222
268
|
show,
|
|
223
269
|
searchModel,
|
|
@@ -298,6 +344,9 @@ function useTemplate () {
|
|
|
298
344
|
const isCounterMode = computed(() => !!props.list.length)
|
|
299
345
|
|
|
300
346
|
const hasButton = computed(() => {
|
|
347
|
+
// Caso a propriedade useAlwaysSeeMore esteja ativa, sempre exibe o botão
|
|
348
|
+
if (props.useAlwaysSeeMore) return true
|
|
349
|
+
|
|
301
350
|
return isCounterMode.value ? normalizedList.value.length > props.maxVisibleItem : isTruncated.value
|
|
302
351
|
})
|
|
303
352
|
|
|
@@ -306,7 +355,7 @@ function useTemplate () {
|
|
|
306
355
|
})
|
|
307
356
|
|
|
308
357
|
const buttonLabel = computed(() => {
|
|
309
|
-
return isCounterMode.value ? counterLabel.value : props.seeMoreLabel
|
|
358
|
+
return isCounterMode.value && !props.useAlwaysSeeMore ? counterLabel.value : props.seeMoreLabel
|
|
310
359
|
})
|
|
311
360
|
|
|
312
361
|
return {
|
|
@@ -51,6 +51,11 @@ props:
|
|
|
51
51
|
default: []
|
|
52
52
|
type: Array
|
|
53
53
|
|
|
54
|
+
useAlwaysSeeMore:
|
|
55
|
+
desc: Sempre exibe o botão "ver mais", mesmo que o texto não esteja truncado.
|
|
56
|
+
default: false
|
|
57
|
+
type: Boolean
|
|
58
|
+
|
|
54
59
|
use-badge:
|
|
55
60
|
desc: Habilita badges para cada item da lista.
|
|
56
61
|
default: false
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
2
|
+
<!-- "data-no-grab" para prevenir o click drag -->
|
|
3
|
+
<div class="qas-toggle-visibility" data-no-grab>
|
|
3
4
|
<!-- "data-table-ignore-tr-hover" é para desabilitar o hover do tr no QasTableGenerator -->
|
|
4
5
|
<div :aria-expanded="isVisible" aria-label="Alternar visibilidade do conteúdo" class="cursor-pointer items-center no-wrap qas-toggle-visibility__container row" data-table-ignore-tr-hover role="button" :style @click.prevent.stop="toggleVisibility">
|
|
5
6
|
<div class="ellipsis qas-toggle-visibility__content">
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<q-tooltip v-bind="tooltipProps" class="bg-grey-10 text-caption">
|
|
2
|
+
<q-tooltip v-if="!isDragging" v-bind="tooltipProps" class="bg-grey-10 text-caption">
|
|
3
3
|
<qas-breakline :text="props.text" />
|
|
4
4
|
</q-tooltip>
|
|
5
5
|
</template>
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
<script setup>
|
|
8
8
|
import QasBreakline from '../breakline/QasBreakline.vue'
|
|
9
9
|
|
|
10
|
+
import { inject, ref } from 'vue'
|
|
11
|
+
|
|
10
12
|
defineOptions({ name: 'QasTooltip' })
|
|
11
13
|
|
|
12
14
|
const props = defineProps({
|
|
@@ -16,6 +18,9 @@ const props = defineProps({
|
|
|
16
18
|
}
|
|
17
19
|
})
|
|
18
20
|
|
|
21
|
+
// injects
|
|
22
|
+
const isDragging = inject('isDragging', ref(false))
|
|
23
|
+
|
|
19
24
|
// consts
|
|
20
25
|
const tooltipProps = {
|
|
21
26
|
anchor: 'center right',
|