add19f33a2
Add size prop configuration to action components in data table to allow consistent sizing. Update dropdown action component to accept size prop with default value.
76 lines
2.7 KiB
Vue
76 lines
2.7 KiB
Vue
<script setup lang="ts">
|
|
import type { DataTableLoader } from './type'
|
|
import type { Col, RecStrFuncComponent, RecStrFuncUnknown, Th } from '~/components/pub/custom-ui/data/types'
|
|
import { Info } from 'lucide-vue-next'
|
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '~/components/pub/ui/table'
|
|
|
|
defineProps<{
|
|
rows: unknown[]
|
|
cols: Col[]
|
|
header: Th[][]
|
|
keys: string[]
|
|
funcParsed: RecStrFuncUnknown
|
|
funcHtml: RecStrFuncUnknown
|
|
funcComponent: RecStrFuncComponent
|
|
}>()
|
|
|
|
const loader = inject('table_data_loader') as DataTableLoader
|
|
</script>
|
|
|
|
<template>
|
|
<Table>
|
|
<TableHeader class="bg-gray-50">
|
|
<TableRow>
|
|
<TableHead
|
|
v-for="(h, idx) in header[0]" :key="`head-${idx}`" class="border"
|
|
:style="{ width: cols[idx]?.width ? `${cols[idx].width}px` : undefined }"
|
|
>
|
|
{{ h.label }}
|
|
</TableHead>
|
|
</TableRow>
|
|
</TableHeader>
|
|
|
|
<TableBody v-if="loader.isTableLoading">
|
|
<!-- Loading state with 5 skeleton rows -->
|
|
<TableRow v-for="n in 5" :key="`skeleton-${n}`">
|
|
<TableCell v-for="(key, cellIndex) in keys" :key="`cell-skel-${n}-${cellIndex}`" class="border">
|
|
<Skeleton class="bg-gray-100 animate-pulse text-muted-foreground w-full h-6" />
|
|
</TableCell>
|
|
</TableRow>
|
|
</TableBody>
|
|
<TableBody v-else-if="rows.length === 0">
|
|
<TableRow>
|
|
<TableCell :colspan="keys.length" class="text-center py-8">
|
|
<div class="flex items-center justify-center">
|
|
<Info class="size-5 text-muted-foreground" />
|
|
<span class="ml-2">Tidak ada data tersedia</span>
|
|
</div>
|
|
</TableCell>
|
|
</TableRow>
|
|
</TableBody>
|
|
<TableBody v-else>
|
|
<TableRow v-for="(row, rowIndex) in rows" :key="`row-${rowIndex}`">
|
|
<TableCell v-for="(key, cellIndex) in keys" :key="`cell-${rowIndex}-${cellIndex}`" class="border">
|
|
<!-- If funcComponent has a renderer -->
|
|
<component
|
|
:is="funcComponent[key]?.(row, rowIndex).component"
|
|
v-if="funcComponent[key]"
|
|
:rec="row"
|
|
:idx="rowIndex"
|
|
v-bind="funcComponent[key]?.(row, rowIndex).props"
|
|
/>
|
|
<!-- If funcParsed or funcHtml returns a value -->
|
|
<template v-else>
|
|
<!-- Use v-html for funcHtml to render HTML content -->
|
|
<div v-if="funcHtml[key]" v-html="funcHtml[key]?.(row, rowIndex)"></div>
|
|
<!-- Use normal interpolation for funcParsed and regular data -->
|
|
<template v-else>
|
|
{{ funcParsed[key]?.(row, rowIndex) ?? (row as any)[key] }}
|
|
</template>
|
|
</template>
|
|
</TableCell>
|
|
</TableRow>
|
|
</TableBody>
|
|
</Table>
|
|
</template>
|