Home.purs 18.9 KB
Newer Older
1
module Gargantext.Components.Nodes.Home where
2

3
import Data.Array as Array
Alexandre Delanoë's avatar
Alexandre Delanoë committed
4
import DOM.Simple.Console (log)
5
import Data.Tuple (fst, snd)
6
import Data.Maybe (Maybe(..))
7
import Data.Newtype (class Newtype)
8
import Data.Sequence as Seq
9
import Effect (Effect)
10 11 12 13
import Gargantext.Components.Data.Landing (BlockText(..), BlockTexts(..), Button(..), LandingData(..))
import Gargantext.Components.Lang (LandingLang(..))
import Gargantext.Components.Lang.Landing.EnUS as En
import Gargantext.Components.Lang.Landing.FrFR as Fr
14
import Gargantext.Components.Nodes.Home.Public (renderPublic)
Alexandre Delanoë's avatar
Alexandre Delanoë committed
15
import Gargantext.Ends (Backend(..))
16
import Gargantext.License (license)
Alexandre Delanoë's avatar
Alexandre Delanoë committed
17
import Gargantext.Prelude -- (Unit, map, pure, unit, void, ($), (<>), (*>))
18
import Gargantext.Sessions (Sessions(..), unSessions)
Alexandre Delanoë's avatar
Alexandre Delanoë committed
19
import Gargantext.Sessions as Sessions
20
import Gargantext.Utils.Reactix as R2
Alexandre Delanoë's avatar
Alexandre Delanoë committed
21 22 23
import Reactix as R
import Reactix.DOM.HTML as H
import Routing.Hash (setHash)
24 25

thisModule = "Gargantext.Components.Nodes.Home"
26

27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
type Props = ()

newtype State = State
  { userName :: String
  , password :: String
  }

derive instance newtypeState :: Newtype State _

initialState :: State
initialState = State { userName : "", password : "" }

data Action
  = Documentation
  | Enter
  | Login
  | SignUp

performAction :: Action -> Effect Unit
performAction Documentation = pure unit
performAction Enter = void $ setHash "/search"
performAction Login = void $ setHash "/login"
performAction SignUp = pure unit

51 52 53
langLandingData :: LandingLang -> LandingData
langLandingData LL_FR = Fr.landingData
langLandingData LL_EN = En.landingData
54 55 56

------------------------------------------------------------------------

57 58 59 60 61 62 63 64 65
type HomeProps = ( lang      :: LandingLang
                 , publicBackend :: Backend
                 , backend   :: R.State (Maybe Backend)
                 , sessions  :: R2.Reductor Sessions Sessions.Action
                 , visible  :: R.State Boolean
                 )

homeLayout :: Record HomeProps -> R.Element
homeLayout props = R.createElement homeLayoutCpt props []
66

67
homeLayoutCpt :: R.Component HomeProps
68
homeLayoutCpt = R.hooksComponentWithModule thisModule "homeLayout" cpt
69
  where
70 71
    cpt {lang, backend, publicBackend, sessions, visible} _ = do
      let landingData = langLandingData lang
72
      pure $ H.span {}
73
           [ H.div { className: "home-title container1" } [ jumboTitle landingData ]
74
           , H.div { className: "home-research-form container1" } [] -- TODO put research form
75 76

           , if Array.length (unSessions $ fst sessions) > 0 
77
                then tutorial
78
                else joinButton
79

80 81 82 83 84 85
           , H.div { className: "home-public container1" } [ renderPublic { backend
                                                                          , publicBackend
                                                                          , sessions
                                                                          , visible
                                                                          }
                                                           ]
Alexandre Delanoë's avatar
Alexandre Delanoë committed
86

Alexandre Delanoë's avatar
Alexandre Delanoë committed
87
           , H.div {className:"col-12 d-flex justify-content-center"}
Alexandre Delanoë's avatar
Alexandre Delanoë committed
88 89 90 91 92
                   [ H.h1 {} [ -- H.span {className: "fa fa-star-o"} []
                              H.text ""
                             ]
                   ]
           , H.div { className: "home-landing-data container1" } [ blocksRandomText' landingData ]
93 94
           , license
           ]
Alexandre Delanoë's avatar
Alexandre Delanoë committed
95
      where
96
        tutorial =  H.div {className: "mx-auto container"}
97 98 99
                 $  [ H.h1 {} [H.text "Welcome!"]
                    , H.h2 {} [H.text "For easy start, just watch the tutorials"]
                    ]
100
                 <> [ H.div { className: "" } summary ]
101 102 103
                 <> tutos

        summary :: Array R.Element
104 105 106 107 108 109
        summary = [ H.h3 {} [ H.text "Tutorial summary"]
                            , H.ol {} [ H.div {className: "alert alert-info"}
                                    [ H.li {} [ H.h4 {} [H.text "How to start (beginner users) ?"]
                                              , H.ol {} (toSummary start_tutos)
                                              ]
                                    ]
Alexandre Delanoë's avatar
Alexandre Delanoë committed
110
{-
111 112 113 114 115 116 117 118 119 120 121
                            , H.div {className: "alert alert-warning"}
                                    [ H.li {} [ H.h4 {} [H.text "How to play (advanced users)?"]
                                              , H.ol {} (toSummary play_tutos)
                                              ]
                                    ]

                            , H.div {className: "alert alert-danger"}
                                    [ H.li {} [ H.h4 {} [H.text "How to master (expert users)?"]
                                              , H.ol {} (toSummary expert_tutos)
                                              ]
                                    ]
Alexandre Delanoë's avatar
Alexandre Delanoë committed
122
                            -}
123 124 125
                            ]
                  ]
            where
126
              toSummary x = map (\(Tuto x) -> H.li {} [H.a {href : "#" <> x.id} [H.text x.title]]) x
127 128 129

        tutos :: Array R.Element
        tutos = [ H.h3 {} [H.text "Tutorial resources"]
130
                , H.div {className : ""}
131
                        $ [ H.h4 {} [H.text "How to start ?"] ]
132
                        <> map (\ (Tuto x) -> H.div { className : "alert alert-info", id : x.id}
133 134 135 136 137
                                            [ video x.id
                                            , H.h4 {} [H.text x.title]
                                            , H.p  {} [H.text x.text ]
                                            ]
                         ) start_tutos
Alexandre Delanoë's avatar
Alexandre Delanoë committed
138
{-
139
                , H.div {className : ""}
140
                        $ [H.h4 {} [H.text "How to play ?"]]
141
                        <> map (\ (Tuto x) -> H.div { className : "alert alert-warning", id : x.id}
142 143 144 145 146
                                                    [ video x.id
                                                    , H.h4 {} [H.text x.title]
                                                    , H.p  {} [H.text x.text]
                                                    ]
                               ) play_tutos
147 148 149 150 151 152 153 154
                , H.div {className : ""}
                        $ [H.h4 {} [H.text "How to master ?"]]
                        <> map (\ (Tuto x) -> H.div { className : "alert alert-danger", id : x.id}
                                                    [ video x.id
                                                    , H.h4 {} [H.text x.title]
                                                    , H.p  {} [H.text x.text]
                                                    ]
                               ) expert_tutos
Alexandre Delanoë's avatar
Alexandre Delanoë committed
155 156
                               -} 
               ]
157 158 159

        start_tutos :: Array Tuto
        start_tutos = [ Tuto { title : "The tree is your friend"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
160
                            , id    : "0_tree.ogv"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
161
                            , text  : "The tree enables you to control all your actions. The Tree has typed nodes. Each node has some attributes and some methods which depend on its type. This specific ergonomy helps the memorization of all the complexity of the GarganTexts' features: hence you do not need to remember all the documentation! Just remember these simple axioms, the Tree is built with parent-children relations of nodes which have specific attributes and methods. To get its methods and attributes, just click on the wheel near its name (for this feature, see advanced tutorial: how to play with GarganText)."
162
                          }
163
                     {-,  Tuto { title : "Edit your profile"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
164
                            , id    : "0_edit.ogv"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
165
                            , text  : "At the root of the tree, there is your user node, parent of all others nodes. Your profile is what others users will see or search for to reach you or to watch/follow your work. If you delete it you remove all your data from the specified instance, clear and simple."
166
                            }
167
                     -}
168
                     , Tuto { title : "Discover the nodes of the tree"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
169
                            , id    : "0_nodes.ogv"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
170
                            , text  : "Under your user node you have 3 main nodes: private, shared and public nodes. Each node has its specific attributes and methods! Under private node, all your work is private only. Under shared folder you can create teams to invite your partners, students or colleagues. Under public node, you can publish your work with the world: hello word!"
171
                            }
Alexandre Delanoë's avatar
Alexandre Delanoë committed
172
{-
173
                     , Tuto { title : "Read a corpus"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
174
                            , id    : "video_tutorial.mp4#t=43,79"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
175
                            , text  : "Each fresh corpus node has 4 children only: docs, list, board, graph. The docs node enable you to manage your documents and rate it. The list node let the user to manage its ngrams. The board node sum up your analysis with the main charts you made with your ngrams. The graph node let you explore your data in a new way. Others new type of nodes are coming such as Phylo node..."
176 177
                            }
                     , Tuto { title : "Manage your ngrams"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
178
                            , id    : "video_tutorial.mp4#t=80,214"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
179
                            , text  : "By default, 4 types of ngrams are created: Terms extracted from text fields such as title or abstract, Institutes are extracted from the Institute field of the metadata, Sources, Authors. In that tutorial, you will learn how to change the status of ngrams, group it or create new categories. Remember you need to save your work with the sycn button. Then the charts are updated after each sync. Your work is either synchronous or asynchronous: you can save locally your data, disconnect your device and sync when your Internet connection is back."
180 181
                            }
                     , Tuto { title : "Watch with the board"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
182
                            , id    : "video_tutorial.mp4#t=215,237"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
183
                            , text  : "Build your own watchboard! Easy. All your list enable you to have charts to follow the evolution of your corpus."
184 185
                            }
                     , Tuto { title : "Explore with the graph"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
186
                            , id    : "video_tutorial.mp4#t=238,293"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
187
                            , text  : "With the map terms you have selected already, the graph is built. 3 main panels can be hidden or shown to give you more visual space: tree, controls, side panel. The side panel shows the legend, the selected data and the community you are watching. You can link your corpus with a community (check nodes methods to do this)."
188 189 190
                            }

                     , Tuto { title : "Edit ngrams in your documents"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
191
                            , id    : "video_tutorial.mp4#t=294,312"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
192
                            , text  : "All selected ngrams can be updated in the document and they are autmatically updated in the lists."
193
                            }
Alexandre Delanoë's avatar
Alexandre Delanoë committed
194
                            -}
195 196 197
                     ]

        play_tutos :: Array Tuto
Alexandre Delanoë's avatar
Alexandre Delanoë committed
198 199
        play_tutos = []{- Tuto { title : "Again the tree is your friend"
                            , id    : "video_tutorial_1.mp4#t=,46"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
200
                            , text  : "At the right of each node, its wheel shows its attributes or enables the execution of its methods. Each type of node has different attributes and methods to help user in an ergonomic way."
201 202
                          }
                      , Tuto { title : "Build your analysis"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
203
                             , id    : "video_tutorial_1.mp4#t=47,146"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
204 205
                             , text  : "To build your analysis you need to create a corpus. Suppose you want to create it in your private folder in this tutorial. Use the wheel to execute any function on the corpus node in the tree. You can search the local database instance, the web or through apis connected to public databases. It becomes easy to add many documents to your dynamic corpus."
                            }
206

Alexandre Delanoë's avatar
Alexandre Delanoë committed
207
                      , Tuto { title : "Add documents with files and download your data"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
208
                            , id    : "video_tutorial_1.mp4#t=157,166"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
209
                            , text  : "You can add CSV files from Gargantext V3 legacy version: in your previous account, export your corpus and download it on your device. Then, upload it to v4 as CSV file."
210 211 212
                          }

                      , Tuto { title : "Move your corpus elsewhere in the tree"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
213
                            , id    : "video_tutorial_1.mp4#t=167,175"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
214
                            , text  : "Each node can be moved with this function. Move it in your team to share it. Remove it to unshare it. Some nodes can not be moved, it depends on the types methods."
215 216 217
                          }

                      , Tuto { title : "Rename your corpus"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
218
                            , id    : "video_tutorial_1.mp4#t=145,160"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
219
                            , text  : "Some nodes can be renamed, most of them. But you can not rename your User Node which is the root of the tree."
220 221 222
                          }

                      , Tuto { title : "Delete your corpus"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
223
                            , id    : "video_tutorial_1.mp4#t=179,182"
224 225 226 227
                            , text  : "Each node can be deleted with its children."
                          }

                      ]
Alexandre Delanoë's avatar
Alexandre Delanoë committed
228
                      --}
