|
1 | | -import React, { FunctionComponent, useEffect, useMemo, useState } from 'react'; |
| 1 | +import React, { FunctionComponent, useEffect, useMemo, useState, useRef } from 'react'; |
2 | 2 | import DatasetSectionContainer from '../../dataset-section-container/dataset-section-container'; |
3 | 3 | import { filtersContainer } from '../reports-section/reports-section.module.scss'; |
4 | 4 | import { apiPrefix, basicFetch } from '../../../utils/api-utils'; |
@@ -28,8 +28,21 @@ const GenerativeReportsSection: FunctionComponent<{ dataset: IDatasetConfig; wid |
28 | 28 | const [allReports, setAllReports] = useState([]); |
29 | 29 | const [apiErrorMessage, setApiErrorMessage] = useState(false); |
30 | 30 | const [noMatchingData, setNoMatchingData] = useState(false); |
| 31 | + const [isFetching, setIsFetching] = useState(false); |
| 32 | + const [renderLoadCount, setRenderLoadCount] = useState(0); |
31 | 33 | const [isLoading, setIsLoading] = useState<boolean>(false); |
32 | 34 |
|
| 35 | + const lastShowTsRef = useRef<number>(0); |
| 36 | + const incrementRender = () => setRenderLoadCount(count => count + 1); |
| 37 | + const decrementRender = () => setRenderLoadCount(count => Math.max(0, count - 1)); |
| 38 | + |
| 39 | + const handleRowLoading = (loading: boolean) => { |
| 40 | + if (loading) incrementRender(); |
| 41 | + else decrementRender(); |
| 42 | + }; |
| 43 | + |
| 44 | + const showLoading = isFetching || renderLoadCount > 0; |
| 45 | + |
33 | 46 | const bannerCopy = reportsBannerCopy[reportGenKey]; |
34 | 47 | const heading = noMatchingData ? bannerCopy?.noDataMatchHeader : bannerCopy?.additionalFiltersHeader; |
35 | 48 | const body = noMatchingData ? bannerCopy?.noDataMatchBody : bannerCopy?.additionalFiltersBody; |
@@ -120,45 +133,60 @@ const GenerativeReportsSection: FunctionComponent<{ dataset: IDatasetConfig; wid |
120 | 133 | setAllReportYears(Array.from(yearsSet)); |
121 | 134 | }, [earliestReportDate, latestReportDate]); |
122 | 135 |
|
| 136 | + useEffect(() => { |
| 137 | + if (showLoading) { |
| 138 | + lastShowTsRef.current = Date.now(); |
| 139 | + setIsLoading(true); |
| 140 | + } else { |
| 141 | + const t = setTimeout(() => setIsLoading(false), 0); |
| 142 | + return () => clearTimeout(t); |
| 143 | + } |
| 144 | + }, [showLoading]); |
| 145 | + |
123 | 146 | useMemo(() => { |
124 | 147 | (async () => { |
125 | | - if (selectedAccount.value) { |
| 148 | + if (!selectedAccount.value) { |
| 149 | + setAllReports([]); |
| 150 | + setIsFetching(false); |
| 151 | + return; |
| 152 | + } |
| 153 | + |
| 154 | + setIsFetching(true); |
| 155 | + try { |
126 | 156 | const reports = []; |
127 | 157 | for (const report of apisProp) { |
128 | 158 | const reportConfig = reportsConfig[reportGenKey][report.apiId]; |
129 | | - if (reportConfig) { |
130 | | - const formattedDate = format(selectedDate, 'MMMM yyyy'); |
131 | | - const downloadDate = format(selectedDate, 'MMyyyy'); |
132 | | - let reportData; |
133 | | - try { |
134 | | - reportData = await getReportData(report, reportConfig); |
135 | | - } catch (error) { |
136 | | - setIsLoading(false); |
137 | | - setApiErrorMessage(true); |
138 | | - break; |
139 | | - } |
140 | | - setApiErrorMessage(false); |
141 | | - const curReport = { |
142 | | - id: report.apiId, |
143 | | - name: `${report.tableName} - ${selectedAccount.label}.pdf`, |
144 | | - date: formattedDate, |
145 | | - size: '2KB', |
146 | | - downloadName: `${reportConfig.downloadName}_${selectedAccount.label}_${downloadDate}.pdf`, |
147 | | - data: reportData.tableData, |
148 | | - summaryData: reportData.summaryTableData, |
149 | | - summaryValues: reportData.summaryData, |
150 | | - config: reportConfig, |
151 | | - colConfig: report, |
152 | | - }; |
153 | | - reports.push(curReport); |
154 | | - //When no main table data is available, pull summary values from the summary data |
155 | | - const summary = reportData.tableData.length > 0 ? reportData.tableData : reportData.summaryData; |
156 | | - setSummaryValues(reportConfig, formattedDate, summary, reportData.summaryData); |
157 | | - } |
| 159 | + if (!reportConfig) continue; |
| 160 | + |
| 161 | + const formattedDate = format(selectedDate, 'MMMM yyyy'); |
| 162 | + const downloadDate = format(selectedDate, 'MMyyyy'); |
| 163 | + |
| 164 | + const reportData = await getReportData(report, reportConfig); |
| 165 | + setApiErrorMessage(false); |
| 166 | + |
| 167 | + const curReport = { |
| 168 | + id: report.apiId, |
| 169 | + name: `${report.tableName} - ${selectedAccount.label}.pdf`, |
| 170 | + date: formattedDate, |
| 171 | + size: '2KB', |
| 172 | + downloadName: `${reportConfig.downloadName}_${selectedAccount.label}_${downloadDate}.pdf`, |
| 173 | + data: reportData.tableData, |
| 174 | + summaryData: reportData.summaryTableData, |
| 175 | + summaryValues: reportData.summaryData, |
| 176 | + config: reportConfig, |
| 177 | + colConfig: report, |
| 178 | + }; |
| 179 | + reports.push(curReport); |
| 180 | + |
| 181 | + const summarySource = reportData.tableData.length > 0 ? reportData.tableData : reportData.summaryData; |
| 182 | + setSummaryValues(reportConfig, formattedDate, summarySource, reportData.summaryData); |
158 | 183 | } |
159 | 184 | setAllReports(reports); |
160 | | - } else { |
| 185 | + } catch (error) { |
| 186 | + setApiErrorMessage(true); |
161 | 187 | setAllReports([]); |
| 188 | + } finally { |
| 189 | + setIsFetching(false); |
162 | 190 | } |
163 | 191 | })(); |
164 | 192 | }, [selectedAccount, selectedDate]); |
@@ -213,7 +241,7 @@ const GenerativeReportsSection: FunctionComponent<{ dataset: IDatasetConfig; wid |
213 | 241 | width={width} |
214 | 242 | setApiErrorMessage={setApiErrorMessage} |
215 | 243 | isLoading={isLoading} |
216 | | - setIsLoading={setIsLoading} |
| 244 | + setIsLoading={handleRowLoading} |
217 | 245 | /> |
218 | 246 | )} |
219 | 247 | <DataPreviewDatatableBanner bannerNotice={dataset?.publishedReportsTip} isReport={true} /> |
|
0 commit comments