v-sistec-features 1.18.0-beta.1 → 1.18.0-beta.3
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/Pagination.d.ts +1 -1
- package/dist/core.d.ts +55 -1
- package/dist/core.js +1 -1
- package/dist/datatableConfig-BMFlKtgh.js +4 -0
- package/dist/index.d.ts +55 -1
- package/dist/index.js +1 -1
- package/dist/{plugin-C0f4EPnK.js → plugin-BwqrOSD_.js} +235 -230
- package/dist/v-sistec-features.css +1 -1
- package/dist/vDataTable.js +623 -591
- package/package.json +1 -1
- package/src/DatatableVue/components/VDataTable.vue +83 -63
- package/src/config/datatableConfig.ts +8 -0
- package/src/core/plugin.ts +18 -4
package/package.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
-
<div class="" :class="
|
|
3
|
+
<div class="" :class="options.class_container">
|
|
4
4
|
<slot></slot>
|
|
5
|
-
<div class="" :class="
|
|
6
|
-
<div :class="
|
|
5
|
+
<div class="" :class="options.class_content">
|
|
6
|
+
<div :class="options.class_filters" class="d-flex justify-content-between align-items-start ">
|
|
7
7
|
<slot name="pageSize" :changePageSize="changePageSize" :limit_per_page="pagination.limit_per_page">
|
|
8
|
-
<div class="text-secondary" :class="
|
|
9
|
-
{{
|
|
8
|
+
<div class="text-secondary" :class="options.class_page_size">
|
|
9
|
+
{{ options.first_text_page_size }}
|
|
10
10
|
<div class="mx-2 d-inline-block">
|
|
11
11
|
<input class="form-control form-control-sm" @change="changePageSize"
|
|
12
12
|
v-model.lazy="pagination.limit_per_page" min="1" size="3" aria-label="Número de registros por página"
|
|
13
13
|
type="number" />
|
|
14
14
|
</div>
|
|
15
|
-
{{
|
|
15
|
+
{{ options.second_text_page_size }}
|
|
16
16
|
</div>
|
|
17
17
|
</slot>
|
|
18
18
|
|
|
@@ -20,13 +20,13 @@
|
|
|
20
20
|
|
|
21
21
|
</slot>
|
|
22
22
|
|
|
23
|
-
<Search v-model:search="pagination.search" v-model:filter="pagination.filter" :list_filter="
|
|
24
|
-
:item_use="item_use" @search="reSearch" :deactivate_search_on_clear="
|
|
25
|
-
:placeholder_search="
|
|
23
|
+
<Search v-model:search="pagination.search" v-model:filter="pagination.filter" :list_filter="options.list_filter"
|
|
24
|
+
:item_use="item_use" @search="reSearch" :deactivate_search_on_clear="options.deactivate_search_on_clear"
|
|
25
|
+
:placeholder_search="options.placeholder_search" :deactivate_search_empty="options.deactivate_search_empty"
|
|
26
26
|
@clicked-clear-search="$emit('clickedClearSearch')" />
|
|
27
27
|
</div>
|
|
28
28
|
<slot name="item-selected-info" :selected_items="selected_items" :clearSelection="() => selected_items = []">
|
|
29
|
-
<div v-if="(
|
|
29
|
+
<div v-if="(options.use_checkbox && selected_items.length > 0) && !options.deactivate_selected_info"
|
|
30
30
|
class="alert alert-cyan d-flex justify-content-center align-items-center py-2" role="alert">
|
|
31
31
|
<h4 class="alert-title m-0"> <strong>oi Itens Selecionados:</strong> <span
|
|
32
32
|
class="badge bg-azure text-azure-fg">{{ selected_items.length }}</span></h4>
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
<VDataTableLoading v-if="showLoadingState" :columns="columns" :limit="pagination.limit_per_page"
|
|
50
|
-
:type_loading="
|
|
50
|
+
:type_loading="options.type_loading" :custom_loading="options.custom_loading" :class_table="options.class_table"
|
|
51
51
|
:attempt="attempt" :pagination="pagination" />
|
|
52
52
|
<div v-else-if="error" class="feedback-container text-center">
|
|
53
53
|
<h4 class="text-danger">Ocorreu um Erro</h4>
|
|
@@ -63,15 +63,15 @@
|
|
|
63
63
|
</div>
|
|
64
64
|
<div class="table-responsive" v-else-if="items">
|
|
65
65
|
<div v-if="items.length > 0">
|
|
66
|
-
<table class="table table-vcenter table-selectable" :class="
|
|
66
|
+
<table class="table table-vcenter table-selectable" :class="options.class_table">
|
|
67
67
|
<thead>
|
|
68
68
|
|
|
69
69
|
<draggable v-model="draggableColumns" tag="tr" item-key="header" :animation="400"
|
|
70
70
|
ghost-class="ghost-item" drag-class="dragging-item" @start="isDraggingColumns = true"
|
|
71
71
|
@end="() => onDragEnd()">
|
|
72
72
|
<template #header>
|
|
73
|
-
<th v-if="
|
|
74
|
-
<th v-if="
|
|
73
|
+
<th v-if="options.use_expandable_items"></th>
|
|
74
|
+
<th v-if="options.use_checkbox" class="w-1">
|
|
75
75
|
<input class="form-check-input m-0" type="checkbox" ref="selectAllCheckbox"
|
|
76
76
|
@change="toggleSelectAll" aria-label="Selecionar todos os itens na página" />
|
|
77
77
|
</th>
|
|
@@ -188,15 +188,15 @@
|
|
|
188
188
|
|
|
189
189
|
</thead>
|
|
190
190
|
<tbody>
|
|
191
|
-
<template v-for="item in items" :key="item[
|
|
191
|
+
<template v-for="item in items" :key="item[options.item_key]">
|
|
192
192
|
<TransitionGroup tag="tr" :name="isDraggingColumns ? 'column-move' : ''">
|
|
193
|
-
<td v-if="
|
|
193
|
+
<td v-if="options.use_expandable_items" class="w-1">
|
|
194
194
|
<slot name="expand-button" :item="item" :is-expanded="is_item_expanded(item)"
|
|
195
195
|
:expand_item_toggle="expand_item_toggle">
|
|
196
196
|
<button type="button" class="btn-clean btn-icon-anim"
|
|
197
197
|
:class="{ 'is-expanded': is_item_expanded(item) }" @click="expand_item_toggle(item)">
|
|
198
198
|
|
|
199
|
-
<template v-if="
|
|
199
|
+
<template v-if="options.type_button_expand === 'arrow'">
|
|
200
200
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
|
201
201
|
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
|
202
202
|
stroke-linejoin="round"
|
|
@@ -220,7 +220,7 @@
|
|
|
220
220
|
</button>
|
|
221
221
|
</slot>
|
|
222
222
|
</td>
|
|
223
|
-
<td v-if="
|
|
223
|
+
<td v-if="options.use_checkbox" class="w-1">
|
|
224
224
|
<input class="form-check-input m-0" type="checkbox" :checked="isSelected(item)"
|
|
225
225
|
@change="toggleItemSelection(item)" aria-label="Selecionar este item" />
|
|
226
226
|
</td>
|
|
@@ -268,10 +268,10 @@
|
|
|
268
268
|
class="badge bg-orange text-white erro-custom-text">{{ col.type }}</span> não suportado</span>
|
|
269
269
|
</td>
|
|
270
270
|
</TransitionGroup>
|
|
271
|
-
<Transition :name="'expand-item-' +
|
|
272
|
-
:css="!
|
|
271
|
+
<Transition :name="'expand-item-' + options.type_animation_expand"
|
|
272
|
+
:css="!options.deactivate_animation_expand">
|
|
273
273
|
<!-- mostra uma linha após cada item -->
|
|
274
|
-
<tr :id="'expand-item-' + item[
|
|
274
|
+
<tr :id="'expand-item-' + item[options.item_key]" v-if="is_item_expanded(item)"
|
|
275
275
|
class="expanded-item-row">
|
|
276
276
|
<!-- se estiver usando checkbox existe uma coluna a mais -->
|
|
277
277
|
<td :colspan="colspanExpandItems()">
|
|
@@ -301,8 +301,8 @@
|
|
|
301
301
|
</div>
|
|
302
302
|
</div>
|
|
303
303
|
<slot name="pagination" :pagination="pagination" :tradePage="fetchDataWithDelay" :error="error">
|
|
304
|
-
<div v-if="!error && pagination.count > 0" class="px-3" :class="
|
|
305
|
-
<PaginationDatatable :page_starts_at="
|
|
304
|
+
<div v-if="!error && pagination.count > 0" class="px-3" :class="options.class_pagination">
|
|
305
|
+
<PaginationDatatable :page_starts_at="options.page_starts_at" :filtering="true" :pagination="pagination"
|
|
306
306
|
@tradePage="tradePageEmit" />
|
|
307
307
|
</div>
|
|
308
308
|
</slot>
|
|
@@ -316,8 +316,8 @@
|
|
|
316
316
|
|
|
317
317
|
<script setup lang="ts" generic="T extends Record<string, any>">
|
|
318
318
|
import type { VDataTableProps, ExposedFunctions, PaginationObject } from '../types/v-data-table.ts';
|
|
319
|
-
import { readonly, ref, provide, computed, watch, nextTick } from 'vue';
|
|
320
|
-
|
|
319
|
+
import { readonly, ref, provide, computed, watch, nextTick, inject } from 'vue';
|
|
320
|
+
import { DATA_TABLE_CONFIG } from '@/config/datatableConfig'
|
|
321
321
|
import PaginationDatatable from '@/Pagination/Pagination.vue';
|
|
322
322
|
import Search from './SearchDatatable.vue';
|
|
323
323
|
import { useImagePreview } from '../composables/useImagePreview';
|
|
@@ -327,6 +327,7 @@ import { useExpandedItem } from '../composables/useExpandedItem';
|
|
|
327
327
|
import { useDataTableFetch } from '../composables/useDataTableFetch';
|
|
328
328
|
import { useCheckBox } from '../composables/useCheckBox.ts';
|
|
329
329
|
import VDataTableLoading from './VDataTableLoading.vue';
|
|
330
|
+
const globalConfig = inject(DATA_TABLE_CONFIG, {});
|
|
330
331
|
const {
|
|
331
332
|
isHovering,
|
|
332
333
|
previewSrc,
|
|
@@ -342,35 +343,16 @@ const {
|
|
|
342
343
|
// =======================================================
|
|
343
344
|
const props = withDefaults(defineProps<VDataTableProps>(), {
|
|
344
345
|
fetch_name: '',
|
|
345
|
-
type_loading: 'placeholder',
|
|
346
346
|
custom_loading: null,
|
|
347
347
|
deactivate_default_params: false,
|
|
348
|
-
|
|
349
|
-
search_param_name: 'search',
|
|
350
|
-
page_param_name: 'page',
|
|
351
|
-
page_size_param_name: 'page_size',
|
|
348
|
+
|
|
352
349
|
add_params: () => ({}),
|
|
353
|
-
data_key: 'results',
|
|
354
|
-
total_key: 'count',
|
|
355
350
|
list_filter: () => [],
|
|
356
|
-
|
|
357
|
-
class_content: '',
|
|
358
|
-
class_container: '',
|
|
359
|
-
class_pagination: '',
|
|
360
|
-
class_filters: '',
|
|
361
|
-
class_page_size: '',
|
|
362
|
-
min_loading_delay: 600,
|
|
363
|
-
retry_attempts: 3,
|
|
364
|
-
retry_delay: 2000,
|
|
351
|
+
|
|
365
352
|
use_checkbox: false,
|
|
366
|
-
|
|
367
|
-
first_text_page_size: 'Mostrar',
|
|
368
|
-
second_text_page_size: 'registros',
|
|
369
|
-
limit_per_page: 5,
|
|
370
|
-
page_starts_at: 0,
|
|
353
|
+
|
|
371
354
|
deactivate_selected_info: false,
|
|
372
355
|
immediate: true,
|
|
373
|
-
placeholder_search: "Buscar...",
|
|
374
356
|
deactivate_search_on_clear: false,
|
|
375
357
|
use_expandable_items: false,
|
|
376
358
|
close_expanded_item_on_expand_new: false,
|
|
@@ -381,7 +363,45 @@ const props = withDefaults(defineProps<VDataTableProps>(), {
|
|
|
381
363
|
deactivate_search_empty: false,
|
|
382
364
|
disable_request: false,
|
|
383
365
|
});
|
|
384
|
-
|
|
366
|
+
const options = computed(() => {
|
|
367
|
+
return {
|
|
368
|
+
// Primeiro, espelha todas as props originais.
|
|
369
|
+
...props,
|
|
370
|
+
|
|
371
|
+
// Agora SOBRESCREVEMOS as propriedades que precisam de lógica Global/Default
|
|
372
|
+
// (Prioridade para Prop, mas aceita Global)
|
|
373
|
+
|
|
374
|
+
// === TEXTOS ===
|
|
375
|
+
first_text_page_size: props.first_text_page_size ?? globalConfig.first_text_page_size ?? 'Mostrar',
|
|
376
|
+
second_text_page_size: props.second_text_page_size ?? globalConfig.second_text_page_size ?? 'registros',
|
|
377
|
+
placeholder_search: props.placeholder_search ?? globalConfig.placeholder_search ?? 'Buscar...',
|
|
378
|
+
|
|
379
|
+
// === CLASSES ===
|
|
380
|
+
class_table: props.class_table || globalConfig.class_table || '',
|
|
381
|
+
class_pagination: props.class_pagination || globalConfig.class_pagination || '',
|
|
382
|
+
class_container: props.class_container || globalConfig.class_container || '',
|
|
383
|
+
class_content: props.class_content || globalConfig.class_content || '',
|
|
384
|
+
class_filters: props.class_filters || globalConfig.class_filters || '',
|
|
385
|
+
class_page_size: props.class_page_size || globalConfig.class_page_size || '',
|
|
386
|
+
|
|
387
|
+
// === CONFIGURAÇÃO DE API ===
|
|
388
|
+
filter_param_name: props.filter_param_name ?? globalConfig.filter_param_name ?? 'filter',
|
|
389
|
+
search_param_name: props.search_param_name ?? globalConfig.search_param_name ?? 'search',
|
|
390
|
+
page_param_name: props.page_param_name ?? globalConfig.page_param_name ?? 'page',
|
|
391
|
+
page_size_param_name: props.page_size_param_name ?? globalConfig.page_size_param_name ?? 'page_size',
|
|
392
|
+
page_starts_at: props.page_starts_at ?? globalConfig.page_starts_at ?? 0,
|
|
393
|
+
item_key: props.item_key ?? globalConfig.item_key ?? 'id',
|
|
394
|
+
data_key: props.data_key ?? globalConfig.data_key ?? 'results',
|
|
395
|
+
total_key: props.total_key ?? globalConfig.total_key ?? 'count',
|
|
396
|
+
|
|
397
|
+
// === COMPORTAMENTO ===
|
|
398
|
+
limit_per_page: props.limit_per_page ?? globalConfig.limit_per_page ?? 5,
|
|
399
|
+
type_loading: props.type_loading ?? globalConfig.type_loading ?? 'placeholder',
|
|
400
|
+
min_loading_delay: props.min_loading_delay ?? globalConfig.min_loading_delay ?? 600,
|
|
401
|
+
retry_attempts: props.retry_attempts ?? globalConfig.retry_attempts ?? 3,
|
|
402
|
+
retry_delay: props.retry_delay ?? globalConfig.retry_delay ?? 2000,
|
|
403
|
+
};
|
|
404
|
+
});
|
|
385
405
|
const emit = defineEmits(['tradePage', 'beforeFetch', 'afterFetch', 'clickedClearSearch']);
|
|
386
406
|
|
|
387
407
|
// =======================================================
|
|
@@ -402,9 +422,9 @@ const isDraggingColumns = ref(false);
|
|
|
402
422
|
|
|
403
423
|
/*--------- definição de páginação ---------------*/
|
|
404
424
|
const pagination = ref<PaginationObject>({
|
|
405
|
-
current_page:
|
|
425
|
+
current_page: options.value.page_starts_at, // pagina atual
|
|
406
426
|
count: 0, // total de itens
|
|
407
|
-
limit_per_page:
|
|
427
|
+
limit_per_page: options.value.limit_per_page, // limite de itens por página
|
|
408
428
|
search: '', // termo de busca
|
|
409
429
|
filter: '', // filtro selecionado
|
|
410
430
|
})
|
|
@@ -416,23 +436,23 @@ const {
|
|
|
416
436
|
close_all_expanded_items,
|
|
417
437
|
is_item_expanded
|
|
418
438
|
} = useExpandedItem(
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
439
|
+
options.value.close_expanded_item_on_expand_new,
|
|
440
|
+
options.value.item_key,
|
|
441
|
+
options.value.deactivate_animation_expand,
|
|
442
|
+
options.value.scroll_to_expanded_item
|
|
423
443
|
);
|
|
424
444
|
|
|
425
445
|
const {
|
|
426
446
|
items, error, response, attempt, default_params,
|
|
427
447
|
fetchDataWithDelay, reSearch,
|
|
428
448
|
showLoadingState, first_fetch
|
|
429
|
-
} = useDataTableFetch<T>(
|
|
449
|
+
} = useDataTableFetch<T>(options.value, pagination, columns, orderings_state, emit, close_all_expanded_items);
|
|
430
450
|
|
|
431
451
|
|
|
432
452
|
const {
|
|
433
453
|
selectAllCheckbox, selected_items, isSelected,
|
|
434
454
|
atLeastOneSelected, toggleSelectAll, toggleItemSelection
|
|
435
|
-
} = useCheckBox(
|
|
455
|
+
} = useCheckBox(options.value, items);
|
|
436
456
|
|
|
437
457
|
// =======================================================
|
|
438
458
|
// 4. PROPRIEDADES COMPUTADAS
|
|
@@ -459,7 +479,7 @@ const renderedColumns = computed(() => {
|
|
|
459
479
|
|
|
460
480
|
const item_use = computed<number[]>(() => {
|
|
461
481
|
let use = [1]
|
|
462
|
-
if (
|
|
482
|
+
if (options.value.list_filter.length > 0) {
|
|
463
483
|
use.push(2)
|
|
464
484
|
}
|
|
465
485
|
return use;
|
|
@@ -477,8 +497,8 @@ const item_use = computed<number[]>(() => {
|
|
|
477
497
|
|
|
478
498
|
watch(response, (newResponse: any) => {
|
|
479
499
|
if (newResponse) {
|
|
480
|
-
items.value = newResponse[
|
|
481
|
-
totalItems.value = newResponse[
|
|
500
|
+
items.value = newResponse[options.value.data_key] || [];
|
|
501
|
+
totalItems.value = newResponse[options.value.total_key] || 0;
|
|
482
502
|
pagination.value.count = totalItems.value;
|
|
483
503
|
} else {
|
|
484
504
|
items.value = [];
|
|
@@ -596,8 +616,8 @@ function set_page(newPage: number): void {
|
|
|
596
616
|
|
|
597
617
|
function colspanExpandItems(): number {
|
|
598
618
|
let colspan = columns.value.length;
|
|
599
|
-
if (
|
|
600
|
-
if (
|
|
619
|
+
if (options.value.use_checkbox) colspan += 1;
|
|
620
|
+
if (options.value.use_expandable_items) colspan += 1;
|
|
601
621
|
return colspan;
|
|
602
622
|
}
|
|
603
623
|
function tradePageEmit(): void {
|
|
@@ -643,7 +663,7 @@ defineExpose<ExposedFunctions<T>>({
|
|
|
643
663
|
});
|
|
644
664
|
const on_mounted_called = ref<boolean>(false);
|
|
645
665
|
watch(
|
|
646
|
-
() =>
|
|
666
|
+
() => options.value.add_params,
|
|
647
667
|
() => {
|
|
648
668
|
if (!on_mounted_called.value) {
|
|
649
669
|
on_mounted_called.value = true;
|
|
@@ -655,7 +675,7 @@ watch(
|
|
|
655
675
|
reSearch();
|
|
656
676
|
}
|
|
657
677
|
},
|
|
658
|
-
{ deep: true, immediate:
|
|
678
|
+
{ deep: true, immediate: options.value.immediate }
|
|
659
679
|
)
|
|
660
680
|
|
|
661
681
|
</script>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { InjectionKey } from 'vue';
|
|
2
|
+
import type { VDataTableProps } from '@/DatatableVue/types/v-data-table';
|
|
3
|
+
|
|
4
|
+
//o Partial para dizer que no global não precisamos passar TUDO
|
|
5
|
+
export type DataTableGlobalConfig = Partial<VDataTableProps>;
|
|
6
|
+
|
|
7
|
+
// A chave para o provide/inject
|
|
8
|
+
export const DATA_TABLE_CONFIG: InjectionKey<DataTableGlobalConfig> = Symbol('DataTableConfig');
|
package/src/core/plugin.ts
CHANGED
|
@@ -26,10 +26,16 @@ import '@tabler/core/dist/css/tabler-themes.min.css'
|
|
|
26
26
|
import * as Tabler from '@tabler/core/dist/js/tabler.min.js';
|
|
27
27
|
import vRequired from "v-required"
|
|
28
28
|
import '../assets/v-required-style.css'
|
|
29
|
-
import Toast from "vue-toastification";
|
|
29
|
+
import Toast, { type PluginOptions as ToastPluginOptions } from "vue-toastification";
|
|
30
30
|
import "vue-toastification/dist/index.css";
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
import { DATA_TABLE_CONFIG, type DataTableGlobalConfig } from '@/config/datatableConfig';
|
|
33
|
+
export interface SistecOptions {
|
|
34
|
+
dataTable?: DataTableGlobalConfig; // Configurações opcionais da tabela
|
|
35
|
+
toast?: ToastPluginOptions; // Configurações opcionais do Toast
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const defaultToastOptions: ToastPluginOptions = {
|
|
33
39
|
transition: "Vue-Toastification__bounce",
|
|
34
40
|
maxToasts: 20,
|
|
35
41
|
newestOnTop: true,
|
|
@@ -38,14 +44,22 @@ const options_toast = {
|
|
|
38
44
|
|
|
39
45
|
const SistecPlugin = {
|
|
40
46
|
// até o momento não usamos opções nem o app, mas deixei aqui caso precise no futuro
|
|
41
|
-
install: (app: App,
|
|
47
|
+
install: (app: App, options: SistecOptions = {}) => {
|
|
42
48
|
// Disponibiliza o Tabler globalmente
|
|
43
49
|
(window as any).bootstrap = Tabler;
|
|
44
50
|
|
|
51
|
+
|
|
52
|
+
|
|
45
53
|
// futuros upgrades podem ser feitos aqui
|
|
46
54
|
// Ex: app.component('MeuComponente', MeuComponente);
|
|
47
55
|
app.directive('required', vRequired);
|
|
48
|
-
|
|
56
|
+
// Aqui um merge: Opções do usuário > Padrão do Sistec
|
|
57
|
+
const finalToastOptions = { ...defaultToastOptions, ...options.toast };
|
|
58
|
+
app.use(Toast, finalToastOptions);
|
|
59
|
+
// CONFIGURAÇÃO DO DATATABLE
|
|
60
|
+
// Se o usuário passou configurações goblais de tabela, fazemos o provide AQUI.
|
|
61
|
+
const tableConfig = options.dataTable || {};
|
|
62
|
+
app.provide(DATA_TABLE_CONFIG, tableConfig);
|
|
49
63
|
}
|
|
50
64
|
};
|
|
51
65
|
export { SistecPlugin };
|