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

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

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

thisModule = "Gargantext.Components.GraphExplorer.Search"
21 22

type Props = (
23
    graph           :: SigmaxT.SGraph
24
  , multiSelectEnabled :: R.State Boolean
25
  , selectedNodeIds :: R.State 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 38 39
nodeSearchControl :: Record Props -> R.Element
nodeSearchControl props = R.createElement sizeButtonCpt props []

sizeButtonCpt :: R.Component Props
40
sizeButtonCpt = R.hooksComponentWithModule thisModule "nodeSearchControl" cpt
41
  where
42
    cpt {graph, multiSelectEnabled, selectedNodeIds} _ = do
43
      search@(search' /\ setSearch) <- R.useState' ""
44 45

      pure $
46 47
        H.div { className: "form-group" }
          [ H.div { className: "input-group" }
48
            [ inputWithAutocomplete { autocompleteSearch: autocompleteSearch graph
49 50
                                    , onAutocompleteClick: \s -> triggerSearch graph s multiSelectEnabled selectedNodeIds
                                    , onEnterPress: \s -> triggerSearch graph s multiSelectEnabled selectedNodeIds
51
                                    , state: search }
52
            , H.div { className: "btn input-group-addon"
53
                    , on: { click: \_ -> triggerSearch graph search' multiSelectEnabled selectedNodeIds }
54
                    }
55 56
              [ H.span { className: "fa fa-search" } [] ]
            ]
57 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 66
              -> String
              -> R.State Boolean
67
              -> R.State SigmaxT.NodeIds
68
              -> Effect Unit
69 70
triggerSearch graph search (multiSelectEnabled /\ _) (_ /\ setNodeIds) = do
  let graphNodes = SigmaxT.graphNodes graph
71
  let matching = Set.fromFoldable $ (_.id) <$> searchNodes search graphNodes
72

73
  log2 "[triggerSearch] search" search
74

75 76
  setNodeIds $ \nodes ->
    Set.union matching $ if multiSelectEnabled then nodes else SigmaxT.emptyNodeIds