229

230
        expert_tutos :: Array Tuto
Alexandre Delanoë's avatar
Alexandre Delanoë committed
231 232
        expert_tutos = [] {- Tuto { title : "Share with a team and send invitations"
                              , id    : "video_tutorial_2.mp4#t=,46"
233 234
                              , text  : "[Link to update]"
                          }
235 236

                       , Tuto { title : "Multi instance connections"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
237
                              , id    : "video_tutorial_2.mp4#t=,46"
238 239 240 241
                              , text  : "[Link to update]"
                          }

                       , Tuto { title : "Freeze a graph"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
242
                              , id    : "video_tutorial_2.mp4#t=,46"
243 244 245 246
                              , text  : "[Link to update]"
                          }

                       , Tuto { title : "Publish"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
247
                              , id    : "video_tutorial_2.mp4#t=,46"
248 249 250 251
                              , text  : "[Link to update]"
                          }

                       , Tuto { title : "Link a set of document (corpus) with a set of persons (community)"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
252
                              , id    : "video_tutorial_2.mp4#t=,46"
253 254
                              , text  : "[Link to update]"
                          }
255
                       ,  Tuto { title : "Social lists: cumulative work made easy"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
256
                              , id    : "video_tutorial_2.mp4#t=,46"
257 258 259
                              , text  : "[Link to update]"
                          }
                       ,  Tuto { title : "Data mining with calc"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
260
                              , id    : "video_tutorial_2.mp4#t=,46"
261 262 263
                              , text  : "[Link to update]"
                          }
                      ,  Tuto { title : "Collaborative sync edition notes"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
264
                                , id    : "video_tutorial_2.mp4#t=,46"
265 266 267
                                , text  : "[Link to update]"
                            }
                      ,  Tuto { title : "Coding with our notebooks"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
268
                                , id    : "video_tutorial_2.mp4#t=,46"
269 270 271 272
                                , text  : "[Link to update]"
                            }

                      ,  Tuto { title : "Our api"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
273
                                , id    : "video_tutorial_2.mp4#t=,46"
274 275 276
                                , text  : "[Link to update]"
                            }
                      ,  Tuto { title : "A tour in the code"
Alexandre Delanoë's avatar
Alexandre Delanoë committed
277
                                , id    : "video_tutorial_2.mp4#t=,46"
278 279 280
                                , text  : "[Link to update]"
                            }
                      ]
