v-sistec-features 1.22.3 → 1.23.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "v-sistec-features",
3
3
  "private": false,
4
- "version": "1.22.3",
4
+ "version": "1.23.2",
5
5
  "author": "Márlon Bento Azevedo (https://github.com/marlon-bento)",
6
6
  "repository": {
7
7
  "type": "git",
@@ -57,18 +57,12 @@
57
57
  "vuedraggable": "^4.1.0"
58
58
  },
59
59
  "devDependencies": {
60
- "@semantic-release/changelog": "^6.0.3",
61
- "@semantic-release/commit-analyzer": "^13.0.1",
62
- "@semantic-release/exec": "^7.1.0",
63
- "@semantic-release/git": "^10.0.1",
64
- "@semantic-release/github": "^11.0.6",
65
- "@semantic-release/npm": "^12.0.2",
66
- "@semantic-release/release-notes-generator": "^14.1.0",
60
+ "@release-it/conventional-changelog": "^11.0.1",
67
61
  "@types/node": "^24.6.0",
68
62
  "@vitejs/plugin-vue": "^6.0.1",
69
63
  "@vue/tsconfig": "^0.8.1",
64
+ "release-it": "^20.2.1",
70
65
  "sass-embedded": "^1.93.2",
71
- "semantic-release": "^24.2.9",
72
66
  "typescript": "~5.9.3",
73
67
  "vite": "^7.1.7",
74
68
  "vite-plugin-dts": "^4.5.4",
@@ -79,7 +73,7 @@
79
73
  "@tabler/core": "^1.4.0",
80
74
  "pinia": "^2.1.0 || ^3.0.0",
81
75
  "v-api-fetch": "^1.6.0",
82
- "v-required": "^2.1.0",
76
+ "v-required": "^2.5.0",
83
77
  "v3-infinite-loading": "^1.3.2",
84
78
  "vue-toastification": "^2.0.0-rc.5"
85
79
  }
@@ -3,12 +3,14 @@
3
3
  </template>
4
4
 
5
5
  <script setup lang="ts">
6
- import { inject, onMounted, useSlots, defineSlots } from 'vue';
6
+ import { inject, onMounted, useSlots } from 'vue';
7
7
  import { dataTableApiKey } from '../keys';
8
8
 
9
9
  defineSlots<{
10
10
  // props para o slot body
11
11
  body?: (props: { item: any }) => any,
12
+ col_header?: (props: { col: any, locked: boolean }) => any,
13
+ col_header_midle?: (props: { col: any, locked: boolean }) => any,
12
14
  }>();
13
15
  interface VColumnProps {
14
16
  field?: string | null;
@@ -113,9 +115,15 @@ onMounted(() => {
113
115
  class_rules: props.class_rules,
114
116
 
115
117
  bodySlot: slots.body,
118
+ // colHeaderSlot é para o slot do header da coluna, que pode ser usado para colocar ícone de ordenação ou qualquer outra coisa que o usuário queira colocar no header da coluna
119
+ colHeaderSlot: slots.col_header,
120
+ // colHeaderMidleSlot é para o slot do header da coluna, mas ele fica entre o texto do header e o ícone de ordenação, para o usuário colocar coisas entre eles
121
+ colHeaderMidleSlot: slots.col_header_midle,
116
122
  ...(props.type === 'text' && { limite_text: Number(props.limite_text) }),
117
123
  ...(props.type === 'img' && { deactivate_img_preview: props.deactivate_img_preview }),
118
124
  ...(props.type === 'date' && { format: props.format }),
125
+
119
126
  });
127
+
120
128
  });
121
129
  </script>
@@ -75,6 +75,7 @@
75
75
  <draggable v-model="draggableColumns" tag="tr" item-key="header" :animation="400"
76
76
  ghost-class="ghost-item" drag-class="dragging-item" @start="isDraggingColumns = true"
