Files
2025_Vuejs_Mpi_Panel/src/components/global/DataTable.vue

290 lines
8.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="list-wrapper">
<table class="table-border table-colored table-list">
<thead>
<tr>
<th class="table-head-row-number" v-if="rowNumber">
<div class="table-head-content">Sıra No</div>
</th>
<template v-for="(headCell, h) in tableHeader">
<th :style="[headCell.style || '']">
<div
:class="[
'table-head-content',
headCell.sort !== undefined && headCell.sort ? 'clickable' : ''
]"
@click="SortColumn(headCell)">
<span>{{ headCell.title }}</span>
<template
v-if="
headCell.sort !== undefined && headCell.sort && tableData.length > 1
">
<i
class="ico-c ico-sort"
v-if="
localSort?.sortOrder === '' ||
headCell.name !== localSort?.sortColumn
">
<svg>
<use href="@/assets/images/icons.svg#arrowsortable" />
</svg>
</i>
<i
:class="[
'ico-c',
'ico-sort',
localSort?.sortOrder === 'asc' ? 'order-asc' : ''
]"
v-if="
headCell.name === localSort?.sortColumn &&
localSort?.sortOrder !== ''
">
<svg>
<use href="@/assets/images/icons.svg#arrowline" />
</svg>
</i>
</template>
</div>
</th>
</template>
<th
:style="[rowActionStyle || '']"
v-if="rowActions !== undefined && rowActions.length > 0">
<div class="table-head-content">İşlemler</div>
</th>
</tr>
</thead>
<tbody>
<tr v-if="tableData.length === 0 && !isPreview">
<td :colspan="ColSpan">Veri bulunamadı</td>
</tr>
<tr
v-else
v-for="(dataRow, i) in tableData"
@click="LocalRowAction(dataRow)"
:class="[rowAction !== undefined && rowAction !== '' ? 'clickable' : '']">
<td v-if="rowNumber">
{{
showPagination && localPagination.pageNumber !== undefined
? (Number(localPagination.pageNumber) - 1) *
Number(localPagination.pageSize) +
i +
1
: i + 1
}}
</td>
<slot :name="'dataRow' + i" :rowData="dataRow" :rowIndex="i">
<template v-for="(dataCell, j) in tableHeader">
<td v-if="dataCell.computeHtml === undefined">
<slot
:name="'dataCell' + j"
:cellData="CellData(dataRow, dataCell.name)"
:cellIndex="j">
<div class="table-inner-content">
{{
dataCell.compute !== undefined
? dataCell.compute(dataRow)
: dataRow[dataCell.name]
}}
</div>
</slot>
</td>
<td v-else v-html="dataCell.computeHtml(dataRow)"></td>
</template>
</slot>
<td
v-if="rowActions !== undefined && rowActions.length > 0"
:class="[actionFixed ? 'action-fixed' : '']">
<template v-for="(action, ai) in rowActions">
<button
:class="[
'button-c button-icon button-export',
action.class !== undefined ? 'back-grad back-grad-' + action.class : ''
]"
@click="LocalRowDataAction($event, action.action, dataRow, i)">
<i class="ico-c" v-if="action.icon !== undefined">
<svg>
<use :href="icourl + '#' + action.icon"></use>
</svg>
</i>
<span class="panel-date">{{ action.text }}</span>
</button>
</template>
</td>
</tr>
<template
v-if="
localTotalValues !== undefined &&
Object.keys(localTotalValues).length > 0 &&
tableData.length > 0
">
<tr>
<td :colspan="totalValuesSpanLength" class="table-cell-align-right">
<strong>TOPLAM:</strong>
</td>
<template v-for="(val, i) in tableHeader">
<td v-if="localTotalValues[val.name] !== undefined">
{{
val.price
? globalStore.toTrLocale(localTotalValues[val.name])
: localTotalValues[val.name]
}}
</td>
</template>
</tr>
</template>
</tbody>
</table>
</div>
<data-table-pagination
v-if="pagination !== undefined && showPagination && !isPreview"
v-model:pagination="localPagination" />
</template>
<script setup lang="ts">
import { ref, reactive, computed, watch } from 'vue'
import type { Ref } from 'vue'
import { useGlobalStore } from '@/stores/globalStore'
import icourl from '@/assets/images/icons.svg'
const globalStore = useGlobalStore()
interface ITableHead {
[key: string]: any
title: string
name: string
compute?: Function
sort?: boolean
computeHtml?: Function
}
interface IPagination {
[key: string]: any
pageNumber?: number
pageSize: number
totalRecords: number
}
interface ISort {
[key: string]: any
sortColumn?: string
sortOrder?: string
}
export interface Props {
tableHeader: ITableHead[]
tableData: Record<string, any>
rowAction?: Function | string
pagination?: IPagination
sortData?: ISort
rowNumber?: boolean
totalValues?: Record<string, any>
isPreview?: boolean
rowActions?: Record<string, any>[]
actionFixed?: boolean
rowActionStyle?: string
}
const props = withDefaults(defineProps<Props>(), {
tableData: () => [],
rowNumber: false,
isPreview: false,
actionFixed: false
})
const emit = defineEmits(['update:sortData', 'update:pagination'])
const localSort: Ref<ISort> = ref(props.sortData as ISort)
const localPagination: Ref<IPagination> = ref(props.pagination as IPagination)
const localTotalValues = reactive<Record<string, any>>(
props.totalValues as Record<string, any>
)
const totalValuesSpanLength = ref<number>(0)
if (localTotalValues !== undefined) {
let totalValuesLength = Object.keys(localTotalValues).length
let headerLength: number =
props.rowNumber !== undefined
? props.tableHeader.length + 1
: props.tableHeader.length
totalValuesSpanLength.value = headerLength - totalValuesLength
}
const showPagination = computed<boolean>(() => {
if (props.pagination !== undefined) {
if (Math.ceil(localPagination.value.totalRecords / globalStore.perPage) > 1)
return true
else return false
} else {
return false
}
})
const ColSpan = computed<number>(() => {
var span = props.tableHeader.length
if (props.rowNumber) span++
if (props.rowActions) span++
return span
})
const LocalRowAction = (d: Record<string, any>) => {
if (props.rowAction !== undefined) {
;(props.rowAction! as Function)(d)
}
}
const LocalRowDataAction = (
e: Event,
action: Function | undefined,
dataRow: Record<string, any>,
i: number | string
) => {
if (action !== undefined) {
e.stopImmediatePropagation()
action(dataRow, i)
}
}
const SortColumn = (d: Record<string, any>) => {
if (d.sort && props.tableData.length > 1) {
let order = ''
if (localSort.value.sortColumn === d.name) {
if (localSort.value.sortOrder === '') order = 'desc'
if (localSort.value.sortOrder === 'desc') order = 'asc'
if (localSort.value.sortOrder === 'asc') {
order = ''
delete localSort.value.sortColumn
}
localSort.value.sortOrder = order
} else {
localSort.value.sortColumn = d.name
localSort.value.sortOrder = 'desc'
}
emit('update:sortData', localSort.value)
}
}
const CellData = (d: Record<string, any>, key: string): any => {
if (d[key] === null) return d
else return d[key]
}
watch(
() => localPagination,
() => {
emit('update:pagination', localPagination.value)
},
{ deep: true }
)
</script>
<style scoped>
.action-fixed {
position: absolute;
z-index: 9;
top: 0;
right: 0;
}
.table-inner-content {
max-height: 400px;
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 20;
line-clamp: 20;
-webkit-box-orient: vertical;
display: -webkit-box;
}
</style>