ProgressBar.purs 2.39 KB
Newer Older
1 2
module Gargantext.Components.Forest.Tree.Node.ProgressBar where

3 4
import Gargantext.Prelude

5
import Data.Int (fromNumber)
6
import Data.Maybe (Maybe(..), fromJust)
7
import Data.Tuple.Nested ((/\))
8
import Effect (Effect)
9
import Effect.Aff (Aff, launchAff_)
10
import Effect.Class (liftEffect)
11
import Effect.Timer (clearInterval, setInterval)
12 13 14
import Gargantext.Components.Forest.Tree.Node.Action (ID)
import Gargantext.Routes (SessionRoute(..))
import Gargantext.Sessions (Session, get)
15
import Gargantext.Types as GT
16
import Partial.Unsafe (unsafePartial)
17

18 19 20 21 22 23
import Reactix as R
import Reactix.DOM.HTML as H


type Props =
  (
24
    asyncTask :: GT.AsyncTaskWithType
25
  , corpusId  :: ID
26
  , onFinish  :: Unit -> Effect Unit
27
  , session   :: Session
28 29 30 31 32 33 34 35 36
  )


asyncProgressBar :: Record Props -> R.Element
asyncProgressBar p = R.createElement asyncProgressBarCpt p []

asyncProgressBarCpt :: R.Component Props
asyncProgressBarCpt = R.hooksComponent "G.C.F.T.N.asyncProgressBar" cpt
  where
37
    cpt props@{asyncTask: (GT.AsyncTaskWithType {task: GT.AsyncTask {id}}), corpusId, onFinish} _ = do
38
      (progress /\ setProgress) <- R.useState' 0.0
39
      intervalIdRef <- R.useRef Nothing
40

41 42
      R.useEffectOnce' $ do
        intervalId <- setInterval 1000 $ do
43
          launchAff_ $ do
44
            asyncProgress@(GT.AsyncProgress {status}) <- queryProgress props
45
            liftEffect do
46 47
              setProgress \p -> min 100.0 $ GT.progressPercent asyncProgress
              if (status == GT.Finished) || (status == GT.Killed) || (status == GT.Failed) then do
48 49 50 51 52 53 54 55 56
                _ <- case R.readRef intervalIdRef of
                  Nothing -> pure unit
                  Just iid -> clearInterval iid
                onFinish unit
              else
                pure unit

        R.setRef intervalIdRef $ Just intervalId

57 58 59 60 61 62 63 64 65 66 67 68 69
        pure unit


      pure $
        H.div { className: "progress" } [
          H.div { className: "progress-bar"
                , role: "progressbar"
                , style: { width: (show $ toInt progress) <> "%" }
                } [ H.text id ]
        ]

    toInt :: Number -> Int
    toInt n = unsafePartial $ fromJust $ fromNumber n
70

71 72
queryProgress :: Record Props -> Aff GT.AsyncProgress
queryProgress {asyncTask: GT.AsyncTaskWithType {task: GT.AsyncTask {id}, typ}, corpusId, session} = get session p
73
  where
74 75
    p = NodeAPI GT.Corpus (Just corpusId) $ path <> id <> "/poll?limit=1"
    path = GT.asyncTaskTypePath typ