122 lines
4.2 KiB
TypeScript
122 lines
4.2 KiB
TypeScript
import type { ColumnDef } from '@tanstack/vue-table';
|
|
import { h } from 'vue';
|
|
import { DataTableColumnHeader } from '@/components/data-table';
|
|
import DataTableActions from '@/components/hr/employees/data-table-actions.vue';
|
|
import EmployeeStatusToggle from '@/components/hr/employees/employee-status-toggle.vue';
|
|
import { Badge } from '@/components/ui/badge';
|
|
import type { EmployeeListItem } from '@/types/employee';
|
|
|
|
function formatDate(value: string | null): string {
|
|
if (!value) {
|
|
return '-';
|
|
}
|
|
|
|
const date = new Date(value);
|
|
|
|
if (Number.isNaN(date.getTime())) {
|
|
return value;
|
|
}
|
|
|
|
return date.toLocaleDateString('id-ID', {
|
|
day: 'numeric',
|
|
month: 'short',
|
|
year: 'numeric',
|
|
});
|
|
}
|
|
|
|
export const columns: ColumnDef<EmployeeListItem>[] = [
|
|
{
|
|
accessorKey: 'full_name',
|
|
enableSorting: true,
|
|
header: () => h(DataTableColumnHeader, { title: 'Nama', column: 'full_name' }),
|
|
},
|
|
{
|
|
id: 'account',
|
|
accessorKey: 'email',
|
|
enableSorting: true,
|
|
header: () => h(DataTableColumnHeader, { title: 'Akun', column: 'email' }),
|
|
cell: ({ row }) => h('div', { class: 'space-y-0.5' }, [
|
|
h('div', { class: 'font-medium' }, row.original.email ?? '-'),
|
|
h('div', { class: 'text-muted-foreground text-xs' }, row.original.username ?? '-'),
|
|
]),
|
|
},
|
|
{
|
|
accessorKey: 'role_label',
|
|
enableSorting: false,
|
|
header: () => h(DataTableColumnHeader, { title: 'Role', column: 'role' }),
|
|
cell: ({ row }) => row.original.role_label
|
|
? h(Badge, { variant: 'outline' }, () => row.original.role_label)
|
|
: '-',
|
|
},
|
|
{
|
|
accessorKey: 'phone_number',
|
|
enableSorting: false,
|
|
header: () => h(DataTableColumnHeader, { title: 'Telepon', column: 'phone_number' }),
|
|
cell: ({ row }) => row.original.phone_number ?? '-',
|
|
},
|
|
{
|
|
accessorKey: 'gender_label',
|
|
enableSorting: false,
|
|
header: () => h(DataTableColumnHeader, { title: 'Jenis Kelamin', column: 'gender' }),
|
|
cell: ({ row }) => row.original.gender_label ?? '-',
|
|
},
|
|
{
|
|
accessorKey: 'birth_date',
|
|
enableSorting: false,
|
|
header: () => h(DataTableColumnHeader, { title: 'Tanggal Lahir', column: 'birth_date' }),
|
|
cell: ({ row }) => formatDate(row.original.birth_date),
|
|
},
|
|
{
|
|
accessorKey: 'address',
|
|
enableSorting: false,
|
|
header: () => h(DataTableColumnHeader, { title: 'Alamat', column: 'address' }),
|
|
cell: ({ row }) => h(
|
|
'span',
|
|
{ class: 'block max-w-[200px] truncate', title: row.original.address ?? undefined },
|
|
row.original.address ?? '-',
|
|
),
|
|
},
|
|
{
|
|
id: 'employment_dates',
|
|
accessorKey: 'join_date',
|
|
enableSorting: true,
|
|
header: () => h(DataTableColumnHeader, { title: 'Masa Kepegawaian', column: 'join_date' }),
|
|
cell: ({ row }) => h('div', { class: 'space-y-0.5 text-sm' }, [
|
|
h('div', {}, [
|
|
h('span', { class: 'text-muted-foreground' }, 'Bergabung: '),
|
|
formatDate(row.original.join_date),
|
|
]),
|
|
h('div', {}, [
|
|
h('span', { class: 'text-muted-foreground' }, 'Resign: '),
|
|
row.original.resign_date ?? '-',
|
|
]),
|
|
]),
|
|
},
|
|
{
|
|
accessorKey: 'employment_status_label',
|
|
enableSorting: true,
|
|
header: () => h(DataTableColumnHeader, { title: 'Status Kepegawaian', column: 'employment_status' }),
|
|
},
|
|
{
|
|
accessorKey: 'base_salary_formatted',
|
|
enableSorting: true,
|
|
header: () => h(DataTableColumnHeader, {
|
|
title: 'Gaji Pokok',
|
|
column: 'base_salary',
|
|
}),
|
|
cell: ({ row }) => row.original.base_salary_formatted,
|
|
},
|
|
{
|
|
id: 'status_toggle',
|
|
enableSorting: false,
|
|
header: () => h(DataTableColumnHeader, { title: 'Status', column: 'is_active' }),
|
|
cell: ({ row }) => h(EmployeeStatusToggle, { employee: row.original }),
|
|
},
|
|
{
|
|
id: 'actions',
|
|
enableSorting: false,
|
|
enableHiding: false,
|
|
cell: ({ row }) => h(DataTableActions, { employee: row.original }),
|
|
},
|
|
];
|