✨ feat (pub): adjust data table
This commit is contained in:
@@ -13,6 +13,12 @@ const props = defineProps<{
|
|||||||
funcParsed: RecStrFuncUnknown
|
funcParsed: RecStrFuncUnknown
|
||||||
funcHtml: RecStrFuncUnknown
|
funcHtml: RecStrFuncUnknown
|
||||||
funcComponent: RecStrFuncComponent
|
funcComponent: RecStrFuncComponent
|
||||||
|
selectMode?: 'single' | 'multiple'
|
||||||
|
modelValue?: any[] | any
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'update:modelValue', val: any[] | any): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const getSkeletonSize = computed(() => {
|
const getSkeletonSize = computed(() => {
|
||||||
@@ -20,6 +26,24 @@ const getSkeletonSize = computed(() => {
|
|||||||
})
|
})
|
||||||
const loader = inject('table_data_loader') as DataTableLoader
|
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) {
|
function handleActionCellClick(event: Event, _cellRef: string) {
|
||||||
// Prevent event if clicked directly on the button/dropdown
|
// Prevent event if clicked directly on the button/dropdown
|
||||||
const target = event.target as HTMLElement
|
const target = event.target as HTMLElement
|
||||||
@@ -70,32 +94,38 @@ function handleActionCellClick(event: Event, _cellRef: string) {
|
|||||||
</TableRow>
|
</TableRow>
|
||||||
</TableBody>
|
</TableBody>
|
||||||
<TableBody v-else>
|
<TableBody v-else>
|
||||||
<TableRow v-for="(row, rowIndex) in rows" :key="`row-${rowIndex}`">
|
<TableRow
|
||||||
<TableCell
|
v-for="(row, rowIndex) in rows"
|
||||||
v-for="(key, cellIndex) in keys"
|
:key="`row-${rowIndex}`"
|
||||||
:key="`cell-${rowIndex}-${cellIndex}`"
|
:class="{
|
||||||
class="border"
|
'bg-green-50': props.selectMode === 'single' && selected.includes(row),
|
||||||
:class="{ 'cursor-pointer': key === 'action' && funcComponent[key] }"
|
'bg-blue-50': props.selectMode === 'multiple' && selected.includes(row),
|
||||||
@click="
|
}"
|
||||||
key === 'action' && funcComponent[key]
|
@click="toggleSelection(row)"
|
||||||
? handleActionCellClick($event, `cell-${rowIndex}-${cellIndex}`)
|
>
|
||||||
: null
|
<!-- opsional: kalau mau tampilkan checkbox/radio di cell pertama -->
|
||||||
"
|
<TableCell v-if="props.selectMode">
|
||||||
>
|
<input
|
||||||
<!-- If funcComponent has a renderer -->
|
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
|
<component
|
||||||
:is="funcComponent[key]?.(row, rowIndex).component"
|
:is="funcComponent[key]?.(row, rowIndex).component"
|
||||||
v-if="funcComponent[key]"
|
v-if="funcComponent[key]"
|
||||||
:ref="key === 'action' ? `actionComponent-${rowIndex}-${cellIndex}` : undefined"
|
|
||||||
:rec="row"
|
:rec="row"
|
||||||
:idx="rowIndex"
|
:idx="rowIndex"
|
||||||
v-bind="funcComponent[key]?.(row, rowIndex).props"
|
v-bind="funcComponent[key]?.(row, rowIndex).props"
|
||||||
/>
|
/>
|
||||||
<!-- If funcParsed or funcHtml returns a value -->
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<!-- Use v-html for funcHtml to render HTML content -->
|
|
||||||
<div v-if="funcHtml[key]" v-html="funcHtml[key]?.(row, rowIndex)"></div>
|
<div v-if="funcHtml[key]" v-html="funcHtml[key]?.(row, rowIndex)"></div>
|
||||||
<!-- Use normal interpolation for funcParsed and regular data -->
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
{{ funcParsed[key]?.(row, rowIndex) ?? (row as any)[key] }}
|
{{ funcParsed[key]?.(row, rowIndex) ?? (row as any)[key] }}
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user