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

pull/15212/head
Torkel Ödegaard 7 years ago
commit 3d5ca99d53
  1. 1
      pkg/api/dtos/playlist.go
  2. 1
      pkg/api/playlist_play.go
  3. 37
      public/app/features/dashboard/components/DashNav/DashNav.tsx
  4. 56
      public/app/features/dashboard/containers/DashboardPage.tsx
  5. 23
      public/app/features/playlist/playlist_srv.ts
  6. 17
      public/app/routes/GrafanaCtrl.ts

@ -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"`
}

@ -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,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>
)}

@ -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`));

@ -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');
}
}

@ -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) {

Loading…
Cancel
Save