feat: refactor column definitions to conditionally include action buttons based on user permissions
This commit is contained in:
parent
5ec0e9ff3b
commit
9bbb00c69f
@ -20,7 +20,7 @@ export function createCashAccountColumns(
|
||||
): ColumnDef<CashAccount>[] {
|
||||
const { handleEdit, handleDeleteClick, can } = params;
|
||||
|
||||
return [
|
||||
const columns: ColumnDef<CashAccount>[] = [
|
||||
{
|
||||
accessorKey: 'name',
|
||||
header: () => <span>Nama</span>,
|
||||
@ -39,7 +39,10 @@ export function createCashAccountColumns(
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
];
|
||||
|
||||
if (can('cash.update') || can('cash.delete')) {
|
||||
columns.push({
|
||||
id: 'actions',
|
||||
header: () => <span className="block text-center">Aksi</span>,
|
||||
meta: {
|
||||
@ -70,6 +73,8 @@ export function createCashAccountColumns(
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
return columns;
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ export function createTransactionColumns(
|
||||
): ColumnDef<CashTransaction>[] {
|
||||
const { handleEdit, handleDeleteClick, can } = params;
|
||||
|
||||
return [
|
||||
const columns: ColumnDef<CashTransaction>[] = [
|
||||
{
|
||||
accessorKey: 'formatted_created_at',
|
||||
header: () => <span>Tanggal</span>,
|
||||
@ -136,7 +136,10 @@ export function createTransactionColumns(
|
||||
return <span>{createdBy?.user_profile?.full_name ?? '-'}</span>;
|
||||
},
|
||||
},
|
||||
{
|
||||
];
|
||||
|
||||
if (can('cash.update') || can('cash.delete')) {
|
||||
columns.push({
|
||||
id: 'actions',
|
||||
header: () => <span className="block text-center">Aksi</span>,
|
||||
meta: {
|
||||
@ -174,6 +177,8 @@ export function createTransactionColumns(
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
return columns;
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ export function createEmployeeAdvanceColumns(
|
||||
const { handleEdit, handleDeleteClick, handleApprove, handlePay, handleShowPayments, can, authUserId } =
|
||||
params;
|
||||
|
||||
return [
|
||||
const columns: ColumnDef<EmployeeAdvance>[] = [
|
||||
{
|
||||
accessorKey: 'formatted_created_at',
|
||||
header: () => <span>Tanggal</span>,
|
||||
@ -162,7 +162,16 @@ export function createEmployeeAdvanceColumns(
|
||||
<span>{getStatusBadge(row.getValue('status') as string)}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
];
|
||||
|
||||
if (
|
||||
can('employee_advances.verify') ||
|
||||
can('employee_advances.pay') ||
|
||||
can('employee_advances.view_payments') ||
|
||||
can('employee_advances.update') ||
|
||||
can('employee_advances.delete')
|
||||
) {
|
||||
columns.push({
|
||||
id: 'actions',
|
||||
header: () => <span className="block text-center">Aksi</span>,
|
||||
meta: {
|
||||
@ -226,6 +235,8 @@ export function createEmployeeAdvanceColumns(
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
return columns;
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ export function createExpenseColumns(
|
||||
): ColumnDef<Expense>[] {
|
||||
const { handleEdit, handleDeleteClick, can } = params;
|
||||
|
||||
return [
|
||||
const columns: ColumnDef<Expense>[] = [
|
||||
{
|
||||
accessorKey: 'formatted_created_at',
|
||||
header: () => <span>Tanggal</span>,
|
||||
@ -83,7 +83,10 @@ export function createExpenseColumns(
|
||||
return <span>{createdBy?.user_profile?.full_name ?? '-'}</span>;
|
||||
},
|
||||
},
|
||||
{
|
||||
];
|
||||
|
||||
if (can('expenses.update') || can('expenses.delete')) {
|
||||
columns.push({
|
||||
id: 'actions',
|
||||
header: () => <span className="block text-center">Aksi</span>,
|
||||
meta: {
|
||||
@ -114,6 +117,8 @@ export function createExpenseColumns(
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
return columns;
|
||||
}
|
||||
|
||||
@ -174,58 +174,57 @@ export function createPayrollPeriodColumns(
|
||||
});
|
||||
}
|
||||
|
||||
columns.push(
|
||||
{
|
||||
accessorKey: 'status',
|
||||
header: () => <span>Status</span>,
|
||||
cell: ({ row }) => (
|
||||
<span>{getStatusBadge(row.getValue('status') as string)}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'actions',
|
||||
header: () => <span className="block text-center">Aksi</span>,
|
||||
meta: {
|
||||
className: 'w-[100px] text-center',
|
||||
headerClassName: 'w-[100px] text-center',
|
||||
},
|
||||
cell: ({ row }) => {
|
||||
const period = row.original;
|
||||
columns.push({
|
||||
accessorKey: 'status',
|
||||
header: () => <span>Status</span>,
|
||||
cell: ({ row }) => (
|
||||
<span>{getStatusBadge(row.getValue('status') as string)}</span>
|
||||
),
|
||||
});
|
||||
|
||||
return (
|
||||
<RowActions
|
||||
actions={[
|
||||
{
|
||||
label: 'Lihat Detail',
|
||||
icon: <Eye className="h-4 w-4" />,
|
||||
href: showUrl(period.id),
|
||||
},
|
||||
{
|
||||
label: 'Tutup Periode',
|
||||
icon: (
|
||||
<Lock className="h-4 w-4 text-orange-600" />
|
||||
),
|
||||
show:
|
||||
can('payroll.adjust') &&
|
||||
period.status === 'open',
|
||||
onClick: () => handleClose(period),
|
||||
},
|
||||
{
|
||||
label: 'Buka Periode',
|
||||
icon: (
|
||||
<Unlock className="h-4 w-4 text-blue-600" />
|
||||
),
|
||||
show:
|
||||
can('payroll.adjust') &&
|
||||
period.status === 'closed',
|
||||
onClick: () => handleReopen(period),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
},
|
||||
columns.push({
|
||||
id: 'actions',
|
||||
header: () => <span className="block text-center">Aksi</span>,
|
||||
meta: {
|
||||
className: 'w-[100px] text-center',
|
||||
headerClassName: 'w-[100px] text-center',
|
||||
},
|
||||
);
|
||||
cell: ({ row }) => {
|
||||
const period = row.original;
|
||||
|
||||
return (
|
||||
<RowActions
|
||||
actions={[
|
||||
{
|
||||
label: 'Lihat Detail',
|
||||
icon: <Eye className="h-4 w-4" />,
|
||||
href: showUrl(period.id),
|
||||
},
|
||||
{
|
||||
label: 'Tutup Periode',
|
||||
icon: (
|
||||
<Lock className="h-4 w-4 text-orange-600" />
|
||||
),
|
||||
show:
|
||||
can('payroll.adjust') &&
|
||||
period.status === 'open',
|
||||
onClick: () => handleClose(period),
|
||||
},
|
||||
{
|
||||
label: 'Buka Periode',
|
||||
icon: (
|
||||
<Unlock className="h-4 w-4 text-blue-600" />
|
||||
),
|
||||
show:
|
||||
can('payroll.adjust') &&
|
||||
period.status === 'closed',
|
||||
onClick: () => handleReopen(period),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
return columns;
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ export function createEmployeeColumns(
|
||||
canViewAll,
|
||||
} = params;
|
||||
|
||||
return [
|
||||
const columns: ColumnDef<Employee>[] = [
|
||||
{
|
||||
accessorKey: 'user_profile.full_name',
|
||||
id: 'full_name',
|
||||
@ -154,7 +154,14 @@ export function createEmployeeColumns(
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
];
|
||||
|
||||
if (
|
||||
can('employees.update') ||
|
||||
can('employees.reset_password') ||
|
||||
can('employees.delete')
|
||||
) {
|
||||
columns.push({
|
||||
id: 'actions',
|
||||
header: () => <span className="block text-center">Aksi</span>,
|
||||
meta: {
|
||||
@ -193,6 +200,8 @@ export function createEmployeeColumns(
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
return columns;
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ export function createLeaveRequestColumns(
|
||||
const { handleEdit, handleDeleteClick, handleApprove, handleReject, can } =
|
||||
params;
|
||||
|
||||
return [
|
||||
const columns: ColumnDef<LeaveRequest>[] = [
|
||||
{
|
||||
id: 'employee_name',
|
||||
header: () => <span>Oleh</span>,
|
||||
@ -112,7 +112,14 @@ export function createLeaveRequestColumns(
|
||||
<span>{getStatusBadge(row.getValue('status') as string)}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
];
|
||||
|
||||
if (
|
||||
can('leave_requests.verify') ||
|
||||
can('leave_requests.update') ||
|
||||
can('leave_requests.delete')
|
||||
) {
|
||||
columns.push({
|
||||
id: 'actions',
|
||||
header: () => <span className="block text-center">Aksi</span>,
|
||||
meta: {
|
||||
@ -167,6 +174,8 @@ export function createLeaveRequestColumns(
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
return columns;
|
||||
}
|
||||
|
||||
@ -139,25 +139,27 @@ export function CuttingCardRow({
|
||||
)}
|
||||
</div>
|
||||
|
||||
<RowActions
|
||||
actions={[
|
||||
{
|
||||
label: 'Edit',
|
||||
icon: <Pencil className="h-4 w-4" />,
|
||||
show: can('cuttings.update'),
|
||||
onClick: () => onEdit(cutting),
|
||||
},
|
||||
{
|
||||
label: 'Hapus',
|
||||
icon: (
|
||||
<Trash2 className="h-4 w-4 text-destructive" />
|
||||
),
|
||||
show: can('cuttings.delete'),
|
||||
onClick: () => onDelete(cutting),
|
||||
},
|
||||
]}
|
||||
wrapperClassName="flex shrink-0 items-center gap-1"
|
||||
/>
|
||||
{(can('cuttings.update') || can('cuttings.delete')) && (
|
||||
<RowActions
|
||||
actions={[
|
||||
{
|
||||
label: 'Edit',
|
||||
icon: <Pencil className="h-4 w-4" />,
|
||||
show: can('cuttings.update'),
|
||||
onClick: () => onEdit(cutting),
|
||||
},
|
||||
{
|
||||
label: 'Hapus',
|
||||
icon: (
|
||||
<Trash2 className="h-4 w-4 text-destructive" />
|
||||
),
|
||||
show: can('cuttings.delete'),
|
||||
onClick: () => onDelete(cutting),
|
||||
},
|
||||
]}
|
||||
wrapperClassName="flex shrink-0 items-center gap-1"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@ -126,25 +126,27 @@ export function PurchaseCardRow({
|
||||
)}
|
||||
</div>
|
||||
|
||||
<RowActions
|
||||
actions={[
|
||||
{
|
||||
label: 'Edit',
|
||||
icon: <Pencil className="h-4 w-4" />,
|
||||
show: can('purchases.update'),
|
||||
onClick: () => onEdit(purchase),
|
||||
},
|
||||
{
|
||||
label: 'Hapus',
|
||||
icon: (
|
||||
<Trash2 className="h-4 w-4 text-destructive" />
|
||||
),
|
||||
show: can('purchases.delete'),
|
||||
onClick: () => onDelete(purchase),
|
||||
},
|
||||
]}
|
||||
wrapperClassName="flex shrink-0 items-center gap-1"
|
||||
/>
|
||||
{(can('purchases.update') || can('purchases.delete')) && (
|
||||
<RowActions
|
||||
actions={[
|
||||
{
|
||||
label: 'Edit',
|
||||
icon: <Pencil className="h-4 w-4" />,
|
||||
show: can('purchases.update'),
|
||||
onClick: () => onEdit(purchase),
|
||||
},
|
||||
{
|
||||
label: 'Hapus',
|
||||
icon: (
|
||||
<Trash2 className="h-4 w-4 text-destructive" />
|
||||
),
|
||||
show: can('purchases.delete'),
|
||||
onClick: () => onDelete(purchase),
|
||||
},
|
||||
]}
|
||||
wrapperClassName="flex shrink-0 items-center gap-1"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@ -135,25 +135,27 @@ export function RestockCardRow({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<RowActions
|
||||
actions={[
|
||||
{
|
||||
label: 'Edit',
|
||||
icon: <Pencil className="h-4 w-4" />,
|
||||
show: can('restocks.update'),
|
||||
onClick: () => onEdit(restock),
|
||||
},
|
||||
{
|
||||
label: 'Hapus',
|
||||
icon: (
|
||||
<Trash2 className="h-4 w-4 text-destructive" />
|
||||
),
|
||||
show: can('restocks.delete'),
|
||||
onClick: () => onDelete(restock),
|
||||
},
|
||||
]}
|
||||
wrapperClassName="flex shrink-0 items-center gap-1"
|
||||
/>
|
||||
{(can('restocks.update') || can('restocks.delete')) && (
|
||||
<RowActions
|
||||
actions={[
|
||||
{
|
||||
label: 'Edit',
|
||||
icon: <Pencil className="h-4 w-4" />,
|
||||
show: can('restocks.update'),
|
||||
onClick: () => onEdit(restock),
|
||||
},
|
||||
{
|
||||
label: 'Hapus',
|
||||
icon: (
|
||||
<Trash2 className="h-4 w-4 text-destructive" />
|
||||
),
|
||||
show: can('restocks.delete'),
|
||||
onClick: () => onDelete(restock),
|
||||
},
|
||||
]}
|
||||
wrapperClassName="flex shrink-0 items-center gap-1"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@ -183,57 +183,59 @@ export function TransactionCardRow({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<RowActions
|
||||
actions={[
|
||||
...(transaction.status === 'pending' && can('orders.update')
|
||||
? [
|
||||
{
|
||||
label: 'Kirim',
|
||||
icon: <Send className="h-4 w-4" />,
|
||||
onClick: () => onUpdateStatus(transaction, 'processing'),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...((transaction.status === 'pending' || transaction.status === 'processing') && can('orders.update')
|
||||
? [
|
||||
{
|
||||
label: 'Selesai',
|
||||
icon: <CheckCircle className="h-4 w-4" />,
|
||||
onClick: () => onUpdateStatus(transaction, 'completed'),
|
||||
},
|
||||
{
|
||||
label: 'Dibatalkan',
|
||||
icon: <XCircle className="h-4 w-4 text-destructive" />,
|
||||
onClick: () => onUpdateStatus(transaction, 'cancelled'),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(transaction.status === 'completed' && can('orders.update')
|
||||
? [
|
||||
{
|
||||
label: 'Refund',
|
||||
icon: <XCircle className="h-4 w-4 text-destructive" />,
|
||||
onClick: () => onUpdateStatus(transaction, 'refunded'),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
label: 'Edit',
|
||||
icon: <Pencil className="h-4 w-4" />,
|
||||
show: can('orders.update'),
|
||||
onClick: () => onEdit(transaction),
|
||||
},
|
||||
{
|
||||
label: 'Hapus',
|
||||
icon: (
|
||||
<Trash2 className="h-4 w-4 text-destructive" />
|
||||
),
|
||||
show: can('orders.delete'),
|
||||
onClick: () => onDelete(transaction),
|
||||
},
|
||||
]}
|
||||
wrapperClassName="flex shrink-0 items-center gap-1"
|
||||
/>
|
||||
{(can('orders.update') || can('orders.delete')) && (
|
||||
<RowActions
|
||||
actions={[
|
||||
...(transaction.status === 'pending' && can('orders.update')
|
||||
? [
|
||||
{
|
||||
label: 'Kirim',
|
||||
icon: <Send className="h-4 w-4" />,
|
||||
onClick: () => onUpdateStatus(transaction, 'processing'),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...((transaction.status === 'pending' || transaction.status === 'processing') && can('orders.update')
|
||||
? [
|
||||
{
|
||||
label: 'Selesai',
|
||||
icon: <CheckCircle className="h-4 w-4" />,
|
||||
onClick: () => onUpdateStatus(transaction, 'completed'),
|
||||
},
|
||||
{
|
||||
label: 'Dibatalkan',
|
||||
icon: <XCircle className="h-4 w-4 text-destructive" />,
|
||||
onClick: () => onUpdateStatus(transaction, 'cancelled'),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(transaction.status === 'completed' && can('orders.update')
|
||||
? [
|
||||
{
|
||||
label: 'Refund',
|
||||
icon: <XCircle className="h-4 w-4 text-destructive" />,
|
||||
onClick: () => onUpdateStatus(transaction, 'refunded'),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
label: 'Edit',
|
||||
icon: <Pencil className="h-4 w-4" />,
|
||||
show: can('orders.update'),
|
||||
onClick: () => onEdit(transaction),
|
||||
},
|
||||
{
|
||||
label: 'Hapus',
|
||||
icon: (
|
||||
<Trash2 className="h-4 w-4 text-destructive" />
|
||||
),
|
||||
show: can('orders.delete'),
|
||||
onClick: () => onDelete(transaction),
|
||||
},
|
||||
]}
|
||||
wrapperClassName="flex shrink-0 items-center gap-1"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@ -18,7 +18,7 @@ export function createCategoryColumns(
|
||||
): ColumnDef<Category>[] {
|
||||
const { handleEdit, handleDeleteClick, can } = params;
|
||||
|
||||
return [
|
||||
const columns: ColumnDef<Category>[] = [
|
||||
{
|
||||
accessorKey: 'name',
|
||||
header: () => <span>Nama</span>,
|
||||
@ -28,7 +28,10 @@ export function createCategoryColumns(
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
];
|
||||
|
||||
if (can('categories.update') || can('categories.delete')) {
|
||||
columns.push({
|
||||
id: 'actions',
|
||||
header: () => <span className="block text-center">Aksi</span>,
|
||||
meta: {
|
||||
@ -59,6 +62,8 @@ export function createCategoryColumns(
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
return columns;
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ export function createCustomerColumns(
|
||||
): ColumnDef<Customer>[] {
|
||||
const { handleEdit, handleDeleteClick, can } = params;
|
||||
|
||||
return [
|
||||
const columns: ColumnDef<Customer>[] = [
|
||||
{
|
||||
accessorKey: 'name',
|
||||
header: () => <span>Nama</span>,
|
||||
@ -46,7 +46,10 @@ export function createCustomerColumns(
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
];
|
||||
|
||||
if (can('customers.update') || can('customers.delete')) {
|
||||
columns.push({
|
||||
id: 'actions',
|
||||
header: () => <span className="block text-center">Aksi</span>,
|
||||
meta: {
|
||||
@ -77,6 +80,8 @@ export function createCustomerColumns(
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
return columns;
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ export function createProductColumns(
|
||||
can,
|
||||
} = params;
|
||||
|
||||
return [
|
||||
const columns: ColumnDef<Product>[] = [
|
||||
{
|
||||
id: 'expand',
|
||||
header: '',
|
||||
@ -338,7 +338,10 @@ export function createProductColumns(
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
];
|
||||
|
||||
if (can('products.update') || can('products.delete')) {
|
||||
columns.push({
|
||||
id: 'actions',
|
||||
header: () => <span className="block text-center">Aksi</span>,
|
||||
meta: {
|
||||
@ -369,6 +372,8 @@ export function createProductColumns(
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
return columns;
|
||||
}
|
||||
|
||||
@ -144,25 +144,27 @@ export function ProductCardRow({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<RowActions
|
||||
actions={[
|
||||
{
|
||||
label: 'Edit',
|
||||
icon: <Pencil className="h-4 w-4" />,
|
||||
show: can('products.update'),
|
||||
onClick: () => onEdit(product),
|
||||
},
|
||||
{
|
||||
label: 'Hapus',
|
||||
icon: (
|
||||
<Trash2 className="h-4 w-4 text-destructive" />
|
||||
),
|
||||
show: can('products.delete'),
|
||||
onClick: () => onDelete(product),
|
||||
},
|
||||
]}
|
||||
wrapperClassName="flex shrink-0 items-center gap-1"
|
||||
/>
|
||||
{(can('products.update') || can('products.delete')) && (
|
||||
<RowActions
|
||||
actions={[
|
||||
{
|
||||
label: 'Edit',
|
||||
icon: <Pencil className="h-4 w-4" />,
|
||||
show: can('products.update'),
|
||||
onClick: () => onEdit(product),
|
||||
},
|
||||
{
|
||||
label: 'Hapus',
|
||||
icon: (
|
||||
<Trash2 className="h-4 w-4 text-destructive" />
|
||||
),
|
||||
show: can('products.delete'),
|
||||
onClick: () => onDelete(product),
|
||||
},
|
||||
]}
|
||||
wrapperClassName="flex shrink-0 items-center gap-1"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@ -34,6 +34,8 @@ export function VariantSubRow({
|
||||
variant: ProductVariant;
|
||||
} | null>(null);
|
||||
|
||||
const canAnyAction = can('products.transfer_stock') || can('products.view_stock_mutations') || can('products.update') || can('products.delete');
|
||||
|
||||
return (
|
||||
<div className="overflow-x-auto">
|
||||
<Table>
|
||||
@ -52,16 +54,18 @@ export function VariantSubRow({
|
||||
</TableHead>
|
||||
<TableHead className="text-center">Stok Ecer</TableHead>
|
||||
<TableHead>Harga</TableHead>
|
||||
<TableHead className="w-[120px] text-center">
|
||||
Aksi
|
||||
</TableHead>
|
||||
{canAnyAction && (
|
||||
<TableHead className="w-[120px] text-center">
|
||||
Aksi
|
||||
</TableHead>
|
||||
)}
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{variants.length === 0 ? (
|
||||
<TableRow>
|
||||
<TableCell
|
||||
colSpan={8}
|
||||
colSpan={canAnyAction ? 8 : 7}
|
||||
className="text-center text-muted-foreground"
|
||||
>
|
||||
Tidak ada varian.
|
||||
@ -116,63 +120,65 @@ export function VariantSubRow({
|
||||
'-'
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<RowActions
|
||||
actions={[
|
||||
{
|
||||
label: 'Transfer Stok',
|
||||
icon: (
|
||||
<ArrowRightLeft className="h-4 w-4" />
|
||||
),
|
||||
show: can('products.transfer_stock'),
|
||||
onClick: () =>
|
||||
setTransferVariant({
|
||||
product,
|
||||
variant,
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: 'Mutasi Stok',
|
||||
icon: (
|
||||
<ScrollText className="h-4 w-4" />
|
||||
),
|
||||
show: can('products.view_stock_mutations'),
|
||||
onClick: () => {
|
||||
router.visit(
|
||||
stockMutations.url({
|
||||
product: product.id,
|
||||
variant: variant.id,
|
||||
{canAnyAction && (
|
||||
<TableCell>
|
||||
<RowActions
|
||||
actions={[
|
||||
{
|
||||
label: 'Transfer Stok',
|
||||
icon: (
|
||||
<ArrowRightLeft className="h-4 w-4" />
|
||||
),
|
||||
show: can('products.transfer_stock'),
|
||||
onClick: () =>
|
||||
setTransferVariant({
|
||||
product,
|
||||
variant,
|
||||
}),
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Edit',
|
||||
icon: (
|
||||
<Pencil className="h-4 w-4" />
|
||||
),
|
||||
show: can('products.update'),
|
||||
onClick: () =>
|
||||
onEditVariant(
|
||||
product,
|
||||
variant,
|
||||
{
|
||||
label: 'Mutasi Stok',
|
||||
icon: (
|
||||
<ScrollText className="h-4 w-4" />
|
||||
),
|
||||
},
|
||||
{
|
||||
label: 'Hapus',
|
||||
icon: (
|
||||
<Trash2 className="h-4 w-4 text-destructive" />
|
||||
),
|
||||
show: can('products.delete'),
|
||||
onClick: () =>
|
||||
onDeleteVariantClick(
|
||||
product,
|
||||
variant,
|
||||
show: can('products.view_stock_mutations'),
|
||||
onClick: () => {
|
||||
router.visit(
|
||||
stockMutations.url({
|
||||
product: product.id,
|
||||
variant: variant.id,
|
||||
}),
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Edit',
|
||||
icon: (
|
||||
<Pencil className="h-4 w-4" />
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</TableCell>
|
||||
show: can('products.update'),
|
||||
onClick: () =>
|
||||
onEditVariant(
|
||||
product,
|
||||
variant,
|
||||
),
|
||||
},
|
||||
{
|
||||
label: 'Hapus',
|
||||
icon: (
|
||||
<Trash2 className="h-4 w-4 text-destructive" />
|
||||
),
|
||||
show: can('products.delete'),
|
||||
onClick: () =>
|
||||
onDeleteVariantClick(
|
||||
product,
|
||||
variant,
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</TableCell>
|
||||
)}
|
||||
</TableRow>
|
||||
))
|
||||
)}
|
||||
|
||||
@ -94,25 +94,27 @@ export function RawMaterialCardRow({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<RowActions
|
||||
actions={[
|
||||
{
|
||||
label: 'Edit',
|
||||
icon: <Pencil className="h-4 w-4" />,
|
||||
show: can('raw_materials.update'),
|
||||
onClick: () => onEdit(rawMaterial),
|
||||
},
|
||||
{
|
||||
label: 'Hapus',
|
||||
icon: (
|
||||
<Trash2 className="h-4 w-4 text-destructive" />
|
||||
),
|
||||
show: can('raw_materials.delete'),
|
||||
onClick: () => onDelete(rawMaterial),
|
||||
},
|
||||
]}
|
||||
wrapperClassName="flex shrink-0 items-center gap-1"
|
||||
/>
|
||||
{(can('raw_materials.update') || can('raw_materials.delete')) && (
|
||||
<RowActions
|
||||
actions={[
|
||||
{
|
||||
label: 'Edit',
|
||||
icon: <Pencil className="h-4 w-4" />,
|
||||
show: can('raw_materials.update'),
|
||||
onClick: () => onEdit(rawMaterial),
|
||||
},
|
||||
{
|
||||
label: 'Hapus',
|
||||
icon: (
|
||||
<Trash2 className="h-4 w-4 text-destructive" />
|
||||
),
|
||||
show: can('raw_materials.delete'),
|
||||
onClick: () => onDelete(rawMaterial),
|
||||
},
|
||||
]}
|
||||
wrapperClassName="flex shrink-0 items-center gap-1"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@ -47,6 +47,8 @@ export function RawMaterialVariantSubRow({
|
||||
);
|
||||
}
|
||||
|
||||
const canAnyAction = can('raw_materials.update') || can('raw_materials.delete');
|
||||
|
||||
return (
|
||||
<div className="overflow-x-auto">
|
||||
<Table>
|
||||
@ -59,16 +61,18 @@ export function RawMaterialVariantSubRow({
|
||||
<TableHead>Nama Varian</TableHead>
|
||||
<TableHead>Harga</TableHead>
|
||||
<TableHead className="text-center">Stok</TableHead>
|
||||
<TableHead className="w-[100px] text-center">
|
||||
Aksi
|
||||
</TableHead>
|
||||
{canAnyAction && (
|
||||
<TableHead className="w-[100px] text-center">
|
||||
Aksi
|
||||
</TableHead>
|
||||
)}
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{variants.length === 0 ? (
|
||||
<TableRow>
|
||||
<TableCell
|
||||
colSpan={6}
|
||||
colSpan={canAnyAction ? 6 : 5}
|
||||
className="text-center text-muted-foreground"
|
||||
>
|
||||
Tidak ada varian.
|
||||
@ -101,37 +105,39 @@ export function RawMaterialVariantSubRow({
|
||||
<TableCell className="text-center">
|
||||
{formatNumber(variant.stock)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<RowActions
|
||||
actions={[
|
||||
{
|
||||
label: 'Edit',
|
||||
icon: (
|
||||
<Pencil className="h-4 w-4" />
|
||||
),
|
||||
show: can('raw_materials.update'),
|
||||
onClick: () => {
|
||||
router.visit(
|
||||
variantEdit.url({
|
||||
rawMaterial:
|
||||
rawMaterial.id,
|
||||
variant: variant.id,
|
||||
}),
|
||||
);
|
||||
{canAnyAction && (
|
||||
<TableCell>
|
||||
<RowActions
|
||||
actions={[
|
||||
{
|
||||
label: 'Edit',
|
||||
icon: (
|
||||
<Pencil className="h-4 w-4" />
|
||||
),
|
||||
show: can('raw_materials.update'),
|
||||
onClick: () => {
|
||||
router.visit(
|
||||
variantEdit.url({
|
||||
rawMaterial:
|
||||
rawMaterial.id,
|
||||
variant: variant.id,
|
||||
}),
|
||||
);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Hapus',
|
||||
icon: (
|
||||
<Trash2 className="h-4 w-4 text-destructive" />
|
||||
),
|
||||
show: can('raw_materials.delete'),
|
||||
onClick: () =>
|
||||
setDeletingVariant(variant),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</TableCell>
|
||||
{
|
||||
label: 'Hapus',
|
||||
icon: (
|
||||
<Trash2 className="h-4 w-4 text-destructive" />
|
||||
),
|
||||
show: can('raw_materials.delete'),
|
||||
onClick: () =>
|
||||
setDeletingVariant(variant),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</TableCell>
|
||||
)}
|
||||
</TableRow>
|
||||
))
|
||||
)}
|
||||
|
||||
@ -20,7 +20,7 @@ export function createSupplierColumns(
|
||||
): ColumnDef<Supplier>[] {
|
||||
const { handleEdit, handleDeleteClick, can } = params;
|
||||
|
||||
return [
|
||||
const columns: ColumnDef<Supplier>[] = [
|
||||
{
|
||||
accessorKey: 'name',
|
||||
header: () => <span>Nama</span>,
|
||||
@ -46,7 +46,10 @@ export function createSupplierColumns(
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
];
|
||||
|
||||
if (can('suppliers.update') || can('suppliers.delete')) {
|
||||
columns.push({
|
||||
id: 'actions',
|
||||
header: () => <span className="block text-center">Aksi</span>,
|
||||
meta: {
|
||||
@ -77,6 +80,8 @@ export function createSupplierColumns(
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
return columns;
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ export function createRoleColumns(
|
||||
): ColumnDef<Role>[] {
|
||||
const { handleEdit, handleDeleteClick, can } = params;
|
||||
|
||||
return [
|
||||
const columns: ColumnDef<Role>[] = [
|
||||
{
|
||||
accessorKey: 'name',
|
||||
header: () => <span>Nama Role</span>,
|
||||
@ -44,7 +44,10 @@ export function createRoleColumns(
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
];
|
||||
|
||||
if (can('roles.update') || can('roles.delete')) {
|
||||
columns.push({
|
||||
id: 'actions',
|
||||
header: () => <span className="block text-center">Aksi</span>,
|
||||
meta: {
|
||||
@ -75,6 +78,8 @@ export function createRoleColumns(
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
return columns;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user