Browse Source

Merge branch 'dashboard-react-page' of github.com:grafana/grafana into dashboard-react-page

Torkel Ödegaard 6 years ago
parent
commit
3d5ca99d53

+ 1 - 0
pkg/api/dtos/playlist.go

@@ -5,6 +5,7 @@ type PlaylistDashboard struct {
 	Slug  string `json:"slug"`
 	Title string `json:"title"`
 	Uri   string `json:"uri"`
+	Url   string `json:"url"`
 	Order int    `json:"order"`
 }
 

+ 1 - 0
pkg/api/playlist_play.go

@@ -26,6 +26,7 @@ func populateDashboardsByID(dashboardByIDs []int64, dashboardIDOrder map[int64]i
 				Slug:  item.Slug,
 				Title: item.Title,
 				Uri:   "db/" + item.Slug,
+				Url:   m.GetDashboardUrl(item.Uid, item.Slug),
 				Order: dashboardIDOrder[item.Id],
 			})
 		}

+ 28 - 9
public/app/features/dashboard/components/DashNav/DashNav.tsx

@@ -28,6 +28,13 @@ export interface Props {
 export class DashNav extends PureComponent<Props> {
   timePickerEl: HTMLElement;
   timepickerCmp: AngularComponent;
+  playlistSrv: PlaylistSrv;
+
+  constructor(props: Props) {
+    super(props);
+
+    this.playlistSrv = this.props.$injector.get('playlistSrv');
+  }
 
   componentDidMount() {
     const loader = getAngularLoader();
@@ -95,7 +102,7 @@ export class DashNav extends PureComponent<Props> {
   };
 
   onStarDashboard = () => {
-    const { $injector, dashboard } = this.props;
+    const { dashboard, $injector } = this.props;
     const dashboardSrv = $injector.get('dashboardSrv');
 
     dashboardSrv.starDashboard(dashboard.id, dashboard.meta.isStarred).then(newState => {
@@ -104,6 +111,19 @@ export class DashNav extends PureComponent<Props> {
     });
   };
 
+  onPlaylistPrev = () => {
+    this.playlistSrv.prev();
+  };
+
+  onPlaylistNext = () => {
+    this.playlistSrv.next();
+  };
+
+  onPlaylistStop = () => {
+    this.playlistSrv.stop();
+    this.forceUpdate();
+  };
+
   onOpenShare = () => {
     const $rootScope = this.props.$injector.get('$rootScope');
     const modalScope = $rootScope.$new();
@@ -117,13 +137,12 @@ export class DashNav extends PureComponent<Props> {
   };
 
   render() {
-    const { dashboard, isFullscreen, editview, $injector } = this.props;
+    const { dashboard, isFullscreen, editview } = this.props;
     const { canStar, canSave, canShare, folderTitle, showSettings, isStarred } = dashboard.meta;
     const { snapshot } = dashboard;
 
     const haveFolder = dashboard.meta.folderId > 0;
     const snapshotUrl = snapshot && snapshot.originalUrl;
-    const playlistSrv: PlaylistSrv = $injector.get('playlistSrv');
 
     return (
       <div className="navbar">
@@ -138,25 +157,25 @@ export class DashNav extends PureComponent<Props> {
 
         <div className="navbar__spacer" />
 
-        {playlistSrv.isPlaying && (
+        {this.playlistSrv.isPlaying && (
           <div className="navbar-buttons navbar-buttons--playlist">
             <DashNavButton
-              tooltip="Jump to previous dashboard"
+              tooltip="Go to previous dashboard"
               classSuffix="tight"
               icon="fa fa-step-backward"
-              onClick={() => playlistSrv.prev()}
+              onClick={this.onPlaylistPrev}
             />
             <DashNavButton
               tooltip="Stop playlist"
               classSuffix="tight"
               icon="fa fa-stop"
-              onClick={() => playlistSrv.stop()}
+              onClick={this.onPlaylistStop}
             />
             <DashNavButton
-              tooltip="Jump forward"
+              tooltip="Go to next dashboard"
               classSuffix="tight"
               icon="fa fa-forward"
-              onClick={() => playlistSrv.next()}
+              onClick={this.onPlaylistNext}
             />
           </div>
         )}

+ 34 - 22
public/app/features/dashboard/containers/DashboardPage.tsx

@@ -100,36 +100,48 @@ export class DashboardPage extends PureComponent<Props, State> {
       }, 10);
     }
 
-    // // when dashboard has loaded subscribe to somme events
-    // if (prevProps.dashboard === null) {
-    //   // set initial fullscreen class state
-    //   this.setPanelFullscreenClass();
-    // }
-
     // Sync url state with model
     if (urlFullscreen !== dashboard.meta.fullscreen || urlEdit !== dashboard.meta.isEditing) {
-      // entering fullscreen/edit mode
       if (urlPanelId) {
-        const panel = dashboard.getPanelById(parseInt(urlPanelId, 10));
-
-        if (panel) {
-          dashboard.setViewMode(panel, urlFullscreen, urlEdit);
-          this.setState({ isEditing: urlEdit, isFullscreen: urlFullscreen, fullscreenPanel: panel });
-          this.setPanelFullscreenClass(urlFullscreen);
-        } else {
-          this.handleFullscreenPanelNotFound(urlPanelId);
-        }
+        this.onEnterFullscreen();
       } else {
-        // handle leaving fullscreen mode
-        if (this.state.fullscreenPanel) {
-          dashboard.setViewMode(this.state.fullscreenPanel, urlFullscreen, urlEdit);
-        }
-        this.setState({ isEditing: false, isFullscreen: false, fullscreenPanel: null });
-        this.setPanelFullscreenClass(false);
+        this.onLeaveFullscreen();
       }
     }
   }
 
+  onEnterFullscreen() {
+    const { dashboard, urlEdit, urlFullscreen, urlPanelId } = this.props;
+
+    const panel = dashboard.getPanelById(parseInt(urlPanelId, 10));
+
+    if (panel) {
+      dashboard.setViewMode(panel, urlFullscreen, urlEdit);
+      this.setState({
+        isEditing: urlEdit,
+        isFullscreen: urlFullscreen,
+        fullscreenPanel: panel,
+      });
+      this.setPanelFullscreenClass(urlFullscreen);
+    } else {
+      this.handleFullscreenPanelNotFound(urlPanelId);
+    }
+  }
+
+  onLeaveFullscreen() {
+    const { dashboard } = this.props;
+
+    if (this.state.fullscreenPanel) {
+      dashboard.setViewMode(this.state.fullscreenPanel, false, false);
+    }
+
+    this.setState({ isEditing: false, isFullscreen: false, fullscreenPanel: null }, () => {
+      dashboard.render();
+    });
+
+    this.setPanelFullscreenClass(false);
+  }
+
   handleFullscreenPanelNotFound(urlPanelId: string) {
     // Panel not found
     this.props.notifyApp(createErrorNotification(`Panel with id ${urlPanelId} not found`));

+ 18 - 5
public/app/features/playlist/playlist_srv.ts

@@ -1,12 +1,16 @@
-import coreModule from '../../core/core_module';
-import kbn from 'app/core/utils/kbn';
-import appEvents from 'app/core/app_events';
+// Libraries
 import _ from 'lodash';
+
+// Utils
 import { toUrlParams } from 'app/core/utils/url';
+import coreModule from '../../core/core_module';
+import appEvents from 'app/core/app_events';
+import locationUtil from 'app/core/utils/location_util';
+import kbn from 'app/core/utils/kbn';
 
 export class PlaylistSrv {
   private cancelPromise: any;
-  private dashboards: Array<{ uri: string }>;
+  private dashboards: Array<{ url: string }>;
   private index: number;
   private interval: number;
   private startUrl: string;
@@ -36,7 +40,12 @@ export class PlaylistSrv {
     const queryParams = this.$location.search();
     const filteredParams = _.pickBy(queryParams, value => value !== null);
 
-    this.$location.url('dashboard/' + dash.uri + '?' + toUrlParams(filteredParams));
+    // this is done inside timeout to make sure digest happens after
+    // as this can be called from react
+    this.$timeout(() => {
+      const stripedUrl = locationUtil.stripBaseFromUrl(dash.url);
+      this.$location.url(stripedUrl  + '?' + toUrlParams(filteredParams));
+    });
 
     this.index++;
     this.cancelPromise = this.$timeout(() => this.next(), this.interval);
@@ -54,6 +63,8 @@ export class PlaylistSrv {
     this.index = 0;
     this.isPlaying = true;
 
+    appEvents.emit('playlist-started');
+
     return this.backendSrv.get(`/api/playlists/${playlistId}`).then(playlist => {
       return this.backendSrv.get(`/api/playlists/${playlistId}/dashboards`).then(dashboards => {
         this.dashboards = dashboards;
@@ -77,6 +88,8 @@ export class PlaylistSrv {
     if (this.cancelPromise) {
       this.$timeout.cancel(this.cancelPromise);
     }
+
+    appEvents.emit('playlist-stopped');
   }
 }
 

+ 7 - 10
public/app/routes/GrafanaCtrl.ts

@@ -120,12 +120,13 @@ export function grafanaAppDirective(playlistSrv, contextSrv, $timeout, $rootScop
         body.toggleClass('sidemenu-hidden');
       });
 
-      scope.$watch(
-        () => playlistSrv.isPlaying,
-        newValue => {
-          elem.toggleClass('view-mode--playlist', newValue === true);
-        }
-      );
+      appEvents.on('playlist-started', () => {
+        elem.toggleClass('view-mode--playlist', true);
+      });
+
+      appEvents.on('playlist-stopped', () => {
+        elem.toggleClass('view-mode--playlist', false);
+      });
 
       // check if we are in server side render
       if (document.cookie.indexOf('renderKey') !== -1) {
@@ -258,10 +259,6 @@ export function grafanaAppDirective(playlistSrv, contextSrv, $timeout, $rootScop
           }, 100);
         }
 
-        if (target.parents('.navbar-buttons--playlist').length === 0) {
-          playlistSrv.stop();
-        }
-
         // hide search
         if (body.find('.search-container').length > 0) {
           if (target.parents('.search-results-container, .search-field-wrapper').length === 0) {