mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-24 23:35:45 +00:00
refactor(FE): Refactor tab actions to use memoized component
This commit is contained in:
@@ -20,7 +20,7 @@ import { generatePurchasesPerSupplierExcel } from '@/components/pages/report/log
|
|||||||
import { generatePurchasesPerSupplierPDF } from '@/components/pages/report/logistic-stock/export/PurchasesPerSupplierExportPDF';
|
import { generatePurchasesPerSupplierPDF } from '@/components/pages/report/logistic-stock/export/PurchasesPerSupplierExportPDF';
|
||||||
import { Icon } from '@iconify/react';
|
import { Icon } from '@iconify/react';
|
||||||
import { ColumnDef } from '@tanstack/react-table';
|
import { ColumnDef } from '@tanstack/react-table';
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import toast from 'react-hot-toast';
|
import toast from 'react-hot-toast';
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
import { useFormik } from 'formik';
|
import { useFormik } from 'formik';
|
||||||
@@ -65,6 +65,8 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
|
|||||||
const [dateErrorShown, setDateErrorShown] = useState(false);
|
const [dateErrorShown, setDateErrorShown] = useState(false);
|
||||||
const [hasDateError, setHasDateError] = useState(false);
|
const [hasDateError, setHasDateError] = useState(false);
|
||||||
|
|
||||||
|
const handleFilterModalOpenRef = useRef(() => {});
|
||||||
|
|
||||||
const filterModal = useModal();
|
const filterModal = useModal();
|
||||||
|
|
||||||
// ===== OPTIONS =====
|
// ===== OPTIONS =====
|
||||||
@@ -104,11 +106,6 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
|
|||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleFilterModalOpen = () => {
|
|
||||||
filterModal.openModal();
|
|
||||||
formik.validateForm();
|
|
||||||
};
|
|
||||||
|
|
||||||
// ===== FORMIK SETUP =====
|
// ===== FORMIK SETUP =====
|
||||||
const formik = useFormik<PurchasesPerSupplierFilterType>({
|
const formik = useFormik<PurchasesPerSupplierFilterType>({
|
||||||
initialValues: {
|
initialValues: {
|
||||||
@@ -151,11 +148,18 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
handleFilterModalOpenRef.current = () => {
|
||||||
|
filterModal.openModal();
|
||||||
|
formik.validateForm();
|
||||||
|
};
|
||||||
|
|
||||||
|
const { setFieldValue } = formik;
|
||||||
|
|
||||||
// ===== DATE CHANGE HANDLERS =====
|
// ===== DATE CHANGE HANDLERS =====
|
||||||
const handleStartDateChange = useCallback(
|
const handleStartDateChange = useCallback(
|
||||||
(e: React.ChangeEvent<HTMLInputElement>) => {
|
(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const value = e.target.value;
|
const value = e.target.value;
|
||||||
formik.setFieldValue('start_date', value || null);
|
setFieldValue('start_date', value || null);
|
||||||
|
|
||||||
if (value && formik.values.end_date) {
|
if (value && formik.values.end_date) {
|
||||||
const startDate = new Date(value);
|
const startDate = new Date(value);
|
||||||
@@ -180,13 +184,13 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
|
|||||||
setHasDateError(false);
|
setHasDateError(false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[formik, dateErrorShown]
|
[setFieldValue, dateErrorShown, formik.values.end_date]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleEndDateChange = useCallback(
|
const handleEndDateChange = useCallback(
|
||||||
(e: React.ChangeEvent<HTMLInputElement>) => {
|
(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const value = e.target.value;
|
const value = e.target.value;
|
||||||
formik.setFieldValue('end_date', value || null);
|
setFieldValue('end_date', value || null);
|
||||||
|
|
||||||
if (value && formik.values.start_date) {
|
if (value && formik.values.start_date) {
|
||||||
const startDateObj = new Date(formik.values.start_date);
|
const startDateObj = new Date(formik.values.start_date);
|
||||||
@@ -210,7 +214,7 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
|
|||||||
setDateErrorShown(false);
|
setDateErrorShown(false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[formik, dateErrorShown]
|
[setFieldValue, dateErrorShown, formik.values.start_date]
|
||||||
);
|
);
|
||||||
|
|
||||||
// ===== DERIVED VALUES =====
|
// ===== DERIVED VALUES =====
|
||||||
@@ -443,88 +447,104 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
|
|||||||
productCategoryOptions,
|
productCategoryOptions,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// ===== REGISTER TAB ACTIONS TO STORE =====
|
// ===== TAB ACTIONS COMPONENT =====
|
||||||
const setTabActions = useTabActionsStore((state) => state.setTabActions);
|
const TabActions = useMemo(() => {
|
||||||
const clearTabActions = useTabActionsStore((state) => state.clearTabActions);
|
return function TabActionsComponent() {
|
||||||
|
const setTabActions = useTabActionsStore((state) => state.setTabActions);
|
||||||
|
const clearTabActions = useTabActionsStore(
|
||||||
|
(state) => state.clearTabActions
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTabActions(
|
setTabActions(
|
||||||
tabId,
|
tabId,
|
||||||
<div className='flex flex-row gap-3'>
|
<div className='flex flex-row gap-3'>
|
||||||
<ButtonFilter
|
<ButtonFilter
|
||||||
values={formik.values}
|
values={filterParams}
|
||||||
fieldGroups={[['start_date', 'end_date']]}
|
fieldGroups={[['start_date', 'end_date']]}
|
||||||
onClick={handleFilterModalOpen}
|
onClick={() => handleFilterModalOpenRef.current()}
|
||||||
variant='outline'
|
|
||||||
className='px-3 py-2.5'
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Dropdown
|
|
||||||
align='end'
|
|
||||||
direction='bottom'
|
|
||||||
className={{
|
|
||||||
content:
|
|
||||||
'mt-1 rounded-xl border border-base-content/5 shadow-sm overflow-hidden',
|
|
||||||
}}
|
|
||||||
trigger={
|
|
||||||
<Button
|
|
||||||
variant='outline'
|
variant='outline'
|
||||||
color='none'
|
className='px-3 py-2.5'
|
||||||
isLoading={isAnyExportLoading}
|
/>
|
||||||
className='px-3 py-2.5 text-sm text-base-content/50 border border-base-content/10 rounded-xl shadow-button-soft'
|
|
||||||
|
<Dropdown
|
||||||
|
align='end'
|
||||||
|
direction='bottom'
|
||||||
|
className={{
|
||||||
|
content:
|
||||||
|
'mt-1 rounded-xl border border-base-content/5 shadow-sm overflow-hidden',
|
||||||
|
}}
|
||||||
|
trigger={
|
||||||
|
<Button
|
||||||
|
variant='outline'
|
||||||
|
color='none'
|
||||||
|
isLoading={isAnyExportLoading}
|
||||||
|
className='px-3 py-2.5 text-sm text-base-content/50 border border-base-content/10 rounded-xl shadow-button-soft'
|
||||||
|
>
|
||||||
|
<div className='flex flex-row items-center gap-1.5'>
|
||||||
|
<Icon
|
||||||
|
icon='heroicons:cloud-arrow-down'
|
||||||
|
width={20}
|
||||||
|
height={20}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span>Export</span>
|
||||||
|
|
||||||
|
<div className='w-px self-stretch bg-base-content/10' />
|
||||||
|
|
||||||
|
<Icon
|
||||||
|
icon='heroicons:chevron-down'
|
||||||
|
width={14}
|
||||||
|
height={14}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<div className='flex flex-row items-center gap-1.5'>
|
<Button
|
||||||
<Icon
|
variant='ghost'
|
||||||
icon='heroicons:cloud-arrow-down'
|
color='none'
|
||||||
width={20}
|
onClick={handleExportExcel}
|
||||||
height={20}
|
isLoading={isExcelExportLoading}
|
||||||
/>
|
className='w-full p-3 justify-start text-sm text-base-content/50 font-semibold text-nowrap'
|
||||||
|
>
|
||||||
|
<Icon icon='heroicons:table-cells' width={20} height={20} />
|
||||||
|
Export to Excel
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant='ghost'
|
||||||
|
color='none'
|
||||||
|
onClick={handleExportPdf}
|
||||||
|
isLoading={isPdfExportLoading}
|
||||||
|
className='w-full p-3 justify-start text-sm text-base-content/50 font-semibold text-nowrap'
|
||||||
|
>
|
||||||
|
<Icon icon='heroicons:document' width={20} height={20} />
|
||||||
|
Export to PDF
|
||||||
|
</Button>
|
||||||
|
</Dropdown>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}, [setTabActions]);
|
||||||
|
|
||||||
<span>Export</span>
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
clearTabActions(tabId);
|
||||||
|
};
|
||||||
|
}, [clearTabActions]);
|
||||||
|
|
||||||
<div className='w-px self-stretch bg-base-content/10' />
|
return null;
|
||||||
|
};
|
||||||
<Icon icon='heroicons:chevron-down' width={14} height={14} />
|
|
||||||
</div>
|
|
||||||
</Button>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
variant='ghost'
|
|
||||||
color='none'
|
|
||||||
onClick={handleExportExcel}
|
|
||||||
isLoading={isExcelExportLoading}
|
|
||||||
className='w-full p-3 justify-start text-sm text-base-content/50 font-semibold text-nowrap'
|
|
||||||
>
|
|
||||||
<Icon icon='heroicons:table-cells' width={20} height={20} />
|
|
||||||
Export to Excel
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant='ghost'
|
|
||||||
color='none'
|
|
||||||
onClick={handleExportPdf}
|
|
||||||
isLoading={isPdfExportLoading}
|
|
||||||
className='w-full p-3 justify-start text-sm text-base-content/50 font-semibold text-nowrap'
|
|
||||||
>
|
|
||||||
<Icon icon='heroicons:document' width={20} height={20} />
|
|
||||||
Export to PDF
|
|
||||||
</Button>
|
|
||||||
</Dropdown>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}, [
|
}, [
|
||||||
tabId,
|
tabId,
|
||||||
formik.values,
|
filterParams,
|
||||||
isAnyExportLoading,
|
isAnyExportLoading,
|
||||||
filterModal.open,
|
handleExportExcel,
|
||||||
setTabActions,
|
handleExportPdf,
|
||||||
|
isExcelExportLoading,
|
||||||
|
isPdfExportLoading,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
const TabActionsElement = useMemo(() => <TabActions />, [TabActions]);
|
||||||
return () => {
|
|
||||||
clearTabActions(tabId);
|
|
||||||
};
|
|
||||||
}, [tabId, clearTabActions]);
|
|
||||||
|
|
||||||
const getTableColumns = (
|
const getTableColumns = (
|
||||||
summary: LogisticPurchasePerSupplierSummary
|
summary: LogisticPurchasePerSupplierSummary
|
||||||
@@ -704,6 +724,7 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{TabActionsElement}
|
||||||
<div className='w-full p-0 sm:p-3 flex flex-col gap-3'>
|
<div className='w-full p-0 sm:p-3 flex flex-col gap-3'>
|
||||||
{!isSubmitted ? (
|
{!isSubmitted ? (
|
||||||
<PurchasePerSupplierSkeleton
|
<PurchasePerSupplierSkeleton
|
||||||
|
|||||||
Reference in New Issue
Block a user