78 lines
2.6 KiB
TypeScript
78 lines
2.6 KiB
TypeScript
import type { ColumnDef } from '@tanstack/vue-table';
|
|
import { h } from 'vue';
|
|
import { DataTableColumnHeader } from '@/components/data-table';
|
|
import type { ActivityLogListItem } from '@/types/activity-log';
|
|
|
|
function formatValue(value: unknown): string {
|
|
if (value === null || value === undefined || value === '') {
|
|
return '-';
|
|
}
|
|
|
|
if (typeof value === 'boolean') {
|
|
return value ? 'Ya' : 'Tidak';
|
|
}
|
|
|
|
if (typeof value === 'object') {
|
|
return JSON.stringify(value);
|
|
}
|
|
|
|
return String(value);
|
|
}
|
|
|
|
export function createColumns(): ColumnDef<ActivityLogListItem>[] {
|
|
return [
|
|
{
|
|
accessorKey: 'created_at_formatted',
|
|
enableSorting: true,
|
|
header: () => h(DataTableColumnHeader, { title: 'Waktu', column: 'created_at' }),
|
|
cell: ({ row }) => row.original.created_at_formatted ?? '-',
|
|
},
|
|
{
|
|
accessorKey: 'causer_name',
|
|
enableSorting: false,
|
|
header: 'Pengguna',
|
|
},
|
|
{
|
|
accessorKey: 'event_label',
|
|
enableSorting: true,
|
|
header: () => h(DataTableColumnHeader, { title: 'Aksi', column: 'event' }),
|
|
},
|
|
{
|
|
accessorKey: 'subject_label',
|
|
enableSorting: false,
|
|
header: 'Modul',
|
|
},
|
|
{
|
|
accessorKey: 'description',
|
|
enableSorting: true,
|
|
header: () => h(DataTableColumnHeader, { title: 'Deskripsi', column: 'description' }),
|
|
},
|
|
{
|
|
id: 'changes',
|
|
enableSorting: false,
|
|
enableHiding: false,
|
|
header: 'Perubahan',
|
|
cell: ({ row }) => {
|
|
const changes = row.original.changes;
|
|
|
|
if (!changes.length) {
|
|
return h('span', { class: 'text-muted-foreground text-sm' }, '-');
|
|
}
|
|
|
|
const items = changes.map((change) =>
|
|
h('div', { class: 'text-xs space-y-0.5' }, [
|
|
h('div', { class: 'font-medium text-muted-foreground' }, change.field),
|
|
h('div', { class: 'flex items-center gap-1.5' }, [
|
|
h('span', { class: 'text-red-600' }, formatValue(change.old)),
|
|
h('span', { class: 'text-muted-foreground' }, '→'),
|
|
h('span', { class: 'text-green-600' }, formatValue(change.new)),
|
|
]),
|
|
]),
|
|
);
|
|
|
|
return h('div', { class: 'space-y-2 min-w-48' }, items);
|
|
},
|
|
},
|
|
];
|
|
}
|