fix(FE): make text area debounce input for lag textarea input issue

This commit is contained in:
randy-ar
2025-11-24 17:18:16 +07:00
parent d769bfe452
commit 034d185b84
@@ -47,6 +47,7 @@ import SalesOrderProductForm from './repeater/sales-order/SalesOrderProductForm'
import DeliveryOrderProductTable from './table-view/DeliveryOrderProductTable'; import DeliveryOrderProductTable from './table-view/DeliveryOrderProductTable';
import DeliveryOrderProductForm from './repeater/delivery-order/DeliverOrderProduct'; import DeliveryOrderProductForm from './repeater/delivery-order/DeliverOrderProduct';
import { DeliveryOrderProductFormValues } from './repeater/delivery-order/DeliverOrderProduct.schema'; import { DeliveryOrderProductFormValues } from './repeater/delivery-order/DeliverOrderProduct.schema';
import DebouncedTextArea from '@/components/input/DebouncedTextArea';
const MemoizedSalesOrderProductTable = memo(SalesOrderProductTable); const MemoizedSalesOrderProductTable = memo(SalesOrderProductTable);
const MemoizedSalesOrderProductForm = memo(SalesOrderProductForm); const MemoizedSalesOrderProductForm = memo(SalesOrderProductForm);
@@ -240,12 +241,6 @@ const MarketingForm = ({
const selectedRowSOIds = Object.keys(rowSOSelection).map((item) => const selectedRowSOIds = Object.keys(rowSOSelection).map((item) =>
parseInt(item) parseInt(item)
); );
const [rowDOSelection, setRowDOSelection] = useState<Record<string, boolean>>(
{}
);
const selectedRowDOIds = Object.keys(rowDOSelection).map((item) =>
parseInt(item)
);
// ================== FETCH OPTIONS ================== // ================== FETCH OPTIONS ==================
const { const {
@@ -353,13 +348,6 @@ const MarketingForm = ({
afterSubmit?.(); afterSubmit?.();
}, },
}); });
const grandTotal = useMemo(() => {
return formik.values.sales_order.reduce(
(total, product) =>
total + parseFloat((product.total_price as string) || '0'),
0
);
}, [formik.values.sales_order]);
// ================== FORM REPEATER HANDLER ================== // ================== FORM REPEATER HANDLER ==================
const createMarketingHandler = async (values: CreateSalesOrderPayload) => { const createMarketingHandler = async (values: CreateSalesOrderPayload) => {
@@ -468,23 +456,20 @@ const MarketingForm = ({
formik.setFieldValue('customer_id', (val as OptionType)?.value); formik.setFieldValue('customer_id', (val as OptionType)?.value);
formik.setFieldValue('customer', val as OptionType); formik.setFieldValue('customer', val as OptionType);
}, },
[formik] []
); );
const handleDelete = useCallback(() => { const handleDelete = useCallback(() => {
deleteModal.openModal(); deleteModal.openModal();
}, [deleteModal]); }, [deleteModal]);
// ================== SALES ORDER HANDLER ================== // ================== SALES ORDER HANDLER ==================
const handleDeleteSO = useCallback( const handleDeleteSO = useCallback((id: number) => {
(id: number) => { const currentProducts = formik.values.sales_order;
const currentProducts = formik.values.sales_order; formik.setFieldValue(
formik.setFieldValue( 'sales_order',
'sales_order', currentProducts.filter((p) => p.id != id)
currentProducts.filter((p) => p.id != id) );
); }, []);
},
[formik]
);
const handleBulkDeleteSO = useCallback(() => { const handleBulkDeleteSO = useCallback(() => {
const currentProducts = formik.values.sales_order; const currentProducts = formik.values.sales_order;
formik.setFieldValue( formik.setFieldValue(
@@ -494,7 +479,7 @@ const MarketingForm = ({
) )
); );
setRowSOSelection({}); setRowSOSelection({});
}, [formik, selectedRowSOIds]); }, [selectedRowSOIds]);
const handleAddSOClick = useCallback(() => { const handleAddSOClick = useCallback(() => {
setSelectedMarketingProduct(null); setSelectedMarketingProduct(null);
addSOModal.openModal(); addSOModal.openModal();
@@ -530,17 +515,10 @@ const MarketingForm = ({
addSOModal.closeModal(); addSOModal.closeModal();
}, },
[formik, addSOModal] [addSOModal]
); );
// ================== DELIVERY ORDER HANDLER ================== // ================== DELIVERY ORDER HANDLER ==================
const handleDeleteDO = useCallback(
(id: number) => {
const currentProducts = formik.values.delivery_order;
setDeliveryOrderValues((prev) => prev.filter((p) => p.id !== id));
},
[formik]
);
const handleEditDO = useCallback( const handleEditDO = useCallback(
(id: number, values?: DeliveryOrderProductFormValues) => { (id: number, values?: DeliveryOrderProductFormValues) => {
setDeliveryFormState('edit'); setDeliveryFormState('edit');
@@ -550,22 +528,13 @@ const MarketingForm = ({
setSelectedDeliveryProduct(values ?? currentProducts ?? null); setSelectedDeliveryProduct(values ?? currentProducts ?? null);
addDOModal.openModal(); addDOModal.openModal();
}, },
[formik, addDOModal] [addDOModal]
); );
const handleBulkDeleteDO = useCallback(() => {
setDeliveryOrderValues((prev) =>
prev.filter((product) => !selectedRowDOIds.includes(product.id ?? -1))
);
setRowDOSelection({});
}, [formik, selectedRowDOIds]);
const handleAddDOClick = useCallback(() => { const handleAddDOClick = useCallback(() => {
setDeliveryFormState('add'); setDeliveryFormState('add');
setSelectedDeliveryProduct(null); setSelectedDeliveryProduct(null);
addDOModal.openModal(); addDOModal.openModal();
}, [addDOModal]); }, [addDOModal]);
const handleAddSubmitDO = useCallback( const handleAddSubmitDO = useCallback(
async (values: DeliveryOrderProductFormValues) => { async (values: DeliveryOrderProductFormValues) => {
const newValues = { const newValues = {
@@ -577,20 +546,7 @@ const MarketingForm = ({
addDOModal.closeModal(); addDOModal.closeModal();
setSelectedDeliveryProduct(null); setSelectedDeliveryProduct(null);
}, },
[formik, addDOModal] [addDOModal]
);
const handleInputDate = useCallback(
(newData: DeliveryOrderProductFormValues) => {
setDeliveryOrderValues((prev) => {
return prev.map((item) => {
if (item.marketing_product_id == newData.marketing_product_id) {
return newData;
}
return item;
});
});
},
[]
); );
const handleUpdateDO = useCallback( const handleUpdateDO = useCallback(
async (id: number, values: DeliveryOrderProductFormValues) => { async (id: number, values: DeliveryOrderProductFormValues) => {
@@ -602,7 +558,7 @@ const MarketingForm = ({
addDOModal.closeModal(); addDOModal.closeModal();
setSelectedDeliveryProduct(null); setSelectedDeliveryProduct(null);
}, },
[formik, addDOModal] [addDOModal]
); );
const memoSalesOrder = formik.values.sales_order; const memoSalesOrder = formik.values.sales_order;
@@ -611,6 +567,14 @@ const MarketingForm = ({
formik.setFieldValue('delivery_order', deliveryOrderValues); formik.setFieldValue('delivery_order', deliveryOrderValues);
}, [deliveryOrderValues, initialValues]); }, [deliveryOrderValues, initialValues]);
const grandTotal = useMemo(() => {
return memoSalesOrder.reduce(
(total, product) =>
total + parseFloat((product.total_price as string) || '0'),
0
);
}, [memoSalesOrder]);
return ( return (
<> <>
<form <form
@@ -705,7 +669,7 @@ const MarketingForm = ({
{/* Input Notes */} {/* Input Notes */}
<div className='grid grid-cols-2 gap-3'> <div className='grid grid-cols-2 gap-3'>
<TextArea <DebouncedTextArea
required required
name='notes' name='notes'
label='Catatan' label='Catatan'