✨ feature: Data table component added
This commit is contained in:
parent
a4bbfeb9ad
commit
3d6b27c13c
414
src/components/table/VDataTable.vue
Normal file
414
src/components/table/VDataTable.vue
Normal file
|
@ -0,0 +1,414 @@
|
|||
<script setup lang="ts">
|
||||
import DataTable from 'primevue/datatable';
|
||||
import type { DataTableProps, DataTableSlots } from 'primevue/datatable';
|
||||
import { useId, ref, watch, computed } from 'vue';
|
||||
|
||||
export interface IVDataTable extends Partial<Omit<DataTableProps, 'pt' | 'dt' | 'ptOptions' | 'unstyled'>>{
|
||||
id: string
|
||||
title: string
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<IVDataTable>(), {
|
||||
id: () => useId(),
|
||||
title: '',
|
||||
selection: undefined,
|
||||
paginator: false,
|
||||
rowsPerPageOptions: undefined,
|
||||
rows: 0,
|
||||
value: undefined,
|
||||
dataKey: undefined,
|
||||
showGridlines: false,
|
||||
stripedRows: false,
|
||||
first: 0,
|
||||
totalRecords: 0,
|
||||
pageLinkSize: 5,
|
||||
paginatorPosition: 'bottom',
|
||||
paginatorTemplate: undefined,
|
||||
alwaysShowPaginator:true,
|
||||
currentPageReportTemplate: '({currentPage} de {totalPages})',
|
||||
lazy: false,
|
||||
loading: false,
|
||||
sortField: undefined,
|
||||
sortOrder: undefined,
|
||||
nullSortOrder: 1,
|
||||
defaultSortOrder: 1,
|
||||
sortMode: 'single',
|
||||
removableSort: false,
|
||||
filters: undefined,
|
||||
filterDisplay: undefined,
|
||||
globalFilterFields: undefined,
|
||||
filterLocale: undefined,
|
||||
selectionMode: undefined,
|
||||
compareSelectionBy: 'deepEquals',
|
||||
metaKeySelection: false,
|
||||
contextMenu: false,
|
||||
contextMenuSelection: undefined,
|
||||
selectAll: undefined,
|
||||
rowHover: false,
|
||||
csvSeparator: ',',
|
||||
exportFilename: 'download',
|
||||
exportFunction: undefined,
|
||||
resizableColumns: false,
|
||||
columnResizeMode: 'fit',
|
||||
reorderableColumns: false,
|
||||
expandedRows: undefined,
|
||||
expandedRowIcon: undefined,
|
||||
collapsedRowIcon: undefined,
|
||||
rowGroupMode: undefined,
|
||||
groupRowsBy: undefined,
|
||||
expandableRowGroups: false,
|
||||
expandedRowGroups: undefined,
|
||||
stateStorage: 'session',
|
||||
stateKey: undefined,
|
||||
editMode: undefined,
|
||||
editingRows: undefined,
|
||||
rowClass: undefined,
|
||||
rowStyle: undefined,
|
||||
scrollable: false,
|
||||
scrollHeight: undefined,
|
||||
virtualScrollerOptions: undefined,
|
||||
frozenValue: undefined,
|
||||
breakpoint: '960px',
|
||||
showHeaders: true,
|
||||
highlightOnSelect: false,
|
||||
size: undefined,
|
||||
tableClass: undefined,
|
||||
tableProps: undefined,
|
||||
tableStyle: undefined,
|
||||
filterButtonProps: undefined,
|
||||
editButtonProps: undefined,
|
||||
multiSortMeta: undefined,
|
||||
})
|
||||
|
||||
const slots = defineSlots<DataTableSlots>();
|
||||
|
||||
const dataTableSlotKeys = [
|
||||
'header',
|
||||
'footer',
|
||||
'empty',
|
||||
'groupheader',
|
||||
'groupfooter',
|
||||
'loading',
|
||||
'expansion',
|
||||
'loadingicon',
|
||||
'reorderindicatorupicon', // deprecated
|
||||
'rowreorderindicatorupicon',
|
||||
'reorderindicatordownicon', // deprecated
|
||||
'rowreorderindicatordownicon',
|
||||
'rowgrouptogglericon',
|
||||
'paginatorcontainer',
|
||||
'paginatorstart',
|
||||
'paginatorend',
|
||||
'paginatorfirstpagelinkicon',
|
||||
'paginatorprevpagelinkicon',
|
||||
'paginatornextpagelinkicon',
|
||||
'paginatorlastpagelinkicon',
|
||||
'paginatorrowsperpagedropdownicon',
|
||||
'paginatorjumptopagedropdownicon'
|
||||
] as const;
|
||||
|
||||
const availableSlots = computed(() =>
|
||||
dataTableSlotKeys.filter((key) => !!slots[key]).map((key) => [key, slots[key]])
|
||||
);
|
||||
|
||||
const dataTableRef = ref();
|
||||
|
||||
defineExpose({
|
||||
exportCSV: () => dataTableRef.value.exportCSV()
|
||||
});
|
||||
|
||||
const emit = defineEmits([
|
||||
'update:selection',
|
||||
'update:rows',
|
||||
'update:sortField',
|
||||
'update:sortOrder',
|
||||
'update:multiSortMeta',
|
||||
'update:contextMenuSelection',
|
||||
'update:expandedRows',
|
||||
'update:expandedRowGroups',
|
||||
'update:filters',
|
||||
'update:editingRows',
|
||||
'update:first',
|
||||
'page',
|
||||
'sort',
|
||||
'row-select',
|
||||
'row-unselect',
|
||||
'filter',
|
||||
'value-change',
|
||||
'row-click',
|
||||
'row-dbclick',
|
||||
'row-contextmenu',
|
||||
'row-select-all',
|
||||
'row-unselect-all',
|
||||
'select-all-change',
|
||||
'column-resize-end',
|
||||
'column-reorder',
|
||||
'row-reorder',
|
||||
'row-expand',
|
||||
'row-collapse',
|
||||
'rowgroup-expand',
|
||||
'rowgroup-collapse',
|
||||
'cell-edit-init',
|
||||
'cell-edit-complete',
|
||||
'cell-edit-cancel',
|
||||
'row-edit-init',
|
||||
'row-edit-save',
|
||||
'row-edit-cancel',
|
||||
'state-restore',
|
||||
'state-save',
|
||||
]);
|
||||
|
||||
const localSelection = ref(props.selection);
|
||||
watch(() => props.selection, (newVal) => {
|
||||
if(localSelection.value !== newVal) {
|
||||
localSelection.value = newVal;
|
||||
}
|
||||
});
|
||||
watch(localSelection, (newVal) => {
|
||||
if(props.selection !== newVal){
|
||||
emit('update:selection', newVal);
|
||||
}
|
||||
});
|
||||
|
||||
const localRows = ref(props.rows);
|
||||
watch(() => props.rows, (newVal) => {
|
||||
if(localRows.value !== newVal){
|
||||
localRows.value = newVal;
|
||||
}
|
||||
})
|
||||
watch(localRows, (newVal) => {
|
||||
if(props.rows !== newVal){
|
||||
emit('update:rows', newVal);
|
||||
}
|
||||
});
|
||||
|
||||
const localFirst = ref(props.first);
|
||||
watch(() => props.first, (newVal) => {
|
||||
if(localFirst.value !== newVal){
|
||||
localFirst.value = newVal;
|
||||
}
|
||||
})
|
||||
watch(localFirst, (newVal) => {
|
||||
if(props.first !== newVal){
|
||||
emit('update:first', newVal);
|
||||
}
|
||||
});
|
||||
|
||||
const localSortField = ref(props.sortField);
|
||||
watch(() => props.sortField, (newVal) => {
|
||||
if(localSortField.value !== newVal){
|
||||
localSortField.value = newVal;
|
||||
}
|
||||
})
|
||||
watch(localSortField, (newVal) => {
|
||||
if(props.sortField !== newVal){
|
||||
emit('update:sortField', newVal);
|
||||
}
|
||||
});
|
||||
|
||||
const localSortOrder = ref(props.sortOrder);
|
||||
watch(() => props.sortOrder, (newVal) => {
|
||||
if(localSortOrder.value !== newVal){
|
||||
localSortOrder.value = newVal;
|
||||
}
|
||||
})
|
||||
watch(localSortOrder, (newVal) => {
|
||||
if(props.sortOrder !== newVal){
|
||||
emit('update:sortOrder', newVal);
|
||||
}
|
||||
});
|
||||
|
||||
const localMultiSortMeta = ref(props.multiSortMeta);
|
||||
watch(() => props.multiSortMeta, (newVal) => {
|
||||
if(localMultiSortMeta.value !== newVal){
|
||||
localMultiSortMeta.value = newVal;
|
||||
}
|
||||
})
|
||||
watch(localMultiSortMeta, (newVal) => {
|
||||
if(props.multiSortMeta !== newVal){
|
||||
emit('update:multiSortMeta', newVal);
|
||||
}
|
||||
});
|
||||
|
||||
const localContextMenuSelection = ref(props.contextMenuSelection);
|
||||
watch(() => props.contextMenuSelection, (newVal) => {
|
||||
if(localContextMenuSelection.value !== newVal){
|
||||
localContextMenuSelection.value = newVal;
|
||||
}
|
||||
})
|
||||
watch(localContextMenuSelection, (newVal) => {
|
||||
if(props.contextMenuSelection){
|
||||
emit('update:contextMenuSelection', newVal);
|
||||
}
|
||||
});
|
||||
|
||||
const localExpandedRows = ref(props.expandedRows);
|
||||
watch(() => props.expandedRows, (newVal) => {
|
||||
if(localExpandedRows.value !== newVal){
|
||||
localExpandedRows.value = newVal;
|
||||
}
|
||||
})
|
||||
watch(localExpandedRows, (newVal) => {
|
||||
if(props.expandedRows !== newVal){
|
||||
emit('update:expandedRows', newVal);
|
||||
}
|
||||
});
|
||||
|
||||
const localExpandedRowGroups = ref(props.expandedRowGroups);
|
||||
watch(() => props.expandedRowGroups, (newVal) => {
|
||||
if(localExpandedRowGroups.value !== newVal){
|
||||
localExpandedRowGroups.value = newVal;
|
||||
}
|
||||
})
|
||||
watch(localExpandedRowGroups, (newVal) => {
|
||||
if(props.expandedRowGroups !== newVal){
|
||||
emit('update:expandedRowGroups', newVal);
|
||||
}
|
||||
});
|
||||
|
||||
const localFilters = ref(props.filters);
|
||||
watch(() => props.filters, (newVal) => {
|
||||
if(localFilters.value !== newVal){
|
||||
localFilters.value = newVal;
|
||||
}
|
||||
})
|
||||
watch(localFilters, (newVal) => {
|
||||
if(props.filters !== newVal){
|
||||
emit('update:filters', newVal);
|
||||
}
|
||||
});
|
||||
|
||||
const localEditingRows = ref(props.editingRows);
|
||||
watch(() => props.editingRows, (newVal) => {
|
||||
if(localEditingRows.value = newVal){
|
||||
localEditingRows.value = newVal;
|
||||
}
|
||||
})
|
||||
watch(localEditingRows, (newVal) => {
|
||||
if(props.editingRows !== newVal){
|
||||
emit('update:editingRows', newVal);
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DataTable
|
||||
:id="`datatable-${props.id}`"
|
||||
role="table"
|
||||
ref="dataTableRef"
|
||||
:value="props.value"
|
||||
:paginator="props.paginator"
|
||||
:rowsPerPageOptions="props.rowsPerPageOptions"
|
||||
:data-key="props.dataKey"
|
||||
:show-gridlines="props.showGridlines"
|
||||
:striped-rows="props.stripedRows"
|
||||
:total-records="props.totalRecords"
|
||||
:page-link-size="props.pageLinkSize"
|
||||
:paginator-position="props.paginatorPosition"
|
||||
:paginator-template="props.paginatorTemplate"
|
||||
:always-show-paginator="props.alwaysShowPaginator"
|
||||
:current-page-report-template="props.currentPageReportTemplate"
|
||||
:lazy="props.lazy"
|
||||
:loading="props.loading"
|
||||
:nullSortOrder="props.nullSortOrder"
|
||||
:defaultSortOrder="props.defaultSortOrder"
|
||||
:sortMode="props.sortMode"
|
||||
:removableSort="props.removableSort"
|
||||
:filterDisplay="props.filterDisplay"
|
||||
:globalFilterFields="props.globalFilterFields"
|
||||
:filterLocale="props.filterLocale"
|
||||
:selectionMode="props.selectionMode"
|
||||
:compareSelectionBy="props.compareSelectionBy"
|
||||
:metaKeySelection="props.metaKeySelection"
|
||||
:contextMenu="props.contextMenu"
|
||||
:selectAll="props.selectAll"
|
||||
:rowHover="props.rowHover"
|
||||
:csvSeparator="props.csvSeparator"
|
||||
:exportFilename="props.exportFilename"
|
||||
:exportFunction="props.exportFunction"
|
||||
:resizableColumns="props.resizableColumns"
|
||||
:columnResizeMode="props.columnResizeMode"
|
||||
:reorderableColumns="props.reorderableColumns"
|
||||
:expandedRowIcon="props.expandedRowIcon"
|
||||
:collapsedRowIcon="props.collapsedRowIcon"
|
||||
:rowGroupMode="props.rowGroupMode"
|
||||
:groupRowsBy="props.groupRowsBy"
|
||||
:expandableRowGroups="props.expandableRowGroups"
|
||||
:stateStorage="props.stateStorage"
|
||||
:stateKey="props.stateKey"
|
||||
:editMode="props.editMode"
|
||||
:rowClass="props.rowClass"
|
||||
:rowStyle="props.rowStyle"
|
||||
:scrollable="props.scrollable"
|
||||
:scrollHeight="props.scrollHeight"
|
||||
:virtualScrollerOptions="props.virtualScrollerOptions"
|
||||
:frozenValue="props.frozenValue"
|
||||
:breakpoint="props.breakpoint"
|
||||
:showHeaders="props.showHeaders"
|
||||
:highlightOnSelect="props.highlightOnSelect"
|
||||
:size="props.size"
|
||||
:tableClass="props.tableClass"
|
||||
:tableProps="props.tableProps"
|
||||
:tableStyle="props.tableStyle"
|
||||
:filterButtonProps="props.filterButtonProps"
|
||||
:editButtonProps="props.editButtonProps"
|
||||
style="width: 100%; height: fit-content;"
|
||||
v-model:selection="localSelection"
|
||||
v-model:rows="localRows"
|
||||
v-model:first="localFirst"
|
||||
v-model:sortField="localSortField"
|
||||
v-model:sortOrder="localSortOrder"
|
||||
v-model:filters="localFilters"
|
||||
v-model:contextMenuSelection="localContextMenuSelection"
|
||||
v-model:expandedRows="localExpandedRows"
|
||||
v-model:expandedRowGroups="localExpandedRowGroups"
|
||||
v-model:editingRows="localEditingRows"
|
||||
v-model:multi-sort-meta="localMultiSortMeta"
|
||||
@update:selection="emit('update:selection', $event)"
|
||||
@update:context-menu-selection="emit('update:contextMenuSelection', $event)"
|
||||
@update:editing-rows="emit('update:editingRows', $event)"
|
||||
@update:expanded-row-groups="emit('update:expandedRowGroups', $event)"
|
||||
@update:filters="emit('update:filters', $event)"
|
||||
@update:first="emit('update:first', $event)"
|
||||
@update:multi-sort-meta="emit('update:multiSortMeta', $event)"
|
||||
@update:rows="emit('update:rows', $event)"
|
||||
@update:sort-field="emit('update:sortField', $event)"
|
||||
@update:sort-order="emit('update:sortOrder', $event)"
|
||||
@page="emit('page', $event)"
|
||||
@sort="emit('sort', $event)"
|
||||
@rowSelect="emit('row-select', $event)"
|
||||
@rowUnselect="emit('row-unselect', $event)"
|
||||
@filter="emit('filter', $event)"
|
||||
@valueChange="emit('value-change', $event)"
|
||||
@rowClick="emit('row-click', $event)"
|
||||
@rowCollapse="emit('row-collapse', $event)"
|
||||
@rowContextmenu="emit('row-contextmenu', $event)"
|
||||
@rowDblclick="emit('row-dbclick', $event)"
|
||||
@rowEditCancel="emit('row-edit-cancel', $event)"
|
||||
@rowEditInit="emit('row-edit-init', $event)"
|
||||
@rowEditSave="emit('row-edit-save', $event)"
|
||||
@rowExpand="emit('row-expand', $event)"
|
||||
@rowReorder="emit('row-reorder', $event)"
|
||||
@rowSelectAll="emit('row-select-all', $event)"
|
||||
@rowUnselectAll="emit('row-unselect-all', $event)"
|
||||
@rowgroupCollapse="emit('rowgroup-collapse', $event)"
|
||||
@rowgroupExpand="emit('rowgroup-expand', $event)"
|
||||
@columnReorder="emit('column-reorder', $event)"
|
||||
@columnResizeEnd="emit('column-resize-end', $event)"
|
||||
@cellEditCancel="emit('cell-edit-cancel', $event)"
|
||||
@cellEditComplete="emit('cell-edit-complete', $event)"
|
||||
@cellEditInit="emit('cell-edit-init', $event)"
|
||||
@stateRestore="emit('state-restore', $event)"
|
||||
@stateSave="emit('state-save', $event)"
|
||||
@selectAllChange="emit('select-all-change', $event)"
|
||||
>
|
||||
<template
|
||||
v-for="([name]) in availableSlots"
|
||||
:key="name"
|
||||
v-slot:[name]="slotProps"
|
||||
>
|
||||
<slot :name="name" v-bind="slotProps" />
|
||||
</template>
|
||||
</DataTable>
|
||||
</template>
|
Loading…
Reference in New Issue
Block a user