wip: New react container route for solo panels that supports both angular and react panels

This commit is contained in:
Torkel Ödegaard 2019-01-31 09:44:12 +01:00
parent aafd4a339a
commit 6a4777eafc
5 changed files with 122 additions and 6 deletions

View File

@ -0,0 +1,101 @@
// Libraries
import React, { Component } from 'react';
import { hot } from 'react-hot-loader';
import { connect } from 'react-redux';
// Utils & Services
import appEvents from 'app/core/app_events';
// Components
import { DashboardPanel } from '../dashgrid/DashboardPanel';
// Types
import { StoreState } from 'app/types';
import { PanelModel, DashboardModel } from 'app/features/dashboard/state';
interface Props {
panelId: string;
uid?: string;
slug?: string;
type?: string;
$scope: any;
$injector: any;
}
interface State {
panel: PanelModel | null;
dashboard: DashboardModel | null;
notFound: boolean;
}
export class SoloPanelPage extends Component<Props, State> {
state: State = {
panel: null,
dashboard: null,
notFound: false,
};
componentDidMount() {
const { $injector, $scope, uid } = this.props;
const dashboardLoaderSrv = $injector.get('dashboardLoaderSrv');
// subscribe to event to know when dashboard controller is done with inititalization
appEvents.on('dashboard-initialized', this.onDashoardInitialized);
dashboardLoaderSrv.loadDashboard('', '', uid).then(result => {
result.meta.soloMode = true;
$scope.initDashboard(result, $scope);
});
}
onDashoardInitialized = () => {
const { $scope, panelId } = this.props;
const dashboard: DashboardModel = $scope.dashboard;
const panel = dashboard.getPanelById(parseInt(panelId, 10));
if (!panel) {
this.setState({ notFound: true });
return;
}
this.setState({ dashboard, panel });
};
render() {
const { panelId } = this.props;
const { notFound, panel, dashboard } = this.state;
if (notFound) {
return (
<div className="alert alert-error">
Panel with id { panelId } not found
</div>
);
}
if (!panel) {
return <div>Loading & initializing dashboard</div>;
}
return (
<div className="panel-solo">
<DashboardPanel dashboard={dashboard} panel={panel} isEditing={false} isFullscreen={false} />
</div>
);
}
}
const mapStateToProps = (state: StoreState) => ({
uid: state.location.routeParams.uid,
slug: state.location.routeParams.slug,
type: state.location.routeParams.type,
panelId: state.location.query.panelId
});
const mapDispatchToProps = {
};
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(SoloPanelPage));

View File

@ -271,7 +271,7 @@ export class DashboardModel {
}
}
getPanelById(id) {
getPanelById(id): PanelModel {
for (const panel of this.panels) {
if (panel.id === id) {
return panel;

View File

@ -18,6 +18,8 @@ function WrapInProvider(store, Component, props) {
export function reactContainer(
$route,
$location,
$injector,
$rootScope,
contextSrv: ContextSrv
) {
return {
@ -38,7 +40,11 @@ export function reactContainer(
component = component.default;
}
const props = { };
const props = {
$injector: $injector,
$rootScope: $rootScope,
$scope: scope,
};
ReactDOM.render(WrapInProvider(store, component, props), elem[0]);

View File

@ -19,6 +19,7 @@ import UsersListPage from 'app/features/users/UsersListPage';
import DataSourceDashboards from 'app/features/datasources/DataSourceDashboards';
import DataSourceSettingsPage from '../features/datasources/settings/DataSourceSettingsPage';
import OrgDetailsPage from '../features/org/OrgDetailsPage';
import SoloPanelPage from '../features/dashboard/containers/SoloPanelPage';
import config from 'app/core/config';
/** @ngInject */
@ -51,10 +52,11 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
pageClass: 'page-dashboard',
})
.when('/d-solo/:uid/:slug', {
templateUrl: 'public/app/features/panel/partials/soloPanel.html',
controller: 'SoloPanelCtrl',
reloadOnSearch: false,
pageClass: 'page-dashboard',
template: '<react-container />',
pageClass: 'dashboard-solo',
resolve: {
component: () => SoloPanelPage,
},
})
.when('/dashboard-solo/:type/:slug', {
templateUrl: 'public/app/features/panel/partials/soloPanel.html',

View File

@ -17,6 +17,13 @@ div.flot-text {
height: 100%;
}
.dashboard-solo {
.footer,
.sidemenu {
display: none;
}
}
.panel-solo {
position: fixed;
bottom: 0;