mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-24 15:25:46 +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 RowCollapseOptions from '@/components/table/RowCollapseOptions';
|
||||||
import RowDropdownOptions from '@/components/table/RowDropdownOptions';
|
import RowDropdownOptions from '@/components/table/RowDropdownOptions';
|
||||||
import { ROWS_OPTIONS } from '@/config/constant';
|
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 { cn } from '@/lib/helper';
|
||||||
import { AreaApi, KandangApi, LocationApi } from '@/services/api/master-data';
|
import { AreaApi, KandangApi, LocationApi } from '@/services/api/master-data';
|
||||||
import { ProjectFlockApi } from '@/services/api/production';
|
import { ProjectFlockApi } from '@/services/api/production';
|
||||||
import { useTableFilter } from '@/services/hooks/useTableFilter';
|
import { useTableFilter } from '@/services/hooks/useTableFilter';
|
||||||
|
import { BaseApiResponse } from '@/types/api/api-general';
|
||||||
import { Kandang } from '@/types/api/master-data/kandang';
|
import { Kandang } from '@/types/api/master-data/kandang';
|
||||||
import { ProjectFlock } from '@/types/api/production/project-flock';
|
import { ProjectFlock } from '@/types/api/production/project-flock';
|
||||||
import { Icon } from '@iconify/react';
|
import { Icon } from '@iconify/react';
|
||||||
@@ -57,7 +58,7 @@ const RowOptionsMenu = ({
|
|||||||
<Icon icon='mdi:eye-outline' width={16} height={16} />
|
<Icon icon='mdi:eye-outline' width={16} height={16} />
|
||||||
Detail
|
Detail
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
{/* <Button
|
||||||
href={`/production/project-flock/detail/edit?projectFlockId=${props.row.original.id}`}
|
href={`/production/project-flock/detail/edit?projectFlockId=${props.row.original.id}`}
|
||||||
variant='ghost'
|
variant='ghost'
|
||||||
color='warning'
|
color='warning'
|
||||||
@@ -65,7 +66,7 @@ const RowOptionsMenu = ({
|
|||||||
>
|
>
|
||||||
<Icon icon='mdi:pencil-outline' width={16} height={16} />
|
<Icon icon='mdi:pencil-outline' width={16} height={16} />
|
||||||
Edit
|
Edit
|
||||||
</Button>
|
</Button> */}
|
||||||
<Button
|
<Button
|
||||||
onClick={deleteClickHandler}
|
onClick={deleteClickHandler}
|
||||||
variant='ghost'
|
variant='ghost'
|
||||||
@@ -194,6 +195,7 @@ const ProjectFlockTable = () => {
|
|||||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||||
const [selectedIds, setSelectedIds] = useState<number[]>([]);
|
const [selectedIds, setSelectedIds] = useState<number[]>([]);
|
||||||
const [selectedFlocks, setSelectedFlocks] = useState<ProjectFlock[]>([]);
|
const [selectedFlocks, setSelectedFlocks] = useState<ProjectFlock[]>([]);
|
||||||
|
const [isApproveLoading, setIsApproveLoading] = useState(false);
|
||||||
|
|
||||||
// Columns
|
// Columns
|
||||||
const projectFlocksColumns: ColumnDef<ProjectFlock>[] = [
|
const projectFlocksColumns: ColumnDef<ProjectFlock>[] = [
|
||||||
@@ -260,7 +262,7 @@ const ProjectFlockTable = () => {
|
|||||||
{kandangNames.length > 0 ? kandangNames.join(', ') : 'Tidak ada'}
|
{kandangNames.length > 0 ? kandangNames.join(', ') : 'Tidak ada'}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}else{
|
} else {
|
||||||
return '-';
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className='w-full p-0 sm:p-4'>
|
<div className='w-full p-0 sm:p-4'>
|
||||||
@@ -557,10 +583,8 @@ const ProjectFlockTable = () => {
|
|||||||
primaryButton={{
|
primaryButton={{
|
||||||
text: 'Ya',
|
text: 'Ya',
|
||||||
color: 'success',
|
color: 'success',
|
||||||
onClick: async () => {
|
onClick: confirmationModalApproveClickHandler,
|
||||||
toast.success('Project Flock berhasil di-approve!');
|
isLoading: isApproveLoading,
|
||||||
confirmModal.closeModal();
|
|
||||||
},
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
import { Icon } from '@iconify/react';
|
import { Icon } from '@iconify/react';
|
||||||
import { useFormik } from 'formik';
|
import { useFormik } from 'formik';
|
||||||
import { useRouter } from 'next/navigation';
|
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 useSWR from 'swr';
|
||||||
import {
|
import {
|
||||||
ProjectFlockFormSchema,
|
ProjectFlockFormSchema,
|
||||||
@@ -35,6 +35,8 @@ import { httpClient } from '@/services/http/client';
|
|||||||
import { BaseApiResponse } from '@/types/api/api-general';
|
import { BaseApiResponse } from '@/types/api/api-general';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { FLOCK_CATEGORY_OPTIONS } from '@/config/constant';
|
import { FLOCK_CATEGORY_OPTIONS } from '@/config/constant';
|
||||||
|
import { useModal } from '@/components/Modal';
|
||||||
|
import ConfirmationModal from '@/components/modal/ConfirmationModal';
|
||||||
|
|
||||||
interface ProjectFlockFormProps {
|
interface ProjectFlockFormProps {
|
||||||
formType?: 'add' | 'edit' | 'detail';
|
formType?: 'add' | 'edit' | 'detail';
|
||||||
@@ -66,6 +68,12 @@ const ProjectFlockForm = ({
|
|||||||
initialValues?.flock?.id ?? 0
|
initialValues?.flock?.id ?? 0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const deleteModal = useModal();
|
||||||
|
const confirmModal = useModal();
|
||||||
|
|
||||||
|
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||||
|
const [isApproveLoading, setIsApproveLoading] = useState(false);
|
||||||
|
|
||||||
// Fetch Data
|
// Fetch Data
|
||||||
const flockUrl = `${FlockApi.basePath}?${new URLSearchParams({
|
const flockUrl = `${FlockApi.basePath}?${new URLSearchParams({
|
||||||
search: '',
|
search: '',
|
||||||
@@ -203,7 +211,7 @@ const ProjectFlockForm = ({
|
|||||||
|
|
||||||
const optionChangeHandler = (
|
const optionChangeHandler = (
|
||||||
val: OptionType | OptionType[] | null,
|
val: OptionType | OptionType[] | null,
|
||||||
inputName: string,
|
inputName: string
|
||||||
) => {
|
) => {
|
||||||
formik.setFieldValue(inputName, val);
|
formik.setFieldValue(inputName, val);
|
||||||
formik.setFieldValue(
|
formik.setFieldValue(
|
||||||
@@ -218,7 +226,7 @@ const ProjectFlockForm = ({
|
|||||||
formik.setFieldValue('category', (val as OptionType)?.value);
|
formik.setFieldValue('category', (val as OptionType)?.value);
|
||||||
formik.setFieldValue('category_option', val);
|
formik.setFieldValue('category_option', val);
|
||||||
formik.setFieldTouched('category', true);
|
formik.setFieldTouched('category', true);
|
||||||
}
|
};
|
||||||
|
|
||||||
const kandangChangeHandler = (event: React.ChangeEvent<HTMLInputElement>) => {
|
const kandangChangeHandler = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const { value, checked } = event.target;
|
const { value, checked } = event.target;
|
||||||
@@ -240,7 +248,11 @@ const ProjectFlockForm = ({
|
|||||||
formik.setFieldValue(
|
formik.setFieldValue(
|
||||||
'kandang_ids',
|
'kandang_ids',
|
||||||
optionsKandang
|
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)
|
.map((kandang) => kandang.id)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@@ -321,7 +333,7 @@ const ProjectFlockForm = ({
|
|||||||
fcr_id: initialValues?.fcr?.id ?? 0,
|
fcr_id: initialValues?.fcr?.id ?? 0,
|
||||||
location_id: initialValues?.location?.id ?? 0,
|
location_id: initialValues?.location?.id ?? 0,
|
||||||
period: initialValues?.period ?? '',
|
period: initialValues?.period ?? '',
|
||||||
kandang_ids: initialValues?.kandangs?.map((k: Kandang) => k.id) ?? [],
|
kandang_ids: initialValues?.kandangs?.map((k: Kandang) => k.id),
|
||||||
};
|
};
|
||||||
}, [initialValues]);
|
}, [initialValues]);
|
||||||
|
|
||||||
@@ -391,26 +403,6 @@ const ProjectFlockForm = ({
|
|||||||
}
|
}
|
||||||
}, [formType, initialValues]);
|
}, [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(() => {
|
useEffect(() => {
|
||||||
formik.validateForm();
|
formik.validateForm();
|
||||||
}, [formik.values]);
|
}, [formik.values]);
|
||||||
@@ -421,6 +413,43 @@ const ProjectFlockForm = ({
|
|||||||
: formik.setFieldValue('period', '');
|
: formik.setFieldValue('period', '');
|
||||||
}, [periodFlocks]);
|
}, [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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<section className='w-full'>
|
<section className='w-full'>
|
||||||
@@ -459,6 +488,22 @@ const ProjectFlockForm = ({
|
|||||||
</div>
|
</div>
|
||||||
</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
|
<form
|
||||||
className='w-auto h-auto'
|
className='w-auto h-auto'
|
||||||
onSubmit={formik.handleSubmit}
|
onSubmit={formik.handleSubmit}
|
||||||
@@ -466,7 +511,7 @@ const ProjectFlockForm = ({
|
|||||||
>
|
>
|
||||||
<div className='card bg-base-100 shadow w-full mb-6'>
|
<div className='card bg-base-100 shadow w-full mb-6'>
|
||||||
<div className='card-body'>
|
<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'>
|
<div className='grid sm:grid-cols-2 gap-4'>
|
||||||
<SelectInput
|
<SelectInput
|
||||||
@@ -538,8 +583,7 @@ const ProjectFlockForm = ({
|
|||||||
onChange={categoryChangeHandler}
|
onChange={categoryChangeHandler}
|
||||||
options={FLOCK_CATEGORY_OPTIONS}
|
options={FLOCK_CATEGORY_OPTIONS}
|
||||||
isError={
|
isError={
|
||||||
formik.touched.category &&
|
formik.touched.category && Boolean(formik.errors.category)
|
||||||
Boolean(formik.errors.category)
|
|
||||||
}
|
}
|
||||||
errorMessage={formik.errors.category as string}
|
errorMessage={formik.errors.category as string}
|
||||||
isClearable
|
isClearable
|
||||||
@@ -571,7 +615,9 @@ const ProjectFlockForm = ({
|
|||||||
<div className='card-title'>Pilih Kandang</div>
|
<div className='card-title'>Pilih Kandang</div>
|
||||||
<Button
|
<Button
|
||||||
variant='link'
|
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
|
||||||
icon='material-symbols:keyboard-arrow-down'
|
icon='material-symbols:keyboard-arrow-down'
|
||||||
@@ -597,24 +643,31 @@ const ProjectFlockForm = ({
|
|||||||
type='checkbox'
|
type='checkbox'
|
||||||
checked={
|
checked={
|
||||||
optionsKandang
|
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) =>
|
.every((k) =>
|
||||||
formik.values.kandang_ids.includes(k.id)
|
formik.values.kandang_ids.includes(k.id)
|
||||||
) &&
|
) &&
|
||||||
optionsKandang.filter(
|
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
|
).length > 0
|
||||||
}
|
}
|
||||||
className='checkbox'
|
className='checkbox transition-none'
|
||||||
disabled={formType === 'detail' || optionsKandang.filter(
|
disabled={
|
||||||
(k) => (k.status === 'NON_ACTIVE')
|
formType === 'detail' ||
|
||||||
).length == 0}
|
optionsKandang.filter(
|
||||||
|
(k) => k.status === 'NON_ACTIVE'
|
||||||
|
).length == 0
|
||||||
|
}
|
||||||
onChange={
|
onChange={
|
||||||
formType === 'detail'
|
formType === 'detail'
|
||||||
? () => {}
|
? () => {}
|
||||||
: kandangCheckAll
|
: kandangCheckAll
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
@@ -634,7 +687,7 @@ const ProjectFlockForm = ({
|
|||||||
<input
|
<input
|
||||||
value={kandang.id}
|
value={kandang.id}
|
||||||
type='checkbox'
|
type='checkbox'
|
||||||
className='checkbox'
|
className='checkbox transition-none'
|
||||||
checked={formik.values.kandang_ids.includes(
|
checked={formik.values.kandang_ids.includes(
|
||||||
kandang.id
|
kandang.id
|
||||||
)}
|
)}
|
||||||
@@ -645,7 +698,7 @@ const ProjectFlockForm = ({
|
|||||||
}
|
}
|
||||||
disabled={
|
disabled={
|
||||||
formType === 'detail' ||
|
formType === 'detail' ||
|
||||||
(kandang.status != 'NON_ACTIVE')
|
kandang.status != 'NON_ACTIVE'
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
@@ -703,7 +756,55 @@ const ProjectFlockForm = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</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>
|
</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