mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-24 23:35:45 +00:00
feat(FE-170,174,175): enhance grading button with consumable eggs validation and update rejection notes
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import { useCallback, useState, useMemo, useEffect } from 'react';
|
import { useCallback, useState, useMemo, useEffect } from 'react';
|
||||||
import { RefObject } from 'react';
|
import { RefObject } from 'react';
|
||||||
|
import { useRouter } from 'next/navigation';
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
import { Icon } from '@iconify/react';
|
import { Icon } from '@iconify/react';
|
||||||
import { SortingState, CellContext } from '@tanstack/react-table';
|
import { SortingState, CellContext } from '@tanstack/react-table';
|
||||||
@@ -34,6 +35,7 @@ import { Area } from '@/types/api/master-data/area';
|
|||||||
import { Location } from '@/types/api/master-data/location';
|
import { Location } from '@/types/api/master-data/location';
|
||||||
import { Kandang } from '@/types/api/master-data/kandang';
|
import { Kandang } from '@/types/api/master-data/kandang';
|
||||||
import { BaseApproval, BaseApiResponse } from '@/types/api/api-general';
|
import { BaseApproval, BaseApiResponse } from '@/types/api/api-general';
|
||||||
|
import { router } from 'next/client';
|
||||||
|
|
||||||
const RowOptionsMenu = ({
|
const RowOptionsMenu = ({
|
||||||
type = 'dropdown',
|
type = 'dropdown',
|
||||||
@@ -42,6 +44,7 @@ const RowOptionsMenu = ({
|
|||||||
approveClickHandler,
|
approveClickHandler,
|
||||||
rejectClickHandler,
|
rejectClickHandler,
|
||||||
isGradingCompleted,
|
isGradingCompleted,
|
||||||
|
hasConsumableEggs,
|
||||||
}: {
|
}: {
|
||||||
type: 'dropdown' | 'collapse';
|
type: 'dropdown' | 'collapse';
|
||||||
props: CellContext<Recording, unknown>;
|
props: CellContext<Recording, unknown>;
|
||||||
@@ -49,6 +52,7 @@ const RowOptionsMenu = ({
|
|||||||
approveClickHandler: () => void;
|
approveClickHandler: () => void;
|
||||||
rejectClickHandler: () => void;
|
rejectClickHandler: () => void;
|
||||||
isGradingCompleted: (recording: Recording) => boolean;
|
isGradingCompleted: (recording: Recording) => boolean;
|
||||||
|
hasConsumableEggs: (recording: Recording) => boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const isLayingCategory =
|
const isLayingCategory =
|
||||||
props.row.original.project_flock_category === 'LAYING';
|
props.row.original.project_flock_category === 'LAYING';
|
||||||
@@ -63,6 +67,7 @@ const RowOptionsMenu = ({
|
|||||||
|
|
||||||
const isApproved = isRecordingApproved(props.row.original);
|
const isApproved = isRecordingApproved(props.row.original);
|
||||||
const isGradingDone = isGradingCompleted(props.row.original);
|
const isGradingDone = isGradingCompleted(props.row.original);
|
||||||
|
const hasConsumable = hasConsumableEggs(props.row.original);
|
||||||
|
|
||||||
const getApprovalTooltip = () => {
|
const getApprovalTooltip = () => {
|
||||||
if (isLayingCategory && !isGradingDone) {
|
if (isLayingCategory && !isGradingDone) {
|
||||||
@@ -95,10 +100,26 @@ const RowOptionsMenu = ({
|
|||||||
</Button>
|
</Button>
|
||||||
{isLayingCategory && !isGradingDone && (
|
{isLayingCategory && !isGradingDone && (
|
||||||
<Button
|
<Button
|
||||||
href={`recording/grading/add?recording_id=${props.row.original.id}`}
|
|
||||||
variant='ghost'
|
variant='ghost'
|
||||||
color='info'
|
color='info'
|
||||||
className='justify-start text-sm'
|
className={`justify-start text-sm ${!hasConsumable ? 'cursor-not-allowed opacity-50' : ''}`}
|
||||||
|
onClick={(e) => {
|
||||||
|
if (!hasConsumable) {
|
||||||
|
e.preventDefault();
|
||||||
|
toast.error(
|
||||||
|
'Tidak bisa melakukan grading karena tidak ada Telur Konsumsi Baik'
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
router.push(
|
||||||
|
`/production/recording/grading/add?recording_id=${props.row.original.id}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
title={
|
||||||
|
hasConsumable
|
||||||
|
? 'Lanjut ke proses grading untuk telur konsumsi baik'
|
||||||
|
: 'Tidak bisa melakukan grading karena tidak ada Telur Konsumsi Baik'
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<Icon icon='material-symbols:egg' width={16} height={16} />
|
<Icon icon='material-symbols:egg' width={16} height={16} />
|
||||||
Grading
|
Grading
|
||||||
@@ -365,6 +386,8 @@ const ApprovalHistoryModal = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const RecordingTable = () => {
|
const RecordingTable = () => {
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
state: tableFilterState,
|
state: tableFilterState,
|
||||||
updateFilter,
|
updateFilter,
|
||||||
@@ -475,6 +498,23 @@ const RecordingTable = () => {
|
|||||||
);
|
);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const hasConsumableEggs = useCallback((recording: Recording): boolean => {
|
||||||
|
if (!recording.eggs || recording.eggs.length === 0) return false;
|
||||||
|
|
||||||
|
return recording.eggs.some((egg) => {
|
||||||
|
if (!egg.product_warehouse || !egg.product_warehouse.product)
|
||||||
|
return false;
|
||||||
|
if (Number(egg.qty) <= 0) return false;
|
||||||
|
|
||||||
|
const productName = egg.product_warehouse.product.name.toLowerCase();
|
||||||
|
return (
|
||||||
|
productName.includes('konsumsi') &&
|
||||||
|
productName.includes('baik') &&
|
||||||
|
Number(egg.qty) > 0
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
const searchChangeHandler = useCallback(
|
const searchChangeHandler = useCallback(
|
||||||
(e: React.ChangeEvent<HTMLInputElement>) => {
|
(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
updateFilter('search', e.target.value);
|
updateFilter('search', e.target.value);
|
||||||
@@ -981,6 +1021,7 @@ const RecordingTable = () => {
|
|||||||
approveClickHandler={approveClickHandler}
|
approveClickHandler={approveClickHandler}
|
||||||
rejectClickHandler={rejectClickHandler}
|
rejectClickHandler={rejectClickHandler}
|
||||||
isGradingCompleted={isGradingCompleted}
|
isGradingCompleted={isGradingCompleted}
|
||||||
|
hasConsumableEggs={hasConsumableEggs}
|
||||||
/>
|
/>
|
||||||
</RowDropdownOptions>
|
</RowDropdownOptions>
|
||||||
)}
|
)}
|
||||||
@@ -994,6 +1035,7 @@ const RecordingTable = () => {
|
|||||||
approveClickHandler={approveClickHandler}
|
approveClickHandler={approveClickHandler}
|
||||||
rejectClickHandler={rejectClickHandler}
|
rejectClickHandler={rejectClickHandler}
|
||||||
isGradingCompleted={isGradingCompleted}
|
isGradingCompleted={isGradingCompleted}
|
||||||
|
hasConsumableEggs={hasConsumableEggs}
|
||||||
/>
|
/>
|
||||||
</RowCollapseOptions>
|
</RowCollapseOptions>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1165,7 +1165,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
|
|
||||||
const rejectResponse = await RecordingApi.reject(
|
const rejectResponse = await RecordingApi.reject(
|
||||||
initialValues?.id as number,
|
initialValues?.id as number,
|
||||||
'Rejected via Form'
|
''
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isResponseSuccess(rejectResponse)) {
|
if (isResponseSuccess(rejectResponse)) {
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export class RecordingService extends BaseApiService<
|
|||||||
|
|
||||||
async reject(
|
async reject(
|
||||||
idOrIds: number | number[],
|
idOrIds: number | number[],
|
||||||
notes: string = 'Rejected via Form'
|
notes: string = ''
|
||||||
): Promise<BaseApiResponse<Recording[]> | undefined> {
|
): Promise<BaseApiResponse<Recording[]> | undefined> {
|
||||||
const approvable_ids = Array.isArray(idOrIds) ? idOrIds : [idOrIds];
|
const approvable_ids = Array.isArray(idOrIds) ? idOrIds : [idOrIds];
|
||||||
return await this.customRequest<BaseApiResponse<Recording[]>>('approvals', {
|
return await this.customRequest<BaseApiResponse<Recording[]>>('approvals', {
|
||||||
|
|||||||
Reference in New Issue
Block a user