From 48f7bf95610285ffd63495f4d0a32c8c33402cb8 Mon Sep 17 00:00:00 2001
From: Karen Konou <konoukaren@gmail.com>
Date: Thu, 4 Jul 2024 11:29:13 +0200
Subject: [PATCH] [Graph/Phylo] doclist filtering

---
 src/Gargantext/Components/FacetsTable.purs    | 14 ++--
 .../GraphExplorer/Sidebar/DocList.purs        | 71 +++++++++++++++++--
 src/Gargantext/Components/GraphQL.purs        |  2 +-
 .../Components/GraphQL/Context.purs           |  6 +-
 .../Components/GraphQL/Endpoints.purs         |  7 +-
 src/Gargantext/Components/Nodes/Lists.purs    |  2 +-
 .../PhyloExplorer/Sidebar/DocList.purs        | 30 +++++---
 7 files changed, 107 insertions(+), 25 deletions(-)

diff --git a/src/Gargantext/Components/FacetsTable.purs b/src/Gargantext/Components/FacetsTable.purs
index f1369843..ef9fcb47 100644
--- a/src/Gargantext/Components/FacetsTable.purs
+++ b/src/Gargantext/Components/FacetsTable.purs
@@ -253,12 +253,13 @@ type PageGQLParams =
    ( corpusId    :: Int
    , params      :: T.Params
    , ngramsTerms :: Array String
-   , session     :: Session )
+   , session     :: Session
+   , logic       :: Boolean )
 
-initialPageGQL :: { corpusId :: Int, ngramsTerms :: Array String, session :: Session }
+initialPageGQL :: { corpusId :: Int, ngramsTerms :: Array String, session :: Session, logic :: Boolean }
                -> Record PageGQLParams
-initialPageGQL { corpusId, ngramsTerms, session } =
-  { corpusId, ngramsTerms, params: T.initialParams, session }
+initialPageGQL { corpusId, ngramsTerms, session, logic } =
+  { corpusId, ngramsTerms, params: T.initialParams, session, logic }
 
 
 loadPageGQL :: Record PageGQLParams -> AffRESTError Rows
@@ -266,9 +267,10 @@ loadPageGQL { corpusId
             -- NOTE: unused
             -- , params: { limit, offset, orderBy }
             , ngramsTerms
-            , session } = do
+            , session
+            , logic } = do
 
-  eResult <- GQLE.getContextsForNgrams session corpusId ngramsTerms
+  eResult <- GQLE.getContextsForNgrams session corpusId ngramsTerms logic
 
   pure $ (\res -> Docs { docs: gqlContextToDocumentsView <$> Seq.fromFoldable res }) <$> eResult
 
diff --git a/src/Gargantext/Components/GraphExplorer/Sidebar/DocList.purs b/src/Gargantext/Components/GraphExplorer/Sidebar/DocList.purs
index 1e76cf8d..cfd6faab 100644
--- a/src/Gargantext/Components/GraphExplorer/Sidebar/DocList.purs
+++ b/src/Gargantext/Components/GraphExplorer/Sidebar/DocList.purs
@@ -14,7 +14,7 @@ import Data.Set as Set
 import Data.Tuple.Nested ((/\))
 import Effect (Effect)
 import Gargantext.Components.Bootstrap as B
-import Gargantext.Components.Bootstrap.Types (Variant(..))
+import Gargantext.Components.Bootstrap.Types (ButtonVariant(..), Variant(..))
 import Gargantext.Components.FacetsTable (DocumentsView(..), Rows(..), initialPageGQL, loadPageGQL, publicationDate)
 import Gargantext.Components.GraphExplorer.Store as GraphStore
 import Gargantext.Components.GraphExplorer.Types (CorpusId, DocId, GraphSideDoc(..), ListId)
@@ -63,6 +63,8 @@ docListWrapperCpt = here.component "wrapper" cpt where
 
     selectedNgramsTerms <- T.useBox []
 
+    buttonState <- T.useBox false
+
     -- | Helpers
     -- |
     let
