github.com/tilt-dev/tilt@v0.36.0/web/src/HeaderBar.tsx (about)

     1  import React from "react"
     2  import { Link } from "react-router-dom"
     3  import styled from "styled-components"
     4  import { ReactComponent as DetailViewSvg } from "./assets/svg/detail-view-icon.svg"
     5  import { ReactComponent as LogoWordmarkSvg } from "./assets/svg/logo-wordmark.svg"
     6  import { ReactComponent as TableViewSvg } from "./assets/svg/table-view-icon.svg"
     7  import { CustomNav } from "./CustomNav"
     8  import { GlobalNav, GlobalNavProps } from "./GlobalNav"
     9  import { usePathBuilder } from "./PathBuilder"
    10  import {
    11    AllResourceStatusSummary,
    12    ResourceStatusSummaryRoot,
    13  } from "./ResourceStatusSummary"
    14  import { useSnapshotAction } from "./snapshot"
    15  import { SnapshotBar } from "./SnapshotBar"
    16  import { AnimDuration, Color, Font, FontSize, SizeUnit } from "./style-helpers"
    17  import { showUpdate } from "./UpdateDialog"
    18  
    19  const HeaderBarRoot = styled.nav`
    20    display: flex;
    21    align-items: center;
    22    padding-left: ${SizeUnit(1)};
    23    background-color: ${Color.gray10};
    24  
    25    ${ResourceStatusSummaryRoot} {
    26      justify-self: center;
    27      flex-grow: 1;
    28      justify-content: center;
    29    }
    30  `
    31  
    32  const Logo = styled(LogoWordmarkSvg)`
    33    justify-self: flex-start;
    34    & .fillStd {
    35      transition: fill ${AnimDuration.short} ease;
    36      fill: ${Color.grayLightest};
    37    }
    38    &:hover .fillStd,
    39    &.isSelected .fillStd {
    40      fill: ${Color.gray70};
    41    }
    42    display: block;
    43  `
    44  
    45  const HeaderDivider = styled.div`
    46    border-left: 1px solid ${Color.gray40};
    47    height: ${SizeUnit(0.7)};
    48    margin: ${SizeUnit(0.5)};
    49  `
    50  
    51  const ViewLinkText = styled.span`
    52    bottom: 0;
    53    color: ${Color.gray70};
    54    font-family: ${Font.monospace};
    55    font-size: ${FontSize.smallest};
    56    opacity: 0;
    57    position: absolute;
    58    transition: opacity ${AnimDuration.default} ease;
    59    white-space: nowrap;
    60    width: 100%;
    61  `
    62  
    63  const viewLinkIconMixin = `
    64    display: flex;
    65    transition: fill ${AnimDuration.default} ease;
    66    height: 100%;
    67    padding: ${SizeUnit(0.65)} 0;
    68    fill: ${Color.gray50};
    69  
    70    &.isCurrent {
    71      fill: ${Color.gray70};
    72    }
    73  `
    74  
    75  const TableViewIcon = styled(TableViewSvg)`
    76    ${viewLinkIconMixin}
    77    /* "Hack" to right-align text */
    78    padding-left: ${SizeUnit(0.5)};
    79  `
    80  
    81  const DetailViewIcon = styled(DetailViewSvg)`
    82    ${viewLinkIconMixin}
    83  `
    84  
    85  const ViewLink = styled(Link)`
    86    position: relative;
    87  
    88    &:is(:hover, :focus, :active) {
    89      ${ViewLinkText} {
    90        opacity: 1;
    91      }
    92  
    93      ${TableViewIcon}, ${DetailViewIcon} {
    94        fill: ${Color.blue};
    95      }
    96    }
    97  `
    98  
    99  const ViewLinkSection = styled.div`
   100    align-items: center;
   101    display: flex;
   102    margin-left: ${SizeUnit(1)};
   103    margin-right: ${SizeUnit(1)};
   104  `
   105  
   106  export enum HeaderBarPage {
   107    Grid = "grid",
   108    Detail = "resource-detail",
   109  }
   110  
   111  type HeaderBarProps = {
   112    view: Proto.webviewView
   113    currentPage: HeaderBarPage
   114    isSocketConnected: boolean
   115  }
   116  
   117  export default function HeaderBar({
   118    view,
   119    currentPage,
   120    isSocketConnected,
   121  }: HeaderBarProps) {
   122    let isSnapshot = usePathBuilder().isSnapshot()
   123    let snapshot = useSnapshotAction()
   124    let session = view?.uiSession?.status
   125    let runningBuild = session?.runningTiltBuild
   126    let suggestedVersion = session?.suggestedTiltVersion
   127    let resources = view?.uiResources || []
   128  
   129    let globalNavProps: GlobalNavProps = {
   130      isSnapshot,
   131      snapshot,
   132      showUpdate: showUpdate(view),
   133      suggestedVersion,
   134      runningBuild,
   135      clusterConnections: view.clusters,
   136    }
   137  
   138    const pb = usePathBuilder()
   139  
   140    const tableViewLinkClass =
   141      currentPage === HeaderBarPage.Grid ? "isCurrent" : ""
   142    const detailViewLinkClass =
   143      currentPage === HeaderBarPage.Detail ? "isCurrent" : ""
   144  
   145    // TODO (lizz): Consider refactoring nav to use more semantic pattern of ul + li
   146    return (
   147      <>
   148        <SnapshotBar className={`is-${currentPage}`} />
   149        <HeaderBarRoot aria-label="Dashboard menu">
   150          <Link to="/overview" aria-label="Tilt home">
   151            <Logo width="57px" />
   152          </Link>
   153          <ViewLinkSection>
   154            <ViewLink
   155              to="/overview"
   156              aria-label="Table view"
   157              aria-current={currentPage == HeaderBarPage.Grid}
   158            >
   159              <TableViewIcon className={tableViewLinkClass} role="presentation" />
   160              <ViewLinkText>Table</ViewLinkText>
   161            </ViewLink>
   162            <HeaderDivider role="presentation" />
   163            <ViewLink
   164              to={pb.encpath`/r/(all)/overview`}
   165              aria-label="Detail view"
   166              aria-current={currentPage == HeaderBarPage.Detail}
   167            >
   168              <DetailViewIcon
   169                className={detailViewLinkClass}
   170                role="presentation"
   171              />
   172              <ViewLinkText>Detail</ViewLinkText>
   173            </ViewLink>
   174          </ViewLinkSection>
   175          <AllResourceStatusSummary
   176            displayText="Resources"
   177            labelText="Status summary for all resources"
   178            resources={resources}
   179            isSocketConnected={isSocketConnected}
   180          />
   181          <CustomNav view={view} />
   182          <GlobalNav {...globalNavProps} />
   183        </HeaderBarRoot>
   184      </>
   185    )
   186  }