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 }