module Gargantext.Components.GraphExplorer.Sidebar.ContactList ( contactListWrapper ) where import Gargantext.Prelude import Data.Array (concat, head) import Data.Foldable (intercalate) import Data.Map as Map import Data.Maybe (Maybe(..)) import Data.Sequence as Seq import Data.Set as Set import Data.Tuple.Nested ((/\)) import Gargantext.Components.Bootstrap as B import Gargantext.Components.FacetsTable (ContactsView(..), Rows(..), initialPagePath, loadPage) import Gargantext.Components.GraphExplorer.Store as GraphStore import Gargantext.Components.GraphExplorer.Types (CorpusId, ListId) import Gargantext.Components.GraphExplorer.Types as GET import Gargantext.Components.RandomText (words) import Gargantext.Components.Search (HyperdataRowContact(..), SearchQuery(..), SearchType(..)) import Gargantext.Config (defaultFrontends) import Gargantext.Config.REST (RESTError(..)) import Gargantext.Ends (Frontends, url) import Gargantext.Hooks.Loader (useLoaderEffect) import Gargantext.Hooks.Session (useSession) import Gargantext.Hooks.Sigmax.Types as SigmaxT import Gargantext.Hooks.UpdateEffect (useUpdateEffect1') import Gargantext.Routes as Routes import Gargantext.Sessions (Session, sessionId) import Gargantext.Utils (nbsp) 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.Sidebar.ContactList" type Props = ( metaData :: GET.MetaData ) contactListWrapper :: R2.Leaf Props contactListWrapper = R2.leaf contactListWrapperCpt contactListWrapperCpt :: R.Component Props contactListWrapperCpt = here.component "wrapper" cpt where cpt { metaData: GET.MetaData metaData } _ = do -- | States -- | session <- useSession { graph , selectedNodeIds } <- GraphStore.use graph' <- R2.useLive' graph selectedNodeIds' <- R2.useLive' selectedNodeIds query' /\ query <- R2.useBox' Nothing -- | Helpers -- | let frontends = defaultFrontends nodesMap = SigmaxT.nodesGraphMap graph' toSearchQuery ids = SearchQuery { expected: SearchContact , query: concat $ toQuery <$> Set.toUnfoldable ids } toQuery id = case Map.lookup id nodesMap of Nothing -> [] Just n -> words n.label -- | Hooks -- | R.useEffect1' selectedNodeIds' $ T.write_ (selectedNodeIds' # toSearchQuery >>> Just) query -- | Render -- | pure $ R.fragment [ case (head metaData.corpusId) /\ query' of (Just corpusId) /\ (Just q') -> contactList { frontends , query: q' , session , corpusId , listId: metaData.list.listId } _ /\ _ -> B.caveat {} [ H.text "You can link an annuaire to retrieve relative contacts about your selection" ] ] ------------------------------------------------------------------- type ListProps = ( query :: SearchQuery , corpusId :: CorpusId , listId :: ListId , frontends :: Frontends , session :: Session ) contactList :: R2.Leaf ListProps contactList = R2.leaf contactListCpt contactListCpt :: R.Component ListProps contactListCpt = here.component "main" cpt where -- | Helpers -- | errorHandler err = do here.warn2 "[pageLayout] RESTError" err case err of ReadJSONError err' -> here.warn2 "[pageLayout] ReadJSONError" $ show err' _ -> pure unit -- | Component -- | cpt { frontends , query , session , corpusId: nodeId , listId } _ = do -- | States -- | path' /\ path <- R2.useBox' $ initialPagePath { nodeId, listId, query, session } state' /\ state <- R2.useBox' Nothing rows' /\ rows <- R2.useBox' Nothing -- | Hooks -- | useLoaderEffect { errorHandler , state , loader: loadPage , path: path' } -- | Effects -- | -- (on query change, reload fetched docs) useUpdateEffect1' query $ flip T.write_ path $ initialPagePath { nodeId, listId, query, session } -- (on fetch success, extract existing docs) useUpdateEffect1' state' case state' of Nothing -> T.write_ (Just Seq.empty) rows Just r -> case r of Contacts { contacts } -> T.write_ (Just contacts) rows _ -> T.write_ (Just Seq.empty) rows -- | Render -- | pure $ R2.fromMaybe rows' \results -> R.fragment [ R2.when (results == Seq.empty) $ B.caveat {} [ H.text "No contact found in your corpus for your selected terms" ] , R2.when (not $ eq results Seq.empty) $ H.ul { className: intercalate " " [ "graph-contact-list" , "list-group" ] } $ Seq.toUnfoldable $ flip Seq.map results \r -> item { frontends , session , contactView: (r :: ContactsView) } ] --------------------------------------------------------- type ItemProps = ( contactView :: ContactsView , frontends :: Frontends , session :: Session ) item :: R2.Leaf ItemProps item = R2.leaf itemCpt itemCpt :: R.Component ItemProps itemCpt = here.component "item" cpt where cpt { contactView: ContactsView { id , annuaireId , hyperdata: HyperdataRowContact { firstname , lastname , labs } } , frontends , session } _ = do -- Computed let -- Creating a href link contactUrl id' = url frontends $ Routes.ContactPage (sessionId session) annuaireId id' -- Render pure $ H.div { className: intercalate " " [ "graph-contact-list__item" , "list-group-item" ] } [ H.a { className: "graph-contact-list__item__title" , target: "_blank" , href: contactUrl id } [ H.text $ firstname , H.text $ nbsp 1 , H.text $ lastname ] , B.div' { className: "graph-contact-list__item__subtitle" } labs ]