Commit d978a66e by Torkel Ödegaard

Fixed lots of loading flow issues and updated solo route page

parent 23ac9405
import config from 'app/core/config'; import config from 'app/core/config';
export const stripBaseFromUrl = url => { export const stripBaseFromUrl = (url: string): string => {
const appSubUrl = config.appSubUrl; const appSubUrl = config.appSubUrl;
const stripExtraChars = appSubUrl.endsWith('/') ? 1 : 0; const stripExtraChars = appSubUrl.endsWith('/') ? 1 : 0;
const urlWithoutBase = const urlWithoutBase =
......
...@@ -5,6 +5,7 @@ import { connect } from 'react-redux'; ...@@ -5,6 +5,7 @@ import { connect } from 'react-redux';
// Utils & Services // Utils & Services
import { AngularComponent, getAngularLoader } from 'app/core/services/AngularLoader'; import { AngularComponent, getAngularLoader } from 'app/core/services/AngularLoader';
import { appEvents } from 'app/core/app_events'; import { appEvents } from 'app/core/app_events';
import { PlaylistSrv } from 'app/features/playlist/playlist_srv';
// Components // Components
import { DashNavButton } from './DashNavButton'; import { DashNavButton } from './DashNavButton';
...@@ -116,12 +117,13 @@ export class DashNav extends PureComponent<Props> { ...@@ -116,12 +117,13 @@ export class DashNav extends PureComponent<Props> {
}; };
render() { render() {
const { dashboard, isFullscreen, editview } = this.props; const { dashboard, isFullscreen, editview, $injector } = this.props;
const { canStar, canSave, canShare, folderTitle, showSettings, isStarred } = dashboard.meta; const { canStar, canSave, canShare, folderTitle, showSettings, isStarred } = dashboard.meta;
const { snapshot } = dashboard; const { snapshot } = dashboard;
const haveFolder = dashboard.meta.folderId > 0; const haveFolder = dashboard.meta.folderId > 0;
const snapshotUrl = snapshot && snapshot.originalUrl; const snapshotUrl = snapshot && snapshot.originalUrl;
const playlistSrv: PlaylistSrv = $injector.get('playlistSrv');
return ( return (
<div className="navbar"> <div className="navbar">
...@@ -135,13 +137,29 @@ export class DashNav extends PureComponent<Props> { ...@@ -135,13 +137,29 @@ export class DashNav extends PureComponent<Props> {
</div> </div>
<div className="navbar__spacer" /> <div className="navbar__spacer" />
{/*
<div class="navbar-buttons navbar-buttons--playlist" ng-if="ctrl.playlistSrv.isPlaying"> {playlistSrv.isPlaying && (
<a class="navbar-button navbar-button--tight" ng-click="ctrl.playlistSrv.prev()"><i class="fa fa-step-backward"></i></a> <div className="navbar-buttons navbar-buttons--playlist">
<a class="navbar-button navbar-button--tight" ng-click="ctrl.playlistSrv.stop()"><i class="fa fa-stop"></i></a> <DashNavButton
<a class="navbar-button navbar-button--tight" ng-click="ctrl.playlistSrv.next()"><i class="fa fa-step-forward"></i></a> tooltip="Jump to previous dashboard"
classSuffix="tight"
icon="fa fa-step-backward"
onClick={() => playlistSrv.prev()}
/>
<DashNavButton
tooltip="Stop playlist"
classSuffix="tight"
icon="fa fa-stop"
onClick={() => playlistSrv.stop()}
/>
<DashNavButton
tooltip="Jump forward"
classSuffix="tight"
icon="fa fa-forward"
onClick={() => playlistSrv.next()}
/>
</div> </div>
*/} )}
<div className="navbar-buttons navbar-buttons--actions"> <div className="navbar-buttons navbar-buttons--actions">
{canSave && ( {canSave && (
......
...@@ -69,6 +69,7 @@ export class DashboardPage extends PureComponent<Props, State> { ...@@ -69,6 +69,7 @@ export class DashboardPage extends PureComponent<Props, State> {
urlType: this.props.urlType, urlType: this.props.urlType,
urlFolderId: this.props.urlFolderId, urlFolderId: this.props.urlFolderId,
routeInfo: this.props.routeInfo, routeInfo: this.props.routeInfo,
fixUrl: true,
}); });
} }
......
...@@ -3,98 +3,78 @@ import React, { Component } from 'react'; ...@@ -3,98 +3,78 @@ import React, { Component } from 'react';
import { hot } from 'react-hot-loader'; import { hot } from 'react-hot-loader';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
// Utils & Services
import appEvents from 'app/core/app_events';
import locationUtil from 'app/core/utils/location_util';
import { getBackendSrv } from 'app/core/services/backend_srv';
// Components // Components
import { DashboardPanel } from '../dashgrid/DashboardPanel'; import { DashboardPanel } from '../dashgrid/DashboardPanel';
// Redux // Redux
import { updateLocation } from 'app/core/actions'; import { initDashboard } from '../state/initDashboard';
// Types // Types
import { StoreState } from 'app/types'; import { StoreState, DashboardRouteInfo } from 'app/types';
import { PanelModel, DashboardModel } from 'app/features/dashboard/state'; import { PanelModel, DashboardModel } from 'app/features/dashboard/state';
interface Props { interface Props {
panelId: string; urlPanelId: string;
urlUid?: string; urlUid?: string;
urlSlug?: string; urlSlug?: string;
urlType?: string; urlType?: string;
$scope: any; $scope: any;
$injector: any; $injector: any;
updateLocation: typeof updateLocation; routeInfo: DashboardRouteInfo;
initDashboard: typeof initDashboard;
dashboard: DashboardModel | null;
} }
interface State { interface State {
panel: PanelModel | null; panel: PanelModel | null;
dashboard: DashboardModel | null;
notFound: boolean; notFound: boolean;
} }
export class SoloPanelPage extends Component<Props, State> { export class SoloPanelPage extends Component<Props, State> {
state: State = { state: State = {
panel: null, panel: null,
dashboard: null,
notFound: false, notFound: false,
}; };
componentDidMount() { componentDidMount() {
const { $injector, $scope, urlUid, urlType, urlSlug } = this.props; const { $injector, $scope, urlUid, urlType, urlSlug, routeInfo } = this.props;
// handle old urls with no uid this.props.initDashboard({
if (!urlUid && !(urlType === 'script' || urlType === 'snapshot')) { $injector: $injector,
this.redirectToNewUrl(); $scope: $scope,
return; urlSlug: urlSlug,
} urlUid: urlUid,
urlType: urlType,
const dashboardLoaderSrv = $injector.get('dashboardLoaderSrv'); routeInfo: routeInfo,
fixUrl: false,
// subscribe to event to know when dashboard controller is done with inititalization
appEvents.on('dashboard-initialized', this.onDashoardInitialized);
dashboardLoaderSrv.loadDashboard(urlType, urlSlug, urlUid).then(result => {
result.meta.soloMode = true;
$scope.initDashboard(result, $scope);
});
}
redirectToNewUrl() {
getBackendSrv().getDashboardBySlug(this.props.urlSlug).then(res => {
if (res) {
const url = locationUtil.stripBaseFromUrl(res.meta.url.replace('/d/', '/d-solo/'));
this.props.updateLocation(url);
}
}); });
} }
onDashoardInitialized = () => { componentDidUpdate(prevProps: Props) {
const { $scope, panelId } = this.props; const { urlPanelId, dashboard } = this.props;
const dashboard: DashboardModel = $scope.dashboard; if (!dashboard) {
const panel = dashboard.getPanelById(parseInt(panelId, 10)); return;
}
// we just got the dashboard!
if (!prevProps.dashboard) {
const panel = dashboard.getPanelById(parseInt(urlPanelId, 10));
if (!panel) { if (!panel) {
this.setState({ notFound: true }); this.setState({ notFound: true });
return; return;
} }
this.setState({ dashboard, panel }); this.setState({ panel });
}; }
}
render() { render() {
const { panelId } = this.props; const { urlPanelId, dashboard } = this.props;
const { notFound, panel, dashboard } = this.state; const { notFound, panel } = this.state;
if (notFound) { if (notFound) {
return ( return <div className="alert alert-error">Panel with id {urlPanelId} not found</div>;
<div className="alert alert-error">
Panel with id { panelId } not found
</div>
);
} }
if (!panel) { if (!panel) {
...@@ -113,11 +93,13 @@ const mapStateToProps = (state: StoreState) => ({ ...@@ -113,11 +93,13 @@ const mapStateToProps = (state: StoreState) => ({
urlUid: state.location.routeParams.uid, urlUid: state.location.routeParams.uid,
urlSlug: state.location.routeParams.slug, urlSlug: state.location.routeParams.slug,
urlType: state.location.routeParams.type, urlType: state.location.routeParams.type,
panelId: state.location.query.panelId urlPanelId: state.location.query.panelId,
loadingState: state.dashboard.loadingState,
dashboard: state.dashboard.model as DashboardModel,
}); });
const mapDispatchToProps = { const mapDispatchToProps = {
updateLocation initDashboard,
}; };
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(SoloPanelPage)); export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(SoloPanelPage));
...@@ -9,7 +9,6 @@ export class DashboardSrv { ...@@ -9,7 +9,6 @@ export class DashboardSrv {
/** @ngInject */ /** @ngInject */
constructor(private backendSrv, private $rootScope, private $location) { constructor(private backendSrv, private $rootScope, private $location) {
appEvents.on('save-dashboard', this.saveDashboard.bind(this), $rootScope); appEvents.on('save-dashboard', this.saveDashboard.bind(this), $rootScope);
appEvents.on('save-dashboard', this.saveDashboard.bind(this), $rootScope);
appEvents.on('panel-change-view', this.onPanelChangeView); appEvents.on('panel-change-view', this.onPanelChangeView);
} }
......
...@@ -25,16 +25,24 @@ export interface InitDashboardArgs { ...@@ -25,16 +25,24 @@ export interface InitDashboardArgs {
urlUid?: string; urlUid?: string;
urlSlug?: string; urlSlug?: string;
urlType?: string; urlType?: string;
urlFolderId: string; urlFolderId?: string;
routeInfo: string; routeInfo: string;
fixUrl: boolean;
} }
async function redirectToNewUrl(slug: string, dispatch: any) { async function redirectToNewUrl(slug: string, dispatch: any, currentPath: string) {
const res = await getBackendSrv().getDashboardBySlug(slug); const res = await getBackendSrv().getDashboardBySlug(slug);
if (res) { if (res) {
const url = locationUtil.stripBaseFromUrl(res.meta.url.replace('/d/', '/d-solo/')); let newUrl = res.meta.url;
dispatch(updateLocation(url));
// fix solo route urls
if (currentPath.indexOf('dashboard-solo') !== -1) {
newUrl = newUrl.replace('/d/', '/d-solo/');
}
const url = locationUtil.stripBaseFromUrl(newUrl);
dispatch(updateLocation({ path: url, partial: true, replace: true }));
} }
} }
...@@ -46,6 +54,7 @@ export function initDashboard({ ...@@ -46,6 +54,7 @@ export function initDashboard({
urlType, urlType,
urlFolderId, urlFolderId,
routeInfo, routeInfo,
fixUrl,
}: InitDashboardArgs): ThunkResult<void> { }: InitDashboardArgs): ThunkResult<void> {
return async (dispatch, getState) => { return async (dispatch, getState) => {
let dashDTO = null; let dashDTO = null;
...@@ -76,14 +85,14 @@ export function initDashboard({ ...@@ -76,14 +85,14 @@ export function initDashboard({
case DashboardRouteInfo.Normal: { case DashboardRouteInfo.Normal: {
// for old db routes we redirect // for old db routes we redirect
if (urlType === 'db') { if (urlType === 'db') {
redirectToNewUrl(urlSlug, dispatch); redirectToNewUrl(urlSlug, dispatch, getState().location.path);
return; return;
} }
const loaderSrv = $injector.get('dashboardLoaderSrv'); const loaderSrv = $injector.get('dashboardLoaderSrv');
dashDTO = await loaderSrv.loadDashboard(urlType, urlSlug, urlUid); dashDTO = await loaderSrv.loadDashboard(urlType, urlSlug, urlUid);
if (dashDTO.meta.url) { if (fixUrl && dashDTO.meta.url) {
// check if the current url is correct (might be old slug) // check if the current url is correct (might be old slug)
const dashboardUrl = locationUtil.stripBaseFromUrl(dashDTO.meta.url); const dashboardUrl = locationUtil.stripBaseFromUrl(dashDTO.meta.url);
const currentPath = getState().location.path; const currentPath = getState().location.path;
......
...@@ -45,12 +45,6 @@ export class GrafanaCtrl { ...@@ -45,12 +45,6 @@ export class GrafanaCtrl {
}; };
$rootScope.colors = colors; $rootScope.colors = colors;
$scope.initDashboard = (dashboardData, viewScope) => {
$scope.appEvent('dashboard-fetch-end', dashboardData);
$controller('DashboardCtrl', { $scope: viewScope }).init(dashboardData);
};
$rootScope.onAppEvent = function(name, callback, localScope) { $rootScope.onAppEvent = function(name, callback, localScope) {
const unbind = $rootScope.$on(name, callback); const unbind = $rootScope.$on(name, callback);
let callerScope = this; let callerScope = this;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment