Commit 4183921c by Peter Holmberg Committed by GitHub

Dashboard import: Bug fixes (#23591)

* clear dashboard on unmount

* fix menu z-index, folderpicker width

* fix issue with saving dashboard in another folder

* use foldermodel instead of selectablevalue

* using z-index from theme

* updated names

* update snapshot

* remove size from folderpicker

* use connectWithCleanup

* update snapshot
parent e1621372
...@@ -332,6 +332,8 @@ export function SelectBase<T>({ ...@@ -332,6 +332,8 @@ export function SelectBase<T>({
}), }),
container: () => ({ container: () => ({
position: 'relative', position: 'relative',
// This puts the menu above Inputs (z-index: 1)
zIndex: theme.zIndex.dropdown,
width: width ? `${8 * width}px` : '100%', width: width ? `${8 * width}px` : '100%',
}), }),
}} }}
......
import React, { FormEvent, PureComponent } from 'react'; import React, { FormEvent, PureComponent } from 'react';
import { connect, MapDispatchToProps, MapStateToProps } from 'react-redux'; import { MapDispatchToProps, MapStateToProps } from 'react-redux';
import { css } from 'emotion'; import { css } from 'emotion';
import { AppEvents, NavModel } from '@grafana/data'; import { AppEvents, NavModel } from '@grafana/data';
import { Button, stylesFactory, Input, TextArea, Field, Form, Legend } from '@grafana/ui'; import { Button, stylesFactory, Input, TextArea, Field, Form, Legend } from '@grafana/ui';
import Page from 'app/core/components/Page/Page'; import Page from 'app/core/components/Page/Page';
import { connectWithCleanUp } from 'app/core/components/connectWithCleanUp';
import { ImportDashboardOverview } from './components/ImportDashboardOverview'; import { ImportDashboardOverview } from './components/ImportDashboardOverview';
import { DashboardFileUpload } from './components/DashboardFileUpload'; import { DashboardFileUpload } from './components/DashboardFileUpload';
import { validateDashboardJson, validateGcomDashboard } from './utils/validation'; import { validateDashboardJson, validateGcomDashboard } from './utils/validation';
...@@ -142,7 +143,11 @@ const mapDispatchToProps: MapDispatchToProps<DispatchProps, Props> = { ...@@ -142,7 +143,11 @@ const mapDispatchToProps: MapDispatchToProps<DispatchProps, Props> = {
importDashboardJson, importDashboardJson,
}; };
export const DashboardImportPage = connect(mapStateToProps, mapDispatchToProps)(DashboardImportUnConnected); export const DashboardImportPage = connectWithCleanUp(
mapStateToProps,
mapDispatchToProps,
state => state.importDashboard
)(DashboardImportUnConnected);
export default DashboardImportPage; export default DashboardImportPage;
DashboardImportPage.displayName = 'DashboardImport'; DashboardImportPage.displayName = 'DashboardImport';
......
...@@ -58,18 +58,12 @@ export const ImportDashboardForm: FC<Props> = ({ ...@@ -58,18 +58,12 @@ export const ImportDashboardForm: FC<Props> = ({
type="text" type="text"
ref={register({ ref={register({
required: 'Name is required', required: 'Name is required',
validate: async (v: string) => await validateTitle(v, getValues().folderId), validate: async (v: string) => await validateTitle(v, getValues().folder.id),
})} })}
/> />
</Field> </Field>
<Field label="Folder"> <Field label="Folder">
<InputControl <InputControl as={FolderPicker} name="folder" useNewForms initialFolderId={initialFolderId} control={control} />
as={FolderPicker}
name="folderId"
useNewForms
initialFolderId={initialFolderId}
control={control}
/>
</Field> </Field>
<Field <Field
label="Unique identifier (uid)" label="Unique identifier (uid)"
......
...@@ -3,7 +3,7 @@ import { dateTime } from '@grafana/data'; ...@@ -3,7 +3,7 @@ import { dateTime } from '@grafana/data';
import { Forms, Form } from '@grafana/ui'; import { Forms, Form } from '@grafana/ui';
import { connect, MapDispatchToProps, MapStateToProps } from 'react-redux'; import { connect, MapDispatchToProps, MapStateToProps } from 'react-redux';
import { ImportDashboardForm } from './ImportDashboardForm'; import { ImportDashboardForm } from './ImportDashboardForm';
import { resetDashboard, saveDashboard } from '../state/actions'; import { clearLoadedDashboard, saveDashboard } from '../state/actions';
import { DashboardInputs, DashboardSource, ImportDashboardDTO } from '../state/reducers'; import { DashboardInputs, DashboardSource, ImportDashboardDTO } from '../state/reducers';
import { StoreState } from 'app/types'; import { StoreState } from 'app/types';
...@@ -14,11 +14,11 @@ interface ConnectedProps { ...@@ -14,11 +14,11 @@ interface ConnectedProps {
inputs: DashboardInputs; inputs: DashboardInputs;
source: DashboardSource; source: DashboardSource;
meta?: any; meta?: any;
folderId: number; folder: { id: number; title?: string };
} }
interface DispatchProps { interface DispatchProps {
resetDashboard: typeof resetDashboard; clearLoadedDashboard: typeof clearLoadedDashboard;
saveDashboard: typeof saveDashboard; saveDashboard: typeof saveDashboard;
} }
...@@ -38,7 +38,7 @@ class ImportDashboardOverviewUnConnected extends PureComponent<Props, State> { ...@@ -38,7 +38,7 @@ class ImportDashboardOverviewUnConnected extends PureComponent<Props, State> {
}; };
onCancel = () => { onCancel = () => {
this.props.resetDashboard(); this.props.clearLoadedDashboard();
}; };
onUidReset = () => { onUidReset = () => {
...@@ -46,7 +46,7 @@ class ImportDashboardOverviewUnConnected extends PureComponent<Props, State> { ...@@ -46,7 +46,7 @@ class ImportDashboardOverviewUnConnected extends PureComponent<Props, State> {
}; };
render() { render() {
const { dashboard, inputs, meta, source, folderId } = this.props; const { dashboard, inputs, meta, source, folder } = this.props;
const { uidReset } = this.state; const { uidReset } = this.state;
return ( return (
...@@ -81,7 +81,7 @@ class ImportDashboardOverviewUnConnected extends PureComponent<Props, State> { ...@@ -81,7 +81,7 @@ class ImportDashboardOverviewUnConnected extends PureComponent<Props, State> {
)} )}
<Form <Form
onSubmit={this.onSubmit} onSubmit={this.onSubmit}
defaultValues={{ ...dashboard, constants: [], dataSources: [], folderId }} defaultValues={{ ...dashboard, constants: [], dataSources: [], folder: folder }}
validateOnMount validateOnMount
validateFieldsOnMount={['title', 'uid']} validateFieldsOnMount={['title', 'uid']}
validateOn="onChange" validateOn="onChange"
...@@ -97,7 +97,7 @@ class ImportDashboardOverviewUnConnected extends PureComponent<Props, State> { ...@@ -97,7 +97,7 @@ class ImportDashboardOverviewUnConnected extends PureComponent<Props, State> {
onCancel={this.onCancel} onCancel={this.onCancel}
onUidReset={this.onUidReset} onUidReset={this.onUidReset}
onSubmit={this.onSubmit} onSubmit={this.onSubmit}
initialFolderId={folderId} initialFolderId={folder.id}
/> />
)} )}
</Form> </Form>
...@@ -111,11 +111,11 @@ const mapStateToProps: MapStateToProps<ConnectedProps, OwnProps, StoreState> = ( ...@@ -111,11 +111,11 @@ const mapStateToProps: MapStateToProps<ConnectedProps, OwnProps, StoreState> = (
meta: state.importDashboard.meta, meta: state.importDashboard.meta,
source: state.importDashboard.source, source: state.importDashboard.source,
inputs: state.importDashboard.inputs, inputs: state.importDashboard.inputs,
folderId: state.location.routeParams.folderId ? Number(state.location.routeParams.folderId) : 0, folder: state.location.routeParams.folderId ? { id: Number(state.location.routeParams.folderId) } : { id: 0 },
}); });
const mapDispatchToProps: MapDispatchToProps<DispatchProps, OwnProps> = { const mapDispatchToProps: MapDispatchToProps<DispatchProps, OwnProps> = {
resetDashboard, clearLoadedDashboard,
saveDashboard, saveDashboard,
}; };
......
...@@ -60,7 +60,7 @@ function processInputs(dashboardJson: any): ThunkResult<void> { ...@@ -60,7 +60,7 @@ function processInputs(dashboardJson: any): ThunkResult<void> {
}; };
} }
export function resetDashboard(): ThunkResult<void> { export function clearLoadedDashboard(): ThunkResult<void> {
return dispatch => { return dispatch => {
dispatch(clearDashboard()); dispatch(clearDashboard());
}; };
...@@ -96,7 +96,7 @@ export function saveDashboard(importDashboardForm: ImportDashboardDTO): ThunkRes ...@@ -96,7 +96,7 @@ export function saveDashboard(importDashboardForm: ImportDashboardDTO): ThunkRes
dashboard: { ...dashboard, title: importDashboardForm.title, uid: importDashboardForm.uid }, dashboard: { ...dashboard, title: importDashboardForm.title, uid: importDashboardForm.uid },
overwrite: true, overwrite: true,
inputs: inputsToPersist, inputs: inputsToPersist,
folderId: importDashboardForm.folderId, folderId: importDashboardForm.folder.id,
}); });
const dashboardUrl = locationUtil.stripBaseFromUrl(result.importedUrl); const dashboardUrl = locationUtil.stripBaseFromUrl(result.importedUrl);
dispatch(updateLocation({ path: dashboardUrl })); dispatch(updateLocation({ path: dashboardUrl }));
......
...@@ -12,7 +12,7 @@ export interface ImportDashboardDTO { ...@@ -12,7 +12,7 @@ export interface ImportDashboardDTO {
gnetId: string; gnetId: string;
constants: string[]; constants: string[];
dataSources: DataSourceSelectItem[]; dataSources: DataSourceSelectItem[];
folderId: number; folder: { id: number; title?: string };
} }
export enum InputType { export enum InputType {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment