From 9ac82f3d0ec213a4936d78c50943ee82d1937f70 Mon Sep 17 00:00:00 2001 From: Patrick O'Carroll Date: Wed, 21 Feb 2018 14:51:28 +0100 Subject: [PATCH 01/11] added tabs and searchfilter to addpanel, fixes#10427 --- .../dashboard/dashgrid/AddPanelPanel.tsx | 98 +++++++++++++++++-- public/sass/components/_panel_add_panel.scss | 19 +++- public/sass/components/_tabs.scss | 12 +-- 3 files changed, 110 insertions(+), 19 deletions(-) diff --git a/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx b/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx index aeb840c317a..8d4ebfb3a10 100644 --- a/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx +++ b/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx @@ -16,6 +16,8 @@ export interface AddPanelPanelProps { export interface AddPanelPanelState { filter: string; panelPlugins: any[]; + copiedPanelPlugins: any[]; + tab: string; } export class AddPanelPanel extends React.Component { @@ -25,12 +27,14 @@ export class AddPanelPanel extends React.Component item) @@ -39,6 +43,19 @@ export class AddPanelPanel extends React.Component item) + .value(); + let copiedPanels = []; + let copiedPanelJson = store.get(LS_PANEL_COPY_KEY); if (copiedPanelJson) { let copiedPanel = JSON.parse(copiedPanelJson); @@ -48,12 +65,13 @@ export class AddPanelPanel extends React.Component { @@ -101,19 +119,85 @@ export class AddPanelPanel extends React.Component { + return regex.test(panel.name); + }); + } + + openCopy() { + this.setState({ tab: 'Copy' }); + this.setState({ filter: '' }); + this.setState({ panelPlugins: this.getPanelPlugins('') }); + this.setState({ copiedPanelPlugins: this.getCopiedPanelPlugins('') }); + } + + openAdd() { + this.setState({ tab: 'Add' }); + this.setState({ filter: '' }); + this.setState({ panelPlugins: this.getPanelPlugins('') }); + this.setState({ copiedPanelPlugins: this.getCopiedPanelPlugins('') }); + } + render() { + let addClass; + let copyClass; + let panelTab; + + if (this.state.tab === 'Add') { + addClass = 'active active--panel'; + copyClass = ''; + panelTab = this.state.panelPlugins.map(this.renderPanelItem); + } else if (this.state.tab === 'Copy') { + addClass = ''; + copyClass = 'active active--panel'; + panelTab = this.state.copiedPanelPlugins.map(this.renderPanelItem); + } + return (
New Panel - Select a visualization +
    +
  • +
    + Add +
    +
  • +
  • +
    + Copy +
    +
  • +
- {this.state.panelPlugins.map(this.renderPanelItem)} + +
+ +
+ {panelTab} +
); diff --git a/public/sass/components/_panel_add_panel.scss b/public/sass/components/_panel_add_panel.scss index 51754a54d92..70aff32a945 100644 --- a/public/sass/components/_panel_add_panel.scss +++ b/public/sass/components/_panel_add_panel.scss @@ -3,9 +3,12 @@ } .add-panel__header { - padding: 5px 15px; + padding: 0 15px; display: flex; align-items: center; + background: $page-header-bg; + box-shadow: $page-header-shadow; + border-bottom: 1px solid $page-header-border-color; .gicon { font-size: 30px; @@ -23,7 +26,7 @@ .add-panel__title { font-size: $font-size-md; - margin-right: $spacer/2; + margin-right: $spacer*2; } .add-panel__sub-title { @@ -39,9 +42,9 @@ flex-direction: row; flex-wrap: wrap; overflow: auto; - height: calc(100% - 43px); + height: calc(100% - 50px); align-content: flex-start; - justify-content: space-around; + justify-content: space-between; position: relative; } @@ -51,7 +54,7 @@ border-radius: 3px; padding: $spacer/3 $spacer; - width: 31%; + width: 32%; height: 60px; text-align: center; margin: $gf-form-margin; @@ -77,3 +80,9 @@ .add-panel__item-icon { padding: 2px; } + +.add-panel__searchbar { + width: 100%; + margin-bottom: 10px; + margin-top: 7px; +} diff --git a/public/sass/components/_tabs.scss b/public/sass/components/_tabs.scss index 197d5892652..eb3c8ce13f5 100644 --- a/public/sass/components/_tabs.scss +++ b/public/sass/components/_tabs.scss @@ -44,18 +44,16 @@ &::before { display: block; - content: " "; + content: ' '; position: absolute; left: 0; right: 0; height: 2px; top: 0; - background-image: linear-gradient( - to right, - #ffd500 0%, - #ff4400 99%, - #ff4400 100% - ); + background-image: linear-gradient(to right, #ffd500 0%, #ff4400 99%, #ff4400 100%); } } + &.active--panel { + background: $panel-bg !important; + } } From 5e5a4cf1b0f8391b85521182c44b995d7c6eee3d Mon Sep 17 00:00:00 2001 From: Patrick O'Carroll Date: Wed, 21 Feb 2018 15:39:15 +0100 Subject: [PATCH 02/11] added highlighter, fixed setState and changed back flex to spacea around --- .../dashboard/dashgrid/AddPanelPanel.tsx | 39 +++++++++++++------ public/sass/components/_panel_add_panel.scss | 4 +- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx b/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx index 8d4ebfb3a10..1c2eeb8fcc6 100644 --- a/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx +++ b/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx @@ -7,6 +7,7 @@ import { PanelContainer } from './PanelContainer'; import ScrollBar from 'app/core/components/ScrollBar/ScrollBar'; import store from 'app/core/store'; import { LS_PANEL_COPY_KEY } from 'app/core/constants'; +import Highlighter from 'react-highlight-words'; export interface AddPanelPanelProps { panel: PanelModel; @@ -110,19 +111,29 @@ export class AddPanelPanel extends React.Component; + //} + //return text; + } + renderPanelItem(panel, index) { return (
this.onAddPanel(panel)} title={panel.name}> -
{panel.name}
+
{this.renderText(panel.name)}
); } filterChange(evt) { - this.setState({ filter: evt.target.value }); - this.setState({ panelPlugins: this.getPanelPlugins(evt.target.value) }); - this.setState({ copiedPanelPlugins: this.getCopiedPanelPlugins(evt.target.value) }); + this.setState({ + filter: evt.target.value, + panelPlugins: this.getPanelPlugins(evt.target.value), + copiedPanelPlugins: this.getCopiedPanelPlugins(evt.target.value), + }); } filterPanels(panels, filter) { @@ -133,17 +144,21 @@ export class AddPanelPanel extends React.Component Date: Thu, 22 Feb 2018 09:58:52 +0100 Subject: [PATCH 03/11] added no copies div --- .../features/dashboard/dashgrid/AddPanelPanel.tsx | 14 ++++++++++---- public/sass/components/_panel_add_panel.scss | 7 +++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx b/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx index 1c2eeb8fcc6..23042285754 100644 --- a/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx +++ b/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx @@ -112,11 +112,8 @@ export class AddPanelPanel extends React.Component; - //} - //return text; } renderPanelItem(panel, index) { @@ -128,6 +125,10 @@ export class AddPanelPanel extends React.ComponentNo copied panels yet.; + } + filterChange(evt) { this.setState({ filter: evt.target.value, @@ -173,7 +174,12 @@ export class AddPanelPanel extends React.Component 0) { + panelTab = this.state.copiedPanelPlugins.map(this.renderPanelItem); + } else { + panelTab = this.noCopiedPanelPlugins(); + } } return ( diff --git a/public/sass/components/_panel_add_panel.scss b/public/sass/components/_panel_add_panel.scss index 6dd609ee544..5322d8fcea0 100644 --- a/public/sass/components/_panel_add_panel.scss +++ b/public/sass/components/_panel_add_panel.scss @@ -86,3 +86,10 @@ margin-bottom: 10px; margin-top: 7px; } + +.add-panel__no-panels { + color: $text-color-weak; + font-style: italic; + width: 100%; + padding: 3px 8px; +} From 07c3fb7e0f1a86009c9497698fa79d731d88dff7 Mon Sep 17 00:00:00 2001 From: Patrick O'Carroll Date: Thu, 22 Feb 2018 10:38:22 +0100 Subject: [PATCH 04/11] changed name of copy tab to paste --- public/app/features/dashboard/dashgrid/AddPanelPanel.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx b/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx index 23042285754..d5b301a9ea1 100644 --- a/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx +++ b/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx @@ -196,7 +196,7 @@ export class AddPanelPanel extends React.Component
  • - Copy + Paste
  • From 8d4c439eebeaa07af8eeab17395a31d26466cbb6 Mon Sep 17 00:00:00 2001 From: Patrick O'Carroll Date: Wed, 7 Mar 2018 12:46:27 +0100 Subject: [PATCH 05/11] add panel to list now copy, started on jest --- public/app/features/dashboard/dashgrid/AddPanelPanel.jest.tsx | 4 ++++ public/app/features/panel/panel_ctrl.ts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 public/app/features/dashboard/dashgrid/AddPanelPanel.jest.tsx diff --git a/public/app/features/dashboard/dashgrid/AddPanelPanel.jest.tsx b/public/app/features/dashboard/dashgrid/AddPanelPanel.jest.tsx new file mode 100644 index 00000000000..e68d84ad8bb --- /dev/null +++ b/public/app/features/dashboard/dashgrid/AddPanelPanel.jest.tsx @@ -0,0 +1,4 @@ +import React from 'react'; +import { AddPanelPanel } from './AddPanelPanel'; + +describe('AddPanelPanel', () => {}); diff --git a/public/app/features/panel/panel_ctrl.ts b/public/app/features/panel/panel_ctrl.ts index d8757f49be6..11dac549aea 100644 --- a/public/app/features/panel/panel_ctrl.ts +++ b/public/app/features/panel/panel_ctrl.ts @@ -193,7 +193,7 @@ export class PanelCtrl { }); menu.push({ - text: 'Add to Panel List', + text: 'Copy', click: 'ctrl.addToPanelList()', role: 'Editor', }); From 834c42194321920e969f0e1155cbf476fe69a8df Mon Sep 17 00:00:00 2001 From: Patrick O'Carroll Date: Wed, 7 Mar 2018 15:01:50 +0100 Subject: [PATCH 06/11] replaced if with classNames --- .../dashboard/dashgrid/AddPanelPanel.tsx | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx b/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx index d5b301a9ea1..eb677b4b4b2 100644 --- a/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx +++ b/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx @@ -1,6 +1,6 @@ import React from 'react'; import _ from 'lodash'; - +import classNames from 'classnames'; import config from 'app/core/config'; import { PanelModel } from '../panel_model'; import { PanelContainer } from './PanelContainer'; @@ -163,18 +163,21 @@ export class AddPanelPanel extends React.Component 0) { panelTab = this.state.copiedPanelPlugins.map(this.renderPanelItem); } else { From 1d190de91800223c732a0ebc57e6c71921f2e0c4 Mon Sep 17 00:00:00 2001 From: Patrick O'Carroll Date: Mon, 12 Mar 2018 11:58:47 +0100 Subject: [PATCH 07/11] added test for sorting and filtering --- .../dashboard/dashgrid/AddPanelPanel.jest.tsx | 100 +++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) diff --git a/public/app/features/dashboard/dashgrid/AddPanelPanel.jest.tsx b/public/app/features/dashboard/dashgrid/AddPanelPanel.jest.tsx index e68d84ad8bb..be7659ae030 100644 --- a/public/app/features/dashboard/dashgrid/AddPanelPanel.jest.tsx +++ b/public/app/features/dashboard/dashgrid/AddPanelPanel.jest.tsx @@ -1,4 +1,102 @@ import React from 'react'; import { AddPanelPanel } from './AddPanelPanel'; +import { PanelModel } from '../panel_model'; +import { shallow } from 'enzyme'; +import config from '../../../core/config'; -describe('AddPanelPanel', () => {}); +jest.mock('app/core/store', () => ({ + get: key => { + return null; + }, + delete: key => { + return null; + }, +})); + +describe('AddPanelPanel', () => { + let wrapper, dashboardMock, getPanelContainer, panel; + + beforeEach(() => { + config.panels = [ + { + id: 'singlestat', + hideFromList: false, + name: 'Singlestat', + sort: 2, + info: { + logos: { + small: '', + }, + }, + }, + { + id: 'hidden', + hideFromList: true, + name: 'Hidden', + sort: 100, + info: { + logos: { + small: '', + }, + }, + }, + { + id: 'graph', + hideFromList: false, + name: 'Graph', + sort: 1, + info: { + logos: { + small: '', + }, + }, + }, + { + id: 'alexander_zabbix', + hideFromList: false, + name: 'Zabbix', + sort: 100, + info: { + logos: { + small: '', + }, + }, + }, + { + id: 'piechart', + hideFromList: false, + name: 'Piechart', + sort: 100, + info: { + logos: { + small: '', + }, + }, + }, + ]; + + dashboardMock = { toggleRow: jest.fn() }; + + getPanelContainer = jest.fn().mockReturnValue({ + getDashboard: jest.fn().mockReturnValue(dashboardMock), + getPanelLoader: jest.fn(), + }); + + panel = new PanelModel({ collapsed: false }); + wrapper = shallow(); + }); + + it('should fetch all panels sorted with core plugins first', () => { + //console.log(wrapper.debug()); + //console.log(wrapper.find('.add-panel__item').get(0).props.title); + expect(wrapper.find('.add-panel__item').get(1).props.title).toBe('Singlestat'); + expect(wrapper.find('.add-panel__item').get(4).props.title).toBe('Piechart'); + }); + + it('should filter', () => { + wrapper.find('input').simulate('change', { target: { value: 'p' } }); + + expect(wrapper.find('.add-panel__item').get(1).props.title).toBe('Piechart'); + expect(wrapper.find('.add-panel__item').get(0).props.title).toBe('Graph'); + }); +}); From 0120023abafb9320c8306de88de2ec88c26aa889 Mon Sep 17 00:00:00 2001 From: Patrick O'Carroll Date: Tue, 17 Apr 2018 13:10:08 +0200 Subject: [PATCH 08/11] added forceupdate to grid item so addpanel items rezie instantly, renamed function to copyPanel, fixed panel items height issue --- public/app/features/dashboard/dashgrid/DashboardGrid.tsx | 2 ++ public/app/features/panel/panel_ctrl.ts | 6 +++--- public/sass/components/_panel_add_panel.scss | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/public/app/features/dashboard/dashgrid/DashboardGrid.tsx b/public/app/features/dashboard/dashgrid/DashboardGrid.tsx index 03bf65afc6e..056d5e36cb3 100644 --- a/public/app/features/dashboard/dashgrid/DashboardGrid.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardGrid.tsx @@ -152,11 +152,13 @@ export class DashboardGrid extends React.Component { onResize(layout, oldItem, newItem) { this.panelMap[newItem.i].updateGridPos(newItem); + this.triggerForceUpdate(); } onResizeStop(layout, oldItem, newItem) { this.updateGridPos(newItem, layout); this.panelMap[newItem.i].resizeDone(); + this.triggerForceUpdate(); } onDragStop(layout, oldItem, newItem) { diff --git a/public/app/features/panel/panel_ctrl.ts b/public/app/features/panel/panel_ctrl.ts index 27e4041a2d1..5718be181a4 100644 --- a/public/app/features/panel/panel_ctrl.ts +++ b/public/app/features/panel/panel_ctrl.ts @@ -195,7 +195,7 @@ export class PanelCtrl { menu.push({ text: 'Copy', - click: 'ctrl.addToPanelList()', + click: 'ctrl.copyPanel()', role: 'Editor', }); } @@ -260,9 +260,9 @@ export class PanelCtrl { }); } - addToPanelList() { + copyPanel() { store.set(LS_PANEL_COPY_KEY, JSON.stringify(this.panel.getSaveModel())); - appEvents.emit('alert-success', ['Panel temporarily added to panel list']); + appEvents.emit('alert-success', ['Panel copied. Open new panel to paste']); } replacePanel(newPanel, oldPanel) { diff --git a/public/sass/components/_panel_add_panel.scss b/public/sass/components/_panel_add_panel.scss index 2f5f80a6a5d..5bfff31a108 100644 --- a/public/sass/components/_panel_add_panel.scss +++ b/public/sass/components/_panel_add_panel.scss @@ -50,7 +50,7 @@ flex-direction: row; flex-wrap: wrap; overflow: auto; - height: calc(100% - 50px); + height: 100%; align-content: flex-start; justify-content: space-around; position: relative; From 23f644c2f5baf5f446c375779caacd6c4d851b93 Mon Sep 17 00:00:00 2001 From: Patrick O'Carroll Date: Wed, 18 Apr 2018 10:34:43 +0200 Subject: [PATCH 09/11] changed copied message and added forced render for width change --- public/app/features/dashboard/dashgrid/DashboardGrid.tsx | 1 + public/app/features/panel/panel_ctrl.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/public/app/features/dashboard/dashgrid/DashboardGrid.tsx b/public/app/features/dashboard/dashgrid/DashboardGrid.tsx index 056d5e36cb3..021a520755e 100644 --- a/public/app/features/dashboard/dashgrid/DashboardGrid.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardGrid.tsx @@ -140,6 +140,7 @@ export class DashboardGrid extends React.Component { for (const panel of this.dashboard.panels) { panel.resizeDone(); } + this.triggerForceUpdate(); } updateGridPos(item, layout) { diff --git a/public/app/features/panel/panel_ctrl.ts b/public/app/features/panel/panel_ctrl.ts index 5718be181a4..da8adc4f908 100644 --- a/public/app/features/panel/panel_ctrl.ts +++ b/public/app/features/panel/panel_ctrl.ts @@ -262,7 +262,7 @@ export class PanelCtrl { copyPanel() { store.set(LS_PANEL_COPY_KEY, JSON.stringify(this.panel.getSaveModel())); - appEvents.emit('alert-success', ['Panel copied. Open new panel to paste']); + appEvents.emit('alert-success', ['Panel copied. Open Add Panel to paste']); } replacePanel(newPanel, oldPanel) { From ce97f89de61073239349faf8d9a66758c6b48cc8 Mon Sep 17 00:00:00 2001 From: Marcus Efraimsson Date: Wed, 18 Apr 2018 13:59:26 +0200 Subject: [PATCH 10/11] make add panel panel scrollbar adjust when panel/dashboard grid are resized --- .../core/components/ScrollBar/ScrollBar.tsx | 4 ++++ .../dashboard/dashgrid/AddPanelPanel.tsx | 19 ++++++++++++++++++- .../dashboard/dashgrid/DashboardGrid.tsx | 3 --- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/public/app/core/components/ScrollBar/ScrollBar.tsx b/public/app/core/components/ScrollBar/ScrollBar.tsx index a358dc1926a..24d17f67367 100644 --- a/public/app/core/components/ScrollBar/ScrollBar.tsx +++ b/public/app/core/components/ScrollBar/ScrollBar.tsx @@ -54,6 +54,10 @@ export default class ScrollBar extends React.Component { return false; } + update() { + this.scrollbar.update(); + } + handleRef = ref => { this.container = ref; }; diff --git a/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx b/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx index 1e9ae20dca2..094bc49b708 100644 --- a/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx +++ b/public/app/features/dashboard/dashgrid/AddPanelPanel.tsx @@ -22,10 +22,13 @@ export interface AddPanelPanelState { } export class AddPanelPanel extends React.Component { + private scrollbar: ScrollBar; + constructor(props) { super(props); this.handleCloseAddPanel = this.handleCloseAddPanel.bind(this); this.renderPanelItem = this.renderPanelItem.bind(this); + this.panelSizeChanged = this.panelSizeChanged.bind(this); this.state = { panelPlugins: this.getPanelPlugins(''), @@ -35,6 +38,20 @@ export class AddPanelPanel extends React.Component { + this.scrollbar.update(); + }); + } + getPanelPlugins(filter) { let panels = _.chain(config.panels) .filter({ hideFromList: false }) @@ -207,7 +224,7 @@ export class AddPanelPanel extends React.Component - + (this.scrollbar = element)} className="add-panel__items">