@@ -89,6 +91,7 @@ docListWrapperCpt = here.component "wrapper" cpt where
             , selectedNgramsTerms
             , session
             , showDoc
+            , buttonState
             }
 
           _ /\ _ ->
@@ -109,6 +112,7 @@ type ListProps =
   , selectedNgramsTerms :: T.Box (Array SigmaxT.Label)
   , session             :: Session
   , showDoc             :: T.Box (Maybe GraphSideDoc)
+  , buttonState         :: T.Box Boolean
   )
 
 docList :: R2.Leaf ListProps
@@ -132,6 +136,7 @@ docListCpt = here.component "main" cpt where
       , selectedNgramsTerms
       , session
       , showDoc
+      , buttonState
       } _ = do
     -- | States
     -- |
@@ -141,10 +146,13 @@ docListCpt = here.component "main" cpt where
 
     selectedNgramsTerms' <- T.useLive T.unequal selectedNgramsTerms
 
+    buttonState' <- R2.useLive' buttonState
+
     path' /\ path
       <- R2.useBox' $ initialPageGQL { corpusId: nodeId
                                      , ngramsTerms: A.fromFoldable selectedNgramsTerms'
-                                     , session }
+                                     , session
+                                     , logic: buttonState' }
 
     state' /\ state <-
       R2.useBox' Nothing
