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

This commit is contained in:
ValdiANS
2025-12-27 14:34:59 +07:00
parent 9e0d3e2bbf
commit 507c4005af
2 changed files with 177 additions and 143 deletions
@@ -6,6 +6,7 @@ import useSWR from 'swr';
import { Icon } from '@iconify/react';
import { SortingState, CellContext } from '@tanstack/react-table';
import { cn, formatDate } from '@/lib/helper';
import RequirePermission from '@/components/helper/RequirePermission';
import { useModal } from '@/components/Modal';
import Modal from '@/components/Modal';
import Button from '@/components/Button';
@@ -59,6 +60,7 @@ const RowOptionsMenu = ({
return (
<RowOptionsMenuWrapper type={type}>
<RequirePermission permissions='lti.production.recording.detail'>
<Button
href={`/production/recording/detail/?recordingId=${props.row.original.id}`}
variant='ghost'
@@ -68,6 +70,8 @@ const RowOptionsMenu = ({
<Icon icon='mdi:eye-outline' width={16} height={16} />
Detail
</Button>
</RequirePermission>
<RequirePermission permissions='lti.production.recording.update'>
<Button
href={`/production/recording/detail/edit/?recordingId=${props.row.original.id}`}
variant='ghost'
@@ -77,7 +81,9 @@ const RowOptionsMenu = ({
<Icon icon='mdi:pencil-outline' width={16} height={16} />
Edit
</Button>
</RequirePermission>
{!isApproved && !isRejected && (
<RequirePermission permissions='lti.production.recording.approve'>
<Button
onClick={approveClickHandler}
variant='ghost'
@@ -87,8 +93,10 @@ const RowOptionsMenu = ({
<Icon icon='material-symbols:check' width={16} height={16} />
Approve
</Button>
</RequirePermission>
)}
{!isApproved && !isRejected && (
<RequirePermission permissions='lti.production.recording.approve'>
<Button
onClick={rejectClickHandler}
variant='ghost'
@@ -98,7 +106,9 @@ const RowOptionsMenu = ({
<Icon icon='material-symbols:close' width={16} height={16} />
Reject
</Button>
</RequirePermission>
)}
<RequirePermission permissions='lti.production.recording.delete'>
<Button
onClick={deleteClickHandler}
variant='ghost'
@@ -113,6 +123,7 @@ const RowOptionsMenu = ({
/>
Delete
</Button>
</RequirePermission>
</RowOptionsMenuWrapper>
);
};
@@ -514,6 +525,7 @@ const RecordingTable = () => {
<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 sm:w-fit flex flex-col sm:flex-row self-start gap-2'>
<RequirePermission permissions='lti.production.recording.create'>
<Button
href='/production/recording/add'
variant='outline'
@@ -523,9 +535,11 @@ const RecordingTable = () => {
<Icon icon='ic:round-plus' width={24} height={24} />
Tambah
</Button>
</RequirePermission>
{selectedRowIds.length > 0 && (
<>
<RequirePermission permissions='lti.production.recording.approve'>
<Button
variant='outline'
color='success'
@@ -538,10 +552,16 @@ const RecordingTable = () => {
}
className='w-full sm:w-fit'
>
<Icon icon='material-symbols:check' width={24} height={24} />
<Icon
icon='material-symbols:check'
width={24}
height={24}
/>
Approve
</Button>
</RequirePermission>
<RequirePermission permissions='lti.production.recording.approve'>
<Button
variant='outline'
color='error'
@@ -554,9 +574,14 @@ const RecordingTable = () => {
}
className='w-full sm:w-fit'
>
<Icon icon='material-symbols:close' width={24} height={24} />
<Icon
icon='material-symbols:close'
width={24}
height={24}
/>
Reject
</Button>
</RequirePermission>
</>
)}
</div>
@@ -8,6 +8,7 @@ import useSWR from 'swr';
import { Icon } from '@iconify/react';
import Button from '@/components/Button';
import RequirePermission from '@/components/helper/RequirePermission';
import Card from '@/components/Card';
import Badge from '@/components/Badge';
import NumberInput from '@/components/input/NumberInput';
@@ -1492,6 +1493,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
!isRecordingApproved(initialValues) &&
!isRecordingRejected(initialValues) && (
<div className='flex flex-row gap-2'>
<RequirePermission permissions='lti.production.recording.approve'>
<Button
variant='outline'
color='success'
@@ -1509,7 +1511,9 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
/>
Approve
</Button>
</RequirePermission>
<RequirePermission permissions='lti.production.recording.approve'>
<Button
variant='outline'
color='error'
@@ -1527,6 +1531,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
/>
Reject
</Button>
</RequirePermission>
</div>
)}
</div>
@@ -2696,6 +2701,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
{/* Left side - Detail & Edit actions */}
<div className='flex flex-col sm:flex-row justify-start gap-2 w-full sm:w-auto'>
{type === 'detail' && deleteRecordingClickHandler && (
<RequirePermission permissions='lti.production.recording.delete'>
<Button
type='button'
color='error'
@@ -2710,8 +2716,10 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
/>
Delete
</Button>
</RequirePermission>
)}
{type === 'detail' && initialValues && (
<RequirePermission permissions='lti.production.recording.update'>
<Button
type='button'
color='warning'
@@ -2726,6 +2734,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
/>
Edit
</Button>
</RequirePermission>
)}
</div>
{/* Right side actions */}