EmbeddedDashboard: Removes no longer used components (#77195)

This commit is contained in:
Torkel Ödegaard
2023-10-26 11:40:15 +02:00
committed by GitHub
parent 75768cea19
commit c4bf32fa2d
6 changed files with 1 additions and 303 deletions
-3
View File
@@ -3309,9 +3309,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "4"]
],
"public/app/features/dashboard/containers/EmbeddedDashboardPage.tsx:5381": [
[0, 0, 0, "Styles should be written using objects.", "0"]
],
"public/app/features/dashboard/dashgrid/DashboardGrid.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
@@ -1,71 +0,0 @@
import React, { useMemo, useState } from 'react';
import { config } from '@grafana/runtime';
import { Dashboard } from '@grafana/schema';
import { Drawer, Tab, TabsBar } from '@grafana/ui';
import { DashboardModel } from '../../state';
import DashboardValidation from '../SaveDashboard/DashboardValidation';
import { SaveDashboardDiff } from '../SaveDashboard/SaveDashboardDiff';
import { SaveDashboardData } from '../SaveDashboard/types';
import { jsonDiff } from '../VersionHistory/utils';
import { SaveDashboardForm } from './SaveDashboardForm';
type SaveDashboardDrawerProps = {
dashboard: DashboardModel;
onDismiss: () => void;
dashboardJson: string;
onSave: (clone: Dashboard) => Promise<unknown>;
};
export const SaveDashboardDrawer = ({ dashboard, onDismiss, dashboardJson, onSave }: SaveDashboardDrawerProps) => {
const data = useMemo<SaveDashboardData>(() => {
const clone = dashboard.getSaveModelClone();
const diff = jsonDiff(JSON.parse(JSON.stringify(dashboardJson, null, 2)), clone);
let diffCount = 0;
for (const d of Object.values(diff)) {
diffCount += d.length;
}
return {
clone,
diff,
diffCount,
hasChanges: diffCount > 0,
};
}, [dashboard, dashboardJson]);
const [showDiff, setShowDiff] = useState(false);
return (
<Drawer
title={'Save dashboard'}
onClose={onDismiss}
subtitle={dashboard.title}
tabs={
<TabsBar>
<Tab label={'Details'} active={!showDiff} onChangeTab={() => setShowDiff(false)} />
{data.hasChanges && (
<Tab label={'Changes'} active={showDiff} onChangeTab={() => setShowDiff(true)} counter={data.diffCount} />
)}
</TabsBar>
}
>
{showDiff ? (
<SaveDashboardDiff diff={data.diff} oldValue={dashboardJson} newValue={data.clone} />
) : (
<SaveDashboardForm
dashboard={dashboard}
saveModel={data}
onCancel={onDismiss}
onSuccess={onDismiss}
onSubmit={onSave}
/>
)}
{config.featureToggles.showDashboardValidationWarnings && <DashboardValidation dashboard={dashboard} />}
</Drawer>
);
};
@@ -1,58 +0,0 @@
import React, { useMemo, useState } from 'react';
import { Stack } from '@grafana/experimental';
import { Dashboard } from '@grafana/schema';
import { Button, Form } from '@grafana/ui';
import { useAppNotification } from 'app/core/copy/appNotification';
import { DashboardModel } from '../../state';
import { SaveDashboardData } from '../SaveDashboard/types';
interface SaveDashboardProps {
dashboard: DashboardModel;
onCancel: () => void;
onSubmit?: (clone: Dashboard) => Promise<unknown>;
onSuccess: () => void;
saveModel: SaveDashboardData;
}
export const SaveDashboardForm = ({ dashboard, onCancel, onSubmit, onSuccess, saveModel }: SaveDashboardProps) => {
const [saving, setSaving] = useState(false);
const notifyApp = useAppNotification();
const hasChanges = useMemo(() => dashboard.hasTimeChanged() || saveModel.hasChanges, [dashboard, saveModel]);
const onFormSubmit = async () => {
if (!onSubmit) {
return;
}
setSaving(true);
onSubmit(saveModel.clone)
.then(() => {
notifyApp.success('Dashboard saved locally');
onSuccess();
})
.catch((error) => {
notifyApp.error(error.message || 'Error saving dashboard');
})
.finally(() => setSaving(false));
};
return (
<Form onSubmit={onFormSubmit}>
{() => {
return (
<Stack gap={2}>
<Stack alignItems="center">
<Button variant="secondary" onClick={onCancel} fill="outline">
Cancel
</Button>
<Button type="submit" disabled={!hasChanges} icon={saving ? 'spinner' : undefined}>
Save
</Button>
{!hasChanges && <div>No changes to save</div>}
</Stack>
</Stack>
);
}}
</Form>
);
};
@@ -1,149 +0,0 @@
import { css } from '@emotion/css';
import React, { useEffect, useState } from 'react';
import { GrafanaTheme2, PageLayoutType } from '@grafana/data';
import { getBackendSrv, locationService } from '@grafana/runtime';
import { Dashboard, 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: Dashboard) => {
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)};
`,
};
};
-20
View File
@@ -33,23 +33,3 @@ export const getPublicDashboardRoutes = (): RouteDescriptor[] => {
}
return [];
};
export const getEmbeddedDashboardRoutes = (): RouteDescriptor[] => {
if (config.featureToggles.dashboardEmbed) {
return [
{
path: '/d-embed',
pageClass: 'dashboard-embed',
routeName: DashboardRoutes.Embedded,
component: SafeDynamicImport(
() =>
import(
/* webpackChunkName: "EmbeddedDashboardPage" */ '../../features/dashboard/containers/EmbeddedDashboardPage'
)
),
},
];
}
return [];
};
+1 -2
View File
@@ -22,7 +22,7 @@ import { AccessControlAction, DashboardRoutes } from 'app/types';
import { SafeDynamicImport } from '../core/components/DynamicImports/SafeDynamicImport';
import { RouteDescriptor } from '../core/navigation/types';
import { getEmbeddedDashboardRoutes, getPublicDashboardRoutes } from '../features/dashboard/routes';
import { getPublicDashboardRoutes } from '../features/dashboard/routes';
export const extraRoutes: RouteDescriptor[] = [];
@@ -493,7 +493,6 @@ export function getAppRoutes(): RouteDescriptor[] {
...extraRoutes,
...getPublicDashboardRoutes(),
...getDataConnectionsRoutes(),
...getEmbeddedDashboardRoutes(),
{
path: '/*',
component: PageNotFound,