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

added tabs and searchfilter to addpanel, fixes#10427

Patrick O'Carroll 7 лет назад
Родитель
Сommit
9ac82f3d0e

+ 91 - 7
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<AddPanelPanelProps, AddPanelPanelState> {
@@ -25,12 +27,14 @@ export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelP
     this.renderPanelItem = this.renderPanelItem.bind(this);
 
     this.state = {
-      panelPlugins: this.getPanelPlugins(),
+      panelPlugins: this.getPanelPlugins(''),
+      copiedPanelPlugins: this.getCopiedPanelPlugins(''),
       filter: '',
+      tab: 'Add',
     };
   }
 
-  getPanelPlugins() {
+  getPanelPlugins(filter) {
     let panels = _.chain(config.panels)
       .filter({ hideFromList: false })
       .map(item => item)
@@ -39,6 +43,19 @@ export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelP
     // 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');
+  }
+
+  getCopiedPanelPlugins(filter) {
+    let panels = _.chain(config.panels)
+      .filter({ hideFromList: false })
+      .map(item => 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<AddPanelPanelProps, AddPanelP
         pluginCopy.name = copiedPanel.title;
         pluginCopy.sort = -1;
         pluginCopy.defaults = copiedPanel;
-        panels.push(pluginCopy);
+        copiedPanels.push(pluginCopy);
       }
     }
 
-    // add sort by sort property
-    return _.sortBy(panels, 'sort');
+    copiedPanels = this.filterPanels(copiedPanels, filter);
+
+    return _.sortBy(copiedPanels, 'sort');
   }
 
   onAddPanel = panelPluginInfo => {
@@ -101,19 +119,85 @@ export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelP
     );
   }
 
+  filterChange(evt) {
+    this.setState({ filter: evt.target.value });
+    this.setState({ panelPlugins: this.getPanelPlugins(evt.target.value) });
+    this.setState({ copiedPanelPlugins: this.getCopiedPanelPlugins(evt.target.value) });
+  }
+
+  filterPanels(panels, filter) {
+    let regex = new RegExp(filter, 'i');
+    return panels.filter(panel => {
+      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 (
       <div className="panel-container">
         <div className="add-panel">
           <div className="add-panel__header">
             <i className="gicon gicon-add-panel" />
             <span className="add-panel__title">New Panel</span>
-            <span className="add-panel__sub-title">Select a visualization</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)}>
+                  Copy
+                </div>
+              </li>
+            </ul>
             <button className="add-panel__close" onClick={this.handleCloseAddPanel}>
               <i className="fa fa-close" />
             </button>
           </div>
-          <ScrollBar className="add-panel__items">{this.state.panelPlugins.map(this.renderPanelItem)}</ScrollBar>
+          <ScrollBar className="add-panel__items">
+            <div className="add-panel__searchbar">
+              <label className="gf-form gf-form--grow gf-form--has-input-icon">
+                <input
+                  type="text"
+                  className="gf-form-input max-width-20"
+                  placeholder="Panel Search Filter"
+                  value={this.state.filter}
+                  onChange={this.filterChange.bind(this)}
+                />
+                <i className="gf-form-input-icon fa fa-search" />
+              </label>
+            </div>
+            {panelTab}
+          </ScrollBar>
         </div>
       </div>
     );

+ 14 - 5
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;
+}

+ 5 - 7
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;
+  }
 }