From 9bbb00c69f540f10b8ff3634d981e3c5a57c5cf3 Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Thu, 6 Aug 2026 22:48:00 +0700 Subject: [PATCH] feat: refactor column definitions to conditionally include action buttons based on user permissions --- .../admin/finance/cash-account/columns.tsx | 13 +- .../cash-account/transaction-columns.tsx | 13 +- .../finance/employee-advance/columns.tsx | 19 ++- .../pages/admin/finance/expense/columns.tsx | 13 +- .../admin/finance/payroll-period/columns.tsx | 99 +++++++-------- .../js/pages/admin/hr/employee/columns.tsx | 17 ++- .../pages/admin/hr/leave-request/columns.tsx | 17 ++- .../admin/manage/cutting/cutting-card.tsx | 40 +++--- .../admin/manage/purchase/purchase-card.tsx | 40 +++--- .../admin/manage/restock/restock-card.tsx | 40 +++--- .../manage/transaction/transaction-card.tsx | 104 +++++++-------- .../pages/admin/master/category/columns.tsx | 13 +- .../pages/admin/master/customer/columns.tsx | 13 +- .../js/pages/admin/master/product/columns.tsx | 13 +- .../admin/master/product/product-card.tsx | 40 +++--- .../admin/master/product/variant/sub-row.tsx | 120 +++++++++--------- .../master/raw-material/raw-material-card.tsx | 40 +++--- .../master/raw-material/variant/sub-row.tsx | 74 ++++++----- .../pages/admin/master/supplier/columns.tsx | 13 +- resources/js/pages/admin/roles/columns.tsx | 13 +- 20 files changed, 423 insertions(+), 331 deletions(-) diff --git a/resources/js/pages/admin/finance/cash-account/columns.tsx b/resources/js/pages/admin/finance/cash-account/columns.tsx index da53382..c6754e9 100644 --- a/resources/js/pages/admin/finance/cash-account/columns.tsx +++ b/resources/js/pages/admin/finance/cash-account/columns.tsx @@ -20,7 +20,7 @@ export function createCashAccountColumns( ): ColumnDef[] { const { handleEdit, handleDeleteClick, can } = params; - return [ + const columns: ColumnDef[] = [ { accessorKey: 'name', header: () => Nama, @@ -39,7 +39,10 @@ export function createCashAccountColumns( ), }, - { + ]; + + if (can('cash.update') || can('cash.delete')) { + columns.push({ id: 'actions', header: () => Aksi, meta: { @@ -70,6 +73,8 @@ export function createCashAccountColumns( /> ); }, - }, - ]; + }); + } + + return columns; } diff --git a/resources/js/pages/admin/finance/cash-account/transaction-columns.tsx b/resources/js/pages/admin/finance/cash-account/transaction-columns.tsx index 142e14c..f0a0a9e 100644 --- a/resources/js/pages/admin/finance/cash-account/transaction-columns.tsx +++ b/resources/js/pages/admin/finance/cash-account/transaction-columns.tsx @@ -47,7 +47,7 @@ export function createTransactionColumns( ): ColumnDef[] { const { handleEdit, handleDeleteClick, can } = params; - return [ + const columns: ColumnDef[] = [ { accessorKey: 'formatted_created_at', header: () => Tanggal, @@ -136,7 +136,10 @@ export function createTransactionColumns( return {createdBy?.user_profile?.full_name ?? '-'}; }, }, - { + ]; + + if (can('cash.update') || can('cash.delete')) { + columns.push({ id: 'actions', header: () => Aksi, meta: { @@ -174,6 +177,8 @@ export function createTransactionColumns( /> ); }, - }, - ]; + }); + } + + return columns; } diff --git a/resources/js/pages/admin/finance/employee-advance/columns.tsx b/resources/js/pages/admin/finance/employee-advance/columns.tsx index 84a5f65..0c4e01f 100644 --- a/resources/js/pages/admin/finance/employee-advance/columns.tsx +++ b/resources/js/pages/admin/finance/employee-advance/columns.tsx @@ -91,7 +91,7 @@ export function createEmployeeAdvanceColumns( const { handleEdit, handleDeleteClick, handleApprove, handlePay, handleShowPayments, can, authUserId } = params; - return [ + const columns: ColumnDef[] = [ { accessorKey: 'formatted_created_at', header: () => Tanggal, @@ -162,7 +162,16 @@ export function createEmployeeAdvanceColumns( {getStatusBadge(row.getValue('status') as string)} ), }, - { + ]; + + 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: () => Aksi, meta: { @@ -226,6 +235,8 @@ export function createEmployeeAdvanceColumns( /> ); }, - }, - ]; + }); + } + + return columns; } diff --git a/resources/js/pages/admin/finance/expense/columns.tsx b/resources/js/pages/admin/finance/expense/columns.tsx index b41a9ee..9191b58 100644 --- a/resources/js/pages/admin/finance/expense/columns.tsx +++ b/resources/js/pages/admin/finance/expense/columns.tsx @@ -30,7 +30,7 @@ export function createExpenseColumns( ): ColumnDef[] { const { handleEdit, handleDeleteClick, can } = params; - return [ + const columns: ColumnDef[] = [ { accessorKey: 'formatted_created_at', header: () => Tanggal, @@ -83,7 +83,10 @@ export function createExpenseColumns( return {createdBy?.user_profile?.full_name ?? '-'}; }, }, - { + ]; + + if (can('expenses.update') || can('expenses.delete')) { + columns.push({ id: 'actions', header: () => Aksi, meta: { @@ -114,6 +117,8 @@ export function createExpenseColumns( /> ); }, - }, - ]; + }); + } + + return columns; } diff --git a/resources/js/pages/admin/finance/payroll-period/columns.tsx b/resources/js/pages/admin/finance/payroll-period/columns.tsx index 329a599..0dfd43c 100644 --- a/resources/js/pages/admin/finance/payroll-period/columns.tsx +++ b/resources/js/pages/admin/finance/payroll-period/columns.tsx @@ -174,58 +174,57 @@ export function createPayrollPeriodColumns( }); } - columns.push( - { - accessorKey: 'status', - header: () => Status, - cell: ({ row }) => ( - {getStatusBadge(row.getValue('status') as string)} - ), - }, - { - id: 'actions', - header: () => Aksi, - meta: { - className: 'w-[100px] text-center', - headerClassName: 'w-[100px] text-center', - }, - cell: ({ row }) => { - const period = row.original; + columns.push({ + accessorKey: 'status', + header: () => Status, + cell: ({ row }) => ( + {getStatusBadge(row.getValue('status') as string)} + ), + }); - return ( - , - href: showUrl(period.id), - }, - { - label: 'Tutup Periode', - icon: ( - - ), - show: - can('payroll.adjust') && - period.status === 'open', - onClick: () => handleClose(period), - }, - { - label: 'Buka Periode', - icon: ( - - ), - show: - can('payroll.adjust') && - period.status === 'closed', - onClick: () => handleReopen(period), - }, - ]} - /> - ); - }, + columns.push({ + id: 'actions', + header: () => Aksi, + meta: { + className: 'w-[100px] text-center', + headerClassName: 'w-[100px] text-center', }, - ); + cell: ({ row }) => { + const period = row.original; + + return ( + , + href: showUrl(period.id), + }, + { + label: 'Tutup Periode', + icon: ( + + ), + show: + can('payroll.adjust') && + period.status === 'open', + onClick: () => handleClose(period), + }, + { + label: 'Buka Periode', + icon: ( + + ), + show: + can('payroll.adjust') && + period.status === 'closed', + onClick: () => handleReopen(period), + }, + ]} + /> + ); + }, + }); return columns; } diff --git a/resources/js/pages/admin/hr/employee/columns.tsx b/resources/js/pages/admin/hr/employee/columns.tsx index 959a5ec..17008a9 100644 --- a/resources/js/pages/admin/hr/employee/columns.tsx +++ b/resources/js/pages/admin/hr/employee/columns.tsx @@ -54,7 +54,7 @@ export function createEmployeeColumns( canViewAll, } = params; - return [ + const columns: ColumnDef[] = [ { 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: () => Aksi, meta: { @@ -193,6 +200,8 @@ export function createEmployeeColumns( /> ); }, - }, - ]; + }); + } + + return columns; } diff --git a/resources/js/pages/admin/hr/leave-request/columns.tsx b/resources/js/pages/admin/hr/leave-request/columns.tsx index 68d41f3..13d6632 100644 --- a/resources/js/pages/admin/hr/leave-request/columns.tsx +++ b/resources/js/pages/admin/hr/leave-request/columns.tsx @@ -64,7 +64,7 @@ export function createLeaveRequestColumns( const { handleEdit, handleDeleteClick, handleApprove, handleReject, can } = params; - return [ + const columns: ColumnDef[] = [ { id: 'employee_name', header: () => Oleh, @@ -112,7 +112,14 @@ export function createLeaveRequestColumns( {getStatusBadge(row.getValue('status') as string)} ), }, - { + ]; + + if ( + can('leave_requests.verify') || + can('leave_requests.update') || + can('leave_requests.delete') + ) { + columns.push({ id: 'actions', header: () => Aksi, meta: { @@ -167,6 +174,8 @@ export function createLeaveRequestColumns( /> ); }, - }, - ]; + }); + } + + return columns; } diff --git a/resources/js/pages/admin/manage/cutting/cutting-card.tsx b/resources/js/pages/admin/manage/cutting/cutting-card.tsx index 4e8172b..ae74580 100644 --- a/resources/js/pages/admin/manage/cutting/cutting-card.tsx +++ b/resources/js/pages/admin/manage/cutting/cutting-card.tsx @@ -139,25 +139,27 @@ export function CuttingCardRow({ )} - , - show: can('cuttings.update'), - onClick: () => onEdit(cutting), - }, - { - label: 'Hapus', - icon: ( - - ), - show: can('cuttings.delete'), - onClick: () => onDelete(cutting), - }, - ]} - wrapperClassName="flex shrink-0 items-center gap-1" - /> + {(can('cuttings.update') || can('cuttings.delete')) && ( + , + show: can('cuttings.update'), + onClick: () => onEdit(cutting), + }, + { + label: 'Hapus', + icon: ( + + ), + show: can('cuttings.delete'), + onClick: () => onDelete(cutting), + }, + ]} + wrapperClassName="flex shrink-0 items-center gap-1" + /> + )} diff --git a/resources/js/pages/admin/manage/purchase/purchase-card.tsx b/resources/js/pages/admin/manage/purchase/purchase-card.tsx index 0028f2b..ce6e599 100644 --- a/resources/js/pages/admin/manage/purchase/purchase-card.tsx +++ b/resources/js/pages/admin/manage/purchase/purchase-card.tsx @@ -126,25 +126,27 @@ export function PurchaseCardRow({ )} - , - show: can('purchases.update'), - onClick: () => onEdit(purchase), - }, - { - label: 'Hapus', - icon: ( - - ), - show: can('purchases.delete'), - onClick: () => onDelete(purchase), - }, - ]} - wrapperClassName="flex shrink-0 items-center gap-1" - /> + {(can('purchases.update') || can('purchases.delete')) && ( + , + show: can('purchases.update'), + onClick: () => onEdit(purchase), + }, + { + label: 'Hapus', + icon: ( + + ), + show: can('purchases.delete'), + onClick: () => onDelete(purchase), + }, + ]} + wrapperClassName="flex shrink-0 items-center gap-1" + /> + )} diff --git a/resources/js/pages/admin/manage/restock/restock-card.tsx b/resources/js/pages/admin/manage/restock/restock-card.tsx index b810235..12b4435 100644 --- a/resources/js/pages/admin/manage/restock/restock-card.tsx +++ b/resources/js/pages/admin/manage/restock/restock-card.tsx @@ -135,25 +135,27 @@ export function RestockCardRow({ - , - show: can('restocks.update'), - onClick: () => onEdit(restock), - }, - { - label: 'Hapus', - icon: ( - - ), - show: can('restocks.delete'), - onClick: () => onDelete(restock), - }, - ]} - wrapperClassName="flex shrink-0 items-center gap-1" - /> + {(can('restocks.update') || can('restocks.delete')) && ( + , + show: can('restocks.update'), + onClick: () => onEdit(restock), + }, + { + label: 'Hapus', + icon: ( + + ), + show: can('restocks.delete'), + onClick: () => onDelete(restock), + }, + ]} + wrapperClassName="flex shrink-0 items-center gap-1" + /> + )} diff --git a/resources/js/pages/admin/manage/transaction/transaction-card.tsx b/resources/js/pages/admin/manage/transaction/transaction-card.tsx index faec082..0fa6e6d 100644 --- a/resources/js/pages/admin/manage/transaction/transaction-card.tsx +++ b/resources/js/pages/admin/manage/transaction/transaction-card.tsx @@ -183,57 +183,59 @@ export function TransactionCardRow({ - , - onClick: () => onUpdateStatus(transaction, 'processing'), - }, - ] - : []), - ...((transaction.status === 'pending' || transaction.status === 'processing') && can('orders.update') - ? [ - { - label: 'Selesai', - icon: , - onClick: () => onUpdateStatus(transaction, 'completed'), - }, - { - label: 'Dibatalkan', - icon: , - onClick: () => onUpdateStatus(transaction, 'cancelled'), - }, - ] - : []), - ...(transaction.status === 'completed' && can('orders.update') - ? [ - { - label: 'Refund', - icon: , - onClick: () => onUpdateStatus(transaction, 'refunded'), - }, - ] - : []), - { - label: 'Edit', - icon: , - show: can('orders.update'), - onClick: () => onEdit(transaction), - }, - { - label: 'Hapus', - icon: ( - - ), - show: can('orders.delete'), - onClick: () => onDelete(transaction), - }, - ]} - wrapperClassName="flex shrink-0 items-center gap-1" - /> + {(can('orders.update') || can('orders.delete')) && ( + , + onClick: () => onUpdateStatus(transaction, 'processing'), + }, + ] + : []), + ...((transaction.status === 'pending' || transaction.status === 'processing') && can('orders.update') + ? [ + { + label: 'Selesai', + icon: , + onClick: () => onUpdateStatus(transaction, 'completed'), + }, + { + label: 'Dibatalkan', + icon: , + onClick: () => onUpdateStatus(transaction, 'cancelled'), + }, + ] + : []), + ...(transaction.status === 'completed' && can('orders.update') + ? [ + { + label: 'Refund', + icon: , + onClick: () => onUpdateStatus(transaction, 'refunded'), + }, + ] + : []), + { + label: 'Edit', + icon: , + show: can('orders.update'), + onClick: () => onEdit(transaction), + }, + { + label: 'Hapus', + icon: ( + + ), + show: can('orders.delete'), + onClick: () => onDelete(transaction), + }, + ]} + wrapperClassName="flex shrink-0 items-center gap-1" + /> + )} diff --git a/resources/js/pages/admin/master/category/columns.tsx b/resources/js/pages/admin/master/category/columns.tsx index 5ee4748..1ae06c9 100644 --- a/resources/js/pages/admin/master/category/columns.tsx +++ b/resources/js/pages/admin/master/category/columns.tsx @@ -18,7 +18,7 @@ export function createCategoryColumns( ): ColumnDef[] { const { handleEdit, handleDeleteClick, can } = params; - return [ + const columns: ColumnDef[] = [ { accessorKey: 'name', header: () => Nama, @@ -28,7 +28,10 @@ export function createCategoryColumns( ), }, - { + ]; + + if (can('categories.update') || can('categories.delete')) { + columns.push({ id: 'actions', header: () => Aksi, meta: { @@ -59,6 +62,8 @@ export function createCategoryColumns( /> ); }, - }, - ]; + }); + } + + return columns; } diff --git a/resources/js/pages/admin/master/customer/columns.tsx b/resources/js/pages/admin/master/customer/columns.tsx index de9353a..eb2cabd 100644 --- a/resources/js/pages/admin/master/customer/columns.tsx +++ b/resources/js/pages/admin/master/customer/columns.tsx @@ -20,7 +20,7 @@ export function createCustomerColumns( ): ColumnDef[] { const { handleEdit, handleDeleteClick, can } = params; - return [ + const columns: ColumnDef[] = [ { accessorKey: 'name', header: () => Nama, @@ -46,7 +46,10 @@ export function createCustomerColumns( ), }, - { + ]; + + if (can('customers.update') || can('customers.delete')) { + columns.push({ id: 'actions', header: () => Aksi, meta: { @@ -77,6 +80,8 @@ export function createCustomerColumns( /> ); }, - }, - ]; + }); + } + + return columns; } diff --git a/resources/js/pages/admin/master/product/columns.tsx b/resources/js/pages/admin/master/product/columns.tsx index 89c7536..f88f78d 100644 --- a/resources/js/pages/admin/master/product/columns.tsx +++ b/resources/js/pages/admin/master/product/columns.tsx @@ -90,7 +90,7 @@ export function createProductColumns( can, } = params; - return [ + const columns: ColumnDef[] = [ { id: 'expand', header: '', @@ -338,7 +338,10 @@ export function createProductColumns( ); }, }, - { + ]; + + if (can('products.update') || can('products.delete')) { + columns.push({ id: 'actions', header: () => Aksi, meta: { @@ -369,6 +372,8 @@ export function createProductColumns( /> ); }, - }, - ]; + }); + } + + return columns; } diff --git a/resources/js/pages/admin/master/product/product-card.tsx b/resources/js/pages/admin/master/product/product-card.tsx index 8815b83..5867867 100644 --- a/resources/js/pages/admin/master/product/product-card.tsx +++ b/resources/js/pages/admin/master/product/product-card.tsx @@ -144,25 +144,27 @@ export function ProductCardRow({ - , - show: can('products.update'), - onClick: () => onEdit(product), - }, - { - label: 'Hapus', - icon: ( - - ), - show: can('products.delete'), - onClick: () => onDelete(product), - }, - ]} - wrapperClassName="flex shrink-0 items-center gap-1" - /> + {(can('products.update') || can('products.delete')) && ( + , + show: can('products.update'), + onClick: () => onEdit(product), + }, + { + label: 'Hapus', + icon: ( + + ), + show: can('products.delete'), + onClick: () => onDelete(product), + }, + ]} + wrapperClassName="flex shrink-0 items-center gap-1" + /> + )} diff --git a/resources/js/pages/admin/master/product/variant/sub-row.tsx b/resources/js/pages/admin/master/product/variant/sub-row.tsx index 1042938..d708274 100644 --- a/resources/js/pages/admin/master/product/variant/sub-row.tsx +++ b/resources/js/pages/admin/master/product/variant/sub-row.tsx @@ -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 (
@@ -52,16 +54,18 @@ export function VariantSubRow({ Stok EcerHarga - - Aksi - + {canAnyAction && ( + + Aksi + + )} {variants.length === 0 ? ( Tidak ada varian. @@ -116,63 +120,65 @@ export function VariantSubRow({ '-' )} - - - ), - show: can('products.transfer_stock'), - onClick: () => - setTransferVariant({ - product, - variant, - }), - }, - { - label: 'Mutasi Stok', - icon: ( - - ), - show: can('products.view_stock_mutations'), - onClick: () => { - router.visit( - stockMutations.url({ - product: product.id, - variant: variant.id, + {canAnyAction && ( + + + ), + show: can('products.transfer_stock'), + onClick: () => + setTransferVariant({ + product, + variant, }), - ); }, - }, - { - label: 'Edit', - icon: ( - - ), - show: can('products.update'), - onClick: () => - onEditVariant( - product, - variant, + { + label: 'Mutasi Stok', + icon: ( + ), - }, - { - label: 'Hapus', - icon: ( - - ), - 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: ( + ), - }, - ]} - /> - + show: can('products.update'), + onClick: () => + onEditVariant( + product, + variant, + ), + }, + { + label: 'Hapus', + icon: ( + + ), + show: can('products.delete'), + onClick: () => + onDeleteVariantClick( + product, + variant, + ), + }, + ]} + /> + + )} )) )} diff --git a/resources/js/pages/admin/master/raw-material/raw-material-card.tsx b/resources/js/pages/admin/master/raw-material/raw-material-card.tsx index eadeeb2..b02cc68 100644 --- a/resources/js/pages/admin/master/raw-material/raw-material-card.tsx +++ b/resources/js/pages/admin/master/raw-material/raw-material-card.tsx @@ -94,25 +94,27 @@ export function RawMaterialCardRow({ - , - show: can('raw_materials.update'), - onClick: () => onEdit(rawMaterial), - }, - { - label: 'Hapus', - icon: ( - - ), - show: can('raw_materials.delete'), - onClick: () => onDelete(rawMaterial), - }, - ]} - wrapperClassName="flex shrink-0 items-center gap-1" - /> + {(can('raw_materials.update') || can('raw_materials.delete')) && ( + , + show: can('raw_materials.update'), + onClick: () => onEdit(rawMaterial), + }, + { + label: 'Hapus', + icon: ( + + ), + show: can('raw_materials.delete'), + onClick: () => onDelete(rawMaterial), + }, + ]} + wrapperClassName="flex shrink-0 items-center gap-1" + /> + )} diff --git a/resources/js/pages/admin/master/raw-material/variant/sub-row.tsx b/resources/js/pages/admin/master/raw-material/variant/sub-row.tsx index 7d09d3f..fa4ba8d 100644 --- a/resources/js/pages/admin/master/raw-material/variant/sub-row.tsx +++ b/resources/js/pages/admin/master/raw-material/variant/sub-row.tsx @@ -47,6 +47,8 @@ export function RawMaterialVariantSubRow({ ); } + const canAnyAction = can('raw_materials.update') || can('raw_materials.delete'); + return (
@@ -59,16 +61,18 @@ export function RawMaterialVariantSubRow({ Nama VarianHargaStok - - Aksi - + {canAnyAction && ( + + Aksi + + )} {variants.length === 0 ? ( Tidak ada varian. @@ -101,37 +105,39 @@ export function RawMaterialVariantSubRow({ {formatNumber(variant.stock)} - - - ), - show: can('raw_materials.update'), - onClick: () => { - router.visit( - variantEdit.url({ - rawMaterial: - rawMaterial.id, - variant: variant.id, - }), - ); + {canAnyAction && ( + + + ), + show: can('raw_materials.update'), + onClick: () => { + router.visit( + variantEdit.url({ + rawMaterial: + rawMaterial.id, + variant: variant.id, + }), + ); + }, }, - }, - { - label: 'Hapus', - icon: ( - - ), - show: can('raw_materials.delete'), - onClick: () => - setDeletingVariant(variant), - }, - ]} - /> - + { + label: 'Hapus', + icon: ( + + ), + show: can('raw_materials.delete'), + onClick: () => + setDeletingVariant(variant), + }, + ]} + /> + + )} )) )} diff --git a/resources/js/pages/admin/master/supplier/columns.tsx b/resources/js/pages/admin/master/supplier/columns.tsx index d4c2061..ef0a092 100644 --- a/resources/js/pages/admin/master/supplier/columns.tsx +++ b/resources/js/pages/admin/master/supplier/columns.tsx @@ -20,7 +20,7 @@ export function createSupplierColumns( ): ColumnDef[] { const { handleEdit, handleDeleteClick, can } = params; - return [ + const columns: ColumnDef[] = [ { accessorKey: 'name', header: () => Nama, @@ -46,7 +46,10 @@ export function createSupplierColumns( ), }, - { + ]; + + if (can('suppliers.update') || can('suppliers.delete')) { + columns.push({ id: 'actions', header: () => Aksi, meta: { @@ -77,6 +80,8 @@ export function createSupplierColumns( /> ); }, - }, - ]; + }); + } + + return columns; } diff --git a/resources/js/pages/admin/roles/columns.tsx b/resources/js/pages/admin/roles/columns.tsx index 695a8fe..c5427bd 100644 --- a/resources/js/pages/admin/roles/columns.tsx +++ b/resources/js/pages/admin/roles/columns.tsx @@ -19,7 +19,7 @@ export function createRoleColumns( ): ColumnDef[] { const { handleEdit, handleDeleteClick, can } = params; - return [ + const columns: ColumnDef[] = [ { accessorKey: 'name', header: () => Nama Role, @@ -44,7 +44,10 @@ export function createRoleColumns( ), }, - { + ]; + + if (can('roles.update') || can('roles.delete')) { + columns.push({ id: 'actions', header: () => Aksi, meta: { @@ -75,6 +78,8 @@ export function createRoleColumns( /> ); }, - }, - ]; + }); + } + + return columns; }