module Gargantext.Pages.Annuaire.User.Contacts.Specs (layoutUser) where import Data.List (List, zipWith, catMaybes, toUnfoldable) import Data.Map (Map, empty, keys, values, lookup) import Data.Array (head) import Data.Semigroup ((<>)) import Data.Maybe (Maybe(..), fromMaybe, maybe) import Data.Set (toUnfoldable) as S import Data.Tuple (Tuple(..), uncurry) import Data.Unfoldable (class Unfoldable) import Data.Maybe (Maybe(..)) import Data.Newtype (unwrap) import Data.String (joinWith) import Effect.Aff (Aff, throwError) import Effect.Exception (error) import Thermite (Render, Spec, defaultPerformAction, simpleSpec, createClass) import React as React import React (ReactClass, ReactElement) import React.DOM (div, h3, img, li, span, text, ul, text) import React.DOM.Props (_id, className, src) import Gargantext.Prelude import Gargantext.Config (toUrl, End(..), NodeType(..), Path(..)) import Gargantext.Config.REST (get) import Gargantext.Components.Node (NodePoly(..), HyperdataList(..)) import Gargantext.Components.Loader as Loader import Gargantext.Pages.Annuaire.User.Contacts.Types import Gargantext.Pages.Annuaire.User.Contacts.Tabs.Specs as Tabs --type Props = Loader.InnerProps Int Contact display :: String -> Array ReactElement -> Array ReactElement display title elems = [ div [className "container-fluid"] [ div [className "row", _id "contact-page-header"] [ div [className "col-md-6"] [ h3 [] [text title] ] , div [className "col-md-8"] [] , div [className "col-md-2"] [ span [] [text ""] ] ] , div [className "row", _id "contact-page-info"] [ div [className "col-md-12"] [ div [className "row"] [ div [className "col-md-2"] --[ ] [ img [src "/images/Gargantextuel-212x300.jpg"] ] , div [className "col-md-1"] [] , div [className "col-md-8"] elems ] ] ] ] ] mapMyMap :: forall k v x f. Ord k => Unfoldable f => (k -> v -> x) -> Map k v -> f x mapMyMap f m = toUnfoldable $ zipWith f mapKeys (catMaybes $ flip lookup m <$> mapKeys) where mapKeys = S.toUnfoldable $ keys m infixl 4 mapMyMap as <.~$> getFirstName obj = fromMaybe "Empty title" $ getFirstName' <$> obj getFirstName' = fromMaybe "Empty first name" <<< _.firstName <<< unwrap getLastName obj = fromMaybe "Empty title" $ getLastName' <$> obj getLastName' = fromMaybe "Empty last name" <<< _.lastName <<< unwrap -- | ContactWhere infos -- TODO factor below getRole :: Array ContactWhere -> String getRole = maybe "Empty Contact-Where" getRole' <<< head where getRole' = fromMaybe "Empty Role" <<< _.role <<< unwrap getOrga :: Array ContactWhere -> String getOrga = maybe "Emtpy Contact-Where" getOrga' <<< head where getOrga' :: ContactWhere -> String getOrga' obj = joinWith ", " $ (\(ContactWhere {organization: o}) ->o) obj getDept :: Array ContactWhere -> String getDept = maybe "Empty Department" getDept' <<< head where getDept' :: ContactWhere -> String getDept' obj = joinWith ", " $ (\(ContactWhere {labTeamDepts: l}) ->l) obj getOffice :: Array ContactWhere -> String getOffice = fromMaybe "Empty Office" <<< maybe Nothing (\(ContactWhere {office:x}) -> x) <<< head getCity :: Array ContactWhere -> String getCity = fromMaybe "Empty City" <<< maybe Nothing (\(ContactWhere {city:x}) -> x) <<< head getCountry :: Array ContactWhere -> String getCountry = fromMaybe "Empty Country" <<< maybe Nothing (\(ContactWhere {country:x}) -> x) <<< head -- | ContactWhere / Touch infos getTouch :: Array ContactWhere -> Maybe ContactTouch getTouch = maybe Nothing (\(ContactWhere {touch:x}) -> x) <<< head getPhone :: Array ContactWhere -> String getPhone obj = fromMaybe "Empty touch info" $ getPhone' <$> (getTouch obj) getPhone' :: ContactTouch -> String getPhone' = fromMaybe "Empty phone" <<< _.phone <<< unwrap getMail :: Array ContactWhere -> String getMail obj = fromMaybe "Empty info" $ getMail' <$> (getTouch obj) getMail' :: ContactTouch -> String getMail' = fromMaybe "Empty mail" <<< _.mail <<< unwrap -- | TODO format data in better design (UI) shape contactInfos :: HyperdataContact -> Array ReactElement contactInfos (HyperdataContact {who:who, ou:ou}) = [ li [className "list-group-item"] (infoRender (Tuple "Last Name" $ " " <> getLastName who)) , li [className "list-group-item"] (infoRender (Tuple "First name" $ " " <> getFirstName who)) , li [className "list-group-item"] (infoRender (Tuple "Organization" $ " " <> getOrga ou )) , li [className "list-group-item"] (infoRender (Tuple "Lab/Team/Dept"$ " " <> getOrga ou )) , li [className "list-group-item"] (infoRender (Tuple "Office" $ " " <> getOffice ou )) , li [className "list-group-item"] (infoRender (Tuple "City" $ " " <> getCity ou )) , li [className "list-group-item"] (infoRender (Tuple "Country" $ " " <> getCountry ou )) , li [className "list-group-item"] (infoRender (Tuple "Role" $ " " <> getRole ou )) , li [className "list-group-item"] (infoRender (Tuple "Phone" $ " " <> getPhone ou )) , li [className "list-group-item"] (infoRender (Tuple "Mail" $ " " <> getMail ou )) ] {- $ listInfo <.~$> hyperdata where checkMaybe (Nothing) = empty checkMaybe (Just (HyperData a)) = a -} listInfo :: Tuple String String -> ReactElement listInfo s = listElement $ infoRender s listElement :: Array ReactElement -> ReactElement listElement = li [className "list-group-item justify-content-between"] infoRender :: Tuple String String -> Array ReactElement infoRender (Tuple title content) = [ span [className "badge badge-default badge-pill"] [text title] , span [] [text content] ] -- | Below an example of a loader, use all code below and adapt it -- to your code -- layoutUser is exported by the module -- only one subnode: contactLoader which as 2 parameters -- - path (nodeId) -- - components (which has to be drawn when loaded layoutUser :: Spec {} {nodeId :: Int} Void layoutUser = simpleSpec defaultPerformAction render where render :: Render {} {nodeId :: Int} Void render _ {nodeId} _ _ = [ contactLoader { path: nodeId , component: createClass "LayoutUser" layoutUser' (const {}) } ] -- | Take the spec and transform it in React Class -- put here how to draw the Composant -- props loaded: what has been loaded by the component loader layoutUser' :: Spec {} Props Void layoutUser' = simpleSpec defaultPerformAction render <> Tabs.pureTabs where render :: Render {} Props Void render dispatch {loaded: {contactNode: Contact {name, hyperdata}}} _ _ = [ ul [className "col-md-12 list-group"] $ display (fromMaybe "no name" name) (contactInfos hyperdata) ] -- | toUrl to get data getContact :: Int -> Aff ContactData getContact id = do contactNode <- get $ toUrl Back Node $ Just id -- TODO: we need a default list for the pairings --defaultListIds <- get $ toUrl Back (Children NodeList 0 1 Nothing) $ Just id --case (head defaultListIds :: Maybe (NodePoly HyperdataList)) of -- Just (NodePoly { id: defaultListId }) -> -- pure {contactNode, defaultListId} -- Nothing -> -- throwError $ error "Missing default list" pure {contactNode, defaultListId: 424242} -- | Change name for you contactLoaderClass :: ReactClass (Loader.Props Int ContactData) contactLoaderClass = Loader.createLoaderClass "ContactLoader" getContact -- | Change type according to what has been loaded contactLoader :: Loader.Props' Int ContactData -> ReactElement contactLoader props = React.createElement contactLoaderClass props []