DashboardScene: Fixes urlsync issue when going from normal to home dashboard (#93758)

* DashboardScene: Fixes urlsync issue when going from normal to home dashboard

* Better fix

* Update
This commit is contained in:
Torkel Ödegaard 2024-09-27 09:10:49 +02:00 committed by GitHub
parent 40bcd0df41
commit 2cfba519f1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 23 additions and 8 deletions

View File

@ -1,5 +1,6 @@
// Libraries // Libraries
import { useEffect, useMemo } from 'react'; import { useEffect, useMemo } from 'react';
import { usePrevious } from 'react-use';
import { PageLayoutType } from '@grafana/data'; import { PageLayoutType } from '@grafana/data';
import { UrlSyncContextProvider } from '@grafana/scenes'; import { UrlSyncContextProvider } from '@grafana/scenes';
@ -19,8 +20,8 @@ import { getDashboardScenePageStateManager } from './DashboardScenePageStateMana
export interface Props extends GrafanaRouteComponentProps<DashboardPageRouteParams, DashboardPageRouteSearchParams> {} export interface Props extends GrafanaRouteComponentProps<DashboardPageRouteParams, DashboardPageRouteSearchParams> {}
export function DashboardScenePage({ match, route, queryParams, history }: Props) { export function DashboardScenePage({ match, route, queryParams, history }: Props) {
const prevMatch = usePrevious(match);
const stateManager = getDashboardScenePageStateManager(); const stateManager = getDashboardScenePageStateManager();
const { dashboard, isLoading, loadError } = stateManager.useState(); const { dashboard, isLoading, loadError } = stateManager.useState();
// After scene migration is complete and we get rid of old dashboard we should refactor dashboardWatcher so this route reload is not need // After scene migration is complete and we get rid of old dashboard we should refactor dashboardWatcher so this route reload is not need
@ -83,12 +84,10 @@ export function DashboardScenePage({ match, route, queryParams, history }: Props
} }
// Do not render anything when transitioning from one dashboard to another // Do not render anything when transitioning from one dashboard to another
if ( // A bit tricky for transition to or from Home dashbord that does not have a uid in the url (but could have it in the dashboard model)
match.params.type !== 'snapshot' && // if prevMatch is undefined we are going from normal route to home route or vice versa
match.params.uid && if (match.params.type !== 'snapshot' && (!prevMatch || match.params.uid !== prevMatch?.params.uid)) {
dashboard.state.uid !== match.params.uid && console.log('skipping rendering');
route.routeName !== DashboardRoutes.Home
) {
return null; return null;
} }

View File

@ -40,6 +40,22 @@ describe('DashboardScenePageStateManager', () => {
expect(loader.state.loadError).toBe('Dashboard not found'); expect(loader.state.loadError).toBe('Dashboard not found');
}); });
it('should clear current dashboard while loading next', async () => {
setupLoadDashboardMock({ dashboard: { uid: 'fake-dash', editable: true }, meta: {} });
const loader = new DashboardScenePageStateManager({});
await loader.loadDashboard({ uid: 'fake-dash', route: DashboardRoutes.Normal });
expect(loader.state.dashboard).toBeDefined();
setupLoadDashboardMock({ dashboard: { uid: 'fake-dash2', editable: true }, meta: {} });
loader.loadDashboard({ uid: 'fake-dash2', route: DashboardRoutes.Normal });
expect(loader.state.isLoading).toBe(true);
expect(loader.state.dashboard).toBeUndefined();
});
it('shoud fetch dashboard from local storage and remove it after if it exists', async () => { it('shoud fetch dashboard from local storage and remove it after if it exists', async () => {
const loader = new DashboardScenePageStateManager({}); const loader = new DashboardScenePageStateManager({});
const localStorageDashboard = { uid: 'fake-dash' }; const localStorageDashboard = { uid: 'fake-dash' };

View File

@ -208,7 +208,7 @@ export class DashboardScenePageStateManager extends StateManagerBase<DashboardSc
options.keepDashboardFromExploreInLocalStorage === false options.keepDashboardFromExploreInLocalStorage === false
); );
this.setState({ isLoading: true }); this.setState({ dashboard: undefined, isLoading: true });
const rsp = await this.fetchDashboard(options); const rsp = await this.fetchDashboard(options);