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