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
5f71811d
Commit
5f71811d
authored
Feb 10, 2022
by
arturo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[graph] Graph search completion issue
* #364
parent
405eea77
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
78 additions
and
36 deletions
+78
-36
Search.purs
src/Gargantext/Components/GraphExplorer/Search.purs
+6
-7
InputWithAutocomplete.purs
src/Gargantext/Components/InputWithAutocomplete.purs
+72
-29
No files found.
src/Gargantext/Components/GraphExplorer/Search.purs
View file @
5f71811d
...
...
@@ -2,19 +2,19 @@ module Gargantext.Components.GraphExplorer.Search
( Props, nodeSearchControl ) where
import Prelude
import DOM.Simple.Console (log2)
import Data.Foldable (foldl)
import Data.Sequence as Seq
import Data.Set as Set
import DOM.Simple.Console (log2)
import Effect (Effect)
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
import Gargantext.Components.InputWithAutocomplete (inputWithAutocomplete)
import Gargantext.Hooks.Sigmax.Types as SigmaxT
import Gargantext.Utils (queryMatchesLabel)
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.GraphExplorer.Search"
...
...
@@ -29,7 +29,7 @@ type Props = (
-- Searches given node and matches it's label or any of the children's labels.
nodeMatchesSearch :: String -> Record SigmaxT.Node -> Boolean
nodeMatchesSearch s n@{ children } =
foldl (\
acc
childLabel -> queryMatchesLabel s childLabel) initial children
foldl (\
_
childLabel -> queryMatchesLabel s childLabel) initial children
where
initial = queryMatchesLabel s n.label
...
...
@@ -79,4 +79,3 @@ triggerSearch graph search multiSelectEnabled selectedNodeIds = do
T.modify_ (\nodes ->
Set.union matching $ if multiSelectEnabled then nodes else SigmaxT.emptyNodeIds) selectedNodeIds
src/Gargantext/Components/InputWithAutocomplete.purs
View file @
5f71811d
...
...
@@ -2,14 +2,14 @@ module Gargantext.Components.InputWithAutocomplete where
import Prelude
import DOM.Simple (contains)
import DOM.Simple as DOM
import DOM.Simple.Event as DE
import Data.Maybe (Maybe(..))
import Data.Maybe (Maybe(..)
, maybe
)
import Data.Nullable (Nullable, null, toMaybe)
import Effect (Effect)
import
Effect.Timer (setTimeout
)
import
FFI.Simple ((..)
)
import Gargantext.Utils.Reactix as R2
import React.SyntheticEvent as E
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
...
...
@@ -34,43 +34,72 @@ inputWithAutocomplete = R.createElement inputWithAutocompleteCpt
inputWithAutocompleteCpt :: R.Component Props
inputWithAutocompleteCpt = here.component "inputWithAutocomplete" cpt
where
cpt props@{ autocompleteSearch
, classes
, onAutocompleteClick
, onEnterPress
, state } _ = do
state' <- T.useLive T.unequal state
inputRef <- R.useRef null
completions <- T.useBox $ autocompleteSearch state'
let onFocus completions' _ = T.write_ (autocompleteSearch state') completions'
cpt { autocompleteSearch
, classes
, onAutocompleteClick
, onEnterPress
, state } _ = do
-- States
state' <- T.useLive T.unequal state
containerRef <- R.useRef null
inputRef <- R.useRef null
completions <- T.useBox $ autocompleteSearch state'
-- Render
pure $
H.span { className: "input-with-autocomplete " <> classes }
H.div
{ className: "input-with-autocomplete " <> classes
, ref: containerRef
}
[
completionsCpt { completions, onAutocompleteClick, state } []
, H.input { type: "text"
, ref: inputRef
, className: "form-control"
, value: state'
, on: { blur: onBlur completions
, focus: onFocus completions
, on: { focus: onFocus completions state'
, input: onInput completions
, change: onInput completions
, keyUp: onInputKeyUp inputRef } }
, keyUp: onInputKeyUp inputRef
, blur: onBlur completions containerRef
}
}
]
-- Helpers
where
-- (!) `onBlur` DOM.Event is triggered before any `onClick` DOM.Event
-- So when a completion is being clicked, the UX will be broken
--
-- ↳ As a solution we chose to check if the click is made from
-- the autocompletion list
onBlur :: forall event.
T.Box Completions
-> R.Ref (Nullable DOM.Element)
-> event
-> Effect Unit
onBlur completions containerRef event =
if isInnerEvent
then
pure $ (event .. "preventDefault")
else
T.write_ [] completions
-- setTimeout is a bit of a hack here -- clicking on autocomplete
-- element will clear out the blur first, so the autocomplete click
-- won't fire without a timeout here. However, blur is very handy and
-- handles automatic autocomplete search, otherwise I'd have to hide it
-- in various different places (i.e. carefully handle all possible
-- events where blur happens and autocomplete should hide).
onBlur completions _ = setTimeout 100 $ do
T.write_ [] completions
where
mContains = do
a <- toMaybe $ R.readRef containerRef
b <- toMaybe (event .. "relatedTarget")
Just (contains a b)
isInnerEvent = maybe false identity mContains
onFocus :: forall event. T.Box Completions -> String -> event -> Effect Unit
onFocus completions st _ = T.write_ (autocompleteSearch st) completions
onInput :: forall event. T.Box Completions -> event -> Effect Unit
onInput completions e = do
let val = R.unsafeEventValue e
T.write_ val state
...
...
@@ -93,10 +122,14 @@ inputWithAutocompleteCpt = here.component "inputWithAutocomplete" cpt
else
pure $ false
---------------------------------------------------------
type CompletionsProps =
( completions :: T.Box Completions
( completions
:: T.Box Completions
, onAutocompleteClick :: String -> Effect Unit
, state :: T.Box String
, state
:: T.Box String
)
completionsCpt :: R2.Component CompletionsProps
...
...
@@ -106,19 +139,29 @@ completionsCptCpt :: R.Component CompletionsProps
completionsCptCpt = here.component "completionsCpt" cpt
where
cpt { completions, onAutocompleteClick, state } _ = do
-- State
completions' <- T.useLive T.unequal completions
let className = "completions " <> (if completions' == [] then "d-none" else "")
pure $ H.div { className }
-- Render
pure $
H.div
{ className }
[
H.div { className: "list-group" } (cCpt <$> completions')
]
-- Helpers
where
cCpt c =
H.button { type: "button"
, className: "list-group-item"
, on: { click: onClick c } } [ H.text c ]
onClick c _ = do
T.write_ c state
T.write_ [] completions
onAutocompleteClick 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