PublicDashboards: Paused or deleted public dashboard screen (#63970)

This commit is contained in:
juanicabanas
2023-03-03 10:12:29 -03:00
committed by GitHub
parent 92f47e72e1
commit c59682fad6
11 changed files with 172 additions and 10 deletions

View File

@@ -0,0 +1,68 @@
import { css, cx } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2 } from '@grafana/data/src';
import { selectors as e2eSelectors } from '@grafana/e2e-selectors/src';
import { useStyles2 } from '@grafana/ui/src';
import { Branding } from '../../../../core/components/Branding/Branding';
import { getLoginStyles } from '../../../../core/components/Login/LoginLayout';
const selectors = e2eSelectors.pages.PublicDashboard.NotAvailable;
export const PublicDashboardNotAvailable = ({ paused }: { paused?: boolean }) => {
const styles = useStyles2(getStyles);
const loginStyles = useStyles2(getLoginStyles);
const loginBoxBackground = Branding.LoginBoxBackground();
return (
<Branding.LoginBackground className={styles.container} data-testid={selectors.container}>
<div className={cx(styles.box, loginBoxBackground)}>
<Branding.LoginLogo className={loginStyles.loginLogo} />
<p className={styles.title} data-testid={selectors.title}>
{paused
? 'The dashboard has been temporarily paused by the administrator.'
: 'The dashboard your are trying to access does not exist.'}
</p>
{paused && (
<p className={styles.description} data-testid={selectors.pausedDescription}>
Please check again soon.
</p>
)}
</div>
</Branding.LoginBackground>
);
};
const getStyles = (theme: GrafanaTheme2) => ({
container: css`
display: flex;
justify-content: center;
align-items: center;
height: 100%;
:before {
opacity: 1;
}
`,
box: css`
width: 608px;
display: flex;
align-items: center;
flex-direction: column;
gap: ${theme.spacing(4)};
z-index: 1;
border-radius: ${theme.shape.borderRadius(4)};
padding: ${theme.spacing(6, 8)};
opacity: 1;
`,
title: css`
font-size: ${theme.typography.h3.fontSize};
text-align: center;
margin: 0;
`,
description: css`
font-size: ${theme.typography.h5.fontSize};
margin: 0;
`,
});

View File

@@ -82,6 +82,7 @@ const renderWithProvider = ({
};
const selectors = e2eSelectors.components;
const publicDashboardSelector = e2eSelectors.pages.PublicDashboard;
const getTestDashboard = (overrides?: Partial<Dashboard>, metaOverrides?: Partial<DashboardMeta>): DashboardModel => {
const data: Dashboard = Object.assign(
@@ -214,6 +215,10 @@ describe('PublicDashboardPage', () => {
expect(screen.queryByTestId(selectors.RefreshPicker.runButtonV2)).not.toBeInTheDocument();
expect(screen.queryByTestId(selectors.RefreshPicker.intervalButtonV2)).not.toBeInTheDocument();
});
it('Should not render paused or deleted screen', () => {
expect(screen.queryByTestId(publicDashboardSelector.NotAvailable.container)).not.toBeInTheDocument();
});
});
dashboardPageScenario('Given a public dashboard with time range enabled', (ctx) => {
@@ -240,4 +245,50 @@ describe('PublicDashboardPage', () => {
expect(screen.getByTestId(selectors.RefreshPicker.intervalButtonV2)).toBeInTheDocument();
});
});
dashboardPageScenario('Given paused public dashboard', (ctx) => {
ctx.setup(() => {
ctx.mount();
ctx.rerender({
newState: {
dashboard: {
getModel: () => getTestDashboard(undefined, { publicDashboardEnabled: false, dashboardNotFound: false }),
initError: null,
initPhase: DashboardInitPhase.Completed,
permissions: [],
},
},
});
});
it('Should render public dashboard paused screen', () => {
expect(screen.queryByTestId(publicDashboardSelector.page)).not.toBeInTheDocument();
expect(screen.getByTestId(publicDashboardSelector.NotAvailable.title)).toBeInTheDocument();
expect(screen.getByTestId(publicDashboardSelector.NotAvailable.pausedDescription)).toBeInTheDocument();
});
});
dashboardPageScenario('Given deleted public dashboard', (ctx) => {
ctx.setup(() => {
ctx.mount();
ctx.rerender({
newState: {
dashboard: {
getModel: () => getTestDashboard(undefined, { dashboardNotFound: true }),
initError: null,
initPhase: DashboardInitPhase.Completed,
permissions: [],
},
},
});
});
it('Should render public dashboard deleted screen', () => {
expect(screen.queryByTestId(publicDashboardSelector.page)).not.toBeInTheDocument();
expect(screen.getByTestId(publicDashboardSelector.NotAvailable.title)).toBeInTheDocument();
expect(screen.queryByTestId(publicDashboardSelector.NotAvailable.pausedDescription)).not.toBeInTheDocument();
});
});
});

View File

@@ -3,6 +3,7 @@ import React, { useEffect } from 'react';
import { usePrevious } from 'react-use';
import { GrafanaTheme2, PageLayoutType, TimeZone } from '@grafana/data';
import { selectors as e2eSelectors } from '@grafana/e2e-selectors/src';
import { PageToolbar, useStyles2 } from '@grafana/ui';
import { Page } from 'app/core/components/Page/Page';
import { useGrafana } from 'app/core/context/GrafanaContext';
@@ -14,6 +15,7 @@ import { DashNavTimeControls } from '../components/DashNav/DashNavTimeControls';
import { DashboardFailed } from '../components/DashboardLoading/DashboardFailed';
import { DashboardLoading } from '../components/DashboardLoading/DashboardLoading';
import { PublicDashboardFooter } from '../components/PublicDashboardFooter/PublicDashboardsFooter';
import { PublicDashboardNotAvailable } from '../components/PublicDashboardNotAvailable/PublicDashboardNotAvailable';
import { DashboardGrid } from '../dashgrid/DashboardGrid';
import { getTimeSrv } from '../services/TimeSrv';
import { DashboardModel } from '../state';
@@ -31,6 +33,8 @@ interface PublicDashboardPageRouteSearchParams {
export type Props = GrafanaRouteComponentProps<PublicDashboardPageRouteParams, PublicDashboardPageRouteSearchParams>;
const selectors = e2eSelectors.pages.PublicDashboard;
const Toolbar = ({ dashboard }: { dashboard: DashboardModel }) => {
const dispatch = useDispatch();
@@ -91,11 +95,20 @@ const PublicDashboardPage = (props: Props) => {
return <DashboardLoading initPhase={dashboardState.initPhase} />;
}
if (dashboard.meta.publicDashboardEnabled === false) {
return <PublicDashboardNotAvailable paused />;
}
if (dashboard.meta.dashboardNotFound) {
return <PublicDashboardNotAvailable />;
}
return (
<Page
pageNav={{ text: dashboard.title }}
layout={PageLayoutType.Custom}
toolbar={<Toolbar dashboard={dashboard} />}
data-testid={selectors.page}
>
{dashboardState.initError && <DashboardFailed initError={dashboardState.initError} />}
<div className={styles.gridContainer}>

View File

@@ -9,7 +9,7 @@ import impressionSrv from 'app/core/services/impression_srv';
import kbn from 'app/core/utils/kbn';
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
import { getGrafanaStorage } from 'app/features/storage/storage';
import { DashboardDTO, DashboardRoutes } from 'app/types';
import { DashboardDataDTO, DashboardDTO, DashboardMeta, DashboardRoutes } from 'app/types';
import { appEvents } from '../../../core/core';
@@ -17,7 +17,10 @@ import { getDashboardSrv } from './DashboardSrv';
export class DashboardLoaderSrv {
constructor() {}
_dashboardLoadFailed(title: string, snapshot?: boolean) {
_dashboardLoadFailed(
title: string,
snapshot?: boolean
): { meta: DashboardMeta; dashboard: Partial<DashboardDataDTO> } {
snapshot = snapshot || false;
return {
meta: {
@@ -51,8 +54,24 @@ export class DashboardLoaderSrv {
.then((result: any) => {
return result;
})
.catch(() => {
return this._dashboardLoadFailed('Public Dashboard Not found', true);
.catch((e) => {
const isPublicDashboardPaused =
e.data.statusCode === 403 && e.data.messageId === 'publicdashboards.notEnabled';
const isPublicDashboardNotFound =
e.data.statusCode === 404 && e.data.messageId === 'publicdashboards.notFound';
const dashboardModel = this._dashboardLoadFailed(
isPublicDashboardPaused ? 'Public Dashboard paused' : 'Public Dashboard Not found',
true
);
return {
...dashboardModel,
meta: {
...dashboardModel.meta,
publicDashboardEnabled: isPublicDashboardNotFound ? undefined : !isPublicDashboardPaused,
dashboardNotFound: isPublicDashboardNotFound,
},
};
});
} else {
promise = backendSrv