mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Plugins: Show a not found error page when accessing an app for a not-found plugin (#77922)
* Plugins: Shows a not found error page when accesing an app for a non-found plugin * Use loadingError in state to verify is a loading error
This commit is contained in:
parent
494a07b522
commit
3a4f73338c
@ -102,6 +102,13 @@ describe('AppRootPage', () => {
|
||||
enabled: true,
|
||||
});
|
||||
|
||||
it("should show a not found page if the plugin settings can't load", async () => {
|
||||
getPluginSettingsMock.mockRejectedValue(new Error('Unknown Plugin'));
|
||||
// Renders once for the first time
|
||||
await renderUnderRouter();
|
||||
expect(await screen.findByText('App not found')).toBeVisible();
|
||||
});
|
||||
|
||||
it('should not render the component if we are not under a plugin path', async () => {
|
||||
getPluginSettingsMock.mockResolvedValue(pluginMeta);
|
||||
|
||||
|
@ -8,6 +8,7 @@ import { config, locationSearchToObject } from '@grafana/runtime';
|
||||
import { Alert } from '@grafana/ui';
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import PageLoader from 'app/core/components/PageLoader/PageLoader';
|
||||
import { EntityNotFound } from 'app/core/components/PageNotFound/EntityNotFound';
|
||||
import { useGrafana } from 'app/core/context/GrafanaContext';
|
||||
import { appEvents, contextSrv } from 'app/core/core';
|
||||
import { getNotFoundNav, getWarningNav, getExceptionNav } from 'app/core/navigation/errorModels';
|
||||
@ -27,19 +28,20 @@ interface Props {
|
||||
|
||||
interface State {
|
||||
loading: boolean;
|
||||
loadingError: boolean;
|
||||
plugin?: AppPlugin | null;
|
||||
// Used to display a tab navigation (used before the new Top Nav)
|
||||
pluginNav: NavModel | null;
|
||||
}
|
||||
|
||||
const initialState: State = { loading: true, pluginNav: null, plugin: null };
|
||||
const initialState: State = { loading: true, loadingError: false, pluginNav: null, plugin: null };
|
||||
|
||||
export function AppRootPage({ pluginId, pluginNavSection }: Props) {
|
||||
const match = useRouteMatch();
|
||||
const location = useLocation();
|
||||
const [state, dispatch] = useReducer(stateSlice.reducer, initialState);
|
||||
const currentUrl = config.appSubUrl + location.pathname + location.search;
|
||||
const { plugin, loading, pluginNav } = state;
|
||||
const { plugin, loading, loadingError, pluginNav } = state;
|
||||
const navModel = buildPluginSectionNav(pluginNavSection, pluginNav, currentUrl);
|
||||
const queryParams = useMemo(() => locationSearchToObject(location.search), [location.search]);
|
||||
const context = useMemo(() => buildPluginPageContext(navModel), [navModel]);
|
||||
@ -60,6 +62,7 @@ export function AppRootPage({ pluginId, pluginNavSection }: Props) {
|
||||
return (
|
||||
<Page navModel={navModel} pageNav={{ text: '' }} layout={currentLayout}>
|
||||
{loading && <PageLoader />}
|
||||
{!loading && loadingError && <EntityNotFound entity="App" />}
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
@ -167,12 +170,13 @@ async function loadAppPlugin(pluginId: string, dispatch: React.Dispatch<AnyActio
|
||||
}
|
||||
return importAppPlugin(info);
|
||||
});
|
||||
dispatch(stateSlice.actions.setState({ plugin: app, loading: false, pluginNav: null }));
|
||||
dispatch(stateSlice.actions.setState({ plugin: app, loading: false, loadingError: false, pluginNav: null }));
|
||||
} catch (err) {
|
||||
dispatch(
|
||||
stateSlice.actions.setState({
|
||||
plugin: null,
|
||||
loading: false,
|
||||
loadingError: true,
|
||||
pluginNav: process.env.NODE_ENV === 'development' ? getExceptionNav(err) : getNotFoundNav(),
|
||||
})
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user