mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
feat(FE-331): implement permission guard in marketing
This commit is contained in:
@@ -26,6 +26,8 @@ import { useRouter } from 'next/navigation';
|
|||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import toast from 'react-hot-toast';
|
import toast from 'react-hot-toast';
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
|
import RequirePermission from '@/components/helper/RequirePermission';
|
||||||
|
import { useAuth } from '@/services/hooks/useAuth';
|
||||||
|
|
||||||
const RowsOptionsMenu = ({
|
const RowsOptionsMenu = ({
|
||||||
type = 'dropdown',
|
type = 'dropdown',
|
||||||
@@ -50,57 +52,71 @@ const RowsOptionsMenu = ({
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className='flex flex-col gap-1'>
|
<div className='flex flex-col gap-1'>
|
||||||
<Button
|
<RequirePermission permissions='lti.marketing.delivery_order.detail'>
|
||||||
href={`/marketing/detail?marketingId=${props.row.original.id}`}
|
|
||||||
variant='ghost'
|
|
||||||
color='primary'
|
|
||||||
className='justify-start text-sm'
|
|
||||||
>
|
|
||||||
<Icon icon='mdi:eye-outline' width={16} height={16} />
|
|
||||||
Detail
|
|
||||||
</Button>
|
|
||||||
{props.row.original.latest_approval.step_number != 1 && (
|
|
||||||
<Button
|
<Button
|
||||||
href={
|
href={`/marketing/detail?marketingId=${props.row.original.id}`}
|
||||||
props.row.original.latest_approval.step_number == 3
|
|
||||||
? `/marketing/detail/delivery-orders/edit?marketingId=${props.row.original.id}`
|
|
||||||
: props.row.original.latest_approval.step_number == 2
|
|
||||||
? `/marketing/add/delivery-orders?marketingId=${props.row.original.id}`
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
onClick={() => {
|
|
||||||
if (props.row.original.latest_approval.step_number == 2) {
|
|
||||||
deliveryClickHandler?.();
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
variant='ghost'
|
variant='ghost'
|
||||||
color='success'
|
color='primary'
|
||||||
className='justify-start text-sm'
|
className='justify-start text-sm'
|
||||||
>
|
>
|
||||||
<Icon icon='mdi:truck' width={16} height={16} />
|
<Icon icon='mdi:eye-outline' width={16} height={16} />
|
||||||
Deliver
|
Detail
|
||||||
</Button>
|
</Button>
|
||||||
|
</RequirePermission>
|
||||||
|
{props.row.original.latest_approval.step_number != 1 && (
|
||||||
|
<RequirePermission
|
||||||
|
permissions={
|
||||||
|
props.row.original.latest_approval.step_number == 3
|
||||||
|
? 'lti.marketing.delivery_order.update'
|
||||||
|
: 'lti.marketing.delivery_order.create'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
href={
|
||||||
|
props.row.original.latest_approval.step_number == 3
|
||||||
|
? `/marketing/detail/delivery-orders/edit?marketingId=${props.row.original.id}`
|
||||||
|
: props.row.original.latest_approval.step_number == 2
|
||||||
|
? `/marketing/add/delivery-orders?marketingId=${props.row.original.id}`
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
onClick={() => {
|
||||||
|
if (props.row.original.latest_approval.step_number == 2) {
|
||||||
|
deliveryClickHandler?.();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
variant='ghost'
|
||||||
|
color='success'
|
||||||
|
className='justify-start text-sm'
|
||||||
|
>
|
||||||
|
<Icon icon='mdi:truck' width={16} height={16} />
|
||||||
|
Deliver
|
||||||
|
</Button>
|
||||||
|
</RequirePermission>
|
||||||
)}
|
)}
|
||||||
{props.row.original.latest_approval.step_number != 3 && (
|
{props.row.original.latest_approval.step_number != 3 && (
|
||||||
<Button
|
<RequirePermission permissions='lti.marketing.sales_order.update'>
|
||||||
href={`/marketing/detail/sales-orders/edit?marketingId=${props.row.original.id}`}
|
<Button
|
||||||
variant='ghost'
|
href={`/marketing/detail/sales-orders/edit?marketingId=${props.row.original.id}`}
|
||||||
color='warning'
|
variant='ghost'
|
||||||
className='justify-start text-sm'
|
color='warning'
|
||||||
>
|
className='justify-start text-sm'
|
||||||
<Icon icon='mdi:pencil-outline' width={16} height={16} />
|
>
|
||||||
Edit
|
<Icon icon='mdi:pencil-outline' width={16} height={16} />
|
||||||
</Button>
|
Edit
|
||||||
|
</Button>
|
||||||
|
</RequirePermission>
|
||||||
)}
|
)}
|
||||||
<Button
|
<RequirePermission permissions='lti.marketing.sales_order.delete'>
|
||||||
onClick={deleteClickHandler}
|
<Button
|
||||||
variant='ghost'
|
onClick={deleteClickHandler}
|
||||||
color='error'
|
variant='ghost'
|
||||||
className='text-error hover:text-inherit justify-start text-sm'
|
color='error'
|
||||||
>
|
className='text-error hover:text-inherit justify-start text-sm'
|
||||||
<Icon icon='mdi:delete-outline' width={16} height={16} />
|
>
|
||||||
Delete
|
<Icon icon='mdi:delete-outline' width={16} height={16} />
|
||||||
</Button>
|
Delete
|
||||||
|
</Button>
|
||||||
|
</RequirePermission>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -116,6 +132,7 @@ const MarketingTable = () => {
|
|||||||
);
|
);
|
||||||
const [selectedItem, setSelectedItem] = useState<Marketing | null>(null);
|
const [selectedItem, setSelectedItem] = useState<Marketing | null>(null);
|
||||||
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
|
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
|
||||||
|
const { permissionCheck } = useAuth();
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
@@ -270,10 +287,14 @@ const MarketingTable = () => {
|
|||||||
<div className='flex flex-col gap-4'>
|
<div className='flex flex-col gap-4'>
|
||||||
<div className='flex flex-col gap-2 mb-4'>
|
<div className='flex flex-col gap-2 mb-4'>
|
||||||
<TableToolbar
|
<TableToolbar
|
||||||
addButton={{
|
addButton={
|
||||||
href: '/marketing/add/sales-orders',
|
permissionCheck('lti.marketing.sales_order.create')
|
||||||
label: 'Tambah Sales Order',
|
? {
|
||||||
}}
|
href: '/marketing/add/sales-orders',
|
||||||
|
label: 'Tambah Sales Order',
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
search={{
|
search={{
|
||||||
value: search,
|
value: search,
|
||||||
onChange: searchChangeHandler,
|
onChange: searchChangeHandler,
|
||||||
@@ -281,25 +302,29 @@ const MarketingTable = () => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div className='flex flex-row gap-2'>
|
<div className='flex flex-row gap-2'>
|
||||||
<Button
|
<RequirePermission permissions='lti.marketing.sales_order.approve'>
|
||||||
color='success'
|
<Button
|
||||||
onClick={approveClickHandler}
|
color='success'
|
||||||
className='justify-start text-sm'
|
onClick={approveClickHandler}
|
||||||
disabled={disableApprove}
|
className='justify-start text-sm'
|
||||||
>
|
disabled={disableApprove}
|
||||||
<Icon icon='material-symbols:check' width={24} height={24} />
|
>
|
||||||
Approve
|
<Icon icon='material-symbols:check' width={24} height={24} />
|
||||||
</Button>
|
Approve
|
||||||
|
</Button>
|
||||||
|
</RequirePermission>
|
||||||
|
|
||||||
<Button
|
<RequirePermission permissions='lti.marketing.sales_order.approve'>
|
||||||
color='error'
|
<Button
|
||||||
onClick={rejectClickHandler}
|
color='error'
|
||||||
className='justify-start text-sm'
|
onClick={rejectClickHandler}
|
||||||
disabled={disableReject}
|
className='justify-start text-sm'
|
||||||
>
|
disabled={disableReject}
|
||||||
<Icon icon='material-symbols:close' width={24} height={24} />
|
>
|
||||||
Reject
|
<Icon icon='material-symbols:close' width={24} height={24} />
|
||||||
</Button>
|
Reject
|
||||||
|
</Button>
|
||||||
|
</RequirePermission>
|
||||||
</div>
|
</div>
|
||||||
<TableRowSizeSelector
|
<TableRowSizeSelector
|
||||||
value={pageSize}
|
value={pageSize}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import { useState } from 'react';
|
|||||||
import toast from 'react-hot-toast';
|
import toast from 'react-hot-toast';
|
||||||
import SalesOrderExport from '@/components/pages/marketing/pdf/SalesOrderExport';
|
import SalesOrderExport from '@/components/pages/marketing/pdf/SalesOrderExport';
|
||||||
import DeliveryOrderExport from '@/components/pages/marketing/pdf/DeliveryOrderExport';
|
import DeliveryOrderExport from '@/components/pages/marketing/pdf/DeliveryOrderExport';
|
||||||
|
import RequirePermission from '@/components/helper/RequirePermission';
|
||||||
|
|
||||||
const MarketingDetail = ({
|
const MarketingDetail = ({
|
||||||
initialValues,
|
initialValues,
|
||||||
@@ -134,45 +135,58 @@ const MarketingDetail = ({
|
|||||||
<div className='flex-row flex gap-3'>
|
<div className='flex-row flex gap-3'>
|
||||||
{initialValues?.latest_approval?.step_number == 1 && (
|
{initialValues?.latest_approval?.step_number == 1 && (
|
||||||
<>
|
<>
|
||||||
<Button
|
<RequirePermission permissions='lti.marketing.sales_order.approve'>
|
||||||
color='success'
|
<Button
|
||||||
onClick={approveClickHandler}
|
color='success'
|
||||||
disabled={
|
onClick={approveClickHandler}
|
||||||
initialValues?.latest_approval?.step_number == 1 &&
|
disabled={
|
||||||
initialValues?.latest_approval?.action == 'REJECTED'
|
initialValues?.latest_approval?.step_number == 1 &&
|
||||||
}
|
initialValues?.latest_approval?.action == 'REJECTED'
|
||||||
>
|
}
|
||||||
<Icon icon='mdi:check' width={24} height={24} />
|
>
|
||||||
Approve
|
<Icon icon='mdi:check' width={24} height={24} />
|
||||||
</Button>
|
Approve
|
||||||
<Button
|
</Button>
|
||||||
color='error'
|
</RequirePermission>
|
||||||
onClick={rejectClickHandler}
|
|
||||||
disabled={
|
<RequirePermission permissions='lti.marketing.sales_order.approve'>
|
||||||
initialValues?.latest_approval?.step_number == 1 &&
|
<Button
|
||||||
initialValues?.latest_approval?.action == 'REJECTED'
|
color='error'
|
||||||
}
|
onClick={rejectClickHandler}
|
||||||
>
|
disabled={
|
||||||
<Icon icon='mdi:close' width={24} height={24} />
|
initialValues?.latest_approval?.step_number == 1 &&
|
||||||
Reject
|
initialValues?.latest_approval?.action == 'REJECTED'
|
||||||
</Button>
|
}
|
||||||
|
>
|
||||||
|
<Icon icon='mdi:close' width={24} height={24} />
|
||||||
|
Reject
|
||||||
|
</Button>
|
||||||
|
</RequirePermission>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{initialValues?.latest_approval?.step_number != 1 && (
|
{initialValues?.latest_approval?.step_number != 1 && (
|
||||||
<Button
|
<RequirePermission
|
||||||
color='success'
|
permissions={
|
||||||
href={
|
|
||||||
initialValues?.latest_approval?.step_number == 3
|
initialValues?.latest_approval?.step_number == 3
|
||||||
? `/marketing/detail/delivery-orders/edit?marketingId=${initialValues?.id}`
|
? 'lti.marketing.delivery_order.update'
|
||||||
: `/marketing/add/delivery-orders?marketingId=${initialValues?.id}`
|
: 'lti.marketing.delivery_order.create'
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Icon icon='mdi:truck' width={24} height={24} />
|
<Button
|
||||||
{initialValues?.latest_approval?.step_number == 3
|
color='success'
|
||||||
? 'Edit '
|
href={
|
||||||
: 'Tambah '}
|
initialValues?.latest_approval?.step_number == 3
|
||||||
Delivery Order
|
? `/marketing/detail/delivery-orders/edit?marketingId=${initialValues?.id}`
|
||||||
</Button>
|
: `/marketing/add/delivery-orders?marketingId=${initialValues?.id}`
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Icon icon='mdi:truck' width={24} height={24} />
|
||||||
|
{initialValues?.latest_approval?.step_number == 3
|
||||||
|
? 'Edit '
|
||||||
|
: 'Tambah '}
|
||||||
|
Delivery Order
|
||||||
|
</Button>
|
||||||
|
</RequirePermission>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -413,19 +427,23 @@ const MarketingDetail = ({
|
|||||||
)}
|
)}
|
||||||
<div className='flex flex-row gap-3'>
|
<div className='flex flex-row gap-3'>
|
||||||
{initialValues?.latest_approval?.step_number != 3 && (
|
{initialValues?.latest_approval?.step_number != 3 && (
|
||||||
<Button
|
<RequirePermission permissions='lti.marketing.sales_order.update'>
|
||||||
color='warning'
|
<Button
|
||||||
type='button'
|
color='warning'
|
||||||
href={`/marketing/detail/${initialValues?.latest_approval.step_number == 3 ? 'delivery-orders' : 'sales-orders'}/edit?marketingId=${initialValues?.id}`}
|
type='button'
|
||||||
>
|
href={`/marketing/detail/${initialValues?.latest_approval.step_number == 3 ? 'delivery-orders' : 'sales-orders'}/edit?marketingId=${initialValues?.id}`}
|
||||||
<Icon icon='mdi:pencil' width={24} height={24} />
|
>
|
||||||
Edit
|
<Icon icon='mdi:pencil' width={24} height={24} />
|
||||||
</Button>
|
Edit
|
||||||
|
</Button>
|
||||||
|
</RequirePermission>
|
||||||
)}
|
)}
|
||||||
<Button color='error' onClick={deleteClickHandler}>
|
<RequirePermission permissions='lti.marketing.sales_order.delete'>
|
||||||
<Icon icon='mdi:delete' width={24} height={24} />
|
<Button color='error' onClick={deleteClickHandler}>
|
||||||
Hapus
|
<Icon icon='mdi:delete' width={24} height={24} />
|
||||||
</Button>
|
Hapus
|
||||||
|
</Button>
|
||||||
|
</RequirePermission>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ConfirmationModal
|
<ConfirmationModal
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import DeliveryOrderProductTable from '@/components/pages/marketing/form/table-v
|
|||||||
import DeliveryOrderProductForm from '@/components/pages/marketing/form/repeater/delivery-order/DeliverOrderProduct';
|
import DeliveryOrderProductForm from '@/components/pages/marketing/form/repeater/delivery-order/DeliverOrderProduct';
|
||||||
import { SalesOrderProductFormValues } from '@/components/pages/marketing/form/repeater/sales-order/SalesOrderProduct.schema';
|
import { SalesOrderProductFormValues } from '@/components/pages/marketing/form/repeater/sales-order/SalesOrderProduct.schema';
|
||||||
import { DeliveryOrderProductFormValues } from '@/components/pages/marketing/form/repeater/delivery-order/DeliverOrderProduct.schema';
|
import { DeliveryOrderProductFormValues } from '@/components/pages/marketing/form/repeater/delivery-order/DeliverOrderProduct.schema';
|
||||||
|
import RequirePermission from '@/components/helper/RequirePermission';
|
||||||
|
|
||||||
const MemoizedSalesOrderProductTable = memo(SalesOrderProductTable);
|
const MemoizedSalesOrderProductTable = memo(SalesOrderProductTable);
|
||||||
const MemoizedSalesOrderProductForm = memo(SalesOrderProductForm);
|
const MemoizedSalesOrderProductForm = memo(SalesOrderProductForm);
|
||||||
@@ -689,15 +690,17 @@ const MarketingForm = ({
|
|||||||
{/* Actions button */}
|
{/* Actions button */}
|
||||||
{formType == 'edit' && (
|
{formType == 'edit' && (
|
||||||
<div className='flex flex-row justify-start'>
|
<div className='flex flex-row justify-start'>
|
||||||
<Button
|
<RequirePermission permissions='lti.marketing.sales_order.delete'>
|
||||||
type='button'
|
<Button
|
||||||
color='error'
|
type='button'
|
||||||
onClick={handleDelete}
|
color='error'
|
||||||
isLoading={isLoading}
|
onClick={handleDelete}
|
||||||
>
|
isLoading={isLoading}
|
||||||
<Icon icon='mdi:trash' width={24} height={24} />
|
>
|
||||||
Hapus
|
<Icon icon='mdi:trash' width={24} height={24} />
|
||||||
</Button>
|
Hapus
|
||||||
|
</Button>
|
||||||
|
</RequirePermission>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user