77
77
  @end="() => onDragEnd()">
78
+
78
79
  <template #header>
79
80
  <th v-if="options.use_expandable_items"></th>
80
81
  <th v-if="options.use_checkbox" class="w-1">
@@ -84,115 +85,27 @@
84
85
  </template>
85
86
 
86
87
  <template #item="{ element: col }">
87
- <template v-if="col.use_ordering">
88
- <th class="header-draggable" :class="col.class_column">
89
- <div class="header-ordering">
90
- <span>{{ col.header }}</span>
91
-
92
- <span @click="() => toggleOrderingState(col.header)" class="ms-2 cursor-pointer">
93
- <svg v-if="!orderings_state[col.header] || orderings_state[col.header] === 'none'"
94
- xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none"
95
- stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
96
- <path d="m3 8 4-4 4 4"></path>
97
- <path d="m11 16-4 4-4-4"></path>
98
- <path d="M7 4v16"></path>
99
- <path d="M15 8h6"></path>
100
- <path d="M15 16h6"></path>
101
- <path d="M13 12h8"></path>
102
- </svg>
103
-
104
-
105
- <svg v-else-if="orderings_state[col.header] === 'decreasing'"
106
- xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none"
107
- stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
108
- <path d="m3 16 4 4 4-4"></path>
109
- <path d="M7 20V4"></path>
110
- <path d="M11 4h10"></path>
111
- <path d="M11 8h7"></path>
112
- <path d="M11 12h4"></path>
113
- </svg>
114
-
115
- <svg v-else-if="orderings_state[col.header] === 'increasing'"
116
- xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none"
117
- stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
118
- <path d="m3 8 4-4 4 4"></path>
119
- <path d="M7 4v16"></path>
120
- <path d="M11 12h4"></path>
121
- <path d="M11 16h7"></path>
122
- <path d="M11 20h10"></path>
123
- </svg>
124
-
125
- </span>
126
- </div>
127
-
128
- </th>
129
- </template>
130
- <template v-else>
131
- <th class="header-draggable" :class="col.class_column">
132
- {{ col.header }}
133
- </th>
134
- </template>
135
-
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
+
92
+ </v-th-data-table>
136
93
  </template>
137
94
 
138
95
  <template #footer>
96
+
139
97
  <template v-for="col in lockedColumns" :key="col.field || col.header">
140
- <template v-if="col.use_ordering">
141
- <th class="header-locked header-ordering" :class="col.class_column">
142
- <div class="header-ordering">
143
- <span>{{ col.header }}</span>
144
-
145
- <span @click="() => toggleOrderingState(col.header)" class="ms-2 cursor-pointer">
146
- <svg v-if="!orderings_state[col.header] || orderings_state[col.header] === 'none'"
147
- xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"
148
- fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
149
- stroke-linejoin="round">
150
- <path d="m3 8 4-4 4 4"></path>
151
- <path d="m11 16-4 4-4-4"></path>
152
- <path d="M7 4v16"></path>
153
- <path d="M15 8h6"></path>
154
- <path d="M15 16h6"></path>
155
- <path d="M13 12h8"></path>
156
- </svg>
157
-
158
-
159
- <svg v-else-if="orderings_state[col.header] === 'decreasing'"
160
- xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"
161
- fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
162
- stroke-linejoin="round">
163
- <path d="m3 16 4 4 4-4"></path>
164
- <path d="M7 20V4"></path>
165
- <path d="M11 4h10"></path>
166
- <path d="M11 8h7"></path>
167
- <path d="M11 12h4"></path>
168
- </svg>
169
-
170
- <svg v-else-if="orderings_state[col.header] === 'increasing'"
171
- xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"
172
- fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
173
- stroke-linejoin="round">
174
- <path d="m3 8 4-4 4 4"></path>
175
- <path d="M7 4v16"></path>
176
- <path d="M11 12h4"></path>
177
- <path d="M11 16h7"></path>
178
- <path d="M11 20h10"></path>
179
- </svg>
180
- </span>
181
- </div>
182
- </th>
183
- </template>
184
-
185
- <template v-else>
186
- <th class="header-locked" :class="col.class_column">
187
- {{ col.header }}
188
- </th>
189
- </template>
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
+
102
+ </v-th-data-table>
190
103
 
