mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 21:41:57 +00:00
fix(FE-86-87-88) Hapus tombol edit di index, tambah tombol approve dan delete di detail, dan hit endpoint approve yang udah ada di hoppscocth
This commit is contained in:
@@ -10,11 +10,12 @@ import Table from '@/components/Table';
|
||||
import RowCollapseOptions from '@/components/table/RowCollapseOptions';
|
||||
import RowDropdownOptions from '@/components/table/RowDropdownOptions';
|
||||
import { ROWS_OPTIONS } from '@/config/constant';
|
||||
import { isResponseSuccess } from '@/lib/api-helper';
|
||||
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
|
||||
import { cn } from '@/lib/helper';
|
||||
import { AreaApi, KandangApi, LocationApi } from '@/services/api/master-data';
|
||||
import { ProjectFlockApi } from '@/services/api/production';
|
||||
import { useTableFilter } from '@/services/hooks/useTableFilter';
|
||||
import { BaseApiResponse } from '@/types/api/api-general';
|
||||
import { Kandang } from '@/types/api/master-data/kandang';
|
||||
import { ProjectFlock } from '@/types/api/production/project-flock';
|
||||
import { Icon } from '@iconify/react';
|
||||
@@ -57,7 +58,7 @@ const RowOptionsMenu = ({
|
||||
<Icon icon='mdi:eye-outline' width={16} height={16} />
|
||||
Detail
|
||||
</Button>
|
||||
<Button
|
||||
{/* <Button
|
||||
href={`/production/project-flock/detail/edit?projectFlockId=${props.row.original.id}`}
|
||||
variant='ghost'
|
||||
color='warning'
|
||||
@@ -65,7 +66,7 @@ const RowOptionsMenu = ({
|
||||
>
|
||||
<Icon icon='mdi:pencil-outline' width={16} height={16} />
|
||||
Edit
|
||||
</Button>
|
||||
</Button> */}
|
||||
<Button
|
||||
onClick={deleteClickHandler}
|
||||
variant='ghost'
|
||||
@@ -194,6 +195,7 @@ const ProjectFlockTable = () => {
|
||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||
const [selectedIds, setSelectedIds] = useState<number[]>([]);
|
||||
const [selectedFlocks, setSelectedFlocks] = useState<ProjectFlock[]>([]);
|
||||
const [isApproveLoading, setIsApproveLoading] = useState(false);
|
||||
|
||||
// Columns
|
||||
const projectFlocksColumns: ColumnDef<ProjectFlock>[] = [
|
||||
@@ -260,7 +262,7 @@ const ProjectFlockTable = () => {
|
||||
{kandangNames.length > 0 ? kandangNames.join(', ') : 'Tidak ada'}
|
||||
</div>
|
||||
);
|
||||
}else{
|
||||
} else {
|
||||
return '-';
|
||||
}
|
||||
},
|
||||
@@ -377,6 +379,30 @@ const ProjectFlockTable = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const confirmationModalApproveClickHandler = async () => {
|
||||
setIsApproveLoading(true);
|
||||
const approveProjectFlockRes = await ProjectFlockApi.customRequest<
|
||||
BaseApiResponse<ProjectFlock>,
|
||||
'POST'
|
||||
>(`/approve`, {
|
||||
method: 'POST',
|
||||
payload: 'POST',
|
||||
params: {
|
||||
ids: selectedFlocks.map((flock) => flock.id).join(','),
|
||||
},
|
||||
});
|
||||
|
||||
if (isResponseSuccess(approveProjectFlockRes)) {
|
||||
toast.success('Project Flock berhasil di-approve!');
|
||||
confirmModal.closeModal();
|
||||
}
|
||||
if (isResponseError(approveProjectFlockRes)) {
|
||||
toast.error(approveProjectFlockRes?.message as string);
|
||||
confirmModal.closeModal();
|
||||
}
|
||||
setIsApproveLoading(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='w-full p-0 sm:p-4'>
|
||||
@@ -557,10 +583,8 @@ const ProjectFlockTable = () => {
|
||||
primaryButton={{
|
||||
text: 'Ya',
|
||||
color: 'success',
|
||||
onClick: async () => {
|
||||
toast.success('Project Flock berhasil di-approve!');
|
||||
confirmModal.closeModal();
|
||||
},
|
||||
onClick: confirmationModalApproveClickHandler,
|
||||
isLoading: isApproveLoading,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
import { Icon } from '@iconify/react';
|
||||
import { useFormik } from 'formik';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { use, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import useSWR from 'swr';
|
||||
import {
|
||||
ProjectFlockFormSchema,
|
||||
@@ -35,6 +35,8 @@ import { httpClient } from '@/services/http/client';
|
||||
import { BaseApiResponse } from '@/types/api/api-general';
|
||||
import axios from 'axios';
|
||||
import { FLOCK_CATEGORY_OPTIONS } from '@/config/constant';
|
||||
import { useModal } from '@/components/Modal';
|
||||
import ConfirmationModal from '@/components/modal/ConfirmationModal';
|
||||
|
||||
interface ProjectFlockFormProps {
|
||||
formType?: 'add' | 'edit' | 'detail';
|
||||
@@ -66,6 +68,12 @@ const ProjectFlockForm = ({
|
||||
initialValues?.flock?.id ?? 0
|
||||
);
|
||||
|
||||
const deleteModal = useModal();
|
||||
const confirmModal = useModal();
|
||||
|
||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||
const [isApproveLoading, setIsApproveLoading] = useState(false);
|
||||
|
||||
// Fetch Data
|
||||
const flockUrl = `${FlockApi.basePath}?${new URLSearchParams({
|
||||
search: '',
|
||||
@@ -203,7 +211,7 @@ const ProjectFlockForm = ({
|
||||
|
||||
const optionChangeHandler = (
|
||||
val: OptionType | OptionType[] | null,
|
||||
inputName: string,
|
||||
inputName: string
|
||||
) => {
|
||||
formik.setFieldValue(inputName, val);
|
||||
formik.setFieldValue(
|
||||
@@ -218,7 +226,7 @@ const ProjectFlockForm = ({
|
||||
formik.setFieldValue('category', (val as OptionType)?.value);
|
||||
formik.setFieldValue('category_option', val);
|
||||
formik.setFieldTouched('category', true);
|
||||
}
|
||||
};
|
||||
|
||||
const kandangChangeHandler = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const { value, checked } = event.target;
|
||||
@@ -240,7 +248,11 @@ const ProjectFlockForm = ({
|
||||
formik.setFieldValue(
|
||||
'kandang_ids',
|
||||
optionsKandang
|
||||
.filter((kandang) => (kandang.status === 'NON_ACTIVE' || formik.values.kandang_ids.includes(kandang.id)))
|
||||
.filter(
|
||||
(kandang) =>
|
||||
kandang.status === 'NON_ACTIVE' ||
|
||||
formik.values.kandang_ids.includes(kandang.id)
|
||||
)
|
||||
.map((kandang) => kandang.id)
|
||||
);
|
||||
} else {
|
||||
@@ -321,7 +333,7 @@ const ProjectFlockForm = ({
|
||||
fcr_id: initialValues?.fcr?.id ?? 0,
|
||||
location_id: initialValues?.location?.id ?? 0,
|
||||
period: initialValues?.period ?? '',
|
||||
kandang_ids: initialValues?.kandangs?.map((k: Kandang) => k.id) ?? [],
|
||||
kandang_ids: initialValues?.kandangs?.map((k: Kandang) => k.id),
|
||||
};
|
||||
}, [initialValues]);
|
||||
|
||||
@@ -391,26 +403,6 @@ const ProjectFlockForm = ({
|
||||
}
|
||||
}, [formType, initialValues]);
|
||||
|
||||
// Setelah data kandang difetch, centang otomatis kandang yang ada di initialValues
|
||||
useEffect(() => {
|
||||
if (formType != 'add' && isResponseSuccess(kandang)) {
|
||||
if (selectedLocation) {
|
||||
setOptionsKandang(kandang.data);
|
||||
setOpenSelectKandangs(true);
|
||||
const kandangIds =
|
||||
initialValues?.kandangs?.map((k: Kandang) => k.id) ?? [];
|
||||
formik.setFieldValue('kandang_ids', kandangIds);
|
||||
console.log("kandangIds");
|
||||
console.log(kandangIds);
|
||||
} else {
|
||||
setOptionsKandang([]);
|
||||
setOpenSelectKandangs(false);
|
||||
formik.setFieldValue('kandang_ids', []);
|
||||
initialValues.kandangs = [];
|
||||
}
|
||||
}
|
||||
}, [formType, kandang, initialValues]);
|
||||
|
||||
useEffect(() => {
|
||||
formik.validateForm();
|
||||
}, [formik.values]);
|
||||
@@ -421,6 +413,43 @@ const ProjectFlockForm = ({
|
||||
: formik.setFieldValue('period', '');
|
||||
}, [periodFlocks]);
|
||||
|
||||
// Actions handler
|
||||
const confirmationModalDeleteClickHandler = async () => {
|
||||
setIsDeleteLoading(true);
|
||||
const deleteProjectFlockRes = await ProjectFlockApi.delete(
|
||||
initialValues?.id as number
|
||||
);
|
||||
|
||||
if (isResponseSuccess(deleteProjectFlockRes)) {
|
||||
toast.success(deleteProjectFlockRes?.message as string);
|
||||
router.push('/production/project-flock');
|
||||
}
|
||||
if (isResponseError(deleteProjectFlockRes)) {
|
||||
toast.error(deleteProjectFlockRes?.message as string);
|
||||
}
|
||||
setIsDeleteLoading(false);
|
||||
};
|
||||
|
||||
const confirmationModalApproveClickHandler = async () => {
|
||||
setIsApproveLoading(true);
|
||||
const approveProjectFlockRes = await ProjectFlockApi.customRequest<
|
||||
BaseApiResponse<ProjectFlock>,
|
||||
'POST'
|
||||
>(`/${initialValues?.id}/approve`, {
|
||||
method: 'POST',
|
||||
});
|
||||
|
||||
if (isResponseSuccess(approveProjectFlockRes)) {
|
||||
toast.success('Project Flock berhasil di-approve!');
|
||||
confirmModal.closeModal();
|
||||
}
|
||||
if (isResponseError(approveProjectFlockRes)) {
|
||||
toast.error(approveProjectFlockRes?.message as string);
|
||||
confirmModal.closeModal();
|
||||
}
|
||||
setIsApproveLoading(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<section className='w-full'>
|
||||
@@ -459,6 +488,22 @@ const ProjectFlockForm = ({
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className='w-full py-4'>
|
||||
<Button
|
||||
variant='outline'
|
||||
color='success'
|
||||
onClick={() => {
|
||||
if (initialValues?.id) {
|
||||
confirmModal.openModal();
|
||||
}
|
||||
}}
|
||||
disabled={!initialValues?.id}
|
||||
className='w-full sm:w-fit'
|
||||
>
|
||||
<Icon icon='material-symbols:check' width={24} height={24} />
|
||||
Approve
|
||||
</Button>
|
||||
</div>
|
||||
<form
|
||||
className='w-auto h-auto'
|
||||
onSubmit={formik.handleSubmit}
|
||||
@@ -466,7 +511,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>
|
||||
<div className='card-title mb-4'>Informasi Umum {formik.values.kandang_ids && formik.values.kandang_ids.join(', ')}</div>
|
||||
|
||||
<div className='grid sm:grid-cols-2 gap-4'>
|
||||
<SelectInput
|
||||
@@ -538,8 +583,7 @@ const ProjectFlockForm = ({
|
||||
onChange={categoryChangeHandler}
|
||||
options={FLOCK_CATEGORY_OPTIONS}
|
||||
isError={
|
||||
formik.touched.category &&
|
||||
Boolean(formik.errors.category)
|
||||
formik.touched.category && Boolean(formik.errors.category)
|
||||
}
|
||||
errorMessage={formik.errors.category as string}
|
||||
isClearable
|
||||
@@ -571,7 +615,9 @@ const ProjectFlockForm = ({
|
||||
<div className='card-title'>Pilih Kandang</div>
|
||||
<Button
|
||||
variant='link'
|
||||
className='text-primary rotate-0 transition-transform hover:text-inherit'
|
||||
className={`text-primary rotate-${
|
||||
openSelectKandangs ? '180' : '0'
|
||||
} transition-transform hover:text-inherit`}
|
||||
>
|
||||
<Icon
|
||||
icon='material-symbols:keyboard-arrow-down'
|
||||
@@ -597,24 +643,31 @@ const ProjectFlockForm = ({
|
||||
type='checkbox'
|
||||
checked={
|
||||
optionsKandang
|
||||
.filter((k) => (k.status === 'NON_ACTIVE' || formik.values.kandang_ids.includes(k.id)))
|
||||
.filter(
|
||||
(k) =>
|
||||
k.status === 'NON_ACTIVE' ||
|
||||
formik.values.kandang_ids.includes(k.id)
|
||||
)
|
||||
.every((k) =>
|
||||
formik.values.kandang_ids.includes(k.id)
|
||||
) &&
|
||||
optionsKandang.filter(
|
||||
(k) => (k.status === 'NON_ACTIVE' || formik.values.kandang_ids.includes(k.id))
|
||||
(k) =>
|
||||
k.status === 'NON_ACTIVE' ||
|
||||
formik.values.kandang_ids.includes(k.id)
|
||||
).length > 0
|
||||
}
|
||||
className='checkbox'
|
||||
disabled={formType === 'detail' || optionsKandang.filter(
|
||||
(k) => (k.status === 'NON_ACTIVE')
|
||||
).length == 0}
|
||||
className='checkbox transition-none'
|
||||
disabled={
|
||||
formType === 'detail' ||
|
||||
optionsKandang.filter(
|
||||
(k) => k.status === 'NON_ACTIVE'
|
||||
).length == 0
|
||||
}
|
||||
onChange={
|
||||
formType === 'detail'
|
||||
? () => {}
|
||||
: kandangCheckAll
|
||||
|
||||
|
||||
}
|
||||
/>
|
||||
</label>
|
||||
@@ -634,7 +687,7 @@ const ProjectFlockForm = ({
|
||||
<input
|
||||
value={kandang.id}
|
||||
type='checkbox'
|
||||
className='checkbox'
|
||||
className='checkbox transition-none'
|
||||
checked={formik.values.kandang_ids.includes(
|
||||
kandang.id
|
||||
)}
|
||||
@@ -645,7 +698,7 @@ const ProjectFlockForm = ({
|
||||
}
|
||||
disabled={
|
||||
formType === 'detail' ||
|
||||
(kandang.status != 'NON_ACTIVE')
|
||||
kandang.status != 'NON_ACTIVE'
|
||||
}
|
||||
/>
|
||||
</label>
|
||||
@@ -703,7 +756,55 @@ const ProjectFlockForm = ({
|
||||
)}
|
||||
</div>
|
||||
</form>
|
||||
<div className='w-full'>
|
||||
<Button
|
||||
onClick={() => {
|
||||
if (initialValues?.id) {
|
||||
deleteModal.openModal();
|
||||
}
|
||||
}}
|
||||
color='error'
|
||||
>
|
||||
<Icon
|
||||
icon='material-symbols:delete-outline-rounded'
|
||||
width={16}
|
||||
height={16}
|
||||
className='justify-start text-sm'
|
||||
/>
|
||||
Delete
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<ConfirmationModal
|
||||
ref={deleteModal.ref}
|
||||
type='error'
|
||||
text={`Apakah anda yakin ingin menghapus data Project Flock ini (${initialValues?.flock?.name} - ${initialValues?.area?.name})?`}
|
||||
secondaryButton={{
|
||||
text: 'Tidak',
|
||||
}}
|
||||
primaryButton={{
|
||||
text: 'Ya',
|
||||
color: 'error',
|
||||
isLoading: isDeleteLoading,
|
||||
onClick: confirmationModalDeleteClickHandler,
|
||||
}}
|
||||
/>
|
||||
|
||||
<ConfirmationModal
|
||||
ref={confirmModal.ref}
|
||||
type='success'
|
||||
text={`Apakah anda yakin ingin approve Project Flock berikut? (${initialValues?.flock?.name} - ${initialValues?.area?.name})?`}
|
||||
secondaryButton={{
|
||||
text: 'Tidak',
|
||||
}}
|
||||
primaryButton={{
|
||||
text: 'Ya',
|
||||
color: 'success',
|
||||
isLoading: isApproveLoading,
|
||||
onClick: confirmationModalApproveClickHandler,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user