Alexandre Delanoë's avatar
Alexandre Delanoë committed
281
                      --}
282 283


Alexandre Delanoë's avatar
Alexandre Delanoë committed
284
        video fileDuration = H.div {className:"col-12 d-flex justify-content-center"}
285 286 287 288 289
                                   [ H.video { src: "http://dl.gargantext.org/" <> fileDuration
                                     , title: "tutorial video here"
                                     , id: "source_" <> fileDuration
                                     , width: "900"
                                     , "type": "video/ogg"
290 291
                                     , controls: true
                                     , muted   : true
Alexandre Delanoë's avatar
Alexandre Delanoë committed
292
                                   } [H.text "Sorry your browser is not compatible: use Firefox or Chromium instead."]
293 294
                                   ]

Alexandre Delanoë's avatar
Alexandre Delanoë committed
295
        joinButton = H.div { className:"flex-space-around d-flex justify-content-center" 
Alexandre Delanoë's avatar
Alexandre Delanoë committed
296 297 298 299 300 301 302 303 304 305 306 307
                       , paddingTop: "100px"
                       , paddingBottom: "100px"
                       }
                       [ H.button { className: "btn btn-primary my-2"
                                  , on : {click}
                                  , title: "Connect to the server"
                                  } [ H.text "Join"
                                    ]
                       ]
        click _ = log "click!" *> (snd backend) (const $ Just publicBackend)
                               *> (snd visible) (const true)

308 309 310 311
data Tuto = Tuto { title :: String
                 , id    :: String
                 , text  :: String
               }
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338

------------------------------------------------------------------------

blocksRandomText' :: LandingData -> R.Element
blocksRandomText' (LandingData hd) = blocksRandomText hd.blockTexts

blocksRandomText :: BlockTexts -> R.Element
blocksRandomText (BlockTexts bt) =
  H.div { className: "row" } ( map showBlock bt.blocks )
  where
    showBlock :: BlockText -> R.Element
    showBlock (BlockText b) =
      H.div { className: "col-md-4 content" }
      [ H.h3 {}
        [ H.a { href: b.href, title: b.title}
          [ H.i {className: b.icon} []
          , H.text ("   " <> b.titleText) ] ]
        , H.p {} [ H.text b.text ]
        , H.p {} [ docButton b.docButton ] ]

docButton :: Button -> R.Element
docButton (Button b) =
  H.a { className: "btn btn-outline-primary btn-sm spacing-class"
      , href: b.href
      , target: "blank"
      , title: b.title
      } [ H.span { aria: {hidden : true}
339
                 , className: "fa fa-hand-right"
340 341 342 343
                 } []
        , H.text b.text
        ]

344 345
-- | TODO
-- <img src='logo.png' onmouseover="this.src='gargantextuel.png';" onmouseout="this.src='logo.png';" />
346 347 348 349 350 351 352 353 354 355
jumboTitle :: LandingData -> R.Element
jumboTitle (LandingData hd) =
  H.div {} [
    H.div { className: "row" } [
       H.div { className: "mx-auto" } [
          H.div { id: "logo-designed" } [
             H.img { src: "images/logo.png"
                   , title: hd.logoTitle
                   }
             ]
356
          ]
357 358
       ]
    ]
359

360
imageEnter :: forall t. LandingData -> t -> R.Element
361 362 363 364 365 366 367 368 369 370
imageEnter (LandingData hd) action =
  H.div {className: "row"}
  [ H.div {className: "col-md-offset-5 col-md-6 content"}
    [ H.img { src: "images/Gargantextuel-212x300.jpg"
            , id: "funnyimg"
            , title: hd.imageTitle
            , action
            }
    ]
  ]
371