dashboard: copy panel to clipboard

Adds a new menu item to panels, Copy to Clipboard, that will both
copy the panel json to the clipboard and temporarily store the panel object
in the browsers window object. The temporarily stored panel object are
available in Add Panel from any dashboard for as long you don't refresh
the browser.
Fixes #10248, #1004
This commit is contained in:
Marcus Efraimsson
2017-12-21 18:10:24 +01:00
parent e480a38dc1
commit 68457f5636
9 changed files with 102 additions and 11 deletions

View File

@@ -2,8 +2,8 @@ import React from 'react';
import _ from 'lodash';
import config from 'app/core/config';
import {PanelModel} from '../panel_model';
import {PanelContainer} from './PanelContainer';
import { PanelModel } from '../panel_model';
import { PanelContainer } from './PanelContainer';
import ScrollBar from 'app/core/components/ScrollBar/ScrollBar';
export interface AddPanelPanelProps {
@@ -14,6 +14,7 @@ export interface AddPanelPanelProps {
export interface AddPanelPanelState {
filter: string;
panelPlugins: any[];
clipboardPanel: any;
}
export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelPanelState> {
@@ -22,45 +23,77 @@ export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelP
this.state = {
panelPlugins: this.getPanelPlugins(),
clipboardPanel: this.getClipboardPanel(),
filter: '',
};
this.onPanelSelected = this.onPanelSelected.bind(this);
this.onClipboardPanelSelected = this.onClipboardPanelSelected.bind(this);
}
getPanelPlugins() {
let panels = _.chain(config.panels)
.filter({hideFromList: false})
.filter({ hideFromList: false })
.map(item => item)
.value();
// add special row type
panels.push({id: 'row', name: 'Row', sort: 8, info: {logos: {small: 'public/img/icn-row.svg'}}});
panels.push({ id: 'row', name: 'Row', sort: 8, info: { logos: { small: 'public/img/icn-row.svg' } } });
// add sort by sort property
return _.sortBy(panels, 'sort');
}
getClipboardPanel() {
return this.props.getPanelContainer().getClipboardPanel();
}
onPanelSelected(panelPluginInfo) {
const panelContainer = this.props.getPanelContainer();
const dashboard = panelContainer.getDashboard();
const {gridPos} = this.props.panel;
const { gridPos } = this.props.panel;
var newPanel: any = {
type: panelPluginInfo.id,
title: 'Panel Title',
gridPos: {x: gridPos.x, y: gridPos.y, w: gridPos.w, h: gridPos.h}
gridPos: { x: gridPos.x, y: gridPos.y, w: gridPos.w, h: gridPos.h },
};
if (panelPluginInfo.id === 'row') {
newPanel.title = 'Row title';
newPanel.gridPos = {x: 0, y: 0};
newPanel.gridPos = { x: 0, y: 0 };
}
dashboard.addPanel(newPanel);
dashboard.removePanel(this.props.panel);
}
onClipboardPanelSelected(panel) {
const panelContainer = this.props.getPanelContainer();
const dashboard = panelContainer.getDashboard();
const { gridPos } = this.props.panel;
panel.gridPos.x = gridPos.x;
panel.gridPos.y = gridPos.y;
dashboard.addPanel(panel);
dashboard.removePanel(this.props.panel);
}
renderClipboardPanel(copiedPanel) {
const panel = copiedPanel.panel;
const title = `Paste copied panel '${panel.title}' from '${copiedPanel.dashboard}'`;
return (
<div className="add-panel__item" onClick={() => this.onClipboardPanelSelected(panel)} title={title}>
<div className="add-panel__item-icon">
<i className="fa fa-paste fa-2x fa-fw" />
</div>
<div className="add-panel__item-name">Paste copied panel</div>
</div>
);
}
renderPanelItem(panel) {
return (
<div key={panel.id} className="add-panel__item" onClick={() => this.onPanelSelected(panel)} title={panel.name}>
@@ -75,11 +108,12 @@ export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelP
<div className="panel-container">
<div className="add-panel">
<div className="add-panel__header">
<i className="gicon gicon-add-panel"></i>
<i className="gicon gicon-add-panel" />
<span className="add-panel__title">New Panel</span>
<span className="add-panel__sub-title">Select a visualization</span>
</div>
<ScrollBar className="add-panel__items">
{this.state.clipboardPanel && this.renderClipboardPanel(this.state.clipboardPanel)}
{this.state.panelPlugins.map(this.renderPanelItem.bind(this))}
</ScrollBar>
</div>
@@ -87,4 +121,3 @@ export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelP
);
}
}