mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-24 07:15:44 +00:00
Merge branch 'development' into 'production'
Development See merge request mbugroup/lti-web-client!456
This commit is contained in:
@@ -11,7 +11,6 @@ import { useModal } from '@/components/Modal';
|
|||||||
import ConfirmationModal from '@/components/modal/ConfirmationModal';
|
import ConfirmationModal from '@/components/modal/ConfirmationModal';
|
||||||
import ConfirmationModalWithNotes from '@/components/modal/ConfirmationModalWithNotes';
|
import ConfirmationModalWithNotes from '@/components/modal/ConfirmationModalWithNotes';
|
||||||
import Table from '@/components/Table';
|
import Table from '@/components/Table';
|
||||||
import Dropdown from '@/components/Dropdown';
|
|
||||||
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
|
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
|
||||||
import { cn, formatDate } from '@/lib/helper';
|
import { cn, formatDate } from '@/lib/helper';
|
||||||
import { AreaApi, KandangApi, LocationApi } from '@/services/api/master-data';
|
import { AreaApi, KandangApi, LocationApi } from '@/services/api/master-data';
|
||||||
@@ -44,6 +43,7 @@ import {
|
|||||||
import Modal from '@/components/Modal';
|
import Modal from '@/components/Modal';
|
||||||
import SelectInputRadio from '@/components/input/SelectInputRadio';
|
import SelectInputRadio from '@/components/input/SelectInputRadio';
|
||||||
import ButtonFilter from '@/components/helper/ButtonFilter';
|
import ButtonFilter from '@/components/helper/ButtonFilter';
|
||||||
|
import NumberInput from '@/components/input/NumberInput';
|
||||||
|
|
||||||
const RowOptionsMenu = ({
|
const RowOptionsMenu = ({
|
||||||
props,
|
props,
|
||||||
@@ -211,8 +211,7 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
|
|||||||
);
|
);
|
||||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||||
const [isApproveLoading, setIsApproveLoading] = useState(false);
|
const [isApproveLoading, setIsApproveLoading] = useState(false);
|
||||||
const [isLoadingExportingToExcel, setIsLoadingExportingToExcel] =
|
|
||||||
useState(false);
|
|
||||||
const {
|
const {
|
||||||
isChickinApproveModalOpen,
|
isChickinApproveModalOpen,
|
||||||
isChickinApproveLoading,
|
isChickinApproveLoading,
|
||||||
@@ -327,14 +326,6 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
|
|||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
const periodOptions = useMemo(
|
|
||||||
() => [
|
|
||||||
{ value: '1', label: 'Periode 1' },
|
|
||||||
{ value: '2', label: 'Periode 2' },
|
|
||||||
],
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
|
|
||||||
// ===== FILTER HELPERS =====
|
// ===== FILTER HELPERS =====
|
||||||
const areaValue = useMemo(() => {
|
const areaValue = useMemo(() => {
|
||||||
if (!formik.values.area_id) return null;
|
if (!formik.values.area_id) return null;
|
||||||
@@ -393,13 +384,6 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
|
|||||||
);
|
);
|
||||||
}, [formik.values.category, categoryOptions]);
|
}, [formik.values.category, categoryOptions]);
|
||||||
|
|
||||||
const periodValue = useMemo(() => {
|
|
||||||
if (!formik.values.period) return null;
|
|
||||||
return (
|
|
||||||
periodOptions.find((opt) => opt.value === formik.values.period) || null
|
|
||||||
);
|
|
||||||
}, [formik.values.period, periodOptions]);
|
|
||||||
|
|
||||||
// ===== FILTER DEPENDENCY HANDLERS =====
|
// ===== FILTER DEPENDENCY HANDLERS =====
|
||||||
const handleFilterAreaChange = (area: OptionType | null) => {
|
const handleFilterAreaChange = (area: OptionType | null) => {
|
||||||
const areaId = area?.value ? String(area.value) : undefined;
|
const areaId = area?.value ? String(area.value) : undefined;
|
||||||
@@ -813,14 +797,6 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
|
|||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
const exportToExcelHandler = async () => {
|
|
||||||
setIsLoadingExportingToExcel(true);
|
|
||||||
|
|
||||||
toast.error('Not implemented yet!');
|
|
||||||
|
|
||||||
setIsLoadingExportingToExcel(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const bulkApproveClickHandler = () => {
|
const bulkApproveClickHandler = () => {
|
||||||
setApprovalAction('APPROVED');
|
setApprovalAction('APPROVED');
|
||||||
confirmModal.openModal();
|
confirmModal.openModal();
|
||||||
@@ -1020,51 +996,6 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
|
|||||||
onClick={handleFilterModalOpen}
|
onClick={handleFilterModalOpen}
|
||||||
className='px-3 py-2.5'
|
className='px-3 py-2.5'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Dropdown
|
|
||||||
align='end'
|
|
||||||
direction='bottom'
|
|
||||||
className={{
|
|
||||||
content:
|
|
||||||
'mt-1 rounded-xl border border-base-content/5 shadow-sm overflow-hidden',
|
|
||||||
}}
|
|
||||||
trigger={
|
|
||||||
<Button
|
|
||||||
variant='outline'
|
|
||||||
color='none'
|
|
||||||
className='px-3 py-2.5 text-sm text-base-content/50 border border-base-content/10 rounded-xl shadow-button-soft'
|
|
||||||
>
|
|
||||||
<div className='flex flex-row items-center gap-1.5'>
|
|
||||||
<Icon
|
|
||||||
icon='heroicons:cloud-arrow-down'
|
|
||||||
width={20}
|
|
||||||
height={20}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<span>Export</span>
|
|
||||||
|
|
||||||
<div className='w-px self-stretch bg-base-content/10' />
|
|
||||||
|
|
||||||
<Icon
|
|
||||||
icon='heroicons:chevron-down'
|
|
||||||
width={14}
|
|
||||||
height={14}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Button>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
variant='ghost'
|
|
||||||
color='none'
|
|
||||||
onClick={exportToExcelHandler}
|
|
||||||
isLoading={isLoadingExportingToExcel}
|
|
||||||
className='w-full p-3 justify-start text-sm text-base-content/50 font-semibold text-nowrap'
|
|
||||||
>
|
|
||||||
<Icon icon='heroicons:table-cells' width={20} height={20} />
|
|
||||||
Export to Excel
|
|
||||||
</Button>
|
|
||||||
</Dropdown>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -1393,18 +1324,14 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
|
|||||||
isClearable={true}
|
isClearable={true}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SelectInputRadio
|
<NumberInput
|
||||||
label='Periode'
|
label='Periode'
|
||||||
placeholder='Pilih Periode'
|
name='period'
|
||||||
options={periodOptions}
|
placeholder='Masukkan Periode'
|
||||||
value={periodValue}
|
value={formik.values.period ?? ''}
|
||||||
onChange={(val) => {
|
onChange={formik.handleChange}
|
||||||
if (!Array.isArray(val)) {
|
onBlur={formik.handleBlur}
|
||||||
formik.setFieldValue('period', val?.value || null);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
className={{ wrapper: 'w-full' }}
|
className={{ wrapper: 'w-full' }}
|
||||||
isClearable
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
CreateLayingRecordingPayload,
|
CreateLayingRecordingPayload,
|
||||||
CreateEggPayload,
|
CreateEggPayload,
|
||||||
} from '@/types/api/production/recording';
|
} from '@/types/api/production/recording';
|
||||||
|
import { getProductWarehouseOptionLabel } from '@/lib/product-warehouse';
|
||||||
|
|
||||||
type RecordingGrowingFormSchemaType = {
|
type RecordingGrowingFormSchemaType = {
|
||||||
record_date: string;
|
record_date: string;
|
||||||
@@ -29,11 +30,19 @@ type RecordingGrowingFormSchemaType = {
|
|||||||
} | null;
|
} | null;
|
||||||
project_flock_kandang_id: number;
|
project_flock_kandang_id: number;
|
||||||
stocks: {
|
stocks: {
|
||||||
product_warehouse_id: number;
|
product_warehouse_id:
|
||||||
|
| {
|
||||||
|
value: number;
|
||||||
|
label: string;
|
||||||
|
}
|
||||||
|
| undefined;
|
||||||
qty: number | string;
|
qty: number | string;
|
||||||
}[];
|
}[];
|
||||||
depletions: {
|
depletions: {
|
||||||
product_warehouse_id?: number;
|
product_warehouse_id?: {
|
||||||
|
value: number;
|
||||||
|
label: string;
|
||||||
|
};
|
||||||
source_product_warehouse_id?: number;
|
source_product_warehouse_id?: number;
|
||||||
qty?: number | string;
|
qty?: number | string;
|
||||||
}[];
|
}[];
|
||||||
@@ -41,34 +50,48 @@ type RecordingGrowingFormSchemaType = {
|
|||||||
|
|
||||||
type RecordingLayingFormSchemaType = RecordingGrowingFormSchemaType & {
|
type RecordingLayingFormSchemaType = RecordingGrowingFormSchemaType & {
|
||||||
eggs: {
|
eggs: {
|
||||||
product_warehouse_id?: number;
|
product_warehouse_id?: {
|
||||||
|
value: number;
|
||||||
|
label: string;
|
||||||
|
};
|
||||||
qty?: number | string;
|
qty?: number | string;
|
||||||
weight?: number | string;
|
weight?: number | string;
|
||||||
}[];
|
}[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type StockSchema = {
|
export type StockSchema = {
|
||||||
product_warehouse_id: number;
|
product_warehouse_id: {
|
||||||
|
value: number;
|
||||||
|
label: string;
|
||||||
|
};
|
||||||
qty: number | string;
|
qty: number | string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DepletionSchema = {
|
export type DepletionSchema = {
|
||||||
product_warehouse_id?: number;
|
product_warehouse_id?: {
|
||||||
|
value: number;
|
||||||
|
label: string;
|
||||||
|
};
|
||||||
source_product_warehouse_id?: number;
|
source_product_warehouse_id?: number;
|
||||||
qty?: number | string;
|
qty?: number | string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type EggSchema = {
|
export type EggSchema = {
|
||||||
product_warehouse_id?: number;
|
product_warehouse_id?: {
|
||||||
|
value: number;
|
||||||
|
label: string;
|
||||||
|
};
|
||||||
qty?: number | string;
|
qty?: number | string;
|
||||||
weight?: number | string;
|
weight?: number | string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const StockObjectSchema: Yup.ObjectSchema<StockSchema> = Yup.object({
|
const StockObjectSchema: Yup.ObjectSchema<StockSchema> = Yup.object({
|
||||||
product_warehouse_id: Yup.number()
|
product_warehouse_id: Yup.object({
|
||||||
|
value: Yup.number().min(1).required(),
|
||||||
|
label: Yup.string().required(),
|
||||||
|
})
|
||||||
.required('Produk wajib diisi!')
|
.required('Produk wajib diisi!')
|
||||||
.min(1, 'Produk wajib diisi!')
|
.typeError('Produk wajib diisi!'),
|
||||||
.typeError('Produk harus berupa angka!'),
|
|
||||||
qty: Yup.number()
|
qty: Yup.number()
|
||||||
.required('Jumlah penggunaan wajib diisi!')
|
.required('Jumlah penggunaan wajib diisi!')
|
||||||
.moreThan(0, 'Jumlah penggunaan harus lebih dari 0!')
|
.moreThan(0, 'Jumlah penggunaan harus lebih dari 0!')
|
||||||
@@ -76,7 +99,10 @@ const StockObjectSchema: Yup.ObjectSchema<StockSchema> = Yup.object({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const DepletionObjectSchema: Yup.ObjectSchema<DepletionSchema> = Yup.object({
|
const DepletionObjectSchema: Yup.ObjectSchema<DepletionSchema> = Yup.object({
|
||||||
product_warehouse_id: Yup.number()
|
product_warehouse_id: Yup.object({
|
||||||
|
value: Yup.number().min(1).required(),
|
||||||
|
label: Yup.string().required(),
|
||||||
|
})
|
||||||
.optional()
|
.optional()
|
||||||
.typeError('Depletions harus berupa angka!'),
|
.typeError('Depletions harus berupa angka!'),
|
||||||
source_product_warehouse_id: Yup.number()
|
source_product_warehouse_id: Yup.number()
|
||||||
@@ -88,7 +114,10 @@ const DepletionObjectSchema: Yup.ObjectSchema<DepletionSchema> = Yup.object({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const EggObjectSchema: Yup.ObjectSchema<EggSchema> = Yup.object({
|
const EggObjectSchema: Yup.ObjectSchema<EggSchema> = Yup.object({
|
||||||
product_warehouse_id: Yup.number()
|
product_warehouse_id: Yup.object({
|
||||||
|
value: Yup.number().min(1).required(),
|
||||||
|
label: Yup.string().required(),
|
||||||
|
})
|
||||||
.optional()
|
.optional()
|
||||||
.typeError('Kondisi telur harus berupa angka!'),
|
.typeError('Kondisi telur harus berupa angka!'),
|
||||||
qty: Yup.number().optional().typeError('Jumlah telur harus berupa angka!'),
|
qty: Yup.number().optional().typeError('Jumlah telur harus berupa angka!'),
|
||||||
@@ -248,14 +277,17 @@ export const getRecordingGrowingFormInitialValues = (
|
|||||||
initialValues?.project_flock?.project_flock_kandang_id ??
|
initialValues?.project_flock?.project_flock_kandang_id ??
|
||||||
0,
|
0,
|
||||||
stocks: initialValues?.stocks?.map((stock) => ({
|
stocks: initialValues?.stocks?.map((stock) => ({
|
||||||
product_warehouse_id: stock.product_warehouse_id,
|
product_warehouse_id: {
|
||||||
|
value: stock.product_warehouse_id,
|
||||||
|
label: getProductWarehouseOptionLabel(stock.product_warehouse),
|
||||||
|
},
|
||||||
qty:
|
qty:
|
||||||
(stock as { qty?: number; usage_amount?: number }).qty ||
|
(stock as { qty?: number; usage_amount?: number }).qty ||
|
||||||
(stock as { qty?: number; usage_amount?: number }).usage_amount ||
|
(stock as { qty?: number; usage_amount?: number }).usage_amount ||
|
||||||
'',
|
'',
|
||||||
})) ?? [
|
})) ?? [
|
||||||
{
|
{
|
||||||
product_warehouse_id: 0,
|
product_warehouse_id: undefined,
|
||||||
qty: '',
|
qty: '',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -263,13 +295,16 @@ export const getRecordingGrowingFormInitialValues = (
|
|||||||
(
|
(
|
||||||
depletion: NonNullable<CreateGrowingRecordingPayload['depletions']>[0]
|
depletion: NonNullable<CreateGrowingRecordingPayload['depletions']>[0]
|
||||||
) => ({
|
) => ({
|
||||||
product_warehouse_id: depletion.product_warehouse_id,
|
product_warehouse_id: {
|
||||||
|
value: Number(depletion.product_warehouse_id ?? 0),
|
||||||
|
label: getProductWarehouseOptionLabel(depletion.product_warehouse),
|
||||||
|
},
|
||||||
source_product_warehouse_id: depletion.source_product_warehouse_id,
|
source_product_warehouse_id: depletion.source_product_warehouse_id,
|
||||||
qty: depletion.qty,
|
qty: depletion.qty,
|
||||||
})
|
})
|
||||||
) ?? [
|
) ?? [
|
||||||
{
|
{
|
||||||
product_warehouse_id: 0,
|
product_warehouse_id: undefined,
|
||||||
qty: '',
|
qty: '',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -281,12 +316,15 @@ export const getRecordingLayingFormInitialValues = (
|
|||||||
...getRecordingGrowingFormInitialValues(initialValues),
|
...getRecordingGrowingFormInitialValues(initialValues),
|
||||||
|
|
||||||
eggs: initialValues?.eggs?.map((egg: CreateEggPayload) => ({
|
eggs: initialValues?.eggs?.map((egg: CreateEggPayload) => ({
|
||||||
product_warehouse_id: egg.product_warehouse_id,
|
product_warehouse_id: {
|
||||||
|
value: Number(egg.product_warehouse_id ?? 0),
|
||||||
|
label: getProductWarehouseOptionLabel(egg.product_warehouse),
|
||||||
|
},
|
||||||
qty: egg.qty,
|
qty: egg.qty,
|
||||||
weight: egg.weight,
|
weight: egg.weight,
|
||||||
})) ?? [
|
})) ?? [
|
||||||
{
|
{
|
||||||
product_warehouse_id: 0,
|
product_warehouse_id: undefined,
|
||||||
qty: '',
|
qty: '',
|
||||||
weight: '',
|
weight: '',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -522,7 +522,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
? values.depletions
|
? values.depletions
|
||||||
?.filter((d) => d.product_warehouse_id && d.qty)
|
?.filter((d) => d.product_warehouse_id && d.qty)
|
||||||
.map((depletion) => ({
|
.map((depletion) => ({
|
||||||
product_warehouse_id: depletion.product_warehouse_id!,
|
product_warehouse_id: depletion.product_warehouse_id?.value ?? 0,
|
||||||
...(depletion.source_product_warehouse_id && {
|
...(depletion.source_product_warehouse_id && {
|
||||||
source_product_warehouse_id:
|
source_product_warehouse_id:
|
||||||
depletion.source_product_warehouse_id,
|
depletion.source_product_warehouse_id,
|
||||||
@@ -533,13 +533,13 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
|
|
||||||
const stocks = recordingRestriction.canEditStock
|
const stocks = recordingRestriction.canEditStock
|
||||||
? (values.stocks ?? [])
|
? (values.stocks ?? [])
|
||||||
.filter((s) => s.product_warehouse_id && s.qty)
|
.filter((s) => s.product_warehouse_id?.value && s.qty)
|
||||||
.map((stock) => ({
|
.map((stock) => ({
|
||||||
// In migration mode, product_warehouse_id field holds product.id;
|
// In migration mode, product_warehouse_id field holds product.id;
|
||||||
// send it as product_id so the backend auto-creates the warehouse entry.
|
// send it as product_id so the backend auto-creates the warehouse entry.
|
||||||
...(isMigrationMode
|
...(isMigrationMode
|
||||||
? { product_id: stock.product_warehouse_id }
|
? { product_id: stock.product_warehouse_id?.value }
|
||||||
: { product_warehouse_id: stock.product_warehouse_id }),
|
: { product_warehouse_id: stock.product_warehouse_id?.value }),
|
||||||
qty: Number(stock.qty) || 0,
|
qty: Number(stock.qty) || 0,
|
||||||
}))
|
}))
|
||||||
: [];
|
: [];
|
||||||
@@ -561,9 +561,9 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
const createLayingPayload = useCallback(
|
const createLayingPayload = useCallback(
|
||||||
(values: RecordingLayingFormValues) => {
|
(values: RecordingLayingFormValues) => {
|
||||||
const depletions = values.depletions
|
const depletions = values.depletions
|
||||||
?.filter((d) => d.product_warehouse_id && d.qty)
|
?.filter((d) => d.product_warehouse_id?.value && d.qty)
|
||||||
.map((depletion) => ({
|
.map((depletion) => ({
|
||||||
product_warehouse_id: depletion.product_warehouse_id!,
|
product_warehouse_id: depletion.product_warehouse_id?.value ?? 0,
|
||||||
...(depletion.source_product_warehouse_id && {
|
...(depletion.source_product_warehouse_id && {
|
||||||
source_product_warehouse_id: depletion.source_product_warehouse_id,
|
source_product_warehouse_id: depletion.source_product_warehouse_id,
|
||||||
}),
|
}),
|
||||||
@@ -573,7 +573,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
const eggs = values.eggs
|
const eggs = values.eggs
|
||||||
?.filter((e) => e.product_warehouse_id && e.qty && e.weight)
|
?.filter((e) => e.product_warehouse_id && e.qty && e.weight)
|
||||||
.map((egg) => ({
|
.map((egg) => ({
|
||||||
product_warehouse_id: egg.product_warehouse_id!,
|
product_warehouse_id: egg.product_warehouse_id?.value ?? 0,
|
||||||
qty: Number(egg.qty) || 0,
|
qty: Number(egg.qty) || 0,
|
||||||
weight:
|
weight:
|
||||||
typeof egg.weight === 'number'
|
typeof egg.weight === 'number'
|
||||||
@@ -583,11 +583,11 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
|
|
||||||
const stocks = recordingRestriction.canEditStock
|
const stocks = recordingRestriction.canEditStock
|
||||||
? values.stocks
|
? values.stocks
|
||||||
.filter((s) => s.product_warehouse_id && s.qty)
|
.filter((s) => s.product_warehouse_id?.value && s.qty)
|
||||||
.map((stock) => ({
|
.map((stock) => ({
|
||||||
...(isMigrationMode
|
...(isMigrationMode
|
||||||
? { product_id: stock.product_warehouse_id }
|
? { product_id: stock.product_warehouse_id?.value }
|
||||||
: { product_warehouse_id: stock.product_warehouse_id }),
|
: { product_warehouse_id: stock.product_warehouse_id?.value }),
|
||||||
qty: Number(stock.qty) || 0,
|
qty: Number(stock.qty) || 0,
|
||||||
}))
|
}))
|
||||||
: [];
|
: [];
|
||||||
@@ -636,21 +636,13 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
rawData: stockProductsPW,
|
rawData: stockProductsPW,
|
||||||
isLoadingOptions: isLoadingStockProductsPW,
|
isLoadingOptions: isLoadingStockProductsPW,
|
||||||
loadMore: loadMoreStockProductsPW,
|
loadMore: loadMoreStockProductsPW,
|
||||||
} = useSelect(
|
} = useSelect(ProductWarehouseApi.basePath, 'id', 'product.name', 'search', {
|
||||||
isMigrationMode ? null : ProductWarehouseApi.basePath,
|
flags: 'PAKAN,OVK',
|
||||||
'id',
|
limit: '100',
|
||||||
'product.name',
|
available_only: 'false',
|
||||||
'search',
|
location_id: stockProductsLocationId,
|
||||||
{
|
...(selectedKandangId ? { kandang_id: selectedKandangId.toString() } : {}),
|
||||||
flags: 'PAKAN,OVK',
|
});
|
||||||
limit: '100',
|
|
||||||
available_only: 'false',
|
|
||||||
location_id: stockProductsLocationId,
|
|
||||||
...(selectedKandangId
|
|
||||||
? { kandang_id: selectedKandangId.toString() }
|
|
||||||
: {}),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
setInputValue: setStockMasterInputValue,
|
setInputValue: setStockMasterInputValue,
|
||||||
@@ -1283,8 +1275,12 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
// product_warehouse object returned by the API.
|
// product_warehouse object returned by the API.
|
||||||
if (isMigrationMode && type === 'edit' && initialValues?.stocks?.length) {
|
if (isMigrationMode && type === 'edit' && initialValues?.stocks?.length) {
|
||||||
baseValues.stocks = initialValues.stocks.map((stock) => ({
|
baseValues.stocks = initialValues.stocks.map((stock) => ({
|
||||||
product_warehouse_id:
|
product_warehouse_id: {
|
||||||
stock.product_warehouse?.product_id ?? stock.product_warehouse_id,
|
value: Number(
|
||||||
|
stock.product_warehouse?.product_id ?? stock.product_warehouse_id
|
||||||
|
),
|
||||||
|
label: getProductWarehouseOptionLabel(stock.product_warehouse),
|
||||||
|
},
|
||||||
qty: stock.usage_amount ?? '',
|
qty: stock.usage_amount ?? '',
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -1438,8 +1434,12 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
formik.setFieldValue(
|
formik.setFieldValue(
|
||||||
'stocks',
|
'stocks',
|
||||||
initialValues.stocks.map((stock) => ({
|
initialValues.stocks.map((stock) => ({
|
||||||
product_warehouse_id:
|
product_warehouse_id: {
|
||||||
stock.product_warehouse?.product_id ?? stock.product_warehouse_id,
|
value: Number(
|
||||||
|
stock.product_warehouse?.product_id ?? stock.product_warehouse_id
|
||||||
|
),
|
||||||
|
label: getProductWarehouseOptionLabel(stock.product_warehouse),
|
||||||
|
},
|
||||||
qty: stock.usage_amount ?? '',
|
qty: stock.usage_amount ?? '',
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
@@ -1462,7 +1462,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
(stockIdx: number) => {
|
(stockIdx: number) => {
|
||||||
if ((type as 'add' | 'edit' | 'detail') === 'detail') return null;
|
if ((type as 'add' | 'edit' | 'detail') === 'detail') return null;
|
||||||
const stock = formik.values.stocks?.[stockIdx];
|
const stock = formik.values.stocks?.[stockIdx];
|
||||||
if (!stock || !stock.product_warehouse_id) return null;
|
if (!stock || !stock.product_warehouse_id?.value) return null;
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
[formik.values.stocks, type]
|
[formik.values.stocks, type]
|
||||||
@@ -1492,13 +1492,17 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
const getStockUsageAdornment = useCallback(
|
const getStockUsageAdornment = useCallback(
|
||||||
(stockIdx: number) => {
|
(stockIdx: number) => {
|
||||||
const stock = formik.values.stocks?.[stockIdx];
|
const stock = formik.values.stocks?.[stockIdx];
|
||||||
if (!stock || !stock.product_warehouse_id) return null;
|
if (!stock || !stock.product_warehouse_id?.value) return null;
|
||||||
|
|
||||||
const isDetail = (type as 'add' | 'edit' | 'detail') === 'detail';
|
const isDetail = (type as 'add' | 'edit' | 'detail') === 'detail';
|
||||||
const availableStock = getAvailableStock(stock.product_warehouse_id);
|
const availableStock = getAvailableStock(
|
||||||
|
stock.product_warehouse_id.value
|
||||||
|
);
|
||||||
const requestedUsage = Number(stock.qty) || 0;
|
const requestedUsage = Number(stock.qty) || 0;
|
||||||
const remainingStock = availableStock - requestedUsage;
|
const remainingStock = availableStock - requestedUsage;
|
||||||
const { pendingQty } = getStockPendingInfo(stock.product_warehouse_id);
|
const { pendingQty } = getStockPendingInfo(
|
||||||
|
stock.product_warehouse_id.value
|
||||||
|
);
|
||||||
|
|
||||||
if (isDetail) {
|
if (isDetail) {
|
||||||
if (pendingQty > 0) {
|
if (pendingQty > 0) {
|
||||||
@@ -1605,10 +1609,10 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
return (
|
return (
|
||||||
idx !== currentIdx &&
|
idx !== currentIdx &&
|
||||||
s.product_warehouse_id &&
|
s.product_warehouse_id &&
|
||||||
s.product_warehouse_id !== 0
|
s.product_warehouse_id.value !== 0
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.map((s) => s.product_warehouse_id) || [];
|
.map((s) => s.product_warehouse_id?.value) || [];
|
||||||
|
|
||||||
return unifiedStockProducts.filter(
|
return unifiedStockProducts.filter(
|
||||||
(opt) => !selectedProductIds.includes(Number(opt.value))
|
(opt) => !selectedProductIds.includes(Number(opt.value))
|
||||||
@@ -1625,10 +1629,10 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
return (
|
return (
|
||||||
idx !== currentIdx &&
|
idx !== currentIdx &&
|
||||||
d.product_warehouse_id &&
|
d.product_warehouse_id &&
|
||||||
d.product_warehouse_id !== 0
|
d.product_warehouse_id.value !== 0
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.map((d) => d.product_warehouse_id) || [];
|
.map((d) => d.product_warehouse_id?.value) || [];
|
||||||
|
|
||||||
return depletionProducts.filter(
|
return depletionProducts.filter(
|
||||||
(opt) => !selectedProductIds.includes(Number(opt.value))
|
(opt) => !selectedProductIds.includes(Number(opt.value))
|
||||||
@@ -1645,10 +1649,10 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
return (
|
return (
|
||||||
idx !== currentIdx &&
|
idx !== currentIdx &&
|
||||||
e.product_warehouse_id &&
|
e.product_warehouse_id &&
|
||||||
e.product_warehouse_id !== 0
|
e.product_warehouse_id.value !== 0
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.map((e) => e.product_warehouse_id) || [];
|
.map((e) => e.product_warehouse_id?.value) || [];
|
||||||
|
|
||||||
return eggProducts.filter(
|
return eggProducts.filter(
|
||||||
(opt) => !selectedProductIds.includes(Number(opt.value))
|
(opt) => !selectedProductIds.includes(Number(opt.value))
|
||||||
@@ -1694,7 +1698,9 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
isError: touchedField && Boolean(errorField?.[column]),
|
isError: touchedField && Boolean(errorField?.[column]),
|
||||||
errorMessage:
|
errorMessage:
|
||||||
touchedField && errorField?.[column]
|
touchedField && errorField?.[column]
|
||||||
? (errorField[column] as string)
|
? errorField[column] instanceof Object
|
||||||
|
? (errorField[column] as OptionType)?.label
|
||||||
|
: (errorField[column] as string)
|
||||||
: '',
|
: '',
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -2901,20 +2907,15 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
<td>
|
<td>
|
||||||
<SelectInput
|
<SelectInput
|
||||||
required
|
required
|
||||||
key={`stock-product-${idx}-${stock.product_warehouse_id}`}
|
key={`stock-product-${idx}-${stock.product_warehouse_id?.value}`}
|
||||||
value={
|
value={stock.product_warehouse_id}
|
||||||
unifiedStockProducts.find(
|
|
||||||
(product) =>
|
|
||||||
product.value === stock.product_warehouse_id
|
|
||||||
) || null
|
|
||||||
}
|
|
||||||
onInputChange={setStockInputValue}
|
onInputChange={setStockInputValue}
|
||||||
onChange={(selectedOption) => {
|
onChange={(selectedOption) => {
|
||||||
const option =
|
const option =
|
||||||
selectedOption as OptionType | null;
|
selectedOption as OptionType | null;
|
||||||
formik.setFieldValue(
|
formik.setFieldValue(
|
||||||
`stocks.${idx}.product_warehouse_id`,
|
`stocks.${idx}.product_warehouse_id`,
|
||||||
option?.value || 0
|
option
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
options={getAvailableStockProductOptions(idx)}
|
options={getAvailableStockProductOptions(idx)}
|
||||||
@@ -2950,9 +2951,9 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
}
|
}
|
||||||
isClearable={type !== 'detail'}
|
isClearable={type !== 'detail'}
|
||||||
inputPrefix={
|
inputPrefix={
|
||||||
stock.product_warehouse_id
|
stock.product_warehouse_id?.value
|
||||||
? getProductFlagBadgeAdornment(
|
? getProductFlagBadgeAdornment(
|
||||||
stock.product_warehouse_id
|
stock.product_warehouse_id.value
|
||||||
)
|
)
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
@@ -2988,7 +2989,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
inputSuffix={
|
inputSuffix={
|
||||||
stock.product_warehouse_id
|
stock.product_warehouse_id
|
||||||
? getProductUomSuffix(
|
? getProductUomSuffix(
|
||||||
stock.product_warehouse_id,
|
stock.product_warehouse_id.value,
|
||||||
'stock'
|
'stock'
|
||||||
)
|
)
|
||||||
: null
|
: null
|
||||||
@@ -3181,19 +3182,13 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
)}
|
)}
|
||||||
<td>
|
<td>
|
||||||
<SelectInput
|
<SelectInput
|
||||||
value={
|
value={depletion.product_warehouse_id}
|
||||||
depletionProducts.find(
|
|
||||||
(product) =>
|
|
||||||
product.value ===
|
|
||||||
depletion.product_warehouse_id
|
|
||||||
) || null
|
|
||||||
}
|
|
||||||
onChange={(selectedOption) => {
|
onChange={(selectedOption) => {
|
||||||
const option =
|
const option =
|
||||||
selectedOption as OptionType | null;
|
selectedOption as OptionType | null;
|
||||||
formik.setFieldValue(
|
formik.setFieldValue(
|
||||||
`depletions.${idx}.product_warehouse_id`,
|
`depletions.${idx}.product_warehouse_id`,
|
||||||
option?.value || 0
|
option
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
options={getAvailableDepletionProductOptions(idx)}
|
options={getAvailableDepletionProductOptions(idx)}
|
||||||
@@ -3256,7 +3251,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
inputSuffix={
|
inputSuffix={
|
||||||
depletion.product_warehouse_id
|
depletion.product_warehouse_id
|
||||||
? getProductUomSuffix(
|
? getProductUomSuffix(
|
||||||
depletion.product_warehouse_id,
|
depletion.product_warehouse_id.value,
|
||||||
'depletion'
|
'depletion'
|
||||||
)
|
)
|
||||||
: null
|
: null
|
||||||
@@ -3434,18 +3429,13 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
)}
|
)}
|
||||||
<td>
|
<td>
|
||||||
<SelectInput
|
<SelectInput
|
||||||
value={
|
value={egg.product_warehouse_id}
|
||||||
eggProducts.find(
|
|
||||||
(product) =>
|
|
||||||
product.value === egg.product_warehouse_id
|
|
||||||
) || null
|
|
||||||
}
|
|
||||||
onChange={(selectedOption) => {
|
onChange={(selectedOption) => {
|
||||||
const option =
|
const option =
|
||||||
selectedOption as OptionType | null;
|
selectedOption as OptionType | null;
|
||||||
formik.setFieldValue(
|
formik.setFieldValue(
|
||||||
`eggs.${idx}.product_warehouse_id`,
|
`eggs.${idx}.product_warehouse_id`,
|
||||||
option?.value || 0
|
option
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
options={getAvailableEggProductOptions(idx)}
|
options={getAvailableEggProductOptions(idx)}
|
||||||
|
|||||||
@@ -223,6 +223,8 @@ const TransferToLayingFormModal = () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { flockSource: formikFlockSource } = formik.values;
|
||||||
|
|
||||||
const { formErrorList, close, handleFormSubmit } = useFormikErrorList(formik);
|
const { formErrorList, close, handleFormSubmit } = useFormikErrorList(formik);
|
||||||
|
|
||||||
const [selectedFlockSourceRawData, setSelectedFlockSourceRawData] = useState<
|
const [selectedFlockSourceRawData, setSelectedFlockSourceRawData] = useState<
|
||||||
@@ -455,13 +457,13 @@ const TransferToLayingFormModal = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isResponseSuccess(flockSourceRawData)) {
|
if (isResponseSuccess(flockSourceRawData)) {
|
||||||
const selectedFlockSourceRawData = flockSourceRawData.data.find(
|
const currentSelectedFlockSourceRawData = flockSourceRawData.data.find(
|
||||||
(item) => item.id === formik.values.flockSource?.value
|
(item) => item.id === formik.values.flockSource?.value
|
||||||
);
|
);
|
||||||
|
|
||||||
setSelectedFlockSourceRawData(selectedFlockSourceRawData);
|
setSelectedFlockSourceRawData(currentSelectedFlockSourceRawData);
|
||||||
}
|
}
|
||||||
}, [flockSourceRawData]);
|
}, [flockSourceRawData, formikFlockSource]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
formik.setFieldValue('totalQuantity', totalTransferedChicken);
|
formik.setFieldValue('totalQuantity', totalTransferedChicken);
|
||||||
@@ -625,6 +627,7 @@ const TransferToLayingFormModal = () => {
|
|||||||
>
|
>
|
||||||
<div className='flex flex-row items-center gap-3'>
|
<div className='flex flex-row items-center gap-3'>
|
||||||
<input
|
<input
|
||||||
|
id={`flock-source-kandang-${item.project_flock_kandang_id}`}
|
||||||
type='radio'
|
type='radio'
|
||||||
name='flockSourceKandang'
|
name='flockSourceKandang'
|
||||||
value={item.project_flock_kandang_id}
|
value={item.project_flock_kandang_id}
|
||||||
@@ -637,13 +640,14 @@ const TransferToLayingFormModal = () => {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<label
|
<label
|
||||||
|
htmlFor={`flock-source-kandang-${item.project_flock_kandang_id}`}
|
||||||
className={cn('text-sm text-base-content/50', {
|
className={cn('text-sm text-base-content/50', {
|
||||||
'cursor-pointer': isAvailable,
|
'cursor-pointer': isAvailable,
|
||||||
'cursor-not-allowed opacity-50': !isAvailable,
|
'cursor-not-allowed opacity-50': !isAvailable,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{item.kandang_name}{' '}
|
{item.kandang_name}{' '}
|
||||||
<span className='text-base-content/20'>{`(Max: ${item.available_qty})`}</span>
|
<span className='text-base-content/20'>{`(Max: ${item.available_qty ?? '-'})`}</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -409,10 +409,17 @@ const PurchaseTable = () => {
|
|||||||
setIsDeleteLoading(true);
|
setIsDeleteLoading(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await PurchaseApi.delete(selectedPurchase?.id as number);
|
const deleteResponse = await PurchaseApi.delete(
|
||||||
refreshPurchaseRequests();
|
selectedPurchase?.id as number
|
||||||
deleteModal.closeModal();
|
);
|
||||||
toast.success('Berhasil menghapus data permintaan pembelian!');
|
|
||||||
|
if (isResponseSuccess(deleteResponse)) {
|
||||||
|
refreshPurchaseRequests();
|
||||||
|
deleteModal.closeModal();
|
||||||
|
toast.success('Berhasil menghapus data permintaan pembelian!');
|
||||||
|
} else {
|
||||||
|
toast.error(deleteResponse?.message ?? 'Gagal menghapus data!');
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
toast.error('Gagal menghapus data permintaan pembelian!');
|
toast.error('Gagal menghapus data permintaan pembelian!');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,7 +89,10 @@ export function Dashboard() {
|
|||||||
options: kandangOptions,
|
options: kandangOptions,
|
||||||
loadMore: loadMoreKandang,
|
loadMore: loadMoreKandang,
|
||||||
isLoadingMore: isLoadingMoreKandang,
|
isLoadingMore: isLoadingMoreKandang,
|
||||||
} = useSelect(DailyChecklistKandangApi.basePath, 'id', 'name');
|
} = useSelect(DailyChecklistKandangApi.basePath, 'id', 'name', 'search', {
|
||||||
|
order_by: 'asc',
|
||||||
|
sort_by: 'name',
|
||||||
|
});
|
||||||
|
|
||||||
const handleKandangScroll = (e: React.UIEvent<HTMLDivElement>) => {
|
const handleKandangScroll = (e: React.UIEvent<HTMLDivElement>) => {
|
||||||
const target = e.target as HTMLDivElement;
|
const target = e.target as HTMLDivElement;
|
||||||
|
|||||||
@@ -110,7 +110,10 @@ export function ListDailyChecklistContent() {
|
|||||||
options: kandangOptions,
|
options: kandangOptions,
|
||||||
isLoadingMore: isLoadingMoreKandang,
|
isLoadingMore: isLoadingMoreKandang,
|
||||||
loadMore: loadMoreKandang,
|
loadMore: loadMoreKandang,
|
||||||
} = useSelect(DailyChecklistKandangApi.basePath, 'id', 'name');
|
} = useSelect(DailyChecklistKandangApi.basePath, 'id', 'name', 'search', {
|
||||||
|
order_by: 'asc',
|
||||||
|
sort_by: 'name',
|
||||||
|
});
|
||||||
|
|
||||||
const checklistList = isResponseSuccess(checklistListRes)
|
const checklistList = isResponseSuccess(checklistListRes)
|
||||||
? checklistListRes.data || []
|
? checklistListRes.data || []
|
||||||
|
|||||||
@@ -96,7 +96,10 @@ export function MasterEmployeeContent() {
|
|||||||
options: kandangOptions,
|
options: kandangOptions,
|
||||||
loadMore: loadMoreKandang,
|
loadMore: loadMoreKandang,
|
||||||
isLoadingMore: isLoadingMoreKandang,
|
isLoadingMore: isLoadingMoreKandang,
|
||||||
} = useSelect(DailyChecklistKandangApi.basePath, 'id', 'name');
|
} = useSelect(DailyChecklistKandangApi.basePath, 'id', 'name', 'search', {
|
||||||
|
order_by: 'asc',
|
||||||
|
sort_by: 'name',
|
||||||
|
});
|
||||||
|
|
||||||
const handleKandangScroll = (e: React.UIEvent<HTMLDivElement>) => {
|
const handleKandangScroll = (e: React.UIEvent<HTMLDivElement>) => {
|
||||||
const target = e.target as HTMLDivElement;
|
const target = e.target as HTMLDivElement;
|
||||||
|
|||||||
@@ -368,7 +368,9 @@ export function MasterKandangContent() {
|
|||||||
name='search'
|
name='search'
|
||||||
placeholder='Cari kandang...'
|
placeholder='Cari kandang...'
|
||||||
value={tableFilterState.search}
|
value={tableFilterState.search}
|
||||||
onChange={(e) => updateFilter('search', e.target.value)}
|
onChange={(e) =>
|
||||||
|
updateFilter('search', e.target.value, true)
|
||||||
|
}
|
||||||
className={{
|
className={{
|
||||||
wrapper: 'w-full sm:w-[280px] border-gray-200',
|
wrapper: 'w-full sm:w-[280px] border-gray-200',
|
||||||
inputWrapper: 'px-3 py-2 h-fit rounded-md',
|
inputWrapper: 'px-3 py-2 h-fit rounded-md',
|
||||||
@@ -383,7 +385,11 @@ export function MasterKandangContent() {
|
|||||||
<Select
|
<Select
|
||||||
value={tableFilterState.location_id}
|
value={tableFilterState.location_id}
|
||||||
onValueChange={(value) =>
|
onValueChange={(value) =>
|
||||||
updateFilter('location_id', value === 'all' ? '' : value)
|
updateFilter(
|
||||||
|
'location_id',
|
||||||
|
value === 'all' ? '' : value,
|
||||||
|
true
|
||||||
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<SelectTrigger className='w-[180px] border-gray-200'>
|
<SelectTrigger className='w-[180px] border-gray-200'>
|
||||||
|
|||||||
@@ -137,6 +137,8 @@ export function DailyChecklistReportsContent() {
|
|||||||
} = useSelect(DailyChecklistKandangApi.basePath, 'id', 'name', 'search', {
|
} = useSelect(DailyChecklistKandangApi.basePath, 'id', 'name', 'search', {
|
||||||
area_id: tableFilterState.area_id,
|
area_id: tableFilterState.area_id,
|
||||||
location_id: tableFilterState.location_id,
|
location_id: tableFilterState.location_id,
|
||||||
|
order_by: 'asc',
|
||||||
|
sort_by: 'name',
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleKandangScroll = (e: React.UIEvent<HTMLDivElement>) => {
|
const handleKandangScroll = (e: React.UIEvent<HTMLDivElement>) => {
|
||||||
@@ -159,17 +161,24 @@ export function DailyChecklistReportsContent() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const { options: employeeOptions } = useSelect(
|
const {
|
||||||
EmployeeApi.basePath,
|
options: employeeOptions,
|
||||||
'id',
|
loadMore: loadMoreEmployee,
|
||||||
'name',
|
isLoadingMore: isLoadingMoreEmployee,
|
||||||
'search',
|
} = useSelect(EmployeeApi.basePath, 'id', 'name', 'search', {
|
||||||
{
|
order_by: 'asc',
|
||||||
page: '1',
|
sort_by: 'name',
|
||||||
limit: '500',
|
kandang_id: tableFilterState.kandang_id,
|
||||||
kandang_id: tableFilterState.kandang_id,
|
});
|
||||||
|
|
||||||
|
const handleEmployeeScroll = (e: React.UIEvent<HTMLDivElement>) => {
|
||||||
|
const target = e.target as HTMLDivElement;
|
||||||
|
if (target.scrollHeight - target.scrollTop <= target.clientHeight + 10) {
|
||||||
|
if (!isLoadingMoreEmployee) {
|
||||||
|
loadMoreEmployee();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
};
|
||||||
|
|
||||||
const currentMonthMaxDay = new Date(
|
const currentMonthMaxDay = new Date(
|
||||||
Number(tableFilterState.tahun),
|
Number(tableFilterState.tahun),
|
||||||
@@ -493,7 +502,7 @@ export function DailyChecklistReportsContent() {
|
|||||||
>
|
>
|
||||||
<SelectValue placeholder='Semua ABK' />
|
<SelectValue placeholder='Semua ABK' />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent onScroll={handleEmployeeScroll}>
|
||||||
<SelectItem value='ALL'>Semua ABK</SelectItem>
|
<SelectItem value='ALL'>Semua ABK</SelectItem>
|
||||||
{employeeOptions.map((employee) => (
|
{employeeOptions.map((employee) => (
|
||||||
<SelectItem
|
<SelectItem
|
||||||
@@ -503,6 +512,11 @@ export function DailyChecklistReportsContent() {
|
|||||||
{employee.label}
|
{employee.label}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
))}
|
))}
|
||||||
|
{isLoadingMoreEmployee && (
|
||||||
|
<div className='flex justify-center p-2'>
|
||||||
|
<Loader2 className='h-4 w-4 animate-spin text-gray-500' />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { RequestOptions } from '@/services/http/base';
|
|||||||
import { redirectToSSO } from '@/lib/auth-helper';
|
import { redirectToSSO } from '@/lib/auth-helper';
|
||||||
|
|
||||||
const BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL ?? '';
|
const BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL ?? '';
|
||||||
const axiosClient = axios.create({ baseURL: BASE_URL, timeout: 30_000 });
|
const axiosClient = axios.create({ baseURL: BASE_URL, timeout: 60_000 });
|
||||||
|
|
||||||
axiosClient.interceptors.response.use(
|
axiosClient.interceptors.response.use(
|
||||||
(response) => response,
|
(response) => response,
|
||||||
@@ -38,7 +38,7 @@ export async function httpClient<T, B = unknown>(
|
|||||||
method: opts.method ?? 'GET',
|
method: opts.method ?? 'GET',
|
||||||
params: opts.query,
|
params: opts.query,
|
||||||
data: opts.body,
|
data: opts.body,
|
||||||
timeout: opts.timeoutMs ?? 30_000,
|
timeout: opts.timeoutMs ?? 60_000,
|
||||||
withCredentials: isCookieAuth && !isBearerAuth,
|
withCredentials: isCookieAuth && !isBearerAuth,
|
||||||
responseType: opts.responseType,
|
responseType: opts.responseType,
|
||||||
headers: {
|
headers: {
|
||||||
|
|||||||
+2
@@ -117,6 +117,7 @@ export type CreateGrowingRecordingPayload = {
|
|||||||
product_warehouse_id?: number;
|
product_warehouse_id?: number;
|
||||||
source_product_warehouse_id?: number;
|
source_product_warehouse_id?: number;
|
||||||
qty?: number;
|
qty?: number;
|
||||||
|
product_warehouse?: ProductWarehouse;
|
||||||
}[];
|
}[];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -124,6 +125,7 @@ export type CreateEggPayload = {
|
|||||||
product_warehouse_id?: number;
|
product_warehouse_id?: number;
|
||||||
qty?: number;
|
qty?: number;
|
||||||
weight?: number;
|
weight?: number;
|
||||||
|
product_warehouse?: ProductWarehouse;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type CreateLayingRecordingPayload = CreateGrowingRecordingPayload & {
|
export type CreateLayingRecordingPayload = CreateGrowingRecordingPayload & {
|
||||||
|
|||||||
Reference in New Issue
Block a user