[Login] backend connection, local storage, logout link

parent 0eab4c4a
This diff is collapsed.
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
...@@ -26,7 +26,7 @@ import React.DOM.Props (_id, _type, className, href, title, onClick, onInput, pl ...@@ -26,7 +26,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
......
...@@ -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
toUrl :: End -> NodeType -> Maybe Id -> Url where
toUrl e nt i = doUrl base path params os = maybe "" (\x -> "&order=" <> show x) s
pathUrl c (Ngrams t listid) i =
pathUrl c (NodeAPI Node) i <> "/" <> "listGet?ngramsType=" <> show t <> listid'
where where
base = endBaseUrl e endConfig listid' = maybe "" (\x -> "&list=" <> show x) listid
path = endPathUrl e endConfig nt i pathUrl c Auth Nothing = c.prePath <> "auth"
params = "" pathUrl c Auth (Just _) = "impossible" -- TODO better types
pathUrl c (NodeAPI nt) i = c.prePath <> nodeTypeUrl nt <> (maybe "" (\i' -> "/" <> show i') i)
------------------------------------------------------------
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
base = endBaseUrl e endConfig
path = endPathUrl e endConfig p i
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
......
...@@ -20,7 +20,7 @@ import Gargantext.Prelude ...@@ -20,7 +20,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(..)) import Gargantext.Pages.Annuaire.User.Contacts.Types (Contact(..), HyperData(..))
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
......
...@@ -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)
......
...@@ -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,10 +84,12 @@ layout0 layout = ...@@ -85,10 +84,12 @@ 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
, rs bs Nothing ->
outerLayout1
, rs bs
] ]
ls = over _render \render d p s c -> [ ls = over _render \render d p s c -> [
div [ className "col-md-2"] (render d p s c) div [ className "col-md-2"] (render d p s c)
...@@ -124,10 +125,12 @@ layout1 layout = ...@@ -124,10 +125,12 @@ 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
, rs bs Nothing ->
outerLayout1
, 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
a [ aria {hidden : true} ]
, className "glyphicon glyphicon-log-in"
, --href "#/login"
onClick $ \e -> d ShowLogin
, style {color:"white"}
, title "Log in and save your time"
-- TODO hover: bold
]
-- TODO if logged in
--, text " username"
-- else
[text " Login / Signup"]
]
] ]
where
loginLink =
a [ aria {hidden : true}
, className "glyphicon glyphicon-log-in"
, onClick $ \e -> d ShowLogin
, style {color:"white"}
, title "Log in and save your time"
-- TODO hover: bold
]
[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,6 +4,7 @@ import Prelude hiding (div) ...@@ -4,6 +4,7 @@ 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.Components.Tree as Tree
...@@ -28,20 +29,22 @@ type AppState = ...@@ -28,20 +29,22 @@ type AppState =
, showTree :: Boolean , showTree :: Boolean
} }
initAppState :: AppState initAppState :: Effect AppState
initAppState = initAppState = do
{ currentRoute : Just Home loginState <- LN.initialState
, loginState : LN.initialState pure
, addCorpusState : AC.initialState { currentRoute : Just Home
, searchState : S.initialState , loginState
, userPageState : C.initialState , addCorpusState : AC.initialState
, documentState : D.initialState {} , searchState : S.initialState
, search : "" , userPageState : C.initialState
, showLogin : false , documentState : D.initialState {}
, showCorpus : false , search : ""
, graphExplorerState : GE.initialState , showLogin : false
, showTree : false , showCorpus : false
} , graphExplorerState : GE.initialState
, showTree : false
}
--------------------------------------------------------- ---------------------------------------------------------
_loginState :: Lens' AppState LN.State _loginState :: Lens' AppState LN.State
......
...@@ -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