feat(FE-331): implement permission guard in purchase

This commit is contained in:
ValdiANS
2025-12-26 16:21:22 +07:00
parent 1152cd2bef
commit 4be719b9d8
3 changed files with 128 additions and 88 deletions
@@ -15,6 +15,7 @@ import SelectInput, { OptionType } from '@/components/input/SelectInput';
import RowDropdownOptions from '@/components/table/RowDropdownOptions';
import RowCollapseOptions from '@/components/table/RowCollapseOptions';
import RowOptionsMenuWrapper from '@/components/table/RowOptionsMenuWrapper';
import RequirePermission from '@/components/helper/RequirePermission';
import { cn, formatDate } from '@/lib/helper';
import { isResponseSuccess } from '@/lib/api-helper';
@@ -38,6 +39,7 @@ const RowOptionsMenu = ({
}: RowOptionsMenuProps) => {
return (
<RowOptionsMenuWrapper type={type}>
<RequirePermission permissions='lti.purchase.detail'>
<Button
href={`/purchase/detail/?purchaseId=${props.row.original.id}`}
variant='ghost'
@@ -47,6 +49,7 @@ const RowOptionsMenu = ({
<Icon icon='mdi:eye-outline' width={16} height={16} />
Detail
</Button>
</RequirePermission>
{/*<Button*/}
{/* href={`/purchase/detail/edit/?purchaseId=${props.row.original.id}`}*/}
@@ -58,6 +61,7 @@ const RowOptionsMenu = ({
{/* Edit*/}
{/*</Button>*/}
<RequirePermission permissions='lti.purchase.delete'>
<Button
onClick={deleteClickHandler}
variant='ghost'
@@ -72,6 +76,7 @@ const RowOptionsMenu = ({
/>
Delete
</Button>
</RequirePermission>
</RowOptionsMenuWrapper>
);
};
@@ -227,6 +232,7 @@ const PurchaseTable = () => {
<div className='flex flex-col gap-2 mb-4'>
<div className='w-full flex flex-col xl:flex-row justify-between items-end xl:items-center gap-2'>
<div className='w-full flex flex-row gap-2'>
<RequirePermission permissions='lti.purchase.create'>
<Button
href='/purchase/add'
variant='outline'
@@ -236,6 +242,7 @@ const PurchaseTable = () => {
<Icon icon='ic:round-plus' width={24} height={24} />
Tambah
</Button>
</RequirePermission>
</div>
<DebouncedTextInput
@@ -32,6 +32,7 @@ import {
} from '@/types/api/purchase/purchase';
import { BaseApproval, BaseGroupedApproval } from '@/types/api/api-general';
import { useRouter } from 'next/navigation';
import RequirePermission from '@/components/helper/RequirePermission';
interface PurchaseOrderStaffApprovalFormProps {
type?: 'add' | 'edit';
@@ -897,11 +898,15 @@ const PurchaseOrderStaffApprovalForm = ({
<div className='flex justify-center'>
{canUpdatePurchaseItems &&
canShowDeleteAddButtons && (
<RequirePermission permissions='lti.purchase.delete.item'>
<Button
type='button'
color='error'
className='text-sm w-fit'
onClick={() =>
removePurchaseItem(formItemIndex)
removePurchaseItem(
formItemIndex
)
}
title='Hapus item'
>
@@ -911,6 +916,7 @@ const PurchaseOrderStaffApprovalForm = ({
height={16}
/>
</Button>
</RequirePermission>
)}
</div>
</td>
@@ -39,10 +39,12 @@ import { toast } from 'react-hot-toast';
import { useSearchParams } from 'next/navigation';
import { formatCurrency, formatNumber, formatDate } from '@/lib/helper';
import { PURCHASE_ORDER_APPROVAL_LINE } from '@/config/approval-line';
import RequirePermission from '@/components/helper/RequirePermission';
const ItemPembelianDropdown = ({ onEdit }: { onEdit: () => void }) => {
return (
<RowOptionsMenuWrapper type='dropdown'>
<RequirePermission permissions='lti.purchase.update'>
<Button
onClick={onEdit}
variant='ghost'
@@ -52,6 +54,7 @@ const ItemPembelianDropdown = ({ onEdit }: { onEdit: () => void }) => {
<Icon icon='material-symbols:edit-outline' width={16} height={16} />
Edit
</Button>
</RequirePermission>
</RowOptionsMenuWrapper>
);
};
@@ -59,6 +62,7 @@ const ItemPembelianDropdown = ({ onEdit }: { onEdit: () => void }) => {
const PenerimaanBarangDropdown = ({ onEdit }: { onEdit: () => void }) => {
return (
<RowOptionsMenuWrapper type='dropdown'>
<RequirePermission permissions='lti.purchase.receive'>
<Button
onClick={onEdit}
variant='ghost'
@@ -68,6 +72,7 @@ const PenerimaanBarangDropdown = ({ onEdit }: { onEdit: () => void }) => {
<Icon icon='material-symbols:edit-outline' width={16} height={16} />
Edit
</Button>
</RequirePermission>
</RowOptionsMenuWrapper>
);
};
@@ -496,6 +501,7 @@ const PurchaseOrderDetail = ({
};
return (
<RequirePermission permissions='lti.purchase.delete.item'>
<Button
type='button'
color='error'
@@ -504,6 +510,7 @@ const PurchaseOrderDetail = ({
>
<Icon icon='mdi:trash-can' width={16} height={16} />
</Button>
</RequirePermission>
);
},
},
@@ -632,6 +639,15 @@ const PurchaseOrderDetail = ({
{showApprovalButton && (
<div className='flex flex-row gap-2'>
<RequirePermission
permissions={
approvalStep === 1
? 'lti.purchase.approve.staff'
: approvalStep === 2
? 'lti.purchase.approve.manager'
: 'lti.purchase.receive'
}
>
<Button
onClick={handleApprovalClick}
variant='outline'
@@ -641,7 +657,17 @@ const PurchaseOrderDetail = ({
<Icon icon='material-symbols:check' width={24} height={24} />
Approve
</Button>
</RequirePermission>
<RequirePermission
permissions={
approvalStep === 1
? 'lti.purchase.approve.staff'
: approvalStep === 2
? 'lti.purchase.approve.manager'
: 'lti.purchase.receive'
}
>
<Button
variant='outline'
color='error'
@@ -651,6 +677,7 @@ const PurchaseOrderDetail = ({
<Icon icon='material-symbols:close' width={24} height={24} />
Reject
</Button>
</RequirePermission>
</div>
)}
</div>