@@ -174,7 +182,14 @@ docListCpt = here.component "main" cpt where
     useUpdateEffect1' selectedNgramsTerms' $
       flip T.write_ path $ initialPageGQL { corpusId: nodeId
                                           , ngramsTerms: A.fromFoldable selectedNgramsTerms'
-                                          , session }
+                                          , session
+                                          , logic: buttonState' }
+
+    useUpdateEffect1' buttonState' $
+      T.write_ (initialPageGQL { corpusId: nodeId
+                               , ngramsTerms: A.fromFoldable selectedNgramsTerms'
+                               , session
+                               , logic: buttonState' }) path
 
     -- (on fetch success, extract existing docs)
     useUpdateEffect1' state' do
@@ -239,7 +254,12 @@ docListCpt = here.component "main" cpt where
 
           H.div {}
             [
-              H.h6 {} [ H.text $ show (Seq.length results) <> " related documents"]
+              H.ul { className: "flex-row list-group vertical-align-middle" } 
+              [ H.li {} [ andOrButton { state: buttonState } ]
+              , H.li {} [ H.h6 {} [ H.text $ show (Seq.length results) <> " related documents" ] ]
+              , H.li {} [ B.iconButton { name: "search", title: "Search the web", callback: \_ -> pure unit} ]
+              , H.li {} [ B.iconButton { name: "wikipedia-w", title: "Search Wikipedia", callback: \_ -> pure unit} ]
+              ]
             , H.ul
               { className: intercalate " "
                   [ "graph-doc-list"
@@ -348,3 +368,46 @@ itemCpt = here.component "item" cpt where
           ]
         ]
       ]
+
+---------------------------------------------------------
+
+type AndOrButtonProps =
+  ( state :: T.Box Boolean
+  )
+
+andOrButton :: R2.Leaf AndOrButtonProps
+andOrButton = R2.leaf andOrButtonCpt
+andOrButtonCpt :: R.Component AndOrButtonProps
+andOrButtonCpt = here.component "andOrButton" cpt
+  where
+    cpt { state } _ = do
+      state' <- R2.useLive' state
+
+      pure $
+        H.div
+        { className: intercalate " "
+            [ "btn-group"
+            , "align-items-center"
+            ]
+        , role: "group"
+        }
+        [
+          B.button
+          { className: "btn-sm"
+          , callback: \_ -> T.write_ false state
+          , variant: state' ?
+              OutlinedButtonVariant Secondary $
+              ButtonVariant Secondary
+          }
+          [ H.text "OR" ]
+        ,
+          B.button
+          { className: "btn-sm"
+          , callback: \_ -> T.write_ true state
+          , variant: state' ?
+              ButtonVariant Secondary $
+              OutlinedButtonVariant Secondary
+          }
+          [ H.text "AND" ]
+        ]
+
diff --git a/src/Gargantext/Components/GraphQL.purs b/src/Gargantext/Components/GraphQL.purs
index 816fb8f6..b6e2815a 100644
--- a/src/Gargantext/Components/GraphQL.purs
+++ b/src/Gargantext/Components/GraphQL.purs
@@ -148,7 +148,7 @@ type Schema
   = { annuaire_contacts :: { contact_id :: Int } -> Array AnnuaireContact
     , context_ngrams :: { context_id :: Int, list_id :: Int } -> Array String
     , contexts :: { context_id :: Int, node_id :: Int } -> Array GQLCTX.NodeContext
-    , contexts_for_ngrams :: { corpus_id :: Int, ngrams_terms :: Array String } -> Array GQLCTX.Context
+    , contexts_for_ngrams :: { corpus_id :: Int, ngrams_terms :: Array String, and_logic :: String } -> Array GQLCTX.Context
     , imt_schools :: {} -> Array GQLIMT.School
     , languages :: {} -> Array GQLNLP.Language
     , node_children :: { node_id :: Int, child_type :: NodeType } -> Array GQLNode.Node
diff --git a/src/Gargantext/Components/GraphQL/Context.purs b/src/Gargantext/Components/GraphQL/Context.purs
index f0de4251..74705fce 100644
--- a/src/Gargantext/Components/GraphQL/Context.purs
+++ b/src/Gargantext/Components/GraphQL/Context.purs
@@ -89,7 +89,8 @@ nodeContextQuery
 type ContextsForNgramsQuery
   = { contexts_for_ngrams :: Args
       { corpus_id    :: Var "corpus_id" Int
-      , ngrams_terms :: Var "ngrams_terms" NgramsTerms }
+      , ngrams_terms :: Var "ngrams_terms" NgramsTerms
+      , and_logic    :: Var "and_logic" String }
       { c_id                        :: Unit
       , c_score                     :: Unit
       , c_date                      :: Unit
@@ -124,7 +125,8 @@ contextsForNgramsQuery :: ContextsForNgramsQuery
 contextsForNgramsQuery
   = { contexts_for_ngrams:
       { corpus_id:    Var :: _ "corpus_id" Int
-      , ngrams_terms: Var :: _ "ngrams_terms" NgramsTerms } =>>
+      , ngrams_terms: Var :: _ "ngrams_terms" NgramsTerms
+      , and_logic:    Var :: _ "and_logic" String } =>>
       GGQL.getFieldsStandard (Proxy :: _ Context)
     }
 
diff --git a/src/Gargantext/Components/GraphQL/Endpoints.purs b/src/Gargantext/Components/GraphQL/Endpoints.purs
index 8976d8e1..3252a91b 100644
--- a/src/Gargantext/Components/GraphQL/Endpoints.purs
+++ b/src/Gargantext/Components/GraphQL/Endpoints.purs
@@ -190,10 +190,11 @@ getNodeContext session context_id node_id = do
         Just context -> pure $ Right context -- TODO: error handling
     
 type ContextsForNgramsGQL = { contexts_for_ngrams :: Array GQLCTX.Context }
-getContextsForNgrams :: Session -> CorpusId -> Array String -> AffRESTError (Array GQLCTX.Context)
-getContextsForNgrams session corpus_id ngrams_terms = do
+getContextsForNgrams :: Session -> CorpusId -> Array String -> Boolean -> AffRESTError (Array GQLCTX.Context)
+getContextsForNgrams session corpus_id ngrams_terms logic = do
   let query = GQLCTX.contextsForNgramsQuery `withVars` { corpus_id
-                                                       , ngrams_terms: GQLCTX.NgramsTerms ngrams_terms }
+                                                       , ngrams_terms: GQLCTX.NgramsTerms ngrams_terms
+                                                       , and_logic: show logic }
   eRes <- queryGql session "get contexts for ngrams" query
   pure $ rmap _.contexts_for_ngrams eRes
 
diff --git a/src/Gargantext/Components/Nodes/Lists.purs b/src/Gargantext/Components/Nodes/Lists.purs
index c6b393cf..8caa72b6 100644
--- a/src/Gargantext/Components/Nodes/Lists.purs
+++ b/src/Gargantext/Components/Nodes/Lists.purs
@@ -213,7 +213,7 @@ type NgramsDocLoadProps =
 
 loaderNgramsDocList :: Record NgramsDocLoadProps -> AffRESTError (Array GQLCTX.Context)
 loaderNgramsDocList { corpusId, ngrams: NormNgramsTerm ngrams, session } =
-  getContextsForNgrams session corpusId [ngrams]
+  getContextsForNgrams session corpusId [ngrams] false
 
 type NgramsDocListLoadedProps =
   ( contexts :: Array GQLCTX.Context
diff --git a/src/Gargantext/Components/PhyloExplorer/Sidebar/DocList.purs b/src/Gargantext/Components/PhyloExplorer/Sidebar/DocList.purs
index e59585e6..c71829e8 100644
--- a/src/Gargantext/Components/PhyloExplorer/Sidebar/DocList.purs
+++ b/src/Gargantext/Components/PhyloExplorer/Sidebar/DocList.purs
@@ -50,6 +50,8 @@ docListWrapperCpt = here.component "wrapper" cpt where
     corpusId       <- R2.useLive' store.corpusId
     listId         <- R2.useLive' store.listId
     selectedTerm   <- R2.useLive' store.selectedTerm
+
+    buttonState <- T.useBox false
     
     query' /\ query <- R2.useBox' Nothing
 
@@ -90,6 +92,7 @@ docListWrapperCpt = here.component "wrapper" cpt where
             , listId
             , frameDoc: store.frameDoc
             , frontends: defaultFrontends
+            , buttonState
             }
       ]
 
@@ -102,6 +105,7 @@ type ListProps =
   , session         :: Session
   , frameDoc        :: T.Box (Maybe FrameDoc)
   , frontends       :: Frontends
+  , buttonState     :: T.Box Boolean
   )
 
 docList :: R2.Leaf ListProps
