From 0f3b4e02a06d3dda51bef2db9378dafde4c5a042 Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Thu, 5 Jan 2023 10:52:37 -0800 Subject: [PATCH] Dashboards: Support drag+drop to import dashboard (#61017) --- .betterer.results | 4 -- .../manage-dashboards/DashboardImportPage.tsx | 57 +++++++++---------- 2 files changed, 27 insertions(+), 34 deletions(-) diff --git a/.betterer.results b/.betterer.results index 66d75913434..3f2a4722773 100644 --- a/.betterer.results +++ b/.betterer.results @@ -3999,10 +3999,6 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "3"], [0, 0, 0, "Do not use any type assertions.", "4"] ], - "public/app/features/manage-dashboards/DashboardImportPage.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] - ], "public/app/features/manage-dashboards/components/ImportDashboardForm.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], diff --git a/public/app/features/manage-dashboards/DashboardImportPage.tsx b/public/app/features/manage-dashboards/DashboardImportPage.tsx index 49bb4339fb0..b2ba8f44256 100644 --- a/public/app/features/manage-dashboards/DashboardImportPage.tsx +++ b/public/app/features/manage-dashboards/DashboardImportPage.tsx @@ -1,5 +1,5 @@ import { css } from '@emotion/css'; -import React, { FormEvent, PureComponent } from 'react'; +import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { AppEvents, GrafanaTheme2, LoadingState, NavModelItem } from '@grafana/data'; @@ -8,7 +8,6 @@ import { reportInteraction } from '@grafana/runtime'; import { Button, Field, - FileUpload, Form, HorizontalGroup, Input, @@ -17,7 +16,10 @@ import { TextArea, Themeable2, VerticalGroup, + FileDropzone, withTheme2, + DropzoneFile, + FileDropzoneDefaultChildren, } from '@grafana/ui'; import appEvents from 'app/core/app_events'; import { Page } from 'app/core/components/Page/Page'; @@ -67,35 +69,21 @@ class UnthemedDashboardImport extends PureComponent { this.props.cleanUpAction({ cleanupAction: (state) => (state.importDashboard = initialImportDashboardState) }); } - onFileUpload = (event: FormEvent) => { + // 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', }); - 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) { - if (error instanceof Error) { - appEvents.emit(AppEvents.alertError, [ - 'Import failed', - 'JSON -> JS Serialization failed: ' + error.message, - ]); - } - return; - } - importDashboardJson(dashboard); - }; - }; - reader.onload = readerOnLoad(); - reader.readAsText(file); + try { + this.props.importDashboardJson(JSON.parse(String(result))); + } catch (error) { + if (error instanceof Error) { + appEvents.emit(AppEvents.alertError, ['Import failed', 'JSON -> JS Serialization failed: ' + error.message]); + } + return; } }; @@ -131,9 +119,17 @@ class UnthemedDashboardImport extends PureComponent { return ( <>
- - Upload JSON file - + + +
@@ -223,6 +219,7 @@ const importStyles = stylesFactory((theme: GrafanaTheme2) => { return { option: css` margin-bottom: ${theme.spacing(4)}; + max-width: 600px; `, }; });