feat (pub): adjust data table

This commit is contained in:
Abizrh
2025-09-27 23:14:56 +07:00
parent f28c7edd62
commit dcfadcf4a0
@@ -13,6 +13,12 @@ const props = defineProps<{
funcParsed: RecStrFuncUnknown
funcHtml: RecStrFuncUnknown
funcComponent: RecStrFuncComponent
selectMode?: 'single' | 'multiple'
modelValue?: any[] | any
}>()
const emit = defineEmits<{
(e: 'update:modelValue', val: any[] | any): void
}>()
const getSkeletonSize = computed(() => {
@@ -20,6 +26,24 @@ const getSkeletonSize = computed(() => {
})
const loader = inject('table_data_loader') as DataTableLoader
// local state utk selection
const selected = ref<any[]>([])
function toggleSelection(row: any) {
if (props.selectMode === 'single') {
selected.value = [row]
emit('update:modelValue', row)
} else {
const idx = selected.value.findIndex((r) => r === row)
if (idx >= 0) {
selected.value.splice(idx, 1)
} else {
selected.value.push(row)
}
emit('update:modelValue', [...selected.value])
}
}
function handleActionCellClick(event: Event, _cellRef: string) {
// Prevent event if clicked directly on the button/dropdown
const target = event.target as HTMLElement
@@ -70,32 +94,38 @@ function handleActionCellClick(event: Event, _cellRef: string) {
</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"
:class="{ 'cursor-pointer': key === 'action' && funcComponent[key] }"
@click="
key === 'action' && funcComponent[key]
? handleActionCellClick($event, `cell-${rowIndex}-${cellIndex}`)
: null
"
>
<!-- If funcComponent has a renderer -->
<TableRow
v-for="(row, rowIndex) in rows"
:key="`row-${rowIndex}`"
:class="{
'bg-green-50': props.selectMode === 'single' && selected.includes(row),
'bg-blue-50': props.selectMode === 'multiple' && selected.includes(row),
}"
@click="toggleSelection(row)"
>
<!-- opsional: kalau mau tampilkan checkbox/radio di cell pertama -->
<TableCell v-if="props.selectMode">
<input
v-if="props.selectMode === 'single'"
type="radio"
:checked="selected.includes(row)"
@change="toggleSelection(row)"
/>
<input v-else type="checkbox" :checked="selected.includes(row)" @change="toggleSelection(row)" />
</TableCell>
<!-- lanjut render cell normal -->
<TableCell v-for="(key, cellIndex) in keys" :key="`cell-${rowIndex}-${cellIndex}`" class="border">
<!-- existing cell renderer -->
<component
:is="funcComponent[key]?.(row, rowIndex).component"
v-if="funcComponent[key]"
:ref="key === 'action' ? `actionComponent-${rowIndex}-${cellIndex}` : undefined"
: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>