mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
feat(FE-149): integrate TransferToLayingsTable to API
This commit is contained in:
@@ -2,7 +2,12 @@
|
||||
|
||||
import { ChangeEventHandler, useState } from 'react';
|
||||
import useSWR from 'swr';
|
||||
import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table';
|
||||
import {
|
||||
CellContext,
|
||||
ColumnDef,
|
||||
Row,
|
||||
SortingState,
|
||||
} from '@tanstack/react-table';
|
||||
import toast from 'react-hot-toast';
|
||||
|
||||
import { Icon } from '@iconify/react';
|
||||
@@ -20,6 +25,7 @@ import RowCollapseOptions from '@/components/table/RowCollapseOptions';
|
||||
import TextInput from '@/components/input/TextInput';
|
||||
import CheckboxInput from '@/components/input/CheckboxInput';
|
||||
import RowOptionsMenuWrapper from '@/components/table/RowOptionsMenuWrapper';
|
||||
import ConfirmationModalWithNotes from '@/components/modal/ConfirmationModalWithNotes';
|
||||
|
||||
import { TransferToLaying } from '@/types/api/production/transfer-to-laying';
|
||||
import { TransferToLayingApi } from '@/services/api/production/transfer-to-laying';
|
||||
@@ -29,6 +35,7 @@ import { useTableFilter } from '@/services/hooks/useTableFilter';
|
||||
import { ROWS_OPTIONS } from '@/config/constant';
|
||||
import { Flock } from '@/types/api/master-data/flock';
|
||||
import { FlockApi } from '@/services/api/master-data';
|
||||
import PillBadge from '@/components/PillBadge';
|
||||
|
||||
const RowOptionsMenu = ({
|
||||
type = 'dropdown',
|
||||
@@ -43,6 +50,16 @@ const RowOptionsMenu = ({
|
||||
rejectClickHandler: () => void;
|
||||
deleteClickHandler: () => void;
|
||||
}) => {
|
||||
const showEditButton =
|
||||
props.row.original.approval.action !== 'APPROVED' &&
|
||||
props.row.original.approval.action !== 'REJECTED';
|
||||
|
||||
const showDeleteButton = showEditButton;
|
||||
|
||||
// TODO: apply RBAC
|
||||
const showApproveButton = showEditButton;
|
||||
const showRejectButton = showEditButton;
|
||||
|
||||
return (
|
||||
<RowOptionsMenuWrapper type={type}>
|
||||
<Button
|
||||
@@ -55,50 +72,57 @@ const RowOptionsMenu = ({
|
||||
Detail
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
href={`/production/transfer-to-laying/detail/edit/?transferToLayingId=${props.row.original.id}`}
|
||||
variant='ghost'
|
||||
color='warning'
|
||||
className='justify-start text-sm'
|
||||
>
|
||||
<Icon icon='material-symbols:edit-outline' width={16} height={16} />
|
||||
Edit
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant='ghost'
|
||||
color='success'
|
||||
onClick={approveClickHandler}
|
||||
className='justify-start text-sm'
|
||||
>
|
||||
<Icon icon='material-symbols:check' width={24} height={24} />
|
||||
Approve
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant='ghost'
|
||||
color='error'
|
||||
onClick={rejectClickHandler}
|
||||
className='justify-start text-sm'
|
||||
>
|
||||
<Icon icon='material-symbols:close' width={24} height={24} />
|
||||
Reject
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
onClick={deleteClickHandler}
|
||||
variant='ghost'
|
||||
color='error'
|
||||
className='justify-start text-sm text-error focus-visible:text-error-content hover:text-error-content'
|
||||
>
|
||||
<Icon
|
||||
icon='material-symbols:delete-outline-rounded'
|
||||
width={16}
|
||||
height={16}
|
||||
{showEditButton && (
|
||||
<Button
|
||||
href={`/production/transfer-to-laying/detail/edit/?transferToLayingId=${props.row.original.id}`}
|
||||
variant='ghost'
|
||||
color='warning'
|
||||
className='justify-start text-sm'
|
||||
/>
|
||||
Delete
|
||||
</Button>
|
||||
>
|
||||
<Icon icon='material-symbols:edit-outline' width={16} height={16} />
|
||||
Edit
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{/* TODO: apply RBAC */}
|
||||
{showApproveButton && (
|
||||
<Button
|
||||
variant='ghost'
|
||||
color='success'
|
||||
onClick={approveClickHandler}
|
||||
className='justify-start text-sm'
|
||||
>
|
||||
<Icon icon='material-symbols:check' width={24} height={24} />
|
||||
Approve
|
||||
</Button>
|
||||
)}
|
||||
{showRejectButton && (
|
||||
<Button
|
||||
variant='ghost'
|
||||
color='error'
|
||||
onClick={rejectClickHandler}
|
||||
className='justify-start text-sm'
|
||||
>
|
||||
<Icon icon='material-symbols:close' width={24} height={24} />
|
||||
Reject
|
||||
</Button>
|
||||
)}
|
||||
{showDeleteButton && (
|
||||
<Button
|
||||
onClick={deleteClickHandler}
|
||||
variant='ghost'
|
||||
color='error'
|
||||
className='justify-start text-sm text-error focus-visible:text-error-content hover:text-error-content'
|
||||
>
|
||||
<Icon
|
||||
icon='material-symbols:delete-outline-rounded'
|
||||
width={16}
|
||||
height={16}
|
||||
className='justify-start text-sm'
|
||||
/>
|
||||
Delete
|
||||
</Button>
|
||||
)}
|
||||
</RowOptionsMenuWrapper>
|
||||
);
|
||||
};
|
||||
@@ -187,17 +211,24 @@ const TransferToLayingsTable = () => {
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
cell: ({ row }) => (
|
||||
<div>
|
||||
<CheckboxInput
|
||||
name='row'
|
||||
checked={row.getIsSelected()}
|
||||
disabled={!row.getCanSelect()}
|
||||
indeterminate={row.getIsSomeSelected()}
|
||||
onChange={row.getToggleSelectedHandler()}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
cell: ({ row }) => {
|
||||
const isCheckboxDisabled =
|
||||
!row.getCanSelect() ||
|
||||
row.original.approval.action === 'APPROVED' ||
|
||||
row.original.approval.action === 'REJECTED';
|
||||
|
||||
return (
|
||||
<div>
|
||||
<CheckboxInput
|
||||
name='row'
|
||||
checked={row.getIsSelected()}
|
||||
disabled={isCheckboxDisabled}
|
||||
indeterminate={row.getIsSomeSelected()}
|
||||
onChange={row.getToggleSelectedHandler()}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
header: '#',
|
||||
@@ -214,21 +245,55 @@ const TransferToLayingsTable = () => {
|
||||
{
|
||||
accessorKey: 'flock_source',
|
||||
header: 'Flock Asal',
|
||||
cell: (props) => props.row.original.flock_source.name,
|
||||
cell: (props) => props.row.original.from_project_flock.flock_name,
|
||||
},
|
||||
{
|
||||
accessorKey: 'flock_destination',
|
||||
header: 'Flock Tujuan',
|
||||
cell: (props) => props.row.original.flock_destination.name,
|
||||
cell: (props) => props.row.original.to_project_flock.flock_name,
|
||||
},
|
||||
{
|
||||
accessorKey: 'quantity',
|
||||
accessorKey: 'usage_qty',
|
||||
header: 'Kuantitas',
|
||||
cell: (props) => props.getValue() ?? props.row.original.pending_usage_qty,
|
||||
},
|
||||
{
|
||||
accessorKey: 'reason',
|
||||
accessorKey: 'notes',
|
||||
header: 'Alasan Transfer',
|
||||
},
|
||||
{
|
||||
header: 'Status',
|
||||
cell: (props) => {
|
||||
const isLatestApprovalRejected =
|
||||
props.row.original.approval.action === 'REJECTED';
|
||||
let latestApprovalStepName = props.row.original.approval.step_name;
|
||||
|
||||
let pillBadgeColor: 'yellow' | 'green' | 'gray' | 'red' = 'gray';
|
||||
|
||||
switch (latestApprovalStepName.toLowerCase()) {
|
||||
case 'pengajuan':
|
||||
pillBadgeColor = 'yellow';
|
||||
break;
|
||||
|
||||
case 'disetujui':
|
||||
pillBadgeColor = 'green';
|
||||
break;
|
||||
}
|
||||
|
||||
if (isLatestApprovalRejected) {
|
||||
pillBadgeColor = 'red';
|
||||
latestApprovalStepName = 'Ditolak';
|
||||
}
|
||||
|
||||
return (
|
||||
<PillBadge
|
||||
content={latestApprovalStepName}
|
||||
color={pillBadgeColor}
|
||||
className='text-sm'
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
header: 'Aksi',
|
||||
cell: (props) => {
|
||||
@@ -237,7 +302,7 @@ const TransferToLayingsTable = () => {
|
||||
const currentRowRelativeIndex =
|
||||
currentPageRows.findIndex((r) => r.id === props.row.id) + 1;
|
||||
|
||||
const isLast2Rows = currentRowRelativeIndex > currentPageSize - 2;
|
||||
const isLast2Rows = currentRowRelativeIndex > currentPageSize - 3;
|
||||
|
||||
const approveClickHandler = () => {
|
||||
setSelectedTransferToLaying(props.row.original);
|
||||
@@ -268,7 +333,7 @@ const TransferToLayingsTable = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
{currentPageSize > 2 && (
|
||||
{currentPageSize > 3 && (
|
||||
<RowDropdownOptions isLast2Rows={isLast2Rows}>
|
||||
<RowOptionsMenu
|
||||
type='dropdown'
|
||||
@@ -280,7 +345,7 @@ const TransferToLayingsTable = () => {
|
||||
</RowDropdownOptions>
|
||||
)}
|
||||
|
||||
{currentPageSize <= 2 && (
|
||||
{currentPageSize <= 3 && (
|
||||
<RowCollapseOptions>
|
||||
<RowOptionsMenu
|
||||
type='collapse'
|
||||
@@ -297,6 +362,15 @@ const TransferToLayingsTable = () => {
|
||||
},
|
||||
];
|
||||
|
||||
const tableEnableRowSelectionHandler: (
|
||||
row: Row<TransferToLaying>
|
||||
) => boolean = (row) => {
|
||||
return (
|
||||
row.original.approval.action !== 'APPROVED' &&
|
||||
row.original.approval.action !== 'REJECTED'
|
||||
);
|
||||
};
|
||||
|
||||
const bulkApproveClickHandler = () => {
|
||||
approveModal.openModal();
|
||||
};
|
||||
@@ -309,27 +383,31 @@ const TransferToLayingsTable = () => {
|
||||
const confirmationModalDeleteClickHandler = async () => {
|
||||
setIsDeleteLoading(true);
|
||||
|
||||
await TransferToLayingApi.delete(selectedTransferToLaying?.id as number);
|
||||
refreshTransferToLayings();
|
||||
try {
|
||||
await TransferToLayingApi.delete(selectedTransferToLaying?.id as number);
|
||||
|
||||
deleteModal.closeModal();
|
||||
toast.success('Berhasil menghapus data transfer ke laying!');
|
||||
setIsDeleteLoading(false);
|
||||
toast.success('Berhasil menghapus data transfer ke laying!');
|
||||
refreshTransferToLayings();
|
||||
} catch (error) {
|
||||
toast.success('Gagal menghapus data transfer ke laying!');
|
||||
} finally {
|
||||
deleteModal.closeModal();
|
||||
setIsDeleteLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const confirmationModalApproveClickHandler = async () => {
|
||||
const confirmationModalApproveClickHandler = async (notes: string) => {
|
||||
setIsApproveLoading(true);
|
||||
|
||||
const bulkApproveResponse =
|
||||
await TransferToLayingApi.bulkApprove(selectedRowIds);
|
||||
const bulkApproveResponse = await TransferToLayingApi.bulkApprove(
|
||||
selectedRowIds,
|
||||
notes
|
||||
);
|
||||
|
||||
if (isResponseSuccess(bulkApproveResponse)) {
|
||||
refreshTransferToLayings();
|
||||
approveModal.closeModal();
|
||||
|
||||
// TODO: remove console.log
|
||||
console.log('Approved data:', selectedRowIds);
|
||||
|
||||
toast.success(
|
||||
`Berhasil approve ${selectedRowIds.length} data transfer ke laying!`
|
||||
);
|
||||
@@ -346,19 +424,18 @@ const TransferToLayingsTable = () => {
|
||||
setIsApproveLoading(false);
|
||||
};
|
||||
|
||||
const confirmationModalRejectClickHandler = async () => {
|
||||
const confirmationModalRejectClickHandler = async (notes: string) => {
|
||||
setIsRejectLoading(true);
|
||||
|
||||
const bulkRejectResponse =
|
||||
await TransferToLayingApi.bulkReject(selectedRowIds);
|
||||
const bulkRejectResponse = await TransferToLayingApi.bulkReject(
|
||||
selectedRowIds,
|
||||
notes
|
||||
);
|
||||
|
||||
if (isResponseSuccess(bulkRejectResponse)) {
|
||||
refreshTransferToLayings();
|
||||
rejectModal.closeModal();
|
||||
|
||||
// TODO: remove console.log
|
||||
console.log('Rejected data:', selectedRowIds);
|
||||
|
||||
toast.success(
|
||||
`Berhasil reject ${selectedRowIds.length} data transfer ke laying!`
|
||||
);
|
||||
@@ -559,6 +636,7 @@ const TransferToLayingsTable = () => {
|
||||
setSorting={setSorting}
|
||||
rowSelection={rowSelection}
|
||||
setRowSelection={setRowSelection}
|
||||
enableRowSelection={tableEnableRowSelectionHandler}
|
||||
className={{
|
||||
containerClassName: cn({
|
||||
'mb-20':
|
||||
@@ -592,7 +670,7 @@ const TransferToLayingsTable = () => {
|
||||
}}
|
||||
/>
|
||||
|
||||
<ConfirmationModal
|
||||
<ConfirmationModalWithNotes
|
||||
ref={approveModal.ref}
|
||||
type='success'
|
||||
text={`Apakah anda yakin ingin approve data transfer ke laying ini (${selectedRowIds.length} data)?`}
|
||||
@@ -607,7 +685,7 @@ const TransferToLayingsTable = () => {
|
||||
}}
|
||||
/>
|
||||
|
||||
<ConfirmationModal
|
||||
<ConfirmationModalWithNotes
|
||||
ref={rejectModal.ref}
|
||||
type='error'
|
||||
text={`Apakah anda yakin ingin reject data transfer ke laying ini (${selectedRowIds.length} data)?`}
|
||||
|
||||
Reference in New Issue
Block a user