mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-24 07:15:44 +00:00
feat: add more filters
This commit is contained in:
@@ -39,6 +39,7 @@ import PopoverContent from '@/components/popover/PopoverContent';
|
||||
import ConfirmationModal from '@/components/modal/ConfirmationModal';
|
||||
import toast from 'react-hot-toast';
|
||||
import RequirePermission from '@/components/helper/RequirePermission';
|
||||
import ButtonFilter from '@/components/helper/ButtonFilter';
|
||||
import { useUiStore } from '@/stores/ui/ui.store';
|
||||
import {
|
||||
FinanceTableFilterSchema,
|
||||
@@ -195,6 +196,9 @@ const FinanceTable = () => {
|
||||
sortBy: '',
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
bankNames: '',
|
||||
customerNames: '',
|
||||
supplierNames: '',
|
||||
},
|
||||
paramMap: {
|
||||
page: 'page',
|
||||
@@ -207,6 +211,9 @@ const FinanceTable = () => {
|
||||
startDate: 'start_date',
|
||||
endDate: 'end_date',
|
||||
},
|
||||
excludeKeysFromUrl: ['bankNames', 'customerNames', 'supplierNames'],
|
||||
persist: true,
|
||||
storeName: 'finance-table',
|
||||
});
|
||||
|
||||
// ===== FILTER MODAL STATE =====
|
||||
@@ -256,9 +263,20 @@ const FinanceTable = () => {
|
||||
updateFilter('sortBy', values.sort_by);
|
||||
updateFilter('startDate', values.start_date);
|
||||
updateFilter('endDate', values.end_date);
|
||||
// Save display names for restoration on modal reopen
|
||||
const toNames = (val: OptionType | OptionType[] | null) =>
|
||||
val ? (Array.isArray(val) ? val : [val]).map((o) => String(o.label)).join(',') : '';
|
||||
updateFilter('bankNames', toNames(selectedBank));
|
||||
updateFilter('customerNames', toNames(selectedCustomerId));
|
||||
updateFilter('supplierNames', toNames(selectedSupplierId));
|
||||
filterModal.closeModal();
|
||||
},
|
||||
onReset: () => {
|
||||
setSelectedTransactionType(null);
|
||||
setSelectedBank(null);
|
||||
setSelectedCustomerId(null);
|
||||
setSelectedSupplierId(null);
|
||||
setSelectedSortBy(null);
|
||||
updateFilter('search', '');
|
||||
resetSearchValue();
|
||||
updateFilter('transactionTypes', '');
|
||||
@@ -268,6 +286,10 @@ const FinanceTable = () => {
|
||||
updateFilter('sortBy', '');
|
||||
updateFilter('startDate', '');
|
||||
updateFilter('endDate', '');
|
||||
updateFilter('bankNames', '');
|
||||
updateFilter('customerNames', '');
|
||||
updateFilter('supplierNames', '');
|
||||
filterModal.closeModal();
|
||||
},
|
||||
});
|
||||
|
||||
@@ -320,31 +342,6 @@ const FinanceTable = () => {
|
||||
});
|
||||
}, [bankOptions, bankRawData]);
|
||||
|
||||
// ===== ACTIVE FILTERS COUNT =====
|
||||
const activeFiltersCount = useMemo(() => {
|
||||
let count = 0;
|
||||
|
||||
if (tableFilterState.transactionTypes) count += 1;
|
||||
if (tableFilterState.bankIds) count += 1;
|
||||
if (tableFilterState.customerIds) count += 1;
|
||||
if (tableFilterState.supplierIds) count += 1;
|
||||
if (tableFilterState.sortBy) count += 1;
|
||||
if (tableFilterState.startDate) count += 1;
|
||||
if (tableFilterState.endDate) count += 1;
|
||||
|
||||
return count;
|
||||
}, [
|
||||
tableFilterState.transactionTypes,
|
||||
tableFilterState.bankIds,
|
||||
tableFilterState.customerIds,
|
||||
tableFilterState.supplierIds,
|
||||
tableFilterState.sortBy,
|
||||
tableFilterState.startDate,
|
||||
tableFilterState.endDate,
|
||||
]);
|
||||
|
||||
const hasFilters = activeFiltersCount > 0;
|
||||
|
||||
// ===== Handler =====
|
||||
const searchChangeHandler = useCallback(
|
||||
(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
@@ -469,28 +466,73 @@ const FinanceTable = () => {
|
||||
};
|
||||
|
||||
const handleFilterModalOpen = () => {
|
||||
// Restore transaction types from stored comma-separated IDs
|
||||
const txIds = tableFilterState.transactionTypes
|
||||
? tableFilterState.transactionTypes.split(',')
|
||||
: [];
|
||||
const restoredTxTypes = FINANCE_TRANSACTION_TYPE_OPTIONS.filter((opt) =>
|
||||
txIds.includes(String(opt.value))
|
||||
);
|
||||
setSelectedTransactionType(restoredTxTypes.length ? restoredTxTypes : null);
|
||||
|
||||
// Restore banks from stored IDs and names
|
||||
const bankIdList = tableFilterState.bankIds
|
||||
? tableFilterState.bankIds.split(',')
|
||||
: [];
|
||||
const bankNameList = tableFilterState.bankNames
|
||||
? tableFilterState.bankNames.split(',')
|
||||
: [];
|
||||
const restoredBanks = bankIdList.map((id, i) => ({
|
||||
value: id,
|
||||
label: bankNameList[i] || id,
|
||||
}));
|
||||
setSelectedBank(restoredBanks.length ? restoredBanks : null);
|
||||
|
||||
// Restore customers from stored IDs and names
|
||||
const customerIdList = tableFilterState.customerIds
|
||||
? tableFilterState.customerIds.split(',')
|
||||
: [];
|
||||
const customerNameList = tableFilterState.customerNames
|
||||
? tableFilterState.customerNames.split(',')
|
||||
: [];
|
||||
const restoredCustomers = customerIdList.map((id, i) => ({
|
||||
value: id,
|
||||
label: customerNameList[i] || id,
|
||||
}));
|
||||
setSelectedCustomerId(restoredCustomers.length ? restoredCustomers : null);
|
||||
|
||||
// Restore suppliers from stored IDs and names
|
||||
const supplierIdList = tableFilterState.supplierIds
|
||||
? tableFilterState.supplierIds.split(',')
|
||||
: [];
|
||||
const supplierNameList = tableFilterState.supplierNames
|
||||
? tableFilterState.supplierNames.split(',')
|
||||
: [];
|
||||
const restoredSuppliers = supplierIdList.map((id, i) => ({
|
||||
value: id,
|
||||
label: supplierNameList[i] || id,
|
||||
}));
|
||||
setSelectedSupplierId(restoredSuppliers.length ? restoredSuppliers : null);
|
||||
|
||||
// Restore sort by
|
||||
const restoredSortBy =
|
||||
sortByOptions.find((opt) => String(opt.value) === tableFilterState.sortBy) ||
|
||||
null;
|
||||
setSelectedSortBy(restoredSortBy);
|
||||
|
||||
// Restore formik values
|
||||
filterFormik.setValues({
|
||||
search: tableFilterState.search || '',
|
||||
transaction_types: tableFilterState.transactionTypes || '',
|
||||
bank_ids: tableFilterState.bankIds || '',
|
||||
customer_ids: tableFilterState.customerIds || '',
|
||||
supplier_ids: tableFilterState.supplierIds || '',
|
||||
sort_by: tableFilterState.sortBy || '',
|
||||
start_date: tableFilterState.startDate || '',
|
||||
end_date: tableFilterState.endDate || '',
|
||||
});
|
||||
|
||||
filterModal.openModal();
|
||||
filterFormik.validateForm();
|
||||
};
|
||||
|
||||
const resetFilterHandler = () => {
|
||||
setSelectedTransactionType(null);
|
||||
setSelectedBank(null);
|
||||
setSelectedCustomerId(null);
|
||||
setSelectedSupplierId(null);
|
||||
setSelectedSortBy(null);
|
||||
|
||||
filterFormik.resetForm();
|
||||
|
||||
updateFilter('search', '');
|
||||
resetSearchValue();
|
||||
updateFilter('transactionTypes', '');
|
||||
updateFilter('bankIds', '');
|
||||
updateFilter('customerIds', '');
|
||||
updateFilter('supplierIds', '');
|
||||
updateFilter('sortBy', '');
|
||||
updateFilter('startDate', '');
|
||||
updateFilter('endDate', '');
|
||||
};
|
||||
|
||||
const confirmationModalDeleteClickHandler = async () => {
|
||||
@@ -687,25 +729,19 @@ const FinanceTable = () => {
|
||||
}}
|
||||
/>
|
||||
|
||||
<Button
|
||||
variant='outline'
|
||||
color='none'
|
||||
<ButtonFilter
|
||||
values={tableFilterState}
|
||||
excludeFields={[
|
||||
'page',
|
||||
'pageSize',
|
||||
'search',
|
||||
'bankNames',
|
||||
'customerNames',
|
||||
'supplierNames',
|
||||
]}
|
||||
onClick={handleFilterModalOpen}
|
||||
className={cn(
|
||||
'px-3 py-2.5 gap-1.5 text-sm text-base-content/50 border border-base-content/10 rounded-xl shadow-button-soft transition-all',
|
||||
{
|
||||
'border-primary-gradient text-primary': hasFilters,
|
||||
}
|
||||
)}
|
||||
>
|
||||
<Icon icon='heroicons:funnel' width={20} height={20} />
|
||||
Filter
|
||||
{hasFilters && (
|
||||
<span className='w-5 h-5 text-white bg-[#FF3535] rounded-lg border border-base-300 flex items-center justify-center text-xs'>
|
||||
{activeFiltersCount}
|
||||
</span>
|
||||
)}
|
||||
</Button>
|
||||
className='px-3 py-2.5'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -874,19 +910,9 @@ const FinanceTable = () => {
|
||||
{/* 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={() => {
|
||||
filterFormik.resetForm();
|
||||
setSelectedTransactionType(null);
|
||||
setSelectedBank(null);
|
||||
setSelectedCustomerId(null);
|
||||
setSelectedSupplierId(null);
|
||||
setSelectedSortBy(null);
|
||||
resetFilterHandler();
|
||||
filterModal.closeModal();
|
||||
}}
|
||||
>
|
||||
Reset Filter
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user