mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
Merge branch 'fix/purchase-form' into 'development'
[FIX/FE] Purchase Form & Expense Filter See merge request mbugroup/lti-web-client!421
This commit is contained in:
@@ -51,7 +51,9 @@ type ExpenseTableFilters = {
|
||||
transactionDate: string;
|
||||
realizationDate: string;
|
||||
locationId: string;
|
||||
locationName: string;
|
||||
vendorId: string;
|
||||
vendorName: string;
|
||||
userId: string;
|
||||
};
|
||||
|
||||
@@ -235,6 +237,7 @@ const ExpensesTable = () => {
|
||||
setPage,
|
||||
setPageSize,
|
||||
toQueryString: getTableFilterQueryString,
|
||||
reset: resetFilter,
|
||||
} = useTableFilter<ExpenseTableFilters>({
|
||||
initial: {
|
||||
page: 1,
|
||||
@@ -244,7 +247,9 @@ const ExpensesTable = () => {
|
||||
transactionDate: '',
|
||||
realizationDate: '',
|
||||
locationId: '',
|
||||
locationName: '',
|
||||
vendorId: '',
|
||||
vendorName: '',
|
||||
userId: '',
|
||||
},
|
||||
paramMap: {
|
||||
@@ -254,7 +259,9 @@ const ExpensesTable = () => {
|
||||
transactionDate: 'transaction_date',
|
||||
realizationDate: 'realization_date',
|
||||
locationId: 'location_id',
|
||||
locationName: 'location_name',
|
||||
vendorId: 'vendor_id',
|
||||
vendorName: 'vendor_name',
|
||||
userId: 'user_id',
|
||||
},
|
||||
|
||||
@@ -740,20 +747,31 @@ const ExpensesTable = () => {
|
||||
const handleFilterSubmit = (values: {
|
||||
transaction_date?: string | null;
|
||||
realization_date?: string | null;
|
||||
location_id?: string | null;
|
||||
vendor_id?: string | null;
|
||||
location?: { value: number; label: string } | null;
|
||||
vendor?: { value: number; label: string } | null;
|
||||
}) => {
|
||||
updateFilter('transactionDate', values.transaction_date || '');
|
||||
updateFilter('realizationDate', values.realization_date || '');
|
||||
updateFilter('locationId', values.location_id || '');
|
||||
updateFilter('vendorId', values.vendor_id || '');
|
||||
updateFilter(
|
||||
'locationId',
|
||||
values.location?.value ? String(values.location?.value) : ''
|
||||
);
|
||||
updateFilter(
|
||||
'locationName',
|
||||
values.location?.label ? String(values.location?.label) : ''
|
||||
);
|
||||
updateFilter(
|
||||
'vendorId',
|
||||
values.vendor?.value ? String(values.vendor?.value) : ''
|
||||
);
|
||||
updateFilter(
|
||||
'vendorName',
|
||||
values.vendor?.label ? String(values.vendor?.label) : ''
|
||||
);
|
||||
};
|
||||
|
||||
const handleFilterReset = () => {
|
||||
updateFilter('transactionDate', '');
|
||||
updateFilter('realizationDate', '');
|
||||
updateFilter('locationId', '');
|
||||
updateFilter('vendorId', '');
|
||||
resetFilter();
|
||||
};
|
||||
|
||||
// track sorting
|
||||
@@ -927,6 +945,8 @@ const ExpensesTable = () => {
|
||||
'search',
|
||||
'nameSort',
|
||||
'userId',
|
||||
'locationName',
|
||||
'vendorName',
|
||||
]}
|
||||
onClick={handleFilterModalOpen}
|
||||
className='px-3 py-2.5'
|
||||
@@ -1245,6 +1265,24 @@ const ExpensesTable = () => {
|
||||
ref={filterModal.ref}
|
||||
onSubmit={handleFilterSubmit}
|
||||
onReset={handleFilterReset}
|
||||
initialValues={{
|
||||
location:
|
||||
tableFilterState.locationId && tableFilterState.locationName
|
||||
? {
|
||||
value: Number(tableFilterState.locationId),
|
||||
label: tableFilterState.locationName,
|
||||
}
|
||||
: null,
|
||||
vendor:
|
||||
tableFilterState.vendorId && tableFilterState.vendorName
|
||||
? {
|
||||
value: Number(tableFilterState.vendorId),
|
||||
label: tableFilterState.vendorName,
|
||||
}
|
||||
: null,
|
||||
realization_date: tableFilterState.realizationDate,
|
||||
transaction_date: tableFilterState.transactionDate,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -3,8 +3,8 @@ import * as yup from 'yup';
|
||||
export type ExpensesFilterType = {
|
||||
transaction_date: string | null;
|
||||
realization_date: string | null;
|
||||
location_id: string | null;
|
||||
vendor_id: string | null;
|
||||
location: { value: number; label: string } | null;
|
||||
vendor: { value: number; label: string } | null;
|
||||
};
|
||||
|
||||
export const ExpensesFilterSchema = yup.object({
|
||||
@@ -21,8 +21,18 @@ export const ExpensesFilterSchema = yup.object({
|
||||
return new Date(value) >= new Date(transaction_date);
|
||||
}
|
||||
),
|
||||
location_id: yup.string().nullable(),
|
||||
vendor_id: yup.string().nullable(),
|
||||
location: yup
|
||||
.object({
|
||||
value: yup.number().required(),
|
||||
label: yup.string().required(),
|
||||
})
|
||||
.nullable(),
|
||||
vendor: yup
|
||||
.object({
|
||||
value: yup.number().required(),
|
||||
label: yup.string().required(),
|
||||
})
|
||||
.nullable(),
|
||||
});
|
||||
|
||||
export type ExpensesFilterValues = yup.InferType<typeof ExpensesFilterSchema>;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { RefObject } from 'react';
|
||||
import { RefObject, useCallback } from 'react';
|
||||
import { useFormik } from 'formik';
|
||||
|
||||
import { Icon } from '@iconify/react';
|
||||
@@ -39,54 +39,51 @@ const ExpensesFilterModal = ({
|
||||
setInputValue: setLocationInputValue,
|
||||
options: locationOptions,
|
||||
isLoadingOptions: isLoadingLocationOptions,
|
||||
loadMore: loadMoreLocations,
|
||||
} = useSelect<Location>(LocationApi.basePath, 'id', 'name');
|
||||
|
||||
const {
|
||||
setInputValue: setVendorInputValue,
|
||||
options: vendorOptions,
|
||||
isLoadingOptions: isLoadingVendorOptions,
|
||||
loadMore: loadMoreVendors,
|
||||
} = useSelect<Supplier>(SupplierApi.basePath, 'id', 'name');
|
||||
|
||||
const formik = useFormik<ExpensesFilterValues>({
|
||||
initialValues: initialValues || {
|
||||
transaction_date: null,
|
||||
realization_date: null,
|
||||
location_id: null,
|
||||
vendor_id: null,
|
||||
location: null,
|
||||
vendor: null,
|
||||
},
|
||||
validationSchema: ExpensesFilterSchema,
|
||||
onSubmit: async (values) => {
|
||||
onSubmit?.(values);
|
||||
closeModalHandler();
|
||||
},
|
||||
onReset: () => {
|
||||
onReset?.();
|
||||
closeModalHandler();
|
||||
},
|
||||
});
|
||||
|
||||
const locationValue = formik.values.location_id
|
||||
? locationOptions.find(
|
||||
(opt) => String(opt.value) === formik.values.location_id
|
||||
) || null
|
||||
: null;
|
||||
const { resetForm } = formik;
|
||||
|
||||
const vendorValue = formik.values.vendor_id
|
||||
? vendorOptions.find(
|
||||
(opt) => String(opt.value) === formik.values.vendor_id
|
||||
) || null
|
||||
: null;
|
||||
const formikResetHandler = useCallback(() => {
|
||||
resetForm({
|
||||
values: {
|
||||
transaction_date: null,
|
||||
realization_date: null,
|
||||
location: null,
|
||||
vendor: null,
|
||||
},
|
||||
});
|
||||
onReset?.();
|
||||
closeModalHandler();
|
||||
}, [resetForm, onReset, closeModalHandler]);
|
||||
|
||||
const locationChangeHandler = (val: OptionType | OptionType[] | null) => {
|
||||
const locationId =
|
||||
val && !Array.isArray(val) ? (String(val.value) as string) : null;
|
||||
formik.setFieldValue('location_id', locationId);
|
||||
formik.setFieldValue('location', val as OptionType | null);
|
||||
};
|
||||
|
||||
const vendorChangeHandler = (val: OptionType | OptionType[] | null) => {
|
||||
const vendorId =
|
||||
val && !Array.isArray(val) ? (String(val.value) as string) : null;
|
||||
formik.setFieldValue('vendor_id', vendorId);
|
||||
formik.setFieldValue('vendor', val as OptionType | null);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -98,7 +95,7 @@ const ExpensesFilterModal = ({
|
||||
>
|
||||
<form
|
||||
onSubmit={formik.handleSubmit}
|
||||
onReset={formik.handleReset}
|
||||
onReset={formikResetHandler}
|
||||
className='w-full flex flex-col'
|
||||
>
|
||||
{/* Modal Header */}
|
||||
@@ -160,10 +157,11 @@ const ExpensesFilterModal = ({
|
||||
label='Lokasi'
|
||||
placeholder='Pilih Lokasi'
|
||||
options={locationOptions}
|
||||
value={locationValue}
|
||||
value={formik.values.location}
|
||||
onChange={locationChangeHandler}
|
||||
onInputChange={setLocationInputValue}
|
||||
isLoading={isLoadingLocationOptions}
|
||||
onMenuScrollToBottom={loadMoreLocations}
|
||||
isClearable
|
||||
isSearchable={true}
|
||||
className={{ wrapper: 'w-full' }}
|
||||
@@ -173,10 +171,11 @@ const ExpensesFilterModal = ({
|
||||
label='Vendor'
|
||||
placeholder='Pilih Vendor'
|
||||
options={vendorOptions}
|
||||
value={vendorValue}
|
||||
value={formik.values.vendor}
|
||||
onChange={vendorChangeHandler}
|
||||
onInputChange={setVendorInputValue}
|
||||
isLoading={isLoadingVendorOptions}
|
||||
onMenuScrollToBottom={loadMoreVendors}
|
||||
isClearable
|
||||
isSearchable={true}
|
||||
className={{ wrapper: 'w-full' }}
|
||||
|
||||
@@ -55,7 +55,6 @@ const PurchaseRequestForm = ({
|
||||
const deleteModal = useModal();
|
||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||
|
||||
const [, setLocationSelectInputValue] = useState('');
|
||||
const [selectedPurchaseItems, setSelectedPurchaseItems] = useState<number[]>(
|
||||
[]
|
||||
);
|
||||
@@ -163,6 +162,7 @@ const PurchaseRequestForm = ({
|
||||
options: locationOptions,
|
||||
isLoadingOptions: isLoadingLocations,
|
||||
loadMore: loadMoreLocations,
|
||||
setInputValue: setLocationSelectInputValue,
|
||||
} = useSelect(LocationApi.basePath, 'id', 'name', '', {
|
||||
area_id:
|
||||
selectedArea != ''
|
||||
|
||||
Reference in New Issue
Block a user