diff --git a/public/app/features/dashboard-scene/pages/DashboardScenePage.test.tsx b/public/app/features/dashboard-scene/pages/DashboardScenePage.test.tsx index 3fe7ba89db6..51777c2fd7a 100644 --- a/public/app/features/dashboard-scene/pages/DashboardScenePage.test.tsx +++ b/public/app/features/dashboard-scene/pages/DashboardScenePage.test.tsx @@ -11,9 +11,11 @@ import { config, getPluginLinkExtensions, locationService, setPluginImportUtils import { VizPanel } from '@grafana/scenes'; import { Dashboard } from '@grafana/schema'; import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; +import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import store from 'app/core/store'; import { DashboardLoaderSrv, setDashboardLoaderSrv } from 'app/features/dashboard/services/DashboardLoaderSrv'; import { DASHBOARD_FROM_LS_KEY } from 'app/features/dashboard/state/initDashboard'; +import { DashboardRoutes } from 'app/types'; import { dashboardSceneGraph } from '../utils/dashboardSceneGraph'; @@ -24,6 +26,11 @@ jest.mock('@grafana/runtime', () => ({ ...jest.requireActual('@grafana/runtime'), setPluginExtensionGetter: jest.fn(), getPluginLinkExtensions: jest.fn(), + getBackendSrv: () => { + return { + get: jest.fn().mockResolvedValue({ dashboard: simpleDashboard, meta: { url: '' } }), + }; + }, getDataSourceSrv: () => { return { get: jest.fn().mockResolvedValue({}), @@ -37,12 +44,19 @@ jest.mock('@grafana/runtime', () => ({ const getPluginLinkExtensionsMock = jest.mocked(getPluginLinkExtensions); -function setup() { +function setup({ routeProps }: { routeProps?: Partial } = {}) { const context = getGrafanaContextMock(); + const defaultRouteProps = getRouteComponentProps(); const props: Props = { - ...getRouteComponentProps(), + ...defaultRouteProps, + match: { + ...defaultRouteProps.match, + params: { + uid: 'my-dash-uid', + }, + }, + ...routeProps, }; - props.match.params.uid = 'my-dash-uid'; const renderResult = render( @@ -258,14 +272,39 @@ describe('DashboardScenePage', () => { }); describe('home page', () => { - it('should not show controls', async () => { + it('should render the dashboard when the route is home', async () => { + setup({ + routeProps: { + route: { + ...getRouteComponentProps().route, + routeName: DashboardRoutes.Home, + }, + match: { + ...getRouteComponentProps().match, + path: '/', + params: {}, + }, + }, + }); + + await waitForDashbordToRender(); + + expect(await screen.findByTitle('Panel A')).toBeInTheDocument(); + expect(await screen.findByText('Content A')).toBeInTheDocument(); + + expect(await screen.findByTitle('Panel B')).toBeInTheDocument(); + expect(await screen.findByText('Content B')).toBeInTheDocument(); + }); + + it('should show controls', async () => { getDashboardScenePageStateManager().clearDashboardCache(); loadDashboardMock.mockClear(); loadDashboardMock.mockResolvedValue({ dashboard: { panels: [] }, meta: {} }); setup(); - await waitFor(() => expect(screen.queryByText('Refresh')).not.toBeInTheDocument()); + await waitFor(() => expect(screen.queryByText('Refresh')).toBeInTheDocument()); + await waitFor(() => expect(screen.queryByText('Last 6 hours')).toBeInTheDocument()); }); }); }); diff --git a/public/app/features/dashboard-scene/pages/DashboardScenePage.tsx b/public/app/features/dashboard-scene/pages/DashboardScenePage.tsx index 0df1d89260b..7159235f8c1 100644 --- a/public/app/features/dashboard-scene/pages/DashboardScenePage.tsx +++ b/public/app/features/dashboard-scene/pages/DashboardScenePage.tsx @@ -76,7 +76,12 @@ export function DashboardScenePage({ match, route, queryParams, history }: Props } // Do not render anything when transitioning from one dashboard to another - if (match.params.type !== 'snapshot' && dashboard.state.uid && dashboard.state.uid !== match.params.uid) { + if ( + match.params.type !== 'snapshot' && + dashboard.state.uid && + dashboard.state.uid !== match.params.uid && + route.routeName !== DashboardRoutes.Home + ) { return null; } diff --git a/public/app/features/dashboard-scene/scene/DashboardControls.test.tsx b/public/app/features/dashboard-scene/scene/DashboardControls.test.tsx index 52b46d49c99..30b391e0aba 100644 --- a/public/app/features/dashboard-scene/scene/DashboardControls.test.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardControls.test.tsx @@ -104,17 +104,29 @@ describe('DashboardControls', () => { expect(scene.state.hideTimeControls).toBeTruthy(); expect(scene.state.hideVariableControls).toBeTruthy(); expect(scene.state.hideLinksControls).toBeTruthy(); + }); + + it('should not override state if no new state comes from url', () => { + const scene = buildTestScene({ hideTimeControls: true, hideVariableControls: true, hideLinksControls: true }); scene.updateFromUrl({}); - expect(scene.state.hideTimeControls).toBeFalsy(); - expect(scene.state.hideVariableControls).toBeFalsy(); - expect(scene.state.hideLinksControls).toBeFalsy(); + expect(scene.state.hideTimeControls).toBeTruthy(); + expect(scene.state.hideVariableControls).toBeTruthy(); + expect(scene.state.hideLinksControls).toBeTruthy(); }); it('should not call setState if no changes', () => { const scene = buildTestScene(); const setState = jest.spyOn(scene, 'setState'); - scene.updateFromUrl({}); - scene.updateFromUrl({}); + scene.updateFromUrl({ + '_dash.hideTimePicker': 'true', + '_dash.hideVariables': 'true', + '_dash.hideLinks': 'true', + }); + scene.updateFromUrl({ + '_dash.hideTimePicker': 'true', + '_dash.hideVariables': 'true', + '_dash.hideLinks': 'true', + }); expect(setState).toHaveBeenCalledTimes(1); }); }); diff --git a/public/app/features/dashboard-scene/scene/DashboardControls.tsx b/public/app/features/dashboard-scene/scene/DashboardControls.tsx index 39db075bc44..5614c57bfd4 100644 --- a/public/app/features/dashboard-scene/scene/DashboardControls.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardControls.tsx @@ -54,9 +54,14 @@ export class DashboardControls extends SceneObjectBase { updateFromUrl(values: SceneObjectUrlValues) { const update: Partial = {}; - update.hideTimeControls = values['_dash.hideTimePicker'] === 'true' || values['_dash.hideTimePicker'] === ''; - update.hideVariableControls = values['_dash.hideVariables'] === 'true' || values['_dash.hideVariables'] === ''; - update.hideLinksControls = values['_dash.hideLinks'] === 'true' || values['_dash.hideLinks'] === ''; + update.hideTimeControls = + values['_dash.hideTimePicker'] === 'true' || values['_dash.hideTimePicker'] === '' || this.state.hideTimeControls; + update.hideVariableControls = + values['_dash.hideVariables'] === 'true' || + values['_dash.hideVariables'] === '' || + this.state.hideVariableControls; + update.hideLinksControls = + values['_dash.hideLinks'] === 'true' || values['_dash.hideLinks'] === '' || this.state.hideLinksControls; if (Object.entries(update).some(([k, v]) => v !== this.state[k as keyof DashboardControlsState])) { this.setState(update); diff --git a/public/app/features/dashboard-scene/scene/DashboardSceneRenderer.tsx b/public/app/features/dashboard-scene/scene/DashboardSceneRenderer.tsx index f8e77d21856..553710923cf 100644 --- a/public/app/features/dashboard-scene/scene/DashboardSceneRenderer.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardSceneRenderer.tsx @@ -57,7 +57,7 @@ export function DashboardSceneRenderer({ model }: SceneComponentProps {scopes && } - {!isHomePage && controls && hasControls && ( + {controls && hasControls && (