feat: add Refresh button with force_recompute to ReportDepreciationTab

Adds a Refresh button to the tab actions bar (left of ButtonFilter) that
re-fetches depreciation data with force_recompute=true in the query param,
triggering a server-side recomputation. The arrow-path icon spins while
the request is in flight. Button is styled to match ButtonFilter. The
force_recompute flag resets to false when filters are changed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ValdiANS
2026-06-04 14:58:51 +07:00
parent 7fb86e9759
commit 97ff90996a
@@ -1,10 +1,11 @@
'use client'; 'use client';
import React, { useEffect, useMemo } from 'react'; import React, { useCallback, useEffect, useMemo, useState } from 'react';
import useSWR from 'swr'; import useSWR from 'swr';
import { ColumnDef } from '@tanstack/react-table'; import { ColumnDef } from '@tanstack/react-table';
import { Icon } from '@iconify/react'; import { Icon } from '@iconify/react';
import Button from '@/components/Button';
import Card from '@/components/Card'; import Card from '@/components/Card';
import Pagination from '@/components/Pagination'; import Pagination from '@/components/Pagination';
import Table from '@/components/Table'; import Table from '@/components/Table';
@@ -56,11 +57,21 @@ const ReportDepreciationTab = ({ tabId }: ReportDepreciationTabProps) => {
storeName: 'report-depreciation-table', storeName: 'report-depreciation-table',
}); });
const { data: depreciationsResponse, isLoading: isLoadingDepreciations } = const [forceRecompute, setForceRecompute] = useState(false);
useSWR(
`${DepreciationReportApi.basePath}${getTableFilterQueryString()}`, const {
DepreciationReportApi.getAllFetcher data: depreciationsResponse,
); isLoading: isLoadingDepreciations,
isValidating,
mutate,
} = useSWR(
`${DepreciationReportApi.basePath}${getTableFilterQueryString()}&force_recompute=${forceRecompute}`,
DepreciationReportApi.getAllFetcher
);
const handleRefresh = useCallback(() => {
setForceRecompute(true);
}, [mutate]);
const depreciations = isResponseSuccess(depreciationsResponse) const depreciations = isResponseSuccess(depreciationsResponse)
? depreciationsResponse.data ? depreciationsResponse.data
@@ -114,6 +125,21 @@ const ReportDepreciationTab = ({ tabId }: ReportDepreciationTabProps) => {
const tabActionsElement = useMemo( const tabActionsElement = useMemo(
() => ( () => (
<div className='flex flex-row gap-3'> <div className='flex flex-row gap-3'>
<Button
variant='outline'
color='none'
onClick={handleRefresh}
disabled={isValidating}
className='rounded-lg max-h-10 font-semibold text-sm gap-1.5 text-base-content/50 border border-base-content/10 shadow-button-soft px-3 py-2.5'
>
<Icon
icon='heroicons:arrow-path'
width={20}
height={20}
className={isValidating ? 'animate-spin' : ''}
/>
Refresh
</Button>
<ButtonFilter <ButtonFilter
values={tableFilterState} values={tableFilterState}
excludeFields={['page', 'pageSize']} excludeFields={['page', 'pageSize']}
@@ -123,7 +149,7 @@ const ReportDepreciationTab = ({ tabId }: ReportDepreciationTabProps) => {
/> />
</div> </div>
), ),
[tableFilterState] [tableFilterState, handleRefresh, isValidating]
); );
useEffect(() => { useEffect(() => {
@@ -255,6 +281,8 @@ const ReportDepreciationTab = ({ tabId }: ReportDepreciationTabProps) => {
values.period ? formatDate(values.period, 'YYYY-MM-DD') : '', values.period ? formatDate(values.period, 'YYYY-MM-DD') : '',
true true
); );
setForceRecompute(false);
}} }}
/> />
</> </>