@@ -125,15 +129,12 @@ docListCpt = here.component "main" cpt where
       , listId
       , frameDoc
       , frontends
+      , buttonState
       } _ = do
     -- | States
     -- |
 
 
-    path' /\ path <- R2.useBox' $ initialPageGQL { corpusId: nodeId
-                                                 , ngramsTerms: q'
-                                                 , session }
-
     state' /\ state <-
       R2.useBox' Nothing
 
@@ -143,7 +144,13 @@ docListCpt = here.component "main" cpt where
     frameDoc' <-
       R2.useLive' frameDoc
 
-    buttonState <- T.useBox false
+    buttonState' <- 
+      R2.useLive' buttonState
+
+    path' /\ path <- R2.useBox' $ initialPageGQL { corpusId: nodeId
+                                                 , ngramsTerms: q'
+                                                 , session
+                                                 , logic: buttonState' }
 
     -- | Hooks
     -- |
@@ -162,7 +169,14 @@ docListCpt = here.component "main" cpt where
     useUpdateEffect1' query $
       T.write_ (initialPageGQL { corpusId: nodeId
                                , ngramsTerms: q'
-                               , session }) path
+                               , session
+                               , logic: buttonState' }) path
+
+    useUpdateEffect1' buttonState' $
+      T.write_ (initialPageGQL { corpusId: nodeId
+                               , ngramsTerms: q'
+                               , session
+                               , logic: buttonState' }) path
 
     -- (on fetch success, extract existing docs)
     useUpdateEffect1' state' case state' of
@@ -372,7 +386,7 @@ andOrButtonCpt = here.component "andOrButton" cpt
               OutlinedButtonVariant Secondary $
               ButtonVariant Secondary
           }
-          [ H.text "AND" ]
+          [ H.text "OR" ]
         ,
           B.button
           { className: "btn-sm"
@@ -381,6 +395,6 @@ andOrButtonCpt = here.component "andOrButton" cpt
               ButtonVariant Secondary $
               OutlinedButtonVariant Secondary
           }
-          [ H.text "OR" ]
+          [ H.text "AND" ]
         ]
 
-- 
2.21.0