first commit
This commit is contained in:
211
resources/js/views/demos/forms/tables/data-table/AgGridTable.vue
Normal file
211
resources/js/views/demos/forms/tables/data-table/AgGridTable.vue
Normal file
@@ -0,0 +1,211 @@
|
||||
<script setup>
|
||||
import { ref, watch, onMounted, onUnmounted } from 'vue'
|
||||
import { AgGridVue } from 'ag-grid-vue3'
|
||||
import data from '@/views/demos/forms/tables/data-table/datatable'
|
||||
import { ModuleRegistry, AllCommunityModule } from 'ag-grid-community'
|
||||
import { ExcelExportModule } from 'ag-grid-enterprise'
|
||||
import DataTableHeader from './components/DataTableHeader.vue'
|
||||
import UserDetailsDialog from './components/UserDetailsDialog.vue'
|
||||
import ConfirmDeleteDialog from './components/ConfirmDeleteDialog.vue'
|
||||
import { useDataTableGrid } from './composables/useDataTableGrid'
|
||||
import { useDataTableActions } from './composables/useDataTableActions'
|
||||
import { useResponsive } from './composables/useResponsive'
|
||||
import jsPDF from 'jspdf'
|
||||
import autoTable from 'jspdf-autotable'
|
||||
|
||||
ModuleRegistry.registerModules([AllCommunityModule, ExcelExportModule])
|
||||
|
||||
const { isMobile, isTablet, windowWidth } = useResponsive()
|
||||
|
||||
const {
|
||||
gridApi,
|
||||
columnDefs,
|
||||
rowData,
|
||||
defaultColDef,
|
||||
gridOptions,
|
||||
onGridReady: gridReady,
|
||||
onCellValueChanged,
|
||||
updateColumnVisibility,
|
||||
updatePagination
|
||||
} = useDataTableGrid(data, isMobile, isTablet)
|
||||
|
||||
const {
|
||||
setupGlobalHandlers,
|
||||
cleanupGlobalHandlers,
|
||||
exportToCSV,
|
||||
exportToExcel,
|
||||
saveUser,
|
||||
confirmDelete,
|
||||
cancelDelete,
|
||||
showDetailsDialog,
|
||||
selectedRowData,
|
||||
deleteRowData,
|
||||
showDeleteDialog,
|
||||
deleteRow
|
||||
} = useDataTableActions(gridApi, rowData)
|
||||
|
||||
const quickFilter = ref('')
|
||||
|
||||
watch(quickFilter, (newValue) => {
|
||||
if (gridApi.value) {
|
||||
gridApi.value.setGridOption('quickFilterText', newValue || '')
|
||||
}
|
||||
}, { immediate: false })
|
||||
|
||||
const onGridReady = params => {
|
||||
gridReady(params)
|
||||
setupGlobalHandlers()
|
||||
}
|
||||
|
||||
const handleSaveUser = updatedData => saveUser(updatedData)
|
||||
|
||||
const handleQuickFilterUpdate = (value) => {
|
||||
quickFilter.value = value || ''
|
||||
|
||||
if (gridApi.value) {
|
||||
gridApi.value.setGridOption('quickFilterText', value || '')
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
setupGlobalHandlers()
|
||||
window.addEventListener('resize', handleResize)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
cleanupGlobalHandlers()
|
||||
window.removeEventListener('resize', handleResize)
|
||||
})
|
||||
|
||||
const handleResize = () => {
|
||||
windowWidth.value = window.innerWidth
|
||||
if (gridApi.value) {
|
||||
updateColumnVisibility()
|
||||
updatePagination()
|
||||
setTimeout(() => {
|
||||
if (gridApi.value && gridApi.value.sizeColumnsToFit) {
|
||||
gridApi.value.sizeColumnsToFit()
|
||||
}
|
||||
}, 100)
|
||||
}
|
||||
}
|
||||
|
||||
const exportToPDF = () => {
|
||||
if (!gridApi.value) {
|
||||
console.error('Grid API not available')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const doc = new jsPDF()
|
||||
const rowDataForPDF = []
|
||||
const headers = []
|
||||
|
||||
columnDefs.value.forEach(col => {
|
||||
if (col.headerName && col.field && col.field !== 'action') {
|
||||
headers.push(col.headerName)
|
||||
}
|
||||
})
|
||||
|
||||
gridApi.value.forEachNodeAfterFilterAndSort(node => {
|
||||
const row = []
|
||||
columnDefs.value.forEach(col => {
|
||||
if (col.field && col.field !== 'action') {
|
||||
let value = node.data[col.field] || ''
|
||||
|
||||
if (col.field === 'salary' && value) {
|
||||
value = `$${Math.floor(Number(value)).toLocaleString()}`
|
||||
} else if (col.field === 'startDate' && value) {
|
||||
const date = new Date(value)
|
||||
if (!isNaN(date.getTime())) {
|
||||
const day = date.getDate().toString().padStart(2, '0')
|
||||
const month = (date.getMonth() + 1).toString().padStart(2, '0')
|
||||
const year = date.getFullYear()
|
||||
value = `${day}/${month}/${year}`
|
||||
}
|
||||
} else if (col.field === 'status') {
|
||||
const statusMap = {
|
||||
0: 'Applied',
|
||||
1: 'Current',
|
||||
2: 'Professional',
|
||||
3: 'Rejected',
|
||||
4: 'Resigned'
|
||||
}
|
||||
value = statusMap[value] || 'Applied'
|
||||
}
|
||||
|
||||
row.push(value)
|
||||
}
|
||||
})
|
||||
rowDataForPDF.push(row)
|
||||
})
|
||||
|
||||
autoTable(doc, {
|
||||
head: [headers],
|
||||
body: rowDataForPDF,
|
||||
styles: {
|
||||
fontSize: 8,
|
||||
cellPadding: 2
|
||||
},
|
||||
headStyles: {
|
||||
fillColor: [41, 128, 185],
|
||||
textColor: 255,
|
||||
fontStyle: 'bold'
|
||||
},
|
||||
alternateRowStyles: {
|
||||
fillColor: [245, 245, 245]
|
||||
},
|
||||
margin: { top: 20 }
|
||||
})
|
||||
|
||||
doc.save(`data-table-${new Date().toISOString().split('T')[0]}.pdf`)
|
||||
console.log('PDF exported successfully')
|
||||
} catch (error) {
|
||||
console.error('Error exporting PDF:', error)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-card class="elevation-2">
|
||||
<DataTableHeader
|
||||
:is-mobile="isMobile"
|
||||
:is-tablet="isTablet"
|
||||
:quick-filter="quickFilter"
|
||||
@update:quick-filter="handleQuickFilterUpdate"
|
||||
@export-csv="exportToCSV"
|
||||
@export-excel="exportToExcel"
|
||||
@export-pdf="exportToPDF"
|
||||
/>
|
||||
|
||||
<v-divider />
|
||||
|
||||
<v-card-text class="pa-0">
|
||||
<AgGridVue
|
||||
class="vuetify-grid ag-theme-alpine-dark"
|
||||
:style="`height:${isMobile ? '400px' : '600px'}; width:100%`"
|
||||
:columnDefs="columnDefs"
|
||||
:rowData="rowData"
|
||||
:defaultColDef="defaultColDef"
|
||||
:gridOptions="gridOptions"
|
||||
@grid-ready="onGridReady"
|
||||
|
||||
/>
|
||||
</v-card-text>
|
||||
|
||||
<UserDetailsDialog
|
||||
v-model="showDetailsDialog"
|
||||
:selected-row-data="selectedRowData"
|
||||
:is-mobile="isMobile"
|
||||
@save-user="handleSaveUser"
|
||||
/>
|
||||
|
||||
<ConfirmDeleteDialog
|
||||
v-model="showDeleteDialog"
|
||||
:selected-row-data="deleteRowData"
|
||||
:is-mobile="isMobile"
|
||||
@confirm="confirmDelete"
|
||||
@cancel="cancelDelete"
|
||||
/>
|
||||
</v-card>
|
||||
</template>
|
||||
Reference in New Issue
Block a user