github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/web/elm/src/Dashboard/Footer.elm (about)

     1  module Dashboard.Footer exposing (handleDelivery, view)
     2  
     3  import Assets
     4  import Concourse.Cli as Cli
     5  import Concourse.PipelineStatus as PipelineStatus exposing (PipelineStatus(..))
     6  import Dashboard.Group.Models exposing (Pipeline)
     7  import Dashboard.Models exposing (Dropdown(..), FooterModel)
     8  import Dashboard.Styles as Styles
     9  import Dict exposing (Dict)
    10  import HoverState
    11  import Html exposing (Html)
    12  import Html.Attributes exposing (attribute, class, download, href, id, style)
    13  import Html.Events exposing (onMouseEnter, onMouseLeave)
    14  import Keyboard
    15  import Message.Effects as Effects
    16  import Message.Message exposing (DomID(..), Message(..))
    17  import Message.Subscription exposing (Delivery(..), Interval(..))
    18  import Routes
    19  import ScreenSize
    20  import Views.Icon as Icon
    21  import Views.Toggle as Toggle
    22  
    23  
    24  handleDelivery :
    25      Delivery
    26      -> ( FooterModel r, List Effects.Effect )
    27      -> ( FooterModel r, List Effects.Effect )
    28  handleDelivery delivery ( model, effects ) =
    29      case delivery of
    30          KeyDown keyEvent ->
    31              case keyEvent.code of
    32                  -- '/' key
    33                  Keyboard.Slash ->
    34                      if keyEvent.shiftKey && model.dropdown == Hidden then
    35                          ( { model
    36                              | showHelp =
    37                                  if
    38                                      model.pipelines
    39                                          |> Maybe.withDefault Dict.empty
    40                                          |> Dict.values
    41                                          |> List.all List.isEmpty
    42                                  then
    43                                      False
    44  
    45                                  else
    46                                      not model.showHelp
    47                            }
    48                          , effects
    49                          )
    50  
    51                      else
    52                          ( model, effects )
    53  
    54                  _ ->
    55                      ( { model | hideFooter = False, hideFooterCounter = 0 }
    56                      , effects
    57                      )
    58  
    59          Moused _ ->
    60              ( { model | hideFooter = False, hideFooterCounter = 0 }, effects )
    61  
    62          ClockTicked OneSecond _ ->
    63              ( if model.hideFooterCounter > 4 then
    64                  { model | hideFooter = True }
    65  
    66                else
    67                  { model | hideFooterCounter = model.hideFooterCounter + 1 }
    68              , effects
    69              )
    70  
    71          _ ->
    72              ( model, effects )
    73  
    74  
    75  view :
    76      { a
    77          | hovered : HoverState.HoverState
    78          , screenSize : ScreenSize.ScreenSize
    79          , version : String
    80      }
    81      -> FooterModel r
    82      -> Html Message
    83  view session model =
    84      if model.showHelp then
    85          keyboardHelp
    86  
    87      else if not model.hideFooter then
    88          infoBar session model
    89  
    90      else
    91          Html.text ""
    92  
    93  
    94  keyboardHelp : Html Message
    95  keyboardHelp =
    96      Html.div
    97          [ class "keyboard-help", id "keyboard-help" ]
    98          [ Html.div
    99              [ class "help-title" ]
   100              [ Html.text "keyboard shortcuts" ]
   101          , Html.div
   102              [ class "help-line" ]
   103              [ Html.div
   104                  [ class "keys" ]
   105                  [ Html.span
   106                      [ class "key" ]
   107                      [ Html.text "/" ]
   108                  ]
   109              , Html.text "search"
   110              ]
   111          , Html.div
   112              [ class "help-line" ]
   113              [ Html.div
   114                  [ class "keys" ]
   115                  [ Html.span
   116                      [ class "key" ]
   117                      [ Html.text "?" ]
   118                  ]
   119              , Html.text "hide/show help"
   120              ]
   121          ]
   122  
   123  
   124  infoBar :
   125      { a
   126          | hovered : HoverState.HoverState
   127          , screenSize : ScreenSize.ScreenSize
   128          , version : String
   129      }
   130      ->
   131          { b
   132              | highDensity : Bool
   133              , dashboardView : Routes.DashboardView
   134              , pipelines : Maybe (Dict String (List Pipeline))
   135          }
   136      -> Html Message
   137  infoBar session model =
   138      Html.div
   139          (id "dashboard-info"
   140              :: Styles.infoBar
   141                  { hideLegend = hideLegend model
   142                  , screenSize = session.screenSize
   143                  }
   144          )
   145          [ legend session model
   146          , concourseInfo session
   147          ]
   148  
   149  
   150  legend :
   151      { a | screenSize : ScreenSize.ScreenSize }
   152      ->
   153          { b
   154              | pipelines : Maybe (Dict String (List Pipeline))
   155              , highDensity : Bool
   156              , dashboardView : Routes.DashboardView
   157          }
   158      -> Html Message
   159  legend session model =
   160      if hideLegend model then
   161          Html.text ""
   162  
   163      else
   164          Html.div
   165              (id "legend" :: Styles.legend)
   166          <|
   167              List.map legendItem
   168                  [ PipelineStatusPending False
   169                  , PipelineStatusPaused
   170                  ]
   171                  ++ Html.div
   172                      Styles.legendItem
   173                      [ Icon.icon
   174                          { sizePx = 20
   175                          , image = Assets.RunningLegend
   176                          }
   177                          []
   178                      , Html.div [ style "width" "10px" ] []
   179                      , Html.text "running"
   180                      ]
   181                  :: List.map legendItem
   182                      [ PipelineStatusFailed PipelineStatus.Running
   183                      , PipelineStatusErrored PipelineStatus.Running
   184                      , PipelineStatusAborted PipelineStatus.Running
   185                      , PipelineStatusSucceeded PipelineStatus.Running
   186                      ]
   187                  ++ legendSeparator session.screenSize
   188                  ++ [ toggleView model ]
   189  
   190  
   191  concourseInfo :
   192      { a | hovered : HoverState.HoverState, version : String }
   193      -> Html Message
   194  concourseInfo { hovered, version } =
   195      Html.div (id "concourse-info" :: Styles.info)
   196          [ Html.div
   197              Styles.infoItem
   198              [ Html.text <| "version: v" ++ version ]
   199          , Html.div Styles.infoItem <|
   200              [ Html.span
   201                  [ style "margin-right" "10px" ]
   202                  [ Html.text "cli: " ]
   203              ]
   204                  ++ List.map (cliIcon hovered) Cli.clis
   205          ]
   206  
   207  
   208  hideLegend : { a | pipelines : Maybe (Dict String (List Pipeline)) } -> Bool
   209  hideLegend { pipelines } =
   210      pipelines
   211          |> Maybe.withDefault Dict.empty
   212          |> Dict.values
   213          |> List.all List.isEmpty
   214  
   215  
   216  legendItem : PipelineStatus -> Html Message
   217  legendItem status =
   218      Html.div
   219          Styles.legendItem
   220          [ Icon.icon
   221              { sizePx = 20, image = Assets.PipelineStatusIcon status }
   222              Styles.pipelineStatusIcon
   223          , Html.div [ style "width" "10px" ] []
   224          , Html.text <| PipelineStatus.show status
   225          ]
   226  
   227  
   228  toggleView :
   229      { r
   230          | highDensity : Bool
   231          , dashboardView : Routes.DashboardView
   232      }
   233      -> Html Message
   234  toggleView { highDensity, dashboardView } =
   235      Toggle.toggleSwitch
   236          { ariaLabel = "Toggle high-density view"
   237          , hrefRoute =
   238              Routes.Dashboard
   239                  { searchType =
   240                      if highDensity then
   241                          Routes.Normal ""
   242  
   243                      else
   244                          Routes.HighDensity
   245                  , dashboardView = dashboardView
   246                  }
   247          , text = "high-density"
   248          , textDirection = Toggle.Right
   249          , on = highDensity
   250          , styles = Styles.highDensityToggle
   251          }
   252  
   253  
   254  legendSeparator : ScreenSize.ScreenSize -> List (Html Message)
   255  legendSeparator screenSize =
   256      case screenSize of
   257          ScreenSize.Mobile ->
   258              []
   259  
   260          ScreenSize.Desktop ->
   261              [ Html.div Styles.legendSeparator [ Html.text "|" ] ]
   262  
   263          ScreenSize.BigDesktop ->
   264              [ Html.div Styles.legendSeparator [ Html.text "|" ] ]
   265  
   266  
   267  cliIcon : HoverState.HoverState -> Cli.Cli -> Html Message
   268  cliIcon hovered cli =
   269      Html.a
   270          ([ href <| Cli.downloadUrl cli
   271           , attribute "aria-label" <| Cli.label cli
   272           , id <| "cli-" ++ Cli.id cli
   273           , onMouseEnter <| Hover <| Just <| FooterCliIcon cli
   274           , onMouseLeave <| Hover Nothing
   275           , download ""
   276           ]
   277              ++ Styles.infoCliIcon
   278                  { hovered = HoverState.isHovered (FooterCliIcon cli) hovered
   279                  , cli = cli
   280                  }
   281          )
   282          []