Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
purescript-gargantext
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Grégoire Locqueville
purescript-gargantext
Commits
1105cefb
Commit
1105cefb
authored
Sep 29, 2019
by
James Laver
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
re-refactor to enable backend chooser
parent
80557556
Changes
57
Hide whitespace changes
Inline
Side-by-side
Showing
57 changed files
with
1544 additions
and
1618 deletions
+1544
-1618
AnnotatedField.purs
src/Gargantext/Components/Annotation/AnnotatedField.purs
+4
-4
Menu.purs
src/Gargantext/Components/Annotation/Menu.purs
+6
-6
App.purs
src/Gargantext/Components/App.purs
+70
-144
Series.purs
src/Gargantext/Components/Charts/Options/Series.purs
+4
-5
ContextMenu.purs
src/Gargantext/Components/ContextMenu/ContextMenu.purs
+1
-1
DocsTable.purs
src/Gargantext/Components/DocsTable.purs
+32
-32
EndsChooser.purs
src/Gargantext/Components/EndsChooser.purs
+0
-83
EndsSummary.purs
src/Gargantext/Components/EndsSummary.purs
+0
-13
FacetsTable.purs
src/Gargantext/Components/FacetsTable.purs
+40
-40
Forest.purs
src/Gargantext/Components/Forest.purs
+38
-0
Forms.purs
src/Gargantext/Components/Forms.purs
+22
-0
Graph.purs
src/Gargantext/Components/Graph.purs
+3
-4
GraphExplorer.purs
src/Gargantext/Components/GraphExplorer.purs
+18
-21
Button.purs
src/Gargantext/Components/GraphExplorer/Button.purs
+2
-7
Controls.purs
src/Gargantext/Components/GraphExplorer/Controls.purs
+1
-2
Sidebar.purs
src/Gargantext/Components/GraphExplorer/Sidebar.purs
+30
-64
ToggleButton.purs
src/Gargantext/Components/GraphExplorer/ToggleButton.purs
+0
-3
Login.purs
src/Gargantext/Components/Login.purs
+162
-169
Modal.purs
src/Gargantext/Components/Modal.purs
+4
-10
NgramsTable.purs
src/Gargantext/Components/NgramsTable.purs
+21
-21
Core.purs
src/Gargantext/Components/NgramsTable/Core.purs
+29
-27
RangeSlider.purs
src/Gargantext/Components/RangeSlider.purs
+3
-8
SearchBar.purs
src/Gargantext/Components/Search/SearchBar.purs
+29
-32
SearchField.purs
src/Gargantext/Components/Search/SearchField.purs
+3
-5
Types.purs
src/Gargantext/Components/Search/Types.purs
+15
-15
Table.purs
src/Gargantext/Components/Table.purs
+2
-7
Tree.purs
src/Gargantext/Components/Tree.purs
+66
-64
Config.purs
src/Gargantext/Config.purs
+22
-438
Ends.purs
src/Gargantext/Ends.purs
+167
-0
Global.purs
src/Gargantext/Global.purs
+0
-16
Loader.purs
src/Gargantext/Hooks/Loader.purs
+1
-3
Router.purs
src/Gargantext/Hooks/Router.purs
+16
-0
Sigmax.purs
src/Gargantext/Hooks/Sigmax.purs
+7
-11
Sigmajs.purs
src/Gargantext/Hooks/Sigmax/Sigmajs.purs
+1
-3
Annuaire.purs
src/Gargantext/Pages/Annuaire.purs
+27
-25
Contacts.purs
src/Gargantext/Pages/Annuaire/User/Contacts.purs
+16
-21
Tabs.purs
src/Gargantext/Pages/Annuaire/User/Contacts/Tabs.purs
+11
-11
Corpus.purs
src/Gargantext/Pages/Corpus.purs
+2
-4
Histo.purs
src/Gargantext/Pages/Corpus/Chart/Histo.purs
+22
-23
Metrics.purs
src/Gargantext/Pages/Corpus/Chart/Metrics.purs
+25
-26
Pie.purs
src/Gargantext/Pages/Corpus/Chart/Pie.purs
+24
-24
Tree.purs
src/Gargantext/Pages/Corpus/Chart/Tree.purs
+18
-19
Dashboard.purs
src/Gargantext/Pages/Corpus/Dashboard.purs
+6
-7
Document.purs
src/Gargantext/Pages/Corpus/Document.purs
+27
-23
Tabs.purs
src/Gargantext/Pages/Corpus/Graph/Tabs.purs
+8
-9
Home.purs
src/Gargantext/Pages/Home.purs
+14
-21
Lists.purs
src/Gargantext/Pages/Lists.purs
+13
-11
Tabs.purs
src/Gargantext/Pages/Lists/Tabs.purs
+16
-16
Texts.purs
src/Gargantext/Pages/Texts.purs
+13
-11
Tabs.purs
src/Gargantext/Pages/Texts/Tabs.purs
+24
-33
Router.purs
src/Gargantext/Router.purs
+4
-52
Routes.purs
src/Gargantext/Routes.purs
+62
-0
Sessions.purs
src/Gargantext/Sessions.purs
+112
-0
Types.purs
src/Gargantext/Types.purs
+240
-3
Utils.purs
src/Gargantext/Utils.purs
+4
-0
Reactix.purs
src/Gargantext/Utils/Reactix.purs
+29
-14
Main.purs
src/Main.purs
+8
-7
No files found.
src/Gargantext/Components/Annotation/AnnotatedField.purs
View file @
1105cefb
...
@@ -22,10 +22,9 @@ import Reactix as R
...
@@ -22,10 +22,9 @@ import Reactix as R
import Reactix.DOM.HTML as HTML
import Reactix.DOM.HTML as HTML
import Reactix.SyntheticEvent as E
import Reactix.SyntheticEvent as E
import Gargantext.Config (CTabNgramType(..))
import Gargantext.Types (CTabNgramType(..), TermList)
import Gargantext.Types ( TermList )
import Gargantext.Components.Annotation.Utils ( termBootstrapClass )
import Gargantext.Components.Annotation.Utils ( termBootstrapClass )
import Gargantext.Components.NgramsTable.Core (
NgramsTerm, NgramsTable(..), highlightNgrams, findNgramTermList
)
import Gargantext.Components.NgramsTable.Core (
NgramsTable, NgramsTerm, findNgramTermList, highlightNgrams
)
import Gargantext.Components.Annotation.Menu ( AnnotationMenu, annotationMenu, MenuType(..) )
import Gargantext.Components.Annotation.Menu ( AnnotationMenu, annotationMenu, MenuType(..) )
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Selection as Sel
import Gargantext.Utils.Selection as Sel
...
@@ -69,6 +68,7 @@ annotatedFieldComponent = R.hooksComponent "AnnotatedField" cpt
...
@@ -69,6 +68,7 @@ annotatedFieldComponent = R.hooksComponent "AnnotatedField" cpt
pure $ HTML.div wrapperProps [maybeAddMenu setMenu runs menu]
pure $ HTML.div wrapperProps [maybeAddMenu setMenu runs menu]
-- forall e. IsMouseEvent e => R2.Setter (Maybe AnnotationMenu) -> R2.Setter ? -> ? -> e -> Effect Unit
maybeShowMenu setMenu setTermList ngrams event = do
maybeShowMenu setMenu setTermList ngrams event = do
s <- Sel.getSelection
s <- Sel.getSelection
case s of
case s of
...
@@ -118,6 +118,6 @@ annotatedRunComponent = R.staticComponent "AnnotatedRun" cpt
...
@@ -118,6 +118,6 @@ annotatedRunComponent = R.staticComponent "AnnotatedRun" cpt
HTML.span { className: className list
HTML.span { className: className list
, onClick: mkEffectFn1 $ \e -> onSelect text (Just list) e} [ HTML.text text ]
, onClick: mkEffectFn1 $ \e -> onSelect text (Just list) e} [ HTML.text text ]
where
where
className
list = "annotation-run bg-" <> termBootstrapClass list
className
list' = "annotation-run bg-" <> termBootstrapClass list'
src/Gargantext/Components/Annotation/Menu.purs
View file @
1105cefb
...
@@ -2,16 +2,16 @@
...
@@ -2,16 +2,16 @@
module Gargantext.Components.Annotation.Menu where
module Gargantext.Components.Annotation.Menu where
import Prelude (
Unit, (==), ($), (<>), unit, pure, otherwise, const
)
import Prelude (
Unit, pure, ($), (<>), (==)
)
import Data.Array as A
import Data.Array as A
import Data.Maybe (
Maybe(..), maybe'
)
import Data.Maybe (
Maybe(..)
)
import Effect (
Effect
)
import Effect (
Effect
)
import Effect.Uncurried (
mkEffectFn1
)
import Effect.Uncurried (
mkEffectFn1
)
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as HTML
import Reactix.DOM.HTML as HTML
import Gargantext.Types (
TermList(..), termListName
)
import Gargantext.Types (
TermList(..), termListName
)
import Gargantext.Components.Annotation.Utils (
termBootstrapClass
)
import Gargantext.Components.Annotation.Utils (
termBootstrapClass
)
import Gargantext.Components.ContextMenu.ContextMenu as CM
import Gargantext.Components.ContextMenu.ContextMenu as CM
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Reactix as R2
...
...
src/Gargantext/Components/
Layout
.purs
→
src/Gargantext/Components/
App
.purs
View file @
1105cefb
module Gargantext.Components.
Layout
where
module Gargantext.Components.
App
where
import Prelude
import Data.Array (fromFoldable)
import Data.Foldable (fold, intercalate)
import Data.Foldable (fold, intercalate)
import Data.Lens (over)
import Data.Maybe (Maybe(..))
import Data.Maybe (Maybe(..), maybe')
import Data.Map as Map
import Data.Newtype (unwrap)
import Data.Tuple (fst, snd)
import Data.Tuple (fst, snd)
import Data.Tuple.Nested((/\))
import DOM.Simple.Console (log2)
import Effect (Effect)
import Effect.Aff (launchAff)
import React.DOM (button, div, text)
import React.DOM.Props (_id, className, onClick, role, style)
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as H
import Reactix.DOM.HTML as H
-- import Unsafe.Coerce (unsafeCoerce)
import Gargantext.BootstrapNative (createDropdown)
import Gargantext.Prelude
import Gargantext.Components.Data.Lang (Lang(..))
import Gargantext.Components.Data.Lang (Lang(..))
import Gargantext.Components.EndsChooser as EndsChooser
import Gargantext.Components.Forest (forest)
import Gargantext.Components.EndsSummary (endsSummary)
import Gargantext.Components.GraphExplorer (explorerLayout)
import Gargantext.Components.GraphExplorer (explorerLayout)
import Gargantext.Components.Login.Types (AuthData(..))
import Gargantext.Components.Login (login)
import Gargantext.Components.Login (Auths, getCurrentAuth, setAuths, login)
import Gargantext.Components.Search.SearchBar as SB
import Gargantext.Components.Search.SearchBar as SB
import Gargantext.Components.
Tree as Tree
import Gargantext.Components.
Search.Types (allDatabases)
import Gargantext.Config (
Ends, defaultEnds, backendKey
)
import Gargantext.Config (
defaultFrontends, defaultBackends
)
import Gargantext.Components.Folder (folder)
import Gargantext.Components.Folder (folder)
import Gargantext.Ends (Frontends)
import Gargantext.Pages.Annuaire (annuaireLayout)
import Gargantext.Pages.Annuaire (annuaireLayout)
import Gargantext.Pages.Annuaire.User.Contacts (userLayout)
import Gargantext.Pages.Annuaire.User.Contacts (userLayout)
import Gargantext.Pages.Corpus (corpusLayout)
import Gargantext.Pages.Corpus (corpusLayout)
...
@@ -35,99 +24,76 @@ import Gargantext.Pages.Corpus.Document (documentLayout)
...
@@ -35,99 +24,76 @@ import Gargantext.Pages.Corpus.Document (documentLayout)
import Gargantext.Pages.Corpus.Dashboard (dashboardLayout)
import Gargantext.Pages.Corpus.Dashboard (dashboardLayout)
import Gargantext.Pages.Lists (listsLayout)
import Gargantext.Pages.Lists (listsLayout)
import Gargantext.Pages.Texts (textsLayout)
import Gargantext.Pages.Texts (textsLayout)
import Gargantext.Pages.Home (layoutLanding)
import Gargantext.Pages.Home (homeLayout)
import Gargantext.Router (Routes(..), routing, useHashRouter)
import Gargantext.Router (router)
import Gargantext.Routes (AppRoute(..))
import Gargantext.Hooks.Router (useHashRouter)
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Reactix as R2
import Gargantext.
Global (Global, defaultGlobal
)
import Gargantext.
Sessions (Session, Sessions, useSessions, unSessions
)
-- TODO (what does this mean?)
-- TODO (what does this mean?)
-- tree changes endConfig state => trigger endConfig change in outerLayout, layoutFooter etc
-- tree changes endConfig state => trigger endConfig change in outerLayout, layoutFooter etc
type State =
app :: {} -> R.Element
( ends :: R.State Ends
app props = R.createElement appCpt props []
, auths :: R.State Auths
, route :: R.State Routes
appCpt :: R.Component ()
, showLogin :: R.State Boolean
appCpt = R.hooksComponent "G.C.App.app" cpt where
, showCorpus :: R.State Boolean
frontends = defaultFrontends
, showTree :: R.State Boolean )
cpt _ _ = do
sessions <- useSessions
layout :: _ -> R.Element
route <- useHashRouter router Home
layout _ = R.createElement layoutCpt {} []
showLogin <- R.useState' false
showCorpus <- R.useState' false
layoutCpt :: R.Component ( )
let tree = forestLayout frontends (fst sessions) (fst route) (snd showLogin)
layoutCpt = R.hooksComponent "Layout" cpt
let mCurrentRoute = Just $ fst route
where
let setVisible = snd showLogin
cpt _ _ = do
let backends = fromFoldable defaultBackends
state <- usePagesState
pure $ case unSessions (fst sessions) of
pure $ pages state
Nothing -> tree $ homeLayout EN
Just session ->
pages :: Record State -> R.Element
case (fst route) of
pages props = R.createElement pagesCpt props []
Home -> tree $ homeLayout EN
Login -> login { sessions, backends, setVisible }
pagesCpt :: R.Component State
Folder _ -> tree $ folder {}
pagesCpt = R.staticComponent "Pages" cpt
Corpus nodeId -> tree $ corpusLayout { nodeId }
Texts nodeId -> tree $ textsLayout { nodeId, session }
Lists nodeId -> tree $ listsLayout { nodeId, session }
Dashboard -> tree $ dashboardLayout {}
Annuaire annuaireId -> tree $ annuaireLayout { annuaireId, session }
UserPage nodeId -> tree $ userLayout { nodeId, session }
ContactPage nodeId -> tree $ userLayout { nodeId, session }
CorpusDocument corpusId listId nodeId ->
tree $ documentLayout { nodeId, listId, session, corpusId: Just corpusId }
Document listId nodeId ->
tree $ documentLayout { nodeId, listId, session, corpusId: Nothing }
PGraphExplorer graphId ->
simpleLayout (fst sessions) $
explorerLayout { graphId, mCurrentRoute, session, treeId: Nothing }
forestLayout :: Frontends -> Sessions -> AppRoute -> R2.Setter Boolean -> R.Element -> R.Element
forestLayout frontends sessions route showLogin child =
R.fragment [ searchBar sessions, row main, footer {} ]
where
where
cpt state@{ends, route, showLogin, showCorpus, showTree} _ = do
row child' = H.div {className: "row"} [child']
case (fst route) of
main =
Home -> tree $ layoutLanding EN
Login -> login { ends: (fst ends), setVisible: (snd showLogin) }
Folder _ -> tree $ folder {}
Corpus nodeId -> tree $ corpusLayout {nodeId, ends: fst ends}
Texts nodeId -> tree $ textsLayout {nodeId, ends: fst ends}
Lists nodeId -> tree $ listsLayout {nodeId, ends: fst ends}
Dashboard -> tree $ dashboardLayout {}
Annuaire annuaireId -> tree $ annuaireLayout { annuaireId, ends: fst ends }
UserPage nodeId -> tree $ userLayout { nodeId, ends: fst ends }
ContactPage nodeId -> tree $ userLayout { nodeId, ends: fst ends }
CorpusDocument corpusId listId nodeId ->
tree $ documentLayout { nodeId, listId, corpusId: Just corpusId, ends: fst ends }
Document listId nodeId ->
tree $ documentLayout { nodeId, listId, corpusId: Nothing, ends: fst ends }
PGraphExplorer graphId ->
simpleLayout state $ explorerLayout {graphId, mCurrentRoute, treeId: Nothing, ends: fst ends}
where
mCurrentRoute = Just $ fst route
tree = treeLayout state
usePagesState :: R.Hooks (Record State)
usePagesState = do
ends <- R.useState' defaultEnds
auths <- R.useState' Map.empty
route <- useHashRouter routing Home
showLogin <- R.useState' false
showCorpus <- R.useState' false
showTree <- R.useState' false
pure $ {ends, auths, route, showLogin, showCorpus, showTree}
treeLayout :: Record State -> R.Element -> R.Element
treeLayout state@{ends, auths, route, showTree} child =
R.fragment [ searchBar state, row layout', footer {} ]
where
backendAuth = getCurrentAuth (fst ends) (fst auths)
layout' = maybe' (\_ -> mainPage false child) (withTree <<< unwrap) backendAuth
withTree {tree_id} =
R.fragment
R.fragment
[ H.div {className: "col-md-2", style: {paddingTop: "60px"}}
[ H.div {className: "col-md-2", style: {paddingTop: "60px"}}
[ Tree.treeView { root: tree_id, mCurrentRoute: Just (fst route), ends: (fst ends) } ]
[ forest {sessions, route, frontends, showLogin} ]
, mainPage true child ]
, mainPage child ]
row child' = H.div {className: "row"} [child']
-- Simple layout does not accommodate the tree
-- Simple layout does not accommodate the tree
simpleLayout ::
Record State
-> R.Element -> R.Element
simpleLayout ::
Sessions
-> R.Element -> R.Element
simpleLayout s
tate child = R.fragment [ searchBar state
, child, footer {}]
simpleLayout s
essions child = R.fragment [ searchBar sessions
, child, footer {}]
mainPage ::
Boolean ->
R.Element -> R.Element
mainPage :: R.Element -> R.Element
mainPage
showTree
child =
mainPage child =
H.div {className}
H.div {className
: "col-md-10"
}
[ H.div {id: "page-wrapper"}
[ H.div {id: "page-wrapper"}
[ H.div {className: "container-fluid"} [ child ] ] ]
[ H.div {className: "container-fluid"} [ child ] ] ]
where
className
| showTree = "col-md-10"
| otherwise = "col-md-12"
searchBar ::
Record State
-> R.Element
searchBar ::
Sessions
-> R.Element
searchBar s
tate@{ends}
=
searchBar s
essions
=
H.div { id: "dafixedtop", role: "navigation"
H.div { id: "dafixedtop", role: "navigation"
, className: "navbar navbar-inverse navbar-fixed-top" }
, className: "navbar navbar-inverse navbar-fixed-top" }
[ H.div { className: "container-fluid" }
[ H.div { className: "container-fluid" }
...
@@ -135,8 +101,11 @@ searchBar state@{ends} =
...
@@ -135,8 +101,11 @@ searchBar state@{ends} =
[ logo
[ logo
, H.div { className: "collapse navbar-collapse" }
, H.div { className: "collapse navbar-collapse" }
[ divDropdownLeft
[ divDropdownLeft
, SB.searchBar (SB.defaultProps (fst ends))
, search ] ] ] ]
, divDropdownRight state ] ] ] ]
where
search = case unSessions sessions of
Just session -> SB.searchBar {session, databases: allDatabases}
Nothing -> R.fragment []
logo :: R.Element
logo :: R.Element
logo =
logo =
...
@@ -244,49 +213,6 @@ liNav (LiNav { title : title'
...
@@ -244,49 +213,6 @@ liNav (LiNav { title : title'
]
]
]
]
loginLinks :: Record State -> R.Element
loginLinks state@{ends, auths, showLogin} =
case getCurrentAuth (fst ends) (fst auths) of
Nothing -> loginLink
Just _ -> logoutLink
where
loginLink =
H.a { aria: {hidden : true}
, className: "glyphicon glyphicon-log-in"
, on: {click: \e -> (snd showLogin) (const true)}
, style: {color:"white"}
, title: "Log in and save your time"
-- TODO hover: bold
}
[H.text " Login / Signup"]
-- TODO dropdown to logout
logoutLink =
H.a { aria: {hidden : true}
, className: "glyphicon glyphicon-log-out"
, on: {click: \e -> logout state}
, style: {color:"white"}
, title: "Log out" -- TODO
-- TODO hover: bold
}
[H.text " Logout"]
logout :: Record State -> Effect Unit
logout {ends, auths} = (snd auths) (const auths2) *> setAuths (Just auths2)
where
key = backendKey (fst ends).backend
auths2 = Map.delete key (fst auths)
divDropdownRight :: Record State -> R.Element
divDropdownRight props = R.createElement divDropdownRightCpt props []
divDropdownRightCpt :: R.Component State
divDropdownRightCpt = R.staticComponent "G.C.Layout.divDropdownRight" cpt
where
cpt state@{ends} _ =
H.ul {className: "nav navbar-nav pull-right"}
[ endsSummary (fst ends), loginLinks state ]
footer :: {} -> R.Element
footer :: {} -> R.Element
footer props = R.createElement footerCpt props []
footer props = R.createElement footerCpt props []
...
...
src/Gargantext/Components/Charts/Options/Series.purs
View file @
1105cefb
module Gargantext.Components.Charts.Options.Series where
module Gargantext.Components.Charts.Options.Series where
import Data.Maybe
import Prelude (class Show, bind, map, pure, show, ($), (+), (<<<), (<>))
import Data.Argonaut (class DecodeJson, decodeJson, (.:))
import Data.Array (foldl)
import Data.Array (foldl)
import Data.Maybe (Maybe(..), maybe)
import Record.Unsafe (unsafeSet)
import Record.Unsafe (unsafeSet)
import Unsafe.Coerce (unsafeCoerce)
import Unsafe.Coerce (unsafeCoerce)
import Prelude
import Data.Argonaut (class DecodeJson, decodeJson, (.:))
import Gargantext.Types (class Optional)
import Gargantext.Types (class Optional)
import Gargantext.Components.Charts.Options.Font (ItemStyle, Tooltip)
import Gargantext.Components.Charts.Options.Font (ItemStyle, Tooltip)
import Gargantext.Components.Charts.Options.Data (DataD1, DataD2)
import Gargantext.Components.Charts.Options.Data (DataD1, DataD2)
...
@@ -181,7 +180,7 @@ toJsTree maybeSurname (TreeNode x) =
...
@@ -181,7 +180,7 @@ toJsTree maybeSurname (TreeNode x) =
, children : (map (toJsTree (Just name)) x.children)
, children : (map (toJsTree (Just name)) x.children)
}
}
where
where
name = maybe "" (\x
-> x
<> ">") maybeSurname <> x.name
name = maybe "" (\x
' -> x'
<> ">") maybeSurname <> x.name
data TreeNode = TreeNode { name :: String
data TreeNode = TreeNode { name :: String
, value :: Int
, value :: Int
...
...
src/Gargantext/Components/ContextMenu/ContextMenu.purs
View file @
1105cefb
...
@@ -15,7 +15,7 @@ import DOM.Simple.Window ( window )
...
@@ -15,7 +15,7 @@ import DOM.Simple.Window ( window )
import DOM.Simple.Document ( document )
import DOM.Simple.Document ( document )
import DOM.Simple.Types ( DOMRect )
import DOM.Simple.Types ( DOMRect )
import Effect (Effect)
import Effect (Effect)
import FFI.Simple (
(...), (..), delay
)
import FFI.Simple (
(..)
)
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as HTML
import Reactix.DOM.HTML as HTML
...
...
src/Gargantext/Components/DocsTable.purs
View file @
1105cefb
-- TODO: this module should be replaced by FacetsTable
-- TODO: this module should be replaced by FacetsTable
module Gargantext.Components.DocsTable where
module Gargantext.Components.DocsTable where
import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, encodeJson, jsonEmptyObject, (.:), (:=), (~>))
import Prelude
import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, jsonEmptyObject, (.:), (:=), (~>))
import Data.Array (drop, take)
import Data.Array (drop, take)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Data.Generic.Rep.Show (genericShow)
...
@@ -15,24 +16,24 @@ import Data.Set as Set
...
@@ -15,24 +16,24 @@ import Data.Set as Set
import Data.Symbol (SProxy(..))
import Data.Symbol (SProxy(..))
import Data.Tuple (Tuple(..), fst)
import Data.Tuple (Tuple(..), fst)
import Data.Tuple.Nested ((/\))
import Data.Tuple.Nested ((/\))
import DOM.Simple.Console (log)
import DOM.Simple.Event as DE
import DOM.Simple.Event as DE
import Effect (Effect)
import Effect (Effect)
import Effect.Aff (Aff, launchAff)
import Effect.Aff (Aff, launchAff)
import Effect.Class (liftEffect)
import Effect.Class (liftEffect)
import Effect.Uncurried (EffectFn1, mkEffectFn1)
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as H
import Reactix.DOM.HTML as H
------------------------------------------------------------------------
------------------------------------------------------------------------
import Gargantext.Prelude
import Gargantext.Config.REST (post, delete)
import Gargantext.Config (Ends, NodeType(..), OrderBy(..), BackendRoute(..), TabType, TabPostQuery(..), url)
import Gargantext.Config.REST (get, put, post, deleteWithBody, delete)
import Gargantext.Components.Node (NodePoly(..))
import Gargantext.Components.Search.Types (Category(..), CategoryQuery(..), favCategory, trashCategory, decodeCategory, putCategories)
import Gargantext.Components.Search.Types (Category(..), CategoryQuery(..), favCategory, trashCategory, decodeCategory, putCategories)
import Gargantext.Components.Table as T
import Gargantext.Components.Table as T
import Gargantext.Ends (url)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Utils.DecodeMaybe ((.|))
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Reactix as R2
import Gargantext.Router as Router
import Gargantext.Routes as Routes
import Gargantext.Routes (SessionRoute(NodeAPI))
import Gargantext.Sessions (Session)
import Gargantext.Types (NodeType(..), OrderBy(..), TabType, TabPostQuery(..))
------------------------------------------------------------------------
------------------------------------------------------------------------
type NodeID = Int
type NodeID = Int
...
@@ -46,7 +47,7 @@ type Props =
...
@@ -46,7 +47,7 @@ type Props =
, listId :: Int
, listId :: Int
, corpusId :: Maybe Int
, corpusId :: Maybe Int
, showSearch :: Boolean
, showSearch :: Boolean
,
ends :: Ends
)
,
session :: Session
)
-- ^ tabType is not ideal here since it is too much entangled with tabs and
-- ^ tabType is not ideal here since it is too much entangled with tabs and
-- ngramtable. Let's see how this evolves. )
-- ngramtable. Let's see how this evolves. )
...
@@ -57,7 +58,7 @@ type PageLoaderProps =
...
@@ -57,7 +58,7 @@ type PageLoaderProps =
, listId :: Int
, listId :: Int
, corpusId :: Maybe Int
, corpusId :: Maybe Int
, query :: Query
, query :: Query
,
ends :: Ends
)
,
session :: Session
)
type LocalCategories = Map Int Category
type LocalCategories = Map Int Category
type Query = String
type Query = String
...
@@ -136,23 +137,22 @@ layoutDocview :: R.State Query -> R.State T.Params -> Record Props -> R.Element
...
@@ -136,23 +137,22 @@ layoutDocview :: R.State Query -> R.State T.Params -> Record Props -> R.Element
layoutDocview query tableParams@(params /\ _) p = R.createElement el p []
layoutDocview query tableParams@(params /\ _) p = R.createElement el p []
where
where
el = R.hooksComponent "LayoutDocView" cpt
el = R.hooksComponent "LayoutDocView" cpt
cpt {
ends
, nodeId, tabType, listId, corpusId, totalRecords, chart, showSearch} _children = do
cpt {
session
, nodeId, tabType, listId, corpusId, totalRecords, chart, showSearch} _children = do
pure $ H.div {className: "container1"}
pure $ H.div {className: "container1"}
[ H.div {className: "row"}
[ H.div {className: "row"}
[ chart
[ chart
, if showSearch then searchBar query else H.div {} []
, if showSearch then searchBar query else H.div {} []
, H.div {className: "col-md-12"}
, H.div {className: "col-md-12"}
[ pageLoader tableParams {
ends
, nodeId, totalRecords, tabType, listId, corpusId, query: fst query} ] ] ]
[ pageLoader tableParams {
session
, nodeId, totalRecords, tabType, listId, corpusId, query: fst query} ] ] ]
onClickTrashAll nodeId = mkEffectFn1 $ \_ ->
do
-- onClickTrashAll nodeId _ =
do
launchAff $ deleteAllDocuments p.ends
nodeId
-- launchAff $ deleteAllDocuments p.session
nodeId
{-, H.div {className: "col-md-1 col-md-offset-11"}
{-, H.div {className: "col-md-1 col-md-offset-11"}
[ pageLoader p.
ends
tableParams {nodeId, totalRecords, tabType, listId, corpusId, query: fst query} ]
[ pageLoader p.
session
tableParams {nodeId, totalRecords, tabType, listId, corpusId, query: fst query} ]
, H.div {className: "col-md-1 col-md-offset-11"}
, H.div {className: "col-md-1 col-md-offset-11"}
[ H.button { className: "btn"
[ H.button { className: "btn"
, style: {backgroundColor: "peru", color : "white", border : "white"}
, style: {backgroundColor: "peru", color : "white", border : "white"}
, onClick: onClickTrashAll nodeId
, on: { click: onClickTrashAll nodeId } }
}
[ H.i {className: "glyphitem glyphicon glyphicon-trash"} []
[ H.i {className: "glyphitem glyphicon glyphicon-trash"} []
, H.text "Trash all"
, H.text "Trash all"
]
]
...
@@ -211,11 +211,11 @@ type PageParams = { nodeId :: Int
...
@@ -211,11 +211,11 @@ type PageParams = { nodeId :: Int
, query :: Query
, query :: Query
, params :: T.Params}
, params :: T.Params}
loadPage ::
Ends
-> PageParams -> Aff (Array DocumentsView)
loadPage ::
Session
-> PageParams -> Aff (Array DocumentsView)
loadPage
ends
{nodeId, tabType, query, listId, corpusId, params: {limit, offset, orderBy}} = do
loadPage
session
{nodeId, tabType, query, listId, corpusId, params: {limit, offset, orderBy}} = do
l
ogs
"loading documents page: loadPage with Offset and limit"
l
iftEffect $ log
"loading documents page: loadPage with Offset and limit"
-- res <- get $ toUrl endConfigStateful Back (Tab tabType offset limit (convOrderBy <$> orderBy)) (Just nodeId)
-- res <- get $ toUrl endConfigStateful Back (Tab tabType offset limit (convOrderBy <$> orderBy)) (Just nodeId)
let url2 = (url
ends
(NodeAPI Node (Just nodeId))) <> "/table"
let url2 = (url
session
(NodeAPI Node (Just nodeId))) <> "/table"
res <- post url2 $ TabPostQuery {
res <- post url2 $ TabPostQuery {
offset
offset
, limit
, limit
...
@@ -256,10 +256,10 @@ renderPage (_ /\ setTableParams) p res = R.createElement el p []
...
@@ -256,10 +256,10 @@ renderPage (_ /\ setTableParams) p res = R.createElement el p []
gi _ = "glyphicon glyphicon-star-empty"
gi _ = "glyphicon glyphicon-star-empty"
trashStyle Trash = {textDecoration: "line-through"}
trashStyle Trash = {textDecoration: "line-through"}
trashStyle _ = {textDecoration: "none"}
trashStyle _ = {textDecoration: "none"}
corpusDocument (Just corpusId) = Route
r
.CorpusDocument corpusId
corpusDocument (Just corpusId) = Route
s
.CorpusDocument corpusId
corpusDocument _ = Route
r
.Document
corpusDocument _ = Route
s
.Document
cpt {
ends
, nodeId, corpusId, listId, totalRecords} _children = do
cpt {
session
, nodeId, corpusId, listId, totalRecords} _children = do
localCategories <- R.useState' (mempty :: LocalCategories)
localCategories <- R.useState' (mempty :: LocalCategories)
pure $ T.table
pure $ T.table
{ rows: rows localCategories
{ rows: rows localCategories
...
@@ -292,15 +292,15 @@ renderPage (_ /\ setTableParams) p res = R.createElement el p []
...
@@ -292,15 +292,15 @@ renderPage (_ /\ setTableParams) p res = R.createElement el p []
onClick (_ /\ setLocalCategories) catType nid cat = \_-> do
onClick (_ /\ setLocalCategories) catType nid cat = \_-> do
let newCat = if (catType == Favorite) then (favCategory cat) else (trashCategory cat)
let newCat = if (catType == Favorite) then (favCategory cat) else (trashCategory cat)
setLocalCategories $ insert nid newCat
setLocalCategories $ insert nid newCat
void $ launchAff $ putCategories
ends
nodeId $ CategoryQuery {nodeIds: [nid], category: newCat}
void $ launchAff $ putCategories
session
nodeId $ CategoryQuery {nodeIds: [nid], category: newCat}
pageLoader :: R.State T.Params -> Record PageLoaderProps -> R.Element
pageLoader :: R.State T.Params -> Record PageLoaderProps -> R.Element
pageLoader tableParams@(pageParams /\ _) p = R.createElement el p []
pageLoader tableParams@(pageParams /\ _) p = R.createElement el p []
where
where
el = R.hooksComponent "PageLoader" cpt
el = R.hooksComponent "PageLoader" cpt
cpt p
@{ends
, nodeId, listId, corpusId, tabType, query} _children = do
cpt p
rops@{session
, nodeId, listId, corpusId, tabType, query} _children = do
useLoader {nodeId, listId, corpusId, tabType, query, params: pageParams} (loadPage
ends
) $
useLoader {nodeId, listId, corpusId, tabType, query, params: pageParams} (loadPage
session
) $
\loaded -> renderPage tableParams p loaded
\loaded -> renderPage tableParams p
rops
loaded
---------------------------------------------------------
---------------------------------------------------------
sampleData' :: DocumentsView
sampleData' :: DocumentsView
...
@@ -344,11 +344,11 @@ searchResults :: SearchQuery -> Aff Int
...
@@ -344,11 +344,11 @@ searchResults :: SearchQuery -> Aff Int
searchResults squery = post "http://localhost:8008/count" unit
searchResults squery = post "http://localhost:8008/count" unit
-- TODO
-- TODO
documentsUrl ::
Ends
-> Int -> String
documentsUrl ::
Session
-> Int -> String
documentsUrl
ends nodeId = url ends
(NodeAPI Node (Just nodeId)) <> "/documents"
documentsUrl
session nodeId = url session
(NodeAPI Node (Just nodeId)) <> "/documents"
deleteAllDocuments ::
Ends
-> Int -> Aff (Array Int)
deleteAllDocuments ::
Session
-> Int -> Aff (Array Int)
deleteAllDocuments
ends = delete <<< documentsUrl ends
deleteAllDocuments
session = delete <<< documentsUrl session
-- TODO: not optimal but Data.Set lacks some function (Set.alter)
-- TODO: not optimal but Data.Set lacks some function (Set.alter)
toggleSet :: forall a. Ord a => a -> Set a -> Set a
toggleSet :: forall a. Ord a => a -> Set a -> Set a
...
...
src/Gargantext/Components/EndsChooser.purs
deleted
100644 → 0
View file @
80557556
-- |
module Gargantext.Components.EndsChooser
-- (
-- )
where
import Prelude (($), pure)
import Reactix as R
import Reactix.DOM.HTML as H
import Gargantext.Config (Backend, Ends, defaultEnds, defaultEnds')
import Gargantext.Utils.Reactix as R2
type Props = ( ends :: R.State Ends )
useEnds :: R.Hooks (R.State Ends)
useEnds = R.useState' defaultEnds
endsChooser :: Record Props -> R.Element
endsChooser props = R.createElement endsChooserCpt props []
endsChooserCpt :: R.Component Props
endsChooserCpt = R.hooksComponent "G.C.EndsChooser.endsChooser" cpt
where
cpt {ends} _ = do
pure $ R.fragment []
-- el = R.hooksComponent "EndConfigChooserCpt" cpt
-- cpt {state} _children = do
-- R.useEffect $ pure $
-- if (configState /= state) then do
-- _ <- log2 "update state: " configState
-- _ <- d $ ConfigStateA $ C.UpdateState configState
-- _ <- log2 "logout" ""
-- d $ Logout
-- else
-- pure $ unit
-- pure $ H.span {}
-- [ endConfigChooser (configState /\ setConfigState)
-- , H.span {className: "text-info"}
-- [ H.text $ C.endConfigDisplayName configState.endConfig ]
-- , H.span {className: "text-danger"}
-- [ H.text $ C.endConfigDisplayName state.endConfig ]
-- ]
-- endConfigChooser :: R.State Ends -> R.Element
-- endConfigChooser (configState /\ setConfigState) = R.createElement el {} []
-- where
-- el = R.hooksComponent "EndConfigChooser" cpt
-- cpt {} _ = do
-- -- NOTE Need to rebind the component after rerender
-- R.useEffect do
-- _ <- pure $ createDropdown "end-config-chooser"
-- pure $ pure unit
-- pure $ H.li {className: "dropdown"}
-- [ H.a { className: "navbar-text dropdown-toggle"
-- , href: "#"
-- , role: "button"
-- , data: {toggle: "dropdown"}
-- , id: "end-config-chooser"
-- }
-- [ H.text $ C.endConfigDisplayName configState.endConfig ]
-- , H.ul { className: "dropdown-menu"
-- } (liItem <$> C.endConfigOptions)
-- ]
-- liItem :: C.EndConfigOption -> R.Element
-- liItem {endConfig, displayName} =
-- H.li {on: {click: onClick endConfig}}
-- [ H.a {href: "#"} [H.text displayName] ]
-- onClick endConfig = \_ -> do
-- log2 "set end config" endConfig
-- setConfigState $ \st -> st {endConfig = endConfig}
-- type BackendProps = ( ends :: R.State Ends, backend :: Backend )
-- backendCpt :: R.Component BackendProps
-- backendCpt = R.hooksComponent "G.C.EndsChooser.backend" cpt
-- where
-- cpt {ends, backend} _ = do
src/Gargantext/Components/EndsSummary.purs
deleted
100644 → 0
View file @
80557556
module Gargantext.Components.EndsSummary
-- (
-- )
where
import Reactix as R
import Reactix.DOM.HTML as H
import Data.Semigroup ((<>))
import Gargantext.Config (Ends)
endsSummary :: Ends -> R.Element
endsSummary ends = H.div {className: "text-info"} [ H.text text ]
where text = "Connected to " <> ends.backend.name
src/Gargantext/Components/FacetsTable.purs
View file @
1105cefb
...
@@ -3,10 +3,9 @@
...
@@ -3,10 +3,9 @@
-- has not been ported to this module yet.
-- has not been ported to this module yet.
module Gargantext.Components.FacetsTable where
module Gargantext.Components.FacetsTable where
import
Control.Monad.Cont.Trans (lift)
import
Prelude
import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson,
encodeJson,
jsonEmptyObject, (.:), (:=), (~>))
import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, jsonEmptyObject, (.:), (:=), (~>))
import Data.Array (filter, (!!))
import Data.Array (filter, (!!))
import Data.Foldable (intercalate)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Data.Generic.Rep.Show (genericShow)
import Data.Maybe (Maybe(..))
import Data.Maybe (Maybe(..))
...
@@ -14,23 +13,24 @@ import Data.Set (Set)
...
@@ -14,23 +13,24 @@ import Data.Set (Set)
import Data.Set as Set
import Data.Set as Set
import Data.Tuple (fst)
import Data.Tuple (fst)
import Data.Tuple.Nested ((/\))
import Data.Tuple.Nested ((/\))
import DOM.Simple.Console (log)
import Effect (Effect)
import Effect (Effect)
import Effect.Aff (Aff, launchAff_)
import Effect.Class (liftEffect)
import Effect.Class (liftEffect)
import Effect.Aff (Aff, launchAff_)
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as H
import Reactix.DOM.HTML as H
------------------------------------------------------------------------
------------------------------------------------------------------------
import Gargantext.Prelude
import Gargantext.Config.REST (post, deleteWithBody)
import Gargantext.Config (Ends, NodeType(..), OrderBy(..), NodePath(..), BackendRoute(..), TabType, url)
import Gargantext.Ends (url)
import Gargantext.Config.REST (put, post, deleteWithBody)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Components.Search.Types (Category(..), CategoryQuery(..), favCategory,
trashCategory,
decodeCategory, putCategories)
import Gargantext.Components.Search.Types (Category(..), CategoryQuery(..), favCategory, decodeCategory, putCategories)
import Gargantext.Components.Table as T
import Gargantext.Components.Table as T
import Gargantext.Router as Router
import Gargantext.Routes (SessionRoute(Search,NodeAPI))
import Gargantext.Sessions (Session)
import Gargantext.Types (NodeType(..), OrderBy(..), NodePath(..))
import Gargantext.Utils (toggleSet)
import Gargantext.Utils (toggleSet)
import Gargantext.Utils.DecodeMaybe ((.|))
import Gargantext.Utils.DecodeMaybe ((.|))
import Gargantext.Utils.Reactix as R2
------------------------------------------------------------------------
------------------------------------------------------------------------
type NodeID = Int
type NodeID = Int
...
@@ -63,7 +63,7 @@ type Props =
...
@@ -63,7 +63,7 @@ type Props =
, totalRecords :: Int
, totalRecords :: Int
, chart :: R.Element
, chart :: R.Element
, container :: Record T.TableContainerProps -> R.Element
, container :: Record T.TableContainerProps -> R.Element
,
ends :: Ends
,
session :: Session
)
)
-- | Tracks the ids of documents to delete and that have been deleted
-- | Tracks the ids of documents to delete and that have been deleted
...
@@ -164,14 +164,14 @@ docView props = R.createElement docViewCpt props []
...
@@ -164,14 +164,14 @@ docView props = R.createElement docViewCpt props []
docViewCpt :: R.Component Props
docViewCpt :: R.Component Props
docViewCpt = R.hooksComponent "G.C.FacetsTable.DocView" cpt
docViewCpt = R.hooksComponent "G.C.FacetsTable.DocView" cpt
where
where
cpt {
ends
, nodeId, listId, query, totalRecords, chart, container} _ = do
cpt {
session
, nodeId, listId, query, totalRecords, chart, container} _ = do
deletions <- R.useState' initialDeletions
deletions <- R.useState' initialDeletions
path <- R.useState' $ initialPagePath {nodeId, listId, query,
ends
}
path <- R.useState' $ initialPagePath {nodeId, listId, query,
session
}
pure $ H.div { className: "container1" }
pure $ H.div { className: "container1" }
[ H.div { className: "row" }
[ H.div { className: "row" }
[ chart
[ chart
, H.div { className: "col-md-12" }
, H.div { className: "col-md-12" }
[ pageLayout { deletions, totalRecords, container,
ends
, path } ]
[ pageLayout { deletions, totalRecords, container,
session
, path } ]
, H.div { className: "col-md-12" }
, H.div { className: "col-md-12" }
[ H.button { style: buttonStyle, on: { click: trashClick deletions } }
[ H.button { style: buttonStyle, on: { click: trashClick deletions } }
[ H.i { className: "glyphitem glyphicon glyphicon-trash"
[ H.i { className: "glyphitem glyphicon glyphicon-trash"
...
@@ -181,19 +181,19 @@ docViewCpt = R.hooksComponent "G.C.FacetsTable.DocView" cpt
...
@@ -181,19 +181,19 @@ docViewCpt = R.hooksComponent "G.C.FacetsTable.DocView" cpt
buttonStyle =
buttonStyle =
{ backgroundColor: "peru", padding: "9px", color: "white"
{ backgroundColor: "peru", padding: "9px", color: "white"
, border: "white", float: "right" }
, border: "white", float: "right" }
trashClick deletions _ = performDeletions
ends
nodeId deletions
trashClick deletions _ = performDeletions
session
nodeId deletions
performDeletions ::
Ends
-> Int -> R.State Deletions -> Effect Unit
performDeletions ::
Session
-> Int -> R.State Deletions -> Effect Unit
performDeletions
ends
nodeId (deletions /\ setDeletions) =
performDeletions
session
nodeId (deletions /\ setDeletions) =
launchAff_ call *> setDeletions del
launchAff_ call *> setDeletions del
where
where
q = {documents: Set.toUnfoldable deletions.pending}
q = {documents: Set.toUnfoldable deletions.pending}
call = deleteDocuments
ends
nodeId (DeleteDocumentQuery q)
call = deleteDocuments
session
nodeId (DeleteDocumentQuery q)
del {pending, deleted} = {pending: mempty, deleted: deleted <> pending}
del {pending, deleted} = {pending: mempty, deleted: deleted <> pending}
-- markCategory :: Ends -> NodeID -> _
-> Array NodeID -> Effect Unit
markCategory :: Session -> NodeID -> Category
-> Array NodeID -> Effect Unit
markCategory
ends
nodeId category nids =
markCategory
session
nodeId category nids =
void $ launchAff_ $putCategories
ends
nodeId (CategoryQuery q)
void $ launchAff_ $putCategories
session
nodeId (CategoryQuery q)
where -- TODO add array of delete rows here
where -- TODO add array of delete rows here
q = {nodeIds: nids, category: favCategory category}
q = {nodeIds: nids, category: favCategory category}
...
@@ -207,12 +207,12 @@ docViewGraph props = R.createElement docViewCpt props []
...
@@ -207,12 +207,12 @@ docViewGraph props = R.createElement docViewCpt props []
docViewGraphCpt :: R.Component Props
docViewGraphCpt :: R.Component Props
docViewGraphCpt = R.hooksComponent "FacetsDocViewGraph" cpt
docViewGraphCpt = R.hooksComponent "FacetsDocViewGraph" cpt
where
where
cpt {
ends
, nodeId, listId, query, totalRecords, chart, container} _ = do
cpt {
session
, nodeId, listId, query, totalRecords, chart, container} _ = do
deletions <- R.useState' initialDeletions
deletions <- R.useState' initialDeletions
let buttonStyle = { backgroundColor: "peru", padding : "9px"
let buttonStyle = { backgroundColor: "peru", padding : "9px"
, color : "white", border : "white", float: "right"}
, color : "white", border : "white", float: "right"}
let performClick = \_ -> performDeletions
ends
nodeId deletions
let performClick = \_ -> performDeletions
session
nodeId deletions
path <- R.useState' $ initialPagePath { nodeId, listId, query,
ends
}
path <- R.useState' $ initialPagePath { nodeId, listId, query,
session
}
pure $ R.fragment
pure $ R.fragment
[ H.br {}
[ H.br {}
, H.p {} [ H.text "" ]
, H.p {} [ H.text "" ]
...
@@ -221,21 +221,21 @@ docViewGraphCpt = R.hooksComponent "FacetsDocViewGraph" cpt
...
@@ -221,21 +221,21 @@ docViewGraphCpt = R.hooksComponent "FacetsDocViewGraph" cpt
[ H.div { className: "row" }
[ H.div { className: "row" }
[ chart
[ chart
, H.div { className: "col-md-12" }
, H.div { className: "col-md-12" }
[ pageLayout { totalRecords, deletions, container,
ends
, path }
[ pageLayout { totalRecords, deletions, container,
session
, path }
, H.button { style: buttonStyle, on: { click: performClick } }
, H.button { style: buttonStyle, on: { click: performClick } }
[ H.i { className: "glyphitem glyphicon glyphicon-trash"
[ H.i { className: "glyphitem glyphicon glyphicon-trash"
, style: { marginRight : "9px" } } []
, style: { marginRight : "9px" } } []
, H.text "Delete document!" ] ] ] ] ]
, H.text "Delete document!" ] ] ] ] ]
type PagePath = {nodeId :: Int, listId :: Int, query :: TextQuery, params :: T.Params,
ends :: Ends
}
type PagePath = {nodeId :: Int, listId :: Int, query :: TextQuery, params :: T.Params,
session :: Session
}
initialPagePath :: {
ends :: Ends
, nodeId :: Int, listId :: Int, query :: TextQuery} -> PagePath
initialPagePath :: {
session :: Session
, nodeId :: Int, listId :: Int, query :: TextQuery} -> PagePath
initialPagePath {
ends, nodeId, listId, query} = {ends
, nodeId, listId, query, params: T.initialParams}
initialPagePath {
session, nodeId, listId, query} = {session
, nodeId, listId, query, params: T.initialParams}
loadPage :: PagePath -> Aff (Array DocumentsView)
loadPage :: PagePath -> Aff (Array DocumentsView)
loadPage {
ends
, nodeId, listId, query, params: {limit, offset, orderBy}} = do
loadPage {
session
, nodeId, listId, query, params: {limit, offset, orderBy}} = do
l
ogs
"loading documents page: loadPage with Offset and limit"
l
iftEffect $ log
"loading documents page: loadPage with Offset and limit"
let url2 = url
ends
$ Search { listId, offset, limit, orderBy: convOrderBy <$> orderBy } (Just nodeId)
let url2 = url
session
$ Search { listId, offset, limit, orderBy: convOrderBy <$> orderBy } (Just nodeId)
SearchResults res <- post url2 $ SearchQuery {query}
SearchResults res <- post url2 $ SearchQuery {query}
pure $ res2corpus <$> res.results
pure $ res2corpus <$> res.results
where
where
...
@@ -255,7 +255,7 @@ type PageLayoutProps =
...
@@ -255,7 +255,7 @@ type PageLayoutProps =
( totalRecords :: Int
( totalRecords :: Int
, deletions :: R.State Deletions
, deletions :: R.State Deletions
, container :: Record T.TableContainerProps -> R.Element
, container :: Record T.TableContainerProps -> R.Element
,
ends :: Ends
,
session :: Session
, path :: R.State PagePath
, path :: R.State PagePath
)
)
...
@@ -268,9 +268,9 @@ pageLayout props = R.createElement pageLayoutCpt props []
...
@@ -268,9 +268,9 @@ pageLayout props = R.createElement pageLayoutCpt props []
pageLayoutCpt :: R.Component PageLayoutProps
pageLayoutCpt :: R.Component PageLayoutProps
pageLayoutCpt = R.hooksComponent "G.C.FacetsTable.PageLayout" cpt
pageLayoutCpt = R.hooksComponent "G.C.FacetsTable.PageLayout" cpt
where
where
cpt {totalRecords, deletions, container,
ends
, path} _ = do
cpt {totalRecords, deletions, container,
session
, path} _ = do
useLoader (fst path) loadPage $ \documents ->
useLoader (fst path) loadPage $ \documents ->
page {totalRecords, deletions, container,
ends
, path, documents}
page {totalRecords, deletions, container,
session
, path, documents}
page :: Record PageProps -> R.Element
page :: Record PageProps -> R.Element
page props = R.createElement pageCpt props []
page props = R.createElement pageCpt props []
...
@@ -278,7 +278,7 @@ page props = R.createElement pageCpt props []
...
@@ -278,7 +278,7 @@ page props = R.createElement pageCpt props []
pageCpt :: R.Component PageProps
pageCpt :: R.Component PageProps
pageCpt = R.staticComponent "G.C.FacetsTable.Page" cpt
pageCpt = R.staticComponent "G.C.FacetsTable.Page" cpt
where
where
cpt {totalRecords, container, deletions, documents,
ends
, path: path@({nodeId, listId, query} /\ setPath)} _ = do
cpt {totalRecords, container, deletions, documents,
session
, path: path@({nodeId, listId, query} /\ setPath)} _ = do
T.table { rows, container, colNames, totalRecords, setParams }
T.table { rows, container, colNames, totalRecords, setParams }
where
where
setParams params = setPath (_ {params = params})
setParams params = setPath (_ {params = params})
...
@@ -290,7 +290,7 @@ pageCpt = R.staticComponent "G.C.FacetsTable.Page" cpt
...
@@ -290,7 +290,7 @@ pageCpt = R.staticComponent "G.C.FacetsTable.Page" cpt
isDeleted (DocumentsView {id}) = Set.member id (fst deletions).deleted
isDeleted (DocumentsView {id}) = Set.member id (fst deletions).deleted
pairUrl (Pair {id,label})
pairUrl (Pair {id,label})
| id > 1 = H.a { href, target: "blank" } [ H.text label ]
| id > 1 = H.a { href, target: "blank" } [ H.text label ]
where href = url
ends
$ NodePath NodeContact (Just id)
where href = url
session
$ NodePath NodeContact (Just id)
| otherwise = H.text label
| otherwise = H.text label
comma = H.span {} [ H.text ", " ]
comma = H.span {} [ H.text ", " ]
rows = row <$> filter (not <<< isDeleted) documents
rows = row <$> filter (not <<< isDeleted) documents
...
@@ -307,7 +307,7 @@ pageCpt = R.staticComponent "G.C.FacetsTable.Page" cpt
...
@@ -307,7 +307,7 @@ pageCpt = R.staticComponent "G.C.FacetsTable.Page" cpt
] ]
] ]
, delete: true }
, delete: true }
where
where
markClick _ = markCategory
ends
nodeId category [id]
markClick _ = markCategory
session
nodeId category [id]
toggleClick _ = togglePendingDeletion deletions id
toggleClick _ = togglePendingDeletion deletions id
className = gi category
className = gi category
maybeStricken
maybeStricken
...
@@ -323,6 +323,6 @@ instance encodeJsonDDQuery :: EncodeJson DeleteDocumentQuery where
...
@@ -323,6 +323,6 @@ instance encodeJsonDDQuery :: EncodeJson DeleteDocumentQuery where
encodeJson (DeleteDocumentQuery post) =
encodeJson (DeleteDocumentQuery post) =
"documents" := post.documents ~> jsonEmptyObject
"documents" := post.documents ~> jsonEmptyObject
deleteDocuments ::
Ends
-> Int -> DeleteDocumentQuery -> Aff (Array Int)
deleteDocuments ::
Session
-> Int -> DeleteDocumentQuery -> Aff (Array Int)
deleteDocuments
ends
nodeId = deleteWithBody to
deleteDocuments
session
nodeId = deleteWithBody to
where to = url
ends
(NodeAPI Node (Just nodeId)) <> "/documents"
where to = url
session
(NodeAPI Node (Just nodeId)) <> "/documents"
src/Gargantext/Components/Forest.purs
0 → 100644
View file @
1105cefb
module Gargantext.Components.Forest where
import Prelude (const, show)
import Data.Maybe (Maybe(..))
import Reactix as R
import Reactix.DOM.HTML as H
import Gargantext.Ends (Frontends)
import Gargantext.Routes (AppRoute)
import Gargantext.Sessions (Session(..), Sessions, unSessions)
import Gargantext.Components.Tree (treeView)
import Gargantext.Utils.Reactix as R2
type Props =
( sessions :: Sessions
, route :: AppRoute
, frontends :: Frontends
, showLogin :: R2.Setter Boolean )
forest :: Record Props -> R.Element
forest props = R.createElement forestCpt props []
forestCpt :: R.Component Props
forestCpt = R.staticComponent "G.C.Forest.forest" cpt where
cpt {sessions, route, frontends, showLogin} _ =
R.fragment [ plus showLogin, trees ]
where
trees =
case unSessions sessions of
Nothing -> R.fragment []
Just s@(Session {treeId}) ->
R.fragment
[ H.text (show s)
, treeView { root: treeId, mCurrentRoute: Just route, session: s } ]
plus :: R2.Setter Boolean -> R.Element
plus showLogin =
H.button {on: {click: \_ -> showLogin (const true)}}
[ H.text "+" ]
src/Gargantext/Components/Forms.purs
0 → 100644
View file @
1105cefb
module Gargantext.Components.Forms where
import Reactix as R
import Reactix.DOM.HTML as H
clearfix :: _ -> R.Element
clearfix _ = H.div {className: "clearfix"} []
formGroup :: Array R.Element -> R.Element
formGroup = H.div {className: "form-group"}
center :: Array R.Element -> R.Element
center = H.div {className: "center"}
card :: Array R.Element -> R.Element
card = H.div {className: "card"}
cardBlock :: Array R.Element -> R.Element
cardBlock = H.div {className: "card-block"}
cardGroup :: Array R.Element -> R.Element
cardGroup = H.div {className: "card-group"}
src/Gargantext/Components/Graph.purs
View file @
1105cefb
...
@@ -4,10 +4,9 @@ module Gargantext.Components.Graph
...
@@ -4,10 +4,9 @@ module Gargantext.Components.Graph
-- , forceAtlas2Settings, ForceAtlas2Settings, ForceAtlas2OptionalSettings
-- , forceAtlas2Settings, ForceAtlas2Settings, ForceAtlas2OptionalSettings
-- )
-- )
where
where
import Prelude
import Prelude (bind, discard, pure, ($))
import Data.Maybe (Maybe(..))
import Data.Maybe (Maybe)
import Data.Nullable (Nullable, null)
import Data.Nullable (null)
import DOM.Simple.Console (log2)
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as RH
import Reactix.DOM.HTML as RH
import Gargantext.Hooks.Sigmax
import Gargantext.Hooks.Sigmax
...
...
src/Gargantext/Components/GraphExplorer.purs
View file @
1105cefb
...
@@ -5,19 +5,16 @@ import Gargantext.Prelude hiding (max,min)
...
@@ -5,19 +5,16 @@ import Gargantext.Prelude hiding (max,min)
import Data.FoldableWithIndex (foldMapWithIndex)
import Data.FoldableWithIndex (foldMapWithIndex)
import Data.Foldable (foldMap)
import Data.Foldable (foldMap)
import Data.Int (toNumber)
import Data.Int (toNumber)
import Data.Maybe (Maybe(..)
, fromJust, fromMaybe
)
import Data.Maybe (Maybe(..))
import Data.Sequence as Seq
import Data.Sequence as Seq
import Data.Tuple (fst)
import Data.Tuple (fst)
import Data.Tuple.Nested ((/\))
import Data.Tuple.Nested ((/\))
import Effect (Effect)
import Effect.Aff (Aff)
import Effect.Aff (Aff)
import Thermite (Render, Spec, simpleSpec)
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as RH
import Reactix.DOM.HTML as RH
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Hooks.Sigmax as Sigmax
import Gargantext.Hooks.Sigmax (Sigma)
import Gargantext.Hooks.Sigmax.Sigma (Sigma)
import Gargantext.Hooks.Sigmax.Types as Sigmax
import Gargantext.Hooks.Sigmax.Types as Sigmax
import Gargantext.Components.GraphExplorer.Controls as Controls
import Gargantext.Components.GraphExplorer.Controls as Controls
import Gargantext.Components.GraphExplorer.Sidebar as Sidebar
import Gargantext.Components.GraphExplorer.Sidebar as Sidebar
...
@@ -25,19 +22,19 @@ import Gargantext.Components.GraphExplorer.ToggleButton as Toggle
...
@@ -25,19 +22,19 @@ import Gargantext.Components.GraphExplorer.ToggleButton as Toggle
import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Components.Graph as Graph
import Gargantext.Components.Graph as Graph
import Gargantext.Components.Tree as Tree
import Gargantext.Components.Tree as Tree
import Gargantext.Config (Ends, url)
import Gargantext.Config as Config
import Gargantext.Config.REST (get)
import Gargantext.Config.REST (get)
import Gargantext.Router (Routes(..))
import Gargantext.Ends (url)
import Gargantext.Utils.Reactix as R2
import Gargantext.Routes (SessionRoute(NodeAPI), AppRoute)
import Gargantext.Sessions (Session)
import Gargantext.Types (NodeType(Graph))
type GraphId = Int
type GraphId = Int
type LayoutProps =
type LayoutProps =
( graphId :: GraphId
( graphId :: GraphId
, mCurrentRoute :: Maybe
Routes
, mCurrentRoute :: Maybe
AppRoute
, treeId :: Maybe Int
, treeId :: Maybe Int
,
ends :: Ends
)
,
session :: Session
)
type Props = ( graph :: Maybe Graph.Graph | LayoutProps )
type Props = ( graph :: Maybe Graph.Graph | LayoutProps )
...
@@ -48,10 +45,10 @@ explorerLayout props = R.createElement explorerLayoutCpt props []
...
@@ -48,10 +45,10 @@ explorerLayout props = R.createElement explorerLayoutCpt props []
explorerLayoutCpt :: R.Component LayoutProps
explorerLayoutCpt :: R.Component LayoutProps
explorerLayoutCpt = R.hooksComponent "G.C.GraphExplorer.explorerLayout" cpt
explorerLayoutCpt = R.hooksComponent "G.C.GraphExplorer.explorerLayout" cpt
where
where
cpt {graphId, mCurrentRoute, treeId,
ends
} _ =
cpt {graphId, mCurrentRoute, treeId,
session
} _ =
useLoader graphId (getNodes
ends
) handler
useLoader graphId (getNodes
session
) handler
where
where
handler loaded = explorer {graphId, mCurrentRoute, treeId,
ends
, graph}
handler loaded = explorer {graphId, mCurrentRoute, treeId,
session
, graph}
where graph = Just (convert loaded)
where graph = Just (convert loaded)
explorer :: Record Props -> R.Element
explorer :: Record Props -> R.Element
...
@@ -60,7 +57,7 @@ explorer props = R.createElement explorerCpt props []
...
@@ -60,7 +57,7 @@ explorer props = R.createElement explorerCpt props []
explorerCpt :: R.Component Props
explorerCpt :: R.Component Props
explorerCpt = R.hooksComponent "G.C.GraphExplorer.explorer" cpt
explorerCpt = R.hooksComponent "G.C.GraphExplorer.explorer" cpt
where
where
cpt {
ends
, graphId, mCurrentRoute, treeId, graph} _ = do
cpt {
session
, graphId, mCurrentRoute, treeId, graph} _ = do
controls <- Controls.useGraphControls
controls <- Controls.useGraphControls
state <- useExplorerState
state <- useExplorerState
pure $
pure $
...
@@ -88,9 +85,9 @@ explorerCpt = R.hooksComponent "G.C.GraphExplorer.explorer" cpt
...
@@ -88,9 +85,9 @@ explorerCpt = R.hooksComponent "G.C.GraphExplorer.explorer" cpt
where
where
tree {treeId: Nothing} _ = RH.div { id: "tree" } []
tree {treeId: Nothing} _ = RH.div { id: "tree" } []
tree _ {showTree: false /\ _} = RH.div { id: "tree" } []
tree _ {showTree: false /\ _} = RH.div { id: "tree" } []
tree {mCurrentRoute
, treeId: Just treeId
} _ =
tree {mCurrentRoute
: m, treeId: Just root
} _ =
RH.div { id: "tree", className: "col-md-2" }
RH.div { id: "tree", className: "col-md-2" }
[ Tree.treeView {mCurrentRoute
, root: treeId, ends: ends
} ]
[ Tree.treeView {mCurrentRoute
: m, root, session: session
} ]
outer = RH.div { className: "col-md-12" }
outer = RH.div { className: "col-md-12" }
inner = RH.div { className: "container-fluid", style: { paddingTop: "90px" } }
inner = RH.div { className: "container-fluid", style: { paddingTop: "90px" } }
row1 = RH.div { className: "row", style: { paddingBottom: "10px", marginTop: "-24px" } }
row1 = RH.div { className: "row", style: { paddingBottom: "10px", marginTop: "-24px" } }
...
@@ -100,7 +97,7 @@ explorerCpt = R.hooksComponent "G.C.GraphExplorer.explorer" cpt
...
@@ -100,7 +97,7 @@ explorerCpt = R.hooksComponent "G.C.GraphExplorer.explorer" cpt
pullRight = RH.div { className: "pull-right" }
pullRight = RH.div { className: "pull-right" }
mGraph :: R.Ref (Maybe Sigma
x.Sigma
) -> {graphId :: GraphId, graph :: Maybe Graph.Graph} -> R.Element
mGraph :: R.Ref (Maybe Sigma) -> {graphId :: GraphId, graph :: Maybe Graph.Graph} -> R.Element
mGraph _ {graph: Nothing} = RH.div {} []
mGraph _ {graph: Nothing} = RH.div {} []
mGraph sigmaRef {graphId, graph: Just graph} = graphView sigmaRef {graphId, graph}
mGraph sigmaRef {graphId, graph: Just graph} = graphView sigmaRef {graphId, graph}
...
@@ -127,7 +124,7 @@ type GraphProps = (
...
@@ -127,7 +124,7 @@ type GraphProps = (
, graph :: Graph.Graph
, graph :: Graph.Graph
)
)
graphView :: R.Ref (Maybe Sigma
x.Sigma
) -> Record GraphProps -> R.Element
graphView :: R.Ref (Maybe Sigma) -> Record GraphProps -> R.Element
--graphView sigmaRef props = R.createElement (R.memo el memoCmp) props []
--graphView sigmaRef props = R.createElement (R.memo el memoCmp) props []
graphView sigmaRef props = R.createElement el props []
graphView sigmaRef props = R.createElement el props []
where
where
...
@@ -288,5 +285,5 @@ defaultPalette = ["#5fa571","#ab9ba2","#da876d","#bdd3ff","#b399df","#ffdfed","#
...
@@ -288,5 +285,5 @@ defaultPalette = ["#5fa571","#ab9ba2","#da876d","#bdd3ff","#b399df","#ffdfed","#
-- ]
-- ]
getNodes ::
Ends
-> GraphId -> Aff GET.GraphData
getNodes ::
Session
-> GraphId -> Aff GET.GraphData
getNodes
ends graphId = get $ url ends $ Config.NodeAPI Config.
Graph (Just graphId)
getNodes
session graphId = get $ url session $ NodeAPI
Graph (Just graphId)
src/Gargantext/Components/GraphExplorer/Button.purs
View file @
1105cefb
module Gargantext.Components.GraphExplorer.Button
module Gargantext.Components.GraphExplorer.Button
(
( centerButton
centerButton
, Props
, Props
, simpleButton
, simpleButton
) where
) where
import Global (readFloat)
import Prelude
import Prelude
import Data.Maybe (Maybe(..))
import Data.Maybe (Maybe(..))
import Data.Tuple (snd)
import DOM.Simple.Console (log2)
import Data.Tuple.Nested ((/\))
import DOM.Simple.Console (log, log2)
import Effect (Effect)
import Effect (Effect)
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as H
import Reactix.DOM.HTML as H
import Gargantext.Hooks.Sigmax as Sigmax
import Gargantext.Hooks.Sigmax as Sigmax
import Gargantext.Hooks.Sigmax.Sigma as Sigma
import Gargantext.Hooks.Sigmax.Sigma as Sigma
import Gargantext.Utils.Reactix as R2
type Props = (
type Props = (
onClick :: forall e. e -> Effect Unit
onClick :: forall e. e -> Effect Unit
...
...
src/Gargantext/Components/GraphExplorer/Controls.purs
View file @
1105cefb
...
@@ -11,8 +11,7 @@ module Gargantext.Components.GraphExplorer.Controls
...
@@ -11,8 +11,7 @@ module Gargantext.Components.GraphExplorer.Controls
, getMultiNodeSelect, setMultiNodeSelect
, getMultiNodeSelect, setMultiNodeSelect
) where
) where
import Data.Maybe (Maybe(..))
import Data.Maybe (Maybe)
import DOM.Simple as DOM
import Data.Tuple.Nested ((/\))
import Data.Tuple.Nested ((/\))
import Effect (Effect)
import Effect (Effect)
import Prelude
import Prelude
...
...
src/Gargantext/Components/GraphExplorer/Sidebar.purs
View file @
1105cefb
module Gargantext.Components.GraphExplorer.Sidebar
module Gargantext.Components.GraphExplorer.Sidebar
where
(Props, sidebar)
where
import Data.Tuple.Nested ((/\))
import Prelude
import Prelude
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as RH
import Reactix.DOM.HTML as RH
import Gargantext.Components.GraphExplorer.Controls as Controls
type Props = ( showSidePanel :: Boolean )
import Gargantext.Utils.Reactix as R2
type Props = (
showSidePanel :: Boolean
)
sidebar :: Record Props -> R.Element
sidebar :: Record Props -> R.Element
sidebar props = R.createElement sidebarCpt props []
sidebar props = R.createElement sidebarCpt props []
...
@@ -24,72 +18,44 @@ sidebarCpt = R.hooksComponent "Sidebar" cpt
...
@@ -24,72 +18,44 @@ sidebarCpt = R.hooksComponent "Sidebar" cpt
pure $ RH.div {} []
pure $ RH.div {} []
cpt props _children = do
cpt props _children = do
pure $
pure $
RH.div { id: "sp-container"
RH.div { id: "sp-container", className: "col-md-2" }
, className: "col-md-2" }
[ RH.div {}
[
[ RH.div { className: "row" }
RH.div {}
[ RH.div { className: "col-md-12" }
[
[ RH.ul { id: "myTab", className: "nav nav-tabs", role: "tablist"}
RH.div { className: "row" }
[ RH.li { className: "nav-item" }
[
[ RH.a { id: "home-tab"
RH.div { className: "col-md-12" }
[
RH.ul { id: "myTab"
, className: "nav nav-tabs"
, role: "tablist"}
[
RH.li { className: "nav-item" }
[
RH.a { id: "home-tab"
, className: "nav-link active"
, className: "nav-link active"
, data: {toggle: "tab"}
, data: {toggle: "tab"}
, href: "#home"
, href: "#home"
, role: "tab"
, role: "tab"
, aria: {controls: "home", selected: "true"}}
, aria: {controls: "home", selected: "true"}}
[
[ RH.text "Neighbours" ] ] ]
RH.text "Neighbours"
, RH.div { className: "tab-content", id: "myTabContent" }
]
[ RH.div { className: "", id: "home", role: "tabpanel" }
]
(badge <$> badges) ] ]
]
, RH.div { className: "col-md-12", id: "horizontal-checkbox" }
, RH.div { className: "tab-content"
[ RH.ul {}
, id: "myTabContent" }
[ checkbox "Pubs"
[ RH.div { className: ""
, id: "home"
, role: "tabpanel" }
[ badge "objects"
, badge "evaluation"
, badge "dynamics"
, badge "virtual environments"
, badge "virtual reality"
, badge "performance analysis"
, badge "software engineering"
, badge "complex systems"
, badge "wireless communications"
]
]
]
, RH.div { className: "col-md-12"
, id: "horizontal-checkbox" }
[
RH.ul {}
[
checkbox "Pubs"
, checkbox "Projects"
, checkbox "Projects"
, checkbox "Patents"
, checkbox "Patents"
, checkbox "Others"
, checkbox "Others" ] ] ] ] ]
]
]
]
]
]
badge text =
badge text =
RH.a { className: "badge badge-light" } [ RH.text text ]
RH.a { className: "badge badge-light" } [ RH.text text ]
checkbox text =
checkbox text =
RH.li {}
RH.li {}
[
[ RH.span {} [ RH.text text ]
RH.span {} [ RH.text text ]
, RH.input { type: "checkbox"
, RH.input { type: "checkbox"
, className: "checkbox"
, className: "checkbox"
, checked: true
, checked: true
, title: "Mark as completed" }
, title: "Mark as completed" } ]
]
badges =
[ "objects"
, "evaluation"
, "dynamics"
, "virtual environments"
, "virtual reality"
, "performance analysis"
, "software engineering"
, "complex systems"
, "wireless communications" ]
src/Gargantext/Components/GraphExplorer/ToggleButton.purs
View file @
1105cefb
...
@@ -12,15 +12,12 @@ import Prelude
...
@@ -12,15 +12,12 @@ import Prelude
import Data.Maybe (Maybe(..))
import Data.Maybe (Maybe(..))
import Data.Tuple (snd)
import Data.Tuple (snd)
import Data.Tuple.Nested ((/\))
import Data.Tuple.Nested ((/\))
import DOM.Simple.Console (log2)
import Effect (Effect)
import Effect (Effect)
import Effect.Class (liftEffect)
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as H
import Reactix.DOM.HTML as H
import Gargantext.Hooks.Sigmax as Sigmax
import Gargantext.Hooks.Sigmax as Sigmax
import Gargantext.Hooks.Sigmax.Sigma as Sigma
import Gargantext.Hooks.Sigmax.Sigma as Sigma
import Gargantext.Utils.Reactix as R2
type Props = (
type Props = (
state :: R.State Boolean
state :: R.State Boolean
...
...
src/Gargantext/Components/Login.purs
View file @
1105cefb
-- The Login component is a modal which allows the user to:
-- See the current login session
-- Select a backend and log into it
module Gargantext.Components.Login where
module Gargantext.Components.Login where
import
Control.Monad.Except (runExcept
)
import
Prelude (Unit, bind, const, discard, pure, ($), (<>)
)
import Data.Either (Either(..))
import Data.Either (Either(..))
import Data.Int as Int
import Data.Map (Map)
import Data.Map as Map
import Data.Maybe (Maybe(..))
import Data.Maybe (Maybe(..))
import Data.Traversable (traverse)
import Data.Tuple (fst, snd)
import Data.Tuple.Nested((/\))
import DOM.Simple.Console (log2)
import Effect.Class (liftEffect)
import Effect (Effect)
import Effect (Effect)
import Effect.Aff (Aff, launchAff_)
import Effect.Class (liftEffect)
import Foreign (MultipleErrors)
import Effect.Aff (launchAff_)
import Foreign.Generic (encodeJSON, decodeJSON)
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as H
import Reactix.DOM.HTML as H
import Web.HTML (window)
import Web.HTML.Window (localStorage)
import Web.Storage.Storage (getItem, setItem, removeItem)
------------------------------------------------------------------------
------------------------------------------------------------------------
import Gargantext.Prelude
import Gargantext.Components.Forms (clearfix, card, cardBlock, cardGroup, center, formGroup)
import Gargantext.Config (Ends, BackendRoute(..), backendKey, url)
import Gargantext.Components.Login.Types (AuthRequest(..))
import Gargantext.Config.REST (post)
import Gargantext.Ends (Backend)
import Gargantext.Components.Modals.Modal (modalHide)
import Gargantext.Sessions (Session, Sessions, postAuthRequest, unSessions)
import Gargantext.Components.Login.Types
import Gargantext.Sessions as Sessions
import Gargantext.Utils (csrfMiddlewareToken)
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Reactix as R2
-- 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
type Auths = Map String AuthData
type Props =
( backends :: Array Backend
type Props = ( ends :: Ends, setVisible :: R2.Setter Boolean)
, sessions :: R2.Reductor Sessions Sessions.Action
, setVisible :: R2.Setter Boolean )
type ModalProps = ( visible :: Boolean )
type ModalProps = ( visible :: Boolean )
...
@@ -41,157 +36,155 @@ modal :: Record ModalProps -> Array R.Element -> R.Element
...
@@ -41,157 +36,155 @@ modal :: Record ModalProps -> Array R.Element -> R.Element
modal = R.createElement modalCpt
modal = R.createElement modalCpt
modalCpt :: R.Component ModalProps
modalCpt :: R.Component ModalProps
modalCpt = R.staticComponent "Modal" cpt
modalCpt = R.staticComponent "Modal" cpt where
where
cpt {visible} children =
cpt {visible} children =
H.div { id: "loginModal", className: modalClass visible
H.div { id: "loginModal", className: modalClass visible, role: "dialog", "data": {show: true}}
, role: "dialog", "data": {show: true}}
[ H.div { className: "modal-dialog", role: "document"}
[ H.div { className: "modal-dialog", role: "document"}
[ H.div { className: "modal-content" }
[ H.div { className: "modal-content" }
[ H.div { className: "modal-header" }
[ H.div { className: "modal-header" }
[ H.h5 { className: "modal-title" } []
[ H.h5 { className: "modal-title" } []
, H.button { "type": "button", className: "close", "data": { dismiss: "modal" } }
, H.button { "type": "button", className: "close"
[ H.span { aria: { hidden: true } } [ H.text "X" ] ]
, "data": { dismiss: "modal" } }
, H.div { className: "modal-body" } children ] ] ] ]
[ H.span { aria: { hidden: true } } [ H.text "X" ] ]
modalClass s = "modal myModal" <> if s then "" else " fade"
, H.div { className: "modal-body" } children ] ] ] ]
modalClass s = "modal myModal" <> if s then "" else " fade"
login :: Record Props -> R.Element
login :: Record Props -> R.Element
login props = R.createElement loginCpt props []
login props = R.createElement loginCpt props []
loginCpt :: R.Component Props
loginCpt :: R.Component Props
loginCpt = R.hooksComponent "
L
ogin" cpt
loginCpt = R.hooksComponent "
G.C.Login.l
ogin" cpt
where
where
cpt {ends, setVisible} _children = do
cpt props@{backends, sessions, setVisible} _ = do
(username /\ setUsername) <- R.useState' ""
backend <- R.useState' Nothing
(password /\ setPassword) <- R.useState' ""
pure $ case (fst backend) of
(error /\ setError) <- R.useState' ""
Nothing -> chooser { backends, backend, sessions, setVisible }
(authData /\ setAuthData) <- R.useState' Nothing
Just b -> form { sessions, setVisible, backend: b }
pure $ H.div {className: "row"}
[ gargLogo
type ChooserProps = ( backend :: R.State (Maybe Backend) | Props )
, H.div {className: "card-group"}
[ H.div {className: "card"}
chooser :: Record ChooserProps -> R.Element
[ H.div {className: "card-block"}
chooser props = R.createElement chooserCpt props []
[ H.div {className: "center"}
[ H.h4 {className: "m-b-0"}
chooserCpt :: R.Component ChooserProps
[ H.span {className: "icon-text"}
chooserCpt = R.staticComponent "G.C.Login.chooser" cpt where
[ H.text "Welcome :)"]
cpt :: Record ChooserProps -> Array R.Element -> R.Element
]
cpt {backend, backends, sessions, setVisible} _ =
, H.p {className: "text-muted"}
R.fragment
[ H.text $ "Login to your account or",
[ renderSessions sessions, renderBackends backends backend ]
H.a { target: "blank"
, href: "https://iscpif.fr/services/applyforourservices/"
renderSessions :: R2.Reductor Sessions Sessions.Action -> R.Element
}
renderSessions sessions = render (unSessions $ fst sessions) where
[H.text " request access"]
render Nothing = R.fragment []
]
render (Just s) = renderSession s
]
, H.div {}
renderSession :: Session -> R.Element
[ H.input { type: "hidden"
renderSession session = R.fragment []
, name: "csrfmiddlewaretoken"
-- TODO hard-coded CSRF token
renderBackends :: Array Backend -> R.State (Maybe Backend) -> R.Element
, value: "Wy52D2nor8kC1r1Y4GrsrSIxQ2eqW8UwkdiQQshMoRwobzU4uldknRUhP0j4WcEM"
renderBackends backends state = R.fragment []
}
renderBackend :: Backend -> R.State (Maybe Backend) -> R.Element
, H.div {className: "form-group"}
renderBackend backend state = R.fragment []
[ H.p {} [H.text error]
, usernameInput username setUsername
type FormProps =
]
( backend :: Backend
, H.div {className: "form-group"}
, sessions :: R2.Reductor Sessions Sessions.Action
[ passwordInput password setPassword
, setVisible :: R2.Setter Boolean )
, H.div {className: "clearfix"} []
]
form :: Record FormProps -> R.Element
, H.div {className: "center"}
form props = R.createElement formCpt props []
[ H.label {}
[ H.div {className: "checkbox"}
formCpt :: R.Component FormProps
[ H.input { id: "terms-accept"
formCpt = R.hooksComponent "G.C.Login.form" cpt where
, type: "checkbox"
cpt :: Record FormProps -> Array R.Element -> R.Hooks R.Element
, value: ""
cpt props@{backend, sessions, setVisible} _ = do
, className: "checkbox"
error <- R.useState' ""
}
username <- R.useState' ""
, H.text "I accept the terms of use "
password <- R.useState' ""
, H.a {href: "http://gitlab.iscpif.fr/humanities/tofu/tree/master"}
pure $ H.div {className: "row"}
[ H.text " [ Read the terms of use ] "]
[ logo
]
, cardGroup
]
[ card
, H.button { id: "login-button"
[ cardBlock
, className: "btn btn-primary btn-rounded"
[ center
, type: "submit"
[ H.h4 {className: "m-b-0"}
-- TODO
[ H.span {className: "icon-text"} [ H.text "Welcome :)" ] ]
--, on: {click: \_ -> dispatch $ PostAuth}
, H.p {className: "text-muted"}
, on: {click: onClick ends setError setAuthData setVisible username password}
[ H.text $ "Login to your account or", requestAccessLink {} ] ]
}
, H.div {}
[H.text "Login"]
[ csrfTokenInput {}
]
, formGroup [ H.p {} [ H.text (fst error) ], usernameInput username ]
]
, formGroup [ passwordInput password, clearfix [] ]
]
, center
]
[ H.label {}
]
[ H.div {className: "checkbox"}
]
[ termsCheckbox {}, H.text "I accept the terms of use ", termsLink {} ] ]
, loginSubmit $
gargLogo =
onClick props error username password ] ] ] ] ] ]
H.div {className: "col-md-10 col-md-push-1"}
onClick {backend, sessions, setVisible} error username password e =
[ H.h2 {className: "text-primary center m-a-2"}
launchAff_ $ do
[ H.i {className: "material-icons md-36"} [ H.text "control_point" ]
let req = AuthRequest {username: fst username, password: fst password}
, H.span {className: "icon-text"} [ H.text "Gargantext" ] ] ]
res <- postAuthRequest backend req
usernameInput username setUsername =
case res of
H.input { className: "form-control"
Left message -> liftEffect $ (snd error) (const message)
, id: "id_username"
Right sess -> liftEffect $ do
, maxLength: "254"
(snd sessions) (Sessions.Login sess)
, name: "username"
(snd error) (const "")
, placeholder: "username"
setVisible (const false)
, type: "text"
logo =
, defaultValue: username
H.div {className: "col-md-10 col-md-push-1"}
--, on: {input: \e -> dispatch (SetUserName $ R2.unsafeEventValue e)}
[ H.h2 {className: "text-primary center m-a-2"}
, on: {change: \e -> setUsername $ const $ R2.unsafeEventValue e}
[ H.i {className: "material-icons md-36"} [ H.text "control_point" ]
}
, H.span {className: "icon-text"} [ H.text "Gargantext" ] ] ]
csrfTokenInput :: {} -> R.Element
csrfTokenInput _ =
H.input { type: "hidden", name: "csrfmiddlewaretoken"
, value: csrfMiddlewareToken }-- TODO hard-coded CSRF token
termsCheckbox :: {} -> R.Element
termsCheckbox _ =
H.input { id: "terms-accept", type: "checkbox", value: "", className: "checkbox" }
termsLink :: {} -> R.Element
termsLink _ =
H.a { target: "_blank", href: termsUrl } [ H.text " [ Read the terms of use ] " ]
where termsUrl = "http://gitlab.iscpif.fr/humanities/tofu/tree/master"
requestAccessLink :: {} -> R.Element
requestAccessLink _ =
H.a { target: "_blank", href: applyUrl } [ H.text " request access" ]
where applyUrl = "https://iscpif.fr/services/applyforourservices/"
usernameInput :: R.State String -> R.Element
usernameInput username =
H.input { className: "form-control"
, id: "id_username"
, maxLength: "254"
, name: "username"
, placeholder: "username"
, type: "text"
, defaultValue: (fst username)
--, on: {input: \e -> dispatch (SetUserName $ R2.unsafeEventValue e)}
, on: {change: \e -> (snd username) $ const $ R2.unsafeEventValue e} }
passwordInput password setPassword =
passwordInput :: R.State String -> R.Element
H.input { className: "form-control"
passwordInput password =
, id: "id_password"
H.input { className: "form-control"
, name: "password"
, id: "id_password"
, placeholder: "password"
, name: "password"
, type: "password"
, placeholder: "password"
, defaultValue: password
, type: "password"
--, on: {input: \e -> dispatch (SetPassword $ R2.unsafeEventValue e)}
, defaultValue: (fst password)
, on: {change: \e -> setPassword $ const $ R2.unsafeEventValue e}
--, on: {input: \e -> dispatch (SetPassword $ R2.unsafeEventValue e)}
}
, on: {change: \e -> (snd password) $ const $ R2.unsafeEventValue e} }
onClick ends setError setAuthData setVisible username password = \e ->
launchAff_ $ do
loginSubmit :: forall e. (e -> Effect Unit) -> R.Element
res <- postAuthRequest ends $ AuthRequest {username, password}
loginSubmit click =
case res of
H.button { id, className, type: "submit", on: {click} } [ H.text "Login" ]
AuthResponse {inval: Just (AuthInvalid {message})} -> liftEffect $ do
where
setError (const message)
id = "login-button"
setAuthData (const Nothing)
className = "btn btn-primary btn-rounded"
AuthResponse {valid} -> liftEffect $ do
setAuthData (const valid)
setError (const "")
setVisible (const false)
-- getAuth :: Effect Auth
-- getAuth = do
-- window >>= localStorage >>= getItem
-- setAuth :: Auth -> Effect Unit
getAuths :: Effect (Maybe Auths)
getAuths = pure Nothing
-- getAuths = window >>= localStorage >>= getItem "auths" >>= traverse decode
-- where
-- decode :: String -> Effect (Maybe Auths)
-- decode = ret <<< runExcept <<< decodeJSON
-- ret (Right v) = pure $ Just v
-- ret (Left e) = log2 "Error reading serialised auths:" e *> pure Nothing
setAuths :: Maybe Auths -> Effect Unit
-- setAuths Map.empty = -- window >>= localStorage >>= removeItem "auths"
setAuths _ = pure unit -- auths = window >>= localStorage >>= setItem "auths" (encodeJSON auths)
-- TODO
-- useLocalStorageAuths :: String -> R.Hooks (R.State Auths)
-- useLocalStorageAuths key = do
postAuthRequest :: Ends -> AuthRequest -> Aff AuthResponse
postAuthRequest ends = post $ url ends Auth
getCurrentAuth :: Ends -> Auths -> Maybe AuthData
getCurrentAuth ends = Map.lookup (backendKey ends.backend)
src/Gargantext/Components/Modal.purs
View file @
1105cefb
...
@@ -3,23 +3,17 @@
...
@@ -3,23 +3,17 @@
-- | content. Clicking outside of the box will close the modal
-- | content. Clicking outside of the box will close the modal
module Gargantext.Components.Modal where
module Gargantext.Components.Modal where
import Prelude hiding (div)
import Prelude (Unit, bind, const, discard, pure, unit, ($))
import Data.Maybe ( Maybe(..), maybe )
import Data.Maybe ( maybe )
import Data.Nullable ( Nullable, null, toMaybe )
import Data.Nullable ( Nullable, null )
import Data.Tuple ( Tuple(..) )
import Data.Tuple.Nested ( (/\) )
import DOM.Simple as DOM
import DOM.Simple as DOM
import DOM.Simple.Console
import DOM.Simple.EventListener ( callback )
import DOM.Simple.EventListener ( Callback, callback )
import DOM.Simple.Element as Element
import DOM.Simple.Element as Element
import DOM.Simple.Event (MouseEvent, target)
import DOM.Simple.Event (MouseEvent, target)
import DOM.Simple.Document ( document )
import DOM.Simple.Document ( document )
import Effect (Effect)
import Effect (Effect)
import Effect.Uncurried ( mkEffectFn1 )
import FFI.Simple ( (...), (..), delay )
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as H
import Reactix.DOM.HTML as H
import Reactix.SyntheticEvent as E
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Reactix as R2
type Props = ( setVisible :: R2.Setter Boolean )
type Props = ( setVisible :: R2.Setter Boolean )
...
...
src/Gargantext/Components/NgramsTable.purs
View file @
1105cefb
module Gargantext.Components.NgramsTable where
module Gargantext.Components.NgramsTable where
import Prelude
import Data.Array as A
import Data.Array as A
import Data.Lens (to, view, (%~), (.~), (^.), (^..))
import Data.Lens (to, view, (%~), (.~), (^.), (^..))
import Data.Lens.Common (_Just)
import Data.Lens.Common (_Just)
...
@@ -25,13 +26,12 @@ import React.DOM.Props (_id, _type, checked, className, name, onChange, onClick,
...
@@ -25,13 +26,12 @@ import React.DOM.Props (_id, _type, checked, className, name, onChange, onClick,
import React.DOM.Props as DOM
import React.DOM.Props as DOM
import Thermite (PerformAction, Render, Spec, defaultPerformAction, modifyState_, simpleSpec, createClass)
import Thermite (PerformAction, Render, Spec, defaultPerformAction, modifyState_, simpleSpec, createClass)
import Gargantext.Types (TermList(..), readTermList, readTermSize, termLists, termSizes)
import Gargantext.Types (TermList(..), OrderBy(..), TabType, CTabNgramType(..), readTermList, readTermSize, termLists, termSizes)
import Gargantext.Config (Ends, OrderBy(..), TabType, CTabNgramType(..))
import Gargantext.Components.AutoUpdate (autoUpdateElt)
import Gargantext.Components.AutoUpdate (autoUpdateElt)
import Gargantext.Components.NgramsTable.Core
import Gargantext.Components.Table as T
import Gargantext.Components.Table as T
import Gargantext.Prelude
import Gargantext.Hooks.Loader (useLoader, useLoader2)
import Gargantext.Hooks.Loader (useLoader, useLoader2)
import Gargantext.
Components.NgramsTable.Core
import Gargantext.
Sessions (Session)
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Reactix as R2
type State =
type State =
...
@@ -173,10 +173,10 @@ performNgramsAction st (ToggleChild' b c) = st
...
@@ -173,10 +173,10 @@ performNgramsAction st (ToggleChild' b c) = st
performNgramsAction st Refresh' = st
performNgramsAction st Refresh' = st
useNgramsReducer :: State -> R.Hooks (R.Reducer State Action')
useNgramsReducer :: State -> R.Hooks (R.Reducer State Action')
useNgramsReducer init = R.useReducer
performNgramsAction identity
init
useNgramsReducer init = R.useReducer
' performNgramsAction
init
type Props =
type Props =
(
ends :: Ends
(
session :: Session
, tabNgramType :: CTabNgramType
, tabNgramType :: CTabNgramType
, path :: R.State PageParams
, path :: R.State PageParams
, versioned :: VersionedNgramsTable )
, versioned :: VersionedNgramsTable )
...
@@ -191,8 +191,8 @@ ngramsTableCpt = R.hooksComponent "G.C.NgramsTable.ngramsTable" cpt
...
@@ -191,8 +191,8 @@ ngramsTableCpt = R.hooksComponent "G.C.NgramsTable.ngramsTable" cpt
state <- useNgramsReducer (initialState versioned)
state <- useNgramsReducer (initialState versioned)
pure $ R.fragment []
pure $ R.fragment []
ngramsTableSpec ::
Ends
-> CTabNgramType -> R2.Setter PageParams -> Spec State (Record LoadedNgramsTableProps) Action
ngramsTableSpec ::
Session
-> CTabNgramType -> R2.Setter PageParams -> Spec State (Record LoadedNgramsTableProps) Action
ngramsTableSpec
ends
ntype setPath = simpleSpec performAction render
ngramsTableSpec
session
ntype setPath = simpleSpec performAction render
where
where
setParentResetChildren :: Maybe NgramsTerm -> State -> State
setParentResetChildren :: Maybe NgramsTerm -> State -> State
setParentResetChildren p = _ { ngramsParent = p, ngramsChildren = mempty }
setParentResetChildren p = _ { ngramsParent = p, ngramsChildren = mempty }
...
@@ -203,9 +203,9 @@ ngramsTableSpec ends ntype setPath = simpleSpec performAction render
...
@@ -203,9 +203,9 @@ ngramsTableSpec ends ntype setPath = simpleSpec performAction render
performAction (ToggleChild b c) _ _ =
performAction (ToggleChild b c) _ _ =
modifyState_ $ _ngramsChildren <<< at c %~ toggleMap b
modifyState_ $ _ngramsChildren <<< at c %~ toggleMap b
performAction Refresh {path: {nodeId, listIds, tabType}} {ngramsVersion} = do
performAction Refresh {path: {nodeId, listIds, tabType}} {ngramsVersion} = do
commitPatch
ends
{nodeId, listIds, tabType} (Versioned {version: ngramsVersion, data: mempty})
commitPatch
session
{nodeId, listIds, tabType} (Versioned {version: ngramsVersion, data: mempty})
performAction (SetTermListItem n pl) {path: {nodeId, listIds, tabType}} {ngramsVersion} =
performAction (SetTermListItem n pl) {path: {nodeId, listIds, tabType}} {ngramsVersion} =
commitPatch
ends
{nodeId, listIds, tabType} (Versioned {version: ngramsVersion, data: pt})
commitPatch
session
{nodeId, listIds, tabType} (Versioned {version: ngramsVersion, data: pt})
where
where
pe = NgramsPatch { patch_list: pl, patch_children: mempty }
pe = NgramsPatch { patch_list: pl, patch_children: mempty }
pt = singletonNgramsTablePatch ntype n pe
pt = singletonNgramsTablePatch ntype n pe
...
@@ -218,13 +218,13 @@ ngramsTableSpec ends ntype setPath = simpleSpec performAction render
...
@@ -218,13 +218,13 @@ ngramsTableSpec ends ntype setPath = simpleSpec performAction render
, ngramsVersion
, ngramsVersion
} = do
} = do
modifyState_ $ setParentResetChildren Nothing
modifyState_ $ setParentResetChildren Nothing
commitPatch
ends
{nodeId, listIds, tabType} (Versioned {version: ngramsVersion, data: pt})
commitPatch
session
{nodeId, listIds, tabType} (Versioned {version: ngramsVersion, data: pt})
where
where
pc = patchSetFromMap ngramsChildren
pc = patchSetFromMap ngramsChildren
pe = NgramsPatch { patch_list: mempty, patch_children: pc }
pe = NgramsPatch { patch_list: mempty, patch_children: pc }
pt = singletonNgramsTablePatch ntype parent pe
pt = singletonNgramsTablePatch ntype parent pe
performAction (AddNewNgram ngram) {path: {listIds, nodeId, tabType}} {ngramsVersion} =
performAction (AddNewNgram ngram) {path: {listIds, nodeId, tabType}} {ngramsVersion} =
commitPatch
ends
{listIds, nodeId, tabType} (Versioned {version: ngramsVersion, data: pt})
commitPatch
session
{listIds, nodeId, tabType} (Versioned {version: ngramsVersion, data: pt})
where
where
pt = addNewNgram ntype ngram CandidateTerm
pt = addNewNgram ntype ngram CandidateTerm
...
@@ -273,18 +273,18 @@ ngramsTableSpec ends ntype setPath = simpleSpec performAction render
...
@@ -273,18 +273,18 @@ ngramsTableSpec ends ntype setPath = simpleSpec performAction render
, delete: false
, delete: false
}
}
-- ngramsTableClass ::
Ends
-> CTabNgramType -> R2.Setter PageParams -> Loader.InnerClass PageParams (Versioned NgramsTable)
-- ngramsTableClass ::
Session
-> CTabNgramType -> R2.Setter PageParams -> Loader.InnerClass PageParams (Versioned NgramsTable)
-- ngramsTableClass
ends ct setPath = createClass "NgramsTable" (ngramsTableSpec ends
ct setPath) initialState
-- ngramsTableClass
session ct setPath = createClass "NgramsTable" (ngramsTableSpec session
ct setPath) initialState
-- ngramsTable' ::
Ends
-> CTabNgramType -> R2.Setter PageParams -> Record LoadedNgramsTableProps -> R.Element
-- ngramsTable' ::
Session
-> CTabNgramType -> R2.Setter PageParams -> Record LoadedNgramsTableProps -> R.Element
-- ngramsTable'
ends ct setPath props = R2.createElement' (ngramsTableClass ends
ct setPath) props []
-- ngramsTable'
session ct setPath props = R2.createElement' (ngramsTableClass session
ct setPath) props []
type MainNgramsTableProps =
type MainNgramsTableProps =
( nodeId :: Int
( nodeId :: Int
-- ^ This node can be a corpus or contact.
-- ^ This node can be a corpus or contact.
, defaultListId :: Int
, defaultListId :: Int
, tabType :: TabType
, tabType :: TabType
,
ends :: Ends
,
session :: Session
, tabNgramType :: CTabNgramType
, tabNgramType :: CTabNgramType
)
)
...
@@ -294,10 +294,10 @@ mainNgramsTable props = R.createElement mainNgramsTableCpt props []
...
@@ -294,10 +294,10 @@ mainNgramsTable props = R.createElement mainNgramsTableCpt props []
mainNgramsTableCpt :: R.Component MainNgramsTableProps
mainNgramsTableCpt :: R.Component MainNgramsTableProps
mainNgramsTableCpt = R.hooksComponent "MainNgramsTable" cpt
mainNgramsTableCpt = R.hooksComponent "MainNgramsTable" cpt
where
where
cpt {nodeId, defaultListId, tabType,
ends
, tabNgramType} _ = do
cpt {nodeId, defaultListId, tabType,
session
, tabNgramType} _ = do
path <- R.useState' $ initialPageParams
ends
nodeId [defaultListId] tabType
path <- R.useState' $ initialPageParams
session
nodeId [defaultListId] tabType
useLoader2 path (loadNgramsTable
ends
) $
useLoader2 path (loadNgramsTable
session
) $
\versioned -> ngramsTable {
ends
, tabNgramType, path, versioned}
\versioned -> ngramsTable {
session
, tabNgramType, path, versioned}
type NgramsDepth = {ngrams :: NgramsTerm, depth :: Int}
type NgramsDepth = {ngrams :: NgramsTerm, depth :: Int}
type NgramsClick = NgramsDepth -> Maybe (Effect Unit)
type NgramsClick = NgramsDepth -> Maybe (Effect Unit)
...
...
src/Gargantext/Components/NgramsTable/Core.purs
View file @
1105cefb
...
@@ -44,6 +44,7 @@ module Gargantext.Components.NgramsTable.Core
...
@@ -44,6 +44,7 @@ module Gargantext.Components.NgramsTable.Core
)
)
where
where
import Prelude
import Control.Monad.State (class MonadState, execState)
import Control.Monad.State (class MonadState, execState)
import Control.Monad.Cont.Trans (lift)
import Control.Monad.Cont.Trans (lift)
import Data.Array (head)
import Data.Array (head)
...
@@ -84,13 +85,14 @@ import Thermite (StateCoTransformer, modifyState_)
...
@@ -84,13 +85,14 @@ import Thermite (StateCoTransformer, modifyState_)
import Partial (crashWith)
import Partial (crashWith)
import Partial.Unsafe (unsafePartial)
import Partial.Unsafe (unsafePartial)
import Gargantext.Utils.KarpRabin (indicesOfAny)
import Gargantext.Types (TermList(..), TermSize)
import Gargantext.Config (Ends, BackendRoute(..), TabType, OrderBy(..), CTabNgramType(..), url)
import Gargantext.Config.REST (get, put, post)
import Gargantext.Config.REST (get, put, post)
import Gargantext.Components.Table as T
import Gargantext.Components.Table as T
import Gargantext.Prelude
import Gargantext.Components.Loader as Loader
import Gargantext.Components.Loader as Loader
import Gargantext.Ends (url)
import Gargantext.Routes (SessionRoute(..))
import Gargantext.Sessions (Session)
import Gargantext.Types (OrderBy(..), CTabNgramType(..), TabType, TermList(..), TermSize)
import Gargantext.Utils.KarpRabin (indicesOfAny)
type CoreParams s =
type CoreParams s =
{ nodeId :: Int
{ nodeId :: Int
...
@@ -106,11 +108,11 @@ type PageParams =
...
@@ -106,11 +108,11 @@ type PageParams =
, searchQuery :: String
, searchQuery :: String
, termListFilter :: Maybe TermList -- Nothing means all
, termListFilter :: Maybe TermList -- Nothing means all
, termSizeFilter :: Maybe TermSize -- Nothing means all
, termSizeFilter :: Maybe TermSize -- Nothing means all
,
ends :: Ends
,
session :: Session
)
)
initialPageParams ::
Ends
-> Int -> Array Int -> TabType -> PageParams
initialPageParams ::
Session
-> Int -> Array Int -> TabType -> PageParams
initialPageParams
ends
nodeId listIds tabType =
initialPageParams
session
nodeId listIds tabType =
{ nodeId
{ nodeId
, listIds
, listIds
, params: T.initialParams
, params: T.initialParams
...
@@ -118,7 +120,7 @@ initialPageParams ends nodeId listIds tabType =
...
@@ -118,7 +120,7 @@ initialPageParams ends nodeId listIds tabType =
, termSizeFilter: Nothing
, termSizeFilter: Nothing
, termListFilter: Just GraphTerm
, termListFilter: Just GraphTerm
, searchQuery: ""
, searchQuery: ""
,
ends
,
session
}
}
type NgramsTerm = String
type NgramsTerm = String
...
@@ -563,43 +565,43 @@ type CoreState s =
...
@@ -563,43 +565,43 @@ type CoreState s =
| s
| s
}
}
postNewNgrams :: forall s.
Ends
-> Array NgramsTerm -> Maybe TermList -> CoreParams s -> Aff Unit
postNewNgrams :: forall s.
Session
-> Array NgramsTerm -> Maybe TermList -> CoreParams s -> Aff Unit
postNewNgrams
ends
newNgrams mayList {nodeId, listIds, tabType} =
postNewNgrams
session
newNgrams mayList {nodeId, listIds, tabType} =
when (not (A.null newNgrams)) $ do
when (not (A.null newNgrams)) $ do
(_ :: Array Unit) <- post (url
ends
put) newNgrams
(_ :: Array Unit) <- post (url
session
put) newNgrams
pure unit
pure unit
where put = PutNgrams tabType (head listIds) mayList (Just nodeId)
where put = PutNgrams tabType (head listIds) mayList (Just nodeId)
postNewElems :: forall s.
Ends
-> NewElems -> CoreParams s -> Aff Unit
postNewElems :: forall s.
Session
-> NewElems -> CoreParams s -> Aff Unit
postNewElems
ends
newElems params = void $ traverseWithIndex postNewElem newElems
postNewElems
session
newElems params = void $ traverseWithIndex postNewElem newElems
where
where
postNewElem ngrams list = postNewNgrams
ends
[ngrams] (Just list) params
postNewElem ngrams list = postNewNgrams
session
[ngrams] (Just list) params
addNewNgram :: CTabNgramType -> NgramsTerm -> TermList -> NgramsTablePatch
addNewNgram :: CTabNgramType -> NgramsTerm -> TermList -> NgramsTablePatch
addNewNgram ntype ngrams list = { ngramsPatches: mempty
addNewNgram ntype ngrams list = { ngramsPatches: mempty
, ngramsNewElems: Map.singleton (normNgram ntype ngrams) list }
, ngramsNewElems: Map.singleton (normNgram ntype ngrams) list }
putNgramsPatches ::
Ends
-> {nodeId :: Int, listIds :: Array Int, tabType :: TabType} -> Versioned NgramsPatches -> Aff (Versioned NgramsPatches)
putNgramsPatches ::
Session
-> {nodeId :: Int, listIds :: Array Int, tabType :: TabType} -> Versioned NgramsPatches -> Aff (Versioned NgramsPatches)
putNgramsPatches
ends {nodeId, listIds, tabType} = put $ url ends
putNgrams
putNgramsPatches
session {nodeId, listIds, tabType} = put $ url session
putNgrams
where putNgrams = PutNgrams tabType (head listIds) Nothing (Just nodeId)
where putNgrams = PutNgrams tabType (head listIds) Nothing (Just nodeId)
commitPatch :: forall s.
Ends
-> {nodeId :: Int, listIds :: Array Int, tabType :: TabType}
commitPatch :: forall s.
Session
-> {nodeId :: Int, listIds :: Array Int, tabType :: TabType}
-> Versioned NgramsTablePatch -> StateCoTransformer (CoreState s) Unit
-> Versioned NgramsTablePatch -> StateCoTransformer (CoreState s) Unit
commitPatch
ends
props (Versioned {version, data: tablePatch@{ngramsPatches, ngramsNewElems}}) = do
commitPatch
session
props (Versioned {version, data: tablePatch@{ngramsPatches, ngramsNewElems}}) = do
let pt = Versioned { version, data: ngramsPatches }
let pt = Versioned { version, data: ngramsPatches }
lift $ postNewElems
ends
ngramsNewElems props
lift $ postNewElems
session
ngramsNewElems props
Versioned {version: newVersion, data: newPatch} <- lift $ putNgramsPatches
ends
props pt
Versioned {version: newVersion, data: newPatch} <- lift $ putNgramsPatches
session
props pt
modifyState_ $ \s ->
modifyState_ $ \s ->
s { ngramsVersion = newVersion
s { ngramsVersion = newVersion
, ngramsTablePatch = fromNgramsPatches newPatch <> tablePatch <> s.ngramsTablePatch
, ngramsTablePatch = fromNgramsPatches newPatch <> tablePatch <> s.ngramsTablePatch
}
}
-- TODO: check that pt.version == s.ngramsTablePatch.version
-- TODO: check that pt.version == s.ngramsTablePatch.version
loadNgramsTable ::
Ends
-> PageParams -> Aff VersionedNgramsTable
loadNgramsTable ::
Session
-> PageParams -> Aff VersionedNgramsTable
loadNgramsTable
ends
loadNgramsTable
session
{ nodeId, listIds, termListFilter, termSizeFilter
{ nodeId, listIds, termListFilter, termSizeFilter
, searchQuery, tabType, params: {offset, limit, orderBy}}
, searchQuery, tabType, params: {offset, limit, orderBy}}
= get $ url
ends
query
= get $ url
session
query
where query = GetNgrams { tabType, offset, limit, listIds
where query = GetNgrams { tabType, offset, limit, listIds
, orderBy: convOrderBy <$> orderBy
, orderBy: convOrderBy <$> orderBy
, termListFilter, termSizeFilter
, termListFilter, termSizeFilter
...
@@ -612,10 +614,10 @@ convOrderBy (T.DESC (T.ColumnName "Score (Occurrences)")) = ScoreDesc
...
@@ -612,10 +614,10 @@ convOrderBy (T.DESC (T.ColumnName "Score (Occurrences)")) = ScoreDesc
convOrderBy (T.ASC _) = TermAsc
convOrderBy (T.ASC _) = TermAsc
convOrderBy (T.DESC _) = TermDesc
convOrderBy (T.DESC _) = TermDesc
ngramsLoaderClass ::
Ends
-> Loader.LoaderClass PageParams VersionedNgramsTable
ngramsLoaderClass ::
Session
-> Loader.LoaderClass PageParams VersionedNgramsTable
ngramsLoaderClass
ends = Loader.createLoaderClass "NgramsTableLoader" (loadNgramsTable ends
)
ngramsLoaderClass
session = Loader.createLoaderClass "NgramsTableLoader" (loadNgramsTable session
)
ngramsLoader ::
Ends
-> Loader.Props' PageParams VersionedNgramsTable -> ReactElement
ngramsLoader ::
Session
-> Loader.Props' PageParams VersionedNgramsTable -> ReactElement
ngramsLoader
ends props = React.createElement (ngramsLoaderClass ends
) props []
ngramsLoader
session props = React.createElement (ngramsLoaderClass session
) props []
type LoadedNgramsTableProps = ( path :: PageParams, loaded :: VersionedNgramsTable )
type LoadedNgramsTableProps = ( path :: PageParams, loaded :: VersionedNgramsTable )
src/Gargantext/Components/RangeSlider.purs
View file @
1105cefb
...
@@ -9,25 +9,20 @@ module Gargantext.Components.RangeSlider where
...
@@ -9,25 +9,20 @@ module Gargantext.Components.RangeSlider where
import Prelude
import Prelude
import Data.Int (fromNumber)
import Data.Int (fromNumber)
import Data.Maybe (Maybe(..), fromMaybe)
import Data.Maybe (Maybe(..), fromMaybe)
import Data.Nullable (Nullable, null
, toMaybe
)
import Data.Nullable (Nullable, null)
import Data.Traversable (traverse_)
import Data.Traversable (traverse_)
import Data.Tuple.Nested ((/\))
import Data.Tuple.Nested ((/\))
import DOM.Simple as DOM
import DOM.Simple as DOM
import DOM.Simple.Console (log2)
import DOM.Simple.Document (document)
import DOM.Simple.Document (document)
import DOM.Simple.Element as Element
import DOM.Simple.Event as Event
import DOM.Simple.Event as Event
import DOM.Simple.EventListener as EL
import DOM.Simple.EventListener as EL
import DOM.Simple
.Types (DOMRect, Elemen
t)
import DOM.Simple
(DOMRec
t)
import Global (toFixed)
import Global (toFixed)
import Effect (Effect)
import Effect (Effect)
import Effect.Class (liftEffect)
import Effect.Uncurried (mkEffectFn1)
import Effect.Uncurried (EffectFn1, mkEffectFn1)
--import Global (toFixed)
import Math as M
import Math as M
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as H
import Reactix.DOM.HTML as H
import Reactix.SyntheticEvent as RE
import Gargantext.Utils.Math (roundToMultiple)
import Gargantext.Utils.Math (roundToMultiple)
import Gargantext.Utils.Range as Range
import Gargantext.Utils.Range as Range
...
...
src/Gargantext/Components/Search/SearchBar.purs
View file @
1105cefb
module Gargantext.Components.Search.SearchBar
module Gargantext.Components.Search.SearchBar
( Props,
defaultProps,
searchBar, searchBarCpt
( Props, searchBar, searchBarCpt
) where
) where
import Prelude (Unit, bind,
const,
discard, not, pure, show, ($), (<>))
import Prelude (Unit, bind, discard, not, pure, show, ($), (<>))
import Data.Maybe (Maybe(..))
import Data.Maybe (Maybe(..))
import Data.Newtype (over)
import Data.Newtype (over)
import Data.Traversable (traverse_)
import Data.Traversable (traverse_)
import Data.Tuple.Nested ( (/\) )
import Data.Tuple (snd)
import Data.Tuple.Nested ((/\))
import Effect.Class (liftEffect)
import Effect.Class (liftEffect)
import Effect.Uncurried (EffectFn1, mkEffectFn1)
import Reactix as R
import Reactix as R
import DOM.Simple.Console (log2)
import DOM.Simple.Console (log2)
import Effect.Aff (Aff, launchAff)
import Effect.Aff (Aff, launchAff
_
)
import Reactix.DOM.HTML as H
import Reactix.DOM.HTML as H
import Gargantext.Config (Ends)
import Gargantext.Components.Search.Types (Database, SearchQuery(..), defaultSearchQuery, performSearch)
import Gargantext.Components.Search.Types (Database, SearchQuery(..), allDatabases, defaultSearchQuery, performSearch)
import Gargantext.Components.Modals.Modal (modalShow)
import Gargantext.Components.Modals.Modal (modalShow)
import Gargantext.Components.Search.SearchField (Search, searchField)
import Gargantext.Components.Search.SearchField (Search, searchField)
import Gargantext.Sessions (Session)
type Props = ( ends :: Ends, open :: Boolean, databases :: Array Database )
type Props = ( session :: Session, databases :: Array Database )
defaultProps :: Ends -> Record Props
defaultProps ends = { open: false, databases: allDatabases, ends }
searchBar :: Record Props -> R.Element
searchBar :: Record Props -> R.Element
searchBar p
= R.createElement searchBarCpt p
[]
searchBar p
rops = R.createElement searchBarCpt props
[]
searchBarCpt :: R.Component Props
searchBarCpt :: R.Component Props
searchBarCpt = R.hooksComponent "
S
earchBar" cpt
searchBarCpt = R.hooksComponent "
G.C.Search.SearchBar.s
earchBar" cpt
where
where
cpt {
ends, databases, open
} _ = do
cpt {
session, databases
} _ = do
open
' <- R.useState $ const open
open
<- R.useState' false
search <- R.useState
$ const
Nothing
search <- R.useState
'
Nothing
onSearchChange
ends
search
onSearchChange
session
search
pure $ H.div { className: "search-bar-container" }
pure $ H.div { className: "search-bar-container
pull-right
" }
[ toggleButton open
'
[ toggleButton open
, searchFieldContainer open
'
databases search ]
, searchFieldContainer open databases search ]
searchFieldContainer :: R.State Boolean -> Array Database -> R.State (Maybe Search) -> R.Element
searchFieldContainer :: R.State Boolean -> Array Database -> R.State (Maybe Search) -> R.Element
searchFieldContainer (open /\ _) databases search =
searchFieldContainer (open /\ _) databases search =
...
@@ -43,25 +40,25 @@ searchFieldContainer (open /\ _) databases search =
...
@@ -43,25 +40,25 @@ searchFieldContainer (open /\ _) databases search =
where
where
openClass = if open then "open" else "closed"
openClass = if open then "open" else "closed"
onSearchChange ::
Ends
-> R.State (Maybe Search) -> R.Hooks Unit
onSearchChange ::
Session
-> R.State (Maybe Search) -> R.Hooks Unit
onSearchChange
ends
(search /\ setSearch) =
onSearchChange
session
(search /\ setSearch) =
R.useLayoutEffect1' search $ traverse_ triggerSearch search
R.useLayoutEffect1' search $ traverse_ triggerSearch search
where
where
triggerSearch q = do
triggerSearch q =
launchAff $ do
launchAff_ $ do
liftEffect $ log2 "Searching db: " $ show q.database
liftEffect $ do
liftEffect $ log2 "Searching term: " q.term
log2 "Searching db: " $ show q.database
r <- (performSearch ends $ searchQuery q) :: Aff Unit
log2 "Searching term: " q.term
liftEffect $ log2 "Return:" r
r <- (performSearch session $ searchQuery q) :: Aff Unit
liftEffect $ modalShow "addCorpus"
liftEffect $ do
log2 "Return:" r
modalShow "addCorpus"
searchQuery {database: Nothing, term} = over SearchQuery (_ {query=term}) defaultSearchQuery
searchQuery {database: Nothing, term} = over SearchQuery (_ {query=term}) defaultSearchQuery
searchQuery {database: Just db, term} = over SearchQuery (_ {databases=[db], query=term}) defaultSearchQuery
searchQuery {database: Just db, term} = over SearchQuery (_ {databases=[db], query=term}) defaultSearchQuery
toggleButton :: R.State Boolean -> R.Element
toggleButton :: R.State Boolean -> R.Element
toggleButton open =
toggleButton open =
H.button { on
Click: onToggleExpanded open
, className: "search-bar-toggle" }
H.button { on
: {click: \_ -> (snd open) not}
, className: "search-bar-toggle" }
[ H.i { className: "material-icons md-24", style } [ H.text "control_point" ] ]
[ H.i { className: "material-icons md-24", style } [ H.text "control_point" ] ]
where style = { marginTop: "-2px", color: "#000" }
where style = { marginTop: "-2px", color: "#000" }
onToggleExpanded :: forall e. R.State Boolean -> EffectFn1 e Unit
onToggleExpanded (_open /\ setOpen) = mkEffectFn1 $ \_ -> setOpen not
src/Gargantext/Components/Search/SearchField.purs
View file @
1105cefb
...
@@ -2,14 +2,12 @@ module Gargantext.Components.Search.SearchField
...
@@ -2,14 +2,12 @@ module Gargantext.Components.Search.SearchField
( Search, Props, searchField, searchFieldComponent )where
( Search, Props, searchField, searchFieldComponent )where
import Prelude (bind, const, identity, pure, show, ($), (/=), (<$>), (||))
import Prelude (bind, const, identity, pure, show, ($), (/=), (<$>), (||))
import Data.Maybe ( Maybe(..), maybe )
import Data.Maybe (Maybe(..), maybe)
import Data.Tuple ( fst )
import Data.Tuple (fst)
import Data.Tuple.Nested ( (/\) )
import Data.Tuple.Nested ((/\))
import Effect ( Effect )
import Effect.Uncurried (mkEffectFn1)
import Effect.Uncurried (mkEffectFn1)
import FFI.Simple ((..))
import FFI.Simple ((..))
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as HTML
import Reactix.DOM.HTML (text, button, div, input, span, ul, li, a)
import Reactix.DOM.HTML (text, button, div, input, span, ul, li, a)
import Gargantext.Components.Search.Types (Database)
import Gargantext.Components.Search.Types (Database)
...
...
src/Gargantext/Components/Search/Types.purs
View file @
1105cefb
module Gargantext.Components.Search.Types where
module Gargantext.Components.Search.Types where
import Prelude (class Eq, class Show, show, ($), (<>))
import Data.Argonaut (class EncodeJson, class DecodeJson, jsonEmptyObject, (:=), (~>), encodeJson)
import Data.Argonaut (class EncodeJson, class DecodeJson, jsonEmptyObject, (:=), (~>), encodeJson)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Eq (genericEq)
import Data.Generic.Rep.Eq (genericEq)
...
@@ -9,10 +10,11 @@ import Data.Newtype (class Newtype)
...
@@ -9,10 +10,11 @@ import Data.Newtype (class Newtype)
import Data.Tuple (Tuple)
import Data.Tuple (Tuple)
import Data.Tuple.Nested ((/\))
import Data.Tuple.Nested ((/\))
import Effect.Aff (Aff)
import Effect.Aff (Aff)
import Gargantext.Prelude
import Gargantext.Types (class ToQuery, toQuery)
import Gargantext.Config (Ends, NodeType(..), class Path, PathType(..), BackendRoute(..), url)
import Gargantext.Config.REST (post, put)
import Gargantext.Config.REST (post, put)
import Gargantext.Ends (class ToUrl, backendUrl, url)
import Gargantext.Routes (SessionRoute(..))
import Gargantext.Sessions (Session(..))
import Gargantext.Types (class ToQuery, toQuery, NodeType(..))
import Gargantext.Utils (id)
import Gargantext.Utils (id)
import URI.Extra.QueryPairs as QP
import URI.Extra.QueryPairs as QP
import URI.Query as Q
import URI.Query as Q
...
@@ -108,10 +110,10 @@ defaultSearchQuery = SearchQuery
...
@@ -108,10 +110,10 @@ defaultSearchQuery = SearchQuery
, limit: Nothing
, limit: Nothing
, order: Nothing }
, order: Nothing }
instance
pathSearchQuery :: Path
SearchQuery where
instance
toUrlSessionSearchQuery :: ToUrl Session
SearchQuery where
pathType _ = BackendPath
toUrl (Session {backend}) q = backendUrl backend q2
path q
= "new" <> Q.print (toQuery q)
where q2
= "new" <> Q.print (toQuery q)
instance searchQueryToQuery :: ToQuery SearchQuery where
instance searchQueryToQuery :: ToQuery SearchQuery where
toQuery (SearchQuery {offset, limit, order}) =
toQuery (SearchQuery {offset, limit, order}) =
QP.print id id $ QP.QueryPairs $
QP.print id id $ QP.QueryPairs $
...
@@ -157,8 +159,6 @@ decodeCategory 1 = Normal
...
@@ -157,8 +159,6 @@ decodeCategory 1 = Normal
decodeCategory 2 = Favorite
decodeCategory 2 = Favorite
decodeCategory _ = Normal
decodeCategory _ = Normal
newtype CategoryQuery = CategoryQuery {
newtype CategoryQuery = CategoryQuery {
nodeIds :: Array Int
nodeIds :: Array Int
, category :: Category
, category :: Category
...
@@ -170,12 +170,12 @@ instance encodeJsonCategoryQuery :: EncodeJson CategoryQuery where
...
@@ -170,12 +170,12 @@ instance encodeJsonCategoryQuery :: EncodeJson CategoryQuery where
~> "ntc_category" := encodeJson post.category
~> "ntc_category" := encodeJson post.category
~> jsonEmptyObject
~> jsonEmptyObject
categoryUrl ::
Ends
-> Int -> String
categoryUrl ::
Session
-> Int -> String
categoryUrl
ends nodeId = url ends
(NodeAPI Node $ Just nodeId) <> "/category"
categoryUrl
session nodeId = url session
(NodeAPI Node $ Just nodeId) <> "/category"
putCategories ::
Ends
-> Int -> CategoryQuery -> Aff (Array Int)
putCategories ::
Session
-> Int -> CategoryQuery -> Aff (Array Int)
putCategories
ends nodeId = put $ categoryUrl ends
nodeId
putCategories
session nodeId = put $ categoryUrl session
nodeId
performSearch :: forall a. DecodeJson a =>
Ends
-> SearchQuery -> Aff a
performSearch :: forall a. DecodeJson a =>
Session
-> SearchQuery -> Aff a
performSearch
ends q = post (url ends
q) q
performSearch
session q = post (url session
q) q
src/Gargantext/Components/Table.purs
View file @
1105cefb
module Gargantext.Components.Table where
module Gargantext.Components.Table where
import Gargantext.Prelude
import Prelude
import Data.Array (filter)
import Data.Array (filter)
import Data.Maybe (Maybe(..), maybe)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Data.Generic.Rep.Show (genericShow)
import Data.Maybe (Maybe(..)
, maybe
)
import Data.Maybe (Maybe(..))
import Data.Tuple.Nested ((/\))
import Data.Tuple.Nested ((/\))
import Effect (Effect)
import Effect (Effect)
import Effect.Class (liftEffect)
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as H
import Reactix.DOM.HTML as H
import Unsafe.Coerce (unsafeCoerce)
import Gargantext.Prelude
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Reactix as R2
type TableContainerProps =
type TableContainerProps =
...
...
src/Gargantext/Components/Tree.purs
View file @
1105cefb
...
@@ -4,7 +4,7 @@ import Prelude hiding (div)
...
@@ -4,7 +4,7 @@ import Prelude hiding (div)
import DOM.Simple.Console (log2)
import DOM.Simple.Console (log2)
import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, jsonEmptyObject, (.:), (:=), (~>))
import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, jsonEmptyObject, (.:), (:=), (~>))
import Data.Array (filter
, sortWith, head
)
import Data.Array (filter)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Eq (genericEq)
import Data.Generic.Rep.Eq (genericEq)
import Data.Generic.Rep.Show (genericShow)
import Data.Generic.Rep.Show (genericShow)
...
@@ -14,25 +14,25 @@ import Data.Tuple (Tuple)
...
@@ -14,25 +14,25 @@ import Data.Tuple (Tuple)
import Data.Tuple.Nested ((/\))
import Data.Tuple.Nested ((/\))
import Effect.Aff (Aff, launchAff, runAff)
import Effect.Aff (Aff, launchAff, runAff)
import Effect.Class (liftEffect)
import Effect.Class (liftEffect)
import Effect (Effect)
import Effect.Uncurried (mkEffectFn1)
import Effect.Uncurried (mkEffectFn1)
import FFI.Simple ((..))
import FFI.Simple ((..))
import Partial.Unsafe (unsafePartial)
import Partial.Unsafe (unsafePartial)
import React.SyntheticEvent as E
import React.SyntheticEvent as E
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as H
import Reactix.DOM.HTML as H
import Thermite (PerformAction, Spec, Render, modifyState_, simpleSpec, defaultPerformAction)
import URI.Extra.QueryPairs as QP
import URI.Extra.QueryPairs as QP
import URI.Query as Q
import URI.Query as Q
import Web.File.File (toBlob)
import Web.File.File (toBlob)
import Web.File.FileList (FileList, item)
import Web.File.FileList (FileList, item)
import Web.File.FileReader.Aff (readAsText)
import Web.File.FileReader.Aff (readAsText)
import Gargantext.Config (Ends, NodeType(..), BackendRoute(..), NodePath(..), readNodeType, url)
import Gargantext.Config.REST (get, put, post, postWwwUrlencoded, delete)
import Gargantext.Config.REST (get, put, post, postWwwUrlencoded, delete)
import Gargantext.Ends (url)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Router as Router
import Gargantext.Routes as Routes
import Gargantext.Types (class ToQuery, toQuery)
import Gargantext.Routes (AppRoute, SessionRoute(..))
import Gargantext.Sessions (Session)
import Gargantext.Types (class ToQuery, toQuery, NodeType(..), NodePath(..), readNodeType)
import Gargantext.Utils (id)
import Gargantext.Utils (id)
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Reactix as R2
...
@@ -44,9 +44,12 @@ type Reload = Int
...
@@ -44,9 +44,12 @@ type Reload = Int
data NodePopup = CreatePopup | NodePopup
data NodePopup = CreatePopup | NodePopup
type Props = ( root :: ID, mCurrentRoute :: Maybe
Router.Routes, ends :: Ends
)
type Props = ( root :: ID, mCurrentRoute :: Maybe
AppRoute, session :: Session
)
type TreeViewProps = ( tree :: FTree, mCurrentRoute :: Maybe Router.Routes, ends :: Ends )
type TreeViewProps =
( tree :: FTree
, mCurrentRoute :: Maybe AppRoute
, session :: Session )
data NTree a = NTree a (Array (NTree a))
data NTree a = NTree a (Array (NTree a))
...
@@ -118,38 +121,38 @@ type Tree = { tree :: FTree }
...
@@ -118,38 +121,38 @@ type Tree = { tree :: FTree }
mapFTree :: (FTree -> FTree) -> Tree -> Tree
mapFTree :: (FTree -> FTree) -> Tree -> Tree
mapFTree f s@{tree} = s {tree = f tree}
mapFTree f s@{tree} = s {tree = f tree}
performAction ::
Ends
-> R.State Int -> R.State Tree -> Action -> Aff Unit
performAction ::
Session
-> R.State Int -> R.State Tree -> Action -> Aff Unit
performAction
ends
(_ /\ setReload) (s@{tree: NTree (LNode {id}) _} /\ setTree) DeleteNode = do
performAction
session
(_ /\ setReload) (s@{tree: NTree (LNode {id}) _} /\ setTree) DeleteNode = do
void $ deleteNode
ends
id
void $ deleteNode
session
id
liftEffect $ setReload (_ + 1)
liftEffect $ setReload (_ + 1)
performAction
ends
_ ({tree: NTree (LNode {id}) _} /\ setTree) (Submit name) = do
performAction
session
_ ({tree: NTree (LNode {id}) _} /\ setTree) (Submit name) = do
void $ renameNode
ends
id $ RenameValue {name}
void $ renameNode
session
id $ RenameValue {name}
liftEffect $ setTree $ \s@{tree: NTree (LNode node) arr} -> s {tree = NTree (LNode node {name = name}) arr}
liftEffect $ setTree $ \s@{tree: NTree (LNode node) arr} -> s {tree = NTree (LNode node {name = name}) arr}
performAction
ends
(_ /\ setReload) (s@{tree: NTree (LNode {id}) _} /\ setTree) (CreateSubmit name nodeType) = do
performAction
session
(_ /\ setReload) (s@{tree: NTree (LNode {id}) _} /\ setTree) (CreateSubmit name nodeType) = do
void $ createNode
ends
id $ CreateValue {name, nodeType}
void $ createNode
session
id $ CreateValue {name, nodeType}
liftEffect $ setReload (_ + 1)
liftEffect $ setReload (_ + 1)
performAction
ends
_ ({tree: NTree (LNode {id}) _} /\ _) (UploadFile fileType contents) = do
performAction
session
_ ({tree: NTree (LNode {id}) _} /\ _) (UploadFile fileType contents) = do
hashes <- uploadFile
ends
id fileType contents
hashes <- uploadFile
session
id fileType contents
liftEffect $ log2 "uploaded:" hashes
liftEffect $ log2 "uploaded:" hashes
------------------------------------------------------------------------
------------------------------------------------------------------------
mCorpusId :: Maybe
Router.Routes
-> Maybe Int
mCorpusId :: Maybe
AppRoute
-> Maybe Int
mCorpusId (Just (Route
r
.Corpus id)) = Just id
mCorpusId (Just (Route
s
.Corpus id)) = Just id
mCorpusId (Just (Route
r
.CorpusDocument id _ _)) = Just id
mCorpusId (Just (Route
s
.CorpusDocument id _ _)) = Just id
mCorpusId _ = Nothing
mCorpusId _ = Nothing
treeView :: Record Props -> R.Element
treeView :: Record Props -> R.Element
treeView props = R.createElement treeViewCpt props []
treeView props = R.createElement treeViewCpt props []
treeViewCpt :: R.Component Props
treeViewCpt :: R.Component Props
treeViewCpt = R.hooksComponent "
T
reeView" cpt
treeViewCpt = R.hooksComponent "
G.C.Tree.t
reeView" cpt
where
where
cpt props _children = do
cpt props _children = do
-- NOTE: this is a hack to reload the tree view on demand
-- NOTE: this is a hack to reload the tree view on demand
...
@@ -160,36 +163,36 @@ treeLoadView :: R.State Reload -> Record Props -> R.Element
...
@@ -160,36 +163,36 @@ treeLoadView :: R.State Reload -> Record Props -> R.Element
treeLoadView reload p = R.createElement el p []
treeLoadView reload p = R.createElement el p []
where
where
el = R.hooksComponent "TreeLoadView" cpt
el = R.hooksComponent "TreeLoadView" cpt
cpt {root, mCurrentRoute,
ends
} _ = do
cpt {root, mCurrentRoute,
session
} _ = do
useLoader root (loadNode
ends
) $ \loaded ->
useLoader root (loadNode
session
) $ \loaded ->
loadedTreeView reload {tree: loaded, mCurrentRoute,
ends
}
loadedTreeView reload {tree: loaded, mCurrentRoute,
session
}
loadedTreeView :: R.State Reload -> Record TreeViewProps -> R.Element
loadedTreeView :: R.State Reload -> Record TreeViewProps -> R.Element
loadedTreeView reload p = R.createElement el p []
loadedTreeView reload p = R.createElement el p []
where
where
el = R.hooksComponent "LoadedTreeView" cpt
el = R.hooksComponent "LoadedTreeView" cpt
cpt {tree, mCurrentRoute,
ends
} _ = do
cpt {tree, mCurrentRoute,
session
} _ = do
treeState <- R.useState' {tree}
treeState <- R.useState' {tree}
pure $ H.div {className: "tree"}
pure $ H.div {className: "tree"}
[ toHtml reload treeState
ends
mCurrentRoute ]
[ toHtml reload treeState
session
mCurrentRoute ]
-- START toHtml
-- START toHtml
toHtml :: R.State Reload -> R.State Tree ->
Ends -> Maybe Router.Routes
-> R.Element
toHtml :: R.State Reload -> R.State Tree ->
Session -> Maybe AppRoute
-> R.Element
toHtml reload treeState@({tree: (NTree (LNode {id, name, nodeType}) ary)} /\ _)
ends
mCurrentRoute = R.createElement el {} []
toHtml reload treeState@({tree: (NTree (LNode {id, name, nodeType}) ary)} /\ _)
session
mCurrentRoute = R.createElement el {} []
where
where
el = R.hooksComponent "NodeView" cpt
el = R.hooksComponent "NodeView" cpt
pAction = performAction
ends
reload treeState
pAction = performAction
session
reload treeState
cpt props _ = do
cpt props _ = do
folderOpen <- R.useState' true
folderOpen <- R.useState' true
let withId (NTree (LNode {id
}) _) = id
let withId (NTree (LNode {id
: id'}) _) = id'
pure $ H.ul {}
pure $ H.ul {}
[ H.li {}
[ H.li {}
( [ nodeMainSpan pAction {id, name, nodeType, mCurrentRoute} folderOpen
ends
]
( [ nodeMainSpan pAction {id, name, nodeType, mCurrentRoute} folderOpen
session
]
<> childNodes
ends
reload folderOpen mCurrentRoute ary
<> childNodes
session
reload folderOpen mCurrentRoute ary
)
)
]
]
...
@@ -197,14 +200,14 @@ type NodeMainSpanProps =
...
@@ -197,14 +200,14 @@ type NodeMainSpanProps =
( id :: ID
( id :: ID
, name :: Name
, name :: Name
, nodeType :: NodeType
, nodeType :: NodeType
, mCurrentRoute :: Maybe
Router.Routes
)
, mCurrentRoute :: Maybe
AppRoute
)
nodeMainSpan :: (Action -> Aff Unit)
nodeMainSpan :: (Action -> Aff Unit)
-> Record NodeMainSpanProps
-> Record NodeMainSpanProps
-> R.State Boolean
-> R.State Boolean
->
Ends
->
Session
-> R.Element
-> R.Element
nodeMainSpan d p folderOpen
ends
= R.createElement el p []
nodeMainSpan d p folderOpen
session
= R.createElement el p []
where
where
el = R.hooksComponent "NodeMainSpan" cpt
el = R.hooksComponent "NodeMainSpan" cpt
cpt {id, name, nodeType, mCurrentRoute} _ = do
cpt {id, name, nodeType, mCurrentRoute} _ = do
...
@@ -215,7 +218,7 @@ nodeMainSpan d p folderOpen ends = R.createElement el p []
...
@@ -215,7 +218,7 @@ nodeMainSpan d p folderOpen ends = R.createElement el p []
pure $ H.span (dropProps droppedFile isDragOver)
pure $ H.span (dropProps droppedFile isDragOver)
[ folderIcon folderOpen
[ folderIcon folderOpen
, H.a { href: (url
ends
(NodePath nodeType (Just id)))
, H.a { href: (url
session
(NodePath nodeType (Just id)))
, style: {marginLeft: "22px"}
, style: {marginLeft: "22px"}
}
}
[ nodeText {isSelected: (mCorpusId mCurrentRoute) == (Just id), name} ]
[ nodeText {isSelected: (mCorpusId mCurrentRoute) == (Just id), name} ]
...
@@ -224,27 +227,26 @@ nodeMainSpan d p folderOpen ends = R.createElement el p []
...
@@ -224,27 +227,26 @@ nodeMainSpan d p folderOpen ends = R.createElement el p []
, createNodeView d {id, name} popupOpen
, createNodeView d {id, name} popupOpen
, fileTypeView d {id} droppedFile isDragOver
, fileTypeView d {id} droppedFile isDragOver
]
]
folderIcon folderOpen@(open /\ _) =
folderIcon folderOpen
'
@(open /\ _) =
H.a {onClick: R2.effToggler folderOpen}
H.a {onClick: R2.effToggler folderOpen
'
}
[ H.i {className: fldr open} [] ]
[ H.i {className: fldr open} [] ]
popOverIcon (popOver /\ setPopOver) =
popOverIcon (popOver /\ setPopOver) =
H.a { className: "glyphicon glyphicon-cog"
H.a { className: "glyphicon glyphicon-cog"
, id: "rename-leaf"
, id: "rename-leaf"
, on
Click: mkEffectFn1 $ \_ -> setPopOver $ toggle
, on
: { click: \_ -> setPopOver $ toggle }
} []
} []
where
where
toggle Nothing = Just NodePopup
toggle Nothing = Just NodePopup
toggle _ = Nothing
toggle _ = Nothing
dropProps droppedFile isDragOver = {
dropProps droppedFile isDragOver =
className: dropClass droppedFile isDragOver
{ className: dropClass droppedFile isDragOver
, onDrop: dropHandler droppedFile
, on: { drop: dropHandler droppedFile
, onDragOver: onDragOverHandler isDragOver
, dragOver: onDragOverHandler isDragOver
, onDragLeave: onDragLeave isDragOver
, dragLeave: onDragLeave isDragOver } }
}
dropClass (Just _ /\ _) _ = "file-dropped"
dropClass (Just _ /\ _) _ = "file-dropped"
dropClass _ (true /\ _) = "file-dropped"
dropClass _ (true /\ _) = "file-dropped"
dropClass (Nothing /\ _) _ = ""
dropClass (Nothing /\ _) _ = ""
dropHandler (_ /\ setDroppedFile)
= mkEffectFn1 $ \e ->
unsafePartial $ do
dropHandler (_ /\ setDroppedFile)
e =
unsafePartial $ do
let ff = fromJust $ item 0 $ ((e .. "dataTransfer" .. "files") :: FileList)
let ff = fromJust $ item 0 $ ((e .. "dataTransfer" .. "files") :: FileList)
liftEffect $ log2 "drop:" ff
liftEffect $ log2 "drop:" ff
-- prevent redirection when file is dropped
-- prevent redirection when file is dropped
...
@@ -254,23 +256,23 @@ nodeMainSpan d p folderOpen ends = R.createElement el p []
...
@@ -254,23 +256,23 @@ nodeMainSpan d p folderOpen ends = R.createElement el p []
void $ runAff (\_ -> pure unit) do
void $ runAff (\_ -> pure unit) do
contents <- readAsText blob
contents <- readAsText blob
liftEffect $ setDroppedFile $ const $ Just $ DroppedFile {contents: (UploadFileContents contents), fileType: Just CSV}
liftEffect $ setDroppedFile $ const $ Just $ DroppedFile {contents: (UploadFileContents contents), fileType: Just CSV}
onDragOverHandler (_ /\ setIsDragOver)
= mkEffectFn1 $ \e ->
do
onDragOverHandler (_ /\ setIsDragOver)
e =
do
-- prevent redirection when file is dropped
-- prevent redirection when file is dropped
-- https://stackoverflow.com/a/6756680/941471
-- https://stackoverflow.com/a/6756680/941471
E.preventDefault e
E.preventDefault e
E.stopPropagation e
E.stopPropagation e
setIsDragOver $ const true
setIsDragOver $ const true
onDragLeave (_ /\ setIsDragOver)
= mkEffectFn1 $ \_ ->
setIsDragOver $ const false
onDragLeave (_ /\ setIsDragOver)
_ =
setIsDragOver $ const false
fldr :: Boolean -> String
fldr :: Boolean -> String
fldr open = if open then "glyphicon glyphicon-folder-open" else "glyphicon glyphicon-folder-close"
fldr open = if open then "glyphicon glyphicon-folder-open" else "glyphicon glyphicon-folder-close"
childNodes ::
Ends -> R.State Reload -> R.State Boolean -> Maybe Router.Routes
-> Array FTree -> Array R.Element
childNodes ::
Session -> R.State Reload -> R.State Boolean -> Maybe AppRoute
-> Array FTree -> Array R.Element
childNodes _ _ _ _ [] = []
childNodes _ _ _ _ [] = []
childNodes _ _ (false /\ _) _ _ = []
childNodes _ _ (false /\ _) _ _ = []
childNodes
ends
reload (true /\ _) mCurrentRoute ary = map (\ctree -> childNode {tree: ctree}) ary
childNodes
session
reload (true /\ _) mCurrentRoute ary = map (\ctree -> childNode {tree: ctree}) ary
where
where
childNode :: Tree -> R.Element
childNode :: Tree -> R.Element
childNode props = R.createElement el props []
childNode props = R.createElement el props []
...
@@ -278,7 +280,7 @@ childNodes ends reload (true /\ _) mCurrentRoute ary = map (\ctree -> childNode
...
@@ -278,7 +280,7 @@ childNodes ends reload (true /\ _) mCurrentRoute ary = map (\ctree -> childNode
cpt {tree} _ = do
cpt {tree} _ = do
treeState <- R.useState' {tree}
treeState <- R.useState' {tree}
pure $ toHtml reload treeState
ends
mCurrentRoute
pure $ toHtml reload treeState
session
mCurrentRoute
-- END toHtml
-- END toHtml
...
@@ -512,13 +514,13 @@ createNodeView d p (Just CreatePopup /\ setPopupOpen) = R.createElement el p []
...
@@ -512,13 +514,13 @@ createNodeView d p (Just CreatePopup /\ setPopupOpen) = R.createElement el p []
]
]
renderOption (opt :: NodeType) = H.option {} [ H.text $ show opt ]
renderOption (opt :: NodeType) = H.option {} [ H.text $ show opt ]
panelFooter :: R.State String -> R.State NodeType -> R.Element
panelFooter :: R.State String -> R.State NodeType -> R.Element
panelFooter (name /\ _) (nt /\ _) =
panelFooter (name
'
/\ _) (nt /\ _) =
H.div {className: "panel-footer"}
H.div {className: "panel-footer"}
[ H.button {className: "btn btn-success"
[ H.button {className: "btn btn-success"
, type: "button"
, type: "button"
, onClick: mkEffectFn1 $ \_ -> do
, onClick: mkEffectFn1 $ \_ -> do
setPopupOpen $ const Nothing
setPopupOpen $ const Nothing
launchAff $ d $ CreateSubmit name nt
launchAff $ d $ CreateSubmit name
'
nt
} [H.text "Create"]
} [H.text "Create"]
]
]
createNodeView _ _ _ = R.createElement el {} []
createNodeView _ _ _ = R.createElement el {} []
...
@@ -618,8 +620,8 @@ nodeText p = R.createElement el p []
...
@@ -618,8 +620,8 @@ nodeText p = R.createElement el p []
-- END node text
-- END node text
loadNode ::
Ends
-> ID -> Aff FTree
loadNode ::
Session
-> ID -> Aff FTree
loadNode
ends = get <<< url ends
<<< NodeAPI Tree <<< Just
loadNode
session = get <<< url session
<<< NodeAPI Tree <<< Just
----- TREE CRUD Operations
----- TREE CRUD Operations
...
@@ -645,15 +647,15 @@ instance encodeJsonCreateValue :: EncodeJson CreateValue where
...
@@ -645,15 +647,15 @@ instance encodeJsonCreateValue :: EncodeJson CreateValue where
~> "pn_typename" := nodeType
~> "pn_typename" := nodeType
~> jsonEmptyObject
~> jsonEmptyObject
createNode ::
Ends
-> ID -> CreateValue -> Aff ID
createNode ::
Session
-> ID -> CreateValue -> Aff ID
--createNode = post $ urlPlease Back $ "new"
--createNode = post $ urlPlease Back $ "new"
createNode
ends parentId = post $ url ends
(NodeAPI Node $ Just parentId)
createNode
session parentId = post $ url session
(NodeAPI Node $ Just parentId)
renameNode ::
Ends
-> ID -> RenameValue -> Aff (Array ID)
renameNode ::
Session
-> ID -> RenameValue -> Aff (Array ID)
renameNode
ends renameNodeId = put $ url ends
(NodeAPI Node $ Just renameNodeId) <> "/rename"
renameNode
session renameNodeId = put $ url session
(NodeAPI Node $ Just renameNodeId) <> "/rename"
deleteNode ::
Ends
-> ID -> Aff ID
deleteNode ::
Session
-> ID -> Aff ID
deleteNode
ends = delete <<< url ends
<<< NodeAPI Node <<< Just
deleteNode
session = delete <<< url session
<<< NodeAPI Node <<< Just
newtype FileUploadQuery = FileUploadQuery {
newtype FileUploadQuery = FileUploadQuery {
fileType :: FileType
fileType :: FileType
...
@@ -666,11 +668,11 @@ instance fileUploadQueryToQuery :: ToQuery FileUploadQuery where
...
@@ -666,11 +668,11 @@ instance fileUploadQueryToQuery :: ToQuery FileUploadQuery where
where pair :: forall a. Show a => String -> a -> Array (Tuple QP.Key (Maybe QP.Value))
where pair :: forall a. Show a => String -> a -> Array (Tuple QP.Key (Maybe QP.Value))
pair k v = [ QP.keyFromString k /\ (Just $ QP.valueFromString $ show v) ]
pair k v = [ QP.keyFromString k /\ (Just $ QP.valueFromString $ show v) ]
uploadFile ::
Ends
-> ID -> FileType -> UploadFileContents -> Aff (Array FileHash)
uploadFile ::
Session
-> ID -> FileType -> UploadFileContents -> Aff (Array FileHash)
uploadFile
ends
id fileType (UploadFileContents fileContents) = postWwwUrlencoded url2 fileContents
uploadFile
session
id fileType (UploadFileContents fileContents) = postWwwUrlencoded url2 fileContents
where
where
q = FileUploadQuery { fileType: fileType }
q = FileUploadQuery { fileType: fileType }
url2 = url
ends
(NodeAPI Node (Just id)) <> "/upload" <> Q.print (toQuery q)
url2 = url
session
(NodeAPI Node (Just id)) <> "/upload" <> Q.print (toQuery q)
fnTransform :: LNode -> FTree
fnTransform :: LNode -> FTree
fnTransform n = NTree n []
fnTransform n = NTree n []
src/Gargantext/Config.purs
View file @
1105cefb
{- | Main Configuration of Gargantext Front-End
The main function to use for internal link in the Front-End
developpement is : toUrl.
* Example usage (depending on your Config):
toUrl Back Corpus 1 == "http://localhost:8008/api/v1.0/corpus/1"
toUrl Front Corpus 1 == "http://localhost:2015/#/corpus/1"
-}
module Gargantext.Config where
module Gargantext.Config where
import Prelude
import Data.NonEmpty (NonEmpty, (:|), head)
import Control.Plus (empty)
import Gargantext.Ends
import Data.Argonaut (class DecodeJson, decodeJson, class EncodeJson, encodeJson, (:=), (~>), jsonEmptyObject)
import Gargantext.Types (ApiVersion(..))
import Data.Array (filter, head)
import Data.NonEmpty (NonEmpty, (:|))
import Data.NonEmpty as NonEmpty
import Data.Foldable (foldMap)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Data.Maybe (Maybe(..), maybe, fromJust)
import Partial.Unsafe (unsafePartial)
import Gargantext.Router as R
import Gargantext.Types (TermList, TermSize(..))
data PathType = BackendPath | FrontendPath | StaticPath
class Path t where
pathType :: t -> PathType
path :: t -> String
url :: forall t. Path t => Ends -> t -> String
url e p = h (pathType p)
where
h BackendPath = back e.backend (path p)
h FrontendPath = front e.frontend (path p)
h StaticPath = front e.static (path p)
back e path = e.baseUrl <> e.prePath <> show e.version <> "/" <> path
front e path = e.baseUrl <> e.prePath <> path
type Backend =
{ name :: String, version :: ApiVersion
, prePath :: String, baseUrl :: String
}
backendKey :: Backend -> String
backendKey {prePath, baseUrl} = prePath <> baseUrl
type Frontend = { name :: String, baseUrl :: String, prePath :: String }
backend :: ApiVersion -> String -> String -> String -> Backend
backend version baseUrl prePath name = { name, version, prePath, baseUrl }
frontend :: String -> String -> String -> Frontend
frontend baseUrl prePath name = { name, baseUrl, prePath }
defaultBackends :: NonEmpty Array Backend
defaultBackends :: NonEmpty Array Backend
defaultBackends = prod :| [dev, demo, local]
defaultBackends = prod :| [dev, demo, local]
where
where
prod
= backend V10 "http://gargantext.org" "/api/
" "gargantext.org"
prod
= backend V10 "/api/" "http://gargantext.org
" "gargantext.org"
dev
= backend V10 "http://dev.gargantext.org" "/api/" "gargantext.org (dev)
"
dev
= backend V10 "/api/" "http://dev.gargantext.org" "dev.gargantext.org
"
demo
= backend V10 "http://demo.gargantext.org" "/api/" "gargantext.org (demo)
"
demo
= backend V10 "/api/" "http://demo.gargantext.org" "demo.gargantext.org
"
local = backend V10 "
http://localhost:8008" "/api/" "local
"
local = backend V10 "
/api/" "http://localhost:8008" "localhost
"
default
Frontend
s :: NonEmpty Array Frontend
default
App
s :: NonEmpty Array Frontend
default
Frontend
s = relative :| [prod, dev, demo, haskell, caddy]
default
App
s = relative :| [prod, dev, demo, haskell, caddy]
where
where
relative = frontend "
" "/
" "Relative"
relative = frontend "
/" "
" "Relative"
prod
= frontend "https://gargantext.org" "/#/
" "gargantext.org"
prod
= frontend "/#/" "https://gargantext.org
" "gargantext.org"
dev
= frontend "https://dev.gargantext.org" "/#/
" "gargantext.org (dev)"
dev
= frontend "/#/" "https://dev.gargantext.org
" "gargantext.org (dev)"
demo
= frontend "https://demo.gargantext.org" "/#/
" "gargantext.org (demo)"
demo
= frontend "/#/" "https://demo.gargantext.org
" "gargantext.org (demo)"
haskell
= frontend "http://localhost:8008" "/#/" "local (
gargantext)"
haskell
= frontend "/#/" "http://localhost:8008" "localhost.
gargantext)"
python
= frontend "http://localhost:8000" "/#/" "local (python)
"
python
= frontend "/#/" "http://localhost:8000" "localhost.python
"
caddy
= frontend "http://localhost:2015" "/#/" "local (caddy)
"
caddy
= frontend "/#/" "http://localhost:2015" "localhost.caddy
"
defaultStatics :: NonEmpty Array Frontend
defaultStatics :: NonEmpty Array Frontend
defaultStatics = relative :| []
defaultStatics = relative :| []
where
where
relative = frontend "" "/" "relative"
relative = frontend "" "/" "relative"
type Ends =
defaultApp :: Frontend
{ backend :: Backend
defaultApp = head defaultApps
, frontend :: Frontend
, static :: Frontend }
type Ends' =
{ backend :: NonEmpty Array Backend
, frontend :: NonEmpty Array Frontend
, static :: NonEmpty Array Frontend }
defaultEnds :: Ends
defaultEnds =
{ backend: NonEmpty.head defaultBackends
, frontend: NonEmpty.head defaultFrontends
, static: NonEmpty.head defaultStatics }
defaultEnds' :: Ends'
defaultEnds' =
{ backend: defaultBackends
, frontend: defaultFrontends
, static: defaultStatics }
limitUrl :: Limit -> String
limitUrl l = "&limit=" <> show l
offsetUrl :: Offset -> String
offsetUrl o = "&offset=" <> show o
orderUrl :: forall a. Show a => Maybe a -> String
orderUrl = maybe "" (\x -> "&order=" <> show x)
orderByUrl :: forall a. Show a => Maybe a -> String
orderByUrl = maybe "" (\x -> "&orderBy=" <> show x)
showTabType' :: TabType -> String
showTabType' (TabCorpus t) = show t
showTabType' (TabDocument t) = show t
showTabType' (TabPairing t) = show t
data TabPostQuery = TabPostQuery {
offset :: Int
, limit :: Int
, orderBy :: OrderBy
, tabType :: TabType
, query :: String
}
instance encodeJsonTabPostQuery :: EncodeJson TabPostQuery where
encodeJson (TabPostQuery post) =
"view" := showTabType' post.tabType
~> "offset" := post.offset
~> "limit" := post.limit
~> "orderBy" := show post.orderBy
~> "query" := post.query
~> jsonEmptyObject
------------------------------------------------------------
instance pathRoutes :: Path R.Routes where
pathType _ = FrontendPath
path = routesPath
routesPath :: R.Routes -> String
routesPath R.Home = ""
routesPath R.Login = "login"
routesPath (R.Folder i) = "folder/" <> show i
routesPath (R.Corpus i) = "corpus/" <> show i
routesPath (R.CorpusDocument c l i) = "corpus/" <> show c <> "/list/" <> show l <> "/document/" <> show i
routesPath (R.Document l i) = "list/" <> show l <> "/document/" <> show i
routesPath (R.PGraphExplorer i) = "#/"
routesPath (R.Texts i) = "texts/" <> show i
routesPath (R.Lists i) = "lists/" <> show i
routesPath R.Dashboard = "dashboard"
routesPath (R.Annuaire i) = "annuaire/" <> show i
routesPath (R.UserPage i) = "user/" <> show i
routesPath (R.ContactPage i) = "contact/" <> show i
-- nodeTypePath :: NodeType -> Path
-- nodeTypePath = NodeAPI
-- instance toUrlNodeType :: ToUrl NodeType where
-- toUrl ec e nt i = toUrl ec e (NodeAPI nt) i
-- instance toUrlPath :: ToUrl Path where
-- toUrl ec e p i = doUrl base path params
-- where
-- base = endBaseUrl e ec
-- path = endPathUrl e ec p i
-- params = ""
------------------------------------------------------------
data NodeType = NodeUser
| Annuaire
| NodeContact
| Corpus
| Url_Document
| CorpusV3
| Dashboard
| Error
| Folder
| Graph
| Phylo
| Individu
| Node
| Nodes
| Tree
| NodeList
| Texts
derive instance eqNodeType :: Eq NodeType
instance showNodeType :: Show NodeType where
show NodeUser = "NodeUser"
show Annuaire = "Annuaire"
show NodeContact = "NodeContact"
show Corpus = "NodeCorpus"
show CorpusV3 = "NodeCorpusV3"
show Dashboard = "NodeDashboard"
show Url_Document = "NodeDocument"
show Error = "NodeError"
show Folder = "NodeFolder"
show Graph = "NodeGraph"
show Phylo = "NodePhylo"
show Individu = "NodeIndividu"
show Node = "Node"
show Nodes = "Nodes"
show Tree = "NodeTree"
show NodeList = "NodeList"
show Texts = "NodeTexts"
readNodeType :: String -> NodeType
readNodeType "NodeAnnuaire" = Annuaire
readNodeType "NodeDashboard" = Dashboard
readNodeType "Document" = Url_Document
readNodeType "NodeFolder" = Folder
readNodeType "NodeGraph" = Graph
readNodeType "NodePhylo" = Phylo
readNodeType "Individu" = Individu
readNodeType "Node" = Node
readNodeType "Nodes" = Nodes
readNodeType "NodeCorpus" = Corpus
readNodeType "NodeCorpusV3" = CorpusV3
readNodeType "NodeUser" = NodeUser
readNodeType "NodeContact" = NodeContact
readNodeType "Tree" = Tree
readNodeType "NodeList" = NodeList
readNodeType "NodeTexts" = Texts
readNodeType _ = Error
{-
------------------------------------------------------------
instance ordNodeType :: Ord NodeType where
compare n1 n2 = compare (show n1) (show n2)
instance eqNodeType :: Eq NodeType where
eq n1 n2 = eq (show n1) (show n2)
-}
------------------------------------------------------------
instance decodeJsonNodeType :: DecodeJson NodeType where
decodeJson json = do
obj <- decodeJson json
pure $ readNodeType obj
instance encodeJsonNodeType :: EncodeJson NodeType where
encodeJson nodeType = encodeJson $ show nodeType
nodeTypePath :: NodeType -> String
nodeTypePath Annuaire = "annuaire"
nodeTypePath Corpus = "corpus"
nodeTypePath CorpusV3 = "corpus"
nodeTypePath Dashboard = "dashboard"
nodeTypePath Url_Document = "document"
nodeTypePath Error = "ErrorNodeType"
nodeTypePath Folder = "folder"
nodeTypePath Graph = "graph"
nodeTypePath Phylo = "phylo"
nodeTypePath Individu = "individu"
nodeTypePath Node = "node"
nodeTypePath Nodes = "nodes"
nodeTypePath NodeUser = "user"
nodeTypePath NodeContact = "contact"
nodeTypePath Tree = "tree"
nodeTypePath NodeList = "lists"
nodeTypePath Texts = "texts"
------------------------------------------------------------
type ListId = Int
type NgramsGetOpts =
{ tabType :: TabType
, offset :: Offset
, limit :: Limit
, orderBy :: Maybe OrderBy
, listIds :: Array ListId
, termListFilter :: Maybe TermList
, termSizeFilter :: Maybe TermSize
, searchQuery :: String
}
type SearchOpts =
{ {-id :: Int
, query :: Array String
,-}
listId :: Int
, limit :: Limit
, offset :: Offset
, orderBy :: Maybe OrderBy
}
type CorpusMetricOpts =
{ tabType :: TabType
, listId :: ListId
, limit :: Maybe Limit
}
type ChartOpts =
{ chartType :: ChartType
, tabType :: TabType
-- , listId :: ListId
-- , limit :: Maybe Limit
}
data BackendRoute
= Auth
| Tab TabType (Maybe Id)
| Children NodeType Offset Limit (Maybe OrderBy) (Maybe Id)
| GetNgrams NgramsGetOpts (Maybe Id)
| PutNgrams TabType (Maybe ListId) (Maybe TermList) (Maybe Id)
-- ^ The name is not good. In particular this URL is used both in PUT and POST.
| NodeAPI NodeType (Maybe Id)
| ListDocument (Maybe ListId) (Maybe Id)
| Search SearchOpts (Maybe Id)
| CorpusMetrics CorpusMetricOpts (Maybe Id)
| Chart ChartOpts (Maybe Id)
instance pathBackendRoute :: Path BackendRoute where
pathType _ = BackendPath
path = backendPath
backendPath :: BackendRoute -> String
backendPath (Tab t i) = backendPath (NodeAPI Node i) <> "/" <> showTabType' t
backendPath (Children n o l s i) = root <> "children?type=" <> show n <> offsetUrl o <> limitUrl l <> orderUrl s
where root = backendPath (NodeAPI Node i) <> "/"
backendPath (NodeAPI Phylo pId) = "phyloscape?nodeId=" <> (show $ maybe 0 identity pId)
backendPath (GetNgrams opts i) =
base opts.tabType
<> "/ngrams?ngramsType="
<> showTabType' opts.tabType
<> offsetUrl opts.offset
<> limitUrl opts.limit
<> orderByUrl opts.orderBy
<> foldMap (\x -> "&list=" <> show x) opts.listIds
<> foldMap (\x -> "&listType=" <> show x) opts.termListFilter
<> foldMap termSizeFilter opts.termSizeFilter
<> search opts.searchQuery
where
base (TabCorpus _) = backendPath (NodeAPI Node i)
base _ = backendPath (NodeAPI Url_Document i)
termSizeFilter MonoTerm = "&minTermSize=0&maxTermSize=1"
termSizeFilter MultiTerm = "&minTermSize=2"
search "" = ""
search s = "&search=" <> s
backendPath (ListDocument lId dId) =
backendPath (NodeAPI NodeList lId) <> "/document/" <> (show $ maybe 0 identity dId)
backendPath (PutNgrams t listId termList i) =
backendPath (NodeAPI Node i)
<> "/ngrams?ngramsType="
<> showTabType' t
<> maybe "" (\x -> "&list=" <> show x) listId
<> foldMap (\x -> "&listType=" <> show x) termList
backendPath Auth = "auth"
backendPath (NodeAPI nt i) = nodeTypePath nt <> (maybe "" (\i' -> "/" <> show i') i)
backendPath (Search {listId,limit,offset,orderBy} i) =
backendPath (NodeAPI Corpus i)
<> "/search?list_id=" <> show listId
<> offsetUrl offset
<> limitUrl limit
<> orderUrl orderBy
backendPath (CorpusMetrics {tabType, listId, limit} i) =
backendPath (NodeAPI Corpus i) <> "/metrics"
<> "?ngrams=" <> show listId
<> "&ngramsType=" <> showTabType' tabType
<> maybe "" (\x -> "&limit=" <> show x) limit
-- TODO fix this url path
backendPath (Chart {chartType, tabType} i) =
backendPath (NodeAPI Corpus i) <> "/" <> show chartType
<> "?ngramsType=" <> showTabType' tabType
<> "&listType=GraphTerm" -- <> show listId
-- <> maybe "" (\x -> "&limit=" <> show x) limit
data NodePath = NodePath NodeType (Maybe Id)
instance pathNodePath :: Path NodePath where
pathType _ = FrontendPath
path (NodePath nt i) = nodeTypePath nt <> id
where id = maybe "" (\i' -> "/" <> show i') i
data ChartType = Histo | Scatter | ChartPie | ChartTree
instance showChartType :: Show ChartType
where
show Histo = "chart"
show Scatter = "scatter"
show ChartPie = "pie"
show ChartTree = "tree"
type Id = Int
type Limit = Int
type Offset = Int
data OrderBy = DateAsc | DateDesc
| TitleAsc | TitleDesc
| ScoreAsc | ScoreDesc
| TermAsc | TermDesc
| SourceAsc | SourceDesc
derive instance genericOrderBy :: Generic OrderBy _
instance showOrderBy :: Show OrderBy where
show = genericShow
------------------------------------------------------------
data ApiVersion = V10 | V11
instance showApiVersion :: Show ApiVersion where
show V10 = "v1.0"
show V11 = "v1.1"
------------------------------------------------------------
instance eqApiVersion :: Eq ApiVersion where
eq V10 V10 = true
eq V11 V11 = true
eq _ _ = false
data CTabNgramType = CTabTerms | CTabSources | CTabAuthors | CTabInstitutes
derive instance eqCTabNgramType :: Eq CTabNgramType
instance showCTabNgramType :: Show CTabNgramType where
show CTabTerms = "Terms"
show CTabSources = "Sources"
show CTabAuthors = "Authors"
show CTabInstitutes = "Institutes"
data PTabNgramType = PTabPatents | PTabBooks | PTabCommunication
derive instance eqPTabNgramType :: Eq PTabNgramType
instance showPTabNgramType :: Show PTabNgramType where
show PTabPatents = "Patents"
show PTabBooks = "Books"
show PTabCommunication = "Communication"
data TabSubType a = TabDocs | TabNgramType a | TabTrash | TabMoreLikeFav | TabMoreLikeTrash
derive instance eqTabSubType :: Eq a => Eq (TabSubType a)
instance showTabSubType :: Show a => Show (TabSubType a) where
show TabDocs = "Docs"
show (TabNgramType a) = show a
show TabTrash = "Trash"
show TabMoreLikeFav = "MoreFav"
show TabMoreLikeTrash = "MoreTrash"
data TabType
= TabCorpus (TabSubType CTabNgramType)
| TabPairing (TabSubType PTabNgramType)
| TabDocument (TabSubType CTabNgramType)
derive instance eqTabType :: Eq TabType
derive instance genericTabType :: Generic TabType _
defaultStatic :: Frontend
defaultStatic = head defaultStatics
instance showTabType :: Show TabType where
defaultFrontends :: Frontends
show = genericShow
defaultFrontends = Frontends { app: defaultApp, static: defaultStatic }
src/Gargantext/Ends.purs
0 → 100644
View file @
1105cefb
-- | Those things at the end of urls
module Gargantext.Ends
-- ( )
where
import Prelude (class Eq, class Show, identity, show, ($), (<>))
import Data.Foldable (foldMap)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Eq (genericEq)
import Data.Maybe (Maybe, maybe)
import Gargantext.Routes as R
import Gargantext.Types (ApiVersion, Limit, NodeType(..), Offset, TabType(..), TermSize(..), nodeTypePath, showTabType')
-- | A means of generating a url to visit, a destination
class ToUrl conf p where
toUrl :: conf -> p -> String
url :: forall conf p. ToUrl conf p => conf -> p -> String
url = toUrl
-- | Encapsulates the data we need to talk to a backend server
newtype Backend = Backend
{ name :: String
, baseUrl :: String
, prePath :: String
, version :: ApiVersion }
backend :: ApiVersion -> String -> String -> String -> Backend
backend version prePath baseUrl name = Backend { name, version, prePath, baseUrl }
-- | Creates a backend url from a backend and the path as a string
backendUrl :: Backend -> String -> String
backendUrl (Backend b) path = b.baseUrl <> b.prePath <> show b.version <> "/" <> path
derive instance genericBackend :: Generic Backend _
instance eqBackend :: Eq Backend where
eq = genericEq
instance showBackend :: Show Backend where
show (Backend {name}) = name
instance toUrlBackendString :: ToUrl Backend String where
toUrl = backendUrl
-- | Encapsulates the data needed to construct a url to a frontend
-- | server (either for the app or static content)
newtype Frontend = Frontend
{ name :: String
, baseUrl :: String
, prePath :: String }
derive instance genericFrontend :: Generic Frontend _
instance eqFrontend :: Eq Frontend where
eq = genericEq
-- | Creates a frontend
frontend :: String -> String -> String -> Frontend
frontend baseUrl prePath name = Frontend { name, baseUrl, prePath }
-- | Creates a url from a frontend and the path as a string
frontendUrl :: Frontend -> String -> String
frontendUrl (Frontend f) path = f.baseUrl <> f.prePath <> path
instance showFrontend :: Show Frontend where
show (Frontend {name}) = name
instance toUrlFrontendString :: ToUrl Frontend String where
toUrl = frontendUrl
instance toUrlFrontendAppRoute :: ToUrl Frontend R.AppRoute where
toUrl f r = frontendUrl f (R.appPath r)
-- | The currently selected App and Static configurations
newtype Frontends = Frontends { app :: Frontend, static :: Frontend }
-- | Creates an app url from a Frontends and the path as a string
appUrl :: Frontends -> String -> String
appUrl (Frontends {app}) = frontendUrl app
-- | Creates a static url from a Frontends and the path as a string
staticUrl :: Frontends -> String -> String
staticUrl (Frontends {static}) = frontendUrl static
instance toUrlFrontendsRoutes :: ToUrl Frontends R.AppRoute where
toUrl f r = appUrl f (R.appPath r)
sessionPath :: R.SessionRoute -> String
sessionPath (R.Tab t i) = sessionPath (R.NodeAPI Node i) <> "/" <> showTabType' t
sessionPath (R.Children n o l s i) = root <> "children?type=" <> show n <> offsetUrl o <> limitUrl l <> orderUrl s
where root = sessionPath (R.NodeAPI Node i) <> "/"
sessionPath (R.NodeAPI Phylo pId) = "phyloscape?nodeId=" <> (show $ maybe 0 identity pId)
sessionPath (R.GetNgrams opts i) =
base opts.tabType
<> "/ngrams?ngramsType="
<> showTabType' opts.tabType
<> offsetUrl opts.offset
<> limitUrl opts.limit
<> orderByUrl opts.orderBy
<> foldMap (\x -> "&list=" <> show x) opts.listIds
<> foldMap (\x -> "&listType=" <> show x) opts.termListFilter
<> foldMap termSizeFilter opts.termSizeFilter
<> search opts.searchQuery
where
base (TabCorpus _) = sessionPath (R.NodeAPI Node i)
base _ = sessionPath (R.NodeAPI Url_Document i)
termSizeFilter MonoTerm = "&minTermSize=0&maxTermSize=1"
termSizeFilter MultiTerm = "&minTermSize=2"
search "" = ""
search s = "&search=" <> s
sessionPath (R.ListDocument lId dId) =
sessionPath (R.NodeAPI NodeList lId) <> "/document/" <> (show $ maybe 0 identity dId)
sessionPath (R.PutNgrams t listId termList i) =
sessionPath (R.NodeAPI Node i)
<> "/ngrams?ngramsType="
<> showTabType' t
<> maybe "" (\x -> "&list=" <> show x) listId
<> foldMap (\x -> "&listType=" <> show x) termList
sessionPath (R.NodeAPI nt i) = nodeTypePath nt <> (maybe "" (\i' -> "/" <> show i') i)
sessionPath (R.Search {listId,limit,offset,orderBy} i) =
sessionPath (R.NodeAPI Corpus i)
<> "/search?list_id=" <> show listId
<> offsetUrl offset
<> limitUrl limit
<> orderUrl orderBy
sessionPath (R.CorpusMetrics {tabType, listId, limit} i) =
sessionPath (R.NodeAPI Corpus i) <> "/metrics"
<> "?ngrams=" <> show listId
<> "&ngramsType=" <> showTabType' tabType
<> maybe "" (\x -> "&limit=" <> show x) limit
-- TODO fix this url path
sessionPath (R.Chart {chartType, tabType} i) =
sessionPath (R.NodeAPI Corpus i) <> "/" <> show chartType
<> "?ngramsType=" <> showTabType' tabType
<> "&listType=GraphTerm" -- <> show listId
-- <> maybe "" (\x -> "&limit=" <> show x) limit
------- misc routing stuff
limitUrl :: Limit -> String
limitUrl l = "&limit=" <> show l
offsetUrl :: Offset -> String
offsetUrl o = "&offset=" <> show o
orderUrl :: forall a. Show a => Maybe a -> String
orderUrl = maybe "" (\x -> "&order=" <> show x)
orderByUrl :: forall a. Show a => Maybe a -> String
orderByUrl = maybe "" (\x -> "&orderBy=" <> show x)
-- nodeTypePath :: NodeType -> Path
-- nodeTypePath = NodeAPI
-- instance toUrlNodeType :: ToUrl NodeType where
-- toUrl ec e nt i = toUrl ec e (NodeAPI nt) i
-- instance toUrlPath :: ToUrl Path where
-- toUrl ec e p i = doUrl base path params
-- where
-- base = endBaseUrl e ec
-- path = endPathUrl e ec p i
-- params = ""
------------------------------------------------------------
src/Gargantext/Global.purs
deleted
100644 → 0
View file @
80557556
module Gargantext.Global
( Global, defaultGlobal )
where
import Prelude (pure)
import Effect (Effect)
import Data.Maybe (Maybe(..))
import Gargantext.Config (Ends, defaultEnds)
import Gargantext.Components.Login.Types (AuthData(..))
type Global =
{ ends :: Ends
, authData :: Maybe AuthData }
defaultGlobal :: Effect Global
defaultGlobal = pure { ends: defaultEnds, authData: Nothing }
src/Gargantext/Hooks/Loader.purs
View file @
1105cefb
module Gargantext.Hooks.Loader where
module Gargantext.Hooks.Loader where
import Data.Functor ((<$>))
import Gargantext.Prelude
import Control.Monad ((=<<))
import Data.Maybe (Maybe(..), isNothing, maybe, maybe')
import Data.Maybe (Maybe(..), isNothing, maybe, maybe')
import Data.Tuple (fst)
import Data.Tuple (fst)
import Data.Tuple.Nested ((/\))
import Data.Tuple.Nested ((/\))
import Gargantext.Prelude
import Effect.Aff (Aff)
import Effect.Aff (Aff)
import Effect.Class (liftEffect)
import Effect.Class (liftEffect)
import Reactix as R
import Reactix as R
...
...
src/Gargantext/Hooks/Router.purs
0 → 100644
View file @
1105cefb
module Gargantext.Hooks.Router (useHashRouter) where
import Prelude (($), bind, discard, const, pure)
import Data.Tuple.Nested ((/\))
import Reactix as R
import Routing.Match (Match)
import Routing.Hash (matches)
-- | Ties the hash router to a state hook of routes
-- | Note: if it gets sent to an unrecognised url, it will quietly drop the change
useHashRouter :: forall routes. Match routes -> routes -> R.Hooks (R.State routes)
useHashRouter routes init = do
route@(_ /\ setRoute) <- R.useState' init
R.useEffectOnce $ matches routes $ \_old new -> setRoute (const new)
pure route
src/Gargantext/Hooks/Sigmax.purs
View file @
1105cefb
...
@@ -3,27 +3,23 @@ module Gargantext.Hooks.Sigmax
...
@@ -3,27 +3,23 @@ module Gargantext.Hooks.Sigmax
-- )
-- )
where
where
import Prelude
import Prelude
(Unit, bind, const, discard, flip, pure, unit, ($), (*>), (<$), (<$>), (<<<), (<>), (>>=))
import Data.Array as A
import Data.Array as A
import Data.Bitraversable (bitraverse)
import Data.Either (Either(..), either)
import Data.Either (Either(..), either)
import Data.Foldable (sequence_)
import Data.Foldable (sequence_)
import Data.Maybe (Maybe(..)
, maybe
)
import Data.Maybe (Maybe(..))
import Data.Nullable (Nullable
, null
)
import Data.Nullable (Nullable)
import Data.Sequence as Seq
import Data.Sequence as Seq
import Data.Sequence (Seq)
import Data.Sequence (Seq)
import Data.Traversable (
for, for_, traverse,
traverse_)
import Data.Traversable (traverse_)
import DOM.Simple.Console (log, log2)
import DOM.Simple.Console (log, log2)
import DOM.Simple.Types (Element)
import DOM.Simple.Types (Element)
import Effect (Effect)
import Effect (Effect)
import FFI.Simple (delay)
import FFI.Simple (delay)
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as RH
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Reactix as R2
import Gargantext.Types (class Optional)
import Gargantext.Hooks.Sigmax.Sigma (SigmaOpts)
import Gargantext.Hooks.Sigmax.Sigma as Sigma
import Gargantext.Hooks.Sigmax.Sigma as Sigma
import Gargantext.Hooks.Sigmax.Types
import Gargantext.Hooks.Sigmax.Types
(Graph(..))
type Sigma =
type Sigma =
{ sigma :: R.Ref (Maybe Sigma.Sigma)
{ sigma :: R.Ref (Maybe Sigma.Sigma)
...
@@ -88,8 +84,8 @@ useSigma container settings sigmaRef = do
...
@@ -88,8 +84,8 @@ useSigma container settings sigmaRef = do
delay unit $ handleSigma sigma (readSigma sigma)
delay unit $ handleSigma sigma (readSigma sigma)
pure $ {sigma, isNew}
pure $ {sigma, isNew}
where
where
newSigma sigmaRef = do
newSigma sigmaRef
'
= do
let mSigma = R.readRef sigmaRef
let mSigma = R.readRef sigmaRef
'
case mSigma of
case mSigma of
Just sigma -> pure sigma
Just sigma -> pure sigma
Nothing -> do
Nothing -> do
...
...
src/Gargantext/Hooks/Sigmax/Sigmajs.purs
View file @
1105cefb
...
@@ -3,10 +3,8 @@ module Gargantext.Hooks.Sigmax.Sigmajs where
...
@@ -3,10 +3,8 @@ module Gargantext.Hooks.Sigmax.Sigmajs where
import Prelude
import Prelude
import Data.Nullable (Nullable)
import Data.Nullable (Nullable)
import Data.Sequence (Seq)
import Data.Sequence as Seq
import Effect (Effect)
import Effect (Effect)
import Effect.Uncurried (EffectFn1,
EffectFn2, mkEffectFn1,
runEffectFn1)
import Effect.Uncurried (EffectFn1, runEffectFn1)
import React (ReactRef, SyntheticEventHandler)
import React (ReactRef, SyntheticEventHandler)
import React.SyntheticEvent (SyntheticMouseEvent)
import React.SyntheticEvent (SyntheticMouseEvent)
import Record.Unsafe (unsafeGet)
import Record.Unsafe (unsafeGet)
...
...
src/Gargantext/Pages/Annuaire.purs
View file @
1105cefb
module Gargantext.Pages.Annuaire where
module Gargantext.Pages.Annuaire where
import Gargantext.Prelude
import Prelude (bind, const, identity, pure, ($), (<$>), (<>))
import Data.Argonaut (class DecodeJson, decodeJson, (.:), (.:!))
import Data.Argonaut (class DecodeJson, decodeJson, (.:), (.:!))
import Data.Array (head)
import Data.Array (head)
import Data.Maybe (Maybe(..), maybe)
import Data.Maybe (Maybe(..), maybe)
import Data.Tuple (fst, snd)
import Data.Tuple (fst, snd)
import Effect.Aff (Aff)
import Effect.Aff (Aff)
import Gargantext.Components.Table as T
import Gargantext.Components.Table as T
import Gargantext.Config (NodeType(..), Ends, BackendRoute(..), NodePath(..), url)
import Gargantext.Ends (url)
import Gargantext.Routes (SessionRoute(..))
import Gargantext.Sessions (Session)
import Gargantext.Types (NodePath(..), NodeType(..))
import Gargantext.Config.REST (get)
import Gargantext.Config.REST (get)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Pages.Annuaire.User.Contacts.Types (Contact(..), HyperdataContact(..), ContactWhere(..))
import Gargantext.Pages.Annuaire.User.Contacts.Types (Contact(..), HyperdataContact(..), ContactWhere(..))
...
@@ -27,7 +29,7 @@ toRows (AnnuaireTable a) = a.annuaireTable
...
@@ -27,7 +29,7 @@ toRows (AnnuaireTable a) = a.annuaireTable
-- | Top level layout component. Loads an annuaire by id and renders
-- | Top level layout component. Loads an annuaire by id and renders
-- | the annuaire using the result
-- | the annuaire using the result
type LayoutProps = ( annuaireId :: Int,
ends :: Ends
)
type LayoutProps = ( annuaireId :: Int,
session :: Session
)
annuaireLayout :: Record LayoutProps -> R.Element
annuaireLayout :: Record LayoutProps -> R.Element
annuaireLayout props = R.createElement annuaireLayoutCpt props []
annuaireLayout props = R.createElement annuaireLayoutCpt props []
...
@@ -35,13 +37,13 @@ annuaireLayout props = R.createElement annuaireLayoutCpt props []
...
@@ -35,13 +37,13 @@ annuaireLayout props = R.createElement annuaireLayoutCpt props []
annuaireLayoutCpt :: R.Component LayoutProps
annuaireLayoutCpt :: R.Component LayoutProps
annuaireLayoutCpt = R.hooksComponent "G.P.Annuaire.annuaireLayout" cpt
annuaireLayoutCpt = R.hooksComponent "G.P.Annuaire.annuaireLayout" cpt
where
where
cpt {annuaireId,
ends
} _ = do
cpt {annuaireId,
session
} _ = do
path <- R.useState' annuaireId
path <- R.useState' annuaireId
useLoader (fst path) (getAnnuaireInfo
ends
) $
useLoader (fst path) (getAnnuaireInfo
session
) $
\info -> annuaire {
ends
, path, info}
\info -> annuaire {
session
, path, info}
type AnnuaireProps =
type AnnuaireProps =
(
ends :: Ends
(
session :: Session
, path :: R.State Int
, path :: R.State Int
, info :: AnnuaireInfo )
, info :: AnnuaireInfo )
...
@@ -53,13 +55,13 @@ annuaire props = R.createElement annuaireCpt props []
...
@@ -53,13 +55,13 @@ annuaire props = R.createElement annuaireCpt props []
annuaireCpt :: R.Component AnnuaireProps
annuaireCpt :: R.Component AnnuaireProps
annuaireCpt = R.staticComponent "G.P.Annuaire.annuaire" cpt
annuaireCpt = R.staticComponent "G.P.Annuaire.annuaire" cpt
where
where
cpt {
ends
, path, info: info@(AnnuaireInfo {name, date: date'})} _ = R.fragment
cpt {
session
, path, info: info@(AnnuaireInfo {name, date: date'})} _ = R.fragment
[ T.tableHeaderLayout headerProps
[ T.tableHeaderLayout headerProps
, H.p {} []
, H.p {} []
, H.div {className: "col-md-3"}
, H.div {className: "col-md-3"}
[ H.text " Filter ", H.input { className: "form-control", style } ]
[ H.text " Filter ", H.input { className: "form-control", style } ]
, H.br {}
, H.br {}
, pageLayout { info,
ends
, annuairePath: path } ]
, pageLayout { info,
session
, annuairePath: path } ]
where
where
headerProps = { title: name, desc: name, query: "", date, user: ""}
headerProps = { title: name, desc: name, query: "", date, user: ""}
date = "Last update: " <> date'
date = "Last update: " <> date'
...
@@ -67,7 +69,7 @@ annuaireCpt = R.staticComponent "G.P.Annuaire.annuaire" cpt
...
@@ -67,7 +69,7 @@ annuaireCpt = R.staticComponent "G.P.Annuaire.annuaire" cpt
type PagePath = { nodeId :: Int, params :: T.Params }
type PagePath = { nodeId :: Int, params :: T.Params }
type PageLayoutProps =
type PageLayoutProps =
(
ends :: Ends
(
session :: Session
, annuairePath :: R.State Int
, annuairePath :: R.State Int
, info :: AnnuaireInfo )
, info :: AnnuaireInfo )
...
@@ -77,14 +79,14 @@ pageLayout props = R.createElement pageLayoutCpt props []
...
@@ -77,14 +79,14 @@ pageLayout props = R.createElement pageLayoutCpt props []
pageLayoutCpt :: R.Component PageLayoutProps
pageLayoutCpt :: R.Component PageLayoutProps
pageLayoutCpt = R.hooksComponent "G.P.Annuaire.pageLayout" cpt
pageLayoutCpt = R.hooksComponent "G.P.Annuaire.pageLayout" cpt
where
where
cpt {annuairePath, info,
ends
} _ = do
cpt {annuairePath, info,
session
} _ = do
pagePath <- R.useState' (initialPagePath (fst annuairePath))
pagePath <- R.useState' (initialPagePath (fst annuairePath))
useLoader (fst pagePath) (loadPage
ends
) $
useLoader (fst pagePath) (loadPage
session
) $
\table -> page {
ends
, table, pagePath, annuairePath}
\table -> page {
session
, table, pagePath, annuairePath}
initialPagePath nodeId = {nodeId, params: T.initialParams}
initialPagePath nodeId = {nodeId, params: T.initialParams}
type PageProps =
type PageProps =
(
ends :: Ends
(
session :: Session
, annuairePath :: R.State Int
, annuairePath :: R.State Int
, pagePath :: R.State PagePath
, pagePath :: R.State PagePath
-- , info :: AnnuaireInfo
-- , info :: AnnuaireInfo
...
@@ -96,21 +98,21 @@ page props = R.createElement pageCpt props []
...
@@ -96,21 +98,21 @@ page props = R.createElement pageCpt props []
pageCpt :: R.Component PageProps
pageCpt :: R.Component PageProps
pageCpt = R.staticComponent "LoadedAnnuairePage" cpt
pageCpt = R.staticComponent "LoadedAnnuairePage" cpt
where
where
cpt {
ends
, annuairePath, pagePath, table: (AnnuaireTable {annuaireTable}) } _ = do
cpt {
session
, annuairePath, pagePath, table: (AnnuaireTable {annuaireTable}) } _ = do
T.table { rows, setParams, container, colNames, totalRecords }
T.table { rows, setParams, container, colNames, totalRecords }
where
where
totalRecords =4361 -- TODO
totalRecords =4361 -- TODO
rows = (\c -> {row: contactCells
ends
c, delete: false}) <$> annuaireTable
rows = (\c -> {row: contactCells
session
c, delete: false}) <$> annuaireTable
setParams params = snd pagePath $ const {params, nodeId: fst annuairePath}
setParams params = snd pagePath $ const {params, nodeId: fst annuairePath}
container = T.defaultContainer { title: "Annuaire" } -- TODO
container = T.defaultContainer { title: "Annuaire" } -- TODO
colNames = T.ColumnName <$> [ "", "Name", "Company", "Service", "Role"]
colNames = T.ColumnName <$> [ "", "Name", "Company", "Service", "Role"]
contactCells ::
Ends
-> Maybe Contact -> Array R.Element
contactCells ::
Session
-> Maybe Contact -> Array R.Element
contactCells
ends
= maybe [] render
contactCells
session
= maybe [] render
where
where
render (Contact { id, hyperdata : (HyperdataContact contact@{who: who, ou:ou} ) }) =
render (Contact { id, hyperdata : (HyperdataContact contact@{who: who, ou:ou} ) }) =
let nodepath = NodePath NodeContact (Just id)
let nodepath = NodePath NodeContact (Just id)
href = url
ends
nodepath in
href = url
session
nodepath in
[ H.text ""
[ H.text ""
, H.a { href, target: "blank" } [ H.text $ maybe "name" identity contact.title ]
, H.a { href, target: "blank" } [ H.text $ maybe "name" identity contact.title ]
, H.text $ maybe "No ContactWhere" contactWhereOrg (head $ ou)
, H.text $ maybe "No ContactWhere" contactWhereOrg (head $ ou)
...
@@ -175,9 +177,9 @@ instance decodeAnnuaireTable :: DecodeJson AnnuaireTable where
...
@@ -175,9 +177,9 @@ instance decodeAnnuaireTable :: DecodeJson AnnuaireTable where
rows <- decodeJson json
rows <- decodeJson json
pure $ AnnuaireTable { annuaireTable : rows}
pure $ AnnuaireTable { annuaireTable : rows}
------------------------------------------------------------------------
------------------------------------------------------------------------
loadPage ::
Ends
-> PagePath -> Aff AnnuaireTable
loadPage ::
Session
-> PagePath -> Aff AnnuaireTable
loadPage
ends
{nodeId, params: { offset, limit, orderBy }} =
loadPage
session
{nodeId, params: { offset, limit, orderBy }} =
get $ url
ends
children
get $ url
session
children
-- TODO orderBy
-- TODO orderBy
-- where
-- where
-- convOrderBy (T.ASC (T.ColumnName "Name")) = NameAsc
-- convOrderBy (T.ASC (T.ColumnName "Name")) = NameAsc
...
@@ -190,6 +192,6 @@ loadPage ends {nodeId, params: { offset, limit, orderBy }} =
...
@@ -190,6 +192,6 @@ loadPage ends {nodeId, params: { offset, limit, orderBy }} =
------ Annuaire loading ------
------ Annuaire loading ------
getAnnuaireInfo ::
Ends
-> Int -> Aff AnnuaireInfo
getAnnuaireInfo ::
Session
-> Int -> Aff AnnuaireInfo
getAnnuaireInfo
ends id = get $ url ends
(NodeAPI Node (Just id))
getAnnuaireInfo
session id = get $ url session
(NodeAPI Node (Just id))
src/Gargantext/Pages/Annuaire/User/Contacts.purs
View file @
1105cefb
...
@@ -3,31 +3,26 @@ module Gargantext.Pages.Annuaire.User.Contacts
...
@@ -3,31 +3,26 @@ module Gargantext.Pages.Annuaire.User.Contacts
, userLayout )
, userLayout )
where
where
import Prelude ((<$>))
import Prelude (bind, pure, ($), (<<<), (<>), (<$>))
import Data.List (List, zipWith, catMaybes, toUnfoldable)
import Data.Map (Map, empty, keys, values, lookup)
import Data.Array (head)
import Data.Array (head)
import Data.Semigroup ((<>))
import Data.Maybe (Maybe(..), fromMaybe, maybe)
import Data.Maybe (Maybe(..), fromMaybe, maybe)
import Data.Set (toUnfoldable) as S
import Data.Tuple (Tuple(..))
import Data.Tuple (Tuple(..), uncurry)
import Data.Tuple.Nested ((/\))
import Data.Tuple.Nested ((/\))
import Data.Unfoldable (class Unfoldable)
import Data.Maybe (Maybe(..))
import Data.Newtype (unwrap)
import Data.Newtype (unwrap)
import Data.String (joinWith)
import Data.String (joinWith)
import Effect.Aff (Aff, throwError)
import Effect.Aff (Aff)
import Effect.Exception (error)
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as H
import Reactix.DOM.HTML as H
import Gargantext.Prelude
import Gargantext.Config (Ends, BackendRoute(..), NodeType(..), url)
import Gargantext.Config.REST (get)
import Gargantext.Config.REST (get)
import Gargantext.
Components.Node (NodePoly(..), HyperdataList(..)
)
import Gargantext.
Ends (url
)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Pages.Annuaire.User.Contacts.Types
import Gargantext.Pages.Annuaire.User.Contacts.Types
( Contact(..), ContactData, ContactTouch(..), ContactWhere(..)
, ContactWho(..), HyperData(..), HyperdataContact(..) )
import Gargantext.Pages.Annuaire.User.Contacts.Tabs.Specs as Tabs
import Gargantext.Pages.Annuaire.User.Contacts.Tabs.Specs as Tabs
import Gargantext.Utils.Reactix as R2
import Gargantext.Routes (SessionRoute(..))
import Gargantext.Sessions (Session)
import Gargantext.Types (NodeType(..))
display :: String -> Array R.Element -> R.Element
display :: String -> Array R.Element -> R.Element
display title elems =
display title elems =
...
@@ -129,7 +124,7 @@ infoRender (Tuple title content) =
...
@@ -129,7 +124,7 @@ infoRender (Tuple title content) =
[ H.span { className: "badge badge-default badge-pill"} [ H.text title ]
[ H.span { className: "badge badge-default badge-pill"} [ H.text title ]
, H.span {} [H.text content] ]
, H.span {} [H.text content] ]
type LayoutProps = ( nodeId :: Int,
ends :: Ends
)
type LayoutProps = ( nodeId :: Int,
session :: Session
)
userLayout :: Record LayoutProps -> R.Element
userLayout :: Record LayoutProps -> R.Element
userLayout props = R.createElement userLayoutCpt props []
userLayout props = R.createElement userLayoutCpt props []
...
@@ -137,17 +132,17 @@ userLayout props = R.createElement userLayoutCpt props []
...
@@ -137,17 +132,17 @@ userLayout props = R.createElement userLayoutCpt props []
userLayoutCpt :: R.Component LayoutProps
userLayoutCpt :: R.Component LayoutProps
userLayoutCpt = R.hooksComponent "G.P.Annuaire.UserLayout" cpt
userLayoutCpt = R.hooksComponent "G.P.Annuaire.UserLayout" cpt
where
where
cpt {nodeId,
ends
} _ =
cpt {nodeId,
session
} _ =
useLoader nodeId (getContact
ends
) $
useLoader nodeId (getContact
session
) $
\contactData@{contactNode: Contact {name, hyperdata}} ->
\contactData@{contactNode: Contact {name, hyperdata}} ->
H.ul { className: "col-md-12 list-group" }
H.ul { className: "col-md-12 list-group" }
[ display (fromMaybe "no name" name) (contactInfos hyperdata)
[ display (fromMaybe "no name" name) (contactInfos hyperdata)
, Tabs.tabs {nodeId, contactData,
ends
} ]
, Tabs.tabs {nodeId, contactData,
session
} ]
-- | toUrl to get data
-- | toUrl to get data
getContact ::
Ends
-> Int -> Aff ContactData
getContact ::
Session
-> Int -> Aff ContactData
getContact
ends
id = do
getContact
session
id = do
contactNode <- get $ url
ends
(NodeAPI NodeContact (Just id))
contactNode <- get $ url
session
(NodeAPI NodeContact (Just id))
-- TODO: we need a default list for the pairings
-- TODO: we need a default list for the pairings
--defaultListIds <- get $ toUrl endConfigStateful Back (Children NodeList 0 1 Nothing) $ Just id
--defaultListIds <- get $ toUrl endConfigStateful Back (Children NodeList 0 1 Nothing) $ Just id
--case (head defaultListIds :: Maybe (NodePoly HyperdataList)) of
--case (head defaultListIds :: Maybe (NodePoly HyperdataList)) of
...
...
src/Gargantext/Pages/Annuaire/User/Contacts/Tabs.purs
View file @
1105cefb
...
@@ -2,7 +2,6 @@
...
@@ -2,7 +2,6 @@
module Gargantext.Pages.Annuaire.User.Contacts.Tabs.Specs where
module Gargantext.Pages.Annuaire.User.Contacts.Tabs.Specs where
import Prelude hiding (div)
import Prelude hiding (div)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Data.Generic.Rep.Show (genericShow)
import Data.List (fromFoldable)
import Data.List (fromFoldable)
...
@@ -10,11 +9,12 @@ import Data.Maybe (Maybe(..))
...
@@ -10,11 +9,12 @@ import Data.Maybe (Maybe(..))
import Data.Tuple (Tuple(..), fst)
import Data.Tuple (Tuple(..), fst)
import Data.Tuple.Nested ((/\))
import Data.Tuple.Nested ((/\))
import Gargantext.Config (Ends, TabType(..), TabSubType(..), PTabNgramType(..), CTabNgramType(..))
import Gargantext.Components.DocsTable as DT
import Gargantext.Components.DocsTable as DT
import Gargantext.Components.NgramsTable as NT
import Gargantext.Components.NgramsTable as NT
import Gargantext.Components.Tab as Tab
import Gargantext.Components.Tab as Tab
import Gargantext.Pages.Annuaire.User.Contacts.Types (ContactData)
import Gargantext.Pages.Annuaire.User.Contacts.Types (ContactData)
import Gargantext.Sessions (Session)
import Gargantext.Types (TabType(..), TabSubType(..), CTabNgramType(..), PTabNgramType(..))
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix as R
...
@@ -43,7 +43,7 @@ modeTabType' Communication = CTabAuthors
...
@@ -43,7 +43,7 @@ modeTabType' Communication = CTabAuthors
type Props =
type Props =
( nodeId :: Int
( nodeId :: Int
, contactData :: ContactData
, contactData :: ContactData
,
ends :: Ends
)
,
session :: Session
)
tabs :: Record Props -> R.Element
tabs :: Record Props -> R.Element
tabs props = R.createElement tabsCpt props []
tabs props = R.createElement tabsCpt props []
...
@@ -51,7 +51,7 @@ tabs props = R.createElement tabsCpt props []
...
@@ -51,7 +51,7 @@ tabs props = R.createElement tabsCpt props []
tabsCpt :: R.Component Props
tabsCpt :: R.Component Props
tabsCpt = R.hooksComponent "G.P.Annuaire.User.Contacts.Tabs.tabs" cpt
tabsCpt = R.hooksComponent "G.P.Annuaire.User.Contacts.Tabs.tabs" cpt
where
where
cpt {nodeId, contactData: {defaultListId},
ends
} _ = do
cpt {nodeId, contactData: {defaultListId},
session
} _ = do
active <- R.useState' 0
active <- R.useState' 0
pure $
pure $
Tab.tabs { tabs: tabs', selected: fst active }
Tab.tabs { tabs: tabs', selected: fst active }
...
@@ -64,13 +64,13 @@ tabsCpt = R.hooksComponent "G.P.Annuaire.User.Contacts.Tabs.tabs" cpt
...
@@ -64,13 +64,13 @@ tabsCpt = R.hooksComponent "G.P.Annuaire.User.Contacts.Tabs.tabs" cpt
, "Trash" /\ docs -- TODO pass-in trash mode
, "Trash" /\ docs -- TODO pass-in trash mode
]
]
where
where
patentsView = {
ends
, defaultListId, nodeId, mode: Patents}
patentsView = {
session
, defaultListId, nodeId, mode: Patents}
booksView = {
ends
, defaultListId, nodeId, mode: Books}
booksView = {
session
, defaultListId, nodeId, mode: Books}
commView = {
ends
, defaultListId, nodeId, mode: Communication}
commView = {
session
, defaultListId, nodeId, mode: Communication}
chart = mempty
chart = mempty
totalRecords = 4736 -- TODO
totalRecords = 4736 -- TODO
docs = DT.docView
docs = DT.docView
{
ends
, nodeId, chart, totalRecords
{
session
, nodeId, chart, totalRecords
, tabType: TabPairing TabDocs
, tabType: TabPairing TabDocs
, listId: defaultListId
, listId: defaultListId
, corpusId: Nothing
, corpusId: Nothing
...
@@ -78,15 +78,15 @@ tabsCpt = R.hooksComponent "G.P.Annuaire.User.Contacts.Tabs.tabs" cpt
...
@@ -78,15 +78,15 @@ tabsCpt = R.hooksComponent "G.P.Annuaire.User.Contacts.Tabs.tabs" cpt
type NgramsViewProps =
type NgramsViewProps =
(
ends :: Ends
(
session :: Session
, mode :: Mode
, mode :: Mode
, defaultListId :: Int
, defaultListId :: Int
, nodeId :: Int )
, nodeId :: Int )
ngramsView :: Record NgramsViewProps -> R.Element
ngramsView :: Record NgramsViewProps -> R.Element
ngramsView {
ends
,mode, defaultListId, nodeId} =
ngramsView {
session
,mode, defaultListId, nodeId} =
NT.mainNgramsTable
NT.mainNgramsTable
{ nodeId, defaultListId, tabType,
ends
, tabNgramType }
{ nodeId, defaultListId, tabType,
session
, tabNgramType }
where
where
tabNgramType = modeTabType' mode
tabNgramType = modeTabType' mode
tabType = TabPairing $ TabNgramType $ modeTabType mode
tabType = TabPairing $ TabNgramType $ modeTabType mode
src/Gargantext/Pages/Corpus.purs
View file @
1105cefb
...
@@ -2,10 +2,8 @@ module Gargantext.Pages.Corpus where
...
@@ -2,10 +2,8 @@ module Gargantext.Pages.Corpus where
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as H
import Reactix.DOM.HTML as H
import Gargantext.Config (Ends)
import Gargantext.Utils.Reactix as R2
type Props = ( nodeId :: Int
, ends :: Ends
)
type Props = ( nodeId :: Int )
corpusLayout :: Record Props -> R.Element
corpusLayout :: Record Props -> R.Element
corpusLayout props = R.createElement corpusLayoutCpt props []
corpusLayout props = R.createElement corpusLayoutCpt props []
...
@@ -13,7 +11,7 @@ corpusLayout props = R.createElement corpusLayoutCpt props []
...
@@ -13,7 +11,7 @@ corpusLayout props = R.createElement corpusLayoutCpt props []
corpusLayoutCpt :: R.Component Props
corpusLayoutCpt :: R.Component Props
corpusLayoutCpt = R.staticComponent "G.P.Corpus.corpusLayout" cpt
corpusLayoutCpt = R.staticComponent "G.P.Corpus.corpusLayout" cpt
where
where
cpt {nodeId} _
children
=
cpt {nodeId} _ =
H.div {}
H.div {}
[ H.h1 {} [H.text "Corpus Description"]
[ H.h1 {} [H.text "Corpus Description"]
, H.p {} [H.text "Soon: corpus synthesis here (when all others charts/features will be stabilized)."] ]
, H.p {} [H.text "Soon: corpus synthesis here (when all others charts/features will be stabilized)."] ]
src/Gargantext/Pages/Corpus/Chart/Histo.purs
View file @
1105cefb
module Gargantext.Pages.Corpus.Chart.Histo where
module Gargantext.Pages.Corpus.Chart.Histo where
import Prelude (bind, map, pure, ($))
import Data.Argonaut (class DecodeJson, decodeJson, (.:))
import Data.Argonaut (class DecodeJson, decodeJson, (.:))
import Data.Maybe (Maybe(..))
import Data.Maybe (Maybe(..))
import Effect.Aff (Aff)
import Effect.Aff (Aff)
import Gargantext.Config
import Gargantext.Config.REST (get)
import Gargantext.Config.REST (get)
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as H
import Gargantext.Prelude
import Gargantext.Components.Charts.Options.ECharts (Options(..), chart, xAxis', yAxis')
import Gargantext.Types (TermList(..))
import Gargantext.Components.Charts.Options.Series (seriesBarD1)
import Gargantext.Components.Loader as Loader
import Gargantext.Components.Charts.Options.Color (grey)
import Gargantext.Components.Charts.Options.ECharts
import Gargantext.Components.Charts.Options.Font (itemStyle, mkTooltip, templateFormatter)
import Gargantext.Components.Charts.Options.Series
import Gargantext.Components.Charts.Options.Data (dataSerie)
import Gargantext.Components.Charts.Options.Color
import Gargantext.Ends (url)
import Gargantext.Components.Charts.Options.Font
import Gargantext.Components.Charts.Options.Data
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Utils.Reactix as R2
import Gargantext.Pages.Corpus.Chart.Utils as U
import Gargantext.Pages.Corpus.Chart.Utils as U
import Gargantext.Routes (SessionRoute(..))
import Gargantext.Sessions (Session)
import Gargantext.Types (ChartType(..), TabType)
type Path = { corpusId :: Int, tabType :: TabType }
type Path = { corpusId :: Int, tabType :: TabType }
type Props = ( path :: Path,
ends :: Ends
)
type Props = ( path :: Path,
session :: Session
)
newtype ChartMetrics = ChartMetrics { "data" :: HistoMetrics }
newtype ChartMetrics = ChartMetrics { "data" :: HistoMetrics }
...
@@ -49,14 +48,14 @@ chartOptions (HistoMetrics { dates: dates', count: count'}) = Options
...
@@ -49,14 +48,14 @@ chartOptions (HistoMetrics { dates: dates', count: count'}) = Options
, subTitle : "Distribution of publications over time"
, subTitle : "Distribution of publications over time"
, xAxis : xAxis' dates'
, xAxis : xAxis' dates'
, yAxis : yAxis' { position: "left", show: true, min:0}
, yAxis : yAxis' { position: "left", show: true, min:0}
, series : [seriesBarD1 {name: "Number of publication / year"} $ map (\n -> dataSerie {value: n, itemStyle : itemStyle {color:grey}}) count']
, addZoom : true
, addZoom : true
, tooltip : mkTooltip { formatter: templateFormatter "{b0}" }
, tooltip : mkTooltip { formatter: templateFormatter "{b0}" }
}
, series : [seriesBarD1 {name: "Number of publication / year"} $
map (\n -> dataSerie {value: n, itemStyle : itemStyle {color:grey}}) count'] }
getMetrics ::
Ends
-> Path -> Aff HistoMetrics
getMetrics ::
Session
-> Path -> Aff HistoMetrics
getMetrics
ends
{corpusId, tabType} = do
getMetrics
session
{corpusId, tabType} = do
ChartMetrics ms <- get $ url
ends
chart
ChartMetrics ms <- get $ url
session
chart
pure ms."data"
pure ms."data"
where chart = Chart {chartType: Histo, tabType: tabType} (Just corpusId)
where chart = Chart {chartType: Histo, tabType: tabType} (Just corpusId)
...
@@ -66,16 +65,16 @@ histo props = R.createElement histoCpt props []
...
@@ -66,16 +65,16 @@ histo props = R.createElement histoCpt props []
histoCpt :: R.Component Props
histoCpt :: R.Component Props
histoCpt = R.hooksComponent "LoadedMetricsHisto" cpt
histoCpt = R.hooksComponent "LoadedMetricsHisto" cpt
where
where
cpt {
ends
,path} _ = do
cpt {
session
,path} _ = do
setReload <- R.useState' 0
setReload <- R.useState' 0
pure $ metricsLoadView
ends
setReload path
pure $ metricsLoadView
session
setReload path
metricsLoadView ::
Ends
-> R.State Int -> Path -> R.Element
metricsLoadView ::
Session
-> R.State Int -> Path -> R.Element
metricsLoadView
ends setReload path = R.createElement el {ends,path
} []
metricsLoadView
s setReload p = R.createElement el {session: s, path: p
} []
where
where
el = R.hooksComponent "MetricsLoadedHistoView" cpt
el = R.hooksComponent "MetricsLoadedHistoView" cpt
cpt {path,
ends
} _ = do
cpt {path,
session
} _ = do
useLoader path (getMetrics
ends
) $ \loaded ->
useLoader path (getMetrics
session
) $ \loaded ->
loadedMetricsView setReload loaded
loadedMetricsView setReload loaded
loadedMetricsView :: R.State Int -> HistoMetrics -> R.Element
loadedMetricsView :: R.State Int -> HistoMetrics -> R.Element
...
...
src/Gargantext/Pages/Corpus/Chart/Metrics.purs
View file @
1105cefb
module Gargantext.Pages.Corpus.Chart.Metrics where
module Gargantext.Pages.Corpus.Chart.Metrics where
import Prelude (bind, negate, pure, ($), (<$>), (<>))
import Data.Argonaut (class DecodeJson, decodeJson, (.:))
import Data.Argonaut (class DecodeJson, decodeJson, (.:))
import Data.Map as Map
import Data.Map as Map
import Data.Map (Map)
import Data.Map (Map)
import Data.Maybe (Maybe(..))
import Data.Maybe (Maybe(..))
import Data.Tuple (Tuple(..))
import Data.Tuple (Tuple(..))
import Effect.Aff (Aff)
import Effect.Aff (Aff)
import Gargantext.Config (Ends, BackendRoute(..), TabType, url)
import Gargantext.Config.REST (get)
import Gargantext.Config.REST (get)
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as H
import Gargantext.Components.Charts.Options.ECharts (Options(..), chart, yAxis')
import Gargantext.Prelude
import Gargantext.Components.Charts.Options.Type (xAxis)
import Gargantext.Types (TermList(..))
import Gargantext.Components.Charts.Options.Series (Series, seriesScatterD2)
import Gargantext.Components.Loader as Loader
import Gargantext.Components.Charts.Options.Color (green, grey, red)
import Gargantext.Components.Charts.Options.ECharts
import Gargantext.Components.Charts.Options.Font (itemStyle, mkTooltip, templateFormatter)
import Gargantext.Components.Charts.Options.Type
import Gargantext.Components.Charts.Options.Data (dataSerie)
import Gargantext.Components.Charts.Options.Series
import Gargantext.Ends (url)
import Gargantext.Components.Charts.Options.Color
import Gargantext.Components.Charts.Options.Font
import Gargantext.Components.Charts.Options.Data
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Utils.Reactix as R2
import Gargantext.Pages.Corpus.Chart.Utils as U
import Gargantext.Pages.Corpus.Chart.Utils as U
import Gargantext.Routes (SessionRoute(..))
import Gargantext.Sessions (Session)
import Gargantext.Types (TabType, TermList(..))
type Path =
type Path =
{ corpusId :: Int
{ corpusId :: Int
...
@@ -31,7 +30,7 @@ type Path =
...
@@ -31,7 +30,7 @@ type Path =
, limit :: Maybe Int
, limit :: Maybe Int
}
}
type Props = ( path :: Path,
ends :: Ends
)
type Props = ( path :: Path,
session :: Session
)
newtype Metric = Metric
newtype Metric = Metric
{ label :: String
{ label :: String
...
@@ -62,12 +61,12 @@ instance decodeMetrics :: DecodeJson Metrics where
...
@@ -62,12 +61,12 @@ instance decodeMetrics :: DecodeJson Metrics where
type Loaded = Array Metric
type Loaded = Array Metric
scatterOptions :: Array Metric -> Options
scatterOptions :: Array Metric -> Options
scatterOptions metrics = Options
scatterOptions metrics
'
= Options
{ mainTitle : "Ngrams Selection Metrics"
{ mainTitle : "Ngrams Selection Metrics"
, subTitle : "Local metrics (Inc/Exc, Spe/Gen), Global metrics (TFICF maillage)"
, subTitle : "Local metrics (Inc/Exc, Spe/Gen), Global metrics (TFICF maillage)"
, xAxis : xAxis { min: -1 }
, xAxis : xAxis { min: -1 }
, yAxis : yAxis' { position : "", show: true, min : -2}
, yAxis : yAxis' { position : "", show: true, min : -2}
, series : map2series $ metric2map metrics
, series : map2series $ metric2map metrics
'
, addZoom : false
, addZoom : false
, tooltip : mkTooltip { formatter: templateFormatter "{b0}" }
, tooltip : mkTooltip { formatter: templateFormatter "{b0}" }
}
}
...
@@ -95,11 +94,11 @@ scatterOptions metrics = Options
...
@@ -95,11 +94,11 @@ scatterOptions metrics = Options
}
}
--}
--}
getMetrics ::
Ends
-> Path -> Aff Loaded
getMetrics ::
Session
-> Path -> Aff Loaded
getMetrics
ends
{corpusId, listId, limit, tabType} = do
getMetrics
session
{corpusId, listId, limit, tabType} = do
Metrics ms <- get $ url
ends metrics
Metrics ms <- get $ url
session metrics'
pure ms."data"
pure ms."data"
where metrics = CorpusMetrics {listId, tabType, limit} (Just corpusId)
where metrics
'
= CorpusMetrics {listId, tabType, limit} (Just corpusId)
metrics :: Record Props -> R.Element
metrics :: Record Props -> R.Element
metrics props = R.createElement metricsCpt props []
metrics props = R.createElement metricsCpt props []
...
@@ -107,16 +106,16 @@ metrics props = R.createElement metricsCpt props []
...
@@ -107,16 +106,16 @@ metrics props = R.createElement metricsCpt props []
metricsCpt :: R.Component Props
metricsCpt :: R.Component Props
metricsCpt = R.hooksComponent "LoadedMetrics" cpt
metricsCpt = R.hooksComponent "LoadedMetrics" cpt
where
where
cpt {path,
ends
} _ = do
cpt {path,
session
} _ = do
setReload <- R.useState' 0
setReload <- R.useState' 0
pure $ metricsLoadView
ends
setReload path
pure $ metricsLoadView
session
setReload path
metricsLoadView ::
Ends
-> R.State Int -> Path -> R.Element
metricsLoadView ::
Session
-> R.State Int -> Path -> R.Element
metricsLoadView
ends setReload path = R.createElement el {ends,path
} []
metricsLoadView
s setReload p = R.createElement el {session: s, path: p
} []
where
where
el = R.hooksComponent "MetricsLoadedView" cpt
el = R.hooksComponent "MetricsLoadedView" cpt
cpt {
ends
, path} _ = do
cpt {
session
, path} _ = do
useLoader path (getMetrics
ends
) $ \loaded ->
useLoader path (getMetrics
session
) $ \loaded ->
loadedMetricsView setReload loaded
loadedMetricsView setReload loaded
loadedMetricsView :: R.State Int -> Loaded -> R.Element
loadedMetricsView :: R.State Int -> Loaded -> R.Element
...
...
src/Gargantext/Pages/Corpus/Chart/Pie.purs
View file @
1105cefb
module Gargantext.Pages.Corpus.Chart.Pie where
module Gargantext.Pages.Corpus.Chart.Pie where
import Prelude (bind, map, pure, ($), (>))
import Data.Argonaut (class DecodeJson, decodeJson, (.:))
import Data.Argonaut (class DecodeJson, decodeJson, (.:))
import Data.Array (zip, filter)
import Data.Array (zip, filter)
import Data.Array as A
import Data.Array as A
...
@@ -7,28 +8,27 @@ import Data.Maybe (Maybe(..))
...
@@ -7,28 +8,27 @@ import Data.Maybe (Maybe(..))
import Data.String (take, joinWith, Pattern(..), split, length)
import Data.String (take, joinWith, Pattern(..), split, length)
import Data.Tuple (Tuple(..))
import Data.Tuple (Tuple(..))
import Effect.Aff (Aff)
import Effect.Aff (Aff)
import Gargantext.Config (Ends, BackendRoute(..), TabType, ChartType(..), url)
import Gargantext.Config.REST (get)
import Gargantext.Config.REST (get)
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as H
import Gargantext.Prelude
import Gargantext.Components.Charts.Options.ECharts (Options(..), chart, xAxis', yAxis')
import Gargantext.Types (TermList(..))
import Gargantext.Components.Charts.Options.ECharts
import Gargantext.Components.Charts.Options.Series (seriesBarD1, seriesPieD1)
import Gargantext.Components.Charts.Options.Series (seriesBarD1, seriesPieD1)
import Gargantext.Components.Charts.Options.Color (blue)
import Gargantext.Components.Charts.Options.Color (blue)
import Gargantext.Components.Charts.Options.Font
import Gargantext.Components.Charts.Options.Font (itemStyle, mkTooltip, templateFormatter)
import Gargantext.Components.Charts.Options.Data
import Gargantext.Components.Charts.Options.Data (dataSerie)
import Gargantext.Ends (url)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Utils.Reactix as R2
import Gargantext.Pages.Corpus.Chart.Utils as U
import Gargantext.Pages.Corpus.Chart.Utils as U
import Gargantext.Routes (SessionRoute(..))
import Gargantext.Sessions (Session)
import Gargantext.Types (ChartType(..), TabType)
type Path =
type Path =
{ corpusId :: Int
{ corpusId :: Int
, tabType :: TabType
, tabType :: TabType
}
}
type Props = (
ends :: Ends
, path :: Path )
type Props = (
session :: Session
, path :: Path )
newtype ChartMetrics = ChartMetrics
newtype ChartMetrics = ChartMetrics
{ "data" :: HistoMetrics
{ "data" :: HistoMetrics
...
@@ -78,9 +78,9 @@ chartOptionsPie (HistoMetrics { dates: dates', count: count'}) = Options
...
@@ -78,9 +78,9 @@ chartOptionsPie (HistoMetrics { dates: dates', count: count'}) = Options
}
}
getMetrics ::
Ends
-> Path -> Aff HistoMetrics
getMetrics ::
Session
-> Path -> Aff HistoMetrics
getMetrics
ends
{corpusId, tabType:tabType} = do
getMetrics
session
{corpusId, tabType:tabType} = do
ChartMetrics ms <- get $ url
ends
chart
ChartMetrics ms <- get $ url
session
chart
pure ms."data"
pure ms."data"
where chart = Chart {chartType: ChartPie, tabType: tabType} (Just corpusId)
where chart = Chart {chartType: ChartPie, tabType: tabType} (Just corpusId)
...
@@ -90,16 +90,16 @@ pie props = R.createElement pieCpt props []
...
@@ -90,16 +90,16 @@ pie props = R.createElement pieCpt props []
pieCpt :: R.Component Props
pieCpt :: R.Component Props
pieCpt = R.hooksComponent "LoadedMetricsPie" cpt
pieCpt = R.hooksComponent "LoadedMetricsPie" cpt
where
where
cpt {path,
ends
} _ = do
cpt {path,
session
} _ = do
setReload <- R.useState' 0
setReload <- R.useState' 0
pure $ metricsLoadPieView
ends
setReload path
pure $ metricsLoadPieView
session
setReload path
metricsLoadPieView ::
Ends
-> R.State Int -> Path -> R.Element
metricsLoadPieView ::
Session
-> R.State Int -> Path -> R.Element
metricsLoadPieView
ends setReload path = R.createElement el {ends,path
} []
metricsLoadPieView
s setReload p = R.createElement el {session: s,path: p
} []
where
where
el = R.hooksComponent "MetricsLoadedPieView" cpt
el = R.hooksComponent "MetricsLoadedPieView" cpt
cpt {
ends
,path} _ = do
cpt {
session
,path} _ = do
useLoader path (getMetrics
ends
) $ \loaded ->
useLoader path (getMetrics
session
) $ \loaded ->
loadedMetricsPieView setReload loaded
loadedMetricsPieView setReload loaded
loadedMetricsPieView :: R.State Int -> HistoMetrics -> R.Element
loadedMetricsPieView :: R.State Int -> HistoMetrics -> R.Element
...
@@ -112,17 +112,17 @@ bar props = R.createElement barCpt props []
...
@@ -112,17 +112,17 @@ bar props = R.createElement barCpt props []
barCpt :: R.Component Props
barCpt :: R.Component Props
barCpt = R.hooksComponent "LoadedMetricsBar" cpt
barCpt = R.hooksComponent "LoadedMetricsBar" cpt
where
where
cpt {path,
ends
} _ = do
cpt {path,
session
} _ = do
setReload <- R.useState' 0
setReload <- R.useState' 0
pure $ metricsLoadBarView
ends
setReload path
pure $ metricsLoadBarView
session
setReload path
metricsLoadBarView ::
Ends
-> R.State Int -> Path -> R.Element
metricsLoadBarView ::
Session
-> R.State Int -> Path -> R.Element
metricsLoadBarView
ends setReload path = R.createElement el {ends,path
} []
metricsLoadBarView
s setReload p = R.createElement el {path: p, session: s
} []
where
where
el = R.hooksComponent "MetricsLoadedBarView" cpt
el = R.hooksComponent "MetricsLoadedBarView" cpt
cpt {path,
ends
} _ = do
cpt {path,
session
} _ = do
useLoader path (getMetrics
ends
) $ \loaded ->
useLoader path (getMetrics
session
) $ \loaded ->
loadedMetricsBarView setReload loaded
loadedMetricsBarView setReload loaded
loadedMetricsBarView :: R.State Int -> Loaded -> R.Element
loadedMetricsBarView :: R.State Int -> Loaded -> R.Element
...
...
src/Gargantext/Pages/Corpus/Chart/Tree.purs
View file @
1105cefb
module Gargantext.Pages.Corpus.Chart.Tree where
module Gargantext.Pages.Corpus.Chart.Tree where
import Prelude (bind, pure, ($))
import Data.Argonaut (class DecodeJson, decodeJson, (.:))
import Data.Argonaut (class DecodeJson, decodeJson, (.:))
import Data.Maybe (Maybe(..))
import Data.Maybe (Maybe(..))
import Effect.Aff (Aff)
import Effect.Aff (Aff)
import Gargantext.Config (Ends, BackendRoute(..), TabType, ChartType(..), url)
import Gargantext.Config.REST (get)
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as H
import Reactix.DOM.HTML as H
import Gargantext.Prelude
import Gargantext.Config.REST (get)
import Gargantext.Types (TermList(..))
import Gargantext.Components.Charts.Options.ECharts (Options(..), chart, xAxis', yAxis')
import Gargantext.Components.Charts.Options.ECharts
import Gargantext.Components.Charts.Options.Series (TreeNode, Trees(..), mkTree)
import Gargantext.Components.Charts.Options.Series
import Gargantext.Components.Charts.Options.Font (mkTooltip, templateFormatter)
import Gargantext.Components.Charts.Options.Font
import Gargantext.Ends (url)
import Gargantext.Components.Charts.Options.Data
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Utils.Reactix as R2
import Gargantext.Pages.Corpus.Chart.Utils as U
import Gargantext.Pages.Corpus.Chart.Utils as U
import Gargantext.Routes (SessionRoute(..))
import Gargantext.Sessions (Session)
import Gargantext.Types (ChartType(..), TabType)
type Path =
type Path =
{ corpusId :: Int
{ corpusId :: Int
...
@@ -25,7 +24,7 @@ type Path =
...
@@ -25,7 +24,7 @@ type Path =
, tabType :: TabType
, tabType :: TabType
, limit :: Maybe Int
, limit :: Maybe Int
}
}
type Props = ( path :: Path,
ends :: Ends
)
type Props = ( path :: Path,
session :: Session
)
newtype Metrics = Metrics
newtype Metrics = Metrics
{ "data" :: Array TreeNode
{ "data" :: Array TreeNode
...
@@ -53,9 +52,9 @@ scatterOptions nodes = Options
...
@@ -53,9 +52,9 @@ scatterOptions nodes = Options
}
}
getMetrics ::
Ends
-> Path -> Aff Loaded
getMetrics ::
Session
-> Path -> Aff Loaded
getMetrics
ends
{corpusId, listId, limit, tabType} = do
getMetrics
session
{corpusId, listId, limit, tabType} = do
Metrics ms <- get $ url
ends
chart
Metrics ms <- get $ url
session
chart
pure ms."data"
pure ms."data"
where
where
chart = Chart {chartType : ChartTree, tabType: tabType} (Just corpusId)
chart = Chart {chartType : ChartTree, tabType: tabType} (Just corpusId)
...
@@ -66,16 +65,16 @@ tree props = R.createElement treeCpt props []
...
@@ -66,16 +65,16 @@ tree props = R.createElement treeCpt props []
treeCpt :: R.Component Props
treeCpt :: R.Component Props
treeCpt = R.hooksComponent "LoadedMetrics" cpt
treeCpt = R.hooksComponent "LoadedMetrics" cpt
where
where
cpt {path,
ends
} _ = do
cpt {path,
session
} _ = do
setReload <- R.useState' 0
setReload <- R.useState' 0
pure $ metricsLoadView
ends
setReload path
pure $ metricsLoadView
session
setReload path
metricsLoadView ::
Ends
-> R.State Int -> Path -> R.Element
metricsLoadView ::
Session
-> R.State Int -> Path -> R.Element
metricsLoadView
ends setReload p = R.createElement el p
[]
metricsLoadView
session setReload path = R.createElement el path
[]
where
where
el = R.hooksComponent "MetricsLoadView" cpt
el = R.hooksComponent "MetricsLoadView" cpt
cpt p _ = do
cpt p _ = do
useLoader p (getMetrics
ends
) $ \loaded ->
useLoader p (getMetrics
session
) $ \loaded ->
loadedMetricsView setReload loaded
loadedMetricsView setReload loaded
loadedMetricsView :: R.State Int -> Loaded -> R.Element
loadedMetricsView :: R.State Int -> Loaded -> R.Element
...
...
src/Gargantext/Pages/Corpus/Dashboard.purs
View file @
1105cefb
module Gargantext.Pages.Corpus.Dashboard where
module Gargantext.Pages.Corpus.Dashboard where
import Prelude hiding (div)
import Prelude (map, show, ($), (<$>), (<>))
import Data.Array (zipWith)
import Data.Array (zipWith)
import Data.Int (toNumber)
import Data.Tuple (Tuple(..))
import Data.Tuple (Tuple(..))
import Reactix as R
import Reactix.DOM.HTML as H
import Gargantext.Components.Charts.Options.ECharts (Options(..), chart, xAxis', yAxis', tooltipTriggerAxis)
import Gargantext.Components.Charts.Options.ECharts (Options(..), chart, xAxis', yAxis', tooltipTriggerAxis)
import Gargantext.Components.Charts.Options.Data
import Gargantext.Components.Charts.Options.Data
import Gargantext.Components.Charts.Options.Series
import Gargantext.Components.Charts.Options.Series
import Data.Int (toNumber)
( TreeNode, Trees(..), mkTree, seriesBarD1, seriesFunnelD1, seriesPieD1
import React.DOM.Props (className)
, seriesSankey, seriesScatterD2, treeLeaf, treeNode )
import Reactix as R
import Reactix.DOM.HTML as H
import Thermite (Render, Spec, simpleSpec, defaultPerformAction)
dashboardLayout :: {} -> R.Element
dashboardLayout :: {} -> R.Element
dashboardLayout props = R.createElement dashboardLayoutCpt props []
dashboardLayout props = R.createElement dashboardLayoutCpt props []
...
...
src/Gargantext/Pages/Corpus/Document.purs
View file @
1105cefb
module Gargantext.Pages.Corpus.Document where
module Gargantext.Pages.Corpus.Document where
import Prelude (class Show, bind, identity, mempty, pure, ($), (<<<))
import Data.Argonaut (class DecodeJson, decodeJson, (.:), (.:!))
import Data.Argonaut (class DecodeJson, decodeJson, (.:), (.:!))
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Data.Generic.Rep.Show (genericShow)
...
@@ -11,16 +12,19 @@ import React.DOM.Props (className)
...
@@ -11,16 +12,19 @@ import React.DOM.Props (className)
import Reactix as R
import Reactix as R
import Thermite (PerformAction, Render, Spec, simpleSpec, createClass)
import Thermite (PerformAction, Render, Spec, simpleSpec, createClass)
import Gargantext.Prelude
import Gargantext.Config
( NodeType(..), Ends, TabSubType(..), TabType(..), CTabNgramType(..), BackendRoute(..), url )
import Gargantext.Config.REST (get)
import Gargantext.Config.REST (get)
import Gargantext.Components.AutoUpdate (autoUpdateElt)
import Gargantext.Components.AutoUpdate (autoUpdateElt)
import Gargantext.Components.Node (NodePoly(..))
import Gargantext.Components.Node (NodePoly(..))
import Gargantext.Components.NgramsTable.Core
import Gargantext.Components.NgramsTable.Core
( CoreState, NgramsPatch(..), NgramsTerm, Replace, Versioned(..)
, VersionedNgramsTable, addNewNgram, applyNgramsTablePatch, commitPatch
, loadNgramsTable, replace, singletonNgramsTablePatch )
import Gargantext.Components.Annotation.AnnotatedField as AnnotatedField
import Gargantext.Components.Annotation.AnnotatedField as AnnotatedField
import Gargantext.Ends (url)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Types (TermList)
import Gargantext.Routes (SessionRoute(..))
import Gargantext.Sessions (Session)
import Gargantext.Types (CTabNgramType(..), NodeType(..), TabSubType(..), TabType(..), TermList)
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Reactix as R2
type DocPath = { nodeId :: Int, listIds :: Array Int, corpusId :: Maybe Int, tabType :: TabType }
type DocPath = { nodeId :: Int, listIds :: Array Int, corpusId :: Maybe Int, tabType :: TabType }
...
@@ -35,7 +39,7 @@ type LoadedData =
...
@@ -35,7 +39,7 @@ type LoadedData =
type Props =
type Props =
{ loaded :: LoadedData
{ loaded :: LoadedData
, path :: DocPath
, path :: DocPath
,
ends :: Ends
,
session :: Session
}
}
-- This is a subpart of NgramsTable.State.
-- This is a subpart of NgramsTable.State.
...
@@ -283,15 +287,15 @@ docViewSpec :: Spec State Props Action
...
@@ -283,15 +287,15 @@ docViewSpec :: Spec State Props Action
docViewSpec = simpleSpec performAction render
docViewSpec = simpleSpec performAction render
where
where
performAction :: PerformAction State Props Action
performAction :: PerformAction State Props Action
performAction Refresh {path: {nodeId, listIds, tabType},
ends
} {ngramsVersion} = do
performAction Refresh {path: {nodeId, listIds, tabType},
session
} {ngramsVersion} = do
commitPatch
ends
{nodeId, listIds, tabType} (Versioned {version: ngramsVersion, data: mempty})
commitPatch
session
{nodeId, listIds, tabType} (Versioned {version: ngramsVersion, data: mempty})
performAction (SetTermListItem n pl) {path: {nodeId, listIds, tabType},
ends
} {ngramsVersion} =
performAction (SetTermListItem n pl) {path: {nodeId, listIds, tabType},
session
} {ngramsVersion} =
commitPatch
ends
{nodeId, listIds, tabType} (Versioned {version: ngramsVersion, data: pt})
commitPatch
session
{nodeId, listIds, tabType} (Versioned {version: ngramsVersion, data: pt})
where
where
pe = NgramsPatch { patch_list: pl, patch_children: mempty }
pe = NgramsPatch { patch_list: pl, patch_children: mempty }
pt = singletonNgramsTablePatch CTabTerms n pe
pt = singletonNgramsTablePatch CTabTerms n pe
performAction (AddNewNgram ngram termList) {path: {nodeId, listIds, tabType},
ends
} {ngramsVersion} =
performAction (AddNewNgram ngram termList) {path: {nodeId, listIds, tabType},
session
} {ngramsVersion} =
commitPatch
ends
{nodeId, listIds, tabType} (Versioned {version: ngramsVersion, data: pt})
commitPatch
session
{nodeId, listIds, tabType} (Versioned {version: ngramsVersion, data: pt})
where
where
pt = addNewNgram CTabTerms ngram termList
pt = addNewNgram CTabTerms ngram termList
...
@@ -341,13 +345,13 @@ docViewSpec = simpleSpec performAction render
...
@@ -341,13 +345,13 @@ docViewSpec = simpleSpec performAction render
docViewClass
docViewClass
:: ReactClass
:: ReactClass
{
ends :: Ends
{
session :: Session
, children :: Children
, children :: Children
, loaded :: LoadedData
, loaded :: LoadedData
, path :: DocPath }
, path :: DocPath }
docViewClass = createClass "DocumentView" docViewSpec initialState
docViewClass = createClass "DocumentView" docViewSpec initialState
type LayoutProps = (
ends :: Ends
, nodeId :: Int, listId :: Int, corpusId :: Maybe Int )
type LayoutProps = (
session :: Session
, nodeId :: Int, listId :: Int, corpusId :: Maybe Int )
documentLayout :: Record LayoutProps -> R.Element
documentLayout :: Record LayoutProps -> R.Element
documentLayout props = R.createElement documentLayoutCpt props []
documentLayout props = R.createElement documentLayoutCpt props []
...
@@ -355,23 +359,23 @@ documentLayout props = R.createElement documentLayoutCpt props []
...
@@ -355,23 +359,23 @@ documentLayout props = R.createElement documentLayoutCpt props []
documentLayoutCpt :: R.Component LayoutProps
documentLayoutCpt :: R.Component LayoutProps
documentLayoutCpt = R.hooksComponent "G.P.Corpus.Document.documentLayout" cpt
documentLayoutCpt = R.hooksComponent "G.P.Corpus.Document.documentLayout" cpt
where
where
cpt {
ends
, nodeId, listId, corpusId} _ = do
cpt {
session
, nodeId, listId, corpusId} _ = do
useLoader path (loadData
ends
) $ \loaded ->
useLoader path (loadData
session
) $ \loaded ->
R2.createElement' docViewClass {
ends
, path, loaded} []
R2.createElement' docViewClass {
session
, path, loaded} []
where
where
tabType = TabDocument (TabNgramType CTabTerms)
tabType = TabDocument (TabNgramType CTabTerms)
path = {nodeId, listIds: [listId], corpusId, tabType}
path = {nodeId, listIds: [listId], corpusId, tabType}
------------------------------------------------------------------------
------------------------------------------------------------------------
loadDocument ::
Ends
-> Int -> Aff NodeDocument
loadDocument ::
Session
-> Int -> Aff NodeDocument
loadDocument
ends = get <<< url ends
<<< NodeAPI Node <<< Just
loadDocument
session = get <<< url session
<<< NodeAPI Node <<< Just
loadData ::
Ends
-> DocPath -> Aff LoadedData
loadData ::
Session
-> DocPath -> Aff LoadedData
loadData
ends
{nodeId, listIds, tabType} = do
loadData
session
{nodeId, listIds, tabType} = do
document <- loadDocument
ends
nodeId
document <- loadDocument
session
nodeId
ngramsTable <- loadNgramsTable
ends
ngramsTable <- loadNgramsTable
session
{
ends
{
session
, nodeId
, nodeId
, listIds: listIds
, listIds: listIds
, params: { offset : 0, limit : 100, orderBy: Nothing}
, params: { offset : 0, limit : 100, orderBy: Nothing}
...
...
src/Gargantext/Pages/Corpus/Graph/Tabs.purs
View file @
1105cefb
...
@@ -3,15 +3,14 @@ module Gargantext.Pages.Corpus.Graph.Tabs where
...
@@ -3,15 +3,14 @@ module Gargantext.Pages.Corpus.Graph.Tabs where
import Prelude hiding (div)
import Prelude hiding (div)
import Data.Array (fromFoldable)
import Data.Array (fromFoldable)
import Data.Tuple (Tuple(..), fst)
import Data.Tuple (Tuple(..), fst)
import
Gargantext.Config (Ends)
import
Reactix as R
import Gargantext.Components.GraphExplorer.Types (GraphSideCorpus(..))
import Gargantext.Components.GraphExplorer.Types (GraphSideCorpus(..))
import Gargantext.Components.FacetsTable (TextQuery, docView)
import Gargantext.Components.FacetsTable (TextQuery, docView)
import Gargantext.Components.Table as T
import Gargantext.Components.Table as T
import Gargantext.Components.Tab as Tab
import Gargantext.Components.Tab as Tab
import Reactix as R
import Gargantext.Sessions (Session)
import Reactix.DOM.HTML as H
type Props = (
ends :: Ends
, query :: TextQuery, sides :: Array GraphSideCorpus )
type Props = (
session :: Session
, query :: TextQuery, sides :: Array GraphSideCorpus )
tabs :: Record Props -> R.Element
tabs :: Record Props -> R.Element
tabs props = R.createElement tabsCpt props []
tabs props = R.createElement tabsCpt props []
...
@@ -20,17 +19,17 @@ tabs props = R.createElement tabsCpt props []
...
@@ -20,17 +19,17 @@ tabs props = R.createElement tabsCpt props []
tabsCpt :: R.Component Props
tabsCpt :: R.Component Props
tabsCpt = R.hooksComponent "G.P.Corpus.Graph.Tabs.tabs" cpt
tabsCpt = R.hooksComponent "G.P.Corpus.Graph.Tabs.tabs" cpt
where
where
cpt {
ends
, query, sides} _ = do
cpt {
session
, query, sides} _ = do
active <- R.useState' 0
active <- R.useState' 0
pure $ Tab.tabs {tabs: tabs', selected: fst active}
pure $ Tab.tabs {tabs: tabs', selected: fst active}
where
where
tabs' = fromFoldable $ tab
ends
query <$> sides
tabs' = fromFoldable $ tab
session
query <$> sides
tab ::
Ends
-> TextQuery -> GraphSideCorpus -> Tuple String R.Element
tab ::
Session
-> TextQuery -> GraphSideCorpus -> Tuple String R.Element
tab
ends
query (GraphSideCorpus {corpusId: nodeId, corpusLabel, listId}) =
tab
session
query (GraphSideCorpus {corpusId: nodeId, corpusLabel, listId}) =
Tuple corpusLabel (docView dvProps)
Tuple corpusLabel (docView dvProps)
where
where
dvProps = {
ends
, nodeId, listId, query, chart, totalRecords: 4736, container}
dvProps = {
session
, nodeId, listId, query, chart, totalRecords: 4736, container}
-- TODO totalRecords: probably need to insert a corpusLoader.
-- TODO totalRecords: probably need to insert a corpusLoader.
chart = mempty
chart = mempty
container = T.graphContainer {title: corpusLabel}
container = T.graphContainer {title: corpusLabel}
...
...
src/Gargantext/Pages/Home.purs
View file @
1105cefb
module Gargantext.Pages.Home where
module Gargantext.Pages.Home where
import Prelude
import Prelude
import Data.Lens (re)
import Data.Newtype (class Newtype)
import Data.Lens.Iso.Newtype (_Newtype)
import Data.Newtype (class Newtype, unwrap)
import Effect (Effect)
import Effect (Effect)
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as H
import Reactix.DOM.HTML as H
...
@@ -12,7 +10,6 @@ import Gargantext.Components.Lang.Landing.EnUS as En
...
@@ -12,7 +10,6 @@ import Gargantext.Components.Lang.Landing.EnUS as En
import Gargantext.Components.Lang.Landing.FrFR as Fr
import Gargantext.Components.Lang.Landing.FrFR as Fr
import Gargantext.Components.Data.Landing (BlockText(..), BlockTexts(..), Button(..), LandingData(..))
import Gargantext.Components.Data.Landing (BlockText(..), BlockTexts(..), Button(..), LandingData(..))
import Gargantext.Components.Data.Lang (Lang(..))
import Gargantext.Components.Data.Lang (Lang(..))
import Gargantext.Utils.Reactix as R2
type Props = ()
type Props = ()
...
@@ -38,28 +35,24 @@ performAction Enter = void $ setHash "/search"
...
@@ -38,28 +35,24 @@ performAction Enter = void $ setHash "/search"
performAction Login = void $ setHash "/login"
performAction Login = void $ setHash "/login"
performAction SignUp = pure unit
performAction SignUp = pure unit
-- Layout |
langLandingData :: Lang -> LandingData
langLandingData FR = Fr.landingData
landingData :: Lang -> LandingData
langLandingData EN = En.landingData
landingData FR = Fr.landingData
landingData EN = En.landingData
------------------------------------------------------------------------
------------------------------------------------------------------------
layoutLanding
:: Lang -> R.Element
homeLayout
:: Lang -> R.Element
layoutLanding lang = R.createElement layoutLandingCpt props
[]
homeLayout lang = R.createElement homeLayoutCpt {landingData}
[]
where
props = { landingData: landingData lang }
where
landingData = langLandingData lang
layoutLanding
Cpt :: R.Component ( landingData :: LandingData )
homeLayout
Cpt :: R.Component ( landingData :: LandingData )
layoutLandingCpt = R.hooks
Component "LayoutLanding" cpt
homeLayoutCpt = R.static
Component "LayoutLanding" cpt
where
where
cpt {landingData} _ = do
cpt {landingData} _ =
pure $ H.span {} [
H.span {}
H.div { className: "container1" }
[ H.div { className: "container1" } [ jumboTitle landingData false ]
[ jumboTitle landingData false ]
, H.div { className: "container1" } [] -- TODO put research form
, H.div { className: "container1" } [] -- TODO put research form
, H.div { className: "container1" } [ blocksRandomText' landingData ] ]
, H.div { className: "container1" } [ blocksRandomText' landingData ]
]
------------------------------------------------------------------------
------------------------------------------------------------------------
...
...
src/Gargantext/Pages/Lists.purs
View file @
1105cefb
...
@@ -10,15 +10,17 @@ import Reactix as R
...
@@ -10,15 +10,17 @@ import Reactix as R
import Gargantext.Prelude
import Gargantext.Prelude
import Gargantext.Components.Node (NodePoly(..), HyperdataList)
import Gargantext.Components.Node (NodePoly(..), HyperdataList)
import Gargantext.Components.Table as Table
import Gargantext.Components.Table as Table
import Gargantext.Config
import Gargantext.Config.REST (get)
import Gargantext.Config.REST (get)
import Gargantext.Ends (url)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Pages.Lists.Tabs as Tabs
import Gargantext.Pages.Lists.Tabs as Tabs
import Gargantext.Utils.Reactix as R2
import Gargantext.Routes (SessionRoute(NodeAPI, Children))
import Gargantext.Sessions (Session)
import Gargantext.Types (NodeType(..))
------------------------------------------------------------------------
------------------------------------------------------------------------
type Props = ( nodeId :: Int,
ends :: Ends
)
type Props = ( nodeId :: Int,
session :: Session
)
listsLayout :: Record Props -> R.Element
listsLayout :: Record Props -> R.Element
listsLayout props = R.createElement listsLayoutCpt props []
listsLayout props = R.createElement listsLayoutCpt props []
...
@@ -26,19 +28,19 @@ listsLayout props = R.createElement listsLayoutCpt props []
...
@@ -26,19 +28,19 @@ listsLayout props = R.createElement listsLayoutCpt props []
listsLayoutCpt :: R.Component Props
listsLayoutCpt :: R.Component Props
listsLayoutCpt = R.hooksComponent "G.P.Lists.listsLayout" cpt
listsLayoutCpt = R.hooksComponent "G.P.Lists.listsLayout" cpt
where
where
cpt {nodeId,
ends
} _ =
cpt {nodeId,
session
} _ =
useLoader nodeId (getCorpus
ends
) $
useLoader nodeId (getCorpus
session
) $
\corpusData@{corpusId, defaultListId, corpusNode: NodePoly poly} ->
\corpusData@{corpusId, defaultListId, corpusNode: NodePoly poly} ->
let { name, date, hyperdata: Tabs.CorpusInfo corpus } = poly
let { name, date, hyperdata: Tabs.CorpusInfo corpus } = poly
{ desc, query, authors: user } = corpus in
{ desc, query, authors: user } = corpus in
R.fragment
R.fragment
[ Table.tableHeaderLayout
[ Table.tableHeaderLayout
{ title: "Corpus " <> name, desc, query, user, date }
{ title: "Corpus " <> name, desc, query, user, date }
, Tabs.tabs {
ends
, corpusId, corpusData}]
, Tabs.tabs {
session
, corpusId, corpusData}]
------------------------------------------------------------------------
------------------------------------------------------------------------
getCorpus ::
Ends
-> Int -> Aff Tabs.CorpusData
getCorpus ::
Session
-> Int -> Aff Tabs.CorpusData
getCorpus
ends
listId = do
getCorpus
session
listId = do
-- fetch corpus via lists parentId
-- fetch corpus via lists parentId
(NodePoly {parentId: corpusId} :: NodePoly {}) <- get nodePolyUrl
(NodePoly {parentId: corpusId} :: NodePoly {}) <- get nodePolyUrl
corpusNode <- get $ corpusNodeUrl corpusId
corpusNode <- get $ corpusNodeUrl corpusId
...
@@ -49,6 +51,6 @@ getCorpus ends listId = do
...
@@ -49,6 +51,6 @@ getCorpus ends listId = do
Nothing ->
Nothing ->
throwError $ error "Missing default list"
throwError $ error "Missing default list"
where
where
nodePolyUrl = url
ends
(NodeAPI Corpus (Just listId))
nodePolyUrl = url
session
(NodeAPI Corpus (Just listId))
corpusNodeUrl = url
ends
<<< NodeAPI Corpus <<< Just
corpusNodeUrl = url
session
<<< NodeAPI Corpus <<< Just
defaultListIdsUrl = url
ends
<<< Children NodeList 0 1 Nothing <<< Just
defaultListIdsUrl = url
session
<<< Children NodeList 0 1 Nothing <<< Just
src/Gargantext/Pages/Lists/Tabs.purs
View file @
1105cefb
...
@@ -17,12 +17,12 @@ import Gargantext.Components.Loader as Loader
...
@@ -17,12 +17,12 @@ import Gargantext.Components.Loader as Loader
import Gargantext.Components.NgramsTable as NT
import Gargantext.Components.NgramsTable as NT
import Gargantext.Components.Node (NodePoly(..))
import Gargantext.Components.Node (NodePoly(..))
import Gargantext.Components.Tab as Tab
import Gargantext.Components.Tab as Tab
import Gargantext.Config
import Gargantext.Pages.Corpus.Chart.Histo (histo)
import Gargantext.Pages.Corpus.Chart.Histo (histo)
import Gargantext.Pages.Corpus.Chart.Metrics (metrics)
import Gargantext.Pages.Corpus.Chart.Metrics (metrics)
import Gargantext.Pages.Corpus.Chart.Pie (pie, bar)
import Gargantext.Pages.Corpus.Chart.Pie (pie, bar)
import Gargantext.Pages.Corpus.Chart.Tree (tree)
import Gargantext.Pages.Corpus.Chart.Tree (tree)
import Gargantext.Sessions (Session)
import Gargantext.Types (CTabNgramType(..), TabType(..), TabSubType(..))
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Reactix as R2
data Mode = Authors | Sources | Institutes | Terms
data Mode = Authors | Sources | Institutes | Terms
...
@@ -41,7 +41,7 @@ modeTabType Institutes = CTabInstitutes
...
@@ -41,7 +41,7 @@ modeTabType Institutes = CTabInstitutes
modeTabType Terms = CTabTerms
modeTabType Terms = CTabTerms
type Props =
type Props =
(
ends :: Ends
(
session :: Session
, corpusId :: Int
, corpusId :: Int
, corpusData :: CorpusData )
, corpusData :: CorpusData )
...
@@ -51,15 +51,15 @@ tabs props = R.createElement tabsCpt props []
...
@@ -51,15 +51,15 @@ tabs props = R.createElement tabsCpt props []
tabsCpt :: R.Component Props
tabsCpt :: R.Component Props
tabsCpt = R.hooksComponent "CorpusTabs" cpt
tabsCpt = R.hooksComponent "CorpusTabs" cpt
where
where
cpt {
ends
, corpusId, corpusData: corpusData@{defaultListId}} _ = do
cpt {
session
, corpusId, corpusData: corpusData@{defaultListId}} _ = do
(selected /\ setSelected) <- R.useState' 0
(selected /\ setSelected) <- R.useState' 0
pure $ Tab.tabs { tabs, selected }
pure $ Tab.tabs { tabs
: tabs'
, selected }
where
where
tabs = [ "Sources" /\ view Sources
tabs
'
= [ "Sources" /\ view Sources
, "Authors" /\ view Authors
, "Authors" /\ view Authors
, "Institutes" /\ view Institutes
, "Institutes" /\ view Institutes
, "Terms" /\ view Terms ]
, "Terms" /\ view Terms ]
view mode = ngramsView {mode,
ends
, corpusId, corpusData}
view mode = ngramsView {mode,
session
, corpusId, corpusData}
type NgramsViewProps = ( mode :: Mode | Props )
type NgramsViewProps = ( mode :: Mode | Props )
...
@@ -69,19 +69,19 @@ ngramsView props = R.createElement ngramsViewCpt props []
...
@@ -69,19 +69,19 @@ ngramsView props = R.createElement ngramsViewCpt props []
ngramsViewCpt :: R.Component NgramsViewProps
ngramsViewCpt :: R.Component NgramsViewProps
ngramsViewCpt = R.staticComponent "ListsNgramsView" cpt
ngramsViewCpt = R.staticComponent "ListsNgramsView" cpt
where
where
cpt {mode,
ends
, corpusId, corpusData: {defaultListId}} _ =
cpt {mode,
session
, corpusId, corpusData: {defaultListId}} _ =
NT.mainNgramsTable
NT.mainNgramsTable
{
ends
, defaultListId, nodeId: corpusId, tabType, tabNgramType}
{
session
, defaultListId, nodeId: corpusId, tabType, tabNgramType}
where
where
tabNgramType = modeTabType mode
tabNgramType = modeTabType mode
tabType = TabCorpus (TabNgramType tabNgramType)
tabType = TabCorpus (TabNgramType tabNgramType)
listId = 0 -- TODO!
listId = 0 -- TODO!
path = {corpusId, tabType}
path = {corpusId, tabType}
path2 = {corpusId, listId, tabType, limit: (Just 1000)} -- todo
path2 = {corpusId, listId, tabType, limit: (Just 1000)} -- todo
chart Authors = pie {
ends
, path}
chart Authors = pie {
session
, path}
chart Sources = bar {
ends
, path}
chart Sources = bar {
session
, path}
chart Institutes = tree {
ends
, path: path2}
chart Institutes = tree {
session
, path: path2}
chart Terms = metrics {
ends
, path: path2}
chart Terms = metrics {
session
, path: path2}
newtype CorpusInfo =
newtype CorpusInfo =
CorpusInfo
CorpusInfo
...
...
src/Gargantext/Pages/Texts.purs
View file @
1105cefb
...
@@ -10,14 +10,16 @@ import Reactix as R
...
@@ -10,14 +10,16 @@ import Reactix as R
import Gargantext.Prelude
import Gargantext.Prelude
import Gargantext.Components.Node (NodePoly(..), HyperdataList)
import Gargantext.Components.Node (NodePoly(..), HyperdataList)
import Gargantext.Components.Table as Table
import Gargantext.Components.Table as Table
import Gargantext.Config
import Gargantext.Config.REST (get)
import Gargantext.Config.REST (get)
import Gargantext.Ends (url)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Pages.Texts.Tabs (CorpusData, CorpusInfo(..))
import Gargantext.Pages.Texts.Tabs (CorpusData, CorpusInfo(..))
import Gargantext.Pages.Texts.Tabs as Tabs
import Gargantext.Pages.Texts.Tabs as Tabs
import Gargantext.Utils.Reactix as R2
import Gargantext.Routes (SessionRoute(NodeAPI, Children))
import Gargantext.Sessions (Session)
import Gargantext.Types (NodeType(..))
type Props = (
ends :: Ends
, nodeId :: Int )
type Props = (
session :: Session
, nodeId :: Int )
textsLayout :: Record Props -> R.Element
textsLayout :: Record Props -> R.Element
textsLayout props = R.createElement textsLayoutCpt props []
textsLayout props = R.createElement textsLayoutCpt props []
...
@@ -26,13 +28,13 @@ textsLayout props = R.createElement textsLayoutCpt props []
...
@@ -26,13 +28,13 @@ textsLayout props = R.createElement textsLayoutCpt props []
textsLayoutCpt :: R.Component Props
textsLayoutCpt :: R.Component Props
textsLayoutCpt = R.hooksComponent "TextsLoader" cpt
textsLayoutCpt = R.hooksComponent "TextsLoader" cpt
where
where
cpt {nodeId,
ends
} _ =
cpt {nodeId,
session
} _ =
useLoader nodeId (getCorpus
ends
) $
useLoader nodeId (getCorpus
session
) $
\corpusData@{corpusId, corpusNode, defaultListId} ->
\corpusData@{corpusId, corpusNode, defaultListId} ->
let
let
NodePoly { name, date, hyperdata: CorpusInfo corpus } = corpusNode
NodePoly { name, date, hyperdata: CorpusInfo corpus } = corpusNode
{desc, query, authors: user} = corpus
{desc, query, authors: user} = corpus
tabs = Tabs.tabs {
ends
, corpusId, corpusData}
tabs = Tabs.tabs {
session
, corpusId, corpusData}
title = "Corpus " <> name
title = "Corpus " <> name
headerProps = { title, desc, query, date, user } in
headerProps = { title, desc, query, date, user } in
R.fragment [Table.tableHeaderLayout headerProps, tabs]
R.fragment [Table.tableHeaderLayout headerProps, tabs]
...
@@ -41,8 +43,8 @@ textsLayoutCpt = R.hooksComponent "TextsLoader" cpt
...
@@ -41,8 +43,8 @@ textsLayoutCpt = R.hooksComponent "TextsLoader" cpt
------------------------------------------------------------------------
------------------------------------------------------------------------
getCorpus ::
Ends
-> Int -> Aff CorpusData
getCorpus ::
Session
-> Int -> Aff CorpusData
getCorpus
ends
textsId = do
getCorpus
session
textsId = do
-- fetch corpus via texts parentId
-- fetch corpus via texts parentId
(NodePoly {parentId: corpusId} :: NodePoly {}) <- get nodePolyUrl
(NodePoly {parentId: corpusId} :: NodePoly {}) <- get nodePolyUrl
corpusNode <- get $ corpusNodeUrl corpusId
corpusNode <- get $ corpusNodeUrl corpusId
...
@@ -53,6 +55,6 @@ getCorpus ends textsId = do
...
@@ -53,6 +55,6 @@ getCorpus ends textsId = do
Nothing ->
Nothing ->
throwError $ error "Missing default list"
throwError $ error "Missing default list"
where
where
nodePolyUrl = url
ends
$ NodeAPI NodeList (Just textsId)
nodePolyUrl = url
session
$ NodeAPI NodeList (Just textsId)
corpusNodeUrl = url
ends
<<< NodeAPI Corpus <<< Just
corpusNodeUrl = url
session
<<< NodeAPI Corpus <<< Just
defaultListIdsUrl = url
ends
<<< Children NodeList 0 1 Nothing <<< Just
defaultListIdsUrl = url
session
<<< Children NodeList 0 1 Nothing <<< Just
src/Gargantext/Pages/Texts/Tabs.purs
View file @
1105cefb
module Gargantext.Pages.Texts.Tabs where
module Gargantext.Pages.Texts.Tabs where
import Data.Argonaut (class DecodeJson, decodeJson, (.?), (.??))
import Data.Maybe (Maybe(..))
--------------------------------------------------------
--------------------------------------------------------
import Gargantext.Prelude
import Prelude (class Eq, class Show, bind, pure, ($))
import Prelude hiding (div)
import Data.Argonaut (class DecodeJson, decodeJson, (.:), (.:!))
import Data.Array as Array
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Data.Generic.Rep.Show (genericShow)
import Data.List (fromFoldable)
import Data.Maybe (Maybe(..))
import Data.Maybe (Maybe(..))
import Data.Tuple (Tuple(..))
import Data.Tuple.Nested ((/\))
import Data.Tuple.Nested ((/\))
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML as H
import Reactix.DOM.HTML as H
import Gargantext.Components.Charts.Options.ECharts (chart) as ECharts
import Gargantext.Components.DocsTable as DT
import Gargantext.Components.DocsTable as DT
import Gargantext.Components.Loader as Loader
import Gargantext.Components.NgramsTable as NT
import Gargantext.Components.Node (NodePoly(..))
import Gargantext.Components.Node (NodePoly(..))
import Gargantext.Components.Tab as Tab
import Gargantext.Components.Tab as Tab
import Gargantext.Config (CTabNgramType(..), TabSubType(..), TabType(..), Ends)
import Gargantext.Pages.Corpus.Chart.Histo (histo)
import Gargantext.Pages.Corpus.Chart.Histo (histo)
import Gargantext.Utils.Reactix as R2
import Gargantext.Sessions (Session)
import Gargantext.Types (CTabNgramType(..), TabSubType(..), TabType(..))
data Mode = MoreLikeFav | MoreLikeTrash
data Mode = MoreLikeFav | MoreLikeTrash
...
@@ -39,7 +30,7 @@ modeTabType :: Mode -> CTabNgramType
...
@@ -39,7 +30,7 @@ modeTabType :: Mode -> CTabNgramType
modeTabType MoreLikeFav = CTabAuthors -- TODO
modeTabType MoreLikeFav = CTabAuthors -- TODO
modeTabType MoreLikeTrash = CTabSources -- TODO
modeTabType MoreLikeTrash = CTabSources -- TODO
type Props = (
ends :: Ends
, corpusId :: Int, corpusData :: CorpusData )
type Props = (
session :: Session
, corpusId :: Int, corpusData :: CorpusData )
tabs :: Record Props -> R.Element
tabs :: Record Props -> R.Element
tabs props = R.createElement tabsCpt props []
tabs props = R.createElement tabsCpt props []
...
@@ -47,21 +38,21 @@ tabs props = R.createElement tabsCpt props []
...
@@ -47,21 +38,21 @@ tabs props = R.createElement tabsCpt props []
tabsCpt :: R.Component Props
tabsCpt :: R.Component Props
tabsCpt = R.hooksComponent "CorpusTabs" cpt
tabsCpt = R.hooksComponent "CorpusTabs" cpt
where
where
cpt {
ends
, corpusId, corpusData} _ = do
cpt {
session
, corpusId, corpusData} _ = do
(selected /\ setSelected) <- R.useState' 0
(selected /\ setSelected) <- R.useState' 0
pure $ Tab.tabs { tabs, selected }
pure $ Tab.tabs { tabs
: tabs'
, selected }
where
where
tabs = [ "Documents" /\ docs, "Trash" /\ trash
tabs
'
= [ "Documents" /\ docs, "Trash" /\ trash
, "More like fav" /\ moreLikeFav, "More like trash" /\ moreLikeTrash ]
, "More like fav" /\ moreLikeFav, "More like trash" /\ moreLikeTrash ]
docView' tabType = docView {
ends
, corpusId, corpusData, tabType }
docView' tabType = docView {
session
, corpusId, corpusData, tabType }
docs = R.fragment [ docsHisto, docView' TabDocs ]
docs = R.fragment [ docsHisto, docView' TabDocs ]
docsHisto = histo { path,
ends
}
docsHisto = histo { path,
session
}
where path = { corpusId, tabType: TabCorpus TabDocs }
where path = { corpusId, tabType: TabCorpus TabDocs }
moreLikeFav = docView' TabMoreLikeFav
moreLikeFav = docView' TabMoreLikeFav
moreLikeTrash = docView' TabMoreLikeTrash
moreLikeTrash = docView' TabMoreLikeTrash
trash = docView' TabTrash
trash = docView' TabTrash
type DocViewProps a = (
ends :: Ends
, corpusId :: Int, corpusData :: CorpusData, tabType :: TabSubType a )
type DocViewProps a = (
session :: Session
, corpusId :: Int, corpusData :: CorpusData, tabType :: TabSubType a )
docView :: forall a. Record (DocViewProps a) -> R.Element
docView :: forall a. Record (DocViewProps a) -> R.Element
docView props = R.createElement docViewCpt props []
docView props = R.createElement docViewCpt props []
...
@@ -70,10 +61,10 @@ docView props = R.createElement docViewCpt props []
...
@@ -70,10 +61,10 @@ docView props = R.createElement docViewCpt props []
docViewCpt :: forall a. R.Component (DocViewProps a)
docViewCpt :: forall a. R.Component (DocViewProps a)
docViewCpt = R.hooksComponent "DocViewWithCorpus" cpt
docViewCpt = R.hooksComponent "DocViewWithCorpus" cpt
where
where
cpt {
ends
, corpusId, corpusData: {defaultListId}, tabType} _children = do
cpt {
session
, corpusId, corpusData: {defaultListId}, tabType} _children = do
pure $ DT.docView $ params tabType
pure $ DT.docView $ params tabType
where
where
params :: forall
a. TabSubType a
-> Record DT.Props
params :: forall
b. TabSubType b
-> Record DT.Props
params TabDocs =
params TabDocs =
{ nodeId: corpusId
{ nodeId: corpusId
-- ^ TODO merge nodeId and corpusId in DT
-- ^ TODO merge nodeId and corpusId in DT
...
@@ -83,7 +74,7 @@ docViewCpt = R.hooksComponent "DocViewWithCorpus" cpt
...
@@ -83,7 +74,7 @@ docViewCpt = R.hooksComponent "DocViewWithCorpus" cpt
, listId: defaultListId
, listId: defaultListId
, corpusId: Just corpusId
, corpusId: Just corpusId
, showSearch: true
, showSearch: true
,
ends
}
,
session
}
params TabMoreLikeFav =
params TabMoreLikeFav =
{ nodeId: corpusId
{ nodeId: corpusId
-- ^ TODO merge nodeId and corpusId in DT
-- ^ TODO merge nodeId and corpusId in DT
...
@@ -93,7 +84,7 @@ docViewCpt = R.hooksComponent "DocViewWithCorpus" cpt
...
@@ -93,7 +84,7 @@ docViewCpt = R.hooksComponent "DocViewWithCorpus" cpt
, listId: defaultListId
, listId: defaultListId
, corpusId: Just corpusId
, corpusId: Just corpusId
, showSearch: false
, showSearch: false
,
ends
}
,
session
}
params TabMoreLikeTrash =
params TabMoreLikeTrash =
{ nodeId: corpusId
{ nodeId: corpusId
-- ^ TODO merge nodeId and corpusId in DT
-- ^ TODO merge nodeId and corpusId in DT
...
@@ -103,7 +94,7 @@ docViewCpt = R.hooksComponent "DocViewWithCorpus" cpt
...
@@ -103,7 +94,7 @@ docViewCpt = R.hooksComponent "DocViewWithCorpus" cpt
, listId: defaultListId
, listId: defaultListId
, corpusId: Just corpusId
, corpusId: Just corpusId
, showSearch: false
, showSearch: false
,
ends
}
,
session
}
params TabTrash =
params TabTrash =
{ nodeId: corpusId
{ nodeId: corpusId
-- ^ TODO merge nodeId and corpusId in DT
-- ^ TODO merge nodeId and corpusId in DT
...
@@ -113,7 +104,7 @@ docViewCpt = R.hooksComponent "DocViewWithCorpus" cpt
...
@@ -113,7 +104,7 @@ docViewCpt = R.hooksComponent "DocViewWithCorpus" cpt
, listId: defaultListId
, listId: defaultListId
, corpusId: Nothing
, corpusId: Nothing
, showSearch: true
, showSearch: true
,
ends
}
,
session
}
-- DUMMY
-- DUMMY
params _ =
params _ =
{ nodeId: corpusId
{ nodeId: corpusId
...
@@ -124,7 +115,7 @@ docViewCpt = R.hooksComponent "DocViewWithCorpus" cpt
...
@@ -124,7 +115,7 @@ docViewCpt = R.hooksComponent "DocViewWithCorpus" cpt
, listId: defaultListId
, listId: defaultListId
, corpusId: Nothing
, corpusId: Nothing
, showSearch: true
, showSearch: true
,
ends
}
,
session
}
newtype CorpusInfo = CorpusInfo { title :: String
newtype CorpusInfo = CorpusInfo { title :: String
, desc :: String
, desc :: String
...
@@ -154,11 +145,11 @@ corpusInfoDefault = NodePoly { id : 0
...
@@ -154,11 +145,11 @@ corpusInfoDefault = NodePoly { id : 0
instance decodeCorpusInfo :: DecodeJson CorpusInfo where
instance decodeCorpusInfo :: DecodeJson CorpusInfo where
decodeJson json = do
decodeJson json = do
obj <- decodeJson json
obj <- decodeJson json
title <- obj .
?
"title"
title <- obj .
:
"title"
desc <- obj .
?
"desc"
desc <- obj .
:
"desc"
query <- obj .
?
"query"
query <- obj .
:
"query"
authors <- obj .
?
"authors"
authors <- obj .
:
"authors"
chart <- obj .
??
"chart"
chart <- obj .
:!
"chart"
let totalRecords = 47361 -- TODO
let totalRecords = 47361 -- TODO
pure $ CorpusInfo {title, desc, query, authors, chart, totalRecords}
pure $ CorpusInfo {title, desc, query, authors, chart, totalRecords}
...
...
src/Gargantext/Router.purs
View file @
1105cefb
module Gargantext.Router where
module Gargantext.Router where
import Gargantext.Prelude
import Prelude
import Data.Foldable (oneOf)
import Data.Foldable (oneOf)
import Data.Int (floor)
import Data.Int (floor)
import Data.Maybe (Maybe(..))
import Data.Tuple.Nested ((/\))
-- import Effect (Effect)
-- import Effect.Class (liftEffect)
import Reactix as R
import Routing.Hash (matches)
import Routing.Match (Match, lit, num)
import Routing.Match (Match, lit, num)
-- import Web.HTML (window)
import Gargantext.Routes (AppRoute(..))
-- import Web.HTML.Window (localStorage)
-- import Web.Storage.Storage (getItem)
data Routes
= Home
| Login
| Folder Int
| Corpus Int
| Document Int Int
| CorpusDocument Int Int Int
| PGraphExplorer Int
| Dashboard
| Texts Int
| Lists Int
| Annuaire Int
| UserPage Int
| ContactPage Int
rout
ing :: Match Routes
rout
er :: Match AppRoute
rout
ing
= oneOf
rout
er
= oneOf
[ Login <$ route "login"
[ Login <$ route "login"
, Folder <$> (route "folder" *> int)
, Folder <$> (route "folder" *> int)
, CorpusDocument <$> (route "corpus" *> int) <*> (lit "list" *> int) <*> (lit "document" *> int)
, CorpusDocument <$> (route "corpus" *> int) <*> (lit "list" *> int) <*> (lit "document" *> int)
...
@@ -46,32 +22,8 @@ routing = oneOf
...
@@ -46,32 +22,8 @@ routing = oneOf
, ContactPage <$> (route "contact" *> int)
, ContactPage <$> (route "contact" *> int)
, Home <$ lit ""
, Home <$ lit ""
]
]
where
where
route str = lit "" *> lit str
route str = lit "" *> lit str
int :: Match Int
int :: Match Int
int = floor <$> num
int = floor <$> num
instance showRoutes :: Show Routes where
show Login = "Login"
show (UserPage i) = "User" <> show i
show (ContactPage i) = "Contact" <> show i
show (CorpusDocument _ _ i) = "Document" <> show i
show (Document _ i) = "Document" <> show i
show (Corpus i) = "Corpus" <> show i
show (Annuaire i) = "Annuaire" <> show i
show (Folder i) = "Folder" <> show i
show Dashboard = "Dashboard"
show (PGraphExplorer i) = "graphExplorer" <> show i
show (Texts i) = "texts" <> show i
show (Lists i) = "lists" <> show i
show Home = "Home"
-- | Ties the hash router to a state hook of routes
-- | Note: if it gets sent to an unrecognised url, it will quietly drop the change
useHashRouter :: forall routes. Match routes -> routes -> R.Hooks (R.State routes)
useHashRouter routes init = do
route@(_ /\ setRoute) <- R.useState' init
R.useEffectOnce $ matches routes $ \_old new -> setRoute (const new)
pure route
src/Gargantext/Routes.purs
0 → 100644
View file @
1105cefb
module Gargantext.Routes where
import Prelude
import Data.Maybe (Maybe)
import Gargantext.Types
data AppRoute
= Home
| Login
| Folder Int
| Corpus Int
| Document Int Int
| CorpusDocument Int Int Int
| PGraphExplorer Int
| Dashboard
| Texts Int
| Lists Int
| Annuaire Int
| UserPage Int
| ContactPage Int
data SessionRoute
= Tab TabType (Maybe Id)
| Children NodeType Offset Limit (Maybe OrderBy) (Maybe Id)
| GetNgrams NgramsGetOpts (Maybe Id)
| PutNgrams TabType (Maybe ListId) (Maybe TermList) (Maybe Id)
-- ^ This name is not good. In particular this URL is used both in PUT and POST.
| NodeAPI NodeType (Maybe Id)
| ListDocument (Maybe ListId) (Maybe Id)
| Search SearchOpts (Maybe Id)
| CorpusMetrics CorpusMetricOpts (Maybe Id)
| Chart ChartOpts (Maybe Id)
instance showAppRoute :: Show AppRoute where
show Home = "Home"
show Login = "Login"
show (Folder i) = "Folder" <> show i
show (Corpus i) = "Corpus" <> show i
show (Document _ i) = "Document" <> show i
show (CorpusDocument _ _ i) = "Document" <> show i
show (PGraphExplorer i) = "graphExplorer" <> show i
show Dashboard = "Dashboard"
show (Texts i) = "texts" <> show i
show (Lists i) = "lists" <> show i
show (Annuaire i) = "Annuaire" <> show i
show (UserPage i) = "User" <> show i
show (ContactPage i) = "Contact" <> show i
appPath :: AppRoute -> String
appPath Home = ""
appPath Login = "login"
appPath (Folder i) = "folder/" <> show i
appPath (CorpusDocument c l i) = "corpus/" <> show c <> "/list/" <> show l <> "/document/" <> show i
appPath (Corpus i) = "corpus/" <> show i
appPath (Document l i) = "list/" <> show l <> "/document/" <> show i
appPath Dashboard = "dashboard"
appPath (PGraphExplorer i) = "graph/" <> show i
appPath (Texts i) = "texts/" <> show i
appPath (Lists i) = "lists/" <> show i
appPath (Annuaire i) = "annuaire/" <> show i
appPath (UserPage i) = "user/" <> show i
appPath (ContactPage i) = "contact/" <> show i
src/Gargantext/Sessions.purs
0 → 100644
View file @
1105cefb
-- | A module for authenticating to create sessions and handling them
module Gargantext.Sessions where
import Prelude (class Eq, class Show, const, otherwise, pure, show, unit, ($), (*>), (<$>), (<>), (==), (>>=))
import Data.Either (Either(..))
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Eq (genericEq)
import Data.Maybe (Maybe(..))
import DOM.Simple.Console (log, log2)
import Effect (Effect)
import Effect.Aff (Aff)
import Reactix as R
import Web.HTML (window)
import Web.HTML.Window (localStorage)
import Web.Storage.Storage (getItem, setItem, removeItem)
import Gargantext.Components.Login.Types
(AuthRequest(..), AuthResponse(..), AuthInvalid(..), AuthData(..))
import Gargantext.Config.REST (post)
import Gargantext.Ends (class ToUrl, Backend, backendUrl, toUrl, sessionPath)
import Gargantext.Routes (SessionRoute)
import Gargantext.Types (NodePath, nodePath)
import Gargantext.Utils.Reactix as R2
-- | A Session represents an authenticated session for a user at a
-- | backend. It contains a token and root tree id.
newtype Session = Session
{ backend :: Backend
, username :: String
, token :: String
, treeId :: Int }
derive instance genericSession :: Generic Session _
instance eqSession :: Eq Session where
eq = genericEq
instance showSession :: Show Session where
show (Session {backend, username}) = username <> "@" <> show backend
instance toUrlSessionRoute :: ToUrl Session SessionRoute where
toUrl (Session {backend}) r = backendUrl backend (sessionPath r)
instance toUrlSessionNodePath :: ToUrl Session NodePath where
toUrl (Session {backend}) np = backendUrl backend (nodePath np)
sessionUrl :: Session -> String -> String
sessionUrl (Session {backend}) = backendUrl backend
instance toUrlSessionString :: ToUrl Session String where
toUrl = sessionUrl
newtype Sessions = Sessions (Maybe Session)
unSessions :: Sessions -> Maybe Session
unSessions (Sessions s) = s
useSessions :: R.Hooks (R2.Reductor Sessions Action)
useSessions = R2.useReductor actAndSave (const loadSessions) unit
where
actAndSave :: R2.Actor Sessions Action
actAndSave s a = act s a >>= saveSessions
data Action
= Login Session
| Logout Session
act :: Sessions -> Action -> Effect Sessions
act _ (Login session) = pure $ Sessions (Just session)
act (Sessions s) (Logout session)
| Just session == s = pure (Sessions Nothing)
| Just s2 <- s = log2 "Alien session:" s2 *> pure (Sessions Nothing)
| otherwise = log "Can't log out of nonexistent session" *> pure (Sessions Nothing)
-- Key we will store the data under
localStorageKey :: String
localStorageKey = "garg-sessions"
empty :: Sessions
empty = Sessions Nothing
-- True if there are no sessions stored
null :: Sessions -> Boolean
null (Sessions Nothing) = true
null _ = false
-- | Will attempt to load saved sessions from localstorage. should log if decoding fails
loadSessions :: Effect Sessions
loadSessions = pure empty
-- loadSessions = window >>= localStorage >>= getItem "auths" >>= traverse decode
-- where
-- decode :: String -> Effect (Maybe Sessions)
-- decode = ret <<< runExcept <<< decodeJSON
-- ret (Right v) = pure $ Just v
-- ret (Left e) = log2 "Error reading serialised sessions:" e *> pure (Malformed e)
saveSessions :: Sessions -> Effect Sessions
saveSessions sessions = effect *> pure sessions
where
effect
| null sessions = window >>= localStorage >>= removeItem localStorageKey
| otherwise = pure unit
-- | otherwise = window >>= localStorage >>= setItem localStorageKey (encodeJSON sessions)
postAuthRequest :: Backend -> AuthRequest -> Aff (Either String Session)
postAuthRequest backend ar@(AuthRequest {username}) =
decode <$> post (toUrl backend "auth") ar
where
decode (AuthResponse ar2)
| {inval: Just (AuthInvalid {message})} <- ar2 = Left message
| {valid: Just (AuthData {token, tree_id})} <- ar2 =
Right $ Session { backend, username, token, treeId: tree_id }
| otherwise = Left "Invalid response from server"
src/Gargantext/Types.purs
View file @
1105cefb
module Gargantext.Types where
module Gargantext.Types where
import Data.Argonaut ( class DecodeJson, decodeJson, class EncodeJson, encodeJson )
import Prelude
import Data.Maybe (Maybe(..))
import Data.Argonaut ( class DecodeJson, decodeJson, class EncodeJson, encodeJson, (:=), (~>), jsonEmptyObject)
import Data.Maybe (Maybe(..), maybe, fromJust)
import Data.Either (Either(..))
import Data.Either (Either(..))
import Prim.Row (class Union)
import Prim.Row (class Union)
import URI.Query (Query)
import URI.Query (Query)
import Gargantext.Prelude
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
data TermSize = MonoTerm | MultiTerm
data TermSize = MonoTerm | MultiTerm
...
@@ -86,3 +88,238 @@ termLists = [ { desc: "All terms", mval: Nothing }
...
@@ -86,3 +88,238 @@ termLists = [ { desc: "All terms", mval: Nothing }
-- | Proof that row `r` is a subset of row `s`
-- | Proof that row `r` is a subset of row `s`
class Optional (r :: # Type) (s :: # Type)
class Optional (r :: # Type) (s :: # Type)
instance optionalInstance :: Union r t s => Optional r s
instance optionalInstance :: Union r t s => Optional r s
showTabType' :: TabType -> String
showTabType' (TabCorpus t) = show t
showTabType' (TabDocument t) = show t
showTabType' (TabPairing t) = show t
data TabPostQuery = TabPostQuery {
offset :: Int
, limit :: Int
, orderBy :: OrderBy
, tabType :: TabType
, query :: String
}
instance encodeJsonTabPostQuery :: EncodeJson TabPostQuery where
encodeJson (TabPostQuery post) =
"view" := showTabType' post.tabType
~> "offset" := post.offset
~> "limit" := post.limit
~> "orderBy" := show post.orderBy
~> "query" := post.query
~> jsonEmptyObject
data NodeType = NodeUser
| Annuaire
| NodeContact
| Corpus
| Url_Document
| CorpusV3
| Dashboard
| Error
| Folder
| Graph
| Phylo
| Individu
| Node
| Nodes
| Tree
| NodeList
| Texts
derive instance eqNodeType :: Eq NodeType
instance showNodeType :: Show NodeType where
show NodeUser = "NodeUser"
show Annuaire = "Annuaire"
show NodeContact = "NodeContact"
show Corpus = "NodeCorpus"
show CorpusV3 = "NodeCorpusV3"
show Dashboard = "NodeDashboard"
show Url_Document = "NodeDocument"
show Error = "NodeError"
show Folder = "NodeFolder"
show Graph = "NodeGraph"
show Phylo = "NodePhylo"
show Individu = "NodeIndividu"
show Node = "Node"
show Nodes = "Nodes"
show Tree = "NodeTree"
show NodeList = "NodeList"
show Texts = "NodeTexts"
readNodeType :: String -> NodeType
readNodeType "NodeAnnuaire" = Annuaire
readNodeType "NodeDashboard" = Dashboard
readNodeType "Document" = Url_Document
readNodeType "NodeFolder" = Folder
readNodeType "NodeGraph" = Graph
readNodeType "NodePhylo" = Phylo
readNodeType "Individu" = Individu
readNodeType "Node" = Node
readNodeType "Nodes" = Nodes
readNodeType "NodeCorpus" = Corpus
readNodeType "NodeCorpusV3" = CorpusV3
readNodeType "NodeUser" = NodeUser
readNodeType "NodeContact" = NodeContact
readNodeType "Tree" = Tree
readNodeType "NodeList" = NodeList
readNodeType "NodeTexts" = Texts
readNodeType _ = Error
{-
------------------------------------------------------------
instance ordNodeType :: Ord NodeType where
compare n1 n2 = compare (show n1) (show n2)
instance eqNodeType :: Eq NodeType where
eq n1 n2 = eq (show n1) (show n2)
-}
------------------------------------------------------------
instance decodeJsonNodeType :: DecodeJson NodeType where
decodeJson json = do
obj <- decodeJson json
pure $ readNodeType obj
instance encodeJsonNodeType :: EncodeJson NodeType where
encodeJson nodeType = encodeJson $ show nodeType
nodeTypePath :: NodeType -> String
nodeTypePath Annuaire = "annuaire"
nodeTypePath Corpus = "corpus"
nodeTypePath CorpusV3 = "corpus"
nodeTypePath Dashboard = "dashboard"
nodeTypePath Url_Document = "document"
nodeTypePath Error = "ErrorNodeType"
nodeTypePath Folder = "folder"
nodeTypePath Graph = "graph"
nodeTypePath Phylo = "phylo"
nodeTypePath Individu = "individu"
nodeTypePath Node = "node"
nodeTypePath Nodes = "nodes"
nodeTypePath NodeUser = "user"
nodeTypePath NodeContact = "contact"
nodeTypePath Tree = "tree"
nodeTypePath NodeList = "lists"
nodeTypePath Texts = "texts"
------------------------------------------------------------
type ListId = Int
type NgramsGetOpts =
{ tabType :: TabType
, offset :: Offset
, limit :: Limit
, orderBy :: Maybe OrderBy
, listIds :: Array ListId
, termListFilter :: Maybe TermList
, termSizeFilter :: Maybe TermSize
, searchQuery :: String
}
type SearchOpts =
{ {-id :: Int
, query :: Array String
,-}
listId :: Int
, limit :: Limit
, offset :: Offset
, orderBy :: Maybe OrderBy
}
type CorpusMetricOpts =
{ tabType :: TabType
, listId :: ListId
, limit :: Maybe Limit
}
type ChartOpts =
{ chartType :: ChartType
, tabType :: TabType
-- , listId :: ListId
-- , limit :: Maybe Limit
}
data NodePath = NodePath NodeType (Maybe Id)
nodePath :: NodePath -> String
nodePath (NodePath t i) = nodeTypePath t <> "/" <> id
where id = maybe "" (\j -> "/" <> show j) i
data ChartType = Histo | Scatter | ChartPie | ChartTree
instance showChartType :: Show ChartType
where
show Histo = "chart"
show Scatter = "scatter"
show ChartPie = "pie"
show ChartTree = "tree"
type Id = Int
type Limit = Int
type Offset = Int
data OrderBy = DateAsc | DateDesc
| TitleAsc | TitleDesc
| ScoreAsc | ScoreDesc
| TermAsc | TermDesc
| SourceAsc | SourceDesc
derive instance genericOrderBy :: Generic OrderBy _
instance showOrderBy :: Show OrderBy where
show = genericShow
------------------------------------------------------------
data ApiVersion = V10 | V11
instance showApiVersion :: Show ApiVersion where
show V10 = "v1.0"
show V11 = "v1.1"
------------------------------------------------------------
instance eqApiVersion :: Eq ApiVersion where
eq V10 V10 = true
eq V11 V11 = true
eq _ _ = false
data CTabNgramType = CTabTerms | CTabSources | CTabAuthors | CTabInstitutes
derive instance eqCTabNgramType :: Eq CTabNgramType
instance showCTabNgramType :: Show CTabNgramType where
show CTabTerms = "Terms"
show CTabSources = "Sources"
show CTabAuthors = "Authors"
show CTabInstitutes = "Institutes"
data PTabNgramType = PTabPatents | PTabBooks | PTabCommunication
derive instance eqPTabNgramType :: Eq PTabNgramType
instance showPTabNgramType :: Show PTabNgramType where
show PTabPatents = "Patents"
show PTabBooks = "Books"
show PTabCommunication = "Communication"
data TabSubType a = TabDocs | TabNgramType a | TabTrash | TabMoreLikeFav | TabMoreLikeTrash
derive instance eqTabSubType :: Eq a => Eq (TabSubType a)
instance showTabSubType :: Show a => Show (TabSubType a) where
show TabDocs = "Docs"
show (TabNgramType a) = show a
show TabTrash = "Trash"
show TabMoreLikeFav = "MoreFav"
show TabMoreLikeTrash = "MoreTrash"
data TabType
= TabCorpus (TabSubType CTabNgramType)
| TabPairing (TabSubType PTabNgramType)
| TabDocument (TabSubType CTabNgramType)
derive instance eqTabType :: Eq TabType
derive instance genericTabType :: Generic TabType _
instance showTabType :: Show TabType where
show = genericShow
src/Gargantext/Utils.purs
View file @
1105cefb
...
@@ -31,6 +31,10 @@ invertOrdering LT = GT
...
@@ -31,6 +31,10 @@ invertOrdering LT = GT
invertOrdering GT = LT
invertOrdering GT = LT
invertOrdering EQ = EQ
invertOrdering EQ = EQ
csrfMiddlewareToken :: String
csrfMiddlewareToken = "Wy52D2nor8kC1r1Y4GrsrSIxQ2eqW8UwkdiQQshMoRwobzU4uldknRUhP0j4WcEM"
-- A lens that always returns unit
-- A lens that always returns unit
_unit :: forall s. Lens' s Unit
_unit :: forall s. Lens' s Unit
_unit = lens (\_ -> unit) (\s _ -> s)
_unit = lens (\_ -> unit) (\s _ -> s)
src/Gargantext/Utils/Reactix.purs
View file @
1105cefb
module Gargantext.Utils.Reactix
module Gargantext.Utils.Reactix where
where
import Prelude
import Prelude
import DOM.Simple as DOM
import DOM.Simple.Document (document)
import DOM.Simple.Event as DE
import Data.Maybe (Maybe(..))
import Data.Maybe (Maybe(..))
import Data.Nullable (Nullable, null, toMaybe)
import Data.Nullable (Nullable, null, toMaybe)
import Data.Traversable (traverse_)
import Data.Tuple (Tuple)
import Data.Tuple (Tuple(..))
import Data.Tuple.Nested ((/\))
import Data.Tuple.Nested ((/\))
import DOM.Simple.Element as Element
import DOM.Simple.Event as DE
import DOM.Simple as DOM
import DOM.Simple as DOM
import DOM.Simple.Document (document)
import DOM.Simple.Event as DE
import DOM.Simple.Element as Element
import Effect (Effect)
import Effect (Effect)
import Effect.Class (liftEffect)
import Effect.Class (liftEffect)
import Effect.Aff (Aff, launchAff, launchAff_, killFiber)
import Effect.Aff (Aff, launchAff, launchAff_, killFiber)
import Effect.Exception (error)
import Effect.Exception (error)
import Effect.Uncurried (EffectFn1, mkEffectFn1)
import Effect.Uncurried (EffectFn1, mkEffectFn1
, mkEffectFn2
)
import FFI.Simple ((...), defineProperty, delay)
import FFI.Simple ((...), defineProperty, delay
, args3
)
import React (
ReactClass, ReactElement, Children, class IsReactElement, class ReactPropFields
)
import React (
class ReactPropFields, Children, ReactClass, ReactElement
)
import React as React
import React as React
import Reactix as R
import Reactix as R
import Reactix.DOM.HTML (ElemFactory, text)
import Reactix.DOM.HTML (ElemFactory, text)
import Reactix.React (createDOMElement)
import Reactix.React (
react,
createDOMElement)
import Reactix.SyntheticEvent as RE
import Reactix.SyntheticEvent as RE
import Reactix.Utils (currySecond, hook, tuple)
import Thermite (Spec, simpleSpec, Render, defaultPerformAction)
import Thermite (Spec, simpleSpec, Render, defaultPerformAction)
import Unsafe.Coerce (unsafeCoerce)
import Unsafe.Coerce (unsafeCoerce)
newtype Point = Point { x :: Number, y :: Number }
newtype Point = Point { x :: Number, y :: Number }
-- a setter function, for useState
type Setter t = (t -> t) -> Effect Unit
type Setter t = (t -> t) -> Effect Unit
-- a reducer function living in effector, for useReductor
type Actor t a = (t -> a -> Effect t)
-- | Turns a ReactElement into aReactix Element
-- | Turns a ReactElement into aReactix Element
-- | buff (v.) to polish
-- | buff (v.) to polish
...
@@ -163,3 +162,19 @@ childless cpt props = R.createElement cpt props []
...
@@ -163,3 +162,19 @@ childless cpt props = R.createElement cpt props []
showText :: forall s. Show s => s -> R.Element
showText :: forall s. Show s => s -> R.Element
showText = text <<< show
showText = text <<< show
----- Reactix's new effectful reducer: sneak-peek because anoe wants to demo on tuesday
-- | Like a reducer, but lives in Effect
type Reductor state action = Tuple state (action -> Effect Unit)
-- | Like useReductor, but lives in Effect
useReductor :: forall s a i. Actor s a -> (i -> Effect s) -> i -> R.Hooks (Reductor s a)
useReductor f i j =
hook $ \_ ->
pure $ currySecond $ tuple $ react ... "useReducer" $ args3 (mkEffectFn2 f) j (mkEffectFn1 i)
-- | Like `useReductor`, but takes an initial state instead of an
-- | initialiser function and argument
useReductor' :: forall s a. Actor s a -> s -> R.Hooks (Reductor s a)
useReductor' r = useReductor r pure
src/Main.purs
View file @
1105cefb
module Main where
module Main
(main)
where
import Prelude (Unit, ($))
import Prelude (Unit, ($))
import Data.Maybe (Maybe(..))
import Data.Maybe (Maybe(..))
import Data.Nullable (toMaybe)
import Data.Nullable (toMaybe)
import DOM.Simple (Element)
import DOM.Simple.Document (document)
import DOM.Simple.Document (document)
import DOM.Simple.Console (log)
import DOM.Simple.Console (log)
import Effect (Effect)
import Effect (Effect)
import FFI.Simple ((...))
import FFI.Simple ((...))
import Reactix as R
import Reactix as R
import Gargantext.Components.
Layout (layout
)
import Gargantext.Components.
App (app
)
main :: Effect Unit
main :: Effect Unit
main = paint $ toMaybe $ document ... "getElementById" $ [ "app" ]
main = paint $ toMaybe (document ... "getElementById" $ [ "app" ])
where
paint Nothing = log "[main] Container not found"
paint :: Maybe Element -> Effect Unit
paint (Just c) = R.render (layout {}) c
paint Nothing = log "[main] Container not found"
paint (Just c) = R.render (app {}) c
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment