mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
feat: only fetch when user scroll to the component
This commit is contained in:
@@ -9,7 +9,7 @@ import { ProductWarehouseStock, StockLog } from '@/types/api/inventory/product';
|
|||||||
import { ColumnDef } from '@tanstack/react-table';
|
import { ColumnDef } from '@tanstack/react-table';
|
||||||
import { FileDown } from 'lucide-react';
|
import { FileDown } from 'lucide-react';
|
||||||
import toast from 'react-hot-toast';
|
import toast from 'react-hot-toast';
|
||||||
import { useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
|
|
||||||
const stockLogTableColumns: (warehouseName: string) => ColumnDef<StockLog>[] = (
|
const stockLogTableColumns: (warehouseName: string) => ColumnDef<StockLog>[] = (
|
||||||
@@ -80,6 +80,23 @@ const StockLogTable = ({
|
|||||||
productWarehouse: ProductWarehouseStock;
|
productWarehouse: ProductWarehouseStock;
|
||||||
}) => {
|
}) => {
|
||||||
const [isExportLoading, setIsExportLoading] = useState(false);
|
const [isExportLoading, setIsExportLoading] = useState(false);
|
||||||
|
const [hasBeenVisible, setHasBeenVisible] = useState(false);
|
||||||
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const observer = new IntersectionObserver(
|
||||||
|
([entry]) => {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
setHasBeenVisible(true);
|
||||||
|
observer.disconnect();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ threshold: 0.1 }
|
||||||
|
);
|
||||||
|
|
||||||
|
if (containerRef.current) observer.observe(containerRef.current);
|
||||||
|
return () => observer.disconnect();
|
||||||
|
}, []);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
state: tableFilterState,
|
state: tableFilterState,
|
||||||
@@ -108,7 +125,9 @@ const StockLogTable = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const { data: stockLogsResponse, isLoading: isLoadingStockLogs } = useSWR(
|
const { data: stockLogsResponse, isLoading: isLoadingStockLogs } = useSWR(
|
||||||
`${StockLogApi.basePath}${getTableFilterQueryString()}`,
|
hasBeenVisible
|
||||||
|
? `${StockLogApi.basePath}${getTableFilterQueryString()}`
|
||||||
|
: null,
|
||||||
StockLogApi.getAllFetcher
|
StockLogApi.getAllFetcher
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -117,46 +136,48 @@ const StockLogTable = ({
|
|||||||
: [];
|
: [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<div ref={containerRef}>
|
||||||
title={`Informasi Stock Produk - ${productWarehouse.warehouse_name}`}
|
<Card
|
||||||
collapsible
|
title={`Informasi Stock Produk - ${productWarehouse.warehouse_name}`}
|
||||||
variant='bordered'
|
collapsible
|
||||||
className={{
|
variant='bordered'
|
||||||
wrapper: 'w-full',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className='flex justify-end px-6 pt-4'>
|
|
||||||
<Button onClick={handleExportExcel} isLoading={isExportLoading}>
|
|
||||||
<FileDown size={16} />
|
|
||||||
Export Excel
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<Table<StockLog>
|
|
||||||
data={stockLogs}
|
|
||||||
columns={stockLogTableColumns(productWarehouse.warehouse_name)}
|
|
||||||
page={tableFilterState.page ?? 0}
|
|
||||||
pageSize={tableFilterState.pageSize}
|
|
||||||
onPageChange={setPage}
|
|
||||||
onPageSizeChange={setPageSize}
|
|
||||||
isLoading={isLoadingStockLogs}
|
|
||||||
totalItems={
|
|
||||||
isResponseSuccess(stockLogsResponse)
|
|
||||||
? stockLogsResponse.meta?.total_results
|
|
||||||
: 0
|
|
||||||
}
|
|
||||||
className={{
|
className={{
|
||||||
containerClassName: 'mt-4 mb-0',
|
wrapper: 'w-full',
|
||||||
tableWrapperClassName: 'overflow-x-auto min-h-full!',
|
|
||||||
tableClassName: 'font-inter w-full table-auto min-h-full!',
|
|
||||||
headerRowClassName: 'border-b border-b-gray-200',
|
|
||||||
headerColumnClassName:
|
|
||||||
'px-6 py-3 text-xs font-semibold text-gray-500 last:flex last:flex-row last:justify-end',
|
|
||||||
bodyRowClassName: 'border-b border-b-gray-200',
|
|
||||||
bodyColumnClassName:
|
|
||||||
'px-6 py-3 last:flex last:flex-row last:justify-end',
|
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
</Card>
|
<div className='flex justify-end px-6 pt-4'>
|
||||||
|
<Button onClick={handleExportExcel} isLoading={isExportLoading}>
|
||||||
|
<FileDown size={16} />
|
||||||
|
Export Excel
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<Table<StockLog>
|
||||||
|
data={stockLogs}
|
||||||
|
columns={stockLogTableColumns(productWarehouse.warehouse_name)}
|
||||||
|
page={tableFilterState.page ?? 0}
|
||||||
|
pageSize={tableFilterState.pageSize}
|
||||||
|
onPageChange={setPage}
|
||||||
|
onPageSizeChange={setPageSize}
|
||||||
|
isLoading={isLoadingStockLogs}
|
||||||
|
totalItems={
|
||||||
|
isResponseSuccess(stockLogsResponse)
|
||||||
|
? stockLogsResponse.meta?.total_results
|
||||||
|
: 0
|
||||||
|
}
|
||||||
|
className={{
|
||||||
|
containerClassName: 'mt-4 mb-0',
|
||||||
|
tableWrapperClassName: 'overflow-x-auto min-h-full!',
|
||||||
|
tableClassName: 'font-inter w-full table-auto min-h-full!',
|
||||||
|
headerRowClassName: 'border-b border-b-gray-200',
|
||||||
|
headerColumnClassName:
|
||||||
|
'px-6 py-3 text-xs font-semibold text-gray-500 last:flex last:flex-row last:justify-end',
|
||||||
|
bodyRowClassName: 'border-b border-b-gray-200',
|
||||||
|
bodyColumnClassName:
|
||||||
|
'px-6 py-3 last:flex last:flex-row last:justify-end',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user