PanelEditor.tsx 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import React, { PureComponent } from 'react';
  2. import classNames from 'classnames';
  3. import { QueriesTab } from './QueriesTab';
  4. import VisualizationTab from './VisualizationTab';
  5. import { GeneralTab } from './GeneralTab';
  6. import { AlertTab } from '../../alerting/AlertTab';
  7. import config from 'app/core/config';
  8. import { store } from 'app/store/store';
  9. import { updateLocation } from 'app/core/actions';
  10. import { AngularComponent } from 'app/core/services/AngularLoader';
  11. import { PanelModel } from '../state/PanelModel';
  12. import { DashboardModel } from '../state/DashboardModel';
  13. import { Tooltip, PanelPlugin, PanelPluginMeta } from '@grafana/ui';
  14. interface PanelEditorProps {
  15. panel: PanelModel;
  16. dashboard: DashboardModel;
  17. plugin: PanelPlugin;
  18. angularPanel?: AngularComponent;
  19. onTypeChanged: (newType: PanelPluginMeta) => void;
  20. }
  21. interface PanelEditorTab {
  22. id: string;
  23. text: string;
  24. }
  25. enum PanelEditorTabIds {
  26. Queries = 'queries',
  27. Visualization = 'visualization',
  28. Advanced = 'advanced',
  29. Alert = 'alert',
  30. }
  31. interface PanelEditorTab {
  32. id: string;
  33. text: string;
  34. }
  35. const panelEditorTabTexts = {
  36. [PanelEditorTabIds.Queries]: 'Queries',
  37. [PanelEditorTabIds.Visualization]: 'Visualization',
  38. [PanelEditorTabIds.Advanced]: 'General',
  39. [PanelEditorTabIds.Alert]: 'Alert',
  40. };
  41. const getPanelEditorTab = (tabId: PanelEditorTabIds): PanelEditorTab => {
  42. return {
  43. id: tabId,
  44. text: panelEditorTabTexts[tabId],
  45. };
  46. };
  47. export class PanelEditor extends PureComponent<PanelEditorProps> {
  48. constructor(props: PanelEditorProps) {
  49. super(props);
  50. }
  51. onChangeTab = (tab: PanelEditorTab) => {
  52. store.dispatch(
  53. updateLocation({
  54. query: { tab: tab.id, openVizPicker: null },
  55. partial: true,
  56. })
  57. );
  58. this.forceUpdate();
  59. };
  60. renderCurrentTab(activeTab: string) {
  61. const { panel, dashboard, onTypeChanged, plugin, angularPanel } = this.props;
  62. switch (activeTab) {
  63. case 'advanced':
  64. return <GeneralTab panel={panel} />;
  65. case 'queries':
  66. return <QueriesTab panel={panel} dashboard={dashboard} />;
  67. case 'alert':
  68. return <AlertTab angularPanel={angularPanel} dashboard={dashboard} panel={panel} />;
  69. case 'visualization':
  70. return (
  71. <VisualizationTab
  72. panel={panel}
  73. dashboard={dashboard}
  74. plugin={plugin}
  75. onTypeChanged={onTypeChanged}
  76. angularPanel={angularPanel}
  77. />
  78. );
  79. default:
  80. return null;
  81. }
  82. }
  83. render() {
  84. const { plugin } = this.props;
  85. let activeTab: PanelEditorTabIds = store.getState().location.query.tab || PanelEditorTabIds.Queries;
  86. const tabs: PanelEditorTab[] = [
  87. getPanelEditorTab(PanelEditorTabIds.Queries),
  88. getPanelEditorTab(PanelEditorTabIds.Visualization),
  89. getPanelEditorTab(PanelEditorTabIds.Advanced),
  90. ];
  91. // handle panels that do not have queries tab
  92. if (plugin.meta.skipDataQuery) {
  93. // remove queries tab
  94. tabs.shift();
  95. // switch tab
  96. if (activeTab === PanelEditorTabIds.Queries) {
  97. activeTab = PanelEditorTabIds.Visualization;
  98. }
  99. }
  100. if (config.alertingEnabled && plugin.meta.id === 'graph') {
  101. tabs.push(getPanelEditorTab(PanelEditorTabIds.Alert));
  102. }
  103. return (
  104. <div className="panel-editor-container__editor">
  105. <div className="panel-editor-tabs">
  106. {tabs.map(tab => {
  107. return <TabItem tab={tab} activeTab={activeTab} onClick={this.onChangeTab} key={tab.id} />;
  108. })}
  109. </div>
  110. <div className="panel-editor__right">{this.renderCurrentTab(activeTab)}</div>
  111. </div>
  112. );
  113. }
  114. }
  115. interface TabItemParams {
  116. tab: PanelEditorTab;
  117. activeTab: string;
  118. onClick: (tab: PanelEditorTab) => void;
  119. }
  120. function TabItem({ tab, activeTab, onClick }: TabItemParams) {
  121. const tabClasses = classNames({
  122. 'panel-editor-tabs__link': true,
  123. active: activeTab === tab.id,
  124. });
  125. return (
  126. <div className="panel-editor-tabs__item" onClick={() => onClick(tab)}>
  127. <a className={tabClasses} aria-label={`${tab.text} tab button`}>
  128. <Tooltip content={`${tab.text}`} placement="auto">
  129. <i className={`gicon gicon-${tab.id}${activeTab === tab.id ? '-active' : ''}`} />
  130. </Tooltip>
  131. </a>
  132. </div>
  133. );
  134. }