Commit 78c93d7e authored by Alexandre Delanoë's avatar Alexandre Delanoë

[FEAT][FOREST] search component on each capable node.

parent f93761e8
...@@ -34,7 +34,7 @@ type Props = ( root :: ID ...@@ -34,7 +34,7 @@ type Props = ( root :: ID
, session :: Session , session :: Session
, frontends :: Frontends , frontends :: Frontends
) )
-----------------
treeView :: Record Props -> R.Element treeView :: Record Props -> R.Element
treeView props = R.createElement treeViewCpt props [] treeView props = R.createElement treeViewCpt props []
......
...@@ -29,6 +29,7 @@ settingsBox :: NodeType -> SettingsBox ...@@ -29,6 +29,7 @@ settingsBox :: NodeType -> SettingsBox
settingsBox NodeUser = SettingsBox { show : true settingsBox NodeUser = SettingsBox { show : true
, edit : false , edit : false
, buttons : [Documentation NodeUser , buttons : [Documentation NodeUser
, SearchBox
, Add [ FolderPrivate , Add [ FolderPrivate
, FolderShared , FolderShared
, FolderPublic , FolderPublic
...@@ -40,6 +41,7 @@ settingsBox NodeUser = SettingsBox { show : true ...@@ -40,6 +41,7 @@ settingsBox NodeUser = SettingsBox { show : true
settingsBox FolderPrivate = SettingsBox { show: true settingsBox FolderPrivate = SettingsBox { show: true
, edit : false , edit : false
, buttons : [Documentation FolderPrivate , buttons : [Documentation FolderPrivate
, SearchBox
, Add [ Corpus , Add [ Corpus
, Folder , Folder
] ]
...@@ -49,15 +51,14 @@ settingsBox FolderPrivate = SettingsBox { show: true ...@@ -49,15 +51,14 @@ settingsBox FolderPrivate = SettingsBox { show: true
settingsBox FolderShared = SettingsBox { show: true settingsBox FolderShared = SettingsBox { show: true
, edit : false , edit : false
, buttons : [Documentation FolderShared , buttons : [Documentation FolderShared
, Add [ Corpus --, Team
, Folder
]
, Delete] , Delete]
} }
settingsBox FolderPublic = SettingsBox { show: true settingsBox FolderPublic = SettingsBox { show: true
, edit : false , edit : false
, buttons : [Documentation FolderPublic , buttons : [Documentation FolderPublic
, SearchBox
, Add [ Corpus , Add [ Corpus
, Folder , Folder
] ]
...@@ -68,20 +69,22 @@ settingsBox FolderPublic = SettingsBox { show: true ...@@ -68,20 +69,22 @@ settingsBox FolderPublic = SettingsBox { show: true
settingsBox Folder = SettingsBox { show : true settingsBox Folder = SettingsBox { show : true
, edit : true , edit : true
, buttons : [ Documentation Folder , buttons : [ Documentation Folder
, SearchBox
, Add [ Corpus , Add [ Corpus
, Folder , Folder
] ]
, Delete] , Delete
]
} }
settingsBox Corpus = SettingsBox { show : true settingsBox Corpus = SettingsBox { show : true
, edit : true , edit : true
, buttons : [ Documentation Corpus , buttons : [ Documentation Corpus
, SearchBox
, Add [ NodeList , Add [ NodeList
, Graph , Graph
, Dashboard , Dashboard
] ]
, Search
, Upload , Upload
, Download , Download
, Share , Share
...@@ -129,16 +132,16 @@ settingsBox _ = SettingsBox { show : false ...@@ -129,16 +132,16 @@ settingsBox _ = SettingsBox { show : false
------------------------------------------------------------------------ ------------------------------------------------------------------------
data NodeAction = Documentation NodeType data NodeAction = Documentation NodeType
| Search | SearchBox
| Download | Upload | Refresh | Download | Upload | Refresh
| Move | Clone | Delete | Move | Clone | Delete
| Share | Share | Team
| Add (Array NodeType) | Add (Array NodeType)
instance eqNodeAction :: Eq NodeAction where instance eqNodeAction :: Eq NodeAction where
eq (Documentation x) (Documentation y) = true && (x == y) eq (Documentation x) (Documentation y) = true && (x == y)
eq Search Search = true eq SearchBox SearchBox = true
eq Download Download = true eq Download Download = true
eq Upload Upload = true eq Upload Upload = true
eq Refresh Refresh = true eq Refresh Refresh = true
...@@ -146,7 +149,7 @@ instance eqNodeAction :: Eq NodeAction where ...@@ -146,7 +149,7 @@ instance eqNodeAction :: Eq NodeAction where
eq Clone Clone = true eq Clone Clone = true
eq Delete Delete = true eq Delete Delete = true
eq Share Share = true eq Share Share = true
eq Team Team = true
eq (Add x) (Add y) = true && (x == y) eq (Add x) (Add y) = true && (x == y)
eq _ _ = false eq _ _ = false
...@@ -13,6 +13,9 @@ import Gargantext.Components.Forest.Tree.Node.Action ...@@ -13,6 +13,9 @@ import Gargantext.Components.Forest.Tree.Node.Action
import Gargantext.Components.Forest.Tree.Node.Action.Add import Gargantext.Components.Forest.Tree.Node.Action.Add
import Gargantext.Components.Forest.Tree.Node.Action.Rename import Gargantext.Components.Forest.Tree.Node.Action.Rename
import Gargantext.Components.Forest.Tree.Node.Action.Upload import Gargantext.Components.Forest.Tree.Node.Action.Upload
import Gargantext.Components.Search.Types
import Gargantext.Components.Search.SearchBar
import Gargantext.Ends (Frontends, url) import Gargantext.Ends (Frontends, url)
import Gargantext.Routes (AppRoute, SessionRoute(..)) import Gargantext.Routes (AppRoute, SessionRoute(..))
import Gargantext.Routes as Routes import Gargantext.Routes as Routes
...@@ -66,6 +69,7 @@ nodeMainSpan d p folderOpen session frontends = R.createElement el p [] ...@@ -66,6 +69,7 @@ nodeMainSpan d p folderOpen session frontends = R.createElement el p []
, name:name' , name:name'
, nodeType , nodeType
, action: Nothing , action: Nothing
, session
} popupOpen } popupOpen
else H.div {} [] else H.div {} []
, fileTypeView d {id, nodeType} droppedFile isDragOver , fileTypeView d {id, nodeType} droppedFile isDragOver
...@@ -161,6 +165,7 @@ type NodePopupProps = ...@@ -161,6 +165,7 @@ type NodePopupProps =
, name :: Name , name :: Name
, nodeType :: NodeType , nodeType :: NodeType
, action :: Maybe NodeAction , action :: Maybe NodeAction
, session :: Session
) )
iconAStyle = { color : "black" iconAStyle = { color : "black"
...@@ -174,7 +179,7 @@ nodePopupView :: (Action -> Aff Unit) ...@@ -174,7 +179,7 @@ nodePopupView :: (Action -> Aff Unit)
nodePopupView d p mPop@(Just NodePopup /\ setPopupOpen) = R.createElement el p [] nodePopupView d p mPop@(Just NodePopup /\ setPopupOpen) = R.createElement el p []
where where
el = R.hooksComponent "NodePopupView" cpt el = R.hooksComponent "NodePopupView" cpt
cpt {id, name, nodeType, action} _ = do cpt {id, name, nodeType, action, session} _ = do
renameBoxOpen <- R.useState' false renameBoxOpen <- R.useState' false
nodePopupState@(nodePopup /\ setNodePopup) <- R.useState' {id, name, nodeType, action} nodePopupState@(nodePopup /\ setNodePopup) <- R.useState' {id, name, nodeType, action}
pure $ H.div tooltipProps $ pure $ H.div tooltipProps $
...@@ -191,7 +196,7 @@ nodePopupView d p mPop@(Just NodePopup /\ setPopupOpen) = R.createElement el p [ ...@@ -191,7 +196,7 @@ nodePopupView d p mPop@(Just NodePopup /\ setPopupOpen) = R.createElement el p [
, onClick : setNodePopup $ const {id,name,nodeType,action :Nothing} , onClick : setNodePopup $ const {id,name,nodeType,action :Nothing}
} [] } []
else H.div {} [] else H.div {} []
, panelAction d {id,name,nodeType,action:nodePopup.action} mPop , panelAction d {id,name,nodeType,action:nodePopup.action, session} mPop
] ]
] ]
where where
...@@ -208,7 +213,7 @@ nodePopupView d p mPop@(Just NodePopup /\ setPopupOpen) = R.createElement el p [ ...@@ -208,7 +213,7 @@ nodePopupView d p mPop@(Just NodePopup /\ setPopupOpen) = R.createElement el p [
H.div {className: "panel-heading"} H.div {className: "panel-heading"}
[ -- H.h1 {className : "col-md-12"} [H.text "Settings Box"] [ -- H.h1 {className : "col-md-12"} [H.text "Settings Box"]
H.div {className: "row" } H.div {className: "row" }
[ H.div {className: "col-md-10"} [ renameBox d {id, name} renameBoxOpen ] [ H.div {className: "col-md-8"} [ renameBox d {id, name} renameBoxOpen ]
, if edit then editIcon renameBoxOpen else H.div {} [] , if edit then editIcon renameBoxOpen else H.div {} []
, H.div {className: "col-md-1"} , H.div {className: "col-md-1"}
[ H.a { "type" : "button" [ H.a { "type" : "button"
...@@ -263,7 +268,6 @@ buttonClick ({id,name,nodeType,action} /\ setNodePopup) _ todo@(Documentation x) ...@@ -263,7 +268,6 @@ buttonClick ({id,name,nodeType,action} /\ setNodePopup) _ todo@(Documentation x)
buttonClick ({id,name,nodeType,action} /\ setNodePopup) d Delete = H.div {className: "col-md-2"} buttonClick ({id,name,nodeType,action} /\ setNodePopup) d Delete = H.div {className: "col-md-2"}
[ H.a { style: iconAStyle [ H.a { style: iconAStyle
, className: "btn glyphitem glyphicon glyphicon-trash" <> if action == (Just Delete) then " active" else "" , className: "btn glyphitem glyphicon glyphicon-trash" <> if action == (Just Delete) then " active" else ""
--, className: (glyphicon "trash")
, id: "delete" , id: "delete"
, title: "Delete" , title: "Delete"
, onClick: mkEffectFn1 $ \_ -> setNodePopup $ const {id, name, nodeType, action : Just Delete} , onClick: mkEffectFn1 $ \_ -> setNodePopup $ const {id, name, nodeType, action : Just Delete}
...@@ -283,6 +287,18 @@ buttonClick (node@{action} /\ setNodePopup) d (Add xs) = H.div {className: "col- ...@@ -283,6 +287,18 @@ buttonClick (node@{action} /\ setNodePopup) d (Add xs) = H.div {className: "col-
} }
[] []
] ]
--{-
buttonClick ({id,name,nodeType,action} /\ setNodePopup) d SearchBox = H.div {className: "col-md-2"}
[ H.a { style: iconAStyle
, className: "btn glyphitem glyphicon glyphicon-search" <> if action == (Just SearchBox) then " active" else ""
, id: "search"
, title: "Search and create " <> show nodeType
, onClick: mkEffectFn1 $ \_ -> setNodePopup $ const {id, name, nodeType, action : Just SearchBox}
}
[]
]
--}
{- {-
...@@ -329,8 +345,11 @@ panelAction :: (Action -> Aff Unit) ...@@ -329,8 +345,11 @@ panelAction :: (Action -> Aff Unit)
-> Record NodePopupProps -> Record NodePopupProps
-> R.State (Maybe NodePopup) -> R.State (Maybe NodePopup)
-> R.Element -> R.Element
panelAction d {id,name,nodeType,action} p = case action of panelAction d {id,name,nodeType,action, session} p = case action of
(Just (Documentation x)) -> R.fragment [ H.div {} [H.text $ "More information on" <> show nodeType]] (Just (Documentation x)) -> R.fragment [ H.div {} [H.text $ "More information on" <> show nodeType]]
(Just SearchBox) -> R.fragment [ searchBar {session, databases:allDatabases}
, H.div {} [ H.text $ "Search and create a private corpus with the search query as corpus name." ]
]
(Just Delete) -> case nodeType of (Just Delete) -> case nodeType of
NodeUser -> R.fragment [ H.div {} [H.text "Yes, we are RGPD compliant! But you can not delete User Node yet (we are still on development). Thanks for your comprehensin."]] NodeUser -> R.fragment [ H.div {} [H.text "Yes, we are RGPD compliant! But you can not delete User Node yet (we are still on development). Thanks for your comprehensin."]]
_ -> R.fragment [ H.div {} [H.text "Are your sure you want to delete, if yes, click again ?"], reallyDelete d] _ -> R.fragment [ H.div {} [H.text "Are your sure you want to delete, if yes, click again ?"], reallyDelete d]
......
...@@ -24,21 +24,13 @@ searchBar :: Record Props -> R.Element ...@@ -24,21 +24,13 @@ searchBar :: Record Props -> R.Element
searchBar props = R.createElement searchBarCpt props [] searchBar props = R.createElement searchBarCpt props []
searchBarCpt :: R.Component Props searchBarCpt :: R.Component Props
searchBarCpt = R.hooksComponent "G.C.Search.SearchBar.searchBar" cpt searchBarCpt = R.hooksComponent "G.C.Node.SearchBar.searchBar" cpt
where where
cpt {session, databases} _ = do cpt {session, databases} _ = do
open <- R.useState' false
search <- R.useState' Nothing search <- R.useState' Nothing
onSearchChange session search onSearchChange session search
pure $ H.div { className: "search-bar-container pull-right" } pure $ H.div { className: "" } [ searchField {databases, search }]
[ toggleButton open
, searchFieldContainer open databases search ]
searchFieldContainer :: R.State Boolean -> Array Database -> R.State (Maybe Search) -> R.Element
searchFieldContainer (open /\ _) databases search =
H.div { className: "search-bar " <> openClass } [ searchField { databases, search } ]
where
openClass = if open then "open" else "closed"
onSearchChange :: Session -> R.State (Maybe Search) -> R.Hooks Unit onSearchChange :: Session -> R.State (Maybe Search) -> R.Hooks Unit
onSearchChange session (search /\ setSearch) = onSearchChange session (search /\ setSearch) =
...@@ -46,19 +38,19 @@ onSearchChange session (search /\ setSearch) = ...@@ -46,19 +38,19 @@ onSearchChange session (search /\ setSearch) =
where where
triggerSearch q = triggerSearch q =
launchAff_ $ do launchAff_ $ do
liftEffect $ do liftEffect $ do
log2 "Searching db: " $ show q.database log2 "Searching db: " $ show q.database
log2 "Searching term: " q.term log2 "Searching term: " q.term
r <- (performSearch session $ searchQuery q) :: Aff Unit r <- (performSearch session $ searchQuery q) :: Aff Unit
liftEffect $ do liftEffect $ do
log2 "Return:" r log2 "Return:" r
modalShow "addCorpus" modalShow "addCorpus"
searchQuery {database: Nothing, term} = over SearchQuery (_ {query=term}) defaultSearchQuery
searchQuery {database: Just db, term} = over SearchQuery (_ {databases=[db], query=term}) defaultSearchQuery
toggleButton :: R.State Boolean -> R.Element searchQuery {database: Nothing, term} =
toggleButton open = over SearchQuery (_ {query=term}) defaultSearchQuery
H.button { on: {click: \_ -> (snd open) not}, className: "search-bar-toggle" }
[ H.i { className: "material-icons md-24", style } [ H.text "control_point" ] ]
where style = { marginTop: "-2px", color: "#000" }
searchQuery {database: Just db, term} =
over SearchQuery (_ {databases=[db], query=term}) defaultSearchQuery
...@@ -5,16 +5,18 @@ import Prelude (bind, const, identity, pure, show, ($), (/=), (<$>), (||)) ...@@ -5,16 +5,18 @@ 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 Gargantext.Utils.Reactix as R2
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 (text, button, div, input, span, ul, li, a) import Reactix.DOM.HTML (text, button, div, input, span, ul, li, a, option)
import Gargantext.Components.Search.Types (Database) import Gargantext.Components.Search.Types (Database(..), readDatabase)
select select :: forall props.
:: forall props R.IsComponent String props (Array R.Element)
. R.IsComponent String props (Array R.Element) => Record props
=> Record props -> Array R.Element -> R.Element -> Array R.Element
-> R.Element
select = R.createElement "select" select = R.createElement "select"
type Search = { database :: Maybe Database, term :: String } type Search = { database :: Maybe Database, term :: String }
...@@ -33,7 +35,8 @@ searchField :: Record Props -> R.Element ...@@ -33,7 +35,8 @@ searchField :: Record Props -> R.Element
searchField p = R.createElement searchFieldComponent p [] searchField p = R.createElement searchFieldComponent p []
placeholder :: String placeholder :: String
placeholder = "Query, URL or FILE (works with Firefox or Chromium browsers)" placeholder = "Query, URL or FILE"
-- TODO add elsewhere "(works with Firefox or Chromium browsers)"
searchFieldComponent :: R.Memo Props searchFieldComponent :: R.Memo Props
searchFieldComponent = R.memo (R.hooksComponent "SearchField" cpt) hasChanged searchFieldComponent = R.memo (R.hooksComponent "SearchField" cpt) hasChanged
...@@ -44,30 +47,31 @@ searchFieldComponent = R.memo (R.hooksComponent "SearchField" cpt) hasChanged ...@@ -44,30 +47,31 @@ searchFieldComponent = R.memo (R.hooksComponent "SearchField" cpt) hasChanged
db <- R.useState' (Nothing :: Maybe Database) db <- R.useState' (Nothing :: Maybe Database)
pure $ pure $
div { className: "search-field input-group" } div { className: "search-field input-group" }
[ databaseInput db props.databases [ searchInput term
, searchInput term , databaseInput db props.databases
, span { className: "input-group-btn" } , span { className: "input-group-btn" } [ submitButton db term props.search ]
[ submitButton db term props.search ]
] ]
hasChanged p p' = (fst p.search /= fst p'.search) || (p.databases /= p'.databases) hasChanged p p' = (fst p.search /= fst p'.search)
|| (p.databases /= p'.databases)
databaseInput :: R.State (Maybe Database) -> Array Database -> R.Element databaseInput :: R.State (Maybe Database) -> Array Database -> R.Element
databaseInput (db /\ setDB) dbs = databaseInput (db /\ setDB) dbs =
div { className: "input-group-btn search-panel dropdown" } R.fragment [ div { className: "form-group" }
[ dropdownBtn db [ R2.select { className: "form-control"
, ul {className: "dropdown-menu", role: "menu"} (liItem <$> dbs) , onChange: mkEffectFn1
$ \e -> setDB
$ const
$ readDatabase
$ e .. "target" .. "value"
} (liItem <$> dbs)
]
] ]
where where
liItem db' = li { onClick } [ a {href: "#"} [text (show db') ] ] liItem :: Database -> R.Element
where liItem db = option {} [ text (show db) ]
onClick = mkEffectFn1 $ \_ -> setDB $ const $ Just db'
dropdownBtnProps = { id: "search-dropdown"
, className: "btn btn-default dropdown-toggle"
, type: "button"
, data: {toggle: "dropdown"}
}
dropdownBtn (Just db') = button dropdownBtnProps [ span {} [ text (show db') ] ]
dropdownBtn (Nothing) = button dropdownBtnProps [ span {} [ text "-" ] ]
searchInput :: R.State String -> R.Element searchInput :: R.State String -> R.Element
searchInput (term /\ setTerm) = searchInput (term /\ setTerm) =
......
...@@ -24,7 +24,8 @@ allDatabases = [All, PubMed ...@@ -24,7 +24,8 @@ allDatabases = [All, PubMed
, HAL_FR , HAL_FR
, IsTex_EN , IsTex_EN
, IsTex_FR , IsTex_FR
, Isidore_EN, Isidore_FR] , Isidore_EN, Isidore_FR
]
data Database = All | PubMed data Database = All | PubMed
| HAL_EN | HAL_FR | HAL_EN | HAL_FR
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment