v-sistec-features 1.9.3 → 1.10.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/v-sistec-features.css +1 -1
- package/dist/vDataTable.d.ts +14 -0
- package/dist/vDataTable.js +501 -398
- package/package.json +1 -1
- package/src/DataPageVue/types/v-data-page.ts +0 -2
- package/src/DatatableVue/components/VColumn.vue +1 -1
- package/src/DatatableVue/components/VDataTable.vue +226 -51
- package/src/DatatableVue/types/v-data-table.ts +7 -0
package/package.json
CHANGED
|
@@ -21,9 +21,8 @@
|
|
|
21
21
|
</slot>
|
|
22
22
|
|
|
23
23
|
<Search v-model:search="pagination.search" v-model:filter="pagination.filter" :list_filter="props.list_filter"
|
|
24
|
-
:item_use="item_use" @search="reSearch"
|
|
25
|
-
:
|
|
26
|
-
:placeholder_search="props.placeholder_search"/>
|
|
24
|
+
:item_use="item_use" @search="reSearch" :deactivate_search_on_clear="props.deactivate_search_on_clear"
|
|
25
|
+
:placeholder_search="props.placeholder_search" />
|
|
27
26
|
</div>
|
|
28
27
|
<slot name="item-selected-info" :selected_items="selected_items" :clearSelection="() => selected_items = []">
|
|
29
28
|
<div v-if="(props.use_checkbox && selected_items.length > 0) && !props.deactivate_selected_info"
|
|
@@ -165,6 +164,7 @@
|
|
|
165
164
|
<draggable v-model="draggableColumns" tag="tr" item-key="header" :animation="400"
|
|
166
165
|
ghost-class="ghost-item" drag-class="dragging-item">
|
|
167
166
|
<template #header>
|
|
167
|
+
<th v-if="props.use_expandable_items"></th>
|
|
168
168
|
<th v-if="props.use_checkbox" class="w-1">
|
|
169
169
|
<input class="form-check-input m-0" type="checkbox" ref="selectAllCheckbox"
|
|
170
170
|
@change="toggleSelectAll" aria-label="Selecionar todos os itens na página" />
|
|
@@ -282,60 +282,109 @@
|
|
|
282
282
|
|
|
283
283
|
</thead>
|
|
284
284
|
<tbody>
|
|
285
|
-
<
|
|
286
|
-
<
|
|
287
|
-
<
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
285
|
+
<template v-for="item in items" :key="item[props.item_key]">
|
|
286
|
+
<TransitionGroup tag="tr" name="column-move">
|
|
287
|
+
<td v-if="props.use_expandable_items" class="w-1">
|
|
288
|
+
<slot name="expand-button" :item="item" :is-expanded="is_item_expanded(item)"
|
|
289
|
+
:expand_item_toggle="expand_item_toggle">
|
|
290
|
+
<button type="button" class="btn-clean btn-icon-anim"
|
|
291
|
+
:class="{ 'is-expanded': is_item_expanded(item) }" @click="expand_item_toggle(item)">
|
|
292
|
+
|
|
293
|
+
<template v-if="props.type_button_expand === 'arrow'">
|
|
294
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
|
295
|
+
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
|
296
|
+
stroke-linejoin="round"
|
|
297
|
+
class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-right icon-transition-arrow">
|
|
298
|
+
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
|
299
|
+
<path d="M9 6l6 6l-6 6" />
|
|
300
|
+
</svg>
|
|
301
|
+
|
|
302
|
+
</template>
|
|
303
|
+
|
|
304
|
+
<template v-else>
|
|
305
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24"
|
|
306
|
+
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
|
307
|
+
stroke-linejoin="round" class="icon icon-transition-plus">
|
|
308
|
+
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
|
309
|
+
<path d="M12 5l0 14" class="vertical-line" />
|
|
310
|
+
<path d="M5 12l14 0" />
|
|
311
|
+
</svg>
|
|
312
|
+
</template>
|
|
313
|
+
|
|
314
|
+
</button>
|
|
315
|
+
</slot>
|
|
316
|
+
</td>
|
|
317
|
+
<td v-if="props.use_checkbox" class="w-1">
|
|
318
|
+
<input class="form-check-input m-0" type="checkbox" :checked="isSelected(item)"
|
|
319
|
+
@change="toggleItemSelection(item)" aria-label="Selecionar este item" />
|
|
320
|
+
</td>
|
|
321
|
+
|
|
322
|
+
<td v-for="col in renderedColumns" :key="col.field || col.header" :class="col.class_row">
|
|
323
|
+
<component v-if="col.bodySlot" :is="col.bodySlot" :item="item" :is-selected="isSelected(item)" />
|
|
324
|
+
<span @click="col.click ? col.click(item) : null"
|
|
325
|
+
:class="col.class_item + (col.click ? ' cursor-pointer' : '')" v-else-if="col.type === 'text'">
|
|
326
|
+
{{
|
|
327
|
+
limiteText(getSubItem(col.field, item, col.transform_function), col.limite_text ?? null)
|
|
328
|
+
}}</span>
|
|
329
|
+
|
|
330
|
+
<span @click="col.click ? col.click(item) : null" v-else-if="col.type === 'date'"
|
|
331
|
+
:class="col.class_item + (col.click ? ' cursor-pointer' : '')">
|
|
332
|
+
<span v-if="col.format === 'complete'">{{ new Date(getSubItem(col.field, item)).toLocaleString()
|
|
333
|
+
}}</span>
|
|
334
|
+
<span v-if="col.format === 'simple'"> {{ new Date(getSubItem(col.field,
|
|
335
|
+
item)).toLocaleDateString()
|
|
304
336
|
}} </span>
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
337
|
+
</span>
|
|
338
|
+
<div @click="col.click ? col.click(item) : null"
|
|
339
|
+
:class="col.class_item + (col.click ? ' cursor-pointer' : '')" v-else-if="col.type === 'html'"
|
|
340
|
+
v-html="getSubItem(col.field, item)">
|
|
341
|
+
</div>
|
|
342
|
+
|
|
343
|
+
<div @click="col.click ? col.click(item) : null"
|
|
344
|
+
:class="col.class_item + (col.click ? ' cursor-pointer' : '')" v-else-if="col.type === 'img'">
|
|
345
|
+
|
|
346
|
+
<div v-if="getSubItem(col.field, item)" v-bind="col.deactivate_img_preview ? {
|
|
347
|
+
class: 'container-img'
|
|
348
|
+
} :
|
|
349
|
+
{
|
|
350
|
+
onMouseover: (event) => handleMouseOver(event, getSubItem(col.field, item)),
|
|
351
|
+
onMousemove: handleMouseMove,
|
|
352
|
+
onMouseleave: handleMouseLeave,
|
|
353
|
+
class: 'container-img container-img-preview'
|
|
354
|
+
}">
|
|
355
|
+
|
|
356
|
+
<img class="img-tamanho" :src="getSubItem(col.field, item)" />
|
|
357
|
+
<img class="img-tamanho-cover" :src="getSubItem(col.field, item)" />
|
|
358
|
+
<div class="bg-img"></div>
|
|
359
|
+
</div>
|
|
360
|
+
|
|
327
361
|
</div>
|
|
362
|
+
<span class="text-danger erro-custom-container" v-else>tipo <span
|
|
363
|
+
class="badge bg-orange text-white erro-custom-text">{{ col.type }}</span> não suportado</span>
|
|
364
|
+
</td>
|
|
365
|
+
</TransitionGroup>
|
|
366
|
+
<Transition :name="'expand-item-' + props.type_animation_expand"
|
|
367
|
+
:css="!props.deactivate_animation_expand">
|
|
368
|
+
<!-- mostra uma linha após cada item -->
|
|
369
|
+
<tr v-if="is_item_expanded(item)" class="">
|
|
370
|
+
<!-- se estiver usando checkbox existe uma coluna a mais -->
|
|
371
|
+
<td :colspan="colspanExpandItems()">
|
|
372
|
+
<slot name="after-row" :item="item">
|
|
373
|
+
|
|
374
|
+
</slot>
|
|
375
|
+
|
|
376
|
+
</td>
|
|
377
|
+
</tr>
|
|
378
|
+
</Transition>
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
</template>
|
|
328
382
|
|
|
329
|
-
</div>
|
|
330
|
-
<span class="text-danger erro-custom-container" v-else>tipo <span
|
|
331
|
-
class="badge bg-orange text-white erro-custom-text">{{ col.type }}</span> não suportado</span>
|
|
332
|
-
</td>
|
|
333
|
-
</TransitionGroup>
|
|
334
383
|
</tbody>
|
|
335
384
|
</table>
|
|
336
385
|
</div>
|
|
337
|
-
<div v-else-if="first_fetch === false"
|
|
338
|
-
|
|
386
|
+
<div v-else-if="first_fetch === false">
|
|
387
|
+
|
|
339
388
|
</div>
|
|
340
389
|
<div v-else class="text-center p-4 text-secondary">
|
|
341
390
|
<p class="m-0">Nenhum item encontrado.</p>
|
|
@@ -413,6 +462,10 @@ const props = withDefaults(defineProps<VDataTableProps>(), {
|
|
|
413
462
|
immediate: true,
|
|
414
463
|
placeholder_search: "Buscar...",
|
|
415
464
|
deactivate_search_on_clear: false,
|
|
465
|
+
use_expandable_items: false,
|
|
466
|
+
type_animation_expand: 'expand',
|
|
467
|
+
deactivate_animation_expand: false,
|
|
468
|
+
type_button_expand: 'arrow'
|
|
416
469
|
});
|
|
417
470
|
|
|
418
471
|
|
|
@@ -427,6 +480,7 @@ const columns = ref<ColumnConfiguration[]>([]);
|
|
|
427
480
|
const items = ref<T[]>([]) as Ref<T[]>;
|
|
428
481
|
const totalItems = ref<number>(0);
|
|
429
482
|
const selected_items = ref<T[]>([]) as Ref<T[]>;
|
|
483
|
+
const expanded_items = ref<any[]>([]);
|
|
430
484
|
const selectAllCheckbox = ref<HTMLInputElement | null>(null);
|
|
431
485
|
const isDelaying = ref<boolean>(false);
|
|
432
486
|
const delayTimer = ref<ReturnType<typeof setTimeout> | null>(null);
|
|
@@ -749,6 +803,28 @@ function set_page(newPage: number): void {
|
|
|
749
803
|
console.warn("Número de página inválido.");
|
|
750
804
|
}
|
|
751
805
|
}
|
|
806
|
+
function expand_item_toggle(item: any): void {
|
|
807
|
+
const identifier_item = item[props.item_key];
|
|
808
|
+
const index = expanded_items.value.findIndex(expandedItem => expandedItem === identifier_item);
|
|
809
|
+
if (index > -1) {
|
|
810
|
+
expanded_items.value.splice(index, 1); // Remove se já existe
|
|
811
|
+
} else {
|
|
812
|
+
expanded_items.value.push(identifier_item); // Adiciona se não existe
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
function is_item_expanded(item: any): boolean {
|
|
816
|
+
const identifier_item = item[props.item_key];
|
|
817
|
+
return expanded_items.value.some(expandedItem => expandedItem === identifier_item);
|
|
818
|
+
}
|
|
819
|
+
function close_all_expanded_items(): void {
|
|
820
|
+
expanded_items.value = [];
|
|
821
|
+
}
|
|
822
|
+
function colspanExpandItems(): number {
|
|
823
|
+
let colspan = columns.value.length;
|
|
824
|
+
if (props.use_checkbox) colspan += 1;
|
|
825
|
+
if (props.use_expandable_items) colspan += 1;
|
|
826
|
+
return colspan;
|
|
827
|
+
}
|
|
752
828
|
|
|
753
829
|
defineExpose<ExposedFunctions<T>>({
|
|
754
830
|
execute: fetchDataWithDelay,
|
|
@@ -761,6 +837,8 @@ defineExpose<ExposedFunctions<T>>({
|
|
|
761
837
|
default_params,
|
|
762
838
|
selected_items,
|
|
763
839
|
atLeastOneSelected,
|
|
840
|
+
expand_item_toggle,
|
|
841
|
+
close_all_expanded_items
|
|
764
842
|
});
|
|
765
843
|
const on_mounted_called = ref<boolean>(false);
|
|
766
844
|
watch(
|
|
@@ -954,4 +1032,101 @@ $max-width-preview: 250px;
|
|
|
954
1032
|
display: flex;
|
|
955
1033
|
justify-content: space-between;
|
|
956
1034
|
}
|
|
1035
|
+
|
|
1036
|
+
|
|
1037
|
+
|
|
1038
|
+
|
|
1039
|
+
|
|
1040
|
+
|
|
1041
|
+
|
|
1042
|
+
|
|
1043
|
+
|
|
1044
|
+
|
|
1045
|
+
/* 1. Animação de entrada para novos itens */
|
|
1046
|
+
.expand-item-expand-enter-active {
|
|
1047
|
+
transition: all 0.5s ease;
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
.expand-item-expand-enter-from {
|
|
1051
|
+
opacity: 0;
|
|
1052
|
+
transform: scaleY(0.3) translateY(-30px);
|
|
1053
|
+
/* Começa em cima e desce */
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
.expand-item-expand-enter-to {
|
|
1057
|
+
opacity: 1;
|
|
1058
|
+
transform: scaleY(1);
|
|
1059
|
+
transform: translateY(0);
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
/* 2. Animação de saída para itens removidos*/
|
|
1063
|
+
.expand-item-expand-leave-active {
|
|
1064
|
+
transition: all 0.4s ease;
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
.expand-item-expand-leave-to {
|
|
1068
|
+
opacity: 0;
|
|
1069
|
+
transform: scaleY(0.3) translateY(-30px);
|
|
1070
|
+
/* Desliza para cima e desaparece */
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
|
|
1074
|
+
|
|
1075
|
+
.expand-item-fade-enter-active,
|
|
1076
|
+
.expand-item-fade-leave-active {
|
|
1077
|
+
transition: opacity 0.5s ease;
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
.expand-item-fade-enter-from,
|
|
1081
|
+
.expand-item-fade-leave-to {
|
|
1082
|
+
opacity: 0;
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
|
|
1086
|
+
|
|
1087
|
+
|
|
1088
|
+
|
|
1089
|
+
.btn-clean {
|
|
1090
|
+
display: inline-flex;
|
|
1091
|
+
align-items: center;
|
|
1092
|
+
justify-content: center;
|
|
1093
|
+
padding: 4px;
|
|
1094
|
+
border-radius: 4px;
|
|
1095
|
+
transition: background-color 0.2s ease;
|
|
1096
|
+
|
|
1097
|
+
&:hover {
|
|
1098
|
+
background-color: rgba(0, 0, 0, 0.05);
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
|
|
1103
|
+
.icon-transition-arrow {
|
|
1104
|
+
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), color 0.2s ease;
|
|
1105
|
+
color: var(--tblr-primary, #206bc4);
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
|
|
1109
|
+
.is-expanded .icon-transition-arrow {
|
|
1110
|
+
transform: rotate(90deg);
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
|
|
1114
|
+
.icon-transition-plus {
|
|
1115
|
+
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), color 0.2s ease;
|
|
1116
|
+
color: var(--tblr-primary, #206bc4);
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
.icon-transition-plus .vertical-line {
|
|
1120
|
+
transform-origin: center;
|
|
1121
|
+
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.2s ease;
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
.is-expanded .icon-transition-plus {
|
|
1125
|
+
transform: rotate(180deg);
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
.is-expanded .icon-transition-plus .vertical-line {
|
|
1129
|
+
transform: scaleY(0);
|
|
1130
|
+
opacity: 0;
|
|
1131
|
+
}
|
|
957
1132
|
</style>
|
|
@@ -54,6 +54,11 @@ export interface VDataTableProps {
|
|
|
54
54
|
|
|
55
55
|
// Ativa a funcionalidade de seleção com checkboxes
|
|
56
56
|
use_checkbox?: boolean;
|
|
57
|
+
use_expandable_items?: boolean;
|
|
58
|
+
type_animation_expand?: 'fade' | 'expand' | 'none';
|
|
59
|
+
deactivate_animation_expand?: boolean;
|
|
60
|
+
type_button_expand?: 'arrow' | 'plus';
|
|
61
|
+
|
|
57
62
|
// Define qual propriedade do item será usada como chave única para a seleção.
|
|
58
63
|
item_key?: string;
|
|
59
64
|
|
|
@@ -76,4 +81,6 @@ export interface ExposedFunctions<T extends Record<string, any>> {
|
|
|
76
81
|
set_search: (newSearch: string) => void;
|
|
77
82
|
set_filter: (newFilter: string) => void;
|
|
78
83
|
set_page: (newPage: number) => void;
|
|
84
|
+
expand_item_toggle: (item: any) => void;
|
|
85
|
+
close_all_expanded_items: () => void;
|
|
79
86
|
}
|