Search.purs 2.66 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.Utils (queryMatchesLabel)
17
import Gargantext.Hooks.Sigmax.Types as SigmaxT
18 19

type Props = (
20
    graph           :: SigmaxT.SGraph
21
  , multiSelectEnabled :: R.State Boolean
22
  , selectedNodeIds :: R.State SigmaxT.NodeIds
23 24
  )

25
-- | Whether a node matches a search string
26
nodeMatchesSearch :: String -> Record SigmaxT.Node -> Boolean
27
nodeMatchesSearch s n = queryMatchesLabel s n.label
28

29
searchNodes :: String -> Seq.Seq (Record SigmaxT.Node) -> Seq.Seq (Record SigmaxT.Node)
30 31
searchNodes "" _ = Seq.empty
searchNodes s nodes = Seq.filter (nodeMatchesSearch s) nodes
32

33 34 35 36 37 38
nodeSearchControl :: Record Props -> R.Element
nodeSearchControl props = R.createElement sizeButtonCpt props []

sizeButtonCpt :: R.Component Props
sizeButtonCpt = R.hooksComponent "NodeSearchControl" cpt
  where
39
    cpt {graph, multiSelectEnabled, selectedNodeIds} _ = do
40
      search@(search' /\ setSearch) <- R.useState' ""
41 42

      pure $
43 44
        H.div { className: "form-group" }
          [ H.div { className: "input-group" }
45
            [ inputWithAutocomplete { autocompleteSearch: autocompleteSearch graph
46 47
                                    , onAutocompleteClick: \s -> triggerSearch graph s multiSelectEnabled selectedNodeIds
                                    , onEnterPress: \s -> triggerSearch graph s multiSelectEnabled selectedNodeIds
48
                                    , state: search }
49
            , H.div { className: "btn input-group-addon"
50
                    , on: { click: \_ -> triggerSearch graph search' multiSelectEnabled selectedNodeIds }
51
                    }
52 53
              [ H.span { className: "fa fa-search" } [] ]
            ]
54 55
          ]

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

61
triggerSearch :: SigmaxT.SGraph
62 63
              -> String
              -> R.State Boolean
64
              -> R.State SigmaxT.NodeIds
65
              -> Effect Unit
66 67
triggerSearch graph search (multiSelectEnabled /\ _) (_ /\ setNodeIds) = do
  let graphNodes = SigmaxT.graphNodes graph
68
  let matching = Set.fromFoldable $ (_.id) <$> searchNodes search graphNodes
69

70
  log2 "[triggerSearch] search" search
71

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