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.
@@ -68,11 +68,11 @@
68
68
  </button>
69
69
  </div>
70
70
  <div class="table-responsive" v-else-if="items">
71
- <div v-if="items.length > 0">
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="header" :animation="400"
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.header] || 'none'"
90
- @toggleOrderingState="() => toggleOrderingState(col.header)" :locked="false" :col="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.header] || 'none'"
100
- @toggleOrderingState="() => toggleOrderingState(col.header)" :col="col" locked>
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-for="(item, index) in items" :key="item[options.item_key]">
111
- <TransitionGroup tag="tr" :name="isDraggingColumns ? 'column-move' : ''">
112
- <td v-if="options.use_expandable_items" class="w-1">
113
- <slot name="expand-button" :item="item" :index="index" :is-expanded="is_item_expanded(item)"
114
- :expand_item_toggle="expand_item_toggle">
115
- <button type="button" class="btn-clean btn-icon-anim"
116
- :class="{ 'is-expanded': is_item_expanded(item) }" @click="expand_item_toggle(item)">
117
-
118
- <template v-if="options.type_button_expand === 'arrow'">
119
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
120
- fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
121
- stroke-linejoin="round"
122
- class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-right icon-transition-arrow">
123
- <path stroke="none" d="M0 0h24v24H0z" fill="none" />
124
- <path d="M9 6l6 6l-6 6" />
125
- </svg>
126
-
127
- </template>
128
-
129
- <template v-else>
130
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24"
131
- fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
132
- stroke-linejoin="round" class="icon icon-transition-plus">
133
- <path stroke="none" d="M0 0h24v24H0z" fill="none" />
134
- <path d="M12 5l0 14" class="vertical-line" />
135
- <path d="M5 12l14 0" />
136
- </svg>
137
- </template>
138
-
139
- </button>
140
- </slot>
141
- </td>
142
- <td v-if="options.use_checkbox" class="w-1">
143
- <input class="form-check-input m-0" type="checkbox" :checked="isSelected(item)"
144
- @change="toggleItemSelection(item)" aria-label="Selecionar este item" />
145
- </td>
146
-
147
- <td v-for="(col, index) in renderedColumns" :key="col.field || col.header" :class="col.class_row">
148
- <component v-if="col.bodySlot" :is="col.bodySlot" :item="item" :index="index"
149
- :is-selected="isSelected(item)" />
150
- <span @click="col.click ? col.click(item) : null" :class="computeClasses(col, item)"
151
- v-else-if="col.type === 'text'">
152
- {{
153
- limiteText(getSubItem(col.field, item, col.transform_function), col.limite_text ?? null)
154
- }}</span>
155
-
156
- <span @click="col.click ? col.click(item) : null" v-else-if="col.type === 'date'"
157
- :class="computeClasses(col, item)">
158
- <span v-if="col.format === 'complete'">{{ new Date(getSubItem(col.field, item)).toLocaleString()
159
- }}</span>
160
- <span v-if="col.format === 'simple'"> {{ new Date(getSubItem(col.field,
161
- item)).toLocaleDateString()
162
- }} </span>
163
- </span>
164
- <div @click="col.click ? col.click(item) : null" :class="computeClasses(col, item)"
165
- v-else-if="col.type === 'html'" v-html="getSubItem(col.field, item)">
166
- </div>
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
- </div>
187
- <span class="text-danger erro-custom-container" v-else>tipo <span
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
- </slot>
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
- </tr>
204
- </Transition>
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-else-if="first_fetch === false">
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 = lockedColumns.value;
398
- columns.value = [...newUnlockedOrder, ...locked];
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(header: string) {
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 !== header) {
533
+ if (key !== id) {
497
534
  orderings_state.value[key] = 'none';
498
535
  }
499
536
  }
500
537
 
501
- const currentState = orderings_state.value[header] || 'none';
538
+ const currentState = orderings_state.value[id] || 'none';
502
539
  if (currentState === 'none') {
503
- orderings_state.value[header] = 'increasing';
540
+ orderings_state.value[id] = 'increasing';
504
541
  } else if (currentState === 'increasing') {
505
- orderings_state.value[header] = 'decreasing';
542
+ orderings_state.value[id] = 'decreasing';
506
543
  } else {
507
- orderings_state.value[header] = 'none';
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
- .table-responsive {
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.header] === 'increasing') {
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.header] === 'decreasing') {
35
+ } else if (orderings_state.value[col.id] === 'decreasing') {
36
36
  objectOrdering[col.param_ordering] = col.decreasing_value || 'decreasing';
37
37
  }
38
38
  }
@@ -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