mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-24 23:35:45 +00:00
fix: implement table filter persist state
This commit is contained in:
@@ -7,8 +7,7 @@ import {
|
||||
useMemo,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import useSWR, { mutate } from 'swr';
|
||||
import useSWR from 'swr';
|
||||
import { Icon } from '@iconify/react';
|
||||
import { ColumnDef, ColumnSort, SortingState } from '@tanstack/react-table';
|
||||
import { useFormik } from 'formik';
|
||||
@@ -25,7 +24,6 @@ import { cn, formatNumber, formatDate, formatCurrency } from '@/lib/helper';
|
||||
import { InventoryAdjustmentApi } from '@/services/api/inventory';
|
||||
import { WarehouseApi, ProductApi } from '@/services/api/master-data';
|
||||
import { useTableFilter } from '@/services/hooks/useTableFilter';
|
||||
import { useUiStore } from '@/stores/ui/ui.store';
|
||||
import ConfirmationModal from '@/components/modal/ConfirmationModal';
|
||||
import PopoverButton from '@/components/popover/PopoverButton';
|
||||
import PopoverContent from '@/components/popover/PopoverContent';
|
||||
@@ -100,27 +98,31 @@ const RowOptionsMenu = ({
|
||||
};
|
||||
|
||||
const InventoryAdjustmentTable = () => {
|
||||
const { searchValue, setSearchValue, setTableState } = useUiStore();
|
||||
const pathname = usePathname();
|
||||
|
||||
const {
|
||||
state: tableFilterState,
|
||||
updateFilter,
|
||||
setPage,
|
||||
setPageSize,
|
||||
toQueryString: getTableFilterQueryString,
|
||||
} = useTableFilter({
|
||||
} = useTableFilter<{
|
||||
search: string;
|
||||
productCategorySort: string;
|
||||
productSort: string;
|
||||
warehouseSort: string;
|
||||
stockSort: string;
|
||||
productFilter?: OptionType<string>;
|
||||
warehouseFilter?: OptionType<string>;
|
||||
transactionTypeFilter?: OptionType<string>;
|
||||
}>({
|
||||
initial: {
|
||||
search: '',
|
||||
productCategorySort: '',
|
||||
productSort: '',
|
||||
warehouseSort: '',
|
||||
stockSort: '',
|
||||
productFilter: '',
|
||||
warehouseFilter: '',
|
||||
transactionTypeFilter: '',
|
||||
productName: '',
|
||||
warehouseName: '',
|
||||
productFilter: undefined,
|
||||
warehouseFilter: undefined,
|
||||
transactionTypeFilter: undefined,
|
||||
},
|
||||
paramMap: {
|
||||
page: 'page',
|
||||
@@ -133,7 +135,6 @@ const InventoryAdjustmentTable = () => {
|
||||
warehouseFilter: 'warehouse_id',
|
||||
transactionTypeFilter: 'transaction_type',
|
||||
},
|
||||
excludeKeysFromUrl: ['productName', 'warehouseName'],
|
||||
persist: true,
|
||||
storeName: 'inventory-adjustment-table',
|
||||
});
|
||||
@@ -144,32 +145,26 @@ const InventoryAdjustmentTable = () => {
|
||||
// ===== FORMIK SETUP =====
|
||||
const formik = useFormik<AdjustmentFilterType>({
|
||||
initialValues: {
|
||||
product_id: null,
|
||||
warehouse_id: null,
|
||||
transaction_type: null,
|
||||
product: tableFilterState.productFilter,
|
||||
warehouse: tableFilterState.warehouseFilter,
|
||||
transaction_type: tableFilterState.transactionTypeFilter,
|
||||
},
|
||||
validationSchema: AdjustmentFilterSchema,
|
||||
onSubmit: (values, { setSubmitting }) => {
|
||||
updateFilter('productFilter', values.product_id || '');
|
||||
updateFilter('warehouseFilter', values.warehouse_id || '');
|
||||
updateFilter('transactionTypeFilter', values.transaction_type || '');
|
||||
updateFilter('productFilter', values.product || undefined, true);
|
||||
updateFilter('warehouseFilter', values.warehouse || undefined, true);
|
||||
updateFilter(
|
||||
'productName',
|
||||
productIdValue?.label ? String(productIdValue.label) : ''
|
||||
);
|
||||
updateFilter(
|
||||
'warehouseName',
|
||||
warehouseIdValue?.label ? String(warehouseIdValue.label) : ''
|
||||
'transactionTypeFilter',
|
||||
values.transaction_type || undefined,
|
||||
true
|
||||
);
|
||||
filterModal.closeModal();
|
||||
setSubmitting(false);
|
||||
},
|
||||
onReset: () => {
|
||||
updateFilter('productFilter', '');
|
||||
updateFilter('warehouseFilter', '');
|
||||
updateFilter('transactionTypeFilter', '');
|
||||
updateFilter('productName', '');
|
||||
updateFilter('warehouseName', '');
|
||||
updateFilter('productFilter', undefined, true);
|
||||
updateFilter('warehouseFilter', undefined, true);
|
||||
updateFilter('transactionTypeFilter', undefined, true);
|
||||
filterModal.closeModal();
|
||||
},
|
||||
});
|
||||
@@ -209,84 +204,28 @@ const InventoryAdjustmentTable = () => {
|
||||
}, []);
|
||||
|
||||
// ===== FILTER HANDLERS =====
|
||||
const handleFilterProductChange = useCallback(
|
||||
(val: OptionType | OptionType[] | null) => {
|
||||
const product = val as OptionType | null;
|
||||
const productId = product?.value ? String(product.value) : null;
|
||||
formik.setFieldValue('product_id', productId);
|
||||
},
|
||||
[formik]
|
||||
);
|
||||
const handleFilterProductChange = (val: OptionType | OptionType[] | null) => {
|
||||
formik.setFieldValue('product', val);
|
||||
};
|
||||
|
||||
const handleFilterWarehouseChange = (
|
||||
val: OptionType | OptionType[] | null
|
||||
) => {
|
||||
const warehouse = val as OptionType | null;
|
||||
formik.setFieldValue(
|
||||
'warehouse_id',
|
||||
warehouse?.value ? String(warehouse.value) : null
|
||||
);
|
||||
formik.setFieldValue('warehouse', val);
|
||||
};
|
||||
|
||||
const handleFilterTransactionTypeChange = useCallback(
|
||||
(val: OptionType | OptionType[] | null) => {
|
||||
const type = val as OptionType | null;
|
||||
const typeValue = type?.value ? String(type.value) : null;
|
||||
formik.setFieldValue('transaction_type', typeValue);
|
||||
},
|
||||
[formik]
|
||||
);
|
||||
|
||||
// ===== FILTER HELPERS =====
|
||||
const productIdValue = useMemo(() => {
|
||||
if (!formik.values.product_id) return null;
|
||||
const found = productOptions.find(
|
||||
(opt) => String(opt.value) === formik.values.product_id
|
||||
);
|
||||
if (found) return found;
|
||||
if (tableFilterState.productName) {
|
||||
return {
|
||||
value: formik.values.product_id,
|
||||
label: tableFilterState.productName,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}, [formik.values.product_id, productOptions, tableFilterState.productName]);
|
||||
|
||||
const warehouseIdValue = useMemo(() => {
|
||||
if (!formik.values.warehouse_id) return null;
|
||||
const found = warehouseOptions.find(
|
||||
(opt) => String(opt.value) === formik.values.warehouse_id
|
||||
);
|
||||
if (found) return found;
|
||||
if (tableFilterState.warehouseName) {
|
||||
return {
|
||||
value: formik.values.warehouse_id,
|
||||
label: tableFilterState.warehouseName,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}, [
|
||||
formik.values.warehouse_id,
|
||||
warehouseOptions,
|
||||
tableFilterState.warehouseName,
|
||||
]);
|
||||
|
||||
const transactionTypeValue = useMemo(() => {
|
||||
if (!formik.values.transaction_type) return null;
|
||||
return (
|
||||
transactionTypeOptions.find(
|
||||
(opt) => String(opt.value) === formik.values.transaction_type
|
||||
) || null
|
||||
);
|
||||
}, [formik.values.transaction_type, transactionTypeOptions]);
|
||||
const handleFilterTransactionTypeChange = (
|
||||
val: OptionType | OptionType[] | null
|
||||
) => {
|
||||
formik.setFieldValue('transaction_type', val);
|
||||
};
|
||||
|
||||
// ===== HANDLE FILTER MODAL OPEN =====
|
||||
const handleFilterModalOpen = () => {
|
||||
formik.setValues({
|
||||
product_id: tableFilterState.productFilter || null,
|
||||
warehouse_id: tableFilterState.warehouseFilter || null,
|
||||
transaction_type: tableFilterState.transactionTypeFilter || null,
|
||||
product: tableFilterState.productFilter ?? undefined,
|
||||
warehouse: tableFilterState.warehouseFilter ?? undefined,
|
||||
transaction_type: tableFilterState.transactionTypeFilter ?? undefined,
|
||||
});
|
||||
filterModal.openModal();
|
||||
};
|
||||
@@ -325,17 +264,8 @@ const InventoryAdjustmentTable = () => {
|
||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||
const singleDeleteModal = useModal();
|
||||
|
||||
useEffect(() => {
|
||||
updateFilter('search', searchValue);
|
||||
}, [searchValue, updateFilter]);
|
||||
|
||||
useEffect(() => {
|
||||
setTableState('inventory-adjustment-table', pathname);
|
||||
}, [pathname, setTableState]);
|
||||
|
||||
const searchChangeHandler: ChangeEventHandler<HTMLInputElement> = (e) => {
|
||||
setSearchValue(e.target.value);
|
||||
updateFilter('search', e.target.value);
|
||||
updateFilter('search', e.target.value, true);
|
||||
};
|
||||
|
||||
const inventoryAdjustmentsColumns: ColumnDef<InventoryAdjustment>[] = useMemo(
|
||||
@@ -647,7 +577,7 @@ const InventoryAdjustmentTable = () => {
|
||||
label='Produk'
|
||||
placeholder='Pilih Produk'
|
||||
options={productOptions}
|
||||
value={productIdValue}
|
||||
value={formik.values.product}
|
||||
onChange={handleFilterProductChange}
|
||||
onInputChange={setProductInputValue}
|
||||
isLoading={isLoadingProductOptions}
|
||||
@@ -659,7 +589,7 @@ const InventoryAdjustmentTable = () => {
|
||||
label='Gudang'
|
||||
placeholder='Pilih Gudang'
|
||||
options={warehouseOptions}
|
||||
value={warehouseIdValue}
|
||||
value={formik.values.warehouse}
|
||||
onChange={handleFilterWarehouseChange}
|
||||
onInputChange={setWarehouseInputValue}
|
||||
isLoading={isLoadingWarehouseOptions}
|
||||
@@ -671,7 +601,7 @@ const InventoryAdjustmentTable = () => {
|
||||
label='Tipe Transaksi'
|
||||
placeholder='Pilih Tipe Transaksi'
|
||||
options={transactionTypeOptions}
|
||||
value={transactionTypeValue}
|
||||
value={formik.values.transaction_type}
|
||||
onChange={handleFilterTransactionTypeChange}
|
||||
isClearable
|
||||
className={{ wrapper: 'w-full' }}
|
||||
|
||||
Reference in New Issue
Block a user