TopBar.purs 8.93 KB
Newer Older
1 2 3
module Gargantext.Components.TopBar where

import Data.Foldable (intercalate)
4 5
import Reactix as R
import Reactix.DOM.HTML as H
6
import Toestand as T
7

8
import Gargantext.Prelude
9 10

import Gargantext.Components.Themes (themeSwitcher, defaultTheme, allThemes)
11
import Gargantext.Types (Handed(..), reverseHanded)
12
import Gargantext.Utils.Reactix as R2
13
import Gargantext.Components.GraphExplorer.ToggleButton as Toggle
14

15 16
here :: R2.Here
here = R2.here "Gargantext.Components.TopBar"
17

18
type TopBarProps = ( handed :: T.Box Handed, showTree :: T.Box Boolean )
19

20 21
topBar :: R2.Component TopBarProps
topBar = R.createElement topBarCpt
22 23

topBarCpt :: R.Component TopBarProps
24
topBarCpt = here.component "topBar" cpt
25
  where
26
    cpt { handed, showTree } children = do
27 28
      handed' <- T.useLive T.unequal handed

29
      pure $ H.div { className: "navbar navbar-expand-lg navbar-dark bg-dark"
30
                   , id: "dafixedtop"
31
                   , role: "navigation"
32 33 34 35 36 37 38 39 40 41 42 43 44
                   }
        [ H.div { className: "container-fluid" } $ reverseHanded handed' [
             -- NOTE: first (and only) entry in the sorted array should have the "ml-auto class"
             -- https://stackoverflow.com/questions/19733447/bootstrap-navbar-with-left-center-or-right-aligned-items
             -- In practice: only apply "ml-auto" to the last element of this list, if handed == LeftHanded
             logo
             , H.div { className: "collapse navbar-collapse" }
               [ H.ul { className: "navbar-nav " <> if handed' == LeftHanded then "ml-auto" else "" } $ reverseHanded handed'
               ([ divDropdownLeft {} []
                , handButton handed'
                , smiley
                , H.li { className: "nav-item" } [ themeSwitcher { theme: defaultTheme
                                                                 , themes: allThemes } [] ]
45
                , Toggle.treeToggleButton { state: showTree } []
46 47 48 49
                ] <> children)
               ]
             ]
        ]
50
          where
51 52 53 54 55
            handButton handed' = H.li { title: "If you are Left Handed you can change\n"
                                            <> "the interface by clicking on me. Click\n"
                                            <> "again to come back to previous state."
                                      , className: "nav-item"
                                      } [handedChooser { handed } []]
56

57 58 59 60 61 62
            smiley = H.li { title: "Hello! Looking for the tree ?\n"
                                <> "Just watch on the other side!\n"
                                <> "Click on the hand again to see it back."
                          , className : "nav-item"
                          }
                          [ H.a { className: "nav-link" } [H.span {className: "fa fa-question-circle-o"} [] ]]
63 64 65 66 67 68 69 70

                        {-, H.ul { title: "Dark Mode soon here"
                                , className : "nav navbar-nav"
                                } [ H.li {} [ H.a {} [ H.span {className : "fa fa-moon"}[]
                                                          ]
                                                ]
                                      ]
                              -}
71

72 73 74
            -- SB.searchBar {session, databases: allDatabases}


75 76 77 78
logo :: R.Element
logo =
  H.a { className, href: "#/" } [
    H.img { src, title, width: "30", height: "28" }
79 80
  ]
  where
81
    className = "navbar-brand logoSmall"
82
    src       = "images/logoSmall.png"
83
    title     = "Back home."
84 85


86 87 88
divDropdownLeft :: R2.Component ()
divDropdownLeft = R.createElement divDropdownLeftCpt
divDropdownLeftCpt :: R.Component ()
89
divDropdownLeftCpt = here.component "divDropdownLeft" cpt
90 91
  where
    cpt {} _ = do
92
      show <- T.useBox false
93

