1- import { ReactNode , useEffect } from "react" ;
1+ import { ReactNode , useEffect , useRef } from "react" ;
22import { useTranslation } from "react-i18next" ;
33import TableFilters from "../shared/TableFilters" ;
44import Table , { TemplateMap } from "../shared/Table" ;
@@ -7,7 +7,7 @@ import { fetchFilters } from "../../slices/tableFilterSlice";
77import { CreateType , NavBarLink } from "../NavBar" ;
88import { AppThunk , RootState , useAppDispatch , useAppSelector } from "../../store" ;
99import { resetTableProperties , Resource } from "../../slices/tableSlice" ;
10- import { AsyncThunk } from "@reduxjs/toolkit" ;
10+ import { AsyncThunk , PayloadAction } from "@reduxjs/toolkit" ;
1111import { ParseKeys } from "i18next" ;
1212import { useLocation } from "react-router" ;
1313import MainPage from "./MainPage" ;
@@ -40,37 +40,89 @@ const TablePage = ({
4040} ) => {
4141 const { t } = useTranslation ( ) ;
4242 const dispatch = useAppDispatch ( ) ;
43+ const currentLoadRequest = useRef < { abort :( ) => void } | null > ( null ) ;
44+ const latestLoadRequestId = useRef ( 0 ) ;
45+ const allowLoadIntoTable = useRef ( true ) ;
46+ const currentLoadSource = useRef < "auto" | "filters" > ( null ) ;
47+ const autoRefreshPaused = useRef ( false ) ;
48+ const autoRefreshPauseTimeout = useRef < ReturnType < typeof setTimeout > | null > ( null ) ;
4349
4450 const location = useLocation ( ) ;
4551
4652 const numberOfRows = useAppSelector ( state => getTotalResources ( state ) ) ;
4753
54+ const pauseAutoRefresh = ( ) => {
55+ autoRefreshPaused . current = true ;
56+
57+ if ( autoRefreshPauseTimeout . current ) {
58+ clearTimeout ( autoRefreshPauseTimeout . current ) ;
59+ }
60+
61+ autoRefreshPauseTimeout . current = setTimeout ( ( ) => {
62+ autoRefreshPaused . current = false ;
63+ autoRefreshPauseTimeout . current = null ;
64+ } , 2000 ) ;
65+ } ;
66+
67+ const loadResource = async ( source : "auto" | "filters" = "auto" ) => {
68+ if ( source === "filters" ) {
69+ pauseAutoRefresh ( ) ;
70+ }
71+
72+ if ( source === "auto" && autoRefreshPaused . current ) {
73+ return ;
74+ }
75+
76+ if ( source === "auto" && currentLoadSource . current === "filters" ) {
77+ return ;
78+ }
79+
80+ const requestId = ++ latestLoadRequestId . current ;
81+ currentLoadSource . current = source ;
82+
83+ currentLoadRequest . current ?. abort ?.( ) ;
84+
85+ const fetchRequest = dispatch ( fetchResource ( ) ) as Promise < PayloadAction < any , string > > & { abort :( ) => void } ;
86+ currentLoadRequest . current = fetchRequest ;
87+
88+ const fetchResult = await fetchRequest as { meta ?: { requestStatus ?: string } } ;
89+
90+ if ( requestId === latestLoadRequestId . current ) {
91+ currentLoadSource . current = null ;
92+ }
93+
94+ if (
95+ allowLoadIntoTable . current
96+ && requestId === latestLoadRequestId . current
97+ && fetchResult ?. meta ?. requestStatus === "fulfilled"
98+ ) {
99+ dispatch ( loadResourceIntoTable ( ) ) ;
100+ }
101+ } ;
102+
103+ const loadResourceFromFilters = ( ) => loadResource ( "filters" ) ;
104+
48105 useEffect ( ( ) => {
49- // State variable for interrupting the load function
50- let allowLoadIntoTable = true ;
106+ allowLoadIntoTable . current = true ;
51107
52108 // Clear table of previous data
53109 dispatch ( resetTableProperties ( ) ) ;
54110
55111 dispatch ( fetchFilters ( resource ) ) ;
56112
57113 // Load resource on mount
58- const loadResource = async ( ) => {
59- // Fetching resources from server
60- await dispatch ( fetchResource ( ) ) ;
61-
62- // Load resources into table
63- if ( allowLoadIntoTable ) {
64- dispatch ( loadResourceIntoTable ( ) ) ;
65- }
66- } ;
67- loadResource ( ) ;
114+ loadResource ( "auto" ) ;
68115
69116 // Fetch resources every minute
70- const fetchResourceInterval = setInterval ( loadResource , 5000 ) ;
117+ const fetchResourceInterval = setInterval ( ( ) => loadResource ( "auto" ) , 5000 ) ;
71118
72119 return ( ) => {
73- allowLoadIntoTable = false ;
120+ allowLoadIntoTable . current = false ;
121+ currentLoadRequest . current ?. abort ?.( ) ;
122+ if ( autoRefreshPauseTimeout . current ) {
123+ clearTimeout ( autoRefreshPauseTimeout . current ) ;
124+ autoRefreshPauseTimeout . current = null ;
125+ }
74126 clearInterval ( fetchResourceInterval ) ;
75127 } ;
76128 // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -91,8 +143,7 @@ const TablePage = ({
91143
92144 { /* Include filters component */ }
93145 < TableFilters
94- loadResource = { fetchResource }
95- loadResourceIntoTable = { loadResourceIntoTable }
146+ loadResource = { loadResourceFromFilters }
96147 resource = { resource }
97148 />
98149 </ div >
0 commit comments