Commit 4fed7755 authored by Alexandre Delanoë's avatar Alexandre Delanoë

Merge remote-tracking branch 'origin/login'

parents c8584b86 3ab70a97
module Gargantext.Components.Login where module Gargantext.Components.Login where
import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, jsonEmptyObject, (.?), (:=), (~>)) import Control.Monad.Cont.Trans (lift)
import Data.Lens (over) import Data.Int as Int
import Data.Maybe (Maybe) import Data.Lens (over, view)
import Data.Maybe (Maybe(..))
import Data.Traversable (traverse_)
import Effect.Class (liftEffect) import Effect.Class (liftEffect)
import Effect (Effect) import Effect (Effect)
import Effect.Aff (Aff) import Effect.Aff (Aff)
import React.DOM (a, button, div, h2, h4, h5, i, input, label, p, span, text) import React.DOM (a, button, div, h2, h4, h5, i, input, label, p, span, text)
import React.DOM.Props (_data, _id, _type, aria, className, href, maxLength, name, onClick, onInput, placeholder, role, target, value) import React.DOM.Props (_data, _id, _type, aria, className, href, maxLength, name, onClick, onInput, placeholder, role, target, value)
import Thermite (PerformAction, Render, Spec, _render, modifyState, simpleSpec) import Thermite (PerformAction, Render, Spec, _render, modifyState_, simpleSpec)
import Unsafe.Coerce (unsafeCoerce) import Unsafe.Coerce (unsafeCoerce)
import Web.HTML (window) import Web.HTML (window)
import Web.HTML.Window (localStorage) import Web.HTML.Window (localStorage)
import Web.Storage.Storage (getItem, setItem) import Web.Storage.Storage (getItem, setItem, removeItem)
------------------------------------------------------------------------ ------------------------------------------------------------------------
import Gargantext.Prelude import Gargantext.Prelude
import Gargantext.Config (toUrl, Path(..), End(..))
import Gargantext.Config.REST (post) import Gargantext.Config.REST (post)
import Gargantext.Components.Modals.Modal (modalHide) import Gargantext.Components.Modals.Modal (modalHide)
import Gargantext.Components.Login.Types
-- TODO: ask for login (modal) or account creation after 15 mn when user -- TODO: ask for login (modal) or account creation after 15 mn when user
-- is not logged and has made one search at least -- is not logged and has made one search at least
newtype State = State type State =
{ username :: String { username :: String
, password :: String , password :: String
, response :: LoginRes , authData :: Maybe AuthData
, errorMessage :: String , errorMessage :: String
, loginC :: Boolean
} }
initialState :: State initialState :: Effect State
initialState = State initialState = do
{username : "" authData <- getAuthData
pure
{ authData
, username : ""
, password : "" , password : ""
, response : LoginRes {token : ""}
, errorMessage : "" , errorMessage : ""
, loginC : false
} }
data Action data Action
= Login = PostAuth
| SetUserName String | SetUserName String
| SetPassword String | SetPassword String
...@@ -51,24 +55,22 @@ modalSpec sm t = over _render \render d p s c -> ...@@ -51,24 +55,22 @@ modalSpec sm t = over _render \render d p s c ->
[ div [ _id "loginModal", className $ "modal myModal" <> if sm then "" else " fade" [ div [ _id "loginModal", className $ "modal myModal" <> if sm then "" else " fade"
, role "dialog" , role "dialog"
, _data {show : true} , _data {show : true}
][ div [ className "modal-dialog"
, role "document"
] [ div [ className "modal-content"]
[ div [ className "modal-header"]
[ h5 [ className "modal-title"
] ]
[ text $ t [ div [ className "modal-dialog"
, role "document"
] ]
[ div [ className "modal-content"]
[ div [ className "modal-header"]
[ h5 [ className "modal-title" ]
[ text t ]
, button [ _type "button" , button [ _type "button"
, className "close" , className "close"
, _data { dismiss : "modal"} , _data { dismiss : "modal"}
] [ span [ aria {hidden : true}]
[ text "X"]
] ]
[ span [ aria {hidden : true}] [ text "X"]
] ]
]
, div [ className "modal-body"] , div [ className "modal-body"] (render d p s c)
(render d p s c)
] ]
] ]
] ]
...@@ -82,46 +84,36 @@ renderSpec = simpleSpec performAction render ...@@ -82,46 +84,36 @@ renderSpec = simpleSpec performAction render
where where
performAction :: PerformAction State {} Action performAction :: PerformAction State {} Action
performAction (SetUserName usr) _ _ = void do performAction (SetUserName usr) _ _ =
modifyState \(State state) -> State $ state { username = usr } modifyState_ $ _ { username = usr }
performAction (SetPassword pwd) _ _ = void do performAction (SetPassword pwd) _ _ =
modifyState \(State state) -> State $ state { password = pwd } modifyState_ $ _ { password = pwd }
performAction Login _ _ = void do performAction PostAuth _ {username, password} = do
--lift $ setHash "/search" res <- lift $ postAuthRequest $ AuthRequest {username, password}
case res of
AuthResponse {inval: Just (AuthInvalid {message})} ->
modifyState_ $ _ { errorMessage = message }
AuthResponse {valid} -> do
liftEffect $ setAuthData valid
modifyState_ $ _ {authData = valid, errorMessage = ""}
liftEffect $ modalHide "loginModal" liftEffect $ modalHide "loginModal"
modifyState \(State state) -> State $ state {loginC = true}
-- res <- lift $ loginReq $ LoginReq { username : state.username, password : state.password }
-- case res of
-- Left e -> do
-- logs e
-- modifyState \(State s) -> State $ s { errorMessage = e}
-- Right r@(LoginRes response) -> do
-- lift $ setHash "/addCorpus"
-- modifyState \(State s) -> State $ s {response = r, errorMessage = ""}
render :: Render State {} Action render :: Render State {} Action
render dispatch _ (State state) _ = render dispatch _ state _ =
[ [ div [className "row"]
div [className "row"] [ div [className "col-sm-10 col-sm-push-1 col-md-6 col-md-push-3 col-lg-6 col-lg-push-3"]
[ [ h2 [className "text-primary center m-a-2"]
div [className "col-sm-10 col-sm-push-1 col-md-6 col-md-push-3 col-lg-6 col-lg-push-3"]
[
h2 [className "text-primary center m-a-2"]
[ i [className "material-icons md-36"] [text "control_point"] [ i [className "material-icons md-36"] [text "control_point"]
, span [className "icon-text"] [text "Gargantext"] , span [className "icon-text"] [text "Gargantext"]
] ]
, div [className "card-group"] , div [className "card-group"]
[ [ div [className "card"]
div [className "card"] [ div [className "card-block"]
[ [ div [className "center"]
div [className "card-block"]
[
div [className "center"]
[ h4 [className "m-b-0"] [ h4 [className "m-b-0"]
[ span [className "icon-text"] [ text "Connexion"] [ span [className "icon-text"] [ text "Connexion"] ]
]
, p [className "text-muted"] , p [className "text-muted"]
[ text $ "Login to your account or", [ text $ "Login to your account or",
a [ target "blank",href "https://iscpif.fr/services/applyforourservices/"] [text " ask to get an access"] a [ target "blank",href "https://iscpif.fr/services/applyforourservices/"] [text " ask to get an access"]
...@@ -130,6 +122,7 @@ renderSpec = simpleSpec performAction render ...@@ -130,6 +122,7 @@ renderSpec = simpleSpec performAction render
, div [] , div []
[ input [_type "hidden", [ input [_type "hidden",
name "csrfmiddlewaretoken", name "csrfmiddlewaretoken",
-- TODO hard-coded CSRF token
value "Wy52D2nor8kC1r1Y4GrsrSIxQ2eqW8UwkdiQQshMoRwobzU4uldknRUhP0j4WcEM" ] value "Wy52D2nor8kC1r1Y4GrsrSIxQ2eqW8UwkdiQQshMoRwobzU4uldknRUhP0j4WcEM" ]
, div [className "form-group"] , div [className "form-group"]
...@@ -141,14 +134,13 @@ renderSpec = simpleSpec performAction render ...@@ -141,14 +134,13 @@ renderSpec = simpleSpec performAction render
, div [className "clearfix"] [] , div [className "clearfix"] []
] ]
, div [className "center"] , div [className "center"]
[ [ label []
label [] [ [ div [className "checkbox"]
div [className "checkbox"]
[ input [_id "terms-accept", _type "checkbox", value "", className "checkbox"] [ input [_id "terms-accept", _type "checkbox", value "", className "checkbox"]
, text "I accept the terms of uses ", , text "I accept the terms of uses ",
a [href "http://gitlab.iscpif.fr/humanities/tofu/tree/master"] [text "[Read the terms of use]"] a [href "http://gitlab.iscpif.fr/humanities/tofu/tree/master"] [text "[Read the terms of use]"]
] ]
, button [_id "login-button",className "btn btn-primary btn-rounded", _type "submit", onClick \_ -> dispatch $ Login] [text "Login"] , button [_id "login-button",className "btn btn-primary btn-rounded", _type "submit", onClick \_ -> dispatch $ PostAuth] [text "Login"]
] ]
] ]
] ]
...@@ -179,7 +171,7 @@ renderSpec = simpleSpec performAction render ...@@ -179,7 +171,7 @@ renderSpec = simpleSpec performAction render
-- ] -- ]
-- , div [ className "modal-body"] -- , div [ className "modal-body"]
-- [ ul [ className "list-group"] ( map fn1 state.response ) ] -- [ ul [ className "list-group"] ( map fn1 state.authData ) ]
-- , div [className "modal-footer"] -- , div [className "modal-footer"]
-- [ button [ _type "button" -- [ button [ _type "button"
...@@ -197,44 +189,28 @@ renderSpec = simpleSpec performAction render ...@@ -197,44 +189,28 @@ renderSpec = simpleSpec performAction render
unsafeEventValue :: forall event. event -> String unsafeEventValue :: forall event. event -> String
unsafeEventValue e = (unsafeCoerce e).target.value unsafeEventValue e = (unsafeCoerce e).target.value
getAuthData :: Effect (Maybe AuthData)
getAuthData = do
getDeviseID :: Effect (Maybe String)
getDeviseID = do
w <- window w <- window
ls <- localStorage w ls <- localStorage w
getItem "token" ls mto <- getItem "token" ls
mti <- getItem "tree_id" ls
pure do
setToken :: String -> Effect Unit token <- mto
setToken s = do tree_id <- Int.fromString =<< mti
pure $ AuthData {token, tree_id}
setAuthData :: Maybe AuthData -> Effect Unit
setAuthData Nothing = do
w <- window w <- window
ls <- localStorage w ls <- localStorage w
setItem "token" s ls removeItem "token" ls
removeItem "tree_id" ls
setAuthData (Just (AuthData {tree_id, token})) = do
w <- window
newtype LoginRes = LoginRes ls <- localStorage w
{token :: String setItem "token" token ls
} setItem "tree_id" (show tree_id) ls
newtype LoginReq = LoginReq
{ username :: String
, password :: String
}
loginReq :: LoginReq -> Aff LoginRes
loginReq = post "https://dev.gargantext.org/api/auth/token"
instance decodeLoginRes :: DecodeJson LoginRes where
decodeJson json = do
obj <- decodeJson json
token <- obj .? "token"
pure $ LoginRes { token}
instance encodeLoginReq :: EncodeJson LoginReq where postAuthRequest :: AuthRequest -> Aff AuthResponse
encodeJson (LoginReq obj) = postAuthRequest = post $ toUrl Back Auth Nothing
"username" := obj.username
~> "password" := obj.password
~> jsonEmptyObject
module Gargantext.Components.Login.Types where
import Prelude
import Data.Lens (Iso', iso)
import Data.Argonaut ( class DecodeJson, class EncodeJson, decodeJson, jsonEmptyObject
, (.?), (.??), (:=), (~>)
)
import Data.Maybe (Maybe)
type Username = String
type Password = String
type Token = String
type TreeId = Int
newtype AuthRequest = AuthRequest
{ username :: Username
, password :: Password
}
newtype AuthResponse = AuthResponse
{ valid :: Maybe AuthData
, inval :: Maybe AuthInvalid
}
newtype AuthInvalid = AuthInvalid
{ message :: String }
newtype AuthData = AuthData
{ token :: Token
, tree_id :: TreeId
}
_AuthData :: Iso' AuthData { token :: Token, tree_id :: TreeId }
_AuthData = iso (\(AuthData v) -> v) AuthData
instance decodeAuthInvalid :: DecodeJson AuthInvalid where
decodeJson json = do
obj <- decodeJson json
message <- obj .? "message"
pure $ AuthInvalid {message}
instance decodeAuthResponse :: DecodeJson AuthResponse where
decodeJson json = do
obj <- decodeJson json
valid <- obj .?? "valid"
inval <- obj .?? "inval"
pure $ AuthResponse {valid, inval}
instance decodeAuthData :: DecodeJson AuthData where
decodeJson json = do
obj <- decodeJson json
token <- obj .? "token"
tree_id <- obj .? "tree_id"
pure $ AuthData {token, tree_id}
instance encodeAuthRequest :: EncodeJson AuthRequest where
encodeJson (AuthRequest {username, password}) =
"username" := username
~> "password" := password
~> jsonEmptyObject
...@@ -8,6 +8,7 @@ import Affjax.RequestBody (RequestBody(..)) ...@@ -8,6 +8,7 @@ import Affjax.RequestBody (RequestBody(..))
import Affjax.ResponseFormat as ResponseFormat import Affjax.ResponseFormat as ResponseFormat
import CSS (backgroundColor, borderRadius, boxShadow, justifyContent, marginTop) import CSS (backgroundColor, borderRadius, boxShadow, justifyContent, marginTop)
import Control.Monad.Cont.Trans (lift) import Control.Monad.Cont.Trans (lift)
import Data.Array (filter)
import Data.Argonaut (class DecodeJson, class EncodeJson, Json, decodeJson, encodeJson, jsonEmptyObject, (.?), (:=), (~>)) import Data.Argonaut (class DecodeJson, class EncodeJson, Json, decodeJson, encodeJson, jsonEmptyObject, (.?), (:=), (~>))
import Data.Argonaut.Core (Json) import Data.Argonaut.Core (Json)
import Data.Either (Either(..)) import Data.Either (Either(..))
...@@ -26,7 +27,7 @@ import React.DOM.Props (_id, _type, className, href, title, onClick, onInput, pl ...@@ -26,7 +27,7 @@ import React.DOM.Props (_id, _type, className, href, title, onClick, onInput, pl
import React.DOM.Props as DOM import React.DOM.Props as DOM
import Thermite (PerformAction, Render, Spec, createClass, defaultPerformAction, defaultRender, modifyState_, simpleSpec) import Thermite (PerformAction, Render, Spec, createClass, defaultPerformAction, defaultRender, modifyState_, simpleSpec)
import Gargantext.Config (toUrl, End(..), NodeType(..), defaultRoot) import Gargantext.Config (toUrl, End(..), NodeType(..))
import Gargantext.Config.REST (get, put, post, delete, deleteWithBody) import Gargantext.Config.REST (get, put, post, delete, deleteWithBody)
import Gargantext.Components.Loader as Loader import Gargantext.Components.Loader as Loader
...@@ -39,6 +40,15 @@ type Props = { root :: ID } ...@@ -39,6 +40,15 @@ type Props = { root :: ID }
data NTree a = NTree a (Array (NTree a)) data NTree a = NTree a (Array (NTree a))
instance ntreeFunctor :: Functor NTree where
map f (NTree x ary) = NTree (f x) (map (map f) ary)
-- Keep only the nodes matching the predicate.
-- The root of the tree is always kept.
filterNTree :: forall a. (a -> Boolean) -> NTree a -> NTree a
filterNTree p (NTree x ary) =
NTree x $ map (filterNTree p) $ filter (\(NTree a _) -> p a) ary
type FTree = NTree LNode type FTree = NTree LNode
data Action = ShowPopOver ID data Action = ShowPopOver ID
...@@ -55,40 +65,39 @@ data Action = ShowPopOver ID ...@@ -55,40 +65,39 @@ data Action = ShowPopOver ID
type State = { state :: FTree } type State = { state :: FTree }
-- TODO remove
initialState :: State initialState :: State
initialState = { state: NTree (LNode {id : 3, name : "hello", nodeType : Node, open : true, popOver : false, renameNodeValue : "", createNode : false, nodeValue : "InitialNode", showRenameBox : false}) [] } initialState = { state: NTree (LNode {id : 3, name : "hello", nodeType : Node, open : true, popOver : false, renameNodeValue : "", createNode : false, nodeValue : "InitialNode", showRenameBox : false}) [] }
mapFTree :: (FTree -> FTree) -> State -> State mapFTree :: (FTree -> FTree) -> State -> State
mapFTree f {state} = {state: f state} mapFTree f {state} = {state: f state}
-- TODO: make it a local function
performAction :: forall props. PerformAction State props Action performAction :: forall props. PerformAction State props Action
performAction (ToggleFolder i) _ _ = performAction (ToggleFolder i) _ _ =
modifyState_ $ mapFTree $ toggleNode i modifyState_ $ mapFTree $ toggleNode i
performAction (ShowPopOver id) _ _ = performAction (ShowPopOver id) _ _ =
modifyState_ $ mapFTree $ popOverNode id modifyState_ $ mapFTree $ map $ popOverNode id
performAction (ShowRenameBox id) _ _ = performAction (ShowRenameBox id) _ _ =
modifyState_ $ mapFTree $ showPopOverNode id modifyState_ $ mapFTree $ map $ showPopOverNode id
performAction (CancelRename id) _ _ = performAction (CancelRename id) _ _ =
modifyState_ $ mapFTree $ showPopOverNode id modifyState_ $ mapFTree $ map $ showPopOverNode id
performAction (ToggleCreateNode id) _ _ = performAction (ToggleCreateNode id) _ _ =
modifyState_ $ mapFTree $ showCreateNode id modifyState_ $ mapFTree $ showCreateNode id
performAction (DeleteNode nid) _ _ = do performAction (DeleteNode nid) _ _ = do
d <- lift $ deleteNode nid void $ lift $ deleteNode nid
--- TODO : Need to update state once API is called modifyState_ $ mapFTree $ filterNTree (\(LNode {id}) -> id /= nid)
pure unit
--- TODO : Need to update state once API is called performAction (Submit rid name) _ _ = do
performAction (Submit rid s'') _ _ = do void $ lift $ renameNode rid $ RenameValue {name}
d <- lift $ renameNode rid $ RenameValue { name : s''} modifyState_ $ mapFTree $ map $ popOverNode rid
-- modifyState_ $ mapFTree $ popOverNode rid <<< onNode rid (\(LNode node) -> LNode (node { name = name }))
modifyState_ $ mapFTree $ showPopOverNode rid -- add this function to toggle rename function
performAction (RenameNode r nid) _ _ = performAction (RenameNode r nid) _ _ =
modifyState_ $ mapFTree $ rename nid r modifyState_ $ mapFTree $ rename nid r
...@@ -99,21 +108,25 @@ performAction (Create nid) _ _ = ...@@ -99,21 +108,25 @@ performAction (Create nid) _ _ =
performAction (SetNodeValue v nid) _ _ = performAction (SetNodeValue v nid) _ _ =
modifyState_ $ mapFTree $ setNodeValue nid v modifyState_ $ mapFTree $ setNodeValue nid v
toggleIf :: Boolean -> Boolean -> Boolean
toggleIf true = not
toggleIf false = const false
popOverNode :: Int -> NTree LNode -> NTree LNode onNode :: Int -> (LNode -> LNode) -> LNode -> LNode
popOverNode sid (NTree (LNode {id, name, nodeType, open, popOver, renameNodeValue, createNode, nodeValue, showRenameBox}) ary) = onNode id f l@(LNode node)
NTree (LNode {id,name, nodeType, open , popOver : npopOver, renameNodeValue, createNode, nodeValue, showRenameBox}) $ map (popOverNode sid) ary | node.id == id = f l
where | otherwise = l
npopOver = if sid == id then not popOver else popOver
showPopOverNode :: Int -> NTree LNode -> NTree LNode popOverNode :: Int -> LNode -> LNode
showPopOverNode sid (NTree (LNode {id, name, nodeType, open, popOver, renameNodeValue, createNode, nodeValue, showRenameBox}) ary) = popOverNode sid (LNode node) =
NTree (LNode {id,name, nodeType, open , popOver , renameNodeValue, createNode, nodeValue, showRenameBox: nshowRenameBox}) $ map (showPopOverNode sid) ary LNode $ node { popOver = toggleIf (sid == node.id) node.popOver
where , showRenameBox = false }
nshowRenameBox = if sid == id then not showRenameBox else showRenameBox
showPopOverNode :: Int -> LNode -> LNode
showPopOverNode sid (LNode node) =
LNode $ node {showRenameBox = toggleIf (sid == node.id) node.showRenameBox}
-- TODO: DRY, NTree.map
showCreateNode :: Int -> NTree LNode -> NTree LNode showCreateNode :: Int -> NTree LNode -> NTree LNode
showCreateNode sid (NTree (LNode {id, name, nodeType, open, popOver, renameNodeValue, createNode, nodeValue, showRenameBox}) ary) = showCreateNode sid (NTree (LNode {id, name, nodeType, open, popOver, renameNodeValue, createNode, nodeValue, showRenameBox}) ary) =
NTree (LNode {id,name, nodeType, open , popOver, renameNodeValue, createNode : createNode', nodeValue, showRenameBox}) $ map (showCreateNode sid) ary NTree (LNode {id,name, nodeType, open , popOver, renameNodeValue, createNode : createNode', nodeValue, showRenameBox}) $ map (showCreateNode sid) ary
...@@ -129,21 +142,21 @@ showCreateNode sid (NTree (LNode {id, name, nodeType, open, popOver, renameNodeV ...@@ -129,21 +142,21 @@ showCreateNode sid (NTree (LNode {id, name, nodeType, open, popOver, renameNodeV
-- NTree (LNode {id,name, nodeType, open , popOver, renameNodeValue, createNode , nodeValue}) $ map (getCreateNode sid) ary -- NTree (LNode {id,name, nodeType, open , popOver, renameNodeValue, createNode , nodeValue}) $ map (getCreateNode sid) ary
-- createNode' = if sid == id then nodeValue else "" -- createNode' = if sid == id then nodeValue else ""
-- TODO: DRY, NTree.map
rename :: Int -> String -> NTree LNode -> NTree LNode rename :: Int -> String -> NTree LNode -> NTree LNode
rename sid v (NTree (LNode {id, name, nodeType, open, popOver, renameNodeValue, createNode, nodeValue, showRenameBox}) ary) = rename sid v (NTree (LNode {id, name, nodeType, open, popOver, renameNodeValue, createNode, nodeValue, showRenameBox}) ary) =
NTree (LNode {id,name, nodeType, open , popOver , renameNodeValue : rvalue, createNode, nodeValue, showRenameBox}) $ map (rename sid v) ary NTree (LNode {id,name, nodeType, open , popOver , renameNodeValue : rvalue, createNode, nodeValue, showRenameBox}) $ map (rename sid v) ary
where where
rvalue = if sid == id then v else "" rvalue = if sid == id then v else ""
-- TODO: DRY, NTree.map
setNodeValue :: Int -> String -> NTree LNode -> NTree LNode setNodeValue :: Int -> String -> NTree LNode -> NTree LNode
setNodeValue sid v (NTree (LNode {id, name, nodeType, open, popOver, renameNodeValue, createNode, nodeValue, showRenameBox}) ary) = setNodeValue sid v (NTree (LNode {id, name, nodeType, open, popOver, renameNodeValue, createNode, nodeValue, showRenameBox}) ary) =
NTree (LNode {id,name, nodeType, open , popOver , renameNodeValue , createNode, nodeValue : nvalue, showRenameBox}) $ map (setNodeValue sid v) ary NTree (LNode {id,name, nodeType, open , popOver , renameNodeValue , createNode, nodeValue : nvalue, showRenameBox}) $ map (setNodeValue sid v) ary
where where
nvalue = if sid == id then v else "" nvalue = if sid == id then v else ""
-- TODO: DRY, NTree.map
toggleNode :: Int -> NTree LNode -> NTree LNode toggleNode :: Int -> NTree LNode -> NTree LNode
toggleNode sid (NTree (LNode {id, name, nodeType, open, popOver, renameNodeValue, createNode, nodeValue, showRenameBox}) ary) = toggleNode sid (NTree (LNode {id, name, nodeType, open, popOver, renameNodeValue, createNode, nodeValue, showRenameBox}) ary) =
NTree (LNode {id,name, nodeType, open : nopen, popOver, renameNodeValue, createNode, nodeValue, showRenameBox}) $ map (toggleNode sid) ary NTree (LNode {id,name, nodeType, open : nopen, popOver, renameNodeValue, createNode, nodeValue, showRenameBox}) $ map (toggleNode sid) ary
...@@ -252,7 +265,7 @@ renameTreeView d s@(NTree (LNode {id, name, nodeType, open, popOver, renameNodeV ...@@ -252,7 +265,7 @@ renameTreeView d s@(NTree (LNode {id, name, nodeType, open, popOver, renameNodeV
[ [
input [ _type "text" input [ _type "text"
, placeholder "Rename Node" , placeholder "Rename Node"
, defaultValue $ getRenameNodeValue s , defaultValue $ name
, style {float: "left"} , style {float: "left"}
, className "col-md-2 form-control" , className "col-md-2 form-control"
, onInput \e -> d (RenameNode (unsafeEventValue e) nid) , onInput \e -> d (RenameNode (unsafeEventValue e) nid)
...@@ -335,10 +348,6 @@ renameTreeViewDummy d s = div [] [] ...@@ -335,10 +348,6 @@ renameTreeViewDummy d s = div [] []
popOverValue :: FTree -> Boolean popOverValue :: FTree -> Boolean
popOverValue (NTree (LNode {id, name, nodeType, open, popOver, renameNodeValue, showRenameBox }) ary) = popOver popOverValue (NTree (LNode {id, name, nodeType, open, popOver, renameNodeValue, showRenameBox }) ary) = popOver
getRenameNodeValue :: FTree -> String
getRenameNodeValue (NTree (LNode {id, name, nodeType, open, popOver, renameNodeValue, showRenameBox }) ary) = renameNodeValue
getCreateNodeValue :: FTree -> String getCreateNodeValue :: FTree -> String
getCreateNodeValue (NTree (LNode {id, name, nodeType, open, popOver, renameNodeValue, nodeValue, showRenameBox}) ary) = nodeValue getCreateNodeValue (NTree (LNode {id, name, nodeType, open, popOver, renameNodeValue, nodeValue, showRenameBox}) ary) = nodeValue
...@@ -420,8 +429,8 @@ newtype RenameValue = RenameValue ...@@ -420,8 +429,8 @@ newtype RenameValue = RenameValue
} }
instance encodeJsonRenameValue :: EncodeJson RenameValue where instance encodeJsonRenameValue :: EncodeJson RenameValue where
encodeJson (RenameValue post) encodeJson (RenameValue {name})
= "r_name" := post.name = "r_name" := name
~> jsonEmptyObject ~> jsonEmptyObject
renameNode :: Int -> RenameValue -> Aff (Array Int) renameNode :: Int -> RenameValue -> Aff (Array Int)
......
...@@ -27,11 +27,6 @@ endConfig' :: ApiVersion -> EndConfig ...@@ -27,11 +27,6 @@ endConfig' :: ApiVersion -> EndConfig
endConfig' v = { front : frontRelative endConfig' v = { front : frontRelative
, back : backLocal v } , back : backLocal v }
-- | Default Root on shared database to develop
-- until authentication implementation
-- (Default Root will be given after authentication)
defaultRoot :: Int
defaultRoot = 950094
------------------------------------------------------------------------ ------------------------------------------------------------------------
frontRelative :: Config frontRelative :: Config
frontRelative = { baseUrl: "" frontRelative = { baseUrl: ""
...@@ -100,25 +95,41 @@ endOf Front = _.front ...@@ -100,25 +95,41 @@ endOf Front = _.front
endBaseUrl :: End -> EndConfig -> UrlBase endBaseUrl :: End -> EndConfig -> UrlBase
endBaseUrl end c = (endOf end c).baseUrl endBaseUrl end c = (endOf end c).baseUrl
endPathUrl :: End -> EndConfig -> NodeType -> Maybe Id -> UrlPath endPathUrl :: End -> EndConfig -> Path -> Maybe Id -> UrlPath
endPathUrl end c nt i = pathUrl (endOf end c) nt i endPathUrl end = pathUrl <<< endOf end
pathUrl :: Config -> NodeType -> Maybe Id -> UrlPath pathUrl :: Config -> Path -> Maybe Id -> UrlPath
pathUrl c nt@(Tab _ _ _ _) i = pathUrl c Node i <> "/" <> show nt pathUrl c (Tab t o l s) i =
pathUrl c nt@(Ngrams _ _) i = pathUrl c Node i <> "/" <> show nt pathUrl c (NodeAPI Node) i <>
pathUrl c nt i = c.prePath <> urlConfig nt <> (maybe "" (\i' -> "/" <> show i') i) "/" <> "table?view=" <> show t <> "&offset=" <> show o
<> "&limit=" <> show l <> os
where
os = maybe "" (\x -> "&order=" <> show x) s
pathUrl c (Ngrams t listid) i =
pathUrl c (NodeAPI Node) i <> "/" <> "listGet?ngramsType=" <> show t <> listid'
where
listid' = maybe "" (\x -> "&list=" <> show x) listid
pathUrl c Auth Nothing = c.prePath <> "auth"
pathUrl c Auth (Just _) = "impossible" -- TODO better types
pathUrl c (NodeAPI nt) i = c.prePath <> nodeTypeUrl nt <> (maybe "" (\i' -> "/" <> show i') i)
------------------------------------------------------------ ------------------------------------------------------------
toUrl :: End -> NodeType -> Maybe Id -> Url
toUrl e nt i = doUrl base path params class ToUrl a where
toUrl :: End -> a -> Maybe Id -> Url
instance toUrlNodeType :: ToUrl NodeType where
toUrl e nt i = toUrl e (NodeAPI nt) i
instance toUrlPath :: ToUrl Path where
toUrl e p i = doUrl base path params
where where
base = endBaseUrl e endConfig base = endBaseUrl e endConfig
path = endPathUrl e endConfig nt i path = endPathUrl e endConfig p i
params = "" params = ""
------------------------------------------------------------ ------------------------------------------------------------
data NodeType = NodeUser data NodeType = NodeUser
| Annuaire | Annuaire
| Tab TabType Offset Limit (Maybe OrderBy)
| Ngrams TabType (Maybe TermList)
| Corpus | Corpus
| CorpusV3 | CorpusV3
| Dashboard | Dashboard
...@@ -130,6 +141,13 @@ data NodeType = NodeUser ...@@ -130,6 +141,13 @@ data NodeType = NodeUser
| Node | Node
| Nodes | Nodes
| Tree | Tree
data Path
= Auth
| Tab TabType Offset Limit (Maybe OrderBy)
| Ngrams TabType (Maybe TermList)
| NodeAPI NodeType
data End = Back | Front data End = Back | Front
type Id = Int type Id = Int
...@@ -162,56 +180,23 @@ instance showTabType :: Show TabType where ...@@ -162,56 +180,23 @@ instance showTabType :: Show TabType where
show TabTrash = "Trash" show TabTrash = "Trash"
------------------------------------------------------------ ------------------------------------------------------------
urlConfig :: NodeType -> Url nodeTypeUrl :: NodeType -> Url
urlConfig Annuaire = show Annuaire nodeTypeUrl Annuaire = "annuaire"
urlConfig nt@(Tab _ _ _ _) = show nt nodeTypeUrl Corpus = "corpus"
urlConfig nt@(Ngrams _ _) = show nt nodeTypeUrl CorpusV3 = "corpus"
urlConfig Corpus = show Corpus nodeTypeUrl Dashboard = "dashboard"
urlConfig CorpusV3 = show CorpusV3 nodeTypeUrl Url_Document = "document"
urlConfig Dashboard = show Dashboard nodeTypeUrl Error = "ErrorNodeType"
urlConfig Url_Document = show Url_Document nodeTypeUrl Folder = "folder"
urlConfig Error = show Error nodeTypeUrl Graph = "graph"
urlConfig Folder = show Folder nodeTypeUrl Individu = "individu"
urlConfig Graph = show Graph nodeTypeUrl Node = "node"
urlConfig Individu = show Individu nodeTypeUrl Nodes = "nodes"
urlConfig Node = show Node nodeTypeUrl NodeUser = "user"
urlConfig Nodes = show Nodes nodeTypeUrl Tree = "tree"
urlConfig NodeUser = show NodeUser
urlConfig Tree = show Tree
------------------------------------------------------------
instance showNodeType :: Show NodeType where
show Annuaire = "annuaire"
show Corpus = "corpus"
show CorpusV3 = "corpus"
show Dashboard = "dashboard"
show Url_Document = "document"
show Error = "ErrorNodeType"
show Folder = "folder"
show Graph = "graph"
show Individu = "individu"
show Node = "node"
show Nodes = "nodes"
show NodeUser = "user"
show Tree = "tree"
show (Tab t o l s) = "table?view=" <> show t <> "&offset=" <> show o
<> "&limit=" <> show l <> os
where
os = maybe "" (\x -> "&order=" <> show x) s
show (Ngrams t listid) = "listGet?ngramsType=" <> show t <> listid'
where
listid' = maybe "" (\x -> "&list=" <> show x) listid
-- | TODO : where is the Read Class ?
-- NP: We don't need the Read class. Here are the encoding formats we need:
-- * JSON
-- * URL parts has in {To,From}HttpApiData but only for certain types
-- The Show class should only be used for dev.
-- instance readNodeType :: Read NodeType where
readNodeType :: String -> NodeType readNodeType :: String -> NodeType
readNodeType "NodeAnnuaire" = Annuaire readNodeType "NodeAnnuaire" = Annuaire
readNodeType "Tab" = (Tab TabDocs 0 0 Nothing)
readNodeType "Ngrams" = (Ngrams TabTerms Nothing)
readNodeType "NodeDashboard" = Dashboard readNodeType "NodeDashboard" = Dashboard
readNodeType "Document" = Url_Document readNodeType "Document" = Url_Document
readNodeType "NodeFolder" = Folder readNodeType "NodeFolder" = Folder
...@@ -224,12 +209,14 @@ readNodeType "NodeCorpusV3" = CorpusV3 ...@@ -224,12 +209,14 @@ readNodeType "NodeCorpusV3" = CorpusV3
readNodeType "NodeUser" = NodeUser readNodeType "NodeUser" = NodeUser
readNodeType "Tree" = Tree readNodeType "Tree" = Tree
readNodeType _ = Error readNodeType _ = Error
{-
------------------------------------------------------------ ------------------------------------------------------------
instance ordNodeType :: Ord NodeType where instance ordNodeType :: Ord NodeType where
compare n1 n2 = compare (show n1) (show n2) compare n1 n2 = compare (show n1) (show n2)
instance eqNodeType :: Eq NodeType where instance eqNodeType :: Eq NodeType where
eq n1 n2 = eq (show n1) (show n2) eq n1 n2 = eq (show n1) (show n2)
-}
------------------------------------------------------------ ------------------------------------------------------------
instance decodeJsonNodeType :: DecodeJson NodeType where instance decodeJsonNodeType :: DecodeJson NodeType where
decodeJson json = do decodeJson json = do
......
...@@ -22,7 +22,7 @@ import Gargantext.Prelude ...@@ -22,7 +22,7 @@ import Gargantext.Prelude
import Gargantext.Components.Loader as Loader import Gargantext.Components.Loader as Loader
import Gargantext.Components.Tab as Tab import Gargantext.Components.Tab as Tab
import Gargantext.Components.Table as T import Gargantext.Components.Table as T
import Gargantext.Config (toUrl, NodeType(..), TabType(..), End(..)) import Gargantext.Config (toUrl, Path(..), NodeType(..), TabType(..), End(..))
import Gargantext.Config.REST (get) import Gargantext.Config.REST (get)
import Gargantext.Pages.Annuaire.User.Contacts.Types (Contact(..), HyperData(..), HyperdataContact(..)) import Gargantext.Pages.Annuaire.User.Contacts.Types (Contact(..), HyperData(..), HyperdataContact(..))
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
......
...@@ -25,7 +25,7 @@ import React as React ...@@ -25,7 +25,7 @@ import React as React
import React (ReactClass, ReactElement, Children) import React (ReactClass, ReactElement, Children)
------------------------------------------------------------------------ ------------------------------------------------------------------------
import Gargantext.Prelude import Gargantext.Prelude
import Gargantext.Config (NodeType(..), TabType(..), toUrl, End(..), OrderBy(..)) import Gargantext.Config (Path(..), NodeType(..), TabType(..), toUrl, End(..), OrderBy(..))
import Gargantext.Config.REST (get, put, post, deleteWithBody) import Gargantext.Config.REST (get, put, post, deleteWithBody)
import Gargantext.Utils.DecodeMaybe ((.|)) import Gargantext.Utils.DecodeMaybe ((.|))
import Gargantext.Components.Charts.Options.ECharts (chart) import Gargantext.Components.Charts.Options.ECharts (chart)
......
...@@ -46,7 +46,6 @@ import Gargantext.Components.Table as T ...@@ -46,7 +46,6 @@ import Gargantext.Components.Table as T
import Gargantext.Prelude import Gargantext.Prelude
import Gargantext.Config import Gargantext.Config
import Gargantext.Config.REST import Gargantext.Config.REST
import Gargantext.Components.Tree (NTree(..))
import Gargantext.Components.Loader as Loader import Gargantext.Components.Loader as Loader
import Gargantext.Pages.Corpus.Tabs.Types (CorpusInfo(..), PropsRow) import Gargantext.Pages.Corpus.Tabs.Types (CorpusInfo(..), PropsRow)
......
...@@ -2,16 +2,15 @@ ...@@ -2,16 +2,15 @@
module Gargantext.Pages.Layout.Actions where module Gargantext.Pages.Layout.Actions where
import Control.Monad.Cont.Trans (lift)
import Data.Either (Either(..)) import Data.Either (Either(..))
import Data.Maybe (Maybe(..))
import Data.Lens (Prism', prism) import Data.Lens (Prism', prism)
import Effect.Class (liftEffect) import Effect.Class (liftEffect)
import Thermite (PerformAction, modifyState, modifyState_) import Thermite (PerformAction, modifyState, modifyState_)
import Routing.Hash (setHash)
import Gargantext.Config (defaultRoot)
import Gargantext.Components.Login as LN import Gargantext.Components.Login as LN
import Gargantext.Components.Modals.Modal (modalShow) import Gargantext.Components.Modals.Modal (modalShow)
import Gargantext.Components.Tree as Tree
import Gargantext.Pages.Annuaire as Annuaire import Gargantext.Pages.Annuaire as Annuaire
import Gargantext.Pages.Annuaire.User.Contacts as C import Gargantext.Pages.Annuaire.User.Contacts as C
import Gargantext.Pages.Corpus.Document as D import Gargantext.Pages.Corpus.Document as D
...@@ -36,6 +35,7 @@ data Action ...@@ -36,6 +35,7 @@ data Action
| UserPageA C.Action | UserPageA C.Action
| Go | Go
| ShowLogin | ShowLogin
| Logout
| ShowAddcorpus | ShowAddcorpus
| ShowTree | ShowTree
...@@ -46,13 +46,20 @@ performAction (SetRoute route) _ _ = void do ...@@ -46,13 +46,20 @@ performAction (SetRoute route) _ _ = void do
performAction (Search s) _ _ = void do performAction (Search s) _ _ = void do
modifyState $ _ {search = s} modifyState $ _ {search = s}
performAction (ShowTree) _ (state) = void do performAction (ShowTree) _ (state) = void do -- TODO
modifyState $ _ {showTree = not (state.showTree)} modifyState $ _ {showTree = not (state.showTree)}
performAction (ShowLogin) _ _ = void do performAction (ShowLogin) _ _ = void do
liftEffect $ modalShow "loginModal" liftEffect $ modalShow "loginModal"
modifyState $ _ {showLogin = true} modifyState $ _ {showLogin = true}
performAction Logout _ _ = do
loginState <- liftEffect do
LN.setAuthData Nothing
setHash "/"
LN.initialState
modifyState_ $ _ {currentRoute = Nothing, loginState = loginState}
--------------------------------------------------------- ---------------------------------------------------------
-- TODO chose one of them -- TODO chose one of them
performAction (ShowAddcorpus) _ _ = void do performAction (ShowAddcorpus) _ _ = void do
......
...@@ -11,8 +11,8 @@ import Thermite (Render, Spec, _render, defaultPerformAction, defaultRender, foc ...@@ -11,8 +11,8 @@ import Thermite (Render, Spec, _render, defaultPerformAction, defaultRender, foc
import Unsafe.Coerce (unsafeCoerce) import Unsafe.Coerce (unsafeCoerce)
import Gargantext.Prelude import Gargantext.Prelude
import Gargantext.Config (defaultRoot)
import Gargantext.Components.Data.Lang (Lang(..)) import Gargantext.Components.Data.Lang (Lang(..))
import Gargantext.Components.Login.Types (AuthData(..))
import Gargantext.Components.Login as LN import Gargantext.Components.Login as LN
import Gargantext.Components.Tree as Tree import Gargantext.Components.Tree as Tree
import Gargantext.Folder as F import Gargantext.Folder as F
...@@ -22,7 +22,6 @@ import Gargantext.Pages.Corpus as Corpus ...@@ -22,7 +22,6 @@ import Gargantext.Pages.Corpus as Corpus
import Gargantext.Pages.Corpus.Document as Annotation import Gargantext.Pages.Corpus.Document as Annotation
import Gargantext.Pages.Corpus.Dashboard as Dsh import Gargantext.Pages.Corpus.Dashboard as Dsh
import Gargantext.Pages.Corpus.Graph as GE import Gargantext.Pages.Corpus.Graph as GE
import Gargantext.Pages.Corpus.Tabs.Ngrams.NgramsTable as NG
import Gargantext.Pages.Home as L import Gargantext.Pages.Home as L
import Gargantext.Pages.Layout.Actions (Action(..), _addCorpusAction, _documentViewAction, _graphExplorerAction, _loginAction, _searchAction, _userPageAction, performAction) import Gargantext.Pages.Layout.Actions (Action(..), _addCorpusAction, _documentViewAction, _graphExplorerAction, _loginAction, _searchAction, _userPageAction, performAction)
import Gargantext.Pages.Layout.Specs.AddCorpus as AC import Gargantext.Pages.Layout.Specs.AddCorpus as AC
...@@ -85,9 +84,11 @@ layout0 layout = ...@@ -85,9 +84,11 @@ layout0 layout =
outerLayout = outerLayout =
cont $ fold cont $ fold
[ withState \st -> [ withState \st ->
if ((\(LN.State s) -> s.loginC) st.loginState == true) case st.loginState.authData of
then ls $ cmapProps (const {root: defaultRoot}) as Just (AuthData {tree_id}) ->
else outerLayout1 ls $ cmapProps (const {root: tree_id}) as
Nothing ->
outerLayout1
, rs bs , rs bs
] ]
ls = over _render \render d p s c -> [ ls = over _render \render d p s c -> [
...@@ -124,9 +125,11 @@ layout1 layout = ...@@ -124,9 +125,11 @@ layout1 layout =
outerLayout = outerLayout =
cont $ fold cont $ fold
[ withState \st -> [ withState \st ->
if ((\(LN.State s) -> s.loginC) st.loginState == true) case st.loginState.authData of
then ls $ cmapProps (const {root: defaultRoot}) as Just (AuthData {tree_id}) ->
else outerLayout1 ls $ cmapProps (const {root: tree_id}) as
Nothing ->
outerLayout1
, rs bs , rs bs
] ]
ls = over _render \render d p s c -> [ ls = over _render \render d p s c -> [
...@@ -164,7 +167,7 @@ layoutSidebar = over _render \render d p s c -> ...@@ -164,7 +167,7 @@ layoutSidebar = over _render \render d p s c ->
, div [ className "collapse navbar-collapse"] , div [ className "collapse navbar-collapse"]
$ [ divDropdownLeft] $ [ divDropdownLeft]
<> render d p s c <> <> render d p s c <>
[ divDropdownRight d] [ divDropdownRight d s ]
] ]
] ]
] ]
...@@ -308,29 +311,35 @@ divSearchBar = simpleSpec performAction render ...@@ -308,29 +311,35 @@ divSearchBar = simpleSpec performAction render
] ]
] ]
--divDropdownRight :: Render AppState {} Action divDropdownRight :: (Action -> Effect Unit) -> AppState -> ReactElement
divDropdownRight :: (Action -> Effect Unit) -> ReactElement divDropdownRight d s =
divDropdownRight d =
ul [className "nav navbar-nav pull-right"] ul [className "nav navbar-nav pull-right"]
[ [ li [className "dropdown"]
-- TODO if logged in : enable dropdown to logout [ case s.loginState.authData of
li [className "dropdown"] Nothing -> loginLink
[ Just _ -> logoutLink
]
]
where
loginLink =
a [ aria {hidden : true} a [ aria {hidden : true}
, className "glyphicon glyphicon-log-in" , className "glyphicon glyphicon-log-in"
, --href "#/login" , onClick $ \e -> d ShowLogin
onClick $ \e -> d ShowLogin
, style {color:"white"} , style {color:"white"}
, title "Log in and save your time" , title "Log in and save your time"
-- TODO hover: bold -- TODO hover: bold
] ]
-- TODO if logged in
--, text " username"
-- else
[text " Login / Signup"] [text " Login / Signup"]
-- TODO dropdown to logout
logoutLink =
a [ aria {hidden : true}
, className "glyphicon glyphicon-log-out"
, onClick $ \e -> d Logout
, style {color:"white"}
, title "Log out" -- TODO
-- TODO hover: bold
] ]
[text " Logout"]
]
layoutFooter :: Spec AppState {} Action layoutFooter :: Spec AppState {} Action
layoutFooter = simpleSpec performAction render layoutFooter = simpleSpec performAction render
......
...@@ -4,8 +4,8 @@ import Prelude hiding (div) ...@@ -4,8 +4,8 @@ import Prelude hiding (div)
import Data.Lens (Lens', lens) import Data.Lens (Lens', lens)
import Data.Maybe (Maybe(Just)) import Data.Maybe (Maybe(Just))
import Effect (Effect)
import Gargantext.Components.Login as LN import Gargantext.Components.Login as LN
import Gargantext.Components.Tree as Tree
import Gargantext.Pages.Corpus.Document as D import Gargantext.Pages.Corpus.Document as D
import Gargantext.Pages.Corpus.Graph as GE import Gargantext.Pages.Corpus.Graph as GE
...@@ -28,10 +28,12 @@ type AppState = ...@@ -28,10 +28,12 @@ type AppState =
, showTree :: Boolean , showTree :: Boolean
} }
initAppState :: AppState initAppState :: Effect AppState
initAppState = initAppState = do
loginState <- LN.initialState
pure
{ currentRoute : Just Home { currentRoute : Just Home
, loginState : LN.initialState , loginState
, addCorpusState : AC.initialState , addCorpusState : AC.initialState
, searchState : S.initialState , searchState : S.initialState
, userPageState : C.initialState , userPageState : C.initialState
......
...@@ -57,24 +57,3 @@ instance showRoutes :: Show Routes where ...@@ -57,24 +57,3 @@ instance showRoutes :: Show Routes where
show Dashboard = "Dashboard" show Dashboard = "Dashboard"
show (PGraphExplorer i) = "graphExplorer" <> show i show (PGraphExplorer i) = "graphExplorer" <> show i
show Home = "Home" show Home = "Home"
routeHandler :: (Maybe Routes -> Routes -> Effect Unit)
-> Maybe Routes -> Routes -> Effect Unit
routeHandler dispatchAction old new = do
logs $ "change route : " <> show new
w <- window
ls <- localStorage w
token <- getItem "accessToken" ls
let tkn = token
logs $ "JWToken : " <> show tkn
case tkn of
Nothing -> do
dispatchAction old new
logs $ "called SignIn Route :"
Just t -> do
dispatchAction old new
logs $ "called Route : " <> show new
...@@ -7,7 +7,7 @@ import Effect (Effect) ...@@ -7,7 +7,7 @@ import Effect (Effect)
import Gargantext.Pages.Layout (dispatchAction) import Gargantext.Pages.Layout (dispatchAction)
import Gargantext.Pages.Layout.Specs (layoutSpec) import Gargantext.Pages.Layout.Specs (layoutSpec)
import Gargantext.Pages.Layout.States (initAppState) import Gargantext.Pages.Layout.States (initAppState)
import Gargantext.Router (routeHandler, routing) import Gargantext.Router (routing)
import Partial.Unsafe (unsafePartial) import Partial.Unsafe (unsafePartial)
import React as R import React as R
import ReactDOM as RDOM import ReactDOM as RDOM
...@@ -24,10 +24,11 @@ setUnsafeComponentWillMount = unsafeSet "unsafeComponentWillMount" ...@@ -24,10 +24,11 @@ setUnsafeComponentWillMount = unsafeSet "unsafeComponentWillMount"
main :: Effect Unit main :: Effect Unit
main = do main = do
case T.createReactSpec layoutSpec (const initAppState) of state <- initAppState
case T.createReactSpec layoutSpec (const state) of
{ spec, dispatcher } -> void $ do { spec, dispatcher } -> void $ do
let setRouting this = void $ do let setRouting this = void $ do
matches routing (routeHandler (dispatchAction (dispatcher this))) matches routing (dispatchAction (dispatcher this))
spec' this = setUnsafeComponentWillMount (setRouting this) <$> (spec this) spec' this = setUnsafeComponentWillMount (setRouting this) <$> (spec this)
document <- window >>= document document <- window >>= document
container <- unsafePartial (fromJust <$> querySelector (QuerySelector "#app") (toParentNode document)) container <- unsafePartial (fromJust <$> querySelector (QuerySelector "#app") (toParentNode document))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment