Просмотр исходного кода

Merge remote-tracking branch 'origin/develop-addpanelpanel' into add-panel-rewrite

Torkel Ödegaard 7 лет назад
Родитель
Сommit
9d8d5b18ef

+ 97 - 124
public/app/features/dashboard/dashgrid/AddPanelPanel.tsx

@@ -1,6 +1,5 @@
 import React from 'react';
 import _ from 'lodash';
-import classNames from 'classnames';
 import config from 'app/core/config';
 import { PanelModel } from '../panel_model';
 import { DashboardModel } from '../dashboard_model';
@@ -8,6 +7,8 @@ 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';
+import { updateLocation } from 'app/core/actions';
+import { store as reduxStore } from 'app/store/store';
 
 export interface AddPanelPanelProps {
   panel: PanelModel;
@@ -27,12 +28,11 @@ export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelP
   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(''),
-      copiedPanelPlugins: this.getCopiedPanelPlugins(''),
+      panelPlugins: this.getPanelPlugins(),
+      copiedPanelPlugins: this.getCopiedPanelPlugins(),
       filter: '',
       tab: 'Add',
     };
@@ -52,27 +52,31 @@ export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelP
     });
   }
 
-  getPanelPlugins(filter) {
-    let panels = _.chain(config.panels)
+  getPanelPlugins() {
+    const panelsList = _.chain(config.panels)
       .filter({ hideFromList: false })
       .map(item => item)
       .value();
 
+    const panels = [];
+
+    for (let i = 0; i < panelsList.length; i++) {
+      if (panelsList[i].id === 'graph') {
+        panels.push(panelsList[i]);
+      }
+    }
     // add special row type
     panels.push({ id: 'row', name: 'Row', sort: 8, info: { logos: { small: 'public/img/icn-row.svg' } } });
-
-    panels = this.filterPanels(panels, filter);
-
     // add sort by sort property
-    return _.sortBy(panels, 'sort');
+    return panels;
   }
 
-  getCopiedPanelPlugins(filter) {
+  getCopiedPanelPlugins() {
     const panels = _.chain(config.panels)
       .filter({ hideFromList: false })
       .map(item => item)
       .value();
-    let copiedPanels = [];
+    const copiedPanels = [];
 
     const copiedPanelJson = store.get(LS_PANEL_COPY_KEY);
     if (copiedPanelJson) {
@@ -86,13 +90,45 @@ export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelP
         copiedPanels.push(pluginCopy);
       }
     }
+    return _.sortBy(copiedPanels, 'sort');
+  }
+
+  handleCloseAddPanel(evt) {
+    evt.preventDefault();
+    this.props.dashboard.removePanel(this.props.dashboard.panels[0]);
+  }
 
-    copiedPanels = this.filterPanels(copiedPanels, filter);
+  renderText(text: string) {
+    const searchWords = this.state.filter.split('');
+    return <Highlighter highlightClassName="highlight-search-match" textToHighlight={text} searchWords={searchWords} />;
+  }
 
-    return _.sortBy(copiedPanels, 'sort');
+  noCopiedPanelPlugins() {
+    return <div className="add-panel__no-panels">No copied panels yet.</div>;
+  }
+
+  copyButton(panel) {
+    return (
+      <button className="btn-inverse btn" onClick={() => this.onPasteCopiedPanel(panel)} title={panel.name}>
+        Paste copied Panel
+      </button>
+    );
+  }
+
+  moveToEdit(panel) {
+    reduxStore.dispatch(
+      updateLocation({
+        query: {
+          panelId: panel.id,
+          edit: true,
+          fullscreen: true,
+        },
+        partial: true,
+      })
+    );
   }
 
-  onAddPanel = panelPluginInfo => {
+  onCreateNewPanel = panelPluginInfo => {
     const dashboard = this.props.dashboard;
     const { gridPos } = this.props.panel;
 
@@ -102,11 +138,6 @@ export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelP
       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 };
-    }
-
     // apply panel template / defaults
     if (panelPluginInfo.defaults) {
       _.defaults(newPanel, panelPluginInfo.defaults);
@@ -117,95 +148,56 @@ export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelP
     }
 
     dashboard.addPanel(newPanel);
+    this.moveToEdit(newPanel);
+
     dashboard.removePanel(this.props.panel);
   };
 
-  handleCloseAddPanel(evt) {
-    evt.preventDefault();
-    this.props.dashboard.removePanel(this.props.dashboard.panels[0]);
-  }
-
-  renderText(text: string) {
-    const searchWords = this.state.filter.split('');
-    return <Highlighter highlightClassName="highlight-search-match" textToHighlight={text} searchWords={searchWords} />;
-  }
+  onPasteCopiedPanel = panelPluginInfo => {
+    const dashboard = this.props.dashboard;
+    const { gridPos } = this.props.panel;
 
-  renderPanelItem(panel, index) {
-    return (
-      <div key={index} className="add-panel__item" onClick={() => this.onAddPanel(panel)} title={panel.name}>
-        <img className="add-panel__item-img" src={panel.info.logos.small} />
-        <div className="add-panel__item-name">{this.renderText(panel.name)}</div>
-      </div>
-    );
-  }
+    const newPanel: any = {
+      type: panelPluginInfo.id,
+      title: 'Panel Title',
+      gridPos: { x: gridPos.x, y: gridPos.y, w: gridPos.w, h: gridPos.h },
+    };
 
-  noCopiedPanelPlugins() {
-    return <div className="add-panel__no-panels">No copied panels yet.</div>;
-  }
+    // apply panel template / defaults
+    if (panelPluginInfo.defaults) {
+      _.defaults(newPanel, panelPluginInfo.defaults);
+      newPanel.gridPos.w = panelPluginInfo.defaults.gridPos.w;
+      newPanel.gridPos.h = panelPluginInfo.defaults.gridPos.h;
+      newPanel.title = panelPluginInfo.defaults.title;
+      store.delete(LS_PANEL_COPY_KEY);
+    }
 
-  filterChange(evt) {
-    this.setState({
-      filter: evt.target.value,
-      panelPlugins: this.getPanelPlugins(evt.target.value),
-      copiedPanelPlugins: this.getCopiedPanelPlugins(evt.target.value),
-    });
-  }
+    dashboard.addPanel(newPanel);
 
-  filterKeyPress(evt) {
-    if (evt.key === 'Enter') {
-      const panel = _.head(this.state.panelPlugins);
-      if (panel) {
-        this.onAddPanel(panel);
-      }
-    }
-  }
+    dashboard.removePanel(this.props.panel);
+  };
 
-  filterPanels(panels, filter) {
-    const regex = new RegExp(filter, 'i');
-    return panels.filter(panel => {
-      return regex.test(panel.name);
-    });
-  }
+  onCreateNewRow = panelPluginInfo => {
+    const dashboard = this.props.dashboard;
 
-  openCopy() {
-    this.setState({
-      tab: 'Copy',
-      filter: '',
-      panelPlugins: this.getPanelPlugins(''),
-      copiedPanelPlugins: this.getCopiedPanelPlugins(''),
-    });
-  }
+    const newRow: any = {
+      type: panelPluginInfo.id,
+      title: 'Row title',
+      gridPos: { x: 0, y: 0 },
+    };
 
-  openAdd() {
-    this.setState({
-      tab: 'Add',
-      filter: '',
-      panelPlugins: this.getPanelPlugins(''),
-      copiedPanelPlugins: this.getCopiedPanelPlugins(''),
-    });
-  }
+    dashboard.addPanel(newRow);
+    dashboard.removePanel(this.props.panel);
+  };
 
   render() {
-    const addClass = classNames({
-      'active active--panel': this.state.tab === 'Add',
-      '': this.state.tab === 'Copy',
-    });
-
-    const copyClass = classNames({
-      '': this.state.tab === 'Add',
-      'active active--panel': this.state.tab === 'Copy',
-    });
+    const panel = this.state.panelPlugins[0];
+    const row = this.state.panelPlugins[1];
 
-    let panelTab;
+    let addCopyButton;
 
-    if (this.state.tab === 'Add') {
-      panelTab = this.state.panelPlugins.map(this.renderPanelItem);
-    } else if (this.state.tab === 'Copy') {
-      if (this.state.copiedPanelPlugins.length > 0) {
-        panelTab = this.state.copiedPanelPlugins.map(this.renderPanelItem);
-      } else {
-        panelTab = this.noCopiedPanelPlugins();
-      }
+    if (this.state.copiedPanelPlugins.length === 1) {
+      addCopyButton = this.copyButton(this.state.copiedPanelPlugins[0]);
     }
 
     return (
@@ -213,40 +205,21 @@ export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelP
         <div className="add-panel">
           <div className="add-panel__header">
             <i className="gicon gicon-add-panel" />
-            <span className="add-panel__title">New Panel</span>
-            <ul className="gf-tabs">
-              <li className="gf-tabs-item">
-                <div className={'gf-tabs-link pointer ' + addClass} onClick={this.openAdd.bind(this)}>
-                  Add
-                </div>
-              </li>
-              <li className="gf-tabs-item">
-                <div className={'gf-tabs-link pointer ' + copyClass} onClick={this.openCopy.bind(this)}>
-                  Paste
-                </div>
-              </li>
-            </ul>
             <button className="add-panel__close" onClick={this.handleCloseAddPanel}>
               <i className="fa fa-close" />
             </button>
           </div>
-          <ScrollBar ref={element => (this.scrollbar = element)} className="add-panel__items">
-            <div className="add-panel__searchbar">
-              <label className="gf-form gf-form--grow gf-form--has-input-icon">
-                <input
-                  type="text"
-                  autoFocus
-                  className="gf-form-input gf-form--grow"
-                  placeholder="Panel Search Filter"
-                  value={this.state.filter}
-                  onChange={this.filterChange.bind(this)}
-                  onKeyPress={this.filterKeyPress.bind(this)}
-                />
-                <i className="gf-form-input-icon fa fa-search" />
-              </label>
+          <div className="add-panel-btn-container">
+            <div className="gf-form-button-row">
+              <button className="btn-success btn" onClick={() => this.onCreateNewPanel(panel)} title={panel.name}>
+                Create new Panel
+              </button>
+              {addCopyButton}
+              <button className="btn-inverse btn" onClick={() => this.onCreateNewRow(row)} title={row.name}>
+                Add new Row
+              </button>
             </div>
-            {panelTab}
-          </ScrollBar>
+          </div>
         </div>
       </div>
     );

+ 0 - 5
public/app/features/dashboard/specs/AddPanelPanel.test.tsx

@@ -32,11 +32,6 @@ describe('AddPanelPanel', () => {
     wrapper = shallow(<AddPanelPanel panel={panel} dashboard={dashboardMock} />);
   });
 
-  it('should fetch all panels sorted with core plugins first', () => {
-    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' } });
 

+ 12 - 20
public/sass/components/_panel_add_panel.scss

@@ -4,20 +4,17 @@
 
 .add-panel {
   height: 100%;
-
-  .baron__root {
-    height: calc(100% - 43px);
-  }
+  //display: flex;
+  //flex-direction: column;
 }
 
 .add-panel__header {
+  top: 0;
+  position: absolute;
   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;
-
+  width: 100%;
   .gicon {
     font-size: 30px;
     margin-right: $spacer;
@@ -32,18 +29,6 @@
   margin-right: -10px;
 }
 
-.add-panel__title {
-  font-size: $font-size-md;
-  margin-right: $spacer*2;
-}
-
-.add-panel__sub-title {
-  font-style: italic;
-  color: $text-muted;
-  position: relative;
-  top: 1px;
-}
-
 .add-panel__items {
   padding: 3px 8px;
   display: flex;
@@ -97,3 +82,10 @@
   width: 100%;
   padding: 3px 8px;
 }
+
+.add-panel-btn-container {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 100%;
+}