diff --git a/public/app/features/dashboard/all.ts b/public/app/features/dashboard/all.ts index fd79b7b1f03..72d1a696651 100644 --- a/public/app/features/dashboard/all.ts +++ b/public/app/features/dashboard/all.ts @@ -27,6 +27,7 @@ import './acl/acl'; import './folder_picker/folder_picker'; import './move_to_folder_modal/move_to_folder'; import './settings/settings'; +import './panel_clipboard_srv'; import coreModule from 'app/core/core_module'; import { DashboardListCtrl } from './dashboard_list_ctrl'; diff --git a/public/app/features/dashboard/dashboard_ctrl.ts b/public/app/features/dashboard/dashboard_ctrl.ts index 8b1c69ef7fe..3012f86fe31 100644 --- a/public/app/features/dashboard/dashboard_ctrl.ts +++ b/public/app/features/dashboard/dashboard_ctrl.ts @@ -22,7 +22,8 @@ export class DashboardCtrl implements PanelContainer { private unsavedChangesSrv, private dashboardViewStateSrv, public playlistSrv, - private panelLoader + private panelLoader, + private panelClipboardSrv ) { // temp hack due to way dashboards are loaded // can't use controllerAs on route yet @@ -122,6 +123,10 @@ export class DashboardCtrl implements PanelContainer { return this.panelLoader; } + getClipboardPanel() { + return this.panelClipboardSrv.getPanel(); + } + timezoneChanged() { this.$rootScope.$broadcast('refresh'); } diff --git a/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx b/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx index 75c8cbf36bc..78def4d47bc 100644 --- a/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx +++ b/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx @@ -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 { @@ -22,45 +23,77 @@ export class AddPanelPanel extends React.Component 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 ( +
this.onClipboardPanelSelected(panel)} title={title}> +
+ +
+
Paste copied panel
+
+ ); + } + renderPanelItem(panel) { return (
this.onPanelSelected(panel)} title={panel.name}> @@ -75,11 +108,12 @@ export class AddPanelPanel extends React.Component
- + New Panel Select a visualization
+ {this.state.clipboardPanel && this.renderClipboardPanel(this.state.clipboardPanel)} {this.state.panelPlugins.map(this.renderPanelItem.bind(this))}
@@ -87,4 +121,3 @@ export class AddPanelPanel extends React.Component { diff --git a/public/app/features/panel/panel_header.ts b/public/app/features/panel/panel_header.ts index ca6ed68b648..de8c93d5038 100644 --- a/public/app/features/panel/panel_header.ts +++ b/public/app/features/panel/panel_header.ts @@ -51,6 +51,12 @@ function renderMenuItem(item, ctrl) { html += ` href="${item.href}"`; } + if (item.directives) { + for (let directive of item.directives) { + html += ` ${directive}`; + } + } + html += `>`; html += `${item.text}`; diff --git a/public/sass/base/font-awesome/_larger.scss b/public/sass/base/font-awesome/_larger.scss index 1efeef30392..5d7bebcda14 100644 --- a/public/sass/base/font-awesome/_larger.scss +++ b/public/sass/base/font-awesome/_larger.scss @@ -8,7 +8,7 @@ vertical-align: -15%; } .#{$fa-css-prefix}-2x { - font-size: 2em; + font-size: 2em !important; } .#{$fa-css-prefix}-3x { font-size: 3em; diff --git a/public/sass/components/_panel_add_panel.scss b/public/sass/components/_panel_add_panel.scss index a6b5aebd107..548d677ef47 100644 --- a/public/sass/components/_panel_add_panel.scss +++ b/public/sass/components/_panel_add_panel.scss @@ -65,3 +65,7 @@ .add-panel__item-img { height: calc(100% - 15px); } + +.add-panel__item-icon { + padding: 2px; +}