Tree.purs 4.57 KB
Newer Older
1 2 3
module Gargantext.Components.Forest.Tree where

import DOM.Simple.Console (log2)
4 5
import Data.Maybe (Maybe)
-- import Data.Newtype (class Newtype)
6
import Data.Tuple.Nested ((/\))
7
import Effect.Aff (Aff)
8
import Effect.Class (liftEffect)
9
import Gargantext.Components.Forest.Tree.Node.Action
10 11
import Gargantext.Components.Forest.Tree.Node.Action.Upload (uploadFile)
import Gargantext.Components.Forest.Tree.Node.Box (nodeMainSpan)
12
import Gargantext.Ends (Frontends)
13
import Gargantext.Components.Loader (loader)
14 15 16
import Gargantext.Routes (AppRoute)
import Gargantext.Sessions (Session)
import Prelude (Unit, bind, discard, map, pure, void, ($), (+), (<>))
17 18 19
import Reactix as R
import Reactix.DOM.HTML as H

20
------------------------------------------------------------------------
21
type Props = ( root          :: ID
22
             , mCurrentRoute :: Maybe AppRoute
23 24
             , session       :: Session
             , frontends     :: Frontends
25
             )
26

27 28 29 30 31 32 33 34 35 36 37 38 39 40
treeView :: Record Props -> R.Element
treeView props = R.createElement treeViewCpt props []

treeViewCpt :: R.Component Props
treeViewCpt = R.hooksComponent "G.C.Tree.treeView" cpt
  where
    cpt props _children = do
      -- NOTE: this is a hack to reload the tree view on demand
      reload <- R.useState' (0 :: Reload)
      pure $ treeLoadView reload props

treeLoadView :: R.State Reload -> Record Props -> R.Element
treeLoadView reload p = R.createElement el p []
  where
41
    el = R.staticComponent "TreeLoadView" cpt
42
    cpt {root, mCurrentRoute, session, frontends} _ = do
43
      loader root (loadNode session) $ \loaded ->
44 45
        loadedTreeView reload {tree: loaded, mCurrentRoute, session, frontends}

46 47 48 49 50 51
type TreeViewProps = ( tree          :: FTree
                     , mCurrentRoute :: Maybe AppRoute
                     , frontends     :: Frontends
                     , session       :: Session 
                     )

52 53 54 55 56 57 58 59 60 61
loadedTreeView :: R.State Reload -> Record TreeViewProps -> R.Element
loadedTreeView reload p = R.createElement el p []
  where
    el = R.hooksComponent "LoadedTreeView" cpt
    cpt {tree, mCurrentRoute, session, frontends} _ = do
      treeState <- R.useState' {tree}

      pure $ H.div {className: "tree"}
        [ toHtml reload treeState session frontends mCurrentRoute ]

62
------------------------------------------------------------------------
63 64 65 66 67 68
toHtml :: R.State Reload
       -> R.State Tree
       -> Session
       -> Frontends
       -> Maybe AppRoute
       -> R.Element
69 70 71 72
toHtml reload treeState@({tree: (NTree (LNode {id, name, nodeType}) ary)} /\ _) session frontends mCurrentRoute = R.createElement el {} []
  where
    el = R.hooksComponent "NodeView" cpt
    pAction = performAction session reload treeState
73

74 75 76 77 78 79 80 81 82 83 84 85
    cpt props _ = do
      folderOpen <- R.useState' true

      let withId (NTree (LNode {id: id'}) _) = id'

      pure $ H.ul {}
        [ H.li {}
          ( [ nodeMainSpan pAction {id, name, nodeType, mCurrentRoute} folderOpen session frontends ]
            <> childNodes session frontends reload folderOpen mCurrentRoute ary
          )
        ]

86

87 88 89 90 91 92 93
childNodes :: Session
           -> Frontends
           -> R.State Reload
           -> R.State Boolean
           -> Maybe AppRoute
           -> Array FTree
           -> Array R.Element
94 95 96 97 98 99 100 101 102 103 104 105 106
childNodes _ _ _ _ _ [] = []
childNodes _ _ _ (false /\ _) _ _ = []
childNodes session frontends reload (true /\ _) mCurrentRoute ary =
  map (\ctree -> childNode {tree: ctree}) ary
    where
      childNode :: Tree -> R.Element
      childNode props = R.createElement el props []
      el = R.hooksComponent "ChildNodeView" cpt
      cpt {tree} _ = do
        treeState <- R.useState' {tree}
        pure $ toHtml reload treeState session frontends mCurrentRoute


107 108 109 110 111
performAction :: Session
              -> R.State Int
              -> R.State Tree
              -> Action
              -> Aff Unit
112 113 114
performAction session (_ /\ setReload) (s@{tree: NTree (LNode {id}) _} /\ setTree) DeleteNode = do
  void $ deleteNode session id
  liftEffect $ setReload (_ + 1)
115

116 117 118
performAction session _ ({tree: NTree (LNode {id}) _} /\ setTree) (Submit name)  = do
  void $ renameNode session id $ RenameValue {name}
  liftEffect $ setTree $ \s@{tree: NTree (LNode node) arr} -> s {tree = NTree (LNode node {name = name}) arr}
119

120 121 122
performAction session (_ /\ setReload) (s@{tree: NTree (LNode {id}) _} /\ setTree) (CreateSubmit name nodeType) = do
  void $ createNode session id $ CreateValue {name, nodeType}
  liftEffect $ setReload (_ + 1)
123

124 125 126
performAction session _ ({tree: NTree (LNode {id}) _} /\ _) (UploadFile fileType contents) = do
  hashes <- uploadFile session id fileType contents
  liftEffect $ log2 "uploaded:" hashes
127