diff --git a/public/app/core/components/AppChrome/AppChromeService.tsx b/public/app/core/components/AppChrome/AppChromeService.tsx index defb56e3de79..dd9a6b04a043 100644 --- a/public/app/core/components/AppChrome/AppChromeService.tsx +++ b/public/app/core/components/AppChrome/AppChromeService.tsx @@ -8,7 +8,7 @@ import { isShallowEqual } from 'app/core/utils/isShallowEqual'; import { RouteDescriptor } from '../../navigation/types'; export interface AppChromeState { - chromeless: boolean; + chromeless?: boolean; sectionNav: NavModelItem; pageNav?: NavModelItem; actions?: React.ReactNode; @@ -20,6 +20,8 @@ const defaultSection: NavModelItem = { text: 'Grafana' }; export class AppChromeService { searchBarStorageKey = 'SearchBar_Hidden'; + private currentRoute?: RouteDescriptor; + private routeChangeHandled?: boolean; readonly state = new BehaviorSubject({ chromeless: true, // start out hidden to not flash it on pages without chrome @@ -27,22 +29,30 @@ export class AppChromeService { searchBarHidden: store.getBool(this.searchBarStorageKey, false), }); - routeMounted(route: RouteDescriptor) { - this.update({ - chromeless: route.chromeless === true, - sectionNav: defaultSection, - pageNav: undefined, - actions: undefined, - }); + registerRouteRender(route: RouteDescriptor) { + if (this.currentRoute !== route) { + this.currentRoute = route; + this.routeChangeHandled = false; + } } - update(state: Partial) { + update(update: Partial) { const current = this.state.getValue(); const newState: AppChromeState = { ...current, - ...state, }; + // when route change update props from route and clear fields + if (!this.routeChangeHandled) { + newState.actions = undefined; + newState.pageNav = undefined; + newState.sectionNav = defaultSection; + newState.chromeless = this.currentRoute?.chromeless; + this.routeChangeHandled = true; + } + + Object.assign(newState, update); + if (!isShallowEqual(current, newState)) { this.state.next(newState); } diff --git a/public/app/core/navigation/GrafanaRoute.tsx b/public/app/core/navigation/GrafanaRoute.tsx index cc53312488c8..4ead00a63163 100644 --- a/public/app/core/navigation/GrafanaRoute.tsx +++ b/public/app/core/navigation/GrafanaRoute.tsx @@ -14,9 +14,9 @@ export interface Props extends Omit { export function GrafanaRoute(props: Props) { const { chrome } = useGrafana(); - useEffect(() => { - chrome.routeMounted(props.route); + chrome.registerRouteRender(props.route); + useEffect(() => { updateBodyClassNames(props.route); cleanupDOM(); reportPageview(); @@ -26,7 +26,9 @@ export function GrafanaRoute(props: Props) { navigationLogger('GrafanaRoute', false, 'Unmounted', props.route); updateBodyClassNames(props.route, true); }; - }, [chrome, props.route, props.match]); + // props.match instance change even though only query params changed so to make this effect only trigger on route mount we have to disable exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); useEffect(() => { // unbinds all and re-bind global keybindins