From ddcbea41555f1ff72ae53310b2c1e2947eb97dd9 Mon Sep 17 00:00:00 2001 From: Ethan Alvizo Date: Tue, 16 Jan 2024 00:30:05 -0500 Subject: [PATCH 1/2] fix: spinner finishes before all series load --- packages/chart/src/FigureChartModel.ts | 5 ++++- packages/dashboard-core-plugins/src/panels/ChartPanel.tsx | 8 ++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/chart/src/FigureChartModel.ts b/packages/chart/src/FigureChartModel.ts index 19ac5c25f1..5b0652a47c 100644 --- a/packages/chart/src/FigureChartModel.ts +++ b/packages/chart/src/FigureChartModel.ts @@ -157,6 +157,9 @@ class FigureChartModel extends ChartModel { const { charts } = this.figure; const axisTypeMap = ChartUtils.getAxisTypeMap(this.figure); const activeSeriesNames: string[] = []; + + this.seriesToProcess = new Set(); + for (let i = 0; i < charts.length; i += 1) { const chart = charts[i]; @@ -216,7 +219,6 @@ class FigureChartModel extends ChartModel { const seriesName = inactiveSeriesNames[i]; this.seriesDataMap.delete(seriesName); } - this.seriesToProcess = new Set([...this.seriesDataMap.keys()]); } /** @@ -241,6 +243,7 @@ class FigureChartModel extends ChartModel { ); this.seriesDataMap.set(series.name, seriesData); + this.seriesToProcess.add(series.name); this.data = [...this.seriesDataMap.values()]; diff --git a/packages/dashboard-core-plugins/src/panels/ChartPanel.tsx b/packages/dashboard-core-plugins/src/panels/ChartPanel.tsx index a1ba969fe3..4dde59aa11 100644 --- a/packages/dashboard-core-plugins/src/panels/ChartPanel.tsx +++ b/packages/dashboard-core-plugins/src/panels/ChartPanel.tsx @@ -174,6 +174,10 @@ interface ChartPanelState { panelState?: GLChartPanelState; } +interface LoadState { + isLoading: boolean; +} + function hasInputFilter( panel: PanelProps ): panel is PanelProps & { inputFilters: InputFilter[] } { @@ -714,8 +718,8 @@ export class ChartPanel extends Component { this.setActive(!isHidden); } - handleUpdate(): void { - this.setState({ isLoading: false }); + handleUpdate({ isLoading }: LoadState): void { + this.setState({ isLoading }); } handleClearAllFilters(): void { From 522cbb4510413fb1c923c5a4ab95aed2e418c6d6 Mon Sep 17 00:00:00 2001 From: Ethan Alvizo Date: Tue, 16 Jan 2024 11:02:54 -0500 Subject: [PATCH 2/2] test for fix --- .../src/panels/ChartPanel.test.tsx | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/packages/dashboard-core-plugins/src/panels/ChartPanel.test.tsx b/packages/dashboard-core-plugins/src/panels/ChartPanel.test.tsx index 09a53f576e..dfc828fe9b 100644 --- a/packages/dashboard-core-plugins/src/panels/ChartPanel.test.tsx +++ b/packages/dashboard-core-plugins/src/panels/ChartPanel.test.tsx @@ -96,8 +96,10 @@ function makeChartPanelWrapper({ ); } -function callUpdateFunction() { - MockChart.mock.calls[MockChart.mock.calls.length - 1][0]?.onUpdate(); +function callUpdateFunction(isLoading = false) { + MockChart.mock.calls[MockChart.mock.calls.length - 1][0]?.onUpdate({ + isLoading, + }); } function callErrorFunction() { @@ -390,6 +392,27 @@ it('shows loading spinner until an error is received B', async () => { checkPanelOverlays({ container, isLoading: false }); }); +it('shows loading spinner until all series to process are loaded', async () => { + const filterFields = []; + const model = makeChartModel({ filterFields }); + const modelPromise = Promise.resolve(model); + const makeModel = () => modelPromise; + + const { container } = render(makeChartPanelWrapper({ makeModel })); + + await act(() => expect(modelPromise).resolves.toBe(model)); + + // Overlays shouldn't appear yet because we haven't received an update or error event, should just see loading + expectLoading(container); + + // Loading spinner should be shown until the update event is received and the isLoading flag is false + callUpdateFunction(true); + expectLoading(container); + + callUpdateFunction(false); + expectNotLoading(container); +}); + describe('linker column selection', () => { it('does not show overlay if linker active but no filterable columns', async () => { const model = makeChartModel();