Commit 2a38dd0a authored by Karen Konou's avatar Karen Konou

Folder actions: basic functionality

parent e1410493
...@@ -4,4 +4,10 @@ exports.back = function() { ...@@ -4,4 +4,10 @@ exports.back = function() {
return function() { return function() {
history.back(); history.back();
} }
}
exports.link = function (url) {
return function() {
window.location.href = url
}
} }
\ No newline at end of file
module Gargantext.Components.FolderView where module Gargantext.Components.FolderView where
import DOM.Simple.Console (log, log2)
import Data.Array as A import Data.Array as A
import Data.Maybe (Maybe(..), fromMaybe) import Data.Maybe (Maybe(..), fromMaybe)
import Data.Nullable (null) import Data.Nullable (null)
import Data.Traversable (traverse_)
import Effect (Effect) import Effect (Effect)
import Effect.Aff (Aff) import Effect.Aff (Aff)
import Gargantext.Components.FolderView.Box (nodePopupView) import Effect.Class (liftEffect)
import Gargantext.AsyncTasks as GAT
import Gargantext.Components.Forest.Tree.Node.Action (Action(..))
import Gargantext.Components.Forest.Tree.Node.Action.Add (AddNodeValue(..), addNode)
import Gargantext.Components.Forest.Tree.Node.Action.Contact as Contact
import Gargantext.Components.Forest.Tree.Node.Action.Delete (deleteNode, unpublishNode)
import Gargantext.Components.Forest.Tree.Node.Action.Link (linkNodeReq)
import Gargantext.Components.Forest.Tree.Node.Action.Merge (mergeNodeReq)
import Gargantext.Components.Forest.Tree.Node.Action.Move (moveNodeReq)
import Gargantext.Components.Forest.Tree.Node.Action.Rename (RenameValue(..), rename)
import Gargantext.Components.Forest.Tree.Node.Action.Share as Share
import Gargantext.Components.Forest.Tree.Node.Action.Update (updateRequest)
import Gargantext.Components.Forest.Tree.Node.Action.Upload (uploadArbitraryFile, uploadFile)
import Gargantext.Components.Forest.Tree.Node.Box (nodePopupView)
import Gargantext.Components.Forest.Tree.Node.Tools.FTree (FTree, LNode(..), NTree(..), fTreeID) import Gargantext.Components.Forest.Tree.Node.Tools.FTree (FTree, LNode(..), NTree(..), fTreeID)
import Gargantext.Components.Forest.Tree.Node.Tools.SubTree.Types (SubTreeOut(..))
import Gargantext.Hooks.Loader (useLoader) import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Prelude (Ordering, Unit, bind, compare, discard, pure, unit, ($), (<$>), (<>)) import Gargantext.Prelude (Ordering, Unit, bind, compare, discard, pure, unit, void, ($), (<$>), (<>))
import Gargantext.Routes (AppRoute(Home), SessionRoute(..), appPath, nodeTypeAppRoute) import Gargantext.Routes (AppRoute(Home), SessionRoute(..), appPath, nodeTypeAppRoute)
import Gargantext.Sessions (Session, get, sessionId) import Gargantext.Sessions (Session, get, sessionId)
import Gargantext.Types (NodeType(..))
import Gargantext.Types as GT import Gargantext.Types as GT
import Gargantext.Utils.Popover as Popover import Gargantext.Utils.Popover as Popover
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Toestand as T2
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
import Record as Record
import Toestand as T
foreign import back :: Effect Unit foreign import back :: Effect Unit
foreign import link :: String -> Effect Unit
here :: R2.Here here :: R2.Here
here = R2.here "Gargantext.Components.FolderView" here = R2.here "Gargantext.Components.FolderView"
...@@ -26,6 +47,7 @@ type Props = ...@@ -26,6 +47,7 @@ type Props =
( nodeId :: Int ( nodeId :: Int
, session :: Session , session :: Session
, backFolder :: Boolean , backFolder :: Boolean
, tasks :: T.Box GAT.Storage
) )
data FolderStyle = FolderUp | FolderChild data FolderStyle = FolderUp | FolderChild
...@@ -35,9 +57,12 @@ folderView props = R.createElement folderViewCpt props [] ...@@ -35,9 +57,12 @@ folderView props = R.createElement folderViewCpt props []
folderViewCpt :: R.Component Props folderViewCpt :: R.Component Props
folderViewCpt = here.component "folderViewCpt" cpt where folderViewCpt = here.component "folderViewCpt" cpt where
cpt {nodeId, session, backFolder} _ = do cpt {nodeId, session, backFolder, tasks} _ = do
useLoader {nodeId, session, backFolder} loadFolders $ setPopoverRef <- R.useRef Nothing
\folders -> folderViewMain {folders, nodeId, session, backFolder} reload <- T.useBox T2.newReload
reload' <- T.useLive T.unequal reload
useLoader { nodeId, session, reload: reload'} loadFolders $
\folders -> folderViewMain {folders, nodeId, session, backFolder, tasks, reload, setPopoverRef}
type FolderViewProps = type FolderViewProps =
( (
...@@ -45,6 +70,9 @@ type FolderViewProps = ...@@ -45,6 +70,9 @@ type FolderViewProps =
, folders:: FTree , folders:: FTree
, session :: Session , session :: Session
, backFolder :: Boolean , backFolder :: Boolean
, tasks :: T.Box GAT.Storage
, reload :: T.Box T2.Reload
, setPopoverRef :: R.Ref (Maybe (Boolean -> Effect Unit))
) )
folderViewMain :: Record FolderViewProps -> R.Element folderViewMain :: Record FolderViewProps -> R.Element
...@@ -52,25 +80,31 @@ folderViewMain props = R.createElement folderViewMainCpt props [] ...@@ -52,25 +80,31 @@ folderViewMain props = R.createElement folderViewMainCpt props []
folderViewMainCpt :: R.Component FolderViewProps folderViewMainCpt :: R.Component FolderViewProps
folderViewMainCpt = here.component "folderViewMainCpt" cpt where folderViewMainCpt = here.component "folderViewMainCpt" cpt where
cpt {nodeId, session, backFolder, folders: (NTree (LNode {parent_id: parentId, nodeType}) (folders))} _ = do cpt {nodeId, session, backFolder, tasks, setPopoverRef, reload, folders: tree@(NTree (LNode {parent_id: parentId, nodeType}) (folders))} _ = do
setPopoverRef <- R.useRef Nothing
let sid = sessionId session
let foldersS = A.sortBy sortFolders folders let foldersS = A.sortBy sortFolders folders
let children = makeFolderElements foldersS sid setPopoverRef
let backHome = isBackHome nodeType let backHome = isBackHome nodeType
let parent = makeParentFolder parentId sid backFolder backHome let parent = makeParentFolder parentId session backFolder backHome
let children = makeFolderElements foldersS {session, setPopoverRef, nodeId, tasks, reload}
pure $ H.div {className: "fv folders"} $ parent <> children pure $ H.div {className: "fv folders"} $ parent <> children
makeFolderElements foldersS sid spr = makeFolderElementsMap <$> foldersS where makeFolderElements foldersS props = makeFolderElementsMap <$> foldersS where
makeFolderElementsMap :: NTree LNode -> R.Element makeFolderElementsMap :: NTree LNode -> R.Element
makeFolderElementsMap (NTree (LNode node) _) = folder {style: FolderChild, text: node.name, nodeId: node.id, nodeType: node.nodeType, sid: sid, setPopoverRef: spr} [] makeFolderElementsMap (NTree (LNode node) _) = folder {style: FolderChild
, text: node.name
makeParentFolder :: Maybe Int -> GT.SessionId -> Boolean -> Boolean -> Array R.Element , nodeId: node.id
makeParentFolder (Just parentId) sid _ _ = , nodeType: node.nodeType
, session: props.session
, setPopoverRef: props.setPopoverRef
, parentId: props.nodeId
, tasks: props.tasks
, reload: props.reload} []
makeParentFolder :: Maybe Int -> Session -> Boolean -> Boolean -> Array R.Element
makeParentFolder (Just parentId) session _ _ =
-- FIXME: The NodeType here should not be hardcoded to FolderPrivate but we currently can't get the actual NodeType -- FIXME: The NodeType here should not be hardcoded to FolderPrivate but we currently can't get the actual NodeType
-- without performing another API call. Also parentId is never being returned by this API even when it clearly exists -- without performing another API call. Also parentId is never being returned by this API even when it clearly exists
[ folderSimple {style: FolderUp, text: "..", nodeId: parentId, nodeType: GT.FolderPrivate, sid: sid} [] ] [ folderSimple {style: FolderUp, text: "..", nodeId: parentId, nodeType: GT.FolderPrivate, session: session} [] ]
makeParentFolder Nothing _ _ true = [ H.a {className: "btn btn-primary", href: appPath Home} [ H.i { className: "fa fa-folder-open" } [] makeParentFolder Nothing _ _ true = [ H.a {className: "btn btn-primary", href: appPath Home} [ H.i { className: "fa fa-folder-open" } []
, H.br {} , H.br {}
, H.text ".."] ] , H.text ".."] ]
...@@ -96,7 +130,7 @@ type FolderSimpleProps = ...@@ -96,7 +130,7 @@ type FolderSimpleProps =
, text :: String , text :: String
, nodeType :: GT.NodeType , nodeType :: GT.NodeType
, nodeId :: Int , nodeId :: Int
, sid :: GT.SessionId , session :: Session
) )
folderSimple :: R2.Component FolderSimpleProps folderSimple :: R2.Component FolderSimpleProps
...@@ -104,7 +138,8 @@ folderSimple = R.createElement folderSimpleCpt ...@@ -104,7 +138,8 @@ folderSimple = R.createElement folderSimpleCpt
folderSimpleCpt :: R.Component FolderSimpleProps folderSimpleCpt :: R.Component FolderSimpleProps
folderSimpleCpt = here.component "folderSimpleCpt" cpt where folderSimpleCpt = here.component "folderSimpleCpt" cpt where
cpt {style, text, nodeId, sid, nodeType} _ = do cpt {style, text, nodeId, session, nodeType} _ = do
let sid = sessionId session
pure $ H.a { className: "btn btn-primary" pure $ H.a { className: "btn btn-primary"
, href: "/#/" <> getFolderPath nodeType sid nodeId } , href: "/#/" <> getFolderPath nodeType sid nodeId }
[ H.i { className: icon style nodeType } [] [ H.i { className: icon style nodeType } []
...@@ -121,6 +156,9 @@ folderSimpleCpt = here.component "folderSimpleCpt" cpt where ...@@ -121,6 +156,9 @@ folderSimpleCpt = here.component "folderSimpleCpt" cpt where
type FolderProps = type FolderProps =
( (
setPopoverRef :: R.Ref (Maybe (Boolean -> Effect Unit)) setPopoverRef :: R.Ref (Maybe (Boolean -> Effect Unit))
, parentId :: Int
, tasks :: T.Box GAT.Storage
, reload :: T.Box T2.Reload
| FolderSimpleProps | FolderSimpleProps
) )
...@@ -129,25 +167,33 @@ folder = R.createElement folderCpt ...@@ -129,25 +167,33 @@ folder = R.createElement folderCpt
folderCpt :: R.Component FolderProps folderCpt :: R.Component FolderProps
folderCpt = here.component "folderCpt" cpt where folderCpt = here.component "folderCpt" cpt where
cpt props@{style, text, nodeId, sid, nodeType, setPopoverRef} _ = do cpt props@{style, text, nodeId, session, nodeType, setPopoverRef, parentId, tasks, reload} _ = do
let sid = sessionId session
let dispatch a = performAction a {setPopoverRef, session, nodeId, parentId, tasks, reload}
popoverRef <- R.useRef null popoverRef <- R.useRef null
buttonState <- T.useBox false
buttonState' <- T.useLive T.unequal buttonState
R.useEffect' $ do R.useEffect' $ do
R.setRef setPopoverRef $ Just $ Popover.setOpen popoverRef R.setRef setPopoverRef $ Just $ Popover.setOpen popoverRef
pure $ H.a {className: "btn btn-primary"} [ pure $
Popover.popover { arrow: false H.button {on: {click: link ("/#/" <> getFolderPath nodeType sid nodeId) }, className: "btn btn-primary", disabled: buttonState'} [
, open: false Popover.popover {
, onClose: \_ -> pure unit arrow: false
, onOpen: \_ -> pure unit , open: false
, ref: popoverRef } [ , onClose: \_ -> pure unit
popOverIcon , onOpen: \_ -> pure unit
, mNodePopupView props (onPopoverClose popoverRef) , ref: popoverRef
] } [
, H.i { className: icon style nodeType } [] popOverIcon buttonState
, H.br {} , mNodePopupView (Record.merge props {dispatch}) (onPopoverClose popoverRef)
, H.text text ] ]
, H.i {className: icon style nodeType} []
, H.br {}
, H.text text]
icon :: FolderStyle -> GT.NodeType -> String icon :: FolderStyle -> GT.NodeType -> String
icon FolderUp _ = "fa fa-folder-open" icon FolderUp _ = "fa fa-folder-open"
icon _ nodeType = GT.fldr nodeType false icon _ nodeType = GT.fldr nodeType false
...@@ -157,13 +203,21 @@ folderCpt = here.component "folderCpt" cpt where ...@@ -157,13 +203,21 @@ folderCpt = here.component "folderCpt" cpt where
onPopoverClose popoverRef _ = Popover.setOpen popoverRef false onPopoverClose popoverRef _ = Popover.setOpen popoverRef false
popOverIcon = H.div { className: "fv action" } [ popOverIcon buttonState = H.div { className: "fv action" } [
H.a { className: "settings fa fa-cog" H.a { className: "settings fa fa-cog"
, title : "Each node of the Tree can perform some actions.\n" , title : "Each node of the Tree can perform some actions.\n"
<> "Click here to execute one of them." } [] <> "Click here to execute one of them."
, on: {mouseEnter: \_ -> T.write_ true buttonState, mouseLeave: \_ -> T.write_ false buttonState}} []
] ]
mNodePopupView props opc = nodePopupView {onPopoverClose: opc, nodeType:props.nodeType, name: props.text, id: props.nodeId} mNodePopupView props opc = nodePopupView {onPopoverClose: opc
,nodeType: props.nodeType
, name: props.text
, id: props.nodeId
, dispatch: props.dispatch
, session: props.session
, handed: GT.RightHanded
}
backButton :: R.Element backButton :: R.Element
backButton = backButton =
...@@ -182,7 +236,113 @@ homeButton = ...@@ -182,7 +236,113 @@ homeButton =
} [ } [
H.i { className: "fa fa-home", title: "Back to home"} [] H.i { className: "fa fa-home", title: "Back to home"} []
] ]
loadFolders :: Record Props -> Aff FTree type LoadProps =
(
session :: Session,
nodeId :: Int,
reload :: T2.Reload
)
loadFolders :: Record LoadProps -> Aff FTree
loadFolders {nodeId, session} = get session $ TreeFirstLevel (Just nodeId) "" loadFolders {nodeId, session} = get session $ TreeFirstLevel (Just nodeId) ""
type PerformActionProps =
(
setPopoverRef :: R.Ref (Maybe (Boolean -> Effect Unit))
, session :: Session
, nodeId :: Int
, parentId :: Int
, tasks :: T.Box GAT.Storage
, reload :: T.Box T2.Reload
)
performAction :: Action -> Record PerformActionProps -> Aff Unit
performAction = performAction' where
performAction' (DeleteNode nt) p = deleteNode' nt p
performAction' (DoSearch task) p = doSearch task p
performAction' (UpdateNode params) p = updateNode params p
performAction' (RenameNode name) p = renameNode name p
performAction' (ShareTeam username) p = shareTeam username p
performAction' (SharePublic { params }) p = sharePublic params p
performAction' (AddContact params) p = addContact params p
performAction' (AddNode name nodeType) p = addNode' name nodeType p
performAction' (UploadFile nodeType fileType mName blob) p = uploadFile' nodeType fileType mName blob p
performAction' (UploadArbitraryFile mName blob) p = uploadArbitraryFile' mName blob p
performAction' DownloadNode _ = liftEffect $ log "[performAction] DownloadNode"
performAction' (MoveNode {params}) p = moveNode params p
performAction' (MergeNode {params}) p = mergeNode params p
performAction' (LinkNode { nodeType, params }) p = linkNode nodeType params p
performAction' NoAction _ = liftEffect $ log "[performAction] NoAction"
performAction' ClosePopover p = closePopover p
performAction' _ _ = liftEffect $ log "[performAction] unsupported action"
closePopover { setPopoverRef } =
liftEffect $ traverse_ (\set -> set false) (R.readRef setPopoverRef)
refreshFolders p = do
liftEffect $ T2.reload p.reload
closePopover p
deleteNode' nt p@{ nodeId: id, parentId: parent_id } = do
case nt of
NodePublic FolderPublic -> void $ deleteNode p.session nt id
NodePublic _ -> void $ unpublishNode p.session (Just parent_id) id
_ -> void $ deleteNode p.session nt id
refreshFolders p
doSearch task p@{ tasks, nodeId: id } = liftEffect $ do
GAT.insert id task tasks
log2 "[performAction] DoSearch task:" task
updateNode params p@{ tasks, nodeId: id } = do
task <- updateRequest params p.session id
liftEffect $ do
GAT.insert id task tasks
log2 "[performAction] UpdateNode task:" task
shareTeam username p@{ nodeId: id} =
void $ Share.shareReq p.session id $ Share.ShareTeamParams {username}
sharePublic params p = traverse_ f params where
f (SubTreeOut { in: inId, out }) = do
void $ Share.shareReq p.session inId $ Share.SharePublicParams { node_id: out }
refreshFolders p
addContact params p@{ nodeId: id } =
void $ Contact.contactReq p.session id params
uploadFile' nodeType fileType mName blob p@{ tasks, nodeId: id } = do
task <- uploadFile p.session nodeType id fileType {mName, blob}
liftEffect $ do
GAT.insert id task tasks
log2 "[performAction] UploadFile, uploaded, task:" task
uploadArbitraryFile' mName blob p@{ tasks, nodeId: id } = do
task <- uploadArbitraryFile p.session id { blob, mName }
liftEffect $ do
GAT.insert id task tasks
log2 "[performAction] UploadArbitraryFile, uploaded, task:" task
moveNode params p@{ session } = traverse_ f params where
f (SubTreeOut { in: in', out }) = do
void $ moveNodeReq p.session in' out
refreshFolders p
mergeNode params p = traverse_ f params where
f (SubTreeOut { in: in', out }) = do
void $ mergeNodeReq p.session in' out
refreshFolders p
linkNode nodeType params p = traverse_ f params where
f (SubTreeOut { in: in', out }) = do
void $ linkNodeReq p.session nodeType in' out
refreshFolders p
renameNode name p@{ nodeId: id } = do
void $ rename p.session id $ RenameValue { text: name }
refreshFolders p
addNode' name nodeType p@{ nodeId: id } = do
void $ addNode p.session id $ AddNodeValue {name, nodeType}
refreshFolders p
module Gargantext.Components.Forest.Tree.Node.Box where module Gargantext.Components.Forest.Tree.Node.Box where
import Gargantext.Prelude
import Data.Array as A import Data.Array as A
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..))
import Effect.Aff (Aff) import Effect.Aff (Aff)
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
import Gargantext.Prelude
import Gargantext.Components.Forest.Tree.Node.Action (Action(..)) import Gargantext.Components.Forest.Tree.Node.Action (Action(..))
import Gargantext.Components.Forest.Tree.Node.Action.Add (NodePopup(..), addNodeView) import Gargantext.Components.Forest.Tree.Node.Action.Add (NodePopup(..), addNodeView)
import Gargantext.Components.Forest.Tree.Node.Action.Contact as Contact
import Gargantext.Components.Forest.Tree.Node.Action.Delete (actionDelete) import Gargantext.Components.Forest.Tree.Node.Action.Delete (actionDelete)
import Gargantext.Components.Forest.Tree.Node.Action.Documentation (actionDoc) import Gargantext.Components.Forest.Tree.Node.Action.Documentation (actionDoc)
import Gargantext.Components.Forest.Tree.Node.Action.Download (actionDownload) import Gargantext.Components.Forest.Tree.Node.Action.Download (actionDownload)
import Gargantext.Components.Forest.Tree.Node.Action.Link (linkNode)
import Gargantext.Components.Forest.Tree.Node.Action.Merge (mergeNode)
import Gargantext.Components.Forest.Tree.Node.Action.Move (moveNode)
import Gargantext.Components.Forest.Tree.Node.Action.Rename (renameAction) import Gargantext.Components.Forest.Tree.Node.Action.Rename (renameAction)
import Gargantext.Components.Forest.Tree.Node.Action.Search (actionSearch) import Gargantext.Components.Forest.Tree.Node.Action.Search (actionSearch)
import Gargantext.Components.Forest.Tree.Node.Action.Share as Share import Gargantext.Components.Forest.Tree.Node.Action.Share as Share
import Gargantext.Components.Forest.Tree.Node.Action.Contact as Contact
import Gargantext.Components.Forest.Tree.Node.Action.Update (update) import Gargantext.Components.Forest.Tree.Node.Action.Update (update)
import Gargantext.Components.Forest.Tree.Node.Action.Upload (actionUpload) import Gargantext.Components.Forest.Tree.Node.Action.Upload (actionUpload)
import Gargantext.Components.Forest.Tree.Node.Action.Move (moveNode)
import Gargantext.Components.Forest.Tree.Node.Action.Link (linkNode)
import Gargantext.Components.Forest.Tree.Node.Action.Merge (mergeNode)
import Gargantext.Components.Forest.Tree.Node.Box.Types (NodePopupProps, NodePopupS) import Gargantext.Components.Forest.Tree.Node.Box.Types (NodePopupProps, NodePopupS)
import Gargantext.Components.Forest.Tree.Node.Settings import Gargantext.Components.Forest.Tree.Node.Settings (NodeAction(..), SettingsBox(..), glyphiconNodeAction, settingsBox)
(NodeAction(..), SettingsBox(..), glyphiconNodeAction, settingsBox)
import Gargantext.Components.Forest.Tree.Node.Status (Status(..), hasStatus) import Gargantext.Components.Forest.Tree.Node.Status (Status(..), hasStatus)
import Gargantext.Components.Forest.Tree.Node.Tools (textInputBox, fragmentPT, panel) import Gargantext.Components.Forest.Tree.Node.Tools (textInputBox, fragmentPT, panel)
import Gargantext.Sessions (Session) import Gargantext.Sessions (Session)
...@@ -32,6 +28,9 @@ import Gargantext.Types (Name, ID, prettyNodeType) ...@@ -32,6 +28,9 @@ import Gargantext.Types (Name, ID, prettyNodeType)
import Gargantext.Types as GT import Gargantext.Types as GT
import Gargantext.Utils (glyphicon, glyphiconActive) import Gargantext.Utils (glyphicon, glyphiconActive)
import Gargantext.Utils.Reactix as R2 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
here = R2.here "Gargantext.Components.Forest.Tree.Node.Box" here = R2.here "Gargantext.Components.Forest.Tree.Node.Box"
...@@ -82,7 +81,7 @@ nodePopupCpt = here.component "nodePopupView" cpt where ...@@ -82,7 +81,7 @@ nodePopupCpt = here.component "nodePopupView" cpt where
, title : "Rename", on: { click: \_ -> T.write_ true isOpen } } [] , title : "Rename", on: { click: \_ -> T.write_ true isOpen } } []
panelBody :: T.Box (Maybe NodeAction) -> Record NodePopupProps -> R.Element panelBody :: T.Box (Maybe NodeAction) -> Record NodePopupProps -> R.Element
panelBody nodePopupState {dispatch: d, nodeType} = panelBody nodePopupState {dispatch: d, nodeType} =
let (SettingsBox { edit, doc, buttons }) = settingsBox nodeType in let (SettingsBox { edit, doc, buttons}) = settingsBox nodeType in
H.div {className: "card-body flex-space-between"} H.div {className: "card-body flex-space-between"}
$ [ H.p { className: "spacer" } [] $ [ H.p { className: "spacer" } []
, H.div { className: "flex-center" } , H.div { className: "flex-center" }
......
...@@ -17,6 +17,7 @@ import Effect.Class (liftEffect) ...@@ -17,6 +17,7 @@ import Effect.Class (liftEffect)
import Effect.Exception (error) import Effect.Exception (error)
import Gargantext.Components.CodeEditor as CE import Gargantext.Components.CodeEditor as CE
import Gargantext.Components.FolderView as FV import Gargantext.Components.FolderView as FV
import Gargantext.AsyncTasks as GAT
import Gargantext.Components.InputWithEnter (inputWithEnter) import Gargantext.Components.InputWithEnter (inputWithEnter)
import Gargantext.Components.Node (NodePoly(..), HyperdataList) import Gargantext.Components.Node (NodePoly(..), HyperdataList)
import Gargantext.Components.Nodes.Corpus.Types (CorpusData, Hyperdata(..)) import Gargantext.Components.Nodes.Corpus.Types (CorpusData, Hyperdata(..))
...@@ -37,15 +38,15 @@ import Toestand as T ...@@ -37,15 +38,15 @@ import Toestand as T
here :: R2.Here here :: R2.Here
here = R2.here "Gargantext.Components.Nodes.Corpus" here = R2.here "Gargantext.Components.Nodes.Corpus"
type Props = ( nodeId :: Int, session :: Session ) type Props = ( nodeId :: Int, session :: Session, tasks :: T.Box GAT.Storage )
corpusLayout :: R2.Leaf Props corpusLayout :: R2.Leaf Props
corpusLayout props = R.createElement corpusLayoutCpt props [] corpusLayout props = R.createElement corpusLayoutCpt props []
corpusLayoutCpt :: R.Component Props corpusLayoutCpt :: R.Component Props
corpusLayoutCpt = here.component "corpusLayout" cpt where corpusLayoutCpt = here.component "corpusLayout" cpt where
cpt { nodeId, session } _ = do cpt { nodeId, session, tasks } _ = do
pure $ corpusLayoutMain { key, nodeId, session } pure $ corpusLayoutMain { key, nodeId, session, tasks }
where where
key = show (sessionId session) <> "-" <> show nodeId key = show (sessionId session) <> "-" <> show nodeId
...@@ -53,6 +54,7 @@ type KeyProps = ...@@ -53,6 +54,7 @@ type KeyProps =
( nodeId :: Int ( nodeId :: Int
, key :: String , key :: String
, session :: Session , session :: Session
, tasks :: T.Box GAT.Storage
) )
corpusLayoutMain :: R2.Leaf KeyProps corpusLayoutMain :: R2.Leaf KeyProps
...@@ -61,7 +63,7 @@ corpusLayoutMain props = R.createElement corpusLayoutMainCpt props [] ...@@ -61,7 +63,7 @@ corpusLayoutMain props = R.createElement corpusLayoutMainCpt props []
corpusLayoutMainCpt :: R.Component KeyProps corpusLayoutMainCpt :: R.Component KeyProps
corpusLayoutMainCpt = here.component "corpusLayoutMain" cpt corpusLayoutMainCpt = here.component "corpusLayoutMain" cpt
where where
cpt { nodeId, key, session } _ = do cpt { nodeId, key, session, tasks } _ = do
viewType <- T.useBox Folders viewType <- T.useBox Folders
pure $ H.div {} [ pure $ H.div {} [
...@@ -71,7 +73,7 @@ corpusLayoutMainCpt = here.component "corpusLayoutMain" cpt ...@@ -71,7 +73,7 @@ corpusLayoutMainCpt = here.component "corpusLayoutMain" cpt
, H.div { className: "col-1" } [ FV.homeButton ] , H.div { className: "col-1" } [ FV.homeButton ]
] ]
] ]
, H.div {} [corpusLayoutSelection {state: viewType, key, session, nodeId}] , H.div {} [corpusLayoutSelection {state: viewType, key, session, nodeId, tasks}]
] ]
type SelectionProps = type SelectionProps =
...@@ -79,6 +81,7 @@ type SelectionProps = ...@@ -79,6 +81,7 @@ type SelectionProps =
, key :: String , key :: String
, session :: Session , session :: Session
, state :: T.Box ViewType , state :: T.Box ViewType
, tasks :: T.Box GAT.Storage
) )
corpusLayoutSelection :: R2.Leaf SelectionProps corpusLayoutSelection :: R2.Leaf SelectionProps
...@@ -86,20 +89,25 @@ corpusLayoutSelection props = R.createElement corpusLayoutSelectionCpt props [] ...@@ -86,20 +89,25 @@ corpusLayoutSelection props = R.createElement corpusLayoutSelectionCpt props []
corpusLayoutSelectionCpt :: R.Component SelectionProps corpusLayoutSelectionCpt :: R.Component SelectionProps
corpusLayoutSelectionCpt = here.component "corpusLayoutSelection" cpt where corpusLayoutSelectionCpt = here.component "corpusLayoutSelection" cpt where
cpt { nodeId, session, key, state} _ = do cpt { nodeId, session, key, state, tasks} _ = do
state' <- T.useLive T.unequal state state' <- T.useLive T.unequal state
viewType <- T.read state viewType <- T.read state
pure $ renderContent viewType nodeId session key pure $ renderContent viewType nodeId session key tasks
renderContent Folders nodeId session key = FV.folderView { nodeId, session, backFolder: true } renderContent Folders nodeId session key tasks = FV.folderView { nodeId, session, backFolder: true, tasks }
renderContent Code nodeId session key = corpusLayoutWithKey { key, nodeId, session } renderContent Code nodeId session key tasks = corpusLayoutWithKey { key, nodeId, session }
type CorpusKeyProps =
( nodeId :: Int
, key :: String
, session :: Session
)
corpusLayoutWithKey :: R2.Leaf KeyProps corpusLayoutWithKey :: R2.Leaf CorpusKeyProps
corpusLayoutWithKey props = R.createElement corpusLayoutWithKeyCpt props [] corpusLayoutWithKey props = R.createElement corpusLayoutWithKeyCpt props []
corpusLayoutWithKeyCpt :: R.Component KeyProps corpusLayoutWithKeyCpt :: R.Component CorpusKeyProps
corpusLayoutWithKeyCpt = here.component "corpusLayoutWithKey" cpt where corpusLayoutWithKeyCpt = here.component "corpusLayoutWithKey" cpt where
cpt { nodeId, session } _ = do cpt { nodeId, session } _ = do
reload <- T.useBox T2.newReload reload <- T.useBox T2.newReload
......
...@@ -6,6 +6,7 @@ import Data.Array as Array ...@@ -6,6 +6,7 @@ import Data.Array as Array
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..))
import Data.Newtype (class Newtype) import Data.Newtype (class Newtype)
import Effect (Effect) import Effect (Effect)
import Gargantext.AsyncTasks as GAT
import Gargantext.Components.Data.Landing (BlockText(..), BlockTexts(..), Button(..), LandingData(..)) import Gargantext.Components.Data.Landing (BlockText(..), BlockTexts(..), Button(..), LandingData(..))
import Gargantext.Components.FolderView as FV import Gargantext.Components.FolderView as FV
import Gargantext.Components.Lang (LandingLang(..)) import Gargantext.Components.Lang (LandingLang(..))
...@@ -57,6 +58,7 @@ type HomeProps s l = ...@@ -57,6 +58,7 @@ type HomeProps s l =
, lang :: LandingLang , lang :: LandingLang
, sessions :: s , sessions :: s
, showLogin :: l , showLogin :: l
, tasks :: T.Box GAT.Storage
) )
homeLayout :: forall s l. T.Read s Sessions => T.ReadWrite l Boolean homeLayout :: forall s l. T.Read s Sessions => T.ReadWrite l Boolean
...@@ -66,7 +68,7 @@ homeLayoutCpt :: forall s l. T.Read s Sessions => T.ReadWrite l Boolean ...@@ -66,7 +68,7 @@ homeLayoutCpt :: forall s l. T.Read s Sessions => T.ReadWrite l Boolean
=> R.Component (HomeProps s l) => R.Component (HomeProps s l)
homeLayoutCpt = here.component "homeLayout" cpt homeLayoutCpt = here.component "homeLayout" cpt
where where
cpt { backend, lang, sessions, showLogin } _ = do cpt { backend, lang, sessions, showLogin, tasks} _ = do
backend' <- T.useLive T.unequal backend backend' <- T.useLive T.unequal backend
sessions' <- T.useLive T.unequal sessions sessions' <- T.useLive T.unequal sessions
let landingData = langLandingData lang let landingData = langLandingData lang
...@@ -75,7 +77,7 @@ homeLayoutCpt = here.component "homeLayout" cpt ...@@ -75,7 +77,7 @@ homeLayoutCpt = here.component "homeLayout" cpt
[ H.div { className: "home-title container1" } [ H.div { className: "home-title container1" }
[ jumboTitle landingData ] [ jumboTitle landingData ]
, H.div { className: "home-research-form container1" } [] -- TODO , H.div { className: "home-research-form container1" } [] -- TODO
, joinButtonOrTutorial sessions' (click backend') , joinButtonOrTutorial tasks sessions' (click backend')
, H.div { className: "home-public container1" } , H.div { className: "home-public container1" }
[ renderPublic { } [ renderPublic { }
, H.div { className:"col-12 d-flex justify-content-center" } , H.div { className:"col-12 d-flex justify-content-center" }
...@@ -96,11 +98,11 @@ homeLayoutCpt = here.component "homeLayout" cpt ...@@ -96,11 +98,11 @@ homeLayoutCpt = here.component "homeLayout" cpt
T.write_ true showLogin T.write_ true showLogin
Just b -> T.write_ true showLogin Just b -> T.write_ true showLogin
joinButtonOrTutorial :: forall e. Sessions -> (e -> Effect Unit) -> R.Element joinButtonOrTutorial :: forall e. T.Box GAT.Storage -> Sessions -> (e -> Effect Unit) -> R.Element
joinButtonOrTutorial sessions click = joinButtonOrTutorial tasks sessions click =
if Sessions.null sessions if Sessions.null sessions
then joinButton click then joinButton click
else tutorial {sessions: Sessions.unSessions sessions} else tutorial {tasks, sessions: Sessions.unSessions sessions}
joinButton :: forall e. (e -> Effect Unit) -> R.Element joinButton :: forall e. (e -> Effect Unit) -> R.Element
joinButton click = joinButton click =
...@@ -146,12 +148,12 @@ summary = ...@@ -146,12 +148,12 @@ summary =
, H.ol {} (map toSummary tutos) ] ] , H.ol {} (map toSummary tutos) ] ]
toSummary (Tuto x) = H.li {} [ H.a {href: "#" <> x.id} [ H.text x.title ]] toSummary (Tuto x) = H.li {} [ H.a {href: "#" <> x.id} [ H.text x.title ]]
tutorial :: R2.Leaf (sessions :: Array Session) tutorial :: R2.Leaf (sessions :: Array Session, tasks :: T.Box GAT.Storage)
tutorial props = R.createElement tutorialCpt props [] tutorial props = R.createElement tutorialCpt props []
tutorialCpt :: R.Component (sessions :: Array Session) tutorialCpt :: R.Component (sessions :: Array Session, tasks:: T.Box GAT.Storage)
tutorialCpt = here.component "tutorial" cpt where tutorialCpt = here.component "tutorial" cpt where
cpt {sessions} _ = do cpt {sessions, tasks} _ = do
let folders = makeFolders sessions let folders = makeFolders sessions
pure $ H.div { className: "mx-auto container" } pure $ H.div { className: "mx-auto container" }
...@@ -176,7 +178,7 @@ tutorialCpt = here.component "tutorial" cpt where ...@@ -176,7 +178,7 @@ tutorialCpt = here.component "tutorial" cpt where
sessionToFolder session@(Session {treeId, username, backend: (Backend {name})}) = sessionToFolder session@(Session {treeId, username, backend: (Backend {name})}) =
H.tr {} [ H.tr {} [
H.div { className: "d-flex justify-content-center" } [ H.text (username <> "@" <> name) ] H.div { className: "d-flex justify-content-center" } [ H.text (username <> "@" <> name) ]
, H.div {} [ FV.folderView {session, nodeId: treeId, backFolder: false} ] ] , H.div {} [ FV.folderView {session, tasks, nodeId: treeId, backFolder: false} ] ]
startTutos :: Array Tuto startTutos :: Array Tuto
startTutos = startTutos =
......
...@@ -279,7 +279,7 @@ corpusCpt = here.component "corpus" cpt where ...@@ -279,7 +279,7 @@ corpusCpt = here.component "corpus" cpt where
cpt props@{ boxes, nodeId } _ = do cpt props@{ boxes, nodeId } _ = do
let sessionProps = RE.pick props :: Record SessionProps let sessionProps = RE.pick props :: Record SessionProps
pure $ authed (Record.merge { content: \session -> pure $ authed (Record.merge { content: \session ->
corpusLayout { nodeId, session } } sessionProps) [] corpusLayout { nodeId, session, tasks: boxes.tasks } } sessionProps) []
type CorpusDocumentProps = type CorpusDocumentProps =
( corpusId :: CorpusId ( corpusId :: CorpusId
...@@ -340,8 +340,8 @@ home :: R2.Component Props ...@@ -340,8 +340,8 @@ home :: R2.Component Props
home = R.createElement homeCpt home = R.createElement homeCpt
homeCpt :: R.Component Props homeCpt :: R.Component Props
homeCpt = here.component "home" cpt where homeCpt = here.component "home" cpt where
cpt props@{ boxes: boxes@{ backend, sessions, showLogin } } _ = do cpt props@{ boxes: boxes@{ backend, sessions, showLogin, tasks } } _ = do
pure $ homeLayout { backend, lang: LL_EN, sessions, showLogin } pure $ homeLayout { backend, lang: LL_EN, sessions, showLogin, tasks }
lists :: R2.Component SessionNodeProps lists :: R2.Component SessionNodeProps
lists = R.createElement listsCpt lists = R.createElement listsCpt
...@@ -410,7 +410,7 @@ teamCpt = here.component "team" cpt where ...@@ -410,7 +410,7 @@ teamCpt = here.component "team" cpt where
cpt props@{ boxes, nodeId } _ = do cpt props@{ boxes, nodeId } _ = do
let sessionProps = RE.pick props :: Record SessionProps let sessionProps = RE.pick props :: Record SessionProps
pure $ authed (Record.merge { content: \session -> pure $ authed (Record.merge { content: \session ->
corpusLayout { nodeId, session } } sessionProps) [] corpusLayout { nodeId, session, tasks: boxes.tasks} } sessionProps) []
texts :: R2.Component SessionNodeProps texts :: R2.Component SessionNodeProps
texts = R.createElement textsCpt texts = R.createElement textsCpt
......
...@@ -6,4 +6,5 @@ ...@@ -6,4 +6,5 @@
.fv.action .fv.action
position: relative position: relative
left: 30px left: 30px
\ No newline at end of file color: white
\ No newline at end of file
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