DashNav.tsx 7.5 KB

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