From d9b13f79343d02e769cde7a43006b7e2a189fb98 Mon Sep 17 00:00:00 2001
From: justinwoo <moomoowoo@gmail.com>
Date: Tue, 28 Jan 2020 21:07:12 +0200
Subject: [PATCH] fix stale tree state being used in tree view

eliminates "treeState" that was a tuple of async tasks and props-derived tree state, to make all tree data use the real loaded state
---
 src/Gargantext/Components/Forest/Tree.purs | 44 +++++++++++-----------
 1 file changed, 23 insertions(+), 21 deletions(-)

diff --git a/src/Gargantext/Components/Forest/Tree.purs b/src/Gargantext/Components/Forest/Tree.purs
index 97f5e664..6d9574d8 100644
--- a/src/Gargantext/Components/Forest/Tree.purs
+++ b/src/Gargantext/Components/Forest/Tree.purs
@@ -11,8 +11,8 @@ import Effect.Class (liftEffect)
 import Gargantext.Components.Forest.Tree.Node.Action (Action(..), CreateValue(..), FTree, ID, LNode(..), NTree(..), Reload, RenameValue(..), Tree, createNode, deleteNode, loadNode, renameNode)
 import Gargantext.Components.Forest.Tree.Node.Action.Upload (uploadFile)
 import Gargantext.Components.Forest.Tree.Node.Box (nodeMainSpan)
-import Gargantext.Components.Loader (loader)
 import Gargantext.Ends (Frontends)
+import Gargantext.Hooks.Loader (useLoader)
 import Gargantext.Prelude (Unit, bind, const, discard, map, pure, void, ($), (+), (/=), (<>))
 import Gargantext.Routes (AppRoute)
 import Gargantext.Sessions (OpenNodes, Session, mkNodeId)
@@ -51,11 +51,12 @@ treeLoadView :: Record Props' -> R.Element
 treeLoadView p = R.createElement treeLoadView' p []
 
 treeLoadView' :: R.Component Props'
-treeLoadView' = R.staticComponent "TreeLoadView" cpt
+treeLoadView' = R.hooksComponent "TreeLoadView" cpt
   where
     cpt {root, mCurrentRoute, session, frontends, openNodes, reload} _ = do
