mirror of
https://github.com/grafana/grafana.git
synced 2025-02-16 18:34:52 -06:00
150 lines
4.7 KiB
TypeScript
150 lines
4.7 KiB
TypeScript
import { css } from '@emotion/css';
|
|
import React, { useEffect, useState } from 'react';
|
|
|
|
import { GrafanaTheme2, PageLayoutType } from '@grafana/data';
|
|
import { getBackendSrv, locationService } from '@grafana/runtime';
|
|
import { TimeZone } from '@grafana/schema';
|
|
import { Button, ModalsController, PageToolbar, useStyles2 } from '@grafana/ui';
|
|
import { Page } from 'app/core/components/Page/Page';
|
|
import { useGrafana } from 'app/core/context/GrafanaContext';
|
|
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
|
|
import { useDispatch, useSelector } from 'app/types';
|
|
|
|
import { updateTimeZoneForSession } from '../../profile/state/reducers';
|
|
import { DashNavTimeControls } from '../components/DashNav/DashNavTimeControls';
|
|
import { DashboardFailed } from '../components/DashboardLoading/DashboardFailed';
|
|
import { DashboardLoading } from '../components/DashboardLoading/DashboardLoading';
|
|
import { SaveDashboardDrawer } from '../components/EmbeddedDashboard/SaveDashboardDrawer';
|
|
import { DashboardGrid } from '../dashgrid/DashboardGrid';
|
|
import { DashboardModel } from '../state';
|
|
import { initDashboard } from '../state/initDashboard';
|
|
|
|
interface EmbeddedDashboardPageRouteParams {
|
|
uid: string;
|
|
}
|
|
|
|
interface EmbeddedDashboardPageRouteSearchParams {
|
|
serverPort?: string;
|
|
json?: string;
|
|
accessToken?: string;
|
|
}
|
|
|
|
export type Props = GrafanaRouteComponentProps<
|
|
EmbeddedDashboardPageRouteParams,
|
|
EmbeddedDashboardPageRouteSearchParams
|
|
>;
|
|
|
|
export default function EmbeddedDashboardPage({ route, queryParams }: Props) {
|
|
const dispatch = useDispatch();
|
|
const context = useGrafana();
|
|
const dashboardState = useSelector((store) => store.dashboard);
|
|
const dashboard = dashboardState.getModel();
|
|
const [dashboardJson, setDashboardJson] = useState('');
|
|
|
|
/**
|
|
* Create dashboard model and initialize the dashboard from JSON
|
|
*/
|
|
useEffect(() => {
|
|
const serverPort = queryParams.serverPort;
|
|
|
|
if (!serverPort) {
|
|
throw new Error('No serverPort provided');
|
|
}
|
|
getBackendSrv()
|
|
.get(`http://localhost:${serverPort}/load-dashboard`)
|
|
.then((dashboardJson) => {
|
|
setDashboardJson(dashboardJson);
|
|
// Remove dashboard UID from JSON to prevent errors from external dashboards
|
|
delete dashboardJson.uid;
|
|
const dashboardModel = new DashboardModel(dashboardJson);
|
|
|
|
dispatch(
|
|
initDashboard({
|
|
routeName: route.routeName,
|
|
fixUrl: false,
|
|
keybindingSrv: context.keybindings,
|
|
dashboardDto: { dashboard: dashboardModel, meta: { canEdit: true } },
|
|
})
|
|
);
|
|
})
|
|
.catch((err) => {
|
|
console.log('Error getting dashboard JSON: ', err);
|
|
});
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, []);
|
|
|
|
if (!dashboard) {
|
|
return <DashboardLoading initPhase={dashboardState.initPhase} />;
|
|
}
|
|
|
|
if (dashboard.meta.dashboardNotFound) {
|
|
return <p>Not available</p>;
|
|
}
|
|
|
|
return (
|
|
<Page pageNav={{ text: dashboard.title }} layout={PageLayoutType.Custom}>
|
|
<Toolbar dashboard={dashboard} dashboardJson={dashboardJson} />
|
|
{dashboardState.initError && <DashboardFailed initError={dashboardState.initError} />}
|
|
<div>
|
|
<DashboardGrid dashboard={dashboard} isEditable viewPanel={null} editPanel={null} hidePanelMenus />
|
|
</div>
|
|
</Page>
|
|
);
|
|
}
|
|
|
|
interface ToolbarProps {
|
|
dashboard: DashboardModel;
|
|
dashboardJson: string;
|
|
}
|
|
|
|
const Toolbar = ({ dashboard, dashboardJson }: ToolbarProps) => {
|
|
const dispatch = useDispatch();
|
|
const styles = useStyles2(getStyles);
|
|
|
|
const onChangeTimeZone = (timeZone: TimeZone) => {
|
|
dispatch(updateTimeZoneForSession(timeZone));
|
|
};
|
|
|
|
const saveDashboard = async (clone: DashboardModel) => {
|
|
const params = locationService.getSearch();
|
|
const serverPort = params.get('serverPort');
|
|
if (!clone || !serverPort) {
|
|
return;
|
|
}
|
|
|
|
return getBackendSrv().post(`http://localhost:${serverPort}/save-dashboard`, { dashboard: clone });
|
|
};
|
|
|
|
return (
|
|
<PageToolbar title={dashboard.title} buttonOverflowAlignment="right" className={styles.toolbar}>
|
|
{!dashboard.timepicker.hidden && (
|
|
<DashNavTimeControls dashboard={dashboard} onChangeTimeZone={onChangeTimeZone} />
|
|
)}
|
|
<ModalsController key="button-save">
|
|
{({ showModal, hideModal }) => (
|
|
<Button
|
|
onClick={() => {
|
|
showModal(SaveDashboardDrawer, {
|
|
dashboard,
|
|
dashboardJson,
|
|
onDismiss: hideModal,
|
|
onSave: saveDashboard,
|
|
});
|
|
}}
|
|
>
|
|
Save
|
|
</Button>
|
|
)}
|
|
</ModalsController>
|
|
</PageToolbar>
|
|
);
|
|
};
|
|
|
|
const getStyles = (theme: GrafanaTheme2) => {
|
|
return {
|
|
toolbar: css`
|
|
padding: ${theme.spacing(3, 2)};
|
|
`,
|
|
};
|
|
};
|