The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
grafana/public/app/features/dashboard/containers/DashboardPage.tsx

139 lines
3.8 KiB

// Libraries
import React, { Component } from 'react';
import { hot } from 'react-hot-loader';
import { connect } from 'react-redux';
// Utils & Services
import locationUtil from 'app/core/utils/location_util';
import { getBackendSrv } from 'app/core/services/backend_srv';
import { createErrorNotification } from 'app/core/copy/appNotification';
// Components
import { LoadingPlaceholder } from '@grafana/ui';
// Redux
import { updateLocation } from 'app/core/actions';
import { notifyApp } from 'app/core/actions';
// Types
import { StoreState } from 'app/types';
import { DashboardModel } from 'app/features/dashboard/state';
interface Props {
panelId: string;
urlUid?: string;
urlSlug?: string;
urlType?: string;
$scope: any;
$injector: any;
updateLocation: typeof updateLocation;
notifyApp: typeof notifyApp;
}
interface State {
dashboard: DashboardModel | null;
notFound: boolean;
}
export class DashboardPage extends Component<Props, State> {
state: State = {
dashboard: null,
notFound: false,
};
async componentDidMount() {
const { $injector, urlUid, urlType, urlSlug } = this.props;
// handle old urls with no uid
if (!urlUid && !(urlType === 'script' || urlType === 'snapshot')) {
this.redirectToNewUrl();
return;
}
const loaderSrv = $injector.get('dashboardLoaderSrv');
const dashDTO = await loaderSrv.loadDashboard(urlType, urlSlug, urlUid);
try {
this.initDashboard(dashDTO);
} catch (err) {
this.props.notifyApp(createErrorNotification('Failed to init dashboard', err.toString()));
console.log(err);
}
}
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);
}
});
}
initDashboard(dashDTO: any) {
const dashboard = new DashboardModel(dashDTO.dashboard, dashDTO.meta);
// init services
this.timeSrv.init(dashboard);
this.annotationsSrv.init(dashboard);
// template values service needs to initialize completely before
// the rest of the dashboard can load
this.variableSrv
.init(dashboard)
// template values failes are non fatal
.catch(this.onInitFailed.bind(this, 'Templating init failed', false))
// continue
.finally(() => {
this.dashboard = dashboard;
this.dashboard.processRepeats();
this.dashboard.updateSubmenuVisibility();
this.dashboard.autoFitPanels(window.innerHeight);
this.unsavedChangesSrv.init(dashboard, this.$scope);
// TODO refactor ViewStateSrv
this.$scope.dashboard = dashboard;
this.dashboardViewState = this.dashboardViewStateSrv.create(this.$scope);
this.keybindingSrv.setupDashboardBindings(this.$scope, dashboard);
this.setWindowTitleAndTheme();
appEvents.emit('dashboard-initialized', dashboard);
})
.catch(this.onInitFailed.bind(this, 'Dashboard init failed', true));
this.setState({ dashboard });
}
render() {
const { notFound, dashboard } = this.state;
if (notFound) {
return <div className="alert alert-error">Dashboard not found</div>;
}
if (!dashboard) {
return <LoadingPlaceholder text="Loading dashboard" />;
}
return <div>title: {dashboard.title}</div>;
}
}
const mapStateToProps = (state: StoreState) => ({
urlUid: state.location.routeParams.uid,
urlSlug: state.location.routeParams.slug,
urlType: state.location.routeParams.type,
panelId: state.location.query.panelId,
});
const mapDispatchToProps = {
updateLocation,
notifyApp,
};
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(DashboardPage));