AddPanelPanel.tsx 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. import React from 'react';
  2. import _ from 'lodash';
  3. import config from 'app/core/config';
  4. import { PanelModel } from '../panel_model';
  5. import { PanelContainer } from './PanelContainer';
  6. import ScrollBar from 'app/core/components/ScrollBar/ScrollBar';
  7. import store from 'app/core/store';
  8. import { LS_PANEL_COPY_KEY } from 'app/core/constants';
  9. export interface AddPanelPanelProps {
  10. panel: PanelModel;
  11. getPanelContainer: () => PanelContainer;
  12. }
  13. export interface AddPanelPanelState {
  14. filter: string;
  15. panelPlugins: any[];
  16. copiedPanelPlugins: any[];
  17. tab: string;
  18. }
  19. export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelPanelState> {
  20. constructor(props) {
  21. super(props);
  22. this.handleCloseAddPanel = this.handleCloseAddPanel.bind(this);
  23. this.renderPanelItem = this.renderPanelItem.bind(this);
  24. this.state = {
  25. panelPlugins: this.getPanelPlugins(''),
  26. copiedPanelPlugins: this.getCopiedPanelPlugins(''),
  27. filter: '',
  28. tab: 'Add',
  29. };
  30. }
  31. getPanelPlugins(filter) {
  32. let panels = _.chain(config.panels)
  33. .filter({ hideFromList: false })
  34. .map(item => item)
  35. .value();
  36. // add special row type
  37. panels.push({ id: 'row', name: 'Row', sort: 8, info: { logos: { small: 'public/img/icn-row.svg' } } });
  38. panels = this.filterPanels(panels, filter);
  39. // add sort by sort property
  40. return _.sortBy(panels, 'sort');
  41. }
  42. getCopiedPanelPlugins(filter) {
  43. let panels = _.chain(config.panels)
  44. .filter({ hideFromList: false })
  45. .map(item => item)
  46. .value();
  47. let copiedPanels = [];
  48. let copiedPanelJson = store.get(LS_PANEL_COPY_KEY);
  49. if (copiedPanelJson) {
  50. let copiedPanel = JSON.parse(copiedPanelJson);
  51. let pluginInfo = _.find(panels, { id: copiedPanel.type });
  52. if (pluginInfo) {
  53. let pluginCopy = _.cloneDeep(pluginInfo);
  54. pluginCopy.name = copiedPanel.title;
  55. pluginCopy.sort = -1;
  56. pluginCopy.defaults = copiedPanel;
  57. copiedPanels.push(pluginCopy);
  58. }
  59. }
  60. copiedPanels = this.filterPanels(copiedPanels, filter);
  61. return _.sortBy(copiedPanels, 'sort');
  62. }
  63. onAddPanel = panelPluginInfo => {
  64. const panelContainer = this.props.getPanelContainer();
  65. const dashboard = panelContainer.getDashboard();
  66. const { gridPos } = this.props.panel;
  67. var newPanel: any = {
  68. type: panelPluginInfo.id,
  69. title: 'Panel Title',
  70. gridPos: { x: gridPos.x, y: gridPos.y, w: gridPos.w, h: gridPos.h },
  71. };
  72. if (panelPluginInfo.id === 'row') {
  73. newPanel.title = 'Row title';
  74. newPanel.gridPos = { x: 0, y: 0 };
  75. }
  76. // apply panel template / defaults
  77. if (panelPluginInfo.defaults) {
  78. _.defaults(newPanel, panelPluginInfo.defaults);
  79. newPanel.gridPos.w = panelPluginInfo.defaults.gridPos.w;
  80. newPanel.gridPos.h = panelPluginInfo.defaults.gridPos.h;
  81. newPanel.title = panelPluginInfo.defaults.title;
  82. store.delete(LS_PANEL_COPY_KEY);
  83. }
  84. dashboard.addPanel(newPanel);
  85. dashboard.removePanel(this.props.panel);
  86. };
  87. handleCloseAddPanel(evt) {
  88. evt.preventDefault();
  89. const panelContainer = this.props.getPanelContainer();
  90. const dashboard = panelContainer.getDashboard();
  91. dashboard.removePanel(dashboard.panels[0]);
  92. }
  93. renderPanelItem(panel, index) {
  94. return (
  95. <div key={index} className="add-panel__item" onClick={() => this.onAddPanel(panel)} title={panel.name}>
  96. <img className="add-panel__item-img" src={panel.info.logos.small} />
  97. <div className="add-panel__item-name">{panel.name}</div>
  98. </div>
  99. );
  100. }
  101. filterChange(evt) {
  102. this.setState({ filter: evt.target.value });
  103. this.setState({ panelPlugins: this.getPanelPlugins(evt.target.value) });
  104. this.setState({ copiedPanelPlugins: this.getCopiedPanelPlugins(evt.target.value) });
  105. }
  106. filterPanels(panels, filter) {
  107. let regex = new RegExp(filter, 'i');
  108. return panels.filter(panel => {
  109. return regex.test(panel.name);
  110. });
  111. }
  112. openCopy() {
  113. this.setState({ tab: 'Copy' });
  114. this.setState({ filter: '' });
  115. this.setState({ panelPlugins: this.getPanelPlugins('') });
  116. this.setState({ copiedPanelPlugins: this.getCopiedPanelPlugins('') });
  117. }
  118. openAdd() {
  119. this.setState({ tab: 'Add' });
  120. this.setState({ filter: '' });
  121. this.setState({ panelPlugins: this.getPanelPlugins('') });
  122. this.setState({ copiedPanelPlugins: this.getCopiedPanelPlugins('') });
  123. }
  124. render() {
  125. let addClass;
  126. let copyClass;
  127. let panelTab;
  128. if (this.state.tab === 'Add') {
  129. addClass = 'active active--panel';
  130. copyClass = '';
  131. panelTab = this.state.panelPlugins.map(this.renderPanelItem);
  132. } else if (this.state.tab === 'Copy') {
  133. addClass = '';
  134. copyClass = 'active active--panel';
  135. panelTab = this.state.copiedPanelPlugins.map(this.renderPanelItem);
  136. }
  137. return (
  138. <div className="panel-container">
  139. <div className="add-panel">
  140. <div className="add-panel__header">
  141. <i className="gicon gicon-add-panel" />
  142. <span className="add-panel__title">New Panel</span>
  143. <ul className="gf-tabs">
  144. <li className="gf-tabs-item">
  145. <div className={'gf-tabs-link pointer ' + addClass} onClick={this.openAdd.bind(this)}>
  146. Add
  147. </div>
  148. </li>
  149. <li className="gf-tabs-item">
  150. <div className={'gf-tabs-link pointer ' + copyClass} onClick={this.openCopy.bind(this)}>
  151. Copy
  152. </div>
  153. </li>
  154. </ul>
  155. <button className="add-panel__close" onClick={this.handleCloseAddPanel}>
  156. <i className="fa fa-close" />
  157. </button>
  158. </div>
  159. <ScrollBar className="add-panel__items">
  160. <div className="add-panel__searchbar">
  161. <label className="gf-form gf-form--grow gf-form--has-input-icon">
  162. <input
  163. type="text"
  164. className="gf-form-input max-width-20"
  165. placeholder="Panel Search Filter"
  166. value={this.state.filter}
  167. onChange={this.filterChange.bind(this)}
  168. />
  169. <i className="gf-form-input-icon fa fa-search" />
  170. </label>
  171. </div>
  172. {panelTab}
  173. </ScrollBar>
  174. </div>
  175. </div>
  176. );
  177. }
  178. }