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
da40ef0e
Commit
da40ef0e
authored
Jun 01, 2023
by
Alexandre Delanoë
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/506-dev-search-in-tree' into dev
parents
9db7a548
7ff9fc76
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
266 additions
and
2 deletions
+266
-2
bootstrap-darkster.css
dist/styles/bootstrap-darkster.css
+6
-0
bootstrap-default.css
dist/styles/bootstrap-default.css
+6
-0
bootstrap-greyson.css
dist/styles/bootstrap-greyson.css
+6
-0
bootstrap-herbie.css
dist/styles/bootstrap-herbie.css
+6
-0
bootstrap-monotony.css
dist/styles/bootstrap-monotony.css
+6
-0
Store.purs
src/Gargantext/Components/App/Store.purs
+3
-0
Forest.purs
src/Gargantext/Components/Forest.purs
+28
-1
Router.purs
src/Gargantext/Components/Router.purs
+11
-1
TreeSearch.purs
src/Gargantext/Components/TreeSearch.purs
+185
-0
Routes.purs
src/Gargantext/Routes.purs
+3
-0
_legacy.sass
src/sass/_legacy.sass
+1
-0
_search.sass
src/sass/_legacy/_search.sass
+5
-0
No files found.
dist/styles/bootstrap-darkster.css
View file @
da40ef0e
...
...
@@ -12251,6 +12251,12 @@ select.form-control {
height
:
auto
;
}
.search-modal__results
{
height
:
14em
;
overflow-x
:
hidden
;
overflow-y
:
scroll
;
}
.dropdown-menu
{
background-color
:
#181A1B
;
}
...
...
dist/styles/bootstrap-default.css
View file @
da40ef0e
...
...
@@ -12052,6 +12052,12 @@ select.form-control {
height
:
auto
;
}
.search-modal__results
{
height
:
14em
;
overflow-x
:
hidden
;
overflow-y
:
scroll
;
}
.btn-secondary
,
.btn-secondary
:hover
,
.btn-outline-secondary
:not
(
:disabled
)
:not
(
.disabled
)
:hover
,
...
...
dist/styles/bootstrap-greyson.css
View file @
da40ef0e
...
...
@@ -11817,4 +11817,10 @@ select.form-control {
height
:
auto
;
}
.search-modal__results
{
height
:
14em
;
overflow-x
:
hidden
;
overflow-y
:
scroll
;
}
/*# sourceMappingURL=bootstrap-greyson.css.map */
dist/styles/bootstrap-herbie.css
View file @
da40ef0e
...
...
@@ -12065,4 +12065,10 @@ select.form-control {
height
:
auto
;
}
.search-modal__results
{
height
:
14em
;
overflow-x
:
hidden
;
overflow-y
:
scroll
;
}
/*# sourceMappingURL=bootstrap-herbie.css.map */
dist/styles/bootstrap-monotony.css
View file @
da40ef0e
...
...
@@ -12066,4 +12066,10 @@ select.form-control {
height
:
auto
;
}
.search-modal__results
{
height
:
14em
;
overflow-x
:
hidden
;
overflow-y
:
scroll
;
}
/*# sourceMappingURL=bootstrap-monotony.css.map */
src/Gargantext/Components/App/Store.purs
View file @
da40ef0e
...
...
@@ -55,6 +55,7 @@ type Store =
, showCorpus :: T.Box Boolean
, showLogin :: T.Box Boolean
, showTree :: T.Box Boolean
, showSearch :: T.Box Boolean
, sidePanelLists :: T.Box (Maybe (Record ListsT.SidePanel))
, sidePanelTexts :: T.Box (Maybe (Record TextsT.SidePanel))
, sidePanelState :: T.Box SidePanelState
...
...
@@ -82,6 +83,7 @@ type State =
, showCorpus :: Boolean
, showLogin :: Boolean
, showTree :: Boolean
, showSearch :: Boolean
, sidePanelLists :: Maybe (Record ListsT.SidePanel)
, sidePanelTexts :: Maybe (Record TextsT.SidePanel)
, sidePanelState :: SidePanelState
...
...
@@ -110,6 +112,7 @@ options =
, showCorpus : false
, showLogin : false
, showTree : true
, showSearch : false
, sidePanelLists : ListsT.initialSidePanel
, sidePanelTexts : TextsT.initialSidePanel
, sidePanelState : InitialClosed
...
...
src/Gargantext/Components/Forest.purs
View file @
da40ef0e
...
...
@@ -84,7 +84,7 @@ plus :: R2.Leaf Plus
plus = R2.leaf plusCpt
plusCpt :: R.Component Plus
plusCpt = here.component "plus" cpt where
cpt { boxes: { backend, showLogin, pinnedTreeId} } _ = do
cpt { boxes: { backend, showLogin,
showSearch,
pinnedTreeId} } _ = do
-- Hooks
{ goToRoute } <- useLinkHandler
...
...
@@ -98,6 +98,7 @@ plusCpt = here.component "plus" cpt where
-- Render
pure $
R.fragment [
H.div
{ className: "forest-layout__action" }
[
...
...
@@ -154,6 +155,32 @@ plusCpt = here.component "plus" cpt where
]
}
]
,
H.div
{ className: "forest-layout__action" }
[
B.tooltipContainer
{ delayShow: 600
, position: TooltipPosition Right
, tooltipSlot:
B.span_ "Search in tree"
, defaultSlot:
B.button
{ className: "forest-layout__action__button"
, callback: \_ -> T.write_ true showSearch
, variant: ButtonVariant Light
}
[
B.icon
{ name: "search"}
,
B.wad_ [ "d-inline-block", "w-1" ]
,
H.text $ "Search"
]
}
]
]
--, H.div { "type": "", className: "fa fa-plus-circle fa-lg"} []
--, H.div { "type": "", className: "fa fa-minus-circle fa-lg"} []
-- TODO same as the one in the Login Modal (same CSS)
...
...
src/Gargantext/Components/Router.purs
View file @
da40ef0e
...
...
@@ -24,14 +24,15 @@ import Gargantext.Components.Nodes.Corpus.Code (corpusCodeLayout)
import Gargantext.Components.Nodes.Corpus.Dashboard (dashboardLayout)
import Gargantext.Components.Nodes.Corpus.Document as Document
import Gargantext.Components.Nodes.Corpus.Phylo as Phylo
import Gargantext.Components.Nodes.Graph as Graph
import Gargantext.Components.Nodes.File (fileLayout)
import Gargantext.Components.Nodes.Frame as Frame
import Gargantext.Components.Nodes.Graph as Graph
import Gargantext.Components.Nodes.Home (homeLayout)
import Gargantext.Components.Nodes.Lists as Lists
import Gargantext.Components.Nodes.Texts as Texts
import Gargantext.Components.Tile (tileBlock)
import Gargantext.Components.TopBar as TopBar
import Gargantext.Components.TreeSearch (treeSearch)
import Gargantext.Config (defaultFrontends, defaultBackends)
import Gargantext.Context.Session as SessionContext
import Gargantext.Ends (Backend)
...
...
@@ -100,6 +101,8 @@ routerCpt = here.component "router" cpt where
{ className: "router" }
[
login' boxes
,
treeSearch' boxes
,
TopBar.component
{}
...
...
@@ -318,6 +321,7 @@ renderRouteCpt = R.memo' $ here.component "renderRoute" cpt where
GR.Home -> home { boxes } []
GR.Lists s n -> lists (sessionNodeProps s n) []
GR.Login -> login' boxes
GR.TreeFlat _ _ _ -> treeSearch' boxes
GR.PGraphExplorer s g -> graphExplorer (sessionNodeProps s g) []
GR.PhyloExplorer s g -> phyloExplorer (sessionNodeProps s g) []
GR.RouteFile s n -> routeFile (sessionNodeProps s n) []
...
...
@@ -599,6 +603,12 @@ login' { backend, sessions, showLogin: visible } =
--------------------------------------------------------------
treeSearch' :: Boxes -> R.Element
treeSearch' { sessions, showSearch: visible } =
treeSearch { sessions, visible }
--------------------------------------------------------------
routeFile :: R2.Component SessionNodeProps
routeFile = R.createElement routeFileCpt
routeFileCpt :: R.Component SessionNodeProps
...
...
src/Gargantext/Components/TreeSearch.purs
0 → 100644
View file @
da40ef0e
module Gargantext.Components.TreeSearch where
import Gargantext.Prelude
import Data.Array (head)
import Data.Maybe (Maybe(..), fromMaybe)
import Effect (Effect)
import Gargantext.Components.Bootstrap (formSelect')
import Gargantext.Components.Bootstrap as B
import Gargantext.Components.Bootstrap.Types (ButtonVariant(..), ModalSizing(..), Position(..), TooltipPosition(..), Variant(..))
import Gargantext.Components.InputWithEnter (inputWithEnter)
import Gargantext.Config.REST (AffRESTError, logRESTError)
import Gargantext.Hooks.LinkHandler (useLinkHandler)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Routes (AppRoute(..), appPath, nodeTypeAppRoute)
import Gargantext.Sessions (Session(..), Sessions, get, sessionId, unSessions)
import Gargantext.Sessions.Types (Session)
import Gargantext.Types (NodeID, NodeType, getIcon)
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
here :: R2.Here
here = R2.here "Gargantext.Components.TreeSearch"
type Props = (
visible :: T.Box Boolean
, sessions :: T.Box Sessions
)
type StateProps = (
visible :: T.Box Boolean
, sessions :: Sessions
, query :: T.Box String
)
type WrapperProps = (
visible :: T.Box Boolean
, sessions :: Sessions
, session :: T.Box (Maybe Session)
, query :: T.Box String
)
type ContainerProps = ( visible :: T.Box Boolean, session :: Session, query :: String)
type RenderContainerProps = ( visible :: T.Box Boolean, session :: Session, searchData :: Array SearchData )
type RenderProps = ( visible :: T.Box Boolean
, session :: Session
, searchData :: Array SearchData
, goToRoute :: AppRoute -> Effect Unit )
type SearchData = { name :: String
, type :: NodeType
, id :: NodeID
}
treeSearch :: R2.Leaf Props
treeSearch = R2.leaf treeSearchCpt
treeSearchCpt :: R.Component Props
treeSearchCpt = here.component "treeSearch" cpt where
cpt { sessions, visible } _ = do
sessions' <- T.useLive T.unequal sessions
query <- T.useBox ""
inputRef <- R.useRef ""
pure $
B.baseModal
{ isVisibleBox: visible
, title: Just "Tree Search"
, size: MediumModalSize
, modalClassName: ""
}
[ inputWithEnter { className: "form-control"
, autoFocus: true
, onEnter: submit inputRef query
, onValueChanged: R.setRef inputRef
, onBlur: R.setRef inputRef
, type: "value"
, defaultValue: ""
, placeholder: "Search..."
}
, treeSearchState {visible, query, sessions: sessions'} ]
where
submit ref box _ = T.write_ (R.readRef ref) box
treeSearchState :: R2.Leaf StateProps
treeSearchState = R2.leaf treeSearchStateCpt
treeSearchStateCpt :: R.Component StateProps
treeSearchStateCpt = here.component "treeSearchState" cpt where
cpt { query, sessions, visible } _ = do
session <- T.useBox $ head $ unSessions sessions
pure $ treeSearchWrapper { query, visible, session, sessions}
treeSearchWrapper :: R2.Leaf WrapperProps
treeSearchWrapper = R2.leaf treeSearchWrapperCpt
treeSearchWrapperCpt :: R.Component WrapperProps
treeSearchWrapperCpt = here.component "treeSearchWrapper" cpt where
cpt { query, visible, sessions, session } _ = do
session' <- T.useLive T.unequal session
query' <- T.useLive T.unequal query
case session' of
Just s ->
pure $ R.fragment [
formSelect'
{ callback: \v -> T.write_ (Just v) session
, list: unSessions sessions
, value: s
} []
,
if query' == "" then
H.div {className: "search-modal__results"} [B.span_ "Enter your search query..."]
else
treeSearchContainer {query: query', visible, session: s}
]
Nothing -> pure $ H.div {} []
treeSearchContainer :: R2.Leaf ContainerProps
treeSearchContainer = R2.leaf treeSearchContainerCpt
treeSearchContainerCpt :: R.Component ContainerProps
treeSearchContainerCpt = here.component "treeSearchContainerCpt" cpt where
cpt {query, visible, session } _ = do
useLoader { errorHandler
, path: { session, query }
, loader: loadSearch
, render: \searchData -> treeSearchRenderContainer { visible, session, searchData }
}
where
errorHandler = logRESTError here "[treeSearchContainer]"
treeSearchRenderContainer :: R2.Leaf RenderContainerProps
treeSearchRenderContainer = R2.leaf treeSearchRenderContainerCpt
treeSearchRenderContainerCpt :: R.Component RenderContainerProps
treeSearchRenderContainerCpt = here.component "treeSearchRenderContainer" cpt where
cpt { visible, session, searchData } _ = do
{ goToRoute } <- useLinkHandler
pure $ treeSearchRender { visible, session, searchData, goToRoute }
treeSearchRender :: R2.Leaf RenderProps
treeSearchRender = R2.leaf treeSearchRenderCpt
treeSearchRenderCpt :: R.Component RenderProps
treeSearchRenderCpt = here.component "treeSearchRenderCpt" cpt where
cpt { visible, session, searchData, goToRoute } _ = do
pure $ H.div {className: "search-modal__results"} (results searchData)
where
results s = map searchResult s
where
searchResult sd = H.div
{ className: "forest-layout__action"}
[
B.tooltipContainer
{ delayShow: 600
, position: TooltipPosition Right
, tooltipSlot: B.span_ $ show $ fromMaybe Home $ nodeTypeAppRoute sd.type (sessionId session) sd.id
, defaultSlot:
B.button
{ className: "forest-layout__action__button"
, callback: \_ -> do
T.write_ false visible
goToRoute $ fromMaybe Home $ nodeTypeAppRoute sd.type (sessionId session) sd.id
, variant: ButtonVariant Light }
[
B.icon {name: getIcon sd.type true}
, B.wad_ [ "d-inline-block", "w-1" ]
, H.text sd.name
]
}
]
type LoadProps = ( session :: Session, query :: String )
loadSearch :: Record LoadProps -> AffRESTError (Array SearchData)
loadSearch { session: s, query: q} = get s $ appPath (TreeFlat (sessionId s) (sessionRoot s) q)
where sessionRoot (Session {treeId}) = treeId
src/Gargantext/Routes.purs
View file @
da40ef0e
...
...
@@ -23,6 +23,7 @@ data AppRoute
| Home
| Lists SessionId Int
| Login
| TreeFlat SessionId Int String
| PGraphExplorer SessionId Int
| PhyloExplorer SessionId Int
| RouteFile SessionId Int
...
...
@@ -40,6 +41,7 @@ derive instance Eq AppRoute
instance Show AppRoute where
show Home = "Home"
show Login = "Login"
show (TreeFlat s i _) = "treeflat" <> show i <> " (" <> show s <> ")"
show (ForgotPassword u) = "ForgotPassword" <> show u
show (Folder s i) = "Folder" <> show i <> " (" <> show s <> ")"
show (FolderPrivate s i) = "FolderPrivate" <> show i <> " (" <> show s <> ")"
...
...
@@ -68,6 +70,7 @@ instance Show AppRoute where
appPath :: AppRoute -> String
appPath Home = ""
appPath Login = "login"
appPath (TreeFlat _ i q) = "treeflat/" <> show i <> "?query=" <> q
appPath (ForgotPassword u) = "forgotPassword/" <> show u
appPath (Folder s i) = "folder/" <> show s <> "/" <> show i
appPath (FolderPrivate s i) = "folderPrivate/" <> show s <> "/" <> show i
...
...
src/sass/_legacy.sass
View file @
da40ef0e
...
...
@@ -12,3 +12,4 @@
@import
"./_legacy/_folder"
@import
"./_legacy/_corpus"
@import
"./_legacy/_annuaire"
@import
"./_legacy/_search"
src/sass/_legacy/_search.sass
0 → 100644
View file @
da40ef0e
.search-modal
&
__results
height
:
14em
overflow-x
:
hidden
overflow-y
:
scroll
\ No newline at end of file
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