Dashboards: Support drag+drop to import dashboard (#61017)

This commit is contained in:
Ryan McKinley 2023-01-05 10:52:37 -08:00 committed by GitHub
parent 8c3a5f6da0
commit 0f3b4e02a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 34 deletions

View File

@ -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"],

View File

@ -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<Props> {
this.props.cleanUpAction({ cleanupAction: (state) => (state.importDashboard = initialImportDashboardState) });
}
onFileUpload = (event: FormEvent<HTMLInputElement>) => {
// 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<Props> {
return (
<>
<div className={styles.option}>
<FileUpload accept="application/json, text/plain" onFileUpload={this.onFileUpload}>
Upload JSON file
</FileUpload>
<FileDropzone
options={{ multiple: false, accept: ['.json', '.txt'] }}
readAs="readAsText"
fileListRenderer={this.fileListRenderer}
onLoad={this.onFileUpload}
>
<FileDropzoneDefaultChildren
primaryText="Upload dashboard JSON file"
secondaryText="Drag and drop here or click to browse"
/>
</FileDropzone>
</div>
<div className={styles.option}>
<Form onSubmit={this.getGcomDashboard} defaultValues={{ gcomDashboard: '' }}>
@ -223,6 +219,7 @@ const importStyles = stylesFactory((theme: GrafanaTheme2) => {
return {
option: css`
margin-bottom: ${theme.spacing(4)};
max-width: 600px;
`,
};
});