mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 21:41:57 +00:00
refactor(FE): Refactor filter schema and form handling for
PurchasesPerSupplier
This commit is contained in:
@@ -1,88 +1,38 @@
|
||||
import { OptionType } from '@/components/input/SelectInput';
|
||||
import * as yup from 'yup';
|
||||
|
||||
export type PurchasesPerSupplierFilterType = {
|
||||
start_date: string | null | undefined;
|
||||
end_date: string | null | undefined;
|
||||
area_ids: OptionType[] | null | undefined;
|
||||
supplier_ids: OptionType[] | null | undefined;
|
||||
product_ids: OptionType[] | null | undefined;
|
||||
product_category_ids: OptionType[] | null | undefined;
|
||||
filter_by: OptionType | null | undefined;
|
||||
sort_by: OptionType | null | undefined;
|
||||
start_date: string | null;
|
||||
end_date: string | null;
|
||||
area_ids: string | null;
|
||||
supplier_ids: string | null;
|
||||
product_ids: string | null;
|
||||
product_category_ids: string | null;
|
||||
filter_by: string | null;
|
||||
sort_by: string | null;
|
||||
};
|
||||
|
||||
export const PurchasesPerSupplierFilterSchema: yup.ObjectSchema<PurchasesPerSupplierFilterType> =
|
||||
yup.object({
|
||||
start_date: yup.string().optional().nullable(),
|
||||
end_date: yup
|
||||
.string()
|
||||
.optional()
|
||||
.nullable()
|
||||
.test(
|
||||
'is-greater-than-start',
|
||||
'Tanggal akhir tidak boleh masa lampau',
|
||||
function (value) {
|
||||
const { start_date } = this.parent;
|
||||
if (!start_date || !value) return true;
|
||||
return new Date(value) >= new Date(start_date);
|
||||
}
|
||||
),
|
||||
area_ids: yup
|
||||
.array()
|
||||
.of(
|
||||
yup.object({
|
||||
value: yup.mixed<string | number>().required(),
|
||||
label: yup.string().required(),
|
||||
})
|
||||
)
|
||||
.optional()
|
||||
.nullable(),
|
||||
supplier_ids: yup
|
||||
.array()
|
||||
.of(
|
||||
yup.object({
|
||||
value: yup.mixed<string | number>().required(),
|
||||
label: yup.string().required(),
|
||||
})
|
||||
)
|
||||
.optional()
|
||||
.nullable(),
|
||||
product_ids: yup
|
||||
.array()
|
||||
.of(
|
||||
yup.object({
|
||||
value: yup.mixed<string | number>().required(),
|
||||
label: yup.string().required(),
|
||||
})
|
||||
)
|
||||
.optional()
|
||||
.nullable(),
|
||||
product_category_ids: yup
|
||||
.array()
|
||||
.of(
|
||||
yup.object({
|
||||
value: yup.mixed<string | number>().required(),
|
||||
label: yup.string().required(),
|
||||
})
|
||||
)
|
||||
.optional()
|
||||
.nullable(),
|
||||
filter_by: yup
|
||||
.object({
|
||||
value: yup.mixed<string | number>().required(),
|
||||
label: yup.string().required(),
|
||||
})
|
||||
.optional()
|
||||
.nullable(),
|
||||
sort_by: yup
|
||||
.object({
|
||||
value: yup.mixed<string | number>().required(),
|
||||
label: yup.string().required(),
|
||||
})
|
||||
.optional()
|
||||
.nullable(),
|
||||
});
|
||||
export const PurchasesPerSupplierFilterSchema = yup.object({
|
||||
start_date: yup.string().optional().nullable(),
|
||||
end_date: yup
|
||||
.string()
|
||||
.optional()
|
||||
.nullable()
|
||||
.test(
|
||||
'is-greater-than-start',
|
||||
'Tanggal akhir tidak boleh masa lampau',
|
||||
function (value) {
|
||||
const { start_date } = this.parent;
|
||||
if (!start_date || !value) return true;
|
||||
return new Date(value) >= new Date(start_date);
|
||||
}
|
||||
),
|
||||
area_ids: yup.string().nullable(),
|
||||
supplier_ids: yup.string().nullable(),
|
||||
product_ids: yup.string().nullable(),
|
||||
product_category_ids: yup.string().nullable(),
|
||||
filter_by: yup.string().nullable(),
|
||||
sort_by: yup.string().nullable(),
|
||||
});
|
||||
|
||||
export type PurchasesPerSupplierFilterValues = yup.InferType<
|
||||
typeof PurchasesPerSupplierFilterSchema
|
||||
|
||||
@@ -125,21 +125,14 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
|
||||
validationSchema: PurchasesPerSupplierFilterSchema,
|
||||
onSubmit: (values, { setSubmitting }) => {
|
||||
setFilterParams({
|
||||
start_date: values.start_date?.toString() || undefined,
|
||||
end_date: values.end_date?.toString() || undefined,
|
||||
area_id:
|
||||
values.area_ids?.map((v) => String(v.value)).join(',') || undefined,
|
||||
supplier_id:
|
||||
values.supplier_ids?.map((v) => String(v.value)).join(',') ||
|
||||
undefined,
|
||||
product_id:
|
||||
values.product_ids?.map((v) => String(v.value)).join(',') ||
|
||||
undefined,
|
||||
product_category_id:
|
||||
values.product_category_ids?.map((v) => String(v.value)).join(',') ||
|
||||
undefined,
|
||||
filter_by: values.filter_by?.value?.toString() || undefined,
|
||||
sort_by: values.sort_by?.value?.toString() || undefined,
|
||||
start_date: values.start_date || undefined,
|
||||
end_date: values.end_date || undefined,
|
||||
area_id: values.area_ids || undefined,
|
||||
supplier_id: values.supplier_ids || undefined,
|
||||
product_id: values.product_ids || undefined,
|
||||
product_category_id: values.product_category_ids || undefined,
|
||||
filter_by: values.filter_by || undefined,
|
||||
sort_by: values.sort_by || undefined,
|
||||
});
|
||||
filterModal.closeModal();
|
||||
setIsSubmitted(true);
|
||||
@@ -220,6 +213,48 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
|
||||
[formik, dateErrorShown]
|
||||
);
|
||||
|
||||
// ===== DERIVED VALUES =====
|
||||
const areaIdsValue = useMemo(() => {
|
||||
if (!formik.values.area_ids) return [];
|
||||
const ids = formik.values.area_ids.split(',');
|
||||
return areaOptions.filter((opt) => ids.includes(String(opt.value)));
|
||||
}, [formik.values.area_ids, areaOptions]);
|
||||
|
||||
const supplierIdsValue = useMemo(() => {
|
||||
if (!formik.values.supplier_ids) return [];
|
||||
const ids = formik.values.supplier_ids.split(',');
|
||||
return supplierOptions.filter((opt) => ids.includes(String(opt.value)));
|
||||
}, [formik.values.supplier_ids, supplierOptions]);
|
||||
|
||||
const productIdsValue = useMemo(() => {
|
||||
if (!formik.values.product_ids) return [];
|
||||
const ids = formik.values.product_ids.split(',');
|
||||
return productOptions.filter((opt) => ids.includes(String(opt.value)));
|
||||
}, [formik.values.product_ids, productOptions]);
|
||||
|
||||
const productCategoryIdsValue = useMemo(() => {
|
||||
if (!formik.values.product_category_ids) return [];
|
||||
const ids = formik.values.product_category_ids.split(',');
|
||||
return productCategoryOptions.filter((opt) =>
|
||||
ids.includes(String(opt.value))
|
||||
);
|
||||
}, [formik.values.product_category_ids, productCategoryOptions]);
|
||||
|
||||
const filterByValue = useMemo(() => {
|
||||
if (!formik.values.filter_by) return null;
|
||||
return (
|
||||
dataTypeOptions.find((opt) => opt.value === formik.values.filter_by) ||
|
||||
null
|
||||
);
|
||||
}, [formik.values.filter_by, dataTypeOptions]);
|
||||
|
||||
const sortByValue = useMemo(() => {
|
||||
if (!formik.values.sort_by) return null;
|
||||
return (
|
||||
sortByOptions.find((opt) => opt.value === formik.values.sort_by) || null
|
||||
);
|
||||
}, [formik.values.sort_by, sortByOptions]);
|
||||
|
||||
// ===== ACTIVE FILTERS COUNT =====
|
||||
const activeFiltersCount = useMemo(() => {
|
||||
let count = 0;
|
||||
@@ -875,17 +910,13 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
|
||||
label='Area'
|
||||
placeholder='Pilih Area'
|
||||
options={areaOptions}
|
||||
value={
|
||||
(formik.values.area_ids as
|
||||
| { value: number; label: string }
|
||||
| { value: number; label: string }[]
|
||||
| null
|
||||
| undefined) || []
|
||||
}
|
||||
value={areaIdsValue}
|
||||
onChange={(val) => {
|
||||
formik.setFieldValue(
|
||||
'area_ids',
|
||||
Array.isArray(val) ? val : val ? [val] : null
|
||||
Array.isArray(val) && val.length > 0
|
||||
? val.map((v) => String(v.value)).join(',')
|
||||
: null
|
||||
);
|
||||
}}
|
||||
isLoading={isLoadingAreas}
|
||||
@@ -898,17 +929,13 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
|
||||
label='Supplier'
|
||||
placeholder='Pilih Supplier'
|
||||
options={supplierOptions}
|
||||
value={
|
||||
(formik.values.supplier_ids as
|
||||
| { value: number; label: string }
|
||||
| { value: number; label: string }[]
|
||||
| null
|
||||
| undefined) || []
|
||||
}
|
||||
value={supplierIdsValue}
|
||||
onChange={(val) => {
|
||||
formik.setFieldValue(
|
||||
'supplier_ids',
|
||||
Array.isArray(val) ? val : val ? [val] : null
|
||||
Array.isArray(val) && val.length > 0
|
||||
? val.map((v) => String(v.value)).join(',')
|
||||
: null
|
||||
);
|
||||
}}
|
||||
isLoading={isLoadingSuppliers}
|
||||
@@ -921,17 +948,13 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
|
||||
label='Produk'
|
||||
placeholder='Pilih Produk'
|
||||
options={productOptions}
|
||||
value={
|
||||
(formik.values.product_ids as
|
||||
| { value: number; label: string }
|
||||
| { value: number; label: string }[]
|
||||
| null
|
||||
| undefined) || []
|
||||
}
|
||||
value={productIdsValue}
|
||||
onChange={(val) => {
|
||||
formik.setFieldValue(
|
||||
'product_ids',
|
||||
Array.isArray(val) ? val : val ? [val] : null
|
||||
Array.isArray(val) && val.length > 0
|
||||
? val.map((v) => String(v.value)).join(',')
|
||||
: null
|
||||
);
|
||||
}}
|
||||
isLoading={isLoadingProducts}
|
||||
@@ -944,17 +967,13 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
|
||||
label='Kategori Produk'
|
||||
placeholder='Pilih Kategori Produk'
|
||||
options={productCategoryOptions}
|
||||
value={
|
||||
(formik.values.product_category_ids as
|
||||
| { value: number; label: string }
|
||||
| { value: number; label: string }[]
|
||||
| null
|
||||
| undefined) || []
|
||||
}
|
||||
value={productCategoryIdsValue}
|
||||
onChange={(val) => {
|
||||
formik.setFieldValue(
|
||||
'product_category_ids',
|
||||
Array.isArray(val) ? val : val ? [val] : null
|
||||
Array.isArray(val) && val.length > 0
|
||||
? val.map((v) => String(v.value)).join(',')
|
||||
: null
|
||||
);
|
||||
}}
|
||||
isLoading={isLoadingProductCategories}
|
||||
@@ -967,15 +986,13 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
|
||||
label='Filter Berdasarkan'
|
||||
placeholder='Pilih Filter Berdasarkan'
|
||||
options={dataTypeOptions}
|
||||
value={
|
||||
(formik.values.filter_by as
|
||||
| { value: string; label: string }
|
||||
| null
|
||||
| undefined) || null
|
||||
}
|
||||
value={filterByValue}
|
||||
onChange={(val) => {
|
||||
if (!Array.isArray(val)) {
|
||||
formik.setFieldValue('filter_by', val);
|
||||
formik.setFieldValue(
|
||||
'filter_by',
|
||||
val?.value?.toString() || null
|
||||
);
|
||||
}
|
||||
}}
|
||||
className={{ wrapper: 'w-full' }}
|
||||
@@ -987,15 +1004,13 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
|
||||
label='Urutkan Berdasarkan'
|
||||
placeholder='Pilih Urutkan Berdasarkan'
|
||||
options={sortByOptions}
|
||||
value={
|
||||
(formik.values.sort_by as
|
||||
| { value: string; label: string }
|
||||
| null
|
||||
| undefined) || null
|
||||
}
|
||||
value={sortByValue}
|
||||
onChange={(val) => {
|
||||
if (!Array.isArray(val)) {
|
||||
formik.setFieldValue('sort_by', val);
|
||||
formik.setFieldValue(
|
||||
'sort_by',
|
||||
val?.value?.toString() || null
|
||||
);
|
||||
}
|
||||
}}
|
||||
className={{ wrapper: 'w-full' }}
|
||||
|
||||
Reference in New Issue
Block a user