-      loader root (loadNode session) $ \loaded ->
-        loadedTreeView {tree: loaded, mCurrentRoute, session, frontends, openNodes, reload}
+      let fetch _ = loadNode session root
+      let paint loaded = loadedTreeView {tree: loaded, mCurrentRoute, session, frontends, openNodes, reload}
+      useLoader {root, counter: fst reload} fetch paint
 
 type TreeViewProps = ( tree          :: FTree
                      , mCurrentRoute :: Maybe AppRoute
@@ -73,23 +74,24 @@ loadedTreeView' :: R.Component TreeViewProps
 loadedTreeView' = R.hooksComponent "LoadedTreeView" cpt
   where
     cpt {tree, mCurrentRoute, session, frontends, openNodes, reload} _ = do
-      treeState <- R.useState' {tree, asyncTasks: []}
+      tasks <- R.useState' []
 
       pure $ H.div {className: "tree"}
-        [ toHtml reload treeState session frontends mCurrentRoute openNodes ]
+        [ toHtml reload tree tasks session frontends mCurrentRoute openNodes ]
 
 ------------------------------------------------------------------------
 toHtml :: R.State Reload
-       -> R.State Tree
+       -> FTree
+       -> R.State (Array GT.AsyncTaskWithType)
        -> Session
        -> Frontends
        -> Maybe AppRoute
        -> R.State OpenNodes
        -> R.Element
-toHtml reload treeState@(ts@{tree: (NTree (LNode {id, name, nodeType}) ary), asyncTasks} /\ setTreeState) session frontends mCurrentRoute openNodes = R.createElement el {} []
+toHtml reload tree@(NTree (LNode {id, name, nodeType}) ary) tasks@(asyncTasks /\ setAsyncTasks) session frontends mCurrentRoute openNodes = R.createElement el {} []
   where
     el = R.hooksComponent "NodeView" cpt
-    pAction = performAction session reload openNodes treeState
+    pAction = performAction session tree reload openNodes tasks
 
     cpt props _ = do
       let nodeId = mkNodeId session id
@@ -113,7 +115,7 @@ toHtml reload treeState@(ts@{tree: (NTree (LNode {id, name, nodeType}) ary), asy
           )
         ]
 
-    onAsyncTaskFinish (GT.AsyncTaskWithType {task: GT.AsyncTask {id: id'}}) = setTreeState $ const $ ts { asyncTasks = newAsyncTasks }
+    onAsyncTaskFinish (GT.AsyncTaskWithType {task: GT.AsyncTask {id: id'}}) = setAsyncTasks $ const newAsyncTasks
       where
         newAsyncTasks = A.filter (\(GT.AsyncTaskWithType {task: GT.AsyncTask {id: id''}}) -> id' /= id'') asyncTasks
 
@@ -137,37 +139,37 @@ childNodes session frontends reload (true /\ _) mCurrentRoute openNodes ary =
       childNode props = R.createElement el props []
       el = R.hooksComponent "ChildNodeView" cpt
       cpt {tree, asyncTasks} _ = do
-        treeState <- R.useState' {tree, asyncTasks}
-        pure $ toHtml reload treeState session frontends mCurrentRoute openNodes
+        tasks <- R.useState' asyncTasks
+        pure $ toHtml reload tree tasks session frontends mCurrentRoute openNodes
 
 performAction :: Session
+              -> FTree
               -> R.State Int
               -> R.State OpenNodes
-              -> R.State Tree
+              -> R.State (Array GT.AsyncTaskWithType)
               -> Action
               -> Aff Unit
-performAction session (_ /\ setReload) (_ /\ setOpenNodes) (s@{tree: NTree (LNode {id}) _} /\ setTree) DeleteNode = do
+performAction session (NTree (LNode {id}) _) (_ /\ setReload) (_ /\ setOpenNodes) _ DeleteNode = do
   void $ deleteNode session id
   liftEffect do
     setOpenNodes (Set.delete (mkNodeId session id))
     setReload (_ + 1)
 
-performAction session (_ /\ setReload) _ ({tree: NTree (LNode {id}) _} /\ setTree) (SearchQuery task) = do
-  liftEffect $ setTree $ \t@{asyncTasks} -> t { asyncTasks = A.cons task asyncTasks }
+performAction session (NTree (LNode {id}) _) (_ /\ setReload) _ (_ /\ setAsyncTasks) (SearchQuery task) = do
+  liftEffect $ setAsyncTasks $ A.cons task
   liftEffect $ log2 "[performAction] SearchQuery task:" task
   liftEffect $ setReload (_ + 1)
 
-performAction session _ _ ({tree: NTree (LNode {id}) _} /\ setTree) (Submit name)  = do
+performAction session (NTree (LNode {id}) _) _ _ _ (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}
 
-performAction session (_ /\ setReload) (_ /\ setOpenNodes) (s@{tree: NTree (LNode {id}) _} /\ setTree) (CreateSubmit name nodeType) = do
+performAction session (NTree (LNode {id}) _) (_ /\ setReload) (_ /\ setOpenNodes) _ (CreateSubmit name nodeType) = do
   void $ createNode session id $ CreateValue {name, nodeType}
   liftEffect do
     setOpenNodes (Set.insert (mkNodeId session id))
     setReload (_ + 1)
 
-performAction session _ _ ({tree: NTree (LNode {id}) _} /\ setTree) (UploadFile fileType contents) = do
+performAction session (NTree (LNode {id}) _) _ _ (_ /\ setAsyncTasks) (UploadFile fileType contents) = do
   task <- uploadFile session id fileType contents
-  liftEffect $ setTree $ \t@{asyncTasks} -> t { asyncTasks = A.cons task asyncTasks }
+  liftEffect $ setAsyncTasks $ A.cons task
   liftEffect $ log2 "uploaded, task:" task
-- 
2.21.0