module Gargantext.Components.Nodes.Annuaire -- ( annuaire ) where import Data.Argonaut (class DecodeJson, decodeJson, (.:), (.:?)) import Data.Array as A import Data.Generic.Rep (class Generic) import Data.Generic.Rep.Eq (genericEq) import Data.Maybe (Maybe(..), maybe, fromMaybe) import Data.Sequence as Seq import Data.Tuple (fst, snd) import Data.Tuple.Nested ((/\)) import Effect.Aff (Aff, launchAff_) import Reactix as R import Reactix.DOM.HTML as H import Toestand as T import Gargantext.Prelude import Gargantext.Components.NgramsTable.Loader (clearCache) import Gargantext.Components.Nodes.Annuaire.User.Contacts.Types as CT import Gargantext.Components.Nodes.Lists.Types as NT import Gargantext.Components.Table as TT import Gargantext.Components.Table.Types as TT import Gargantext.Ends (url, Frontends) import Gargantext.Hooks.Loader (useLoader) import Gargantext.Routes (SessionRoute(..)) import Gargantext.Routes as Routes import Gargantext.Sessions (Session, sessionId, get) import Gargantext.Types (NodeType(..), AffTableResult, TableResult) import Gargantext.Utils.Reactix as R2 here :: R2.Here here = R2.here "Gargantext.Components.Nodes.Annuaire" newtype IndividuView = CorpusView { id :: Int , name :: String , role :: String , company :: String } --toRows :: AnnuaireTable -> Array (Maybe Contact) --toRows (AnnuaireTable a) = a.annuaireTable -- | Top level layout component. Loads an annuaire by id and renders -- | the annuaire using the result type LayoutProps = ( frontends :: Frontends , nodeId :: Int , session :: Session ) annuaireLayout :: R2.Leaf LayoutProps annuaireLayout props = R.createElement annuaireLayoutCpt props [] annuaireLayoutCpt :: R.Component LayoutProps annuaireLayoutCpt = here.component "annuaireLayout" cpt where cpt { frontends, nodeId, session } _ = do pure $ annuaireLayoutWithKey { frontends, key, nodeId, session } where key = show (sessionId session) <> "-" <> show nodeId type KeyLayoutProps = ( key :: String | LayoutProps ) annuaireLayoutWithKey :: R2.Leaf KeyLayoutProps annuaireLayoutWithKey props = R.createElement annuaireLayoutWithKeyCpt props [] annuaireLayoutWithKeyCpt :: R.Component KeyLayoutProps annuaireLayoutWithKeyCpt = here.component "annuaireLayoutWithKey" cpt where cpt { frontends, nodeId, session } _ = do path <- T.useBox nodeId path' <- T.useLive T.unequal path useLoader path' (getAnnuaireInfo session) $ \info -> annuaire { frontends, info, path, session } type AnnuaireProps = ( session :: Session , path :: T.Box Int , info :: AnnuaireInfo , frontends :: Frontends ) -- | Renders a basic table and the page loader annuaire :: R2.Leaf AnnuaireProps annuaire props = R.createElement annuaireCpt props [] -- Abuses closure to work around the Loader annuaireCpt :: R.Component AnnuaireProps annuaireCpt = here.component "annuaire" cpt where cpt {session, path, info: info@(AnnuaireInfo {name, date: date'}), frontends} _ = do path' <- T.useLive T.unequal path pagePath <- T.useBox $ initialPagePath path' cacheState <- T.useBox NT.CacheOff cacheState' <- T.useLive T.unequal cacheState R.useEffectOnce' $ do T.listen (\_ -> launchAff_ $ clearCache unit) cacheState pure $ R.fragment [ TT.tableHeaderLayout { cacheState , date , desc: name , key: "annuaire-" <> (show cacheState') , query: "" , title: name , user: "" } [] , H.p {} [] -- , H.div {className: "col-md-3"} [ H.text " Filter ", H.input { className: "form-control", style } ] , H.br {} , pageLayout { info, session, pagePath, frontends} ] where date = "Last update: " <> date' style = {width: "250px", display: "inline-block"} initialPagePath nodeId = {nodeId, params: TT.initialParams} type PagePath = { nodeId :: Int, params :: TT.Params } type PageLayoutProps = ( session :: Session , frontends :: Frontends , info :: AnnuaireInfo , pagePath :: T.Box PagePath ) pageLayout :: Record PageLayoutProps -> R.Element pageLayout props = R.createElement pageLayoutCpt props [] pageLayoutCpt :: R.Component PageLayoutProps pageLayoutCpt = here.component "pageLayout" cpt where cpt { info, frontends, pagePath, session } _ = do pagePath' <- T.useLive T.unequal pagePath useLoader pagePath' (loadPage session) $ \table -> page { session, table, frontends, pagePath } type PageProps = ( session :: Session , frontends :: Frontends , pagePath :: T.Box PagePath -- , info :: AnnuaireInfo , table :: TableResult CT.NodeContact ) page :: Record PageProps -> R.Element page props = R.createElement pageCpt props [] pageCpt :: R.Component PageProps pageCpt = here.component "page" cpt where cpt { frontends , pagePath , session , table: ({count: totalRecords, docs}) } _ = do pagePath' <- T.useLive T.unequal pagePath params <- T.useFocused (_.params) (\a b -> b { params = a }) pagePath pure $ TT.table { colNames , container , params , rows: rows pagePath' , syncResetButton : [ H.div {} [] ] , totalRecords , wrapColElts } where rows pagePath' = (row pagePath') <$> Seq.fromFoldable docs row pagePath'@{ nodeId } contact = { row: contactCells { annuaireId: nodeId, frontends, contact, session } , delete: false } container = TT.defaultContainer { title: "Annuaire" } -- TODO colNames = TT.ColumnName <$> [ "", "First Name", "Last Name", "Company", "Role"] wrapColElts = const identity type AnnuaireId = Int type ContactCellsProps = ( annuaireId :: AnnuaireId , contact :: CT.NodeContact , frontends :: Frontends , session :: Session ) contactCells :: Record ContactCellsProps -> R.Element contactCells p = R.createElement contactCellsCpt p [] contactCellsCpt :: R.Component ContactCellsProps contactCellsCpt = here.component "contactCells" cpt where cpt { annuaireId, frontends, session , contact: CT.NodeContact { id, hyperdata: CT.HyperdataContact { who : Nothing }}} _ = pure $ TT.makeRow [ H.text "" , H.span {} [ H.text "Name" ] --, H.a { href, target: "blank" } [ H.text $ fromMaybe "name" contact.title ] , H.text "No ContactWhere" , H.text "No ContactWhereDept" , H.div { className: "nooverflow" } [ H.text "No ContactWhereRole" ] ] cpt { annuaireId, frontends, session , contact: CT.NodeContact { id, hyperdata: CT.HyperdataContact { who: Just (CT.ContactWho { firstName, lastName }) , ou: ou }}} _ = do pure $ TT.makeRow [ H.text "" , H.a { target: "_blank", href: contactUrl annuaireId id } [ H.text $ fromMaybe "First Name" firstName ] , H.text $ fromMaybe "First Name" lastName -- , H.a { href } [ H.text $ fromMaybe "name" contact.title ] --, H.a { href, target: "blank" } [ H.text $ fromMaybe "name" contact.title ] , H.text $ maybe "No ContactWhere" contactWhereOrg (A.head $ ou) , H.text $ maybe "No ContactWhereDept" contactWhereDept (A.head $ ou) -- , H.div {className: "nooverflow"} [ -- H.text $ maybe "No ContactWhereRole" contactWhereRole (A.head $ ou) ] where --nodepath = NodePath (sessionId session) NodeContact (Just id) nodepath = Routes.ContactPage (sessionId session) annuaireId id href = url frontends nodepath contactUrl aId id' = url frontends $ Routes.ContactPage (sessionId session) aId id' contactWhereOrg (CT.ContactWhere { organization: [] }) = "No Organization" contactWhereOrg (CT.ContactWhere { organization: orga }) = fromMaybe "No orga (list)" (A.head orga) contactWhereDept (CT.ContactWhere { labTeamDepts : [] }) = "Empty Dept" contactWhereDept (CT.ContactWhere { labTeamDepts : dept }) = fromMaybe "No Dept (list)" (A.head dept) contactWhereRole (CT.ContactWhere { role: Nothing }) = "Empty Role" contactWhereRole (CT.ContactWhere { role: Just role }) = role data HyperdataAnnuaire = HyperdataAnnuaire { title :: Maybe String , desc :: Maybe String } derive instance genericHyperdataAnnuaire :: Generic HyperdataAnnuaire _ instance eqHyperdataAnnuaire :: Eq HyperdataAnnuaire where eq = genericEq instance decodeHyperdataAnnuaire :: DecodeJson HyperdataAnnuaire where decodeJson json = do obj <- decodeJson json title <- obj .:? "title" desc <- obj .:? "desc" pure $ HyperdataAnnuaire { title, desc } ------------------------------------------------------------------------------ newtype AnnuaireInfo = AnnuaireInfo { id :: Int , typename :: Int , userId :: Int , parentId :: Int , name :: String , date :: String , hyperdata :: HyperdataAnnuaire } derive instance genericAnnuaireInfo :: Generic AnnuaireInfo _ instance eqAnnuaireInfo :: Eq AnnuaireInfo where eq = genericEq instance decodeAnnuaireInfo :: DecodeJson AnnuaireInfo where decodeJson json = do obj <- decodeJson json id <- obj .: "id" typename <- obj .: "typename" userId <- obj .: "userId" parentId <- obj .: "parentId" name <- obj .: "name" date <- obj .: "date" hyperdata <- obj .: "hyperdata" pure $ AnnuaireInfo { id : id , typename : typename , userId : userId , parentId : parentId , name : name , date : date , hyperdata: hyperdata } --newtype AnnuaireTable = AnnuaireTable { annuaireTable :: Array (Maybe Contact)} --instance decodeAnnuaireTable :: DecodeJson AnnuaireTable where -- decodeJson json = do -- rows <- decodeJson json -- pure $ AnnuaireTable { annuaireTable : rows} ------------------------------------------------------------------------ loadPage :: Session -> PagePath -> AffTableResult CT.NodeContact loadPage session {nodeId, params: { offset, limit, orderBy }} = get session children -- TODO orderBy -- where -- convOrderBy (T.ASC (T.ColumnName "Name")) = NameAsc -- convOrderBy (T.DESC (T.ColumnName "Name")) = NameDesc -- ... -- convOrderBy _ = NameAsc -- TODO where children = Children NodeContact offset limit Nothing {-(convOrderBy <$> orderBy)-} (Just nodeId) getAnnuaireInfo :: Session -> Int -> Aff AnnuaireInfo getAnnuaireInfo session id = get session (NodeAPI Node (Just id) "")