191
104
  </template>
192
105
  </template>
193
106
  </draggable>
194
-
195
107
  </thead>
108
+
196
109
  <tbody>
197
110
  <template v-for="(item, index) in items" :key="item[options.item_key]">
198
111
  <TransitionGroup tag="tr" :name="isDraggingColumns ? 'column-move' : ''">
@@ -243,10 +156,10 @@
243
156
  <span @click="col.click ? col.click(item) : null" v-else-if="col.type === 'date'"
244
157
  :class="computeClasses(col, item)">
245
158
  <span v-if="col.format === 'complete'">{{ new Date(getSubItem(col.field, item)).toLocaleString()
246
- }}</span>
159
+ }}</span>
247
160
  <span v-if="col.format === 'simple'"> {{ new Date(getSubItem(col.field,
248
161
  item)).toLocaleDateString()
249
- }} </span>
162
+ }} </span>
250
163
  </span>
251
164
  <div @click="col.click ? col.click(item) : null" :class="computeClasses(col, item)"
252
165
  v-else-if="col.type === 'html'" v-html="getSubItem(col.field, item)">
@@ -336,6 +249,7 @@ import { useExpandedItem } from '../composables/useExpandedItem';
336
249
  import { useDataTableFetch } from '../composables/useDataTableFetch';
337
250
  import { useCheckBox } from '../composables/useCheckBox.ts';
338
251
  import VDataTableLoading from './VDataTableLoading.vue';
252
+ import VThDataTable from './VThDataTable.vue';
339
253
  const globalConfig = inject(DATA_TABLE_CONFIG, {});
340
254
  const {
341
255
  isHovering,
@@ -532,6 +446,7 @@ function onDragEnd() {
532
446
  function addColumn(colConfig: ColumnConfiguration): void {
533
447
  columns.value.push(colConfig);
534
448
  }
449
+
535
450
  provide(dataTableApiKey, { addColumn });
536
451
 
537
452
 
@@ -575,6 +490,7 @@ function limiteText(text: string | null, limite: number | null): string | null {
575
490
  }
576
491
 
577
492
  function toggleOrderingState(header: string) {
493
+
578
494
  // desabilita todos que não são o header clicado
579
495
  for (const key in orderings_state.value) {
580
496
  if (key !== header) {
@@ -0,0 +1,107 @@
1
+ <template>
2
+ <th :class="class_all">
3
+ <div :class="{ 'header-ordering': use_ordering }">
4
+
5
+ <component
6
+ v-if="hasCustomHeader"
7
+ :is="col.colHeaderSlot"
8
+ v-bind="{ col: props.col, locked: props.locked }"
9
+ ></component>
10
+
11
+ <template v-else>
12
+ <span>
13
+ {{ props.header }}
14
+ </span>
15
+
16
+ <component
17
+ v-if="col.colHeaderMidleSlot"
18
+ :is="col.colHeaderMidleSlot"
19
+ v-bind="{ col: props.col, locked: props.locked }"
20
+ ></component>
21
+
22
+ <span v-if="use_ordering" @click="emit('toggleOrderingState')" class="ms-2 cursor-pointer">
23
+ <svg v-if="!props.orderings_state || props.orderings_state === 'none'" xmlns="http://www.w3.org/2000/svg"
24
+ width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
25
+ stroke-linecap="round" stroke-linejoin="round">
26
+ <path d="m3 8 4-4 4 4"></path>
27
+ <path d="m11 16-4 4-4-4"></path>
28
+ <path d="M7 4v16"></path>
29
+ <path d="M15 8h6"></path>
30
+ <path d="M15 16h6"></path>
31
+ <path d="M13 12h8"></path>
32
+ </svg>
33
+
34
+ <svg v-else-if="props.orderings_state === 'decreasing'" xmlns="http://www.w3.org/2000/svg" width="16"
35
+ height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
36
+ stroke-linejoin="round">
37
+ <path d="m3 16 4 4 4-4"></path>
38
+ <path d="M7 20V4"></path>
39
+ <path d="M11 4h10"></path>
40
+ <path d="M11 8h7"></path>
41
+ <path d="M11 12h4"></path>
42
+ </svg>
43
+
44
+ <svg v-else-if="props.orderings_state === 'increasing'" xmlns="http://www.w3.org/2000/svg" width="16"
45
+ height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
46
+ stroke-linejoin="round">
47
+ <path d="m3 8 4-4 4 4"></path>
48
+ <path d="M7 4v16"></path>
49
+ <path d="M11 12h4"></path>
50
+ <path d="M11 16h7"></path>
51
+ <path d="M11 20h10"></path>
52
+ </svg>
53
+ </span>
54
+ </template>
55
+
56
+ </div>
57
+ </th>
58
+ </template>
59
+
60
+ <script setup lang="ts">
61
+ import { computed, Comment, Fragment, Text } from 'vue';
62
+
63
+ const props = defineProps<{
64
+ header: string;
65
+ class_column: string;
66
+ locked: boolean;
67
+ use_ordering: boolean;
68
+ orderings_state: 'none' | 'increasing' | 'decreasing';
69
+ col: any;
70
+ }>();
71
+
72
+ const class_all = computed(() => {
73
+ return {
74
+ 'header-draggable': !props.locked,
75
+ 'header-locked': props.locked,
76
+ [props.class_column]: true,
77
+ }
78
+ })
79
+
80
+ const emit = defineEmits<{
81
+ toggleOrderingState: [void];
82
+ }>();
83
+
84
+ // Função robusta para verificar se todos os nós gerados são apenas comentários (v-if false)
85
+ // para evitar falsos positivos, também verifica se são nós de texto vazios ou apenas espaços em branco, e trata recursivamente fragmentos
86
+ // quando isso for vazio significa que não tem nada no slot então ele mostra a versão padrão do header
87
+ // se tiver algo ele sobrescreve o header padrão
88
+ const isEmptySlot = (vnodes: any[]): boolean => {
89
+ if (!vnodes || vnodes.length === 0) return true;
90
+ return vnodes.every(vnode => {
91
+ if (vnode.type === Comment) return true;
92
+ if (vnode.type === Text && typeof vnode.children === 'string' && !vnode.children.trim()) return true;
93
+ if (vnode.type === Fragment || vnode.type === Symbol.for('v-fgt') || String(vnode.type) === 'Symbol(Fragment)') {
94
+ return isEmptySlot(vnode.children as any[]);
95
+ }
96
+ return false;
97
+ });
98
+ };
99
+
100
+ const hasCustomHeader = computed(() => {
101
+ if (!props.col || !props.col.colHeaderSlot) return false;
102
+ // Executa a função do slot original e analisa a árvore
103
+ const vnodes = props.col.colHeaderSlot({ col: props.col, locked: props.locked });
104
+ return !isEmptySlot(vnodes);
105
+ });
106
+ </script>
107
+ <style scoped></style>
@@ -10,6 +10,8 @@ export interface ColumnConfiguration {
10
10
  class_item: string;
11
11
  transform_function: ((value: any) => any) | null;
12
12
  bodySlot?: Slot;
13
+ colHeaderSlot?: Slot;
14
+ colHeaderMidleSlot?: Slot;
13
15
  limite_text?: number;
14
16
  deactivate_img_preview?: boolean;
15
17
  format?: 'complete' | 'simple';