v-sistec-features 1.23.2 → 1.25.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/core.d.ts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/v-sistec-features.css +1 -1
- package/dist/vDataTable.d.ts +12 -0
- package/dist/vDataTable.js +617 -590
- package/package.json +1 -1
- package/src/DatatableVue/components/VColumn.vue +8 -2
- package/src/DatatableVue/components/VDataTable.vue +153 -367
- package/src/DatatableVue/composables/useDataTableFetch.ts +2 -2
- package/src/DatatableVue/keys.ts +4 -0
- package/src/DatatableVue/style/scss/VDataTable.scss +177 -0
- package/src/DatatableVue/style/scss/_image-preview.scss +84 -0
- package/src/DatatableVue/types/v-data-table.ts +10 -0
|
@@ -68,11 +68,11 @@
|
|
|
68
68
|
</button>
|
|
69
69
|
</div>
|
|
70
70
|
<div class="table-responsive" v-else-if="items">
|
|
71
|
-
<div v-if="
|
|
71
|
+
<div v-if="hasItems || options.show_header_when_empty">
|
|
72
72
|
<table class="table table-vcenter table-selectable" :class="options.class_table">
|
|
73
73
|
<thead>
|
|
74
74
|
|
|
75
|
-
<draggable v-model="draggableColumns" tag="tr" item-key="
|
|
75
|
+
<draggable v-model="draggableColumns" tag="tr" item-key="id" :animation="400"
|
|
76
76
|
ghost-class="ghost-item" drag-class="dragging-item" @start="isDraggingColumns = true"
|
|
77
77
|
@end="() => onDragEnd()">
|
|
78
78
|
|
|
@@ -86,9 +86,9 @@
|
|
|
86
86
|
|
|
87
87
|
<template #item="{ element: col }">
|
|
88
88
|
<v-th-data-table :header="col.header" :class_column="col.class_column"
|
|
89
|
-
:use_ordering="col.use_ordering" :orderings_state="orderings_state[col.
|
|
90
|
-
@toggleOrderingState="() => toggleOrderingState(col.
|
|
91
|
-
|
|
89
|
+
:use_ordering="col.use_ordering" :orderings_state="orderings_state[col.id] || 'none'"
|
|
90
|
+
@toggleOrderingState="() => toggleOrderingState(col.id)" :locked="false" :col="col">
|
|
91
|
+
|
|
92
92
|
</v-th-data-table>
|
|
93
93
|
</template>
|
|
94
94
|
|
|
@@ -96,9 +96,9 @@
|
|
|
96
96
|
|
|
97
97
|
<template v-for="col in lockedColumns" :key="col.field || col.header">
|
|
98
98
|
<v-th-data-table :header="col.header" :class_column="col.class_column"
|
|
99
|
-
:use_ordering="col.use_ordering" :orderings_state="orderings_state[col.
|
|
100
|
-
@toggleOrderingState="() => toggleOrderingState(col.
|
|
101
|
-
|
|
99
|
+
:use_ordering="col.use_ordering" :orderings_state="orderings_state[col.id] || 'none'"
|
|
100
|
+
@toggleOrderingState="() => toggleOrderingState(col.id)" :col="col" locked>
|
|
101
|
+
|
|
102
102
|
</v-th-data-table>
|
|
103
103
|
|
|
104
104
|
</template>
|
|
@@ -107,114 +107,119 @@
|
|
|
107
107
|
</thead>
|
|
108
108
|
|
|
109
109
|
<tbody>
|
|
110
|
-
<template v-
|
|
111
|
-
<
|
|
112
|
-
<
|
|
113
|
-
<
|
|
114
|
-
:
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
<
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
<
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
<
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
<
|
|
149
|
-
:is
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
<div @click="col.click ? col.click(item) : null" :class="computeClasses(col, item)"
|
|
169
|
-
v-else-if="col.type === 'img'">
|
|
170
|
-
|
|
171
|
-
<div v-if="getSubItem(col.field, item)" v-bind="col.deactivate_img_preview ? {
|
|
172
|
-
class: 'container-img'
|
|
173
|
-
} :
|
|
174
|
-
{
|
|
175
|
-
onMouseover: (event) => handleMouseOver(event, getSubItem(col.field, item)),
|
|
176
|
-
onMousemove: handleMouseMove,
|
|
177
|
-
onMouseleave: handleMouseLeave,
|
|
178
|
-
class: 'container-img container-img-preview'
|
|
179
|
-
}">
|
|
180
|
-
|
|
181
|
-
<img class="img-tamanho" :src="getSubItem(col.field, item)" />
|
|
182
|
-
<img class="img-tamanho-cover" :src="getSubItem(col.field, item)" />
|
|
183
|
-
<div class="bg-img"></div>
|
|
110
|
+
<template v-if="hasItems">
|
|
111
|
+
<template v-for="(item, index) in items" :key="item[options.item_key]">
|
|
112
|
+
<TransitionGroup tag="tr" :name="isDraggingColumns ? 'column-move' : ''">
|
|
113
|
+
<td v-if="options.use_expandable_items" class="w-1">
|
|
114
|
+
<slot name="expand-button" :item="item" :index="index" :is-expanded="is_item_expanded(item)"
|
|
115
|
+
:expand_item_toggle="expand_item_toggle">
|
|
116
|
+
<button type="button" class="btn-clean btn-icon-anim"
|
|
117
|
+
:class="{ 'is-expanded': is_item_expanded(item) }" @click="expand_item_toggle(item)">
|
|
118
|
+
|
|
119
|
+
<template v-if="options.type_button_expand === 'arrow'">
|
|
120
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
|
121
|
+
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
|
122
|
+
stroke-linejoin="round"
|
|
123
|
+
class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-right icon-transition-arrow">
|
|
124
|
+
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
|
125
|
+
<path d="M9 6l6 6l-6 6" />
|
|
126
|
+
</svg>
|
|
127
|
+
|
|
128
|
+
</template>
|
|
129
|
+
|
|
130
|
+
<template v-else>
|
|
131
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24"
|
|
132
|
+
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
|
133
|
+
stroke-linejoin="round" class="icon icon-transition-plus">
|
|
134
|
+
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
|
135
|
+
<path d="M12 5l0 14" class="vertical-line" />
|
|
136
|
+
<path d="M5 12l14 0" />
|
|
137
|
+
</svg>
|
|
138
|
+
</template>
|
|
139
|
+
|
|
140
|
+
</button>
|
|
141
|
+
</slot>
|
|
142
|
+
</td>
|
|
143
|
+
<td v-if="options.use_checkbox" class="w-1">
|
|
144
|
+
<input class="form-check-input m-0" type="checkbox" :checked="isSelected(item)"
|
|
145
|
+
@change="toggleItemSelection(item)" aria-label="Selecionar este item" />
|
|
146
|
+
</td>
|
|
147
|
+
|
|
148
|
+
<td v-for="(col, index) in renderedColumns" :key="col.field || col.header" :class="col.class_row">
|
|
149
|
+
<component v-if="col.bodySlot" :is="col.bodySlot" :item="item" :index="index"
|
|
150
|
+
:is-selected="isSelected(item)" />
|
|
151
|
+
<span @click="col.click ? col.click(item) : null" :class="computeClasses(col, item)"
|
|
152
|
+
v-else-if="col.type === 'text'">
|
|
153
|
+
{{
|
|
154
|
+
limiteText(getSubItem(col.field, item, col.transform_function), col.limite_text ?? null)
|
|
155
|
+
}}</span>
|
|
156
|
+
|
|
157
|
+
<span @click="col.click ? col.click(item) : null" v-else-if="col.type === 'date'"
|
|
158
|
+
:class="computeClasses(col, item)">
|
|
159
|
+
<span v-if="col.format === 'complete'">{{ new Date(getSubItem(col.field,
|
|
160
|
+
item)).toLocaleString()
|
|
161
|
+
}}</span>
|
|
162
|
+
<span v-if="col.format === 'simple'"> {{ new Date(getSubItem(col.field,
|
|
163
|
+
item)).toLocaleDateString()
|
|
164
|
+
}} </span>
|
|
165
|
+
</span>
|
|
166
|
+
<div @click="col.click ? col.click(item) : null" :class="computeClasses(col, item)"
|
|
167
|
+
v-else-if="col.type === 'html'" v-html="getSubItem(col.field, item)">
|
|
184
168
|
</div>
|
|
185
169
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
class="badge bg-orange text-white erro-custom-text">{{ col.type }}</span> não suportado</span>
|
|
189
|
-
</td>
|
|
190
|
-
</TransitionGroup>
|
|
191
|
-
<Transition :name="'expand-item-' + options.type_animation_expand"
|
|
192
|
-
:css="!options.deactivate_animation_expand">
|
|
193
|
-
<!-- mostra uma linha após cada item -->
|
|
194
|
-
<tr :id="'expand-item-' + item[options.item_key]" v-if="is_item_expanded(item)"
|
|
195
|
-
class="expanded-item-row">
|
|
196
|
-
<!-- se estiver usando checkbox existe uma coluna a mais -->
|
|
197
|
-
<td :colspan="colspanExpandItems()">
|
|
198
|
-
<slot name="after-row" :item="item">
|
|
170
|
+
<div @click="col.click ? col.click(item) : null" :class="computeClasses(col, item)"
|
|
171
|
+
v-else-if="col.type === 'img'">
|
|
199
172
|
|
|
200
|
-
|
|
173
|
+
<div v-if="getSubItem(col.field, item)" v-bind="col.deactivate_img_preview ? {
|
|
174
|
+
class: 'container-img'
|
|
175
|
+
} :
|
|
176
|
+
{
|
|
177
|
+
onMouseover: (event) => handleMouseOver(event, getSubItem(col.field, item)),
|
|
178
|
+
onMousemove: handleMouseMove,
|
|
179
|
+
onMouseleave: handleMouseLeave,
|
|
180
|
+
class: 'container-img container-img-preview'
|
|
181
|
+
}">
|
|
182
|
+
|
|
183
|
+
<img class="img-tamanho" :src="getSubItem(col.field, item)" />
|
|
184
|
+
<img class="img-tamanho-cover" :src="getSubItem(col.field, item)" />
|
|
185
|
+
<div class="bg-img"></div>
|
|
186
|
+
</div>
|
|
201
187
|
|
|
188
|
+
</div>
|
|
189
|
+
<span class="text-danger erro-custom-container" v-else>tipo <span
|
|
190
|
+
class="badge bg-orange text-white erro-custom-text">{{ col.type }}</span> não
|
|
191
|
+
suportado</span>
|
|
202
192
|
</td>
|
|
203
|
-
</
|
|
204
|
-
|
|
193
|
+
</TransitionGroup>
|
|
194
|
+
<Transition :name="'expand-item-' + options.type_animation_expand"
|
|
195
|
+
:css="!options.deactivate_animation_expand">
|
|
196
|
+
<!-- mostra uma linha após cada item -->
|
|
197
|
+
<tr :id="'expand-item-' + item[options.item_key]" v-if="is_item_expanded(item)"
|
|
198
|
+
class="expanded-item-row">
|
|
199
|
+
<!-- se estiver usando checkbox existe uma coluna a mais -->
|
|
200
|
+
<td :colspan="colspanExpandItems()">
|
|
201
|
+
<slot name="after-row" :item="item">
|
|
202
|
+
|
|
203
|
+
</slot>
|
|
205
204
|
|
|
205
|
+
</td>
|
|
206
|
+
</tr>
|
|
207
|
+
</Transition>
|
|
206
208
|
|
|
209
|
+
|
|
210
|
+
</template>
|
|
207
211
|
</template>
|
|
208
212
|
|
|
213
|
+
|
|
209
214
|
</tbody>
|
|
210
215
|
</table>
|
|
211
216
|
</div>
|
|
212
|
-
<div v-
|
|
217
|
+
<div v-if="!hasItems && first_fetch === false">
|
|
213
218
|
<slot name="idle-state">
|
|
214
219
|
|
|
215
220
|
</slot>
|
|
216
221
|
</div>
|
|
217
|
-
<div v-else class="text-center p-4 text-secondary">
|
|
222
|
+
<div v-else-if="!hasItems" class="text-center p-4 text-secondary">
|
|
218
223
|
<p class="m-0">Nenhum item encontrado.</p>
|
|
219
224
|
</div>
|
|
220
225
|
</div>
|
|
@@ -250,6 +255,7 @@ import { useDataTableFetch } from '../composables/useDataTableFetch';
|
|
|
250
255
|
import { useCheckBox } from '../composables/useCheckBox.ts';
|
|
251
256
|
import VDataTableLoading from './VDataTableLoading.vue';
|
|
252
257
|
import VThDataTable from './VThDataTable.vue';
|
|
258
|
+
|
|
253
259
|
const globalConfig = inject(DATA_TABLE_CONFIG, {});
|
|
254
260
|
const {
|
|
255
261
|
isHovering,
|
|
@@ -288,6 +294,7 @@ const props = withDefaults(defineProps<VDataTableProps>(), {
|
|
|
288
294
|
disable_search: false,
|
|
289
295
|
pagination_teleport: null,
|
|
290
296
|
search_teleport: null,
|
|
297
|
+
show_header_when_empty: false,
|
|
291
298
|
});
|
|
292
299
|
const options = computed(() => {
|
|
293
300
|
return {
|
|
@@ -326,6 +333,7 @@ const options = computed(() => {
|
|
|
326
333
|
min_loading_delay: props.min_loading_delay ?? globalConfig.min_loading_delay ?? 600,
|
|
327
334
|
retry_attempts: props.retry_attempts ?? globalConfig.retry_attempts ?? 3,
|
|
328
335
|
retry_delay: props.retry_delay ?? globalConfig.retry_delay ?? 2000,
|
|
336
|
+
show_header_when_empty: props.show_header_when_empty ?? globalConfig.show_header_when_empty ?? false,
|
|
329
337
|
};
|
|
330
338
|
});
|
|
331
339
|
const emit = defineEmits(['tradePage', 'beforeFetch', 'afterFetch', 'clickedClearSearch']);
|
|
@@ -386,22 +394,49 @@ const {
|
|
|
386
394
|
|
|
387
395
|
// colunas TRAVADAS (apenas leitura)
|
|
388
396
|
const lockedColumns = computed(() =>
|
|
389
|
-
columns.value.filter(c => c.locked)
|
|
397
|
+
columns.value.filter(c => c.locked && c.visible !== false)
|
|
390
398
|
);
|
|
391
399
|
// 'v-model' para as colunas ARRASTÁVEIS (com get/set)
|
|
392
400
|
const draggableColumns = computed({
|
|
393
401
|
get() {
|
|
394
|
-
return columns.value.filter(c => !c.locked);
|
|
402
|
+
return columns.value.filter(c => !c.locked && c.visible !== false);
|
|
395
403
|
},
|
|
396
404
|
set(newUnlockedOrder) {
|
|
397
|
-
const locked =
|
|
398
|
-
columns.value
|
|
405
|
+
const locked = columns.value.filter(c => c.locked);
|
|
406
|
+
const hidden = columns.value.filter(c => !c.locked && c.visible === false);
|
|
407
|
+
columns.value = [...newUnlockedOrder, ...hidden, ...locked];
|
|
399
408
|
}
|
|
400
409
|
});
|
|
401
410
|
// colunas RENDERIZADAS (ordem final)
|
|
402
411
|
const renderedColumns = computed(() => {
|
|
403
412
|
return [...draggableColumns.value, ...lockedColumns.value];
|
|
404
413
|
});
|
|
414
|
+
/*
|
|
415
|
+
Variável que mapeia as colunas cadastradas.
|
|
416
|
+
Usada para entregar ao componente pai as informações de cabeçalho, campo, se a coluna é opcional e se está visível atualmente.
|
|
417
|
+
*/
|
|
418
|
+
const columns_list = computed(() => {
|
|
419
|
+
return columns.value.map(col => ({
|
|
420
|
+
id: col.id,
|
|
421
|
+
header: col.header,
|
|
422
|
+
field: col.field,
|
|
423
|
+
start_hidden: !!col.start_hidden, // Converte para booleano, caso seja undefined
|
|
424
|
+
visible: col.visible !== false,
|
|
425
|
+
locked: col.locked
|
|
426
|
+
}));
|
|
427
|
+
});
|
|
428
|
+
/*
|
|
429
|
+
Função que inverte o estado de visibilidade de uma coluna específica.
|
|
430
|
+
Recebe: id (string), que é o identificador único da coluna.
|
|
431
|
+
Devolve: nada (void).
|
|
432
|
+
Por que é usada: Permite ao usuário exibir ou ocultar uma coluna dinamicamente (como as opcionais) diretamente pela interface externa da tabela.
|
|
433
|
+
*/
|
|
434
|
+
function toggleColumnVisibility(id: string): void {
|
|
435
|
+
const coluna = columns.value.find(c => c.id === id);
|
|
436
|
+
if (coluna) {
|
|
437
|
+
coluna.visible = !coluna.visible;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
405
440
|
|
|
406
441
|
const item_use = computed<number[]>(() => {
|
|
407
442
|
let use = [1]
|
|
@@ -411,8 +446,10 @@ const item_use = computed<number[]>(() => {
|
|
|
411
446
|
return use;
|
|
412
447
|
});
|
|
413
448
|
|
|
414
|
-
|
|
415
|
-
|
|
449
|
+
//tem pelo menos um item
|
|
450
|
+
const hasItems = computed(() => {
|
|
451
|
+
return items.value.length > 0
|
|
452
|
+
});
|
|
416
453
|
|
|
417
454
|
|
|
418
455
|
// =======================================================
|
|
@@ -489,22 +526,22 @@ function limiteText(text: string | null, limite: number | null): string | null {
|
|
|
489
526
|
return text;
|
|
490
527
|
}
|
|
491
528
|
|
|
492
|
-
function toggleOrderingState(
|
|
529
|
+
function toggleOrderingState(id: string) {
|
|
493
530
|
|
|
494
531
|
// desabilita todos que não são o header clicado
|
|
495
532
|
for (const key in orderings_state.value) {
|
|
496
|
-
if (key !==
|
|
533
|
+
if (key !== id) {
|
|
497
534
|
orderings_state.value[key] = 'none';
|
|
498
535
|
}
|
|
499
536
|
}
|
|
500
537
|
|
|
501
|
-
const currentState = orderings_state.value[
|
|
538
|
+
const currentState = orderings_state.value[id] || 'none';
|
|
502
539
|
if (currentState === 'none') {
|
|
503
|
-
orderings_state.value[
|
|
540
|
+
orderings_state.value[id] = 'increasing';
|
|
504
541
|
} else if (currentState === 'increasing') {
|
|
505
|
-
orderings_state.value[
|
|
542
|
+
orderings_state.value[id] = 'decreasing';
|
|
506
543
|
} else {
|
|
507
|
-
orderings_state.value[
|
|
544
|
+
orderings_state.value[id] = 'none';
|
|
508
545
|
}
|
|
509
546
|
|
|
510
547
|
reSearch();
|
|
@@ -587,7 +624,9 @@ defineExpose<ExposedFunctions<T>>({
|
|
|
587
624
|
atLeastOneSelected,
|
|
588
625
|
expand_item_toggle,
|
|
589
626
|
close_all_expanded_items,
|
|
590
|
-
selectAllCheckbox
|
|
627
|
+
selectAllCheckbox,
|
|
628
|
+
toggleColumnVisibility,
|
|
629
|
+
columns_list,
|
|
591
630
|
});
|
|
592
631
|
|
|
593
632
|
onMounted(() => {
|
|
@@ -608,258 +647,5 @@ watch(
|
|
|
608
647
|
</script>
|
|
609
648
|
|
|
610
649
|
<style lang="scss" scoped>
|
|
611
|
-
.
|
|
612
|
-
overflow-x: auto;
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
.state-feedback {
|
|
616
|
-
padding: 1rem;
|
|
617
|
-
text-align: center;
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
.state-feedback.error {
|
|
621
|
-
color: red;
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
.pagination-controls {
|
|
625
|
-
margin-top: 1rem;
|
|
626
|
-
display: flex;
|
|
627
|
-
justify-content: space-between;
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
$max-width-img: 40px;
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
.container-img {
|
|
634
|
-
aspect-ratio: 1;
|
|
635
|
-
display: flex;
|
|
636
|
-
justify-content: center;
|
|
637
|
-
overflow: hidden;
|
|
638
|
-
position: relative;
|
|
639
|
-
max-width: $max-width-img;
|
|
640
|
-
min-width: $max-width-img;
|
|
641
|
-
|
|
642
|
-
.img-tamanho-cover {
|
|
643
|
-
position: absolute;
|
|
644
|
-
top: 0;
|
|
645
|
-
width: 100%;
|
|
646
|
-
height: 100%;
|
|
647
|
-
object-fit: cover;
|
|
648
|
-
z-index: 0;
|
|
649
|
-
opacity: 0.5;
|
|
650
|
-
filter: blur(4px);
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
.img-tamanho {
|
|
654
|
-
object-fit: contain;
|
|
655
|
-
width: 100%;
|
|
656
|
-
height: 100%;
|
|
657
|
-
z-index: 2;
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
&.container-img-preview {
|
|
661
|
-
cursor: pointer;
|
|
662
|
-
|
|
663
|
-
&:hover {
|
|
664
|
-
border-style: dashed;
|
|
665
|
-
border-color: var(--tblr-primary);
|
|
666
|
-
border-width: 2px;
|
|
667
|
-
transition: border-width 0.15s ease-in-out;
|
|
668
|
-
|
|
669
|
-
.img-tamanho {
|
|
670
|
-
opacity: 0.3;
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
.bg-img {
|
|
677
|
-
background-color: #0000004d;
|
|
678
|
-
position: absolute;
|
|
679
|
-
top: 0;
|
|
680
|
-
width: 100%;
|
|
681
|
-
height: 100%;
|
|
682
|
-
z-index: 1;
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
$max-width-preview: 250px;
|
|
686
|
-
|
|
687
|
-
.image-preview-container {
|
|
688
|
-
position: fixed;
|
|
689
|
-
|
|
690
|
-
z-index: 9999;
|
|
691
|
-
|
|
692
|
-
background-color: #fff;
|
|
693
|
-
border-radius: 8px;
|
|
694
|
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
|
695
|
-
padding: 5px;
|
|
696
|
-
|
|
697
|
-
pointer-events: none;
|
|
698
|
-
transition: opacity 0.2s ease-in-out;
|
|
699
|
-
|
|
700
|
-
.image-preview-large {
|
|
701
|
-
display: block;
|
|
702
|
-
max-width: $max-width-preview;
|
|
703
|
-
|
|
704
|
-
max-height: $max-width-preview;
|
|
705
|
-
border-radius: 4px;
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
.form-check-input {
|
|
710
|
-
border-width: 1px !important;
|
|
711
|
-
border-color: rgba(0, 0, 0, 0.391) !important;
|
|
712
|
-
width: 17px;
|
|
713
|
-
height: 17px;
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
[data-bs-theme=dark] .form-check-input {
|
|
717
|
-
border-color: rgba(255, 255, 255, 0.374) !important;
|
|
718
|
-
}
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
/*
|
|
723
|
-
Estilos para arrastar e soltar colunas
|
|
724
|
-
*/
|
|
725
|
-
|
|
726
|
-
.ghost-item {
|
|
727
|
-
opacity: 0.5;
|
|
728
|
-
background: var(--tblr-primary-lt, #e6f0ff);
|
|
729
|
-
border-radius: 8px;
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
.dragging-item {
|
|
733
|
-
cursor: grabbing;
|
|
734
|
-
background: var(--tblr-primary);
|
|
735
|
-
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
|
736
|
-
opacity: 0.5;
|
|
737
|
-
background-color: var(--tblr-primary-bg-subtle);
|
|
738
|
-
filter: grayscale(0) invert(0);
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
.header-draggable {
|
|
742
|
-
cursor: grab;
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
/*
|
|
747
|
-
Animações para movimentação de colunas
|
|
748
|
-
*/
|
|
749
|
-
.column-move-move {
|
|
750
|
-
transition: transform 0.4s ease;
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
.column-move-enter-active,
|
|
754
|
-
.column-move-leave-active {
|
|
755
|
-
transition: all 0.4s ease;
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
.header-ordering {
|
|
760
|
-
display: flex;
|
|
761
|
-
justify-content: space-between;
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
/* 1. Animação de entrada para novos itens */
|
|
774
|
-
.expand-item-expand-enter-active {
|
|
775
|
-
transition: all 0.5s ease;
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
.expand-item-expand-enter-from {
|
|
779
|
-
opacity: 0;
|
|
780
|
-
transform: scaleY(0.3) translateY(-30px);
|
|
781
|
-
/* Começa em cima e desce */
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
.expand-item-expand-enter-to {
|
|
785
|
-
opacity: 1;
|
|
786
|
-
transform: scaleY(1);
|
|
787
|
-
transform: translateY(0);
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
/* 2. Animação de saída para itens removidos*/
|
|
791
|
-
.expand-item-expand-leave-active {
|
|
792
|
-
transition: all 0.4s ease;
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
.expand-item-expand-leave-to {
|
|
796
|
-
opacity: 0;
|
|
797
|
-
transform: scaleY(0.3) translateY(-30px);
|
|
798
|
-
/* Desliza para cima e desaparece */
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
.expand-item-fade-enter-active,
|
|
804
|
-
.expand-item-fade-leave-active {
|
|
805
|
-
transition: opacity 0.5s ease;
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
.expand-item-fade-enter-from,
|
|
809
|
-
.expand-item-fade-leave-to {
|
|
810
|
-
opacity: 0;
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
.btn-clean {
|
|
818
|
-
display: inline-flex;
|
|
819
|
-
align-items: center;
|
|
820
|
-
justify-content: center;
|
|
821
|
-
padding: 4px;
|
|
822
|
-
border-radius: 4px;
|
|
823
|
-
transition: background-color 0.2s ease;
|
|
824
|
-
background: transparent;
|
|
825
|
-
border: none;
|
|
826
|
-
outline: none;
|
|
827
|
-
cursor: pointer;
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
&:hover {
|
|
831
|
-
background-color: rgba(0, 0, 0, 0.05);
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
.icon-transition-arrow {
|
|
837
|
-
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), color 0.2s ease;
|
|
838
|
-
color: var(--tblr-primary, #206bc4);
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
.is-expanded .icon-transition-arrow {
|
|
843
|
-
transform: rotate(90deg);
|
|
844
|
-
}
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
.icon-transition-plus {
|
|
848
|
-
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), color 0.2s ease;
|
|
849
|
-
color: var(--tblr-primary, #206bc4);
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
.icon-transition-plus .vertical-line {
|
|
853
|
-
transform-origin: center;
|
|
854
|
-
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.2s ease;
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
.is-expanded .icon-transition-plus {
|
|
858
|
-
transform: rotate(180deg);
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
.is-expanded .icon-transition-plus .vertical-line {
|
|
862
|
-
transform: scaleY(0);
|
|
863
|
-
opacity: 0;
|
|
864
|
-
}
|
|
650
|
+
@use '@/DatatableVue/style/scss/VDataTable.scss';
|
|
865
651
|
</style>
|
|
@@ -30,9 +30,9 @@ export function useDataTableFetch<T>(
|
|
|
30
30
|
const objectOrdering: Record<string, any> = {};
|
|
31
31
|
for (const col of columns.value) {
|
|
32
32
|
if (col.use_ordering) {
|
|
33
|
-
if (orderings_state.value[col.
|
|
33
|
+
if (orderings_state.value[col.id] === 'increasing') {
|
|
34
34
|
objectOrdering[col.param_ordering] = col.increasing_value || 'increasing';
|
|
35
|
-
} else if (orderings_state.value[col.
|
|
35
|
+
} else if (orderings_state.value[col.id] === 'decreasing') {
|
|
36
36
|
objectOrdering[col.param_ordering] = col.decreasing_value || 'decreasing';
|
|
37
37
|
}
|
|
38
38
|
}
|
package/src/DatatableVue/keys.ts
CHANGED
|
@@ -22,6 +22,10 @@ export interface ColumnConfiguration {
|
|
|
22
22
|
decreasing_value: string;
|
|
23
23
|
increasing_value: string;
|
|
24
24
|
class_rules?: Record<string, (item: any) => boolean>;
|
|
25
|
+
start_hidden?: boolean;
|
|
26
|
+
// não é prop, é uma propriedade interna do VDataTable para controlar a visibilidade da coluna
|
|
27
|
+
visible?: boolean;
|
|
28
|
+
id: string; // ID único da coluna, gerado internamente pelo VDataTable
|
|
25
29
|
}
|
|
26
30
|
|
|
27
31
|
// A API que o VDataTable "fornece" para os filhos
|