module Gargantext.Components.Nodes.Annuaire -- ( annuaire ) where import Gargantext.Prelude import Data.Array as A import Data.Either (Either) import Data.Eq.Generic (genericEq) import Data.Generic.Rep (class Generic) import Data.Maybe (Maybe(..), maybe, fromMaybe) import Data.Newtype (class Newtype) import Data.Sequence as Seq import Data.Symbol (SProxy(..)) import Effect.Aff (Aff, launchAff_) 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 (defaultContainer, initialParams, makeRow, table, tableHeaderLayout) as TT import Gargantext.Components.Table.Types (ColumnName(..), Params) as TT import Gargantext.Config.REST (RESTError, logRESTError) 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(..), AffETableResult, TableResult) import Gargantext.Utils.Reactix as R2 import Reactix as R import Reactix.DOM.HTML as H import Record as Record import Simple.JSON as JSON import Toestand as T 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 { errorHandler , loader: getAnnuaireInfo session , path: path' , render: \info -> annuaire { frontends, info, path, session } } where errorHandler = logRESTError here "[annuaireLayoutWithKey]" 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' 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 { frontends, pagePath, session } _ = do pagePath' <- T.useLive T.unequal pagePath useLoader { errorHandler , loader: loadPage session , path: pagePath' , render: \table -> page { session, table, frontends, pagePath } } where errorHandler = logRESTError here "[pageLayout]" 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 { nodeId } contact = { row: contactCells { annuaireId: nodeId, frontends, contact, session } , delete: false } container = TT.defaultContainer -- 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 { contact: CT.NodeContact { 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 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) newtype HyperdataAnnuaire = HyperdataAnnuaire { title :: Maybe String , desc :: Maybe String } derive instance Generic HyperdataAnnuaire _ derive instance Newtype HyperdataAnnuaire _ instance Eq HyperdataAnnuaire where eq = genericEq derive newtype instance JSON.ReadForeign HyperdataAnnuaire ------------------------------------------------------------------------------ newtype AnnuaireInfo = AnnuaireInfo { id :: Int , typename :: Int , userId :: Int , parentId :: Int , name :: String , date :: String , hyperdata :: HyperdataAnnuaire } derive instance Generic AnnuaireInfo _ derive instance Newtype AnnuaireInfo _ instance Eq AnnuaireInfo where eq = genericEq instance JSON.ReadForeign AnnuaireInfo where readImpl f = do inst <- JSON.readImpl f pure $ AnnuaireInfo $ Record.rename user_idP userIdP $ Record.rename parent_idP parentIdP inst where user_idP = SProxy :: SProxy "user_id" userIdP = SProxy :: SProxy "userId" parent_idP = SProxy :: SProxy "parent_id" parentIdP = SProxy :: SProxy "parentId" --newtype AnnuaireTable = AnnuaireTable { annuaireTable :: Array (Maybe Contact)} --instance DecodeJson AnnuaireTable where -- decodeJson json = do -- rows <- decodeJson json -- pure $ AnnuaireTable { annuaireTable : rows} ------------------------------------------------------------------------ loadPage :: Session -> PagePath -> AffETableResult CT.NodeContact loadPage session {nodeId, params: { offset, limit }} = 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 (Either RESTError AnnuaireInfo) getAnnuaireInfo session id = get session (NodeAPI Node (Just id) "")