import { css } from '@emotion/css'; import React, { FormEvent, PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { AppEvents, GrafanaTheme2, LoadingState } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { reportInteraction } from '@grafana/runtime'; import { Button, Field, FileUpload, Form, HorizontalGroup, Input, Spinner, stylesFactory, TextArea, Themeable2, VerticalGroup, withTheme2, } from '@grafana/ui'; import appEvents from 'app/core/app_events'; import Page from 'app/core/components/Page/Page'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types'; import { cleanUpAction } from '../../core/actions/cleanUp'; import { ImportDashboardOverview } from './components/ImportDashboardOverview'; import { fetchGcomDashboard, importDashboardJson } from './state/actions'; import { validateDashboardJson, validateGcomDashboard } from './utils/validation'; type DashboardImportPageRouteSearchParams = { gcomDashboardId?: string; }; type OwnProps = Themeable2 & GrafanaRouteComponentProps<{}, DashboardImportPageRouteSearchParams>; const IMPORT_STARTED_EVENT_NAME = 'dashboard_import_loaded'; const mapStateToProps = (state: StoreState) => ({ navModel: getNavModel(state.navIndex, 'import', undefined, true), loadingState: state.importDashboard.state, }); 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({ stateSelector: (state: StoreState) => state.importDashboard }); } onFileUpload = (event: FormEvent) => { reportInteraction(IMPORT_STARTED_EVENT_NAME, { import_source: 'json_uploaded', }); const { importDashboardJson } = this.props; const file = event.currentTarget.files && event.currentTarget.files.length > 0 && event.currentTarget.files[0]; if (file) { const reader = new FileReader(); const readerOnLoad = () => { return (e: any) => { let dashboard: any; try { dashboard = JSON.parse(e.target.result); } catch (error) { appEvents.emit(AppEvents.alertError, [ 'Import failed', 'JSON -> JS Serialization failed: ' + error.message, ]); return; } importDashboardJson(dashboard); }; }; reader.onload = readerOnLoad(); reader.readAsText(file); } }; getDashboardFromJson = (formData: { dashboardJson: string }) => { reportInteraction(IMPORT_STARTED_EVENT_NAME, { import_source: 'json_pasted', }); this.props.importDashboardJson(JSON.parse(formData.dashboardJson)); }; 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); return ( <>
Upload JSON file
{({ register, errors }) => ( Load} /> )}
{({ register, errors }) => ( <>