From 4d2131f58fa4550639e09153735a766bc5dd149c Mon Sep 17 00:00:00 2001 From: Chris Bedwell Date: Fri, 13 Oct 2023 15:08:46 +0100 Subject: [PATCH] feat: add useLayout effect to route back home --- src/components/ConfigActions.tsx | 2 +- src/components/Routing.test.tsx | 2 +- src/components/Routing.tsx | 8 +++++++- src/hooks/useNavigation.ts | 29 +++++++++++++++++------------ src/page/WelcomePage.tsx | 18 ++++++++++-------- 5 files changed, 36 insertions(+), 23 deletions(-) diff --git a/src/components/ConfigActions.tsx b/src/components/ConfigActions.tsx index 351d6df2c..1fc3ce7a2 100644 --- a/src/components/ConfigActions.tsx +++ b/src/components/ConfigActions.tsx @@ -31,7 +31,7 @@ export const ConfigActions = ({ enabled, pluginId }: Props) => { }; const handleSetup = () => { - navigate(ROUTES.Setup); + navigate(ROUTES.Home); }; const getAction = () => { diff --git a/src/components/Routing.test.tsx b/src/components/Routing.test.tsx index ecbc59579..694f997a7 100644 --- a/src/components/Routing.test.tsx +++ b/src/components/Routing.test.tsx @@ -28,7 +28,7 @@ describe('Only renders the welcome page regardless of route when app is not init }); }); -// Would like to find the h1s but rendering the Grafana pluginpage is tricky +// Would like to have asserted on the h1s but rendering the Grafana pluginpage is tricky describe('Routes to pages correctly', () => { test('Home page renders', async () => { renderRouting({ path: getRoute(ROUTES.Home) }); diff --git a/src/components/Routing.tsx b/src/components/Routing.tsx index 375426a76..9bf5f116f 100644 --- a/src/components/Routing.tsx +++ b/src/components/Routing.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useContext } from 'react'; +import React, { useLayoutEffect, useEffect, useContext } from 'react'; import { Redirect, Route, Switch, useLocation } from 'react-router-dom'; import { AppRootProps } from '@grafana/data'; import { config } from '@grafana/runtime'; @@ -47,6 +47,12 @@ export const Routing = ({ onNavChanged }: Pick) => } }, [page, navigate, queryParams]); + useLayoutEffect(() => { + if (!provisioned || (!initialized && location.pathname !== getRoute(ROUTES.Home))) { + navigate(ROUTES.Home); + } + }, [provisioned, initialized, location.pathname, navigate]); + if (!provisioned) { return ; } diff --git a/src/hooks/useNavigation.ts b/src/hooks/useNavigation.ts index 782c4bce7..90c665230 100644 --- a/src/hooks/useNavigation.ts +++ b/src/hooks/useNavigation.ts @@ -1,5 +1,6 @@ import { getLocationSrv } from '@grafana/runtime'; import { PLUGIN_URL_PATH } from 'components/constants'; +import { useCallback } from 'react'; import { useHistory } from 'react-router-dom'; export type QueryParamMap = { @@ -8,17 +9,21 @@ export type QueryParamMap = { export function useNavigation() { const history = useHistory(); - const navigate = (url: string, queryParams?: QueryParamMap, external?: boolean, additionalState?: any) => { - const normalized = url.startsWith('/') ? url.slice(1) : url; - if (external) { - getLocationSrv().update({ partial: false, path: `/${normalized}`, query: queryParams }); - } else { - const paramString = Object.entries(queryParams ?? {}).reduce( - (acc, [key, val]) => acc.concat(`&${key}=${val}`), - '' - ); - history.push(`${PLUGIN_URL_PATH}${normalized}${paramString ? '?' : ''}${paramString}`, additionalState); - } - }; + const navigate = useCallback( + (url: string, queryParams?: QueryParamMap, external?: boolean, additionalState?: any) => { + const normalized = url.startsWith('/') ? url.slice(1) : url; + if (external) { + getLocationSrv().update({ partial: false, path: `/${normalized}`, query: queryParams }); + } else { + const paramString = Object.entries(queryParams ?? {}).reduce( + (acc, [key, val]) => acc.concat(`&${key}=${val}`), + '' + ); + history.push(`${PLUGIN_URL_PATH}${normalized}${paramString ? '?' : ''}${paramString}`, additionalState); + } + }, + [history] + ); + return navigate; } diff --git a/src/page/WelcomePage.tsx b/src/page/WelcomePage.tsx index 6b6420c05..21c91cd03 100644 --- a/src/page/WelcomePage.tsx +++ b/src/page/WelcomePage.tsx @@ -1,19 +1,21 @@ import React, { FC, useState, useContext } from 'react'; import { Button, Alert, useStyles2, Spinner, Modal } from '@grafana/ui'; import { getBackendSrv, config } from '@grafana/runtime'; -import { findSMDataSources, hasRole, initializeDatasource } from 'utils'; -import { importAllDashboards } from 'dashboards/loader'; -import { InstanceContext } from 'contexts/InstanceContext'; import { DataSourceInstanceSettings, GrafanaTheme2, OrgRole, DataSourceJsonData } from '@grafana/data'; +import { FaroEvent, reportEvent, reportError } from 'faro'; import { css } from '@emotion/css'; -import { colors, LEGACY_LOGS_DS_NAME, LEGACY_METRICS_DS_NAME, PLUGIN_URL_PATH } from 'components/constants'; -import { dashboardScreenshot, dashboardScreenshotLight } from 'img'; import { isNumber } from 'lodash'; + import { ROUTES, SubmissionErrorWrapper } from 'types'; +import { findSMDataSources, hasRole, initializeDatasource } from 'utils'; +import { dashboardScreenshot, dashboardScreenshotLight } from 'img'; +import { importAllDashboards } from 'dashboards/loader'; +import { InstanceContext } from 'contexts/InstanceContext'; +import { getRoute } from 'components/Routing'; +import { colors, LEGACY_LOGS_DS_NAME, LEGACY_METRICS_DS_NAME } from 'components/constants'; import { DisplayCard } from 'components/DisplayCard'; import FeaturesBanner from 'components/FeaturesBanner'; import { PluginPage } from 'components/PluginPage'; -import { FaroEvent, reportEvent, reportError } from 'faro'; const getStyles = (theme: GrafanaTheme2) => { const textColor = theme.isDark ? colors.darkText : colors.lightText; @@ -274,7 +276,7 @@ export const WelcomePage: FC = () => { await initializeDatasource(datasourcePayload, dashboards); // force reload so that GrafanaBootConfig is updated. - window.location.href = `${window.location.origin}${PLUGIN_URL_PATH}${ROUTES.Home}`; + window.location.href = `${window.location.origin}${getRoute(ROUTES.Home)}`; } catch (e) { const err = e as unknown as SubmissionErrorWrapper; setError(err.data?.msg ?? err.data?.err ?? 'Something went wrong'); @@ -284,7 +286,7 @@ export const WelcomePage: FC = () => { }; return ( - +