From 8e3282bb7dd4c9fbf1334fa28e566b4083ecaaa7 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Wed, 12 Nov 2025 13:31:35 +0700 Subject: [PATCH] feat(FE-149): integrate TransferToLayingsTable to API --- .../TransferToLayingsTable.tsx | 240 ++++++++++++------ 1 file changed, 159 insertions(+), 81 deletions(-) diff --git a/src/components/pages/production/transfer-to-laying/TransferToLayingsTable.tsx b/src/components/pages/production/transfer-to-laying/TransferToLayingsTable.tsx index b44a499e..424cc3c2 100644 --- a/src/components/pages/production/transfer-to-laying/TransferToLayingsTable.tsx +++ b/src/components/pages/production/transfer-to-laying/TransferToLayingsTable.tsx @@ -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 ( - - - - - - + > + + Edit + + )} + + {/* TODO: apply RBAC */} + {showApproveButton && ( + + )} + {showRejectButton && ( + + )} + {showDeleteButton && ( + + )} ); }; @@ -187,17 +211,24 @@ const TransferToLayingsTable = () => { /> ), - cell: ({ row }) => ( -
- -
- ), + cell: ({ row }) => { + const isCheckboxDisabled = + !row.getCanSelect() || + row.original.approval.action === 'APPROVED' || + row.original.approval.action === 'REJECTED'; + + return ( +
+ +
+ ); + }, }, { 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 ( + + ); + }, + }, { 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 && ( { )} - {currentPageSize <= 2 && ( + {currentPageSize <= 3 && ( { }, ]; + const tableEnableRowSelectionHandler: ( + row: Row + ) => 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 = () => { }} /> - { }} /> -