github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ui/src/views/app/components/layoutSidebar/index.tsx (about) 1 // Copyright 2018 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 import React from "react"; 12 import { connect } from "react-redux"; 13 import { Link, withRouter, RouteComponentProps } from "react-router-dom"; 14 15 import { SideNavigation } from "src/components"; 16 import "./navigation-bar.styl"; 17 18 interface RouteParam { 19 path: string; 20 text: string; 21 activeFor: string[]; 22 // ignoreFor allows exclude specific paths from been recognized as active 23 // even if path is matched with activeFor paths. 24 ignoreFor?: string[]; 25 } 26 27 /** 28 * Sidebar represents the static navigation sidebar available on all pages. It 29 * displays a number of graphic icons representing available pages; the icon of 30 * the page which is currently active will be highlighted. 31 */ 32 class Sidebar extends React.Component<RouteComponentProps> { 33 readonly routes: RouteParam[] = [ 34 { path: "/overview", text: "Overview", activeFor: ["/node"] }, 35 { path: "/metrics", text: "Metrics", activeFor: [] }, 36 { path: "/databases", text: "Databases", activeFor: ["/database"] }, 37 { path: "/statements", text: "Statements", activeFor: ["/statement"] }, 38 { path: "/reports/network", text: "Network Latency", activeFor: ["/reports/network"] }, 39 { path: "/jobs", text: "Jobs", activeFor: [] }, 40 { 41 path: "/debug", 42 text: "Advanced Debug", 43 activeFor: ["/reports", "/data-distribution", "/raft"], 44 ignoreFor: ["/reports/network"], 45 }, 46 ]; 47 48 isActiveNavigationItem = (path: string): boolean => { 49 const { pathname } = this.props.location; 50 const { activeFor, ignoreFor = []} = this.routes.find(route => route.path === path); 51 return [...activeFor, path].some(p => { 52 const isMatchedToIgnoredPaths = ignoreFor.some(ignorePath => pathname.startsWith(ignorePath)); 53 const isMatchedToActiveFor = pathname.startsWith(p); 54 return isMatchedToActiveFor && !isMatchedToIgnoredPaths; 55 }); 56 } 57 58 render() { 59 const navigationItems = this.routes.map(({ path, text }, idx) => ( 60 <SideNavigation.Item 61 isActive={this.isActiveNavigationItem(path)} 62 key={idx} 63 > 64 <Link to={path}>{text}</Link> 65 </SideNavigation.Item> 66 )); 67 return ( 68 <SideNavigation> 69 {navigationItems} 70 </SideNavigation> 71 ); 72 } 73 } 74 75 export default withRouter(connect(null, null)(Sidebar));