2019-02-04 14:08:30 -06:00
|
|
|
// Libraries
|
2018-08-30 04:52:31 -05:00
|
|
|
import _ from 'lodash';
|
2019-02-04 14:08:30 -06:00
|
|
|
|
|
|
|
// Utils
|
|
|
|
import coreModule from '../../core/core_module';
|
|
|
|
import appEvents from 'app/core/app_events';
|
2020-04-20 00:37:38 -05:00
|
|
|
|
2019-02-04 14:08:30 -06:00
|
|
|
import kbn from 'app/core/utils/kbn';
|
2019-03-06 09:58:19 -06:00
|
|
|
import { store } from 'app/store/store';
|
2019-10-14 03:27:47 -05:00
|
|
|
import { CoreEvents } from 'app/types';
|
2020-01-21 03:08:07 -06:00
|
|
|
import { getBackendSrv } from '@grafana/runtime';
|
2020-04-20 00:37:38 -05:00
|
|
|
import { locationUtil, urlUtil } from '@grafana/data';
|
2016-01-18 06:21:48 -06:00
|
|
|
|
2019-04-05 04:09:57 -05:00
|
|
|
export const queryParamsToPreserve: { [key: string]: boolean } = {
|
|
|
|
kiosk: true,
|
|
|
|
autofitpanels: true,
|
|
|
|
orgId: true,
|
|
|
|
};
|
|
|
|
|
2019-01-19 09:58:26 -06:00
|
|
|
export class PlaylistSrv {
|
2016-01-18 07:05:48 -06:00
|
|
|
private cancelPromise: any;
|
2019-02-04 14:08:30 -06:00
|
|
|
private dashboards: Array<{ url: string }>;
|
2016-01-18 07:05:48 -06:00
|
|
|
private index: number;
|
2019-01-19 09:58:26 -06:00
|
|
|
private interval: number;
|
2016-12-05 04:43:51 -06:00
|
|
|
private startUrl: string;
|
2019-01-19 09:58:26 -06:00
|
|
|
private numberOfLoops = 0;
|
2019-03-06 09:58:19 -06:00
|
|
|
private storeUnsub: () => void;
|
|
|
|
private validPlaylistUrl: string;
|
2018-08-31 09:40:23 -05:00
|
|
|
isPlaying: boolean;
|
2016-01-18 06:21:48 -06:00
|
|
|
|
|
|
|
/** @ngInject */
|
2020-01-21 03:08:07 -06:00
|
|
|
constructor(private $location: any, private $timeout: any) {}
|
2016-01-18 06:21:48 -06:00
|
|
|
|
|
|
|
next() {
|
|
|
|
this.$timeout.cancel(this.cancelPromise);
|
|
|
|
|
2018-08-26 13:19:23 -05:00
|
|
|
const playedAllDashboards = this.index > this.dashboards.length - 1;
|
2016-01-18 07:58:46 -06:00
|
|
|
if (playedAllDashboards) {
|
2019-01-19 09:58:26 -06:00
|
|
|
this.numberOfLoops++;
|
|
|
|
|
|
|
|
// This does full reload of the playlist to keep memory in check due to existing leaks but at the same time
|
|
|
|
// we do not want page to flicker after each full loop.
|
|
|
|
if (this.numberOfLoops >= 3) {
|
|
|
|
window.location.href = this.startUrl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.index = 0;
|
2017-06-28 09:29:46 -05:00
|
|
|
}
|
|
|
|
|
2018-08-26 13:19:23 -05:00
|
|
|
const dash = this.dashboards[this.index];
|
2018-08-30 04:52:31 -05:00
|
|
|
const queryParams = this.$location.search();
|
2019-04-05 04:09:57 -05:00
|
|
|
const filteredParams = _.pickBy(queryParams, (value: any, key: string) => queryParamsToPreserve[key]);
|
2019-03-06 09:58:19 -06:00
|
|
|
const nextDashboardUrl = locationUtil.stripBaseFromUrl(dash.url);
|
2018-08-30 04:52:31 -05:00
|
|
|
|
2019-02-04 14:08:30 -06:00
|
|
|
// this is done inside timeout to make sure digest happens after
|
|
|
|
// as this can be called from react
|
|
|
|
this.$timeout(() => {
|
2020-04-20 00:37:38 -05:00
|
|
|
this.$location.url(nextDashboardUrl + '?' + urlUtil.toUrlParams(filteredParams));
|
2019-02-04 14:08:30 -06:00
|
|
|
});
|
2017-06-28 09:29:46 -05:00
|
|
|
|
|
|
|
this.index++;
|
2019-03-06 09:58:19 -06:00
|
|
|
this.validPlaylistUrl = nextDashboardUrl;
|
2017-06-28 09:29:46 -05:00
|
|
|
this.cancelPromise = this.$timeout(() => this.next(), this.interval);
|
|
|
|
}
|
|
|
|
|
2016-01-18 09:00:11 -06:00
|
|
|
prev() {
|
2016-01-18 06:21:48 -06:00
|
|
|
this.index = Math.max(this.index - 2, 0);
|
|
|
|
this.next();
|
|
|
|
}
|
|
|
|
|
2019-03-06 09:58:19 -06:00
|
|
|
// Detect url changes not caused by playlist srv and stop playlist
|
|
|
|
storeUpdated() {
|
|
|
|
const state = store.getState();
|
|
|
|
|
|
|
|
if (state.location.path !== this.validPlaylistUrl) {
|
|
|
|
this.stop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-18 01:03:04 -05:00
|
|
|
start(playlistId: number) {
|
2016-01-18 06:21:48 -06:00
|
|
|
this.stop();
|
|
|
|
|
2016-12-05 04:43:51 -06:00
|
|
|
this.startUrl = window.location.href;
|
2016-01-18 06:21:48 -06:00
|
|
|
this.index = 0;
|
2017-06-02 07:00:42 -05:00
|
|
|
this.isPlaying = true;
|
2016-01-18 06:21:48 -06:00
|
|
|
|
2019-03-06 09:58:19 -06:00
|
|
|
// setup location tracking
|
|
|
|
this.storeUnsub = store.subscribe(() => this.storeUpdated());
|
|
|
|
this.validPlaylistUrl = this.$location.path();
|
|
|
|
|
2019-10-14 03:27:47 -05:00
|
|
|
appEvents.emit(CoreEvents.playlistStarted);
|
2019-02-04 14:08:30 -06:00
|
|
|
|
2020-01-21 03:08:07 -06:00
|
|
|
return getBackendSrv()
|
|
|
|
.get(`/api/playlists/${playlistId}`)
|
|
|
|
.then((playlist: any) => {
|
|
|
|
return getBackendSrv()
|
|
|
|
.get(`/api/playlists/${playlistId}/dashboards`)
|
|
|
|
.then((dashboards: any) => {
|
|
|
|
this.dashboards = dashboards;
|
|
|
|
this.interval = kbn.interval_to_ms(playlist.interval);
|
|
|
|
this.next();
|
|
|
|
});
|
2017-12-21 01:39:31 -06:00
|
|
|
});
|
2016-01-18 06:21:48 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
stop() {
|
2018-08-30 04:52:31 -05:00
|
|
|
if (this.isPlaying) {
|
|
|
|
const queryParams = this.$location.search();
|
|
|
|
if (queryParams.kiosk) {
|
2019-10-14 03:27:47 -05:00
|
|
|
appEvents.emit(CoreEvents.toggleKioskMode, { exit: true });
|
2018-08-30 04:52:31 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-18 06:21:48 -06:00
|
|
|
this.index = 0;
|
2017-06-02 07:00:42 -05:00
|
|
|
this.isPlaying = false;
|
2016-01-18 06:21:48 -06:00
|
|
|
|
2019-03-06 09:58:19 -06:00
|
|
|
if (this.storeUnsub) {
|
|
|
|
this.storeUnsub();
|
|
|
|
}
|
|
|
|
|
2016-01-18 06:21:48 -06:00
|
|
|
if (this.cancelPromise) {
|
2016-01-18 09:00:11 -06:00
|
|
|
this.$timeout.cancel(this.cancelPromise);
|
2016-01-18 06:21:48 -06:00
|
|
|
}
|
2019-02-04 14:08:30 -06:00
|
|
|
|
2019-10-14 03:27:47 -05:00
|
|
|
appEvents.emit(CoreEvents.playlistStopped);
|
2016-01-18 06:21:48 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-20 05:33:33 -06:00
|
|
|
coreModule.service('playlistSrv', PlaylistSrv);
|