DashNav.tsx 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. // Libaries
  2. import React, { PureComponent } from 'react';
  3. import { connect } from 'react-redux';
  4. // Utils & Services
  5. import { AngularComponent, getAngularLoader } from 'app/core/services/AngularLoader';
  6. import { appEvents } from 'app/core/app_events';
  7. // Components
  8. import { DashNavButton } from './DashNavButton';
  9. // State
  10. import { updateLocation } from 'app/core/actions';
  11. // Types
  12. import { DashboardModel } from '../../state/DashboardModel';
  13. export interface Props {
  14. dashboard: DashboardModel;
  15. editview: string;
  16. isEditing: boolean;
  17. isFullscreen: boolean;
  18. $injector: any;
  19. updateLocation: typeof updateLocation;
  20. }
  21. export class DashNav extends PureComponent<Props> {
  22. timePickerEl: HTMLElement;
  23. timepickerCmp: AngularComponent;
  24. componentDidMount() {
  25. const loader = getAngularLoader();
  26. const template = '<gf-time-picker class="gf-timepicker-nav" dashboard="dashboard" ng-if="!dashboard.timepicker.hidden" />';
  27. const scopeProps = { dashboard: this.props.dashboard };
  28. this.timepickerCmp = loader.load(this.timePickerEl, scopeProps, template);
  29. }
  30. componentWillUnmount() {
  31. if (this.timepickerCmp) {
  32. this.timepickerCmp.destroy();
  33. }
  34. }
  35. onOpenSearch = () => {
  36. appEvents.emit('show-dash-search');
  37. };
  38. onAddPanel = () => {
  39. const { dashboard } = this.props;
  40. // Return if the "Add panel" exists already
  41. if (dashboard.panels.length > 0 && dashboard.panels[0].type === 'add-panel') {
  42. return;
  43. }
  44. dashboard.addPanel({
  45. type: 'add-panel',
  46. gridPos: { x: 0, y: 0, w: 12, h: 8 },
  47. title: 'Panel Title',
  48. });
  49. };
  50. onClose = () => {
  51. if (this.props.editview) {
  52. this.props.updateLocation({
  53. query: { editview: null },
  54. partial: true,
  55. });
  56. } else {
  57. this.props.updateLocation({
  58. query: { panelId: null, edit: null, fullscreen: null },
  59. partial: true,
  60. });
  61. }
  62. };
  63. onToggleTVMode = () => {
  64. appEvents.emit('toggle-kiosk-mode');
  65. };
  66. onSave = () => {
  67. const { $injector } = this.props;
  68. const dashboardSrv = $injector.get('dashboardSrv');
  69. dashboardSrv.saveDashboard();
  70. };
  71. onOpenSettings = () => {
  72. this.props.updateLocation({
  73. query: { editview: 'settings' },
  74. partial: true,
  75. });
  76. };
  77. onStarDashboard = () => {
  78. const { $injector, dashboard } = this.props;
  79. const dashboardSrv = $injector.get('dashboardSrv');
  80. dashboardSrv.starDashboard(dashboard.id, dashboard.meta.isStarred).then(newState => {
  81. dashboard.meta.isStarred = newState;
  82. this.forceUpdate();
  83. });
  84. };
  85. onOpenShare = () => {
  86. const $rootScope = this.props.$injector.get('$rootScope');
  87. const modalScope = $rootScope.$new();
  88. modalScope.tabIndex = 0;
  89. modalScope.dashboard = this.props.dashboard;
  90. appEvents.emit('show-modal', {
  91. src: 'public/app/features/dashboard/components/ShareModal/template.html',
  92. scope: modalScope,
  93. });
  94. };
  95. render() {
  96. const { dashboard, isFullscreen, editview } = this.props;
  97. const { canStar, canSave, canShare, folderTitle, showSettings, isStarred } = dashboard.meta;
  98. const { snapshot } = dashboard;
  99. const haveFolder = dashboard.meta.folderId > 0;
  100. const snapshotUrl = snapshot && snapshot.originalUrl;
  101. return (
  102. <div className="navbar">
  103. <div>
  104. <a className="navbar-page-btn" onClick={this.onOpenSearch}>
  105. <i className="gicon gicon-dashboard" />
  106. {haveFolder && <span className="navbar-page-btn--folder">{folderTitle} / </span>}
  107. {dashboard.title}
  108. <i className="fa fa-caret-down" />
  109. </a>
  110. </div>
  111. <div className="navbar__spacer" />
  112. {/*
  113. <div class="navbar-buttons navbar-buttons--playlist" ng-if="ctrl.playlistSrv.isPlaying">
  114. <a class="navbar-button navbar-button--tight" ng-click="ctrl.playlistSrv.prev()"><i class="fa fa-step-backward"></i></a>
  115. <a class="navbar-button navbar-button--tight" ng-click="ctrl.playlistSrv.stop()"><i class="fa fa-stop"></i></a>
  116. <a class="navbar-button navbar-button--tight" ng-click="ctrl.playlistSrv.next()"><i class="fa fa-step-forward"></i></a>
  117. </div>
  118. */}
  119. <div className="navbar-buttons navbar-buttons--actions">
  120. {canSave && (
  121. <DashNavButton
  122. tooltip="Add panel"
  123. classSuffix="add-panel"
  124. icon="gicon gicon-add-panel"
  125. onClick={this.onAddPanel}
  126. />
  127. )}
  128. {canStar && (
  129. <DashNavButton
  130. tooltip="Mark as favorite"
  131. classSuffix="star"
  132. icon={`${isStarred ? 'fa fa-star' : 'fa fa-star-o'}`}
  133. onClick={this.onStarDashboard}
  134. />
  135. )}
  136. {canShare && (
  137. <DashNavButton
  138. tooltip="Share dashboard"
  139. classSuffix="share"
  140. icon="fa fa-share-square-o"
  141. onClick={this.onOpenShare}
  142. />
  143. )}
  144. {canSave && (
  145. <DashNavButton tooltip="Save dashboard" classSuffix="save" icon="fa fa-save" onClick={this.onSave} />
  146. )}
  147. {snapshotUrl && (
  148. <DashNavButton
  149. tooltip="Open original dashboard"
  150. classSuffix="snapshot-origin"
  151. icon="fa fa-link"
  152. href={snapshotUrl}
  153. />
  154. )}
  155. {showSettings && (
  156. <DashNavButton
  157. tooltip="Dashboard settings"
  158. classSuffix="settings"
  159. icon="fa fa-cog"
  160. onClick={this.onOpenSettings}
  161. />
  162. )}
  163. </div>
  164. <div className="navbar-buttons navbar-buttons--tv">
  165. <DashNavButton
  166. tooltip="Cycke view mode"
  167. classSuffix="tv"
  168. icon="fa fa-desktop"
  169. onClick={this.onToggleTVMode}
  170. />
  171. </div>
  172. <div className="gf-timepicker-nav" ref={element => (this.timePickerEl = element)} />
  173. {(isFullscreen || editview) && (
  174. <div className="navbar-buttons navbar-buttons--close">
  175. <DashNavButton
  176. tooltip="Back to dashboard"
  177. classSuffix="primary"
  178. icon="fa fa-reply"
  179. onClick={this.onClose}
  180. />
  181. </div>
  182. )}
  183. </div>
  184. );
  185. }
  186. }
  187. const mapStateToProps = () => ({});
  188. const mapDispatchToProps = {
  189. updateLocation,
  190. };
  191. export default connect(mapStateToProps, mapDispatchToProps)(DashNav);