mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
fix(FE-270): adjust flock_name in select input and fixing project flock approval
This commit is contained in:
@@ -11,10 +11,6 @@ const AddChickin = () => {
|
||||
return (
|
||||
<>
|
||||
<section className='w-full p-4'>
|
||||
<FormHeader
|
||||
title='Daftar Kandang Project Flock'
|
||||
backUrl='/production/project-flock'
|
||||
/>
|
||||
<ProjectFlockChickinDetail projectFlockId={Number(projectFlockId)} />
|
||||
</section>
|
||||
</>
|
||||
|
||||
@@ -45,7 +45,7 @@ const ChickinFormKandang = ({
|
||||
return (
|
||||
<div className='flex flex-col gap-4'>
|
||||
<FormHeader
|
||||
title='Chick In DOC'
|
||||
title={`Chick In ${initialValues.kandang?.name ?? 'Kandang'}`}
|
||||
backUrl={`/production/project-flock/chickin/add?projectFlockId=${initialValues?.project_flock?.id}`}
|
||||
/>
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import Button from '@/components/Button';
|
||||
import Card from '@/components/Card';
|
||||
import { useModal } from '@/components/Modal';
|
||||
import ConfirmationModal from '@/components/modal/ConfirmationModal';
|
||||
import ConfirmationModalWithNotes from '@/components/modal/ConfirmationModalWithNotes';
|
||||
import PillBadge from '@/components/PillBadge';
|
||||
import Table from '@/components/Table';
|
||||
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
|
||||
@@ -31,12 +32,13 @@ const ChickinLogsView = ({
|
||||
confirmModal.openModal();
|
||||
};
|
||||
|
||||
const confirmationModalApproveClickHandler = async () => {
|
||||
const confirmationModalApproveClickHandler = async (notes?: string) => {
|
||||
setChickinErrorMessage('');
|
||||
setIsApproveLoading(true);
|
||||
const approveChickinRes = await ChickinApi.singleApproval(
|
||||
initialValues?.id as number,
|
||||
'APPROVED'
|
||||
'APPROVED',
|
||||
notes
|
||||
);
|
||||
if (isResponseSuccess(approveChickinRes)) {
|
||||
toast.success(approveChickinRes?.message as string);
|
||||
@@ -151,7 +153,7 @@ const ChickinLogsView = ({
|
||||
</div>
|
||||
)}
|
||||
</Card>
|
||||
<ConfirmationModal
|
||||
<ConfirmationModalWithNotes
|
||||
ref={confirmModal.ref}
|
||||
type='success'
|
||||
text={`Apakah anda yakin ingin approve data Chickin yang Pending?`}
|
||||
@@ -161,7 +163,9 @@ const ChickinLogsView = ({
|
||||
primaryButton={{
|
||||
text: 'Ya',
|
||||
color: 'success',
|
||||
onClick: confirmationModalApproveClickHandler,
|
||||
onClick: (notes) => {
|
||||
confirmationModalApproveClickHandler(notes);
|
||||
},
|
||||
isLoading: isApproveLoading,
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -6,6 +6,7 @@ import DebouncedTextInput from '@/components/input/DebouncedTextInput';
|
||||
import SelectInput, { OptionType } from '@/components/input/SelectInput';
|
||||
import { useModal } from '@/components/Modal';
|
||||
import ConfirmationModal from '@/components/modal/ConfirmationModal';
|
||||
import ConfirmationModalWithNotes from '@/components/modal/ConfirmationModalWithNotes';
|
||||
import Table from '@/components/Table';
|
||||
import RowCollapseOptions from '@/components/table/RowCollapseOptions';
|
||||
import RowDropdownOptions from '@/components/table/RowDropdownOptions';
|
||||
@@ -144,6 +145,9 @@ const ProjectFlockTable = () => {
|
||||
useState<ProjectFlock>();
|
||||
const deleteModal = useModal();
|
||||
const confirmModal = useModal();
|
||||
const [approvalAction, setApprovalAction] = useState<'APPROVED' | 'REJECTED'>(
|
||||
'APPROVED'
|
||||
);
|
||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||
const [isApproveLoading, setIsApproveLoading] = useState(false);
|
||||
|
||||
@@ -226,18 +230,21 @@ const ProjectFlockTable = () => {
|
||||
updateFilter('search', e.target.value);
|
||||
};
|
||||
|
||||
const confirmationModalApproveClickHandler = async () => {
|
||||
const confirmApprovalHandler = async (
|
||||
notes: string,
|
||||
approvalAction: 'APPROVED' | 'REJECTED'
|
||||
) => {
|
||||
setIsApproveLoading(true);
|
||||
const approveProjectFlockRes = await ProjectFlockApi.customRequest<
|
||||
BaseApiResponse<ProjectFlock>,
|
||||
ProjectFlockApprovalPayload
|
||||
>(`/approvals`, {
|
||||
method: 'POST',
|
||||
payload: {
|
||||
action: 'APPROVED',
|
||||
approvable_ids: selectedRowIds.map((id) => id),
|
||||
},
|
||||
});
|
||||
const approveProjectFlockRes =
|
||||
approvalAction === 'APPROVED'
|
||||
? await ProjectFlockApi.bulkApprove(
|
||||
selectedRowIds.map((id) => id),
|
||||
notes
|
||||
)
|
||||
: await ProjectFlockApi.bulkReject(
|
||||
selectedRowIds.map((id) => id),
|
||||
notes
|
||||
);
|
||||
|
||||
if (isResponseSuccess(approveProjectFlockRes)) {
|
||||
toast.success('Project Flock berhasil di-approve!');
|
||||
@@ -271,6 +278,7 @@ const ProjectFlockTable = () => {
|
||||
variant='outline'
|
||||
color='success'
|
||||
onClick={() => {
|
||||
setApprovalAction('APPROVED');
|
||||
confirmModal.openModal();
|
||||
}}
|
||||
disabled={selectedRowIds.length === 0}
|
||||
@@ -279,6 +287,19 @@ const ProjectFlockTable = () => {
|
||||
<Icon icon='material-symbols:check' width={24} height={24} />
|
||||
Approve
|
||||
</Button>
|
||||
<Button
|
||||
variant='outline'
|
||||
color='error'
|
||||
onClick={() => {
|
||||
setApprovalAction('REJECTED');
|
||||
confirmModal.openModal();
|
||||
}}
|
||||
disabled={selectedRowIds.length === 0}
|
||||
className='w-full sm:w-fit'
|
||||
>
|
||||
<Icon icon='mdi:times' width={24} height={24} />
|
||||
Reject
|
||||
</Button>
|
||||
<div className='ms-auto w-full sm:w-auto'>
|
||||
<DebouncedTextInput
|
||||
name='search'
|
||||
@@ -570,17 +591,19 @@ const ProjectFlockTable = () => {
|
||||
}}
|
||||
/>
|
||||
|
||||
<ConfirmationModal
|
||||
<ConfirmationModalWithNotes
|
||||
ref={confirmModal.ref}
|
||||
type='success'
|
||||
text={`Apakah anda yakin ingin approve data Project Flock ini (${selectedRowIds.length} data)?`}
|
||||
type={approvalAction == 'APPROVED' ? 'success' : 'error'}
|
||||
text={`Apakah anda yakin ingin ${approvalAction == 'APPROVED' ? 'approve' : 'reject'} data Project Flock ini (${selectedRowIds.length} data)?`}
|
||||
secondaryButton={{
|
||||
text: 'Tidak',
|
||||
}}
|
||||
primaryButton={{
|
||||
text: 'Ya',
|
||||
color: 'success',
|
||||
onClick: confirmationModalApproveClickHandler,
|
||||
color: approvalAction == 'APPROVED' ? 'success' : 'error',
|
||||
onClick: (notes) => {
|
||||
confirmApprovalHandler(notes, approvalAction);
|
||||
},
|
||||
isLoading: isApproveLoading,
|
||||
}}
|
||||
/>
|
||||
|
||||
+11
-6
@@ -20,6 +20,7 @@ import { Icon } from '@iconify/react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useEffect, useState } from 'react';
|
||||
import useSWR from 'swr';
|
||||
import { FormHeader } from '@/components/helper/form/FormHeader';
|
||||
|
||||
const ProjectFlockChickinDetail = ({
|
||||
projectFlockId,
|
||||
@@ -100,6 +101,10 @@ const ProjectFlockChickinDetail = ({
|
||||
}, [projectFlockId, listProjectFlock]);
|
||||
return (
|
||||
<>
|
||||
<FormHeader
|
||||
title={`Chick In ${projectFlock?.flock_name ?? 'Project Flock'}`}
|
||||
backUrl='/production/project-flock'
|
||||
/>
|
||||
<div className='flex flex-col gap-4 w-full my-4'>
|
||||
<div className='max-w-full sm:max-w-1/2 md:max-w-3/5 lg:max-w-2/5'>
|
||||
<SelectInput
|
||||
@@ -114,7 +119,7 @@ const ProjectFlockChickinDetail = ({
|
||||
value={
|
||||
projectFlock
|
||||
? {
|
||||
label: `${projectFlock?.flock?.name}`,
|
||||
label: `${projectFlock?.flock_name}`,
|
||||
value: projectFlock?.id,
|
||||
}
|
||||
: null
|
||||
@@ -171,7 +176,7 @@ const ProjectFlockChickinDetail = ({
|
||||
},
|
||||
{
|
||||
header: 'Nama Flock',
|
||||
accessorKey: 'flock.name',
|
||||
accessorKey: 'flock_name',
|
||||
},
|
||||
{
|
||||
header: 'Kategori',
|
||||
@@ -205,10 +210,6 @@ const ProjectFlockChickinDetail = ({
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
header: 'Periode',
|
||||
accessorKey: 'period',
|
||||
},
|
||||
{
|
||||
header: 'FCR Layer',
|
||||
accessorKey: 'fcr.name',
|
||||
@@ -274,6 +275,10 @@ const ProjectFlockChickinDetail = ({
|
||||
accessorKey: 'kandang.capacity',
|
||||
header: 'Kapasitas',
|
||||
},
|
||||
{
|
||||
accessorFn: () => projectFlock?.period,
|
||||
header: 'Periode',
|
||||
},
|
||||
{
|
||||
accessorKey: 'approval.step_name',
|
||||
header: 'Status',
|
||||
|
||||
@@ -41,6 +41,7 @@ import ApprovalSteps, {
|
||||
useApprovalSteps,
|
||||
} from '@/components/pages/ApprovalSteps';
|
||||
import { PROJECT_FLOCK_APPROVAL_LINE } from '@/config/approval-line';
|
||||
import ConfirmationModalWithNotes from '@/components/modal/ConfirmationModalWithNotes';
|
||||
|
||||
interface ProjectFlockFormProps {
|
||||
formType?: 'add' | 'edit' | 'detail';
|
||||
@@ -71,8 +72,11 @@ const ProjectFlockForm = ({
|
||||
const [optionsKandang, setOptionsKandang] = useState<Kandang[]>(
|
||||
initialValues?.kandangs ?? []
|
||||
);
|
||||
const [selectedFlock, setSelectedFlock] = useState<number | undefined>(
|
||||
initialValues?.flock?.id ?? 0
|
||||
const [selectedFlock, setSelectedFlock] = useState<string | undefined>(
|
||||
initialValues?.flock_name?.slice(
|
||||
0,
|
||||
initialValues?.flock_name?.lastIndexOf(' ')
|
||||
) ?? ''
|
||||
);
|
||||
|
||||
const deleteModal = useModal();
|
||||
@@ -101,9 +105,13 @@ const ProjectFlockForm = ({
|
||||
|
||||
useEffect(() => {
|
||||
if (initialValues?.approval?.step_name) {
|
||||
const approvedDisabled = initialValues.approval.step_name !== 'Pengajuan';
|
||||
const pengajuanRejected =
|
||||
initialValues.approval.step_number == 1 &&
|
||||
initialValues.approval.action == 'REJECTED';
|
||||
const approvedDisabled =
|
||||
initialValues.approval.step_number !== 1 || pengajuanRejected;
|
||||
setIsApprovedDisabled(approvedDisabled);
|
||||
setIsRejectedDisabled(!approvedDisabled);
|
||||
setIsRejectedDisabled(!approvedDisabled || pengajuanRejected);
|
||||
setApprovalAction(!approvedDisabled ? 'APPROVED' : 'REJECTED');
|
||||
}
|
||||
}, [initialValues]);
|
||||
@@ -470,32 +478,23 @@ const ProjectFlockForm = ({
|
||||
setIsDeleteLoading(false);
|
||||
};
|
||||
|
||||
const confirmationModalClickHandler = async ({
|
||||
action = 'APPROVED',
|
||||
}: {
|
||||
action: 'APPROVED' | 'REJECTED';
|
||||
}) => {
|
||||
const confirmApprovalHandler = async (
|
||||
notes: string,
|
||||
approvalAction: 'REJECTED' | 'APPROVED'
|
||||
) => {
|
||||
if (initialValues?.id === undefined) return;
|
||||
setIsApproveLoading(true);
|
||||
const approveProjectFlockRes = await ProjectFlockApi.customRequest<
|
||||
BaseApiResponse<ProjectFlock>,
|
||||
ProjectFlockApprovalPayload
|
||||
>(`/approvals`, {
|
||||
method: 'POST',
|
||||
payload: {
|
||||
action: action,
|
||||
approvable_ids: [initialValues?.id],
|
||||
},
|
||||
});
|
||||
|
||||
if (isResponseSuccess(approveProjectFlockRes)) {
|
||||
if (refreshProjectFlocks) {
|
||||
await refreshProjectFlocks();
|
||||
const approvalRes =
|
||||
approvalAction == 'APPROVED'
|
||||
? await ProjectFlockApi.approve(initialValues?.id, notes)
|
||||
: await ProjectFlockApi.reject(initialValues?.id, notes);
|
||||
if (isResponseSuccess(approvalRes)) {
|
||||
refreshProjectFlocks?.();
|
||||
toast.success(approvalRes.message as string);
|
||||
}
|
||||
toast.success(approveProjectFlockRes.message as string);
|
||||
}
|
||||
if (isResponseError(approveProjectFlockRes)) {
|
||||
toast.error(approveProjectFlockRes?.message as string);
|
||||
if (isResponseError(approvalRes)) {
|
||||
toast.error(approvalRes?.message as string);
|
||||
}
|
||||
refreshApprovals();
|
||||
confirmModal.closeModal();
|
||||
@@ -600,7 +599,7 @@ const ProjectFlockForm = ({
|
||||
<div className='card bg-base-100 shadow w-full mb-6'>
|
||||
<div className='card-body'>
|
||||
<div className='card-title mb-4'>Informasi Umum</div>
|
||||
|
||||
{selectedFlock}
|
||||
<div className='grid sm:grid-cols-2 gap-4'>
|
||||
<SelectInput
|
||||
required
|
||||
@@ -619,10 +618,19 @@ const ProjectFlockForm = ({
|
||||
<SelectInput
|
||||
required
|
||||
label='Flock'
|
||||
value={formik.values.flock as OptionType}
|
||||
value={
|
||||
formik.values.flock_name
|
||||
? ({
|
||||
label: selectedFlock,
|
||||
value: optionsFlock.find((flock) => {
|
||||
return flock.label === selectedFlock;
|
||||
})?.value,
|
||||
} as OptionType)
|
||||
: undefined
|
||||
}
|
||||
onChange={(val) => {
|
||||
optionChangeHandler(val, 'flock');
|
||||
setSelectedFlock((val as OptionType)?.value as number);
|
||||
setSelectedFlock((val as OptionType)?.label as string);
|
||||
formik.setFieldValue(
|
||||
'flock_name',
|
||||
(val as OptionType)?.label
|
||||
@@ -816,7 +824,7 @@ const ProjectFlockForm = ({
|
||||
}}
|
||||
/>
|
||||
|
||||
<ConfirmationModal
|
||||
<ConfirmationModalWithNotes
|
||||
ref={confirmModal.ref}
|
||||
type={approvalAction == 'APPROVED' ? 'success' : 'error'}
|
||||
text={`Apakah anda yakin ingin ${
|
||||
@@ -831,10 +839,8 @@ const ProjectFlockForm = ({
|
||||
text: 'Ya',
|
||||
color: approvalAction == 'APPROVED' ? 'success' : 'error',
|
||||
isLoading: isApproveLoading,
|
||||
onClick: () => {
|
||||
confirmationModalClickHandler({
|
||||
action: approvalAction,
|
||||
});
|
||||
onClick: (notes) => {
|
||||
confirmApprovalHandler(notes, approvalAction);
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -21,7 +21,8 @@ export class ChickinService extends BaseApiService<
|
||||
*/
|
||||
async singleApproval(
|
||||
id: number,
|
||||
action: 'APPROVED' | 'REJECTED'
|
||||
action: 'APPROVED' | 'REJECTED',
|
||||
notes?: string
|
||||
): Promise<BaseApiResponse<{ message: string }> | undefined> {
|
||||
try {
|
||||
const path = `${this.basePath}/approvals`;
|
||||
@@ -30,7 +31,7 @@ export class ChickinService extends BaseApiService<
|
||||
body: {
|
||||
action: action,
|
||||
approvable_ids: [id],
|
||||
notes: `${action} chickin ${id}`,
|
||||
notes: notes ?? `${action} chickin ${id}`,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
@@ -120,7 +120,7 @@ export class ProjectFlockService extends BaseApiService<
|
||||
| undefined
|
||||
> {
|
||||
try {
|
||||
const path = `${this.basePath}/kandangs/${locationId.toString()}/periods`;
|
||||
const path = `${this.basePath}/location/${locationId.toString()}/periods`;
|
||||
return await httpClient<
|
||||
SuccessApiResponse<
|
||||
{
|
||||
@@ -145,36 +145,40 @@ export class ProjectFlockService extends BaseApiService<
|
||||
* Approve single Project Flock
|
||||
*/
|
||||
async approve(
|
||||
id: number
|
||||
id: number,
|
||||
notes?: string
|
||||
): Promise<BaseApiResponse<{ message: string }> | undefined> {
|
||||
return await this.bulkApprovalAction([id], 'APPROVED');
|
||||
return await this.bulkApprovalAction([id], 'APPROVED', notes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reject single Project Flock
|
||||
*/
|
||||
async reject(
|
||||
id: number
|
||||
id: number,
|
||||
notes?: string
|
||||
): Promise<BaseApiResponse<{ message: string }> | undefined> {
|
||||
return await this.bulkApprovalAction([id], 'REJECTED');
|
||||
return await this.bulkApprovalAction([id], 'REJECTED', notes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Approve Bulk Project Flock
|
||||
*/
|
||||
async bulkApprove(
|
||||
ids: number[]
|
||||
ids: number[],
|
||||
notes?: string
|
||||
): Promise<BaseApiResponse<{ message: string }> | undefined> {
|
||||
return await this.bulkApprovalAction(ids, 'APPROVED');
|
||||
return await this.bulkApprovalAction(ids, 'APPROVED', notes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reject Bulk Project Flock
|
||||
*/
|
||||
async bulkReject(
|
||||
ids: number[]
|
||||
ids: number[],
|
||||
notes?: string
|
||||
): Promise<BaseApiResponse<{ message: string }> | undefined> {
|
||||
return await this.bulkApprovalAction(ids, 'REJECTED');
|
||||
return await this.bulkApprovalAction(ids, 'REJECTED', notes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,7 +186,8 @@ export class ProjectFlockService extends BaseApiService<
|
||||
*/
|
||||
async bulkApprovalAction(
|
||||
ids: number[],
|
||||
action: 'APPROVED' | 'REJECTED'
|
||||
action: 'APPROVED' | 'REJECTED',
|
||||
notes?: string
|
||||
): Promise<BaseApiResponse<{ message: string }> | undefined> {
|
||||
try {
|
||||
const path = `${this.basePath}/approvals`;
|
||||
@@ -191,7 +196,7 @@ export class ProjectFlockService extends BaseApiService<
|
||||
body: {
|
||||
action: action,
|
||||
approvable_ids: ids,
|
||||
notes: `Bulk ${action} Project Flock ${ids.join(', ')}`,
|
||||
notes: notes ?? `Bulk ${action} Project Flock ${ids.join(', ')}`,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user