2023-09-22 00:13:19 +08:00
|
|
|
import { css } from '@emotion/css';
|
2023-03-28 17:42:23 +08:00
|
|
|
import React from 'react';
|
|
|
|
|
|
|
|
|
|
import { GrafanaTheme2 } from '@grafana/data';
|
2023-06-08 18:16:08 +08:00
|
|
|
import { selectors } from '@grafana/e2e-selectors';
|
2023-07-12 21:09:22 +08:00
|
|
|
import { config, locationService, reportInteraction } from '@grafana/runtime';
|
2023-08-02 20:58:00 +08:00
|
|
|
import { Button, useStyles2, Text } from '@grafana/ui';
|
2023-09-22 00:13:19 +08:00
|
|
|
import { Box, Flex } from '@grafana/ui/src/unstable';
|
2023-04-20 22:35:29 +08:00
|
|
|
import { Trans } from 'app/core/internationalization';
|
2023-03-30 18:50:35 +08:00
|
|
|
import { DashboardModel } from 'app/features/dashboard/state';
|
2023-09-01 16:11:32 +08:00
|
|
|
import { onAddLibraryPanel, onCreateNewPanel, onImportDashboard } from 'app/features/dashboard/utils/dashboard';
|
2023-04-27 18:11:19 +08:00
|
|
|
import { useDispatch, useSelector } from 'app/types';
|
|
|
|
|
|
|
|
|
|
import { setInitialDatasource } from '../state/reducers';
|
2023-03-28 17:42:23 +08:00
|
|
|
|
|
|
|
|
export interface Props {
|
|
|
|
|
dashboard: DashboardModel;
|
|
|
|
|
canCreate: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-08 18:16:08 +08:00
|
|
|
const DashboardEmpty = ({ dashboard, canCreate }: Props) => {
|
2023-03-28 17:42:23 +08:00
|
|
|
const styles = useStyles2(getStyles);
|
2023-04-27 18:11:19 +08:00
|
|
|
const dispatch = useDispatch();
|
|
|
|
|
const initialDatasource = useSelector((state) => state.dashboard.initialDatasource);
|
2023-03-28 17:42:23 +08:00
|
|
|
|
|
|
|
|
return (
|
2023-09-22 00:13:19 +08:00
|
|
|
<Flex alignItems="center" justifyContent="center">
|
|
|
|
|
<div className={styles.wrapper}>
|
|
|
|
|
<Flex alignItems="stretch" justifyContent="center" gap={4} direction="column">
|
|
|
|
|
<Box borderStyle="dashed" borderColor="info" padding={4}>
|
|
|
|
|
<Flex direction="column" alignItems="center" gap={2}>
|
|
|
|
|
<Text element="h1" textAlignment="center" weight="medium">
|
|
|
|
|
<Trans i18nKey="dashboard.empty.add-visualization-header">
|
|
|
|
|
Start your new dashboard by adding a visualization
|
|
|
|
|
</Trans>
|
|
|
|
|
</Text>
|
|
|
|
|
<Box marginBottom={2} paddingX={4}>
|
2023-07-20 18:59:42 +08:00
|
|
|
<Text element="p" textAlignment="center" color="secondary">
|
2023-09-22 00:13:19 +08:00
|
|
|
<Trans i18nKey="dashboard.empty.add-visualization-body">
|
|
|
|
|
Select a data source and then query and visualize your data with charts, stats and tables or create
|
|
|
|
|
lists, markdowns and other widgets.
|
|
|
|
|
</Trans>
|
2023-07-20 18:59:42 +08:00
|
|
|
</Text>
|
2023-09-22 00:13:19 +08:00
|
|
|
</Box>
|
2023-07-12 21:09:22 +08:00
|
|
|
<Button
|
2023-09-22 00:13:19 +08:00
|
|
|
size="lg"
|
2023-07-12 21:09:22 +08:00
|
|
|
icon="plus"
|
2023-09-22 00:13:19 +08:00
|
|
|
data-testid={selectors.pages.AddDashboard.itemButton('Create new panel button')}
|
2023-07-12 21:09:22 +08:00
|
|
|
onClick={() => {
|
2023-09-22 00:13:19 +08:00
|
|
|
const id = onCreateNewPanel(dashboard, initialDatasource);
|
|
|
|
|
reportInteraction('dashboards_emptydashboard_clicked', { item: 'add_visualization' });
|
|
|
|
|
locationService.partial({ editPanel: id, firstPanel: true });
|
|
|
|
|
dispatch(setInitialDatasource(undefined));
|
2023-07-12 21:09:22 +08:00
|
|
|
}}
|
|
|
|
|
disabled={!canCreate}
|
|
|
|
|
>
|
2023-09-22 00:13:19 +08:00
|
|
|
<Trans i18nKey="dashboard.empty.add-visualization-button">Add visualization</Trans>
|
2023-07-12 21:09:22 +08:00
|
|
|
</Button>
|
2023-09-22 00:13:19 +08:00
|
|
|
</Flex>
|
|
|
|
|
</Box>
|
|
|
|
|
<Flex direction={{ xs: 'column', md: 'row' }} wrap="wrap" gap={4}>
|
|
|
|
|
{config.featureToggles.vizAndWidgetSplit && (
|
|
|
|
|
<Box borderStyle="dashed" borderColor="info" padding={3} grow={1}>
|
|
|
|
|
<Flex direction="column" alignItems="center" gap={1}>
|
|
|
|
|
<Text element="h3" textAlignment="center" weight="medium">
|
|
|
|
|
<Trans i18nKey="dashboard.empty.add-widget-header">Add a widget</Trans>
|
|
|
|
|
</Text>
|
|
|
|
|
<Box marginBottom={2}>
|
|
|
|
|
<Text element="p" textAlignment="center" color="secondary">
|
|
|
|
|
<Trans i18nKey="dashboard.empty.add-widget-body">Create lists, markdowns and other widgets</Trans>
|
|
|
|
|
</Text>
|
|
|
|
|
</Box>
|
|
|
|
|
<Button
|
|
|
|
|
icon="plus"
|
|
|
|
|
fill="outline"
|
|
|
|
|
data-testid={selectors.pages.AddDashboard.itemButton('Create new widget button')}
|
|
|
|
|
onClick={() => {
|
|
|
|
|
reportInteraction('dashboards_emptydashboard_clicked', { item: 'add_widget' });
|
|
|
|
|
locationService.partial({ addWidget: true });
|
|
|
|
|
}}
|
|
|
|
|
disabled={!canCreate}
|
|
|
|
|
>
|
|
|
|
|
<Trans i18nKey="dashboard.empty.add-widget-button">Add widget</Trans>
|
|
|
|
|
</Button>
|
|
|
|
|
</Flex>
|
|
|
|
|
</Box>
|
|
|
|
|
)}
|
|
|
|
|
<Box borderStyle="dashed" borderColor="info" padding={3} grow={1}>
|
|
|
|
|
<Flex direction="column" alignItems="center" gap={1}>
|
|
|
|
|
<Text element="h3" textAlignment="center" weight="medium">
|
|
|
|
|
<Trans i18nKey="dashboard.empty.add-library-panel-header">Import panel</Trans>
|
|
|
|
|
</Text>
|
|
|
|
|
<Box marginBottom={2}>
|
|
|
|
|
<Text element="p" textAlignment="center" color="secondary">
|
|
|
|
|
<Trans i18nKey="dashboard.empty.add-library-panel-body">
|
|
|
|
|
Add visualizations that are shared with other dashboards.
|
|
|
|
|
</Trans>
|
|
|
|
|
</Text>
|
|
|
|
|
</Box>
|
|
|
|
|
<Button
|
|
|
|
|
icon="plus"
|
|
|
|
|
fill="outline"
|
|
|
|
|
data-testid={selectors.pages.AddDashboard.itemButton('Add a panel from the panel library button')}
|
|
|
|
|
onClick={() => {
|
|
|
|
|
reportInteraction('dashboards_emptydashboard_clicked', { item: 'import_from_library' });
|
|
|
|
|
onAddLibraryPanel(dashboard);
|
|
|
|
|
}}
|
|
|
|
|
disabled={!canCreate}
|
|
|
|
|
>
|
|
|
|
|
<Trans i18nKey="dashboard.empty.add-library-panel-button">Add library panel</Trans>
|
|
|
|
|
</Button>
|
|
|
|
|
</Flex>
|
|
|
|
|
</Box>
|
|
|
|
|
<Box borderStyle="dashed" borderColor="info" padding={3} grow={1}>
|
|
|
|
|
<Flex direction="column" alignItems="center" gap={1}>
|
|
|
|
|
<Text element="h3" textAlignment="center" weight="medium">
|
|
|
|
|
<Trans i18nKey="dashboard.empty.import-a-dashboard-header">Import a dashboard</Trans>
|
|
|
|
|
</Text>
|
|
|
|
|
<Box marginBottom={2}>
|
|
|
|
|
<Text element="p" textAlignment="center" color="secondary">
|
|
|
|
|
<Trans i18nKey="dashboard.empty.import-a-dashboard-body">
|
|
|
|
|
Import dashboards from files or
|
|
|
|
|
<a href="https://grafana.com/grafana/dashboards/">grafana.com</a>.
|
|
|
|
|
</Trans>
|
|
|
|
|
</Text>
|
|
|
|
|
</Box>
|
|
|
|
|
<Button
|
|
|
|
|
icon="upload"
|
|
|
|
|
fill="outline"
|
|
|
|
|
data-testid={selectors.pages.AddDashboard.itemButton('Import dashboard button')}
|
|
|
|
|
onClick={() => {
|
|
|
|
|
reportInteraction('dashboards_emptydashboard_clicked', { item: 'import_dashboard' });
|
|
|
|
|
onImportDashboard();
|
|
|
|
|
}}
|
|
|
|
|
disabled={!canCreate}
|
|
|
|
|
>
|
|
|
|
|
<Trans i18nKey="dashboard.empty.import-dashboard-button">Import dashboard</Trans>
|
|
|
|
|
</Button>
|
|
|
|
|
</Flex>
|
|
|
|
|
</Box>
|
|
|
|
|
</Flex>
|
|
|
|
|
</Flex>
|
2023-03-28 17:42:23 +08:00
|
|
|
</div>
|
2023-09-22 00:13:19 +08:00
|
|
|
</Flex>
|
2023-03-28 17:42:23 +08:00
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2023-06-08 18:16:08 +08:00
|
|
|
export default DashboardEmpty;
|
|
|
|
|
|
2023-03-30 18:50:35 +08:00
|
|
|
function getStyles(theme: GrafanaTheme2) {
|
2023-03-28 17:42:23 +08:00
|
|
|
return {
|
|
|
|
|
wrapper: css({
|
|
|
|
|
label: 'dashboard-empty-wrapper',
|
|
|
|
|
flexDirection: 'column',
|
|
|
|
|
maxWidth: '890px',
|
|
|
|
|
gap: theme.spacing.gridSize * 4,
|
2023-05-09 20:33:41 +08:00
|
|
|
paddingTop: theme.spacing(2),
|
|
|
|
|
|
|
|
|
|
[theme.breakpoints.up('sm')]: {
|
|
|
|
|
paddingTop: theme.spacing(12),
|
|
|
|
|
},
|
2023-03-28 17:42:23 +08:00
|
|
|
}),
|
|
|
|
|
};
|
2023-03-30 18:50:35 +08:00
|
|
|
}
|