import { css } from '@emotion/css'; import { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { AppEvents, GrafanaTheme2, LoadingState, NavModelItem } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { Trans, t } from '@grafana/i18n'; import { config, reportInteraction } from '@grafana/runtime'; import { Button, Field, Input, Spinner, stylesFactory, TextArea, Themeable2, FileDropzone, withTheme2, DropzoneFile, FileDropzoneDefaultChildren, LinkButton, TextLink, Label, Stack, } from '@grafana/ui'; import appEvents from 'app/core/app_events'; import { Form } from 'app/core/components/Form/Form'; import { Page } from 'app/core/components/Page/Page'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { dispatch } from 'app/store/store'; import { StoreState } from 'app/types/store'; import { cleanUpAction } from '../../core/actions/cleanUp'; import { ImportDashboardOverviewV2 } from '../dashboard-scene/v2schema/ImportDashboardOverviewV2'; import { ImportDashboardOverview } from './components/ImportDashboardOverview'; import { fetchGcomDashboard, importDashboardJson, importDashboardV2Json } from './state/actions'; import { initialImportDashboardState } from './state/reducers'; import { validateDashboardJson, validateGcomDashboard } from './utils/validation'; type DashboardImportPageRouteSearchParams = { gcomDashboardId?: string; }; type OwnProps = Themeable2 & GrafanaRouteComponentProps<{}, DashboardImportPageRouteSearchParams>; const IMPORT_STARTED_EVENT_NAME = 'dashboard_import_loaded'; const JSON_PLACEHOLDER = `{ "title": "Example - Repeating Dictionary variables", "uid": "_0HnEoN4z", "panels": [...] ... } `; const mapStateToProps = (state: StoreState) => ({ loadingState: state.importDashboard.state, dashboard: state.importDashboard.dashboard, }); const mapDispatchToProps = { fetchGcomDashboard, importDashboardJson, cleanUpAction, }; const connector = connect(mapStateToProps, mapDispatchToProps); type Props = OwnProps & ConnectedProps; class UnthemedDashboardImport extends PureComponent { constructor(props: Props) { super(props); const { gcomDashboardId } = this.props.queryParams; if (gcomDashboardId) { this.getGcomDashboard({ gcomDashboard: gcomDashboardId }); return; } } componentWillUnmount() { this.props.cleanUpAction({ cleanupAction: (state) => (state.importDashboard = initialImportDashboardState) }); } // Do not display upload file list fileListRenderer = (file: DropzoneFile, removeFile: (file: DropzoneFile) => void) => null; onFileUpload = (result: string | ArrayBuffer | null) => { reportInteraction(IMPORT_STARTED_EVENT_NAME, { import_source: 'json_uploaded', }); try { const json = JSON.parse(String(result)); if (json.spec?.elements) { dispatch(importDashboardV2Json(json.spec)); return; } else if (json.elements) { dispatch(importDashboardV2Json(json)); return; } // check if it's a v1 resource format if (json.spec) { this.props.importDashboardJson(json.spec); return; } this.props.importDashboardJson(json); } catch (error) { if (error instanceof Error) { appEvents.emit(AppEvents.alertError, ['Import failed', 'JSON -> JS Serialization failed: ' + error.message]); } return; } }; getDashboardFromJson = (formData: { dashboardJson: string }) => { reportInteraction(IMPORT_STARTED_EVENT_NAME, { import_source: 'json_pasted', }); const dashboard = JSON.parse(formData.dashboardJson); // check if it's a v2 resource format if (dashboard.spec?.elements) { dispatch(importDashboardV2Json(dashboard.spec)); return; // check if it's just a v2 spec } else if (dashboard.elements) { dispatch(importDashboardV2Json(dashboard)); return; } // check if it's a v1 resource format if (dashboard.spec) { this.props.importDashboardJson(dashboard.spec); return; } this.props.importDashboardJson(dashboard); }; getGcomDashboard = (formData: { gcomDashboard: string }) => { reportInteraction(IMPORT_STARTED_EVENT_NAME, { import_source: 'gcom', }); let dashboardId; const match = /(^\d+$)|dashboards\/(\d+)/.exec(formData.gcomDashboard); if (match && match[1]) { dashboardId = match[1]; } else if (match && match[2]) { dashboardId = match[2]; } if (dashboardId) { this.props.fetchGcomDashboard(dashboardId); } }; renderImportForm() { const styles = importStyles(this.props.theme); const GcomDashboardsLink = () => ( // eslint-disable-next-line @grafana/i18n/no-untranslated-strings grafana.com/dashboards ); return ( <>
{({ register, errors }) => ( Find and import dashboards for common applications at } invalid={!!errors.gcomDashboard} error={errors.gcomDashboard && errors.gcomDashboard.message} > Load } /> )}
{({ register, errors }) => ( <>