github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ui/ccl/src/views/clusterviz/containers/map/nodeCanvasContainer.tsx (about)

     1  // Copyright 2017 The Cockroach Authors.
     2  //
     3  // Licensed as a CockroachDB Enterprise file under the Cockroach Community
     4  // License (the "License"); you may not use this file except in compliance with
     5  // the License. You may obtain a copy of the License at
     6  //
     7  //     https://github.com/cockroachdb/cockroach/blob/master/licenses/CCL.txt
     8  
     9  import _ from "lodash";
    10  import React from "react";
    11  import { connect } from "react-redux";
    12  import { withRouter, RouteComponentProps } from "react-router-dom";
    13  import { createSelector } from "reselect";
    14  
    15  import { cockroach } from "src/js/protos";
    16  import { refreshNodes, refreshLiveness, refreshLocations } from "src/redux/apiReducers";
    17  import { selectLocalityTree, LocalityTier, LocalityTree } from "src/redux/localities";
    18  import { selectLocationsRequestStatus, selectLocationTree, LocationTree } from "src/redux/locations";
    19  import {
    20    nodesSummarySelector,
    21    NodesSummary,
    22    selectNodeRequestStatus,
    23    selectLivenessRequestStatus,
    24    livenessStatusByNodeIDSelector,
    25    LivenessStatus,
    26    livenessByNodeIDSelector,
    27  } from "src/redux/nodes";
    28  import { AdminUIState } from "src/redux/state";
    29  import { CLUSTERVIZ_ROOT } from "src/routes/visualization";
    30  import { getLocality } from "src/util/localities";
    31  import Loading from "src/views/shared/components/loading";
    32  import { NodeCanvas } from "./nodeCanvas";
    33  
    34  type Liveness = cockroach.kv.kvserver.storagepb.ILiveness;
    35  
    36  interface NodeCanvasContainerProps {
    37    nodesSummary: NodesSummary;
    38    localityTree: LocalityTree;
    39    locationTree: LocationTree;
    40    livenessStatuses: { [id: string]: LivenessStatus };
    41    livenesses: { [id: string]: Liveness };
    42    dataExists: boolean;
    43    dataIsValid: boolean;
    44    dataErrors: Error[];
    45    refreshNodes: typeof refreshNodes;
    46    refreshLiveness: any;
    47    refreshLocations: any;
    48  }
    49  
    50  export interface NodeCanvasContainerOwnProps {
    51    tiers: LocalityTier[];
    52  }
    53  
    54  class NodeCanvasContainer extends React.Component<NodeCanvasContainerProps & NodeCanvasContainerOwnProps & RouteComponentProps> {
    55    componentDidMount() {
    56      this.props.refreshNodes();
    57      this.props.refreshLiveness();
    58      this.props.refreshLocations();
    59    }
    60  
    61    componentDidUpdate() {
    62      this.props.refreshNodes();
    63      this.props.refreshLiveness();
    64      this.props.refreshLocations();
    65    }
    66  
    67    render() {
    68      const currentLocality = getLocality(this.props.localityTree, this.props.tiers);
    69      if (this.props.dataIsValid && _.isNil(currentLocality)) {
    70        this.props.history.replace(CLUSTERVIZ_ROOT);
    71      }
    72  
    73      return (
    74        <Loading
    75          loading={!this.props.dataExists}
    76          error={this.props.dataErrors}
    77          render={() => (
    78            <NodeCanvas
    79              localityTree={currentLocality}
    80              locationTree={this.props.locationTree}
    81              tiers={this.props.tiers}
    82              livenessStatuses={this.props.livenessStatuses}
    83              livenesses={this.props.livenesses}
    84            />
    85          )}
    86        />
    87      );
    88    }
    89  }
    90  
    91  const selectDataExists = createSelector(
    92    selectNodeRequestStatus,
    93    selectLocationsRequestStatus,
    94    selectLivenessRequestStatus,
    95    (nodes, locations, liveness) => !!nodes.data && !!locations.data && !!liveness.data,
    96  );
    97  
    98  const selectDataIsValid = createSelector(
    99    selectNodeRequestStatus,
   100    selectLocationsRequestStatus,
   101    selectLivenessRequestStatus,
   102    (nodes, locations, liveness) => nodes.valid && locations.valid && liveness.valid,
   103  );
   104  
   105  const dataErrors = createSelector(
   106    selectNodeRequestStatus,
   107    selectLocationsRequestStatus,
   108    selectLivenessRequestStatus,
   109    (nodes, locations, liveness) => [nodes.lastError, locations.lastError, liveness.lastError],
   110  );
   111  
   112  export default withRouter(connect(
   113    (state: AdminUIState, _ownProps: NodeCanvasContainerOwnProps) => ({
   114      nodesSummary: nodesSummarySelector(state),
   115      localityTree: selectLocalityTree(state),
   116      locationTree: selectLocationTree(state),
   117      livenessStatuses: livenessStatusByNodeIDSelector(state),
   118      livenesses: livenessByNodeIDSelector(state),
   119      dataIsValid: selectDataIsValid(state),
   120      dataExists: selectDataExists(state),
   121      dataErrors: dataErrors(state),
   122    }),
   123    {
   124      refreshNodes,
   125      refreshLiveness,
   126      refreshLocations,
   127    },
   128  )(NodeCanvasContainer));