mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Don't use proxy for rendering dashboard page
This commit is contained in:
parent
bf14c0b125
commit
95836bdb2c
@ -6,27 +6,39 @@ import { Page } from 'app/core/components/Page/Page';
|
||||
import PageLoader from 'app/core/components/PageLoader/PageLoader';
|
||||
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
|
||||
import { DashboardPageRouteParams } from 'app/features/dashboard/containers/types';
|
||||
import { DashboardModel } from 'app/features/dashboard/state';
|
||||
import { DashboardRoutes } from 'app/types';
|
||||
|
||||
import { getDashboardScenePageStateManager } from './DashboardScenePageStateManager';
|
||||
|
||||
export interface Props extends GrafanaRouteComponentProps<DashboardPageRouteParams> {}
|
||||
export interface Props extends GrafanaRouteComponentProps<DashboardPageRouteParams> {
|
||||
preloadedDashboard?: DashboardModel;
|
||||
}
|
||||
|
||||
export function DashboardScenePage({ match, route }: Props) {
|
||||
export function DashboardScenePage({ match, route, preloadedDashboard }: Props) {
|
||||
const stateManager = getDashboardScenePageStateManager();
|
||||
const { dashboard, isLoading, loadError } = stateManager.useState();
|
||||
|
||||
useEffect(() => {
|
||||
if (route.routeName === DashboardRoutes.Home) {
|
||||
stateManager.loadDashboard(route.routeName);
|
||||
} else {
|
||||
stateManager.loadDashboard(match.params.uid);
|
||||
if (!preloadedDashboard) {
|
||||
if (route.routeName === DashboardRoutes.Home) {
|
||||
stateManager.loadDashboard(route.routeName);
|
||||
} else {
|
||||
stateManager.loadDashboard(match.params.uid);
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(preloadedDashboard && preloadedDashboard.uid === match.params.uid) ||
|
||||
(preloadedDashboard && preloadedDashboard.uid === null && route.routeName === DashboardRoutes.Home)
|
||||
) {
|
||||
stateManager.loadSceneFromDashboardModel(preloadedDashboard, route.routeName === DashboardRoutes.Home);
|
||||
}
|
||||
|
||||
return () => {
|
||||
stateManager.clearState();
|
||||
};
|
||||
}, [stateManager, match.params.uid, route.routeName]);
|
||||
}, [stateManager, match.params.uid, route.routeName, preloadedDashboard]);
|
||||
|
||||
if (!dashboard) {
|
||||
return (
|
||||
|
@ -2,11 +2,15 @@ import { getBackendSrv } from '@grafana/runtime';
|
||||
import { StateManagerBase } from 'app/core/services/StateManagerBase';
|
||||
import { dashboardLoaderSrv } from 'app/features/dashboard/services/DashboardLoaderSrv';
|
||||
import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
|
||||
import { DashboardModel } from 'app/features/dashboard/state';
|
||||
import { DashboardDTO, DashboardRoutes } from 'app/types';
|
||||
|
||||
import { buildPanelEditScene, PanelEditor } from '../panel-edit/PanelEditor';
|
||||
import { DashboardScene } from '../scene/DashboardScene';
|
||||
import { transformSaveModelToScene } from '../serialization/transformSaveModelToScene';
|
||||
import {
|
||||
createDashboardSceneFromDashboardModel,
|
||||
transformSaveModelToScene,
|
||||
} from '../serialization/transformSaveModelToScene';
|
||||
import { getVizPanelKeyForPanelId, findVizPanelByKey } from '../utils/utils';
|
||||
|
||||
export interface DashboardScenePageState {
|
||||
@ -88,6 +92,22 @@ export class DashboardScenePageStateManager extends StateManagerBase<DashboardSc
|
||||
throw new Error('Dashboard not found');
|
||||
}
|
||||
|
||||
public loadSceneFromDashboardModel(model: DashboardModel, isHome?: boolean) {
|
||||
const uid = isHome ? 'home' : model.uid;
|
||||
if (!uid) {
|
||||
return;
|
||||
}
|
||||
|
||||
let dashboard: DashboardScene = this.cache[uid];
|
||||
if (!dashboard) {
|
||||
dashboard = createDashboardSceneFromDashboardModel(model);
|
||||
this.cache[uid] = dashboard;
|
||||
}
|
||||
|
||||
this.setState({ dashboard, isLoading: false });
|
||||
dashboard.startUrlSync();
|
||||
}
|
||||
|
||||
public clearState() {
|
||||
getDashboardSrv().setCurrent(undefined);
|
||||
this.setState({ dashboard: undefined, loadError: undefined, isLoading: false, panelEditor: undefined });
|
||||
|
@ -14,9 +14,8 @@ import {
|
||||
SceneObjectStateChangedEvent,
|
||||
sceneUtils,
|
||||
} from '@grafana/scenes';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
|
||||
import { AccessControlAction, DashboardMeta } from 'app/types';
|
||||
import { DashboardMeta } from 'app/types';
|
||||
|
||||
import { DashboardSceneRenderer } from '../scene/DashboardSceneRenderer';
|
||||
import { SaveDashboardDrawer } from '../serialization/SaveDashboardDrawer';
|
||||
@ -254,8 +253,6 @@ export class DashboardScene extends SceneObjectBase<DashboardSceneState> {
|
||||
canEditDashboard() {
|
||||
const { meta } = this.state;
|
||||
|
||||
return (
|
||||
contextSrv.hasPermission(AccessControlAction.DashboardsWrite) && Boolean(meta.canEdit || meta.canMakeEditable)
|
||||
);
|
||||
return Boolean(meta.canEdit || meta.canMakeEditable);
|
||||
}
|
||||
}
|
||||
|
@ -17,15 +17,13 @@ export function DashboardSceneRenderer({ model }: SceneComponentProps<DashboardS
|
||||
const pageNav = model.getPageNav(location);
|
||||
const bodyToRender = model.getBodyToRender(viewPanelId);
|
||||
|
||||
const hasControls = model.canEditDashboard() && controls;
|
||||
|
||||
return (
|
||||
<Page navId="scenes" pageNav={pageNav} layout={PageLayoutType.Custom}>
|
||||
<CustomScrollbar autoHeightMin={'100%'}>
|
||||
<div className={styles.canvasContent}>
|
||||
<NavToolbarActions dashboard={model} />
|
||||
|
||||
{hasControls && (
|
||||
{controls && (
|
||||
<div className={styles.controls}>
|
||||
{controls.map((control) => (
|
||||
<control.Component key={control.state.key} model={control} />
|
||||
@ -33,7 +31,7 @@ export function DashboardSceneRenderer({ model }: SceneComponentProps<DashboardS
|
||||
<SceneDebugger scene={model} key={'scene-debugger'} />
|
||||
</div>
|
||||
)}
|
||||
<div className={cx(styles.body, !hasControls && styles.bodyNoControls)}>
|
||||
<div className={cx(styles.body)}>
|
||||
<bodyToRender.Component model={bodyToRender} />
|
||||
</div>
|
||||
</div>
|
||||
@ -60,9 +58,7 @@ function getStyles(theme: GrafanaTheme2) {
|
||||
gap: '8px',
|
||||
marginBottom: theme.spacing(2),
|
||||
}),
|
||||
bodyNoControls: css({
|
||||
paddingTop: theme.spacing(2),
|
||||
}),
|
||||
|
||||
controls: css({
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
|
@ -202,18 +202,25 @@ export function createDashboardSceneFromDashboardModel(oldModel: DashboardModel)
|
||||
});
|
||||
}
|
||||
|
||||
const controls: SceneObject[] = [
|
||||
let controls: SceneObject[] = [
|
||||
new VariableValueSelectors({}),
|
||||
...filtersSets,
|
||||
new SceneDataLayerControls(),
|
||||
new SceneControlsSpacer(),
|
||||
new SceneTimePicker({}),
|
||||
new SceneRefreshPicker({
|
||||
refresh: oldModel.refresh,
|
||||
intervals: oldModel.timepicker.refresh_intervals,
|
||||
}),
|
||||
];
|
||||
|
||||
if (!Boolean(oldModel.timepicker.hidden)) {
|
||||
controls = controls.concat([
|
||||
new SceneTimePicker({
|
||||
hidePicker: Boolean(oldModel.timepicker.hidden),
|
||||
}),
|
||||
new SceneRefreshPicker({
|
||||
refresh: oldModel.refresh,
|
||||
intervals: oldModel.timepicker.refresh_intervals,
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
return new DashboardScene({
|
||||
title: oldModel.title,
|
||||
uid: oldModel.uid,
|
||||
|
@ -16,6 +16,7 @@ import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
|
||||
import { getNavModel } from 'app/core/selectors/navModel';
|
||||
import { newBrowseDashboardsEnabled } from 'app/features/browse-dashboards/featureFlag';
|
||||
import { PanelModel } from 'app/features/dashboard/state';
|
||||
import DashboardScenePage from 'app/features/dashboard-scene/pages/DashboardScenePage';
|
||||
import { dashboardWatcher } from 'app/features/live/dashboard/dashboardWatcher';
|
||||
import { AngularDeprecationNotice } from 'app/features/plugins/angularDeprecation/AngularDeprecationNotice';
|
||||
import { getPageNavFromSlug, getRootContentNavModel } from 'app/features/storage/StorageFolderPage';
|
||||
@ -339,6 +340,21 @@ export class UnthemedDashboardPage extends PureComponent<Props, State> {
|
||||
);
|
||||
}
|
||||
|
||||
if (config.featureToggles.dashboardSceneForViewers) {
|
||||
if (dashboard && !dashboard.meta.canEdit) {
|
||||
return (
|
||||
<DashboardScenePage
|
||||
history={this.props.history}
|
||||
location={this.props.location}
|
||||
match={this.props.match}
|
||||
queryParams={this.props.queryParams}
|
||||
route={this.props.route}
|
||||
preloadedDashboard={dashboard}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Page
|
||||
|
@ -1,28 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import { config } from '@grafana/runtime';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
|
||||
import DashboardScenePage from 'app/features/dashboard-scene/pages/DashboardScenePage';
|
||||
import { AccessControlAction } from 'app/types';
|
||||
|
||||
import DashboardPage from './DashboardPage';
|
||||
import { DashboardPageRouteParams, DashboardPageRouteSearchParams } from './types';
|
||||
|
||||
type Props = GrafanaRouteComponentProps<DashboardPageRouteParams, DashboardPageRouteSearchParams>;
|
||||
|
||||
// This proxy component is used for Dashboard -> Scenes migration.
|
||||
// It will render DashboardScenePage if user does not have write permissions to a dashboard.
|
||||
function DashboardPageProxy(props: Props) {
|
||||
if (config.featureToggles.dashboardSceneForViewers) {
|
||||
if (contextSrv.hasPermission(AccessControlAction.DashboardsWrite)) {
|
||||
return <DashboardPage {...props} />;
|
||||
} else {
|
||||
return <DashboardScenePage {...props} />;
|
||||
}
|
||||
}
|
||||
|
||||
return <DashboardPage {...props} />;
|
||||
}
|
||||
|
||||
export default DashboardPageProxy;
|
@ -36,7 +36,7 @@ export function getAppRoutes(): RouteDescriptor[] {
|
||||
pageClass: 'page-dashboard',
|
||||
routeName: DashboardRoutes.Home,
|
||||
component: SafeDynamicImport(
|
||||
() => import(/* webpackChunkName: "DashboardPageProxy" */ '../features/dashboard/containers/DashboardPageProxy')
|
||||
() => import(/* webpackChunkName: "DashboardPage" */ '../features/dashboard/containers/DashboardPage')
|
||||
),
|
||||
},
|
||||
{
|
||||
@ -44,7 +44,7 @@ export function getAppRoutes(): RouteDescriptor[] {
|
||||
pageClass: 'page-dashboard',
|
||||
routeName: DashboardRoutes.Normal,
|
||||
component: SafeDynamicImport(
|
||||
() => import(/* webpackChunkName: "DashboardPageProxy" */ '../features/dashboard/containers/DashboardPageProxy')
|
||||
() => import(/* webpackChunkName: "DashboardPage" */ '../features/dashboard/containers/DashboardPage')
|
||||
),
|
||||
},
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user