94
      pure $ H.li { className: "nav-item dropdown" } [
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
          menuButton { element: menuElement, show } []
        , menuElements { elements, show } []
        ]

    menuElement = LiNav { title : "About Gargantext"
                        , href  : "#"
                        , icon  : "fa fa-info-circle"
                        , text  : "Info" }

    elements = [
      [
        LiNav { title : "Quick start, tutorials and methodology"
              , href  : "https://iscpif.fr/gargantext/your-first-map/"
              , icon  : "fa fa-lightbulb-o"
              , text  : "Tutorials"
              }
      , LiNav { title : "Report bug here"
              , href  : "https://www.iscpif.fr/gargantext/feedback-and-bug-reports/"
113
              , icon  : "fa fa-bullhorn"
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
              , text  : "Feedback"
              }
      ]
      , -----------------------------------------------------------
      [ LiNav { title : "Chat"
              , href  : "https://chat.iscpif.fr/channel/gargantext"
              , icon  : "fa fa-rocket"
              , text  : "Chat"
              }
      , LiNav { title : "Forums"
              , href  : "https://discourse.iscpif.fr/c/gargantext"
              , icon  : "fa fa-weixin"
              , text  : "Forum"
              }
      ]
      ,------------------------------------------------------------
      [ LiNav { title : "Code documentation"
              , href  : "https://doc.gargantext.org"
132
              , icon  : "fa fa-book"
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
              , text  : "Source Code Documentation"
              }
      , LiNav { title : "API documentation"
              , href  : "https://v4.gargantext.org/swagger-ui"
              , icon  : "fa fa-code-fork"
              , text  : "API documentation"
              }
      , LiNav { title : "Source code"
              , href  : "https://gitlab.iscpif.fr/gargantext/haskell-gargantext"
              , icon  : "fa fa-code"
              , text  : "Source Code"
              }
      ]

      ,------------------------------------------------------------
      [ LiNav { title : "More about us (you)"
              , href  : "https://iscpif.fr"
150
              , icon  : "fa fa-question"
151 152 153 154 155 156 157
              , text  : "About"
              }
      ]
    ] -- ===========================================================

type MenuButtonProps = (
    element :: LiNav
158
  , show    :: T.Box Boolean
159 160 161 162
  )

menuButton :: R2.Component MenuButtonProps
menuButton = R.createElement menuButtonCpt
163
menuButtonCpt :: R.Component MenuButtonProps
164
menuButtonCpt = here.component "menuButton" cpt
165
  where
166
    cpt { element: LiNav { title, href, icon, text }, show } _ = do
167 168
      pure $ H.a { className: "dropdown-toggle navbar-text"
                -- , data: {toggle: "dropdown"}
169
                , title
170
                , on: { click: \_ -> T.modify_ not show }
171 172 173 174 175 176 177 178
                , role: "button" } [
          H.span { aria: {hidden : true}, className: icon } []
        , H.text (" " <> text)
        ]

-- | Menu in the sidebar, syntactic sugar
type MenuElementsProps = (
    elements :: Array (Array LiNav)
179
  , show     :: T.Box Boolean
180
  )
181

182 183
menuElements :: R2.Component MenuElementsProps
menuElements = R.createElement menuElementsCpt
184
menuElementsCpt :: R.Component MenuElementsProps
185
menuElementsCpt = here.component "menuElements" cpt
186
  where
187 188 189 190 191 192 193 194 195 196 197
    cpt { elements, show } _ = do
      show' <- T.useLive T.unequal show

      pure $ if show' then
               H.ul { className: "dropdown-menu"
                    , on: { click: \_ -> T.write_ false show }
                    , style: { display: "block" } } $ intercalate divider $ map (map liNav) elements
             else
               H.div {} []
    divider :: Array R.Element
    divider = [H.li {className: "dropdown-divider"} []]
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218

-- | surgar for target : "blank"
--data LiNav_ = LiNav_ { title  :: String
--                     , href   :: String
--                     , icon   :: String
--                     , text   :: String
--                     , target :: String
--                     }

data LiNav = LiNav { title :: String
                   , href  :: String
                   , icon  :: String
                   , text  :: String
                   }

liNav :: LiNav -> R.Element
liNav (LiNav { title : title'
             , href  : href'
             , icon  : icon'
             , text  : text'
             }
219 220 221 222 223 224 225
      ) = H.li { className: "dropdown-item" } [
            H.a { tabIndex: (-1)
                , target: "blank"
                , title: title'
                , href: href'
                } [ H.span { className: icon' } []
                  , H.text $ " " <> text'
226
                  ]
227
            ]
228 229 230


type HandedChooserProps = (
231
  handed :: T.Box Handed
232 233
  )

234 235
handedChooser :: R2.Component HandedChooserProps
handedChooser = R.createElement handedChooserCpt
236 237

handedChooserCpt :: R.Component HandedChooserProps
238
handedChooserCpt = here.component "handedChooser" cpt
239 240
  where
    cpt { handed } _ = do
241 242
      handed' <- T.useLive T.unequal handed

243
      pure $ H.a { className: "nav-link" } [
244
        H.span { className: handedClass handed'
245
               , on: { click: onClick handed } } []
246 247
        ]

248 249
    handedClass LeftHanded = "fa fa-hand-o-left"
    handedClass RightHanded = "fa fa-hand-o-right"
250

251
    onClick handed = T.modify_ (\h -> case h of
252
      LeftHanded  -> RightHanded
253
      RightHanded -> LeftHanded) handed