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

     1  // Copyright 2018 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 React from "react";
    10  import { Dispatch, Action } from "redux";
    11  import { connect } from "react-redux";
    12  import { Link } from "react-router-dom";
    13  import classNames from "classnames";
    14  
    15  import { allNodesHaveLocality } from "src/util/localities";
    16  import {
    17    instructionsBoxCollapsedSelector, setInstructionsBoxCollapsed,
    18  } from "src/redux/alerts";
    19  import { AdminUIState } from "src/redux/state";
    20  import { nodeStatusesSelector } from "src/redux/nodes";
    21  import { LocalityTier } from "src/redux/localities";
    22  import * as docsURL from "src/util/docs";
    23  import nodeMapScreenshot from "assets/nodeMapSteps/3-seeMap.png";
    24  import questionMap from "assets/questionMap.svg";
    25  import "./instructionsBox.styl";
    26  
    27  interface InstructionsBoxProps {
    28    allNodesHaveLocality: boolean;
    29    collapsed: boolean;
    30    expand: () => void;
    31    collapse: () => void;
    32  }
    33  
    34  class InstructionsBox extends React.Component<InstructionsBoxProps> {
    35    renderExpanded() {
    36      const firstTodoDone = this.props.allNodesHaveLocality;
    37  
    38      return (
    39        <div className="instructions-box instructions-box--expanded">
    40          <div className="instructions-box-top-bar">
    41            <div>
    42              <span className="instructions-box-top-bar__see_nodes">
    43                See your nodes on a map!
    44              </span>{" "}
    45              <a
    46                href={docsURL.enableNodeMap}
    47                target="_blank"
    48                className="instructions-box-top-bar__setup_link"
    49              >
    50                Follow our configuration guide
    51              </a>
    52            </div>
    53            <span
    54              className="instructions-box-top-bar__x-out"
    55              onClick={this.props.collapse}
    56            >
    57              ✕
    58            </span>
    59          </div>
    60          <div className="instructions-box-content">
    61            <ol>
    62              <li
    63                className={classNames(
    64                  "instructions-box-content__todo-item",
    65                  { "instructions-box-content__todo-item--done": firstTodoDone },
    66                )}
    67              >
    68                { firstTodoDone ? (<div className="instructions-box-content__todo-check">{"\u2714"}</div>) : null }
    69                Ensure every node in your cluster was started with a <code>--locality</code> flag.
    70                (<Link to={"/reports/localities"}>See current locality tree</Link>)
    71              </li>
    72              <li>
    73                Add locations to the <code>system.locations</code> table corresponding to
    74                your locality flags.
    75              </li>
    76            </ol>
    77            <div className="instructions-box-content__screenshot">
    78              <img src={nodeMapScreenshot} />
    79            </div>
    80          </div>
    81        </div>
    82      );
    83    }
    84  
    85    renderCollapsed() {
    86      return (
    87        <div
    88          className="instructions-box instructions-box--collapsed"
    89          onClick={this.props.expand}
    90        >
    91          <img src={questionMap} />
    92        </div>
    93      );
    94    }
    95  
    96    render() {
    97      if (this.props.collapsed) {
    98        return this.renderCollapsed();
    99      } else {
   100        return this.renderExpanded();
   101      }
   102    }
   103  }
   104  
   105  function mapStateToProps(state: AdminUIState) {
   106    return {
   107      collapsed: instructionsBoxCollapsedSelector(state),
   108      allNodesHaveLocality: allNodesHaveLocality(nodeStatusesSelector(state)),
   109    };
   110  }
   111  
   112  function mapDispatchToProps(dispatch: Dispatch<Action, AdminUIState>) {
   113    return {
   114      expand: () => dispatch(setInstructionsBoxCollapsed(false)),
   115      collapse: () => dispatch(setInstructionsBoxCollapsed(true)),
   116    };
   117  }
   118  
   119  export default connect(mapStateToProps, mapDispatchToProps)(InstructionsBox);
   120  
   121  // Helper functions.
   122  
   123  /**
   124   * showInstructionBox decides whether to show the instructionBox.
   125   */
   126  export function showInstructionsBox(showMap: boolean, tiers: LocalityTier[]): boolean {
   127    const atTopLevel = tiers.length === 0;
   128    return atTopLevel && !showMap;
   129  }