Browse Source

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

Torkel Ödegaard 6 years ago
parent
commit
6a4777eafc

+ 101 - 0
public/app/features/dashboard/containers/SoloPanelPage.tsx

@@ -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));

+ 1 - 1
public/app/features/dashboard/state/DashboardModel.ts

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

+ 7 - 1
public/app/routes/ReactContainer.tsx

@@ -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]);
 

+ 6 - 4
public/app/routes/routes.ts

@@ -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',

+ 7 - 0
public/sass/pages/_dashboard.scss

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