mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 21:41:57 +00:00
Merge branch 'fix/production' into 'development'
[FIX/FE] Production See merge request mbugroup/lti-web-client!461
This commit is contained in:
@@ -1,13 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import axios from 'axios';
|
||||
import React, {
|
||||
useCallback,
|
||||
useState,
|
||||
useMemo,
|
||||
useEffect,
|
||||
useRef,
|
||||
} from 'react';
|
||||
import React, { useCallback, useState, useMemo, useEffect } from 'react';
|
||||
import useSWR from 'swr';
|
||||
import { Icon } from '@iconify/react';
|
||||
import { SortingState, CellContext, ColumnDef } from '@tanstack/react-table';
|
||||
@@ -46,8 +39,6 @@ import { useTableFilter } from '@/services/hooks/useTableFilter';
|
||||
import toast from 'react-hot-toast';
|
||||
import StatusBadge from '@/components/helper/StatusBadge';
|
||||
import CheckboxInput from '@/components/input/CheckboxInput';
|
||||
import { useUiStore } from '@/stores/ui/ui.store';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { Color } from '@/types/theme';
|
||||
import ButtonFilter from '@/components/helper/ButtonFilter';
|
||||
import Dropdown from '@/components/Dropdown';
|
||||
@@ -77,6 +68,26 @@ const getStatusBadgeColor = (status: string): Color => {
|
||||
return statusBadgeColorMap[normalizedStatus] || 'neutral';
|
||||
};
|
||||
|
||||
const isRecordingApproved = (recording: Recording): boolean => {
|
||||
return (
|
||||
recording.approval?.action === 'APPROVED' &&
|
||||
recording.approval?.step_name === 'Disetujui'
|
||||
);
|
||||
};
|
||||
|
||||
// ===== FILTER HELPERS =====
|
||||
const recordingApprovalStatusOptions: OptionType<string>[] = [
|
||||
{ value: 'CREATED', label: 'Pengajuan' },
|
||||
{ value: 'UPDATED', label: 'Diperbarui' },
|
||||
{ value: 'APPROVED', label: 'Disetujui' },
|
||||
{ value: 'REJECTED', label: 'Ditolak' },
|
||||
];
|
||||
|
||||
const projectFlockCategoryOptions: OptionType<string>[] = [
|
||||
{ value: 'GROWING', label: 'Growing' },
|
||||
{ value: 'LAYING', label: 'Laying' },
|
||||
];
|
||||
|
||||
const RowOptionsMenu = ({
|
||||
popoverPosition = 'bottom',
|
||||
props,
|
||||
@@ -268,25 +279,31 @@ const RowOptionsMenu = ({
|
||||
};
|
||||
|
||||
const RecordingTable = () => {
|
||||
const { searchValue, setSearchValue, setTableState } = useUiStore();
|
||||
const pathname = usePathname();
|
||||
|
||||
const {
|
||||
state: tableFilterState,
|
||||
updateFilter,
|
||||
setPage,
|
||||
setPageSize,
|
||||
toQueryString: getTableFilterQueryString,
|
||||
} = useTableFilter({
|
||||
} = useTableFilter<{
|
||||
search: string;
|
||||
areaFilter: OptionType<number> | null;
|
||||
locationFilter: OptionType<number> | null;
|
||||
projectFlockFilter: OptionType<number> | null;
|
||||
kandangFilter: OptionType<number> | null;
|
||||
projectFlockKandangFilter: number | null;
|
||||
approvalStatusFilter: OptionType<string> | null;
|
||||
projectFlockCategoryFilter: OptionType<string> | null;
|
||||
}>({
|
||||
initial: {
|
||||
search: '',
|
||||
areaFilter: '',
|
||||
locationFilter: '',
|
||||
projectFlockFilter: '',
|
||||
kandangFilter: '',
|
||||
projectFlockKandangFilter: '',
|
||||
approvalStatusFilter: '',
|
||||
projectFlockCategoryFilter: '',
|
||||
areaFilter: null,
|
||||
locationFilter: null,
|
||||
projectFlockFilter: null,
|
||||
kandangFilter: null,
|
||||
projectFlockKandangFilter: null,
|
||||
approvalStatusFilter: null,
|
||||
projectFlockCategoryFilter: null,
|
||||
},
|
||||
paramMap: {
|
||||
page: 'page',
|
||||
@@ -300,68 +317,73 @@ const RecordingTable = () => {
|
||||
approvalStatusFilter: 'approval_status',
|
||||
projectFlockCategoryFilter: 'project_flock_category',
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
updateFilter('search', searchValue);
|
||||
}, [searchValue, updateFilter]);
|
||||
persist: true,
|
||||
storeName: 'recording-table',
|
||||
});
|
||||
|
||||
// ===== FILTER MODAL STATE =====
|
||||
const filterModal = useModal();
|
||||
|
||||
// ===== FILTER STATE =====
|
||||
const [filterArea, setFilterArea] = useState<OptionType | null>(null);
|
||||
const [filterLocation, setFilterLocation] = useState<OptionType | null>(null);
|
||||
const [filterProjectFlock, setFilterProjectFlock] =
|
||||
useState<OptionType | null>(null);
|
||||
const [filterKandang, setFilterKandang] = useState<OptionType | null>(null);
|
||||
const [, setFilterProjectFlockKandangId] = useState<number | undefined>(
|
||||
undefined
|
||||
);
|
||||
const [filterLocationAreaId, setFilterLocationAreaId] = useState<string>('');
|
||||
const [filterProjectFlockLocationId, setFilterProjectFlockLocationId] =
|
||||
useState<string>('');
|
||||
|
||||
// ===== FORMIK SETUP =====
|
||||
const formik = useFormik<RecordingFilterType>({
|
||||
initialValues: {
|
||||
area_id: null,
|
||||
location_id: null,
|
||||
project_flock_id: null,
|
||||
kandang_id: null,
|
||||
project_flock_kandang_id: null,
|
||||
approval_status: null,
|
||||
project_flock_category: null,
|
||||
area_id: tableFilterState.areaFilter,
|
||||
location_id: tableFilterState.locationFilter,
|
||||
project_flock_id: tableFilterState.projectFlockFilter,
|
||||
kandang_id: tableFilterState.kandangFilter,
|
||||
project_flock_kandang_id: tableFilterState.projectFlockKandangFilter,
|
||||
approval_status: tableFilterState.approvalStatusFilter,
|
||||
project_flock_category: tableFilterState.projectFlockCategoryFilter,
|
||||
},
|
||||
validationSchema: RecordingFilterSchema,
|
||||
onSubmit: (values, { setSubmitting }) => {
|
||||
updateFilter('areaFilter', values.area_id || '');
|
||||
updateFilter('locationFilter', values.location_id || '');
|
||||
updateFilter('projectFlockFilter', values.project_flock_id || '');
|
||||
updateFilter('kandangFilter', values.kandang_id || '');
|
||||
updateFilter('areaFilter', values.area_id, true);
|
||||
updateFilter('locationFilter', values.location_id, true);
|
||||
updateFilter('projectFlockFilter', values.project_flock_id, true);
|
||||
updateFilter('kandangFilter', values.kandang_id, true);
|
||||
updateFilter(
|
||||
'projectFlockKandangFilter',
|
||||
values.project_flock_kandang_id || ''
|
||||
values.project_flock_kandang_id,
|
||||
true
|
||||
);
|
||||
updateFilter('approvalStatusFilter', values.approval_status || '');
|
||||
updateFilter('approvalStatusFilter', values.approval_status, true);
|
||||
updateFilter(
|
||||
'projectFlockCategoryFilter',
|
||||
values.project_flock_category || ''
|
||||
values.project_flock_category,
|
||||
true
|
||||
);
|
||||
filterModal.closeModal();
|
||||
setSubmitting(false);
|
||||
},
|
||||
onReset: () => {
|
||||
updateFilter('areaFilter', '');
|
||||
updateFilter('locationFilter', '');
|
||||
updateFilter('projectFlockFilter', '');
|
||||
updateFilter('kandangFilter', '');
|
||||
updateFilter('projectFlockKandangFilter', '');
|
||||
updateFilter('approvalStatusFilter', '');
|
||||
updateFilter('projectFlockCategoryFilter', '');
|
||||
},
|
||||
});
|
||||
|
||||
const formikResetHandler = () => {
|
||||
updateFilter('areaFilter', null, true);
|
||||
updateFilter('locationFilter', null, true);
|
||||
updateFilter('projectFlockFilter', null, true);
|
||||
updateFilter('kandangFilter', null, true);
|
||||
updateFilter('projectFlockKandangFilter', null, true);
|
||||
updateFilter('approvalStatusFilter', null, true);
|
||||
updateFilter('projectFlockCategoryFilter', null, true);
|
||||
|
||||
formik.resetForm({
|
||||
values: {
|
||||
area_id: null,
|
||||
location_id: null,
|
||||
project_flock_id: null,
|
||||
kandang_id: null,
|
||||
project_flock_kandang_id: null,
|
||||
approval_status: null,
|
||||
project_flock_category: null,
|
||||
},
|
||||
});
|
||||
|
||||
filterModal.closeModal();
|
||||
};
|
||||
|
||||
const { project_flock_id, kandang_id } = formik.values;
|
||||
|
||||
const [sorting, setSorting] = useState<SortingState>([]);
|
||||
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
|
||||
const selectedRowIds = Object.keys(rowSelection).map((item) =>
|
||||
@@ -396,13 +418,6 @@ const RecordingTable = () => {
|
||||
);
|
||||
|
||||
// ===== LOCATION, AREA, KANDANG OPTIONS =====
|
||||
const locationParams = useMemo(() => {
|
||||
if (filterLocationAreaId) {
|
||||
return { area_id: filterLocationAreaId };
|
||||
}
|
||||
return undefined;
|
||||
}, [filterLocationAreaId]);
|
||||
|
||||
const {
|
||||
setInputValue: setLocationInputValue,
|
||||
options: locationOptions,
|
||||
@@ -413,7 +428,9 @@ const RecordingTable = () => {
|
||||
'id',
|
||||
'name',
|
||||
'search',
|
||||
locationParams
|
||||
{
|
||||
area_id: String(formik.values.area_id?.value),
|
||||
}
|
||||
);
|
||||
|
||||
const {
|
||||
@@ -428,13 +445,6 @@ const RecordingTable = () => {
|
||||
'search'
|
||||
);
|
||||
|
||||
const projectFlockParams = useMemo(() => {
|
||||
if (filterProjectFlockLocationId) {
|
||||
return { location_id: filterProjectFlockLocationId };
|
||||
}
|
||||
return undefined;
|
||||
}, [filterProjectFlockLocationId]);
|
||||
|
||||
const {
|
||||
setInputValue: setProjectFlockInputValue,
|
||||
options: projectFlockOptions,
|
||||
@@ -446,34 +456,41 @@ const RecordingTable = () => {
|
||||
'id',
|
||||
'flock_name',
|
||||
'search',
|
||||
projectFlockParams
|
||||
{
|
||||
location_id: String(formik.values.location_id?.value),
|
||||
}
|
||||
);
|
||||
|
||||
const kandangOptions = useMemo(() => {
|
||||
if (!filterProjectFlock || !projectFlocksRawData) return [];
|
||||
if (!project_flock_id || !projectFlocksRawData) return [];
|
||||
if (!isResponseSuccess(projectFlocksRawData)) return [];
|
||||
|
||||
const data = projectFlocksRawData.data as ProjectFlock[];
|
||||
const selectedProjectFlockData = data.find(
|
||||
(pf) => pf.id === filterProjectFlock.value
|
||||
const selectedProjectFlockData = data.find((pf) =>
|
||||
pf.id === formik.values.project_flock_id?.value
|
||||
? Number(formik.values.project_flock_id.value)
|
||||
: 0
|
||||
);
|
||||
|
||||
if (!selectedProjectFlockData?.kandangs) return [];
|
||||
|
||||
return selectedProjectFlockData.kandangs.map((k) => ({
|
||||
value: k.id,
|
||||
label: k.name || '',
|
||||
}));
|
||||
}, [filterProjectFlock, projectFlocksRawData]);
|
||||
}, [project_flock_id, projectFlocksRawData]);
|
||||
|
||||
// ===== PROJECT FLOCK KANDANG LOOKUP =====
|
||||
const projectFlockKandangLookupUrl = useMemo(() => {
|
||||
if (!filterProjectFlock || !filterKandang) return null;
|
||||
if (!project_flock_id?.value || !kandang_id?.value) return null;
|
||||
|
||||
const params = new URLSearchParams({
|
||||
project_flock_id: filterProjectFlock.value.toString(),
|
||||
kandang_id: filterKandang.value.toString(),
|
||||
project_flock_id: project_flock_id.value.toString(),
|
||||
kandang_id: kandang_id.value.toString(),
|
||||
});
|
||||
|
||||
return `${ProjectFlockApi.basePath}/kandangs/lookup?${params.toString()}`;
|
||||
}, [filterProjectFlock, filterKandang]);
|
||||
}, [project_flock_id, kandang_id]);
|
||||
|
||||
const { data: projectFlockKandangLookupData } = useSWR(
|
||||
projectFlockKandangLookupUrl,
|
||||
@@ -495,154 +512,45 @@ const RecordingTable = () => {
|
||||
? projectFlockKandangLookupData.data
|
||||
: undefined;
|
||||
|
||||
const formikRef = useRef(formik);
|
||||
|
||||
useEffect(() => {
|
||||
formikRef.current = formik;
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (projectFlockKandangLookup?.id) {
|
||||
const pfkId = String(projectFlockKandangLookup.id);
|
||||
setFilterProjectFlockKandangId(projectFlockKandangLookup.id);
|
||||
formikRef.current.setFieldValue('project_flock_kandang_id', pfkId);
|
||||
formik.setFieldValue('project_flock_kandang_id', pfkId);
|
||||
} else {
|
||||
setFilterProjectFlockKandangId(undefined);
|
||||
formikRef.current.setFieldValue('project_flock_kandang_id', null);
|
||||
formik.setFieldValue('project_flock_kandang_id', null);
|
||||
}
|
||||
}, [projectFlockKandangLookup]);
|
||||
|
||||
// ===== FILTER HANDLERS =====
|
||||
const handleFilterAreaChange = useCallback(
|
||||
(val: OptionType | OptionType[] | null) => {
|
||||
const area = val as OptionType | null;
|
||||
const areaId = area?.value ? String(area.value) : null;
|
||||
const handleFilterAreaChange = (val: OptionType | OptionType[] | null) => {
|
||||
formik.setFieldValue('area_id', val);
|
||||
formik.setFieldValue('location_id', null);
|
||||
formik.setFieldValue('project_flock_id', null);
|
||||
formik.setFieldValue('kandang_id', null);
|
||||
formik.setFieldValue('project_flock_kandang_id', null);
|
||||
};
|
||||
|
||||
formik.setFieldValue('area_id', areaId);
|
||||
formik.setFieldValue('location_id', null);
|
||||
formik.setFieldValue('project_flock_id', null);
|
||||
formik.setFieldValue('kandang_id', null);
|
||||
formik.setFieldValue('project_flock_kandang_id', null);
|
||||
const handleFilterLocationChange = (
|
||||
val: OptionType | OptionType[] | null
|
||||
) => {
|
||||
formik.setFieldValue('location_id', val);
|
||||
formik.setFieldValue('project_flock_id', null);
|
||||
formik.setFieldValue('kandang_id', null);
|
||||
formik.setFieldValue('project_flock_kandang_id', null);
|
||||
};
|
||||
|
||||
setFilterArea(area);
|
||||
setFilterLocation(null);
|
||||
setFilterProjectFlock(null);
|
||||
setFilterKandang(null);
|
||||
setFilterLocationAreaId(areaId || '');
|
||||
setFilterProjectFlockLocationId('');
|
||||
},
|
||||
[formik]
|
||||
);
|
||||
const handleFilterProjectFlockChange = (
|
||||
val: OptionType | OptionType[] | null
|
||||
) => {
|
||||
formik.setFieldValue('project_flock_id', val);
|
||||
formik.setFieldValue('kandang_id', null);
|
||||
formik.setFieldValue('project_flock_kandang_id', null);
|
||||
};
|
||||
|
||||
const handleFilterLocationChange = useCallback(
|
||||
(val: OptionType | OptionType[] | null) => {
|
||||
const location = val as OptionType | null;
|
||||
const locationId = location?.value ? String(location.value) : null;
|
||||
|
||||
formik.setFieldValue('location_id', locationId);
|
||||
formik.setFieldValue('project_flock_id', null);
|
||||
formik.setFieldValue('kandang_id', null);
|
||||
formik.setFieldValue('project_flock_kandang_id', null);
|
||||
|
||||
setFilterLocation(location);
|
||||
setFilterProjectFlock(null);
|
||||
setFilterKandang(null);
|
||||
setFilterProjectFlockLocationId(locationId || '');
|
||||
},
|
||||
[formik]
|
||||
);
|
||||
|
||||
const handleFilterProjectFlockChange = useCallback(
|
||||
(val: OptionType | OptionType[] | null) => {
|
||||
const projectFlock = val as OptionType | null;
|
||||
const projectFlockId = projectFlock?.value
|
||||
? String(projectFlock.value)
|
||||
: null;
|
||||
|
||||
formik.setFieldValue('project_flock_id', projectFlockId);
|
||||
formik.setFieldValue('kandang_id', null);
|
||||
formik.setFieldValue('project_flock_kandang_id', null);
|
||||
|
||||
setFilterProjectFlock(projectFlock);
|
||||
setFilterKandang(null);
|
||||
},
|
||||
[formik]
|
||||
);
|
||||
|
||||
const handleFilterKandangChange = useCallback(
|
||||
(val: OptionType | OptionType[] | null) => {
|
||||
const kandang = val as OptionType | null;
|
||||
const kandangId = kandang?.value ? String(kandang.value) : null;
|
||||
|
||||
formik.setFieldValue('kandang_id', kandangId);
|
||||
formik.setFieldValue('project_flock_kandang_id', null);
|
||||
|
||||
setFilterKandang(kandang);
|
||||
},
|
||||
[formik]
|
||||
);
|
||||
|
||||
// ===== FILTER HELPERS =====
|
||||
const areaIdValue = useMemo(() => {
|
||||
if (!formik.values.area_id) return null;
|
||||
return (
|
||||
areaOptions.find((opt) => String(opt.value) === formik.values.area_id) ||
|
||||
null
|
||||
);
|
||||
}, [formik.values.area_id, areaOptions]);
|
||||
|
||||
const locationIdValue = useMemo(() => {
|
||||
if (!formik.values.location_id) return null;
|
||||
return (
|
||||
locationOptions.find(
|
||||
(opt) => String(opt.value) === formik.values.location_id
|
||||
) || null
|
||||
);
|
||||
}, [formik.values.location_id, locationOptions]);
|
||||
|
||||
const projectFlockIdValue = useMemo(() => {
|
||||
if (!filterProjectFlock) return null;
|
||||
return filterProjectFlock;
|
||||
}, [filterProjectFlock]);
|
||||
|
||||
const kandangIdValue = useMemo(() => {
|
||||
if (!formik.values.kandang_id) return null;
|
||||
return (
|
||||
kandangOptions.find(
|
||||
(opt) => String(opt.value) === formik.values.kandang_id
|
||||
) || null
|
||||
);
|
||||
}, [formik.values.kandang_id, kandangOptions]);
|
||||
|
||||
const recordingApprovalStatusOptions: OptionType<string>[] = [
|
||||
{ value: 'CREATED', label: 'Pengajuan' },
|
||||
{ value: 'UPDATED', label: 'Diperbarui' },
|
||||
{ value: 'APPROVED', label: 'Disetujui' },
|
||||
{ value: 'REJECTED', label: 'Ditolak' },
|
||||
];
|
||||
|
||||
const projectFlockCategoryOptions: OptionType<string>[] = [
|
||||
{ value: 'GROWING', label: 'Growing' },
|
||||
{ value: 'LAYING', label: 'Laying' },
|
||||
];
|
||||
|
||||
const approvalStatusValue = useMemo(() => {
|
||||
if (!formik.values.approval_status) return null;
|
||||
return (
|
||||
recordingApprovalStatusOptions.find(
|
||||
(opt) => opt.value === formik.values.approval_status
|
||||
) || null
|
||||
);
|
||||
}, [formik.values.approval_status]);
|
||||
|
||||
const projectFlockCategoryValue = useMemo(() => {
|
||||
if (!formik.values.project_flock_category) return null;
|
||||
return (
|
||||
projectFlockCategoryOptions.find(
|
||||
(opt) => opt.value === formik.values.project_flock_category
|
||||
) || null
|
||||
);
|
||||
}, [formik.values.project_flock_category]);
|
||||
const handleFilterKandangChange = (val: OptionType | OptionType[] | null) => {
|
||||
formik.setFieldValue('kandang_id', val);
|
||||
formik.setFieldValue('project_flock_kandang_id', null);
|
||||
};
|
||||
|
||||
// ===== HANDLE FILTER MODAL OPEN =====
|
||||
const handleFilterModalOpen = () => {
|
||||
@@ -650,25 +558,9 @@ const RecordingTable = () => {
|
||||
formik.validateForm();
|
||||
};
|
||||
|
||||
const isRecordingApproved = useCallback((recording: Recording): boolean => {
|
||||
return (
|
||||
recording.approval?.action === 'APPROVED' &&
|
||||
recording.approval?.step_name === 'Disetujui'
|
||||
);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setTableState('recording-table', pathname);
|
||||
}, [pathname, setTableState]);
|
||||
|
||||
const searchChangeHandler = useCallback(
|
||||
(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
updateFilter('search', e.target.value);
|
||||
setSearchValue(e.target.value);
|
||||
setPage(1);
|
||||
},
|
||||
[updateFilter, setSearchValue, setPage]
|
||||
);
|
||||
const searchChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
updateFilter('search', e.target.value, true);
|
||||
};
|
||||
|
||||
const singleDeleteHandler = async () => {
|
||||
setIsDeleteLoading(true);
|
||||
@@ -1220,7 +1112,7 @@ const RecordingTable = () => {
|
||||
return (
|
||||
<div className='text-center'>
|
||||
{value !== null && value !== undefined
|
||||
? `${value.toFixed(2)}%`
|
||||
? `${value.toFixed(2)} butir`
|
||||
: '-'}
|
||||
</div>
|
||||
);
|
||||
@@ -1236,7 +1128,7 @@ const RecordingTable = () => {
|
||||
return (
|
||||
<div className='text-center text-gray-600'>
|
||||
{value !== null && value !== undefined
|
||||
? `${value.toFixed(2)}%`
|
||||
? `${value.toFixed(2)} btr`
|
||||
: '-'}
|
||||
</div>
|
||||
);
|
||||
@@ -1572,13 +1464,13 @@ const RecordingTable = () => {
|
||||
<Icon icon='heroicons:x-mark' width={20} height={20} />
|
||||
</Button>
|
||||
</div>
|
||||
<form onSubmit={formik.handleSubmit} onReset={formik.handleReset}>
|
||||
<form onSubmit={formik.handleSubmit} onReset={formikResetHandler}>
|
||||
<div className='p-4 flex flex-col gap-1.5'>
|
||||
<SelectInput
|
||||
label='Area'
|
||||
placeholder='Pilih Area'
|
||||
options={areaOptions}
|
||||
value={areaIdValue}
|
||||
value={formik.values.area_id}
|
||||
onChange={handleFilterAreaChange}
|
||||
onInputChange={setAreaInputValue}
|
||||
isLoading={isLoadingAreaOptions}
|
||||
@@ -1591,13 +1483,13 @@ const RecordingTable = () => {
|
||||
label='Lokasi'
|
||||
placeholder='Pilih Lokasi'
|
||||
options={locationOptions}
|
||||
value={locationIdValue}
|
||||
value={formik.values.location_id}
|
||||
onChange={handleFilterLocationChange}
|
||||
onInputChange={setLocationInputValue}
|
||||
isLoading={isLoadingLocationOptions}
|
||||
isClearable
|
||||
onMenuScrollToBottom={loadMoreLocations}
|
||||
isDisabled={!filterArea}
|
||||
isDisabled={!formik.values.area_id?.value}
|
||||
className={{ wrapper: 'w-full' }}
|
||||
/>
|
||||
|
||||
@@ -1605,13 +1497,13 @@ const RecordingTable = () => {
|
||||
label='Project Flock'
|
||||
placeholder='Pilih Project Flock'
|
||||
options={projectFlockOptions}
|
||||
value={projectFlockIdValue}
|
||||
value={formik.values.project_flock_id}
|
||||
onChange={handleFilterProjectFlockChange}
|
||||
onInputChange={setProjectFlockInputValue}
|
||||
isLoading={isLoadingProjectFlocks}
|
||||
isClearable
|
||||
onMenuScrollToBottom={loadMoreProjectFlocks}
|
||||
isDisabled={!filterLocation}
|
||||
isDisabled={!formik.values.location_id?.value}
|
||||
className={{ wrapper: 'w-full' }}
|
||||
/>
|
||||
|
||||
@@ -1619,11 +1511,11 @@ const RecordingTable = () => {
|
||||
label='Kandang'
|
||||
placeholder='Pilih Kandang'
|
||||
options={kandangOptions}
|
||||
value={kandangIdValue}
|
||||
value={formik.values.kandang_id}
|
||||
onChange={handleFilterKandangChange}
|
||||
isLoading={!filterProjectFlock}
|
||||
isLoading={!formik.values.project_flock_id?.value}
|
||||
isClearable
|
||||
isDisabled={!filterProjectFlock}
|
||||
isDisabled={!formik.values.project_flock_id?.value}
|
||||
className={{ wrapper: 'w-full' }}
|
||||
/>
|
||||
|
||||
@@ -1631,12 +1523,9 @@ const RecordingTable = () => {
|
||||
label='Kategori'
|
||||
placeholder='Pilih Kategori'
|
||||
options={projectFlockCategoryOptions}
|
||||
value={projectFlockCategoryValue}
|
||||
value={formik.values.project_flock_category}
|
||||
onChange={(val) => {
|
||||
formik.setFieldValue(
|
||||
'project_flock_category',
|
||||
!Array.isArray(val) && val ? String(val.value) : null
|
||||
);
|
||||
formik.setFieldValue('project_flock_category', val);
|
||||
}}
|
||||
isClearable
|
||||
className={{ wrapper: 'w-full' }}
|
||||
@@ -1646,12 +1535,9 @@ const RecordingTable = () => {
|
||||
label='Status Approval'
|
||||
placeholder='Pilih Status Approval'
|
||||
options={recordingApprovalStatusOptions}
|
||||
value={approvalStatusValue}
|
||||
value={formik.values.approval_status}
|
||||
onChange={(val) => {
|
||||
formik.setFieldValue(
|
||||
'approval_status',
|
||||
!Array.isArray(val) && val ? String(val.value) : null
|
||||
);
|
||||
formik.setFieldValue('approval_status', val);
|
||||
}}
|
||||
isClearable
|
||||
className={{ wrapper: 'w-full' }}
|
||||
@@ -1661,19 +1547,9 @@ const RecordingTable = () => {
|
||||
{/* Modal Footer */}
|
||||
<div className='flex justify-between items-center gap-4 p-4 border-t border-base-content/10 bg-gray-50'>
|
||||
<Button
|
||||
type='button'
|
||||
type='reset'
|
||||
variant='soft'
|
||||
className='rounded-lg text-base-content/65 bg-transparent border-none hover:bg-base-content/10 hover:text-base-content/65 transition-colors px-3 py-2'
|
||||
onClick={() => {
|
||||
formik.resetForm();
|
||||
setFilterArea(null);
|
||||
setFilterLocation(null);
|
||||
setFilterProjectFlock(null);
|
||||
setFilterKandang(null);
|
||||
setFilterLocationAreaId('');
|
||||
setFilterProjectFlockLocationId('');
|
||||
filterModal.closeModal();
|
||||
}}
|
||||
>
|
||||
Reset Filter
|
||||
</Button>
|
||||
|
||||
@@ -1,21 +1,40 @@
|
||||
import { string, object } from 'yup';
|
||||
import { OptionType } from '@/components/input/SelectInput';
|
||||
import * as Yup from 'yup';
|
||||
|
||||
export const RecordingFilterSchema = object().shape({
|
||||
area_id: string().nullable(),
|
||||
location_id: string().nullable(),
|
||||
project_flock_id: string().nullable(),
|
||||
kandang_id: string().nullable(),
|
||||
project_flock_kandang_id: string().nullable(),
|
||||
approval_status: string().nullable(),
|
||||
project_flock_category: string().nullable(),
|
||||
export const RecordingFilterSchema = Yup.object().shape({
|
||||
area_id: Yup.object({
|
||||
value: Yup.number().nullable(),
|
||||
label: Yup.string().nullable(),
|
||||
}).nullable(),
|
||||
location_id: Yup.object({
|
||||
value: Yup.number().nullable(),
|
||||
label: Yup.string().nullable(),
|
||||
}).nullable(),
|
||||
project_flock_id: Yup.object({
|
||||
value: Yup.number().nullable(),
|
||||
label: Yup.string().nullable(),
|
||||
}).nullable(),
|
||||
kandang_id: Yup.object({
|
||||
value: Yup.number().nullable(),
|
||||
label: Yup.string().nullable(),
|
||||
}).nullable(),
|
||||
project_flock_kandang_id: Yup.number().nullable(),
|
||||
approval_status: Yup.object({
|
||||
value: Yup.string().nullable(),
|
||||
label: Yup.string().nullable(),
|
||||
}).nullable(),
|
||||
project_flock_category: Yup.object({
|
||||
value: Yup.string().nullable(),
|
||||
label: Yup.string().nullable(),
|
||||
}).nullable(),
|
||||
});
|
||||
|
||||
export type RecordingFilterType = {
|
||||
area_id: string | null;
|
||||
location_id: string | null;
|
||||
project_flock_id: string | null;
|
||||
kandang_id: string | null;
|
||||
project_flock_kandang_id: string | null;
|
||||
approval_status: string | null;
|
||||
project_flock_category: string | null;
|
||||
area_id: OptionType<number> | null;
|
||||
location_id: OptionType<number> | null;
|
||||
project_flock_id: OptionType<number> | null;
|
||||
kandang_id: OptionType<number> | null;
|
||||
project_flock_kandang_id: number | null;
|
||||
approval_status: OptionType<string> | null;
|
||||
project_flock_category: OptionType<string> | null;
|
||||
};
|
||||
|
||||
@@ -42,7 +42,7 @@ type RecordingGrowingFormSchemaType = {
|
||||
product_warehouse_id?: {
|
||||
value: number;
|
||||
label: string;
|
||||
};
|
||||
} | null;
|
||||
source_product_warehouse_id?: number;
|
||||
qty?: number | string;
|
||||
}[];
|
||||
@@ -53,7 +53,7 @@ type RecordingLayingFormSchemaType = RecordingGrowingFormSchemaType & {
|
||||
product_warehouse_id?: {
|
||||
value: number;
|
||||
label: string;
|
||||
};
|
||||
} | null;
|
||||
qty?: number | string;
|
||||
weight?: number | string;
|
||||
}[];
|
||||
@@ -71,7 +71,7 @@ export type DepletionSchema = {
|
||||
product_warehouse_id?: {
|
||||
value: number;
|
||||
label: string;
|
||||
};
|
||||
} | null;
|
||||
source_product_warehouse_id?: number;
|
||||
qty?: number | string;
|
||||
};
|
||||
@@ -80,7 +80,7 @@ export type EggSchema = {
|
||||
product_warehouse_id?: {
|
||||
value: number;
|
||||
label: string;
|
||||
};
|
||||
} | null;
|
||||
qty?: number | string;
|
||||
weight?: number | string;
|
||||
};
|
||||
@@ -104,7 +104,7 @@ const DepletionObjectSchema: Yup.ObjectSchema<DepletionSchema> = Yup.object({
|
||||
label: Yup.string().required(),
|
||||
})
|
||||
.optional()
|
||||
.typeError('Depletions harus berupa angka!'),
|
||||
.nullable(),
|
||||
source_product_warehouse_id: Yup.number()
|
||||
.optional()
|
||||
.typeError('Gudang sumber harus berupa angka!'),
|
||||
@@ -119,7 +119,7 @@ const EggObjectSchema: Yup.ObjectSchema<EggSchema> = Yup.object({
|
||||
label: Yup.string().required(),
|
||||
})
|
||||
.optional()
|
||||
.typeError('Kondisi telur harus berupa angka!'),
|
||||
.nullable(),
|
||||
qty: Yup.number().optional().typeError('Jumlah telur harus berupa angka!'),
|
||||
weight: Yup.number().optional().typeError('Berat telur harus berupa angka!'),
|
||||
});
|
||||
@@ -324,7 +324,7 @@ export const getRecordingLayingFormInitialValues = (
|
||||
weight: egg.weight,
|
||||
})) ?? [
|
||||
{
|
||||
product_warehouse_id: undefined,
|
||||
product_warehouse_id: null,
|
||||
qty: '',
|
||||
weight: '',
|
||||
},
|
||||
|
||||
@@ -1472,7 +1472,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
(productWarehouseId: number) => {
|
||||
if ((type === 'edit' || type === 'detail') && initialValues?.stocks) {
|
||||
const existingStock = initialValues.stocks.find(
|
||||
(s) => s.product_warehouse_id === productWarehouseId
|
||||
(s) => Number(s.product_warehouse_id) === Number(productWarehouseId)
|
||||
) as RecordingStock | undefined;
|
||||
if (existingStock) {
|
||||
return {
|
||||
@@ -1731,14 +1731,14 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
formik.setFieldTouched('stocks', false, false);
|
||||
formik.setFieldValue('stocks', [
|
||||
{
|
||||
product_warehouse_id: 0,
|
||||
product_warehouse_id: null,
|
||||
qty: '',
|
||||
},
|
||||
]);
|
||||
formik.setFieldTouched('depletions', false, false);
|
||||
formik.setFieldValue('depletions', [
|
||||
{
|
||||
product_warehouse_id: 0,
|
||||
product_warehouse_id: null,
|
||||
qty: '',
|
||||
},
|
||||
]);
|
||||
@@ -1746,7 +1746,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
formik.setFieldTouched('eggs', false, false);
|
||||
formik.setFieldValue('eggs', [
|
||||
{
|
||||
product_warehouse_id: 0,
|
||||
product_warehouse_id: null,
|
||||
qty: '',
|
||||
weight: '',
|
||||
},
|
||||
@@ -1795,14 +1795,14 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
formik.setFieldTouched('stocks', false, false);
|
||||
formik.setFieldValue('stocks', [
|
||||
{
|
||||
product_warehouse_id: 0,
|
||||
product_warehouse_id: null,
|
||||
qty: '',
|
||||
},
|
||||
]);
|
||||
formik.setFieldTouched('depletions', false, false);
|
||||
formik.setFieldValue('depletions', [
|
||||
{
|
||||
product_warehouse_id: 0,
|
||||
product_warehouse_id: null,
|
||||
qty: '',
|
||||
},
|
||||
]);
|
||||
@@ -1810,7 +1810,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
formik.setFieldTouched('eggs', false, false);
|
||||
formik.setFieldValue('eggs', [
|
||||
{
|
||||
product_warehouse_id: 0,
|
||||
product_warehouse_id: null,
|
||||
qty: '',
|
||||
weight: '',
|
||||
},
|
||||
@@ -1848,14 +1848,14 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
formik.setFieldTouched('stocks', false, false);
|
||||
formik.setFieldValue('stocks', [
|
||||
{
|
||||
product_warehouse_id: 0,
|
||||
product_warehouse_id: null,
|
||||
qty: '',
|
||||
},
|
||||
]);
|
||||
formik.setFieldTouched('depletions', false, false);
|
||||
formik.setFieldValue('depletions', [
|
||||
{
|
||||
product_warehouse_id: 0,
|
||||
product_warehouse_id: null,
|
||||
qty: '',
|
||||
},
|
||||
]);
|
||||
@@ -1863,7 +1863,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
formik.setFieldTouched('eggs', false, false);
|
||||
formik.setFieldValue('eggs', [
|
||||
{
|
||||
product_warehouse_id: 0,
|
||||
product_warehouse_id: null,
|
||||
qty: '',
|
||||
weight: '',
|
||||
},
|
||||
@@ -2076,7 +2076,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
const newStocks = [
|
||||
...(formik.values.stocks || []),
|
||||
{
|
||||
product_warehouse_id: 0,
|
||||
product_warehouse_id: null,
|
||||
qty: '',
|
||||
},
|
||||
];
|
||||
@@ -2108,7 +2108,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
const newDepletions = [
|
||||
...(formik.values.depletions || []),
|
||||
{
|
||||
product_warehouse_id: 0,
|
||||
product_warehouse_id: null,
|
||||
qty: '',
|
||||
},
|
||||
];
|
||||
@@ -2142,7 +2142,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
const newEggs = [
|
||||
...((formik.values as RecordingLayingFormValues).eggs || []),
|
||||
{
|
||||
product_warehouse_id: 0,
|
||||
product_warehouse_id: null,
|
||||
qty: '',
|
||||
},
|
||||
];
|
||||
@@ -2185,7 +2185,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
if (isLayingCategory && (type as 'add' | 'edit' | 'detail') !== 'detail') {
|
||||
const layingValues = formik.values as RecordingLayingFormValues;
|
||||
if (!layingValues.eggs || layingValues.eggs.length === 0) {
|
||||
setFieldValue('eggs', [{ product_warehouse_id: 0, qty: '' }]);
|
||||
setFieldValue('eggs', [{ product_warehouse_id: null, qty: '' }]);
|
||||
}
|
||||
}
|
||||
}, [isLayingCategory, type, formik.values, setFieldValue]);
|
||||
|
||||
Reference in New Issue
Block a user