Commit 784d5604 authored by Przemyslaw Kaminski's avatar Przemyslaw Kaminski

[forest] fix layout view, custom sidebar for texts initial impl

parent fd66a25f
......@@ -22,8 +22,7 @@ localStorageKey :: String
localStorageKey = "garg-async-tasks"
type NodeId = Int
type Storage = Map.Map NodeId (Array GT.AsyncTaskWithType)
type Storage = Map.Map GT.NodeID (Array GT.AsyncTaskWithType)
empty :: Storage
empty = Map.empty
......@@ -41,7 +40,7 @@ getAsyncTasks = R2.getls >>= WSS.getItem localStorageKey >>= handleMaybe
parse s = GU.mapLeft (log2 "Error parsing serialised sessions:") (jsonParser s)
decode j = GU.mapLeft (log2 "Error decoding serialised sessions:") (decodeJson j)
getTasks :: Record ReductorProps -> NodeId -> Array GT.AsyncTaskWithType
getTasks :: Record ReductorProps -> GT.NodeID -> Array GT.AsyncTaskWithType
getTasks { storage } nodeId = fromMaybe [] $ Map.lookup nodeId storage
removeTaskFromList :: Array GT.AsyncTaskWithType -> GT.AsyncTaskWithType -> Array GT.AsyncTaskWithType
......@@ -68,9 +67,9 @@ useTasks appReload treeReload = R2.useReductor act initializer unit
pure { appReload, treeReload, storage }
data Action =
Insert NodeId GT.AsyncTaskWithType
| Finish NodeId GT.AsyncTaskWithType
| Remove NodeId GT.AsyncTaskWithType
Insert GT.NodeID GT.AsyncTaskWithType
| Finish GT.NodeID GT.AsyncTaskWithType
| Remove GT.NodeID GT.AsyncTaskWithType
action :: Record ReductorProps -> Action -> Effect (Record ReductorProps)
action p@{ treeReload, storage } (Insert nodeId t) = do
......
......@@ -5,7 +5,6 @@ import Data.Maybe (Maybe(..), maybe')
import Data.Tuple (fst, snd)
import Data.Tuple.Nested ((/\))
import Reactix as R
import Reactix.DOM.HTML as H
import Gargantext.Prelude
......
......@@ -25,80 +25,61 @@ import Effect.Aff (Aff, launchAff)
import Effect.Class (liftEffect)
import Reactix as R
import Reactix.DOM.HTML as H
------------------------------------------------------------------------
import Gargantext.Prelude
import Gargantext.Components.Category.Types
import Gargantext.Components.DocsTable.Types (DocumentsView(..), LocalCategories)
import Gargantext.Ends (Frontends, url)
import Gargantext.Hooks.Loader (useLoaderWithCacheAPI, HashedResponse(..))
import Gargantext.Utils.Reactix as R2
import Gargantext.Routes as Routes
import Gargantext.Routes (SessionRoute(NodeAPI))
import Gargantext.Sessions (Session, sessionId, get, delete, put)
import Gargantext.Types (NodeType(..), OrderBy(..), TableResult, TabType, showTabType')
import Gargantext.Types (NodeID, NodeType(..), OrderBy(..), TableResult, TabType, showTabType')
import Gargantext.Utils.CacheAPI as GUC
thisModule :: String
thisModule = "Gargantext.Components.Category"
------------------------------------------------------------------------
data Category = Trash | UnRead | Checked | Topic | Favorite
categories :: Array Category
categories = [Trash, UnRead, Checked, Topic, Favorite]
derive instance genericFavorite :: Generic Category _
instance showCategory :: Show Category where
show = genericShow
instance eqCategory :: Eq Category where
eq = genericEq
instance decodeJsonCategory :: DecodeJson Category where
decodeJson json = do
obj <- decodeJson json
pure $ decodeCategory obj
instance encodeJsonCategory :: EncodeJson Category where
encodeJson cat = encodeJson (cat2score cat)
favCategory :: Category -> Category
favCategory Favorite = Topic
favCategory _ = Favorite
trashCategory :: Category -> Category
trashCategory _ = Trash
-- TODO: ?
--trashCategory Trash = UnRead
decodeCategory :: Int -> Category
decodeCategory 0 = Trash
decodeCategory 1 = UnRead
decodeCategory 2 = Checked
decodeCategory 3 = Topic
decodeCategory 4 = Favorite
decodeCategory _ = UnRead
cat2score :: Category -> Int
cat2score Trash = 0
cat2score UnRead = 1
cat2score Checked = 2
cat2score Topic = 3
cat2score Favorite = 4
type CarousselProps = (
category :: Category
, nodeId :: NodeID
, row :: DocumentsView
, session :: Session
, setLocalCategories :: R.Setter LocalCategories
)
-- caroussel :: Category -> R.Element
caroussel session nodeId setLocalCategories r cat = H.div {className:"flex"} divs
caroussel :: R2.Component CarousselProps
caroussel = R.createElement carousselCpt
carousselCpt :: R.Component CarousselProps
carousselCpt = R.hooksComponentWithModule thisModule "caroussel" cpt
where
divs = map (\c -> if cat == c
then
H.div { className : icon c (cat == c) } []
else
H.div { className : icon c (cat == c)
, on: { click: onClick c}
} []
) (caroussel' cat)
caroussel' :: Category -> Array Category
caroussel' Trash = A.take 2 categories
caroussel' c = A.take 3 $ A.drop (cat2score c - 1 ) categories
onClick c = \_-> do
setLocalCategories $ Map.insert r._id c
void $ launchAff $ putCategories session nodeId $ CategoryQuery {nodeIds: [r._id], category: c}
cpt { category, nodeId, row: DocumentsView r, session, setLocalCategories } _ = do
pure $ H.div {className:"flex"} divs
where
divs = map (\c -> if category == c
then
H.div { className : icon c (category == c) } []
else
H.div { className : icon c (category == c)
, on: { click: onClick c}
} []
) (caroussel' category)
caroussel' :: Category -> Array Category
caroussel' Trash = A.take 2 categories
caroussel' c = A.take 3 $ A.drop (cat2score c - 1 ) categories
onClick c = \_-> do
setLocalCategories $ Map.insert r._id c
void $ launchAff $ putCategories session nodeId $ CategoryQuery {nodeIds: [r._id], category: c}
icon :: Category -> Boolean -> String
icon cat b = btn b $ "glyphicon glyphicon-" <> (color $ size b $ icon' cat b)
......
module Gargantext.Components.Category.Types where
import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, encodeJson)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Eq (genericEq)
import Data.Generic.Rep.Show (genericShow)
import Gargantext.Prelude
------------------------------------------------------------------------
data Category = Trash | UnRead | Checked | Topic | Favorite
categories :: Array Category
categories = [Trash, UnRead, Checked, Topic, Favorite]
derive instance genericFavorite :: Generic Category _
instance showCategory :: Show Category where
show = genericShow
instance eqCategory :: Eq Category where
eq = genericEq
instance decodeJsonCategory :: DecodeJson Category where
decodeJson json = do
obj <- decodeJson json
pure $ decodeCategory obj
instance encodeJsonCategory :: EncodeJson Category where
encodeJson cat = encodeJson (cat2score cat)
favCategory :: Category -> Category
favCategory Favorite = Topic
favCategory _ = Favorite
trashCategory :: Category -> Category
trashCategory _ = Trash
-- TODO: ?
--trashCategory Trash = UnRead
decodeCategory :: Int -> Category
decodeCategory 0 = Trash
decodeCategory 1 = UnRead
decodeCategory 2 = Checked
decodeCategory 3 = Topic
decodeCategory 4 = Favorite
decodeCategory _ = UnRead
cat2score :: Category -> Int
cat2score Trash = 0
cat2score UnRead = 1
cat2score Checked = 2
cat2score Topic = 3
cat2score Favorite = 4
......@@ -22,15 +22,18 @@ import Reactix as R
import Reactix.DOM.HTML as H
------------------------------------------------------------------------
import Gargantext.Prelude
import Gargantext.Components.Category (Category(..), caroussel, decodeCategory)
import Gargantext.Components.Category (caroussel)
import Gargantext.Components.Category.Types (Category(..), decodeCategory)
import Gargantext.Components.DocsTable.Types
import Gargantext.Components.Nodes.Lists.Types as NT
import Gargantext.Components.Nodes.Texts.Types (SidePanelTriggers)
import Gargantext.Components.Table as T
import Gargantext.Ends (Frontends, url)
import Gargantext.Hooks.Loader (useLoader, useLoaderWithCacheAPI, HashedResponse(..))
import Gargantext.Routes as Routes
import Gargantext.Routes (SessionRoute(NodeAPI))
import Gargantext.Sessions (Session, sessionId, get, delete)
import Gargantext.Types (NodeType(..), OrderBy(..), TableResult, TabSubType, TabType, showTabType')
import Gargantext.Types (NodeID, NodeType(..), OrderBy(..), TableResult, TabSubType, TabType, showTabType')
import Gargantext.Utils (sortWith)
import Gargantext.Utils.CacheAPI as GUC
import Gargantext.Utils.QueryString (joinQueryStrings, mQueryParamS, queryParam, queryParamS)
......@@ -51,19 +54,20 @@ type Path a = (
)
type LayoutProps = (
cacheState :: R.State NT.CacheState
, corpusId :: Maybe Int
, frontends :: Frontends
, chart :: R.Element
, listId :: Int
, nodeId :: Int
cacheState :: R.State NT.CacheState
, corpusId :: Maybe Int
, frontends :: Frontends
, chart :: R.Element
, listId :: Int
, nodeId :: Int
-- , path :: Record (Path a)
, session :: Session
, showSearch :: Boolean
, tabType :: TabType
, session :: Session
, showSearch :: Boolean
, sidePanelTriggers :: Record SidePanelTriggers
, tabType :: TabType
-- ^ tabType is not ideal here since it is too much entangled with tabs and
-- ngramtable. Let's see how this evolves. )
, totalRecords :: Int
, totalRecords :: Int
)
type PageLayoutProps = (
......@@ -76,97 +80,14 @@ type PageLayoutProps = (
, params :: T.Params
, query :: Query
, session :: Session
, sidePanelTriggers :: Record SidePanelTriggers
, tabType :: TabType
, totalRecords :: Int
)
type LocalCategories = Map Int Category
type Query = String
_documentIdsDeleted = prop (SProxy :: SProxy "documentIdsDeleted")
_localCategories = prop (SProxy :: SProxy "localCategories")
data Action
= MarkCategory Int Category
newtype DocumentsView
= DocumentsView
{ _id :: Int
, category :: Category
, date :: Int
, ngramCount :: Int
, source :: String
, title :: String
, url :: String
}
{-
derive instance genericDocumentsView :: Generic DocumentsView _
instance showDocumentsView :: Show DocumentsView where
show = genericShow
instance decodeJsonSearchType :: Argonaut.DecodeJson SearchType where
decodeJson = genericSumDecodeJson
instance encodeJsonSearchType :: Argonaut.EncodeJson SearchType where
encodeJson = genericSumEncodeJson
-}
instance decodeDocumentsView :: DecodeJson DocumentsView where
decodeJson json = do
obj <- decodeJson json
_id <- obj .: "id"
category <- obj .: "category"
date <- obj .: "date"
ngramCount <- obj .: "ngramCount"
source <- obj .: "source"
title <- obj .: "title"
url <- obj .: "url"
pure $ DocumentsView { _id, category, date, ngramCount, source, title, url }
instance encodeDocumentsView :: EncodeJson DocumentsView where
encodeJson (DocumentsView dv) =
"id" := dv._id
~> "category" := dv.category
~> "date" := dv.date
~> "ngramCount" := dv.ngramCount
~> "source" := dv.source
~> "title" := dv.title
~> "url" := dv.url
~> jsonEmptyObject
newtype Response = Response
{ cid :: Int
, hyperdata :: Hyperdata
, category :: Category
, ngramCount :: Int
, title :: String
}
newtype Hyperdata = Hyperdata
{ title :: String
, source :: String
, pub_year :: Int
}
instance decodeHyperdata :: DecodeJson Hyperdata where
decodeJson json = do
obj <- decodeJson json
title <- obj .: "title"
source <- obj .: "source"
pub_year <- obj .: "publication_year"
pure $ Hyperdata { title,source, pub_year}
instance decodeResponse :: DecodeJson Response where
decodeJson json = do
obj <- decodeJson json
category <- obj .: "category"
cid <- obj .: "id"
hyperdata <- obj .: "hyperdata"
ngramCount <- obj .: "id"
title <- obj .: "title"
pure $ Response { cid, title, category: decodeCategory category, ngramCount, hyperdata }
docViewLayout :: Record LayoutProps -> R.Element
docViewLayout props = R.createElement docViewLayoutCpt props []
......@@ -197,6 +118,7 @@ docViewCpt = R.hooksComponentWithModule thisModule "docView" cpt where
, nodeId
, session
, showSearch
, sidePanelTriggers
, tabType
, totalRecords
}
......@@ -217,6 +139,7 @@ docViewCpt = R.hooksComponentWithModule thisModule "docView" cpt where
, params
, query: fst query
, session
, sidePanelTriggers
, tabType
, totalRecords
} ] ] ]
......@@ -310,7 +233,16 @@ pageLayout props = R.createElement pageLayoutCpt props []
pageLayoutCpt :: R.Component PageLayoutProps
pageLayoutCpt = R.hooksComponentWithModule thisModule "pageLayout" cpt where
cpt props@{ cacheState, corpusId, frontends, listId, nodeId, params, query, session, tabType } _ = do
cpt props@{ cacheState
, corpusId
, frontends
, listId
, nodeId
, params
, query
, session
, sidePanelTriggers
, tabType } _ = do
let path = { corpusId, listId, nodeId, params, query, tabType }
handleResponse :: HashedResponse (TableResult Response) -> Tuple Int (Array DocumentsView)
handleResponse (HashedResponse { hash, value: res }) = ret
......@@ -402,7 +334,7 @@ pagePaintRaw props = R.createElement pagePaintRawCpt props []
pagePaintRawCpt :: R.Component PagePaintRawProps
pagePaintRawCpt = R.hooksComponentWithModule thisModule "pagePaintRawCpt" cpt where
cpt { documents
, layout: { corpusId, frontends, listId, nodeId, session, totalRecords }
, layout: { corpusId, frontends, listId, nodeId, session, sidePanelTriggers, totalRecords }
, localCategories
, params } _ = do
pure $ T.table
......@@ -427,10 +359,10 @@ pagePaintRawCpt = R.hooksComponentWithModule thisModule "pagePaintRawCpt" cpt wh
getCategory (localCategories /\ _) {_id, category} = fromMaybe category (localCategories ^. at _id)
rows localCategories = row <$> A.toUnfoldable documents
where
row (DocumentsView r) =
row dv@(DocumentsView r) =
{ row:
T.makeRow [ -- H.div {} [ H.a { className, style, on: {click: click Favorite} } [] ]
caroussel session nodeId setLocalCategories r cat
caroussel { category: cat, nodeId, row: dv, session, setLocalCategories } []
--, H.input { type: "checkbox", defaultValue: checked, on: {click: click Trash} }
-- TODO show date: Year-Month-Day only
, H.div { style } [ R2.showText r.date ]
......
module Gargantext.Components.DocsTable.Types where
import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, jsonEmptyObject, (.:), (:=), (~>))
import Data.Map (Map)
import Data.Map as Map
import Gargantext.Prelude
import Gargantext.Components.Category.Types (Category(..), decodeCategory)
data Action
= MarkCategory Int Category
newtype DocumentsView
= DocumentsView
{ _id :: Int
, category :: Category
, date :: Int
, ngramCount :: Int
, source :: String
, title :: String
, url :: String
}
{-
derive instance genericDocumentsView :: Generic DocumentsView _
instance showDocumentsView :: Show DocumentsView where
show = genericShow
instance decodeJsonSearchType :: Argonaut.DecodeJson SearchType where
decodeJson = genericSumDecodeJson
instance encodeJsonSearchType :: Argonaut.EncodeJson SearchType where
encodeJson = genericSumEncodeJson
-}
instance decodeDocumentsView :: DecodeJson DocumentsView where
decodeJson json = do
obj <- decodeJson json
_id <- obj .: "id"
category <- obj .: "category"
date <- obj .: "date"
ngramCount <- obj .: "ngramCount"
source <- obj .: "source"
title <- obj .: "title"
url <- obj .: "url"
pure $ DocumentsView { _id, category, date, ngramCount, source, title, url }
instance encodeDocumentsView :: EncodeJson DocumentsView where
encodeJson (DocumentsView dv) =
"id" := dv._id
~> "category" := dv.category
~> "date" := dv.date
~> "ngramCount" := dv.ngramCount
~> "source" := dv.source
~> "title" := dv.title
~> "url" := dv.url
~> jsonEmptyObject
newtype Response = Response
{ cid :: Int
, hyperdata :: Hyperdata
, category :: Category
, ngramCount :: Int
, title :: String
}
newtype Hyperdata = Hyperdata
{ title :: String
, source :: String
, pub_year :: Int
}
instance decodeHyperdata :: DecodeJson Hyperdata where
decodeJson json = do
obj <- decodeJson json
title <- obj .: "title"
source <- obj .: "source"
pub_year <- obj .: "publication_year"
pure $ Hyperdata { title,source, pub_year}
instance decodeResponse :: DecodeJson Response where
decodeJson json = do
obj <- decodeJson json
category <- obj .: "category"
cid <- obj .: "id"
hyperdata <- obj .: "hyperdata"
ngramCount <- obj .: "id"
title <- obj .: "title"
pure $ Response { cid, title, category: decodeCategory category, ngramCount, hyperdata }
type LocalCategories = Map Int Category
type Query = String
......@@ -22,7 +22,8 @@ import Prelude
import Reactix as R
import Reactix.DOM.HTML as H
import Gargantext.Components.Category (Category(..), CategoryQuery(..), favCategory, decodeCategory, putCategories)
import Gargantext.Components.Category (CategoryQuery(..), putCategories)
import Gargantext.Components.Category.Types (Category(..), decodeCategory, favCategory)
import Gargantext.Components.Search
import Gargantext.Components.Table as T
import Gargantext.Ends (url, Frontends)
......
......@@ -133,7 +133,7 @@ forestLayoutCpt :: R.Component ForestLayoutProps
forestLayoutCpt = R.hooksComponentWithModule thisModule "forestLayout" cpt
where
cpt props@{ handed } children = do
pure $ R.fragment [ topBar { handed } [], forestLayoutMain props children ]
pure $ R.fragment [ topBar { handed } [], forestLayoutRaw props children ]
-- a component, for which first child element is placed inside the top bar
-- while the remaining ones are put into the main view
......@@ -148,6 +148,39 @@ forestLayoutWithTopBarCpt = R.hooksComponentWithModule thisModule "forestLayoutW
fromMaybe { head: H.div {} [], tail: [] } $ A.uncons children
pure $ R.fragment [ topBar { handed } [ topBarChild ], forestLayoutMain props mainChildren ]
forestLayoutRaw :: R2.Component ForestLayoutProps
forestLayoutRaw props = R.createElement forestLayoutRawCpt props
forestLayoutRawCpt :: R.Component ForestLayoutProps
forestLayoutRawCpt = R.hooksComponentWithModule thisModule "forestLayoutRaw" cpt
where
cpt { appReload
, asyncTasksRef
, backend
, frontends
, handed
, route
, sessions
, showLogin
, treeReloadRef } children = do
let ordering =
case fst handed of
LeftHanded -> A.reverse
RightHanded -> identity
pure $ R2.row $ ordering [
H.div { className: "col-md-2", style: { paddingTop: "60px" } } ([
forest { appReload
, asyncTasksRef
, backend
, frontends
, handed: fst handed
, route
, sessions
, showLogin
, treeReloadRef } ] <> children)
]
forestLayoutMain :: R2.Component ForestLayoutProps
forestLayoutMain props = R.createElement forestLayoutMainCpt props
......
......@@ -20,6 +20,7 @@ import Gargantext.Components.InputWithEnter (inputWithEnter)
import Gargantext.Components.Nodes.Annuaire.User.Contacts.Tabs as Tabs
import Gargantext.Components.Nodes.Annuaire.User.Contacts.Types (Contact(..), ContactData, ContactTouch(..), ContactWhere(..), ContactWho(..), HyperdataContact(..), HyperdataUser(..), _city, _country, _firstName, _labTeamDeptsJoinComma, _lastName, _mail, _office, _organizationJoinComma, _ouFirst, _phone, _role, _shared, _touch, _who, defaultContactTouch, defaultContactWhere, defaultContactWho, defaultHyperdataContact, defaultHyperdataUser)
import Gargantext.Components.Nodes.Lists.Types as NT
import Gargantext.Components.Nodes.Texts.Types as TT
import Gargantext.Ends (Frontends)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Prelude (Unit, bind, const, discard, pure, show, unit, ($), (+), (<$>), (<<<), (<>), (==))
......@@ -198,6 +199,8 @@ userLayoutWithKeyCpt = R.hooksComponentWithModule thisModule "userLayoutWithKey"
cacheState <- R.useState' NT.CacheOn
sidePanelTriggers <- TT.emptySidePanelTriggers
useLoader {nodeId, reload: fst reload, session} getContactWithReload $
\contactData@{contactNode: Contact {name, hyperdata}} ->
H.ul { className: "col-md-12 list-group" } [
......@@ -210,13 +213,13 @@ userLayoutWithKeyCpt = R.hooksComponentWithModule thisModule "userLayoutWithKey"
, frontends
, nodeId
, session
, sidePanelTriggers
, treeReloadRef
}
]
where
onUpdateHyperdata :: ReloadS -> HyperdataUser -> Effect Unit
onUpdateHyperdata (_ /\ setReload) hd = do
log2 "[onUpdateHyperdata] hd" hd
launchAff_ $ do
_ <- saveContactHyperdata session nodeId hd
liftEffect $ setReload $ (+) 1
......@@ -256,6 +259,8 @@ annuaireUserLayoutCpt = R.hooksComponentWithModule thisModule "annuaireUserLayou
cpt { annuaireId, appReload, asyncTasksRef, frontends, nodeId, session, treeReloadRef } _ = do
cacheState <- R.useState' NT.CacheOn
sidePanelTriggers <- TT.emptySidePanelTriggers
useLoader nodeId (getAnnuaireContact session annuaireId) $
\contactData@{contactNode: Contact {name, hyperdata}} ->
H.ul { className: "col-md-12 list-group" } [
......@@ -268,6 +273,7 @@ annuaireUserLayoutCpt = R.hooksComponentWithModule thisModule "annuaireUserLayou
, frontends
, nodeId
, session
, sidePanelTriggers
, treeReloadRef
}
]
......
......@@ -7,6 +7,7 @@ import Data.Generic.Rep.Show (genericShow)
import Data.Maybe (Maybe(..))
import Data.Tuple (fst)
import Data.Tuple.Nested ((/\))
import Effect (Effect)
import Reactix as R
import Gargantext.AsyncTasks as GAT
......@@ -16,9 +17,10 @@ import Gargantext.Components.NgramsTable.Core as NTC
import Gargantext.Components.Tab as Tab
import Gargantext.Components.Nodes.Annuaire.User.Contacts.Types (ContactData)
import Gargantext.Components.Nodes.Lists.Types as NTypes
import Gargantext.Components.Nodes.Texts.Types (SidePanelTriggers)
import Gargantext.Ends (Frontends)
import Gargantext.Sessions (Session)
import Gargantext.Types (ReloadS, TabType(..), TabSubType(..), CTabNgramType(..), PTabNgramType(..))
import Gargantext.Types (CTabNgramType(..), NodeID, PTabNgramType(..), ReloadS, TabType(..), TabSubType(..))
thisModule :: String
thisModule = "Gargantext.Components.Nodes.Annuaire.User.Contacts.Tabs"
......@@ -45,14 +47,15 @@ modeTabType' Books = CTabAuthors
modeTabType' Communication = CTabAuthors
type TabsProps = (
appReload :: ReloadS
, asyncTasksRef :: R.Ref (Maybe GAT.Reductor)
, cacheState :: R.State NTypes.CacheState
, contactData :: ContactData
, frontends :: Frontends
, nodeId :: Int
, session :: Session
, treeReloadRef :: R.Ref (Maybe ReloadS)
appReload :: ReloadS
, asyncTasksRef :: R.Ref (Maybe GAT.Reductor)
, cacheState :: R.State NTypes.CacheState
, contactData :: ContactData
, frontends :: Frontends
, nodeId :: Int
, session :: Session
, sidePanelTriggers :: Record SidePanelTriggers
, treeReloadRef :: R.Ref (Maybe ReloadS)
)
tabs :: Record TabsProps -> R.Element
......@@ -61,7 +64,15 @@ tabs props = R.createElement tabsCpt props []
tabsCpt :: R.Component TabsProps
tabsCpt = R.hooksComponentWithModule thisModule "tabs" cpt
where
cpt { appReload, asyncTasksRef, cacheState, contactData: {defaultListId}, frontends, nodeId, session, treeReloadRef } _ = do
cpt { appReload
, asyncTasksRef
, cacheState
, contactData: {defaultListId}
, frontends
, nodeId
, session
, sidePanelTriggers
, treeReloadRef } _ = do
active <- R.useState' 0
pure $
Tab.tabs { selected: fst active, tabs: tabs' }
......@@ -74,9 +85,32 @@ tabsCpt = R.hooksComponentWithModule thisModule "tabs" cpt
, "Trash" /\ docs -- TODO pass-in trash mode
]
where
patentsView = { appReload, asyncTasksRef, cacheState, defaultListId, mode: Patents, nodeId, session, treeReloadRef }
booksView = { appReload, asyncTasksRef, cacheState, defaultListId, mode: Books, nodeId, session, treeReloadRef }
commView = { appReload, asyncTasksRef, cacheState, defaultListId, mode: Communication, nodeId, session, treeReloadRef }
patentsView = { appReload
, asyncTasksRef
, cacheState
, defaultListId
, mode: Patents
, nodeId
, session
, sidePanelTriggers
, treeReloadRef }
booksView = { appReload
, asyncTasksRef
, cacheState
, defaultListId
, mode: Books
, nodeId
, session
, sidePanelTriggers
, treeReloadRef }
commView = { appReload, asyncTasksRef
, cacheState
, defaultListId
, mode: Communication
, nodeId
, session
, sidePanelTriggers
, treeReloadRef }
chart = mempty
totalRecords = 4736 -- TODO
docs = DT.docViewLayout
......@@ -88,6 +122,7 @@ tabsCpt = R.hooksComponentWithModule thisModule "tabs" cpt
, nodeId
, session
, showSearch: true
, sidePanelTriggers
, tabType: TabPairing TabDocs
, totalRecords
}
......@@ -101,6 +136,7 @@ type NgramsViewTabsProps = (
, mode :: Mode
, nodeId :: Int
, session :: Session
, sidePanelTriggers :: Record SidePanelTriggers
, treeReloadRef :: R.Ref (Maybe ReloadS)
)
......
......@@ -28,7 +28,7 @@ import Gargantext.Components.Tab as Tab
import Gargantext.Components.Table as Table
import Gargantext.Ends (Frontends)
import Gargantext.Sessions (Session, Sessions, sessionId, getCacheState, setCacheState)
import Gargantext.Types (CTabNgramType(..), Handed(..), ReloadS, TabSubType(..), TabType(..))
import Gargantext.Types (CTabNgramType(..), Handed(..), NodeID, ReloadS, TabSubType(..), TabType(..))
import Gargantext.Utils.Reactix as R2
thisModule :: String
......@@ -52,21 +52,31 @@ textsWithForestCpt = R.hooksComponentWithModule thisModule "textsWithForest" cpt
pure $ Forest.forestLayoutWithTopBar forestProps [
topBar { controls } []
, textsLayout (Record.merge textsProps { controls }) []
, H.div {className: "col-md-10"} [
H.div {id: "page-wrapper"} [
H.div {className: "container-fluid"} [
textsLayout (Record.merge textsProps { controls }) []
]
]
]
, sidePanel { controls } []
]
--------------------------------------------------------
type TextsLayoutControls = (
showSidePanel :: R.State SidePanelState
showSidePanel :: R.State SidePanelState
, triggers :: Record SidePanelTriggers
)
initialControls :: R.Hooks (Record TextsLayoutControls)
initialControls = do
showSidePanel <- R.useState' InitialClosed
showSidePanel <- R.useState' InitialClosed
triggers <- emptySidePanelTriggers
pure $ {
showSidePanel
showSidePanel
, triggers
}
type TopBarProps = (
......@@ -96,7 +106,7 @@ type CommonProps = (
)
type Props = (
controls :: Record TextsLayoutControls
controls :: Record TextsLayoutControls
| CommonProps
)
......@@ -127,7 +137,7 @@ textsLayoutWithKey = R.createElement textsLayoutWithKeyCpt
textsLayoutWithKeyCpt :: R.Component KeyProps
textsLayoutWithKeyCpt = R.hooksComponentWithModule thisModule "textsLayoutWithKey" cpt
where
cpt { frontends, nodeId, session, sessionUpdate } _children = do
cpt { controls, frontends, nodeId, session, sessionUpdate } _children = do
cacheState <- R.useState' $ getCacheState NT.CacheOff session nodeId
pure $ loader { nodeId, session } loadCorpusWithChild $
......@@ -145,7 +155,12 @@ textsLayoutWithKeyCpt = R.hooksComponentWithModule thisModule "textsLayoutWithKe
, query
, title
, user: authors }
, tabs { cacheState, corpusData, corpusId, frontends, session }
, tabs { cacheState
, corpusData
, corpusId
, frontends
, session
, sidePanelTriggers: controls.triggers }
]
where
afterCacheStateChange cacheState = do
......@@ -166,11 +181,12 @@ modeTabType MoreLikeFav = CTabAuthors -- TODO
modeTabType MoreLikeTrash = CTabSources -- TODO
type TabsProps = (
cacheState :: R.State NT.CacheState
, corpusData :: CorpusData
, corpusId :: Int
, frontends :: Frontends
, session :: Session
cacheState :: R.State NT.CacheState
, corpusData :: CorpusData
, corpusId :: Int
, frontends :: Frontends
, session :: Session
, sidePanelTriggers :: Record SidePanelTriggers
)
tabs :: Record TabsProps -> R.Element
......@@ -179,7 +195,7 @@ tabs props = R.createElement tabsCpt props []
tabsCpt :: R.Component TabsProps
tabsCpt = R.hooksComponentWithModule thisModule "tabs" cpt
where
cpt { cacheState, corpusId, corpusData, frontends, session } _ = do
cpt { cacheState, corpusId, corpusData, frontends, session, sidePanelTriggers } _ = do
(selected /\ setSelected) <- R.useState' 0
let path = initialPath
......@@ -205,16 +221,18 @@ tabsCpt = R.hooksComponentWithModule thisModule "tabs" cpt
, frontends
-- , path
, session
, tabType }
, tabType
, sidePanelTriggers }
type DocViewProps a = (
cacheState :: R.State NT.CacheState
, corpusData :: CorpusData
, corpusId :: Int
, frontends :: Frontends
-- , path :: Record DT.Path
, session :: Session
, tabType :: TabSubType a
cacheState :: R.State NT.CacheState
, corpusData :: CorpusData
, corpusId :: Int
, frontends :: Frontends
-- , path :: Record DT.Path
, session :: Session
, tabType :: TabSubType a
, sidePanelTriggers :: Record SidePanelTriggers
)
docView :: forall a. Record (DocViewProps a) -> R.Element
......@@ -227,7 +245,13 @@ docViewCpt = R.hooksComponentWithModule thisModule "docView" cpt
pure $ DT.docViewLayout $ docViewLayoutRec props
-- docViewLayoutRec :: forall a. DocViewProps a -> Record DT.LayoutProps
docViewLayoutRec { cacheState, corpusData: { defaultListId }, corpusId, frontends, session, tabType: TabDocs } =
docViewLayoutRec { cacheState
, corpusData: { defaultListId }
, corpusId
, frontends
, session
, tabType: TabDocs
, sidePanelTriggers } =
{ cacheState
, chart : H.div {} []
, corpusId: Just corpusId
......@@ -237,10 +261,17 @@ docViewLayoutRec { cacheState, corpusData: { defaultListId }, corpusId, frontend
-- ^ TODO merge nodeId and corpusId in DT
, session
, showSearch: true
, sidePanelTriggers
, tabType: TabCorpus TabDocs
, totalRecords: 4737
}
docViewLayoutRec { cacheState, corpusData: { defaultListId }, corpusId, frontends, session, tabType: TabMoreLikeFav } =
docViewLayoutRec { cacheState
, corpusData: { defaultListId }
, corpusId
, frontends
, session
, tabType: TabMoreLikeFav
, sidePanelTriggers } =
{ cacheState
, chart : H.div {} []
, corpusId: Just corpusId
......@@ -250,10 +281,17 @@ docViewLayoutRec { cacheState, corpusData: { defaultListId }, corpusId, frontend
-- ^ TODO merge nodeId and corpusId in DT
, session
, showSearch: false
, sidePanelTriggers
, tabType: TabCorpus TabMoreLikeFav
, totalRecords: 4737
}
docViewLayoutRec { cacheState, corpusData: { defaultListId }, corpusId, frontends, session, tabType: TabMoreLikeTrash } =
docViewLayoutRec { cacheState
, corpusData: { defaultListId }
, corpusId
, frontends
, session
, tabType: TabMoreLikeTrash
, sidePanelTriggers } =
{ cacheState
, chart : H.div {} []
, corpusId: Just corpusId
......@@ -263,10 +301,17 @@ docViewLayoutRec { cacheState, corpusData: { defaultListId }, corpusId, frontend
-- ^ TODO merge nodeId and corpusId in DT
, session
, showSearch: false
, sidePanelTriggers
, tabType: TabCorpus TabMoreLikeTrash
, totalRecords: 4737
}
docViewLayoutRec { cacheState, corpusData: { defaultListId }, corpusId, frontends, session, tabType: TabTrash } =
docViewLayoutRec { cacheState
, corpusData: { defaultListId }
, corpusId
, frontends
, session
, tabType: TabTrash
, sidePanelTriggers } =
{ cacheState
, chart : H.div {} []
, corpusId: Nothing
......@@ -276,11 +321,18 @@ docViewLayoutRec { cacheState, corpusData: { defaultListId }, corpusId, frontend
-- ^ TODO merge nodeId and corpusId in DT
, session
, showSearch: true
, sidePanelTriggers
, tabType: TabCorpus TabTrash
, totalRecords: 4737
}
-- DUMMY
docViewLayoutRec { cacheState, corpusData: { defaultListId }, corpusId, frontends, session, tabType } =
docViewLayoutRec { cacheState
, corpusData: { defaultListId }
, corpusId
, frontends
, session
, tabType
, sidePanelTriggers } =
{ cacheState
, chart : H.div {} []
, corpusId: Nothing
......@@ -290,6 +342,29 @@ docViewLayoutRec { cacheState, corpusData: { defaultListId }, corpusId, frontend
-- ^ TODO merge nodeId and corpusId in DT
, session
, showSearch: true
, sidePanelTriggers
, tabType: TabCorpus TabTrash
, totalRecords: 4737
}
--------------------------------------------------------
type SidePanelProps = (
controls :: Record TextsLayoutControls
)
sidePanel :: R2.Component SidePanelProps
sidePanel = R.createElement sidePanelCpt
sidePanelCpt :: R.Component SidePanelProps
sidePanelCpt = R.hooksComponentWithModule thisModule "sidePanel" cpt
where
cpt { controls: { showSidePanel: (InitialClosed /\ _) } } _ = do
pure $ H.div {} []
cpt { controls: { showSidePanel: (Closed /\ _) } } _ = do
pure $ H.div {} []
cpt { controls: { showSidePanel: (Opened /\ _) } } _ = do
pure $ H.div { className: "side-bar" } [
H.h4 {} [ H.text "Side Bar" ]
]
......@@ -28,5 +28,5 @@ sidePanelToggleButtonCpt = R.hooksComponentWithModule thisModule "sidePanelToggl
H.button { className: "btn btn-primary"
, on: { click: \_ -> setOpen $ toggleSidePanelState } } [ H.text (text open) ]
text InitialClosed = "Show Side Panel"
text Opened = "Show Side Panel"
text Closed = "Hide Side Panel"
text Opened = "Hide Side Panel"
text Closed = "Show Side Panel"
module Gargantext.Components.Nodes.Texts.Types where
import Data.Maybe (Maybe(..))
import Effect (Effect)
import Reactix as R
import Gargantext.Prelude
import Gargantext.Types (NodeID)
data SidePanelState = InitialClosed | Opened | Closed
derive instance eqSidePanelState :: Eq SidePanelState
......@@ -9,3 +15,16 @@ toggleSidePanelState :: SidePanelState -> SidePanelState
toggleSidePanelState InitialClosed = Opened
toggleSidePanelState Closed = Opened
toggleSidePanelState Opened = Closed
type SidePanelTriggers = (
triggerAnnotatedDocIdChange :: R.Ref (Maybe (NodeID -> Effect Unit))
)
emptySidePanelTriggers :: R.Hooks (Record SidePanelTriggers)
emptySidePanelTriggers = do
triggerAnnotatedDocIdChange <- R.useRef Nothing
pure $ {
triggerAnnotatedDocIdChange
}
......@@ -4,11 +4,13 @@ module Gargantext.Components.Search where
import Data.Argonaut as Argonaut
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Gargantext.Utils.Argonaut (genericSumDecodeJson, genericSumEncodeJson, genericEnumDecodeJson, genericEnumEncodeJson)
import Gargantext.Components.Category (Category)
import Data.Maybe (Maybe(..))
import Gargantext.Prelude (class Eq, class Read, class Show)
import Gargantext.Components.Category.Types (Category)
import Gargantext.Utils.Argonaut (genericSumDecodeJson, genericSumEncodeJson, genericEnumDecodeJson, genericEnumEncodeJson)
-- Example:
-- [["machine","learning"],["artificial","intelligence"]]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment