Search.purs 2.78 KB
Newer Older
1
module Gargantext.Components.GraphExplorer.Search
2
  ( Props, nodeSearchControl ) where
3 4

import Prelude
5
import Data.Sequence as Seq
6 7
import Data.Set as Set
import Data.Tuple.Nested ((/\))
8
import DOM.Simple.Console (log2)
9 10 11
import Effect (Effect)
import Reactix as R
import Reactix.DOM.HTML as H
12
import Toestand as T
13

14
import Gargantext.Components.InputWithAutocomplete (inputWithAutocomplete)
15
import Gargantext.Hooks.Sigmax.Types as SigmaxT
16 17 18
import Gargantext.Utils (queryMatchesLabel)
import Gargantext.Utils.Reactix as R2

19
here :: R2.Here
20
here = R2.here "Gargantext.Components.GraphExplorer.Search"
21 22

type Props = (
23
    graph              :: SigmaxT.SGraph
24 25
  , multiSelectEnabled :: T.Box Boolean
  , selectedNodeIds    :: T.Box SigmaxT.NodeIds
26 27
  )

28
-- | Whether a node matches a search string
29
nodeMatchesSearch :: String -> Record SigmaxT.Node -> Boolean
30
nodeMatchesSearch s n = queryMatchesLabel s n.label
31

32
searchNodes :: String -> Seq.Seq (Record SigmaxT.Node) -> Seq.Seq (Record SigmaxT.Node)
33 34
searchNodes "" _ = Seq.empty
searchNodes s nodes = Seq.filter (nodeMatchesSearch s) nodes
35

36 37
nodeSearchControl :: R2.Component Props
nodeSearchControl = R.createElement sizeButtonCpt
38 39

sizeButtonCpt :: R.Component Props
40
sizeButtonCpt = here.component "nodeSearchControl" cpt
41
  where
42
    cpt { graph, multiSelectEnabled, selectedNodeIds } _ = do
43 44
      search <- T.useBox ""
      search' <- T.useLive T.unequal search
45
      multiSelectEnabled' <- T.useLive T.unequal multiSelectEnabled
46

47 48 49 50 51 52 53 54 55 56 57
      pure $ R.fragment
        [ inputWithAutocomplete { autocompleteSearch: autocompleteSearch graph
                                , classes: "mx-2"
                                , onAutocompleteClick: \s -> triggerSearch graph s multiSelectEnabled' selectedNodeIds
                                , onEnterPress: \s -> triggerSearch graph s multiSelectEnabled' selectedNodeIds
                                , state: search } []
        , H.div { className: "btn input-group-addon"
                , on: { click: \_ -> triggerSearch graph search' multiSelectEnabled' selectedNodeIds }
                }
          [ H.span { className: "fa fa-search" } [] ]
        ]
58

59
autocompleteSearch :: SigmaxT.SGraph -> String -> Array String
60 61
autocompleteSearch graph s = Seq.toUnfoldable $ (_.label) <$> searchNodes s nodes
  where
62
    nodes = SigmaxT.graphNodes graph
63

64
triggerSearch :: SigmaxT.SGraph
65
              -> String
66
              -> Boolean
67
              -> T.Box SigmaxT.NodeIds
68
              -> Effect Unit
69
triggerSearch graph search multiSelectEnabled selectedNodeIds = do
70
  let graphNodes = SigmaxT.graphNodes graph
71
  let matching = Set.fromFoldable $ (_.id) <$> searchNodes search graphNodes
72

73
  log2 "[triggerSearch] search" search
74

75
  T.modify_ (\nodes ->
76
    Set.union matching $ if multiSelectEnabled then nodes else SigmaxT.emptyNodeIds) selectedNodeIds