mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Fixed lots of loading flow issues and updated solo route page
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
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';
|
|||||||
// 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> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
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> {
|
|||||||
</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> {
|
|||||||
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';
|
|||||||
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,
|
||||||
|
urlSlug: urlSlug,
|
||||||
|
urlUid: urlUid,
|
||||||
|
urlType: urlType,
|
||||||
|
routeInfo: routeInfo,
|
||||||
|
fixUrl: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps: Props) {
|
||||||
|
const { urlPanelId, dashboard } = this.props;
|
||||||
|
|
||||||
|
if (!dashboard) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dashboardLoaderSrv = $injector.get('dashboardLoaderSrv');
|
// we just got the dashboard!
|
||||||
|
if (!prevProps.dashboard) {
|
||||||
// subscribe to event to know when dashboard controller is done with inititalization
|
const panel = dashboard.getPanelById(parseInt(urlPanelId, 10));
|
||||||
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 = () => {
|
|
||||||
const { $scope, panelId } = this.props;
|
|
||||||
|
|
||||||
const dashboard: DashboardModel = $scope.dashboard;
|
|
||||||
const panel = dashboard.getPanelById(parseInt(panelId, 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) => ({
|
|||||||
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));
|
||||||
|
|||||||
@@ -8,7 +8,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 {
|
|||||||
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({
|
|||||||
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({
|
|||||||
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 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
$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;
|
||||||
|
|||||||
Reference in New Issue
Block a user