v-sistec-features 1.2.5 → 1.3.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/_plugin-vue_export-helper-CHgC5LLL.js +9 -0
- package/dist/v-sistec-features.css +1 -1
- package/dist/vDataPage.js +460 -0
- package/dist/vDataTable.js +170 -174
- package/package.json +8 -3
- package/src/DataPageVue/components/PaginationDatatable.vue +222 -0
- package/src/DataPageVue/components/VDataPage.vue +519 -0
- package/src/DataPageVue/index.ts +4 -0
- package/src/DatatableVue/components/VDataTable.vue +1 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "v-sistec-features",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.3.0",
|
|
5
5
|
"author": "Márlon Bento Azevedo (https://github.com/marlon-bento)",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -23,6 +23,10 @@
|
|
|
23
23
|
"import": "./dist/vDataTable.js",
|
|
24
24
|
"types": "./dist/vDataTable.d.ts"
|
|
25
25
|
},
|
|
26
|
+
"./vDataPage": {
|
|
27
|
+
"import": "./dist/vDataPage.js",
|
|
28
|
+
"types": "./dist/vDataPage.d.ts"
|
|
29
|
+
},
|
|
26
30
|
"./iframeCommunicator": {
|
|
27
31
|
"import": "./dist/iframeCommunicator.js",
|
|
28
32
|
"types": "./dist/iframeCommunicator.d.ts"
|
|
@@ -51,17 +55,18 @@
|
|
|
51
55
|
"@semantic-release/github": "^11.0.6",
|
|
52
56
|
"@semantic-release/npm": "^12.0.2",
|
|
53
57
|
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
54
|
-
"semantic-release": "^24.2.9",
|
|
55
58
|
"@types/node": "^24.6.0",
|
|
56
59
|
"@vitejs/plugin-vue": "^6.0.1",
|
|
57
60
|
"@vue/tsconfig": "^0.8.1",
|
|
58
61
|
"sass-embedded": "^1.93.2",
|
|
62
|
+
"semantic-release": "^24.2.9",
|
|
59
63
|
"typescript": "~5.9.3",
|
|
60
64
|
"vite": "^7.1.7",
|
|
61
65
|
"vue-tsc": "^3.1.0"
|
|
62
66
|
},
|
|
63
67
|
"dependencies": {
|
|
64
68
|
"@tabler/core": "^1.4.0",
|
|
65
|
-
"
|
|
69
|
+
"v3-infinite-loading": "^1.3.2",
|
|
70
|
+
"vue": "^3.2.0"
|
|
66
71
|
}
|
|
67
72
|
}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed } from "vue";
|
|
3
|
+
|
|
4
|
+
// =======================================================
|
|
5
|
+
// 1. DEFINIÇÃO DE TIPOS E INTERFACES
|
|
6
|
+
// =======================================================
|
|
7
|
+
interface PaginationObject {
|
|
8
|
+
current_page: number;
|
|
9
|
+
count: number;
|
|
10
|
+
limit_per_page: number;
|
|
11
|
+
}
|
|
12
|
+
interface PaginationProps {
|
|
13
|
+
pagination: PaginationObject;
|
|
14
|
+
filtering?: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// =======================================================
|
|
18
|
+
// 2. PROPS E EMITS
|
|
19
|
+
// =======================================================
|
|
20
|
+
const props = withDefaults(defineProps<PaginationProps>(), {
|
|
21
|
+
filtering: false,
|
|
22
|
+
});
|
|
23
|
+
const emit = defineEmits<{
|
|
24
|
+
(e: 'tradePage'): void
|
|
25
|
+
}>();
|
|
26
|
+
|
|
27
|
+
// =======================================================
|
|
28
|
+
// 3. LÓGICA REATIVA (Computeds e Funções)
|
|
29
|
+
// =======================================================
|
|
30
|
+
const total_pages = computed<number>(() => {
|
|
31
|
+
if (!props.pagination.limit_per_page) return 0;
|
|
32
|
+
return Math.ceil(props.pagination.count / props.pagination.limit_per_page);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const next = computed(() => {
|
|
36
|
+
return props.pagination.current_page + 1 < total_pages.value
|
|
37
|
+
? props.pagination.current_page + 1
|
|
38
|
+
: null;
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Funções de navegação
|
|
42
|
+
const nextPage = (): void => {
|
|
43
|
+
props.pagination.current_page++;
|
|
44
|
+
emit("tradePage");
|
|
45
|
+
};
|
|
46
|
+
const setPage = (newPage: number): void => {
|
|
47
|
+
props.pagination.current_page = newPage - 1;
|
|
48
|
+
emit("tradePage");
|
|
49
|
+
};
|
|
50
|
+
const lastPage = (): void => {
|
|
51
|
+
props.pagination.current_page = total_pages.value - 1;
|
|
52
|
+
emit("tradePage");
|
|
53
|
+
};
|
|
54
|
+
const firstPage = (): void => {
|
|
55
|
+
props.pagination.current_page = 0;
|
|
56
|
+
emit("tradePage");
|
|
57
|
+
};
|
|
58
|
+
const prevPage = (): void => {
|
|
59
|
+
if (props.pagination.current_page > 0) {
|
|
60
|
+
props.pagination.current_page--;
|
|
61
|
+
emit("tradePage");
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// =======================================================
|
|
66
|
+
// 4. LÓGICA DE GERAÇÃO DE PÁGINAS
|
|
67
|
+
// =======================================================
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @description Computa um array com os números das páginas e as reticências a serem exibidas.
|
|
71
|
+
* Ex: [1, 2, '...', 10, 11, 12, '...', 33, 34]
|
|
72
|
+
*/
|
|
73
|
+
const paginasParaExibir = computed(() => {
|
|
74
|
+
// Se houver 7 páginas ou menos, mostre todas.
|
|
75
|
+
if (total_pages.value <= 7) {
|
|
76
|
+
return Array.from({ length: total_pages.value }, (_, i) => i + 1);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const paginaAtual = props.pagination.current_page + 1;
|
|
80
|
+
const total = total_pages.value;
|
|
81
|
+
|
|
82
|
+
// O conjunto de páginas visíveis sempre inclui as 2 primeiras, 2 últimas,
|
|
83
|
+
// a atual e suas duas vizinhas. O Set cuida de remover duplicatas.
|
|
84
|
+
const paginasEssenciais = new Set([
|
|
85
|
+
1, 2, // Sempre mostra as 2 primeiras
|
|
86
|
+
paginaAtual - 1, paginaAtual, paginaAtual + 1, // Mostra a atual e vizinhas
|
|
87
|
+
total - 1, total // Sempre mostra as 2 últimas
|
|
88
|
+
]);
|
|
89
|
+
|
|
90
|
+
const resultado: (number | string)[] = [];
|
|
91
|
+
let ultimoNumeroAdicionado = 0;
|
|
92
|
+
|
|
93
|
+
// Ordena os números e itera sobre eles para inserir as reticências
|
|
94
|
+
Array.from(paginasEssenciais).sort((a, b) => a - b).forEach(num => {
|
|
95
|
+
// Ignora números inválidos (como página 0 ou menores, ou maiores que o total)
|
|
96
|
+
if (num < 1 || num > total) return;
|
|
97
|
+
|
|
98
|
+
// Se houver um buraco entre o último número adicionado e o atual, insere "..."
|
|
99
|
+
if (num > ultimoNumeroAdicionado + 1) {
|
|
100
|
+
resultado.push('...');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
resultado.push(num);
|
|
104
|
+
ultimoNumeroAdicionado = num;
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
return resultado;
|
|
109
|
+
});
|
|
110
|
+
const svg_duas_setas =`
|
|
111
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
|
112
|
+
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
|
113
|
+
class="icon icon-tabler icons-tabler-outline icon-tabler-chevrons-left">
|
|
114
|
+
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
|
115
|
+
<path d="M11 7l-5 5l5 5" />
|
|
116
|
+
<path d="M17 7l-5 5l5 5" />
|
|
117
|
+
</svg>
|
|
118
|
+
`
|
|
119
|
+
const svg_uma_seta = `
|
|
120
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
|
121
|
+
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
|
122
|
+
class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-left">
|
|
123
|
+
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
|
124
|
+
<path d="M15 6l-6 6l6 6" />
|
|
125
|
+
</svg>
|
|
126
|
+
`
|
|
127
|
+
|
|
128
|
+
</script>
|
|
129
|
+
|
|
130
|
+
<template>
|
|
131
|
+
<div class="d-flex align-items-center justify-content-between w-100" v-if="props.pagination.count > 0">
|
|
132
|
+
<span>
|
|
133
|
+
Mostrando de
|
|
134
|
+
{{
|
|
135
|
+
props.pagination.count !== 0
|
|
136
|
+
? props.pagination.limit_per_page * props.pagination.current_page + 1
|
|
137
|
+
: 0
|
|
138
|
+
}}
|
|
139
|
+
até
|
|
140
|
+
{{
|
|
141
|
+
props.pagination.limit_per_page * (props.pagination.current_page + 1) < props.pagination.count ?
|
|
142
|
+
props.pagination.limit_per_page * (props.pagination.current_page + 1) : props.pagination.count }} de {{
|
|
143
|
+
props.pagination.count }} registros </span>
|
|
144
|
+
<div class="d-flex align-items-center gap-2" v-if="total_pages > 0">
|
|
145
|
+
<div class="d-flex">
|
|
146
|
+
<button class="btn btn-estilo" @click.prevent="firstPage" :disabled="props.pagination.current_page === 0" v-html="svg_duas_setas">
|
|
147
|
+
</button>
|
|
148
|
+
<button class="btn btn-estilo" @click.prevent="prevPage" :disabled="props.pagination.current_page === 0" v-html="svg_uma_seta">
|
|
149
|
+
</button>
|
|
150
|
+
</div>
|
|
151
|
+
|
|
152
|
+
<div class="d-flex gap-2">
|
|
153
|
+
<template v-for="(pagina, index) in paginasParaExibir" :key="index">
|
|
154
|
+
<button v-if="typeof pagina === 'number'"
|
|
155
|
+
:class="props.pagination.current_page + 1 == pagina ? 'page-select' : ''" class="page-estilo"
|
|
156
|
+
@click.prevent="setPage(pagina)" :disabled="props.pagination.current_page + 1 == pagina">
|
|
157
|
+
{{ pagina }}
|
|
158
|
+
</button>
|
|
159
|
+
<span v-else class="m-0 p-0">...</span>
|
|
160
|
+
</template>
|
|
161
|
+
</div>
|
|
162
|
+
<div class="d-flex">
|
|
163
|
+
<button @click.prevent="nextPage" class="btn btn-estilo rotate-180" :disabled="!next" v-html="svg_uma_seta">
|
|
164
|
+
</button>
|
|
165
|
+
<button @click.prevent="lastPage" class="btn btn-estilo rotate-180" :disabled="!next" v-html="svg_duas_setas">
|
|
166
|
+
</button>
|
|
167
|
+
</div>
|
|
168
|
+
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
</template>
|
|
172
|
+
<style lang="scss" scoped>
|
|
173
|
+
.rotate-180 {
|
|
174
|
+
:deep(svg) {
|
|
175
|
+
transform: rotate(180deg);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
}
|
|
179
|
+
.page-select {
|
|
180
|
+
background-color: var(--tblr-primary) !important;
|
|
181
|
+
color: white !important;
|
|
182
|
+
border: none !important;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.page-estilo {
|
|
186
|
+
border: none;
|
|
187
|
+
--cor-escurecida: color-mix(in srgb, var(--tblr-primary), #000 25%);
|
|
188
|
+
//border: 2px solid var(--cor-escurecida);
|
|
189
|
+
background: transparent;
|
|
190
|
+
padding: 1px 10px;
|
|
191
|
+
border-radius: 7px;
|
|
192
|
+
margin: 0 !important;
|
|
193
|
+
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out;
|
|
194
|
+
|
|
195
|
+
&:hover {
|
|
196
|
+
background: var(--cor-escurecida);
|
|
197
|
+
color: white;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.btn{
|
|
202
|
+
padding: 0 !important;
|
|
203
|
+
margin: 0 !important;
|
|
204
|
+
background: transparent !important;
|
|
205
|
+
border: none !important;
|
|
206
|
+
box-shadow: none !important;
|
|
207
|
+
}
|
|
208
|
+
:deep(.btn-estilo) {
|
|
209
|
+
svg {
|
|
210
|
+
padding: 0px !important;
|
|
211
|
+
margin: 0px !important;
|
|
212
|
+
}
|
|
213
|
+
&:hover svg {
|
|
214
|
+
stroke: var(--tblr-primary);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.icon-tabler {
|
|
219
|
+
margin: 0 !important;
|
|
220
|
+
padding: 0 !important;
|
|
221
|
+
}
|
|
222
|
+
</style>
|