Commit 771df0c7 authored by James Laver's avatar James Laver Committed by Alexandre Delanoë

Rewrite AnnotatedField to use Reactix

parent 1c66a227
...@@ -12,9 +12,9 @@ ...@@ -12,9 +12,9 @@
module Gargantext.Components.Annotated.AnnotatedField where module Gargantext.Components.Annotated.AnnotatedField where
import Prelude hiding (div) import Prelude hiding (div)
import Data.Array (fromFoldable) import Data.Array as A
import Data.Map as Map import Data.Map as Map
import Data.Maybe (Maybe(..), maybe) import Data.Maybe (Maybe(..), maybe, isJust)
import Data.Lens (Lens', lens) import Data.Lens (Lens', lens)
import Data.List as List import Data.List as List
import Data.List (List(..)) import Data.List (List(..))
...@@ -23,113 +23,68 @@ import Effect (Effect) ...@@ -23,113 +23,68 @@ import Effect (Effect)
import Effect.Class.Console (log) import Effect.Class.Console (log)
import Effect.Unsafe (unsafePerformEffect) import Effect.Unsafe (unsafePerformEffect)
import React (ReactElement, ReactClass, createElement) import React (ReactElement, ReactClass, createElement)
import React.DOM (p, span, text)
import React.DOM.Props as Props
import React.DOM.Props (className, onContextMenu, style)
import Thermite (PerformAction, Render, createReactSpec, simpleSpec, writeState)
import Gargantext.Types (TermList(..)) import Gargantext.Types (TermList(..))
import Gargantext.Components.NgramsTable (NgramsTable(..), highlightNgrams) import Gargantext.Components.NgramsTable (NgramsTable(..), highlightNgrams)
import Gargantext.Utils.React (WithChildren)
import Gargantext.Utils.Selection (getSelection, toString) import Gargantext.Utils.Selection (getSelection, toString)
import React as React import Reactix as R
import React.SyntheticEvent (SyntheticMouseEvent, pageX, pageY) import Reactix.DOM.Raw as RDOM
newtype PageOffset = PageOffset { x :: Number, y :: Number } newtype PageOffset = PageOffset { x :: Number, y :: Number }
type Run = Tuple String (Maybe TermList) type Run = Tuple String (Maybe TermList)
type State = { runs :: List Run, contextMenu :: { visible :: Boolean } } type Props = ( ngrams :: NgramsTable, text :: Maybe String )
type Props' = ( ngrams :: NgramsTable, text :: Maybe String ) defaultProps :: Record Props
type Props = { | Props' } defaultProps = { ngrams: NgramsTable Map.empty, text: Nothing }
data Action annotatedField :: Record Props -> R.Element
= ForceRefresh annotatedField = R.createLeaf annotatedFieldComponent
| OnContextMenu PageOffset String
| AddTerm String TermList
defaultProps :: Props annotatedFieldComponent :: R.Component Props
defaultProps = { ngrams: NgramsTable Map.empty, text: Nothing } annotatedFieldComponent = R.pureLeaf "AnnotatedField" cpt
defaultState :: State
defaultState = { runs: Nil, contextMenu: { visible: false } } -- contextMenu: ContextMenu.defaultState }
annotatedField :: Props -> ReactElement
annotatedField p = createElement annotatedFieldClass p []
annotatedFieldClass :: ReactClass (WithChildren Props')
annotatedFieldClass =
React.component "AnnotatedField"
(\this -> do
-- log $ "AnnotatedField: constructing"
s <- spec this
pure { state : s.state
, render: s.render
, componentDidUpdate: \old _s _snap -> do
new <- React.getProps this
when (old.ngrams /= new.ngrams || old.text /= new.text) do
-- log "AnnotatedField: forcing refresh"
dispatcher this ForceRefresh
})
where where
performAction :: PerformAction State Props Action cpt props = R.createDOMElement "p" { className: "annotated-field" } $ children props
performAction ForceRefresh = forceRefresh children props = A.fromFoldable (annotateRun <$> compile props)
performAction _ = \_ _ -> pure unit
-- performAction (ShowContextMenu i) = showContextMenu i type RunProps = ( list :: Maybe TermList, text :: String )
-- performAction (AddTerm t l) = addTerm t l
-- performAction = defaultPerformAction annotateRun :: Run -> R.Element
render :: Render State Props Action annotateRun (Tuple text list) = R.createLeaf annotatedRunComponent { text, list }
render d _p s _c = [ p [className "annotated-field"] $ children d s.runs ]
children d = fromFoldable <<< map (renderRun $ contextMenuHandler d) annotatedRunComponent :: R.Component RunProps
renderRun menu (Tuple txt lst) annotatedRunComponent = R.pureLeaf "AnnotatedRun" cpt
| Just list <- lst = span [termStyle list, onContextMenu menu] [text txt] where cpt { text, list } = maybe (unstyled text) (styled text) list
| otherwise = span [] [text txt] styled text list = R.createDOMElement "span" { style: termStyle list } [ RDOM.text text ]
{spec, dispatcher} = createReactSpec (simpleSpec performAction render) compile unstyled text = R.createDOMElement "span" {} [ RDOM.text text ]
-- performAction handlers compile :: Record Props -> List Run
compile props = runs props.text
forceRefresh props state = where runs (Just text) = highlight props.ngrams text
do wrote <- writeState (compile props)
log $ msg wrote
pure unit
where msg = maybe "AnnotatedField: failed to write new state" (const "AnnotatedField: recompiled")
-- showContextMenu :: PerformAction State Props String
-- showContextMenu p s = pure unit
-- addTerm :: String -> PerformAction State Props TermList
-- addTerm t l p s = pure unit
compile :: Props -> State
compile props =
unsafePerformEffect $
do let ret = { runs: runs props.text, contextMenu: { visible: false } }
-- log "Compiling..."
pure ret
where runs (Just txt) = highlight props.ngrams txt
runs _ = Nil runs _ = Nil
highlight :: NgramsTable -> String -> List Run highlight :: NgramsTable -> String -> List Run
highlight n t = List.fromFoldable $ highlightNgrams n t highlight n t = List.fromFoldable $ highlightNgrams n t
contextMenuHandler :: (Action -> Effect Unit) -> SyntheticMouseEvent -> Effect Unit -- contextMenuHandler :: (Action -> Effect Unit) -> SyntheticMouseEvent -> Effect Unit
contextMenuHandler d e = -- contextMenuHandler d e =
do sel <- getSelection -- do sel <- getSelection
case toString <$> sel of -- case toString <$> sel of
Just s -> submit s -- Just s -> submit s
Nothing -> pure unit -- Nothing -> pure unit
where submit s = offset >>= \o -> d $ OnContextMenu o s -- where submit s = offset >>= \o -> d $ OnContextMenu o s
offset = -- offset =
do x <- pageX e -- do x <- pageX e
y <- pageY e -- y <- pageY e
pure $ PageOffset { x, y } -- pure $ PageOffset { x, y }
termStyle :: TermList -> Props.Props termStyle :: TermList -> { backgroundColor :: String }
termStyle GraphTerm = style {backgroundColor: "green"} termStyle GraphTerm = { backgroundColor: "green" }
termStyle StopTerm = style {backgroundColor: "red", textDecoration : "line-through"} termStyle StopTerm = { backgroundColor: "red" }
termStyle CandidateTerm = style {backgroundColor: "black"} termStyle CandidateTerm = { backgroundColor: "black" }
_runs :: Lens' State (List Run) -- _runs :: Lens' State (List Run)
_runs = lens (\a -> a.runs) (\a r -> a { runs = r }) -- _runs = lens (\a -> a.runs) (\a r -> a { runs = r })
-- _contextMenu :: Lens' State ??? -- _contextMenu :: Lens' State ???
-- _contextMenu = lens (\a -> a.contextMenu) (\a m -> a { contextMenu = m }) -- _contextMenu = lens (\a -> a.contextMenu) (\a m -> a { contextMenu = m })
...@@ -24,6 +24,7 @@ import Gargantext.Components.Node (NodePoly(..)) ...@@ -24,6 +24,7 @@ import Gargantext.Components.Node (NodePoly(..))
import Gargantext.Components.NgramsTable (NgramsTable(..), NgramsElement(..)) import Gargantext.Components.NgramsTable (NgramsTable(..), NgramsElement(..))
import Gargantext.Components.Annotated.AnnotatedField as AnnotatedField import Gargantext.Components.Annotated.AnnotatedField as AnnotatedField
import Gargantext.Types (TermList(..)) import Gargantext.Types (TermList(..))
import Gargantext.Utils.React ( crapify )
nge :: String -> Tuple String NgramsElement nge :: String -> Tuple String NgramsElement
nge word = Tuple word elem where nge word = Tuple word elem where
...@@ -38,7 +39,6 @@ testTable = NgramsTable $ Map.fromFoldable $ nge <$> words ...@@ -38,7 +39,6 @@ testTable = NgramsTable $ Map.fromFoldable $ nge <$> words
type State = type State =
{ document :: Maybe (NodePoly Document) { document :: Maybe (NodePoly Document)
, annotatedDocument :: AnnotatedDocument
, ngramsTable :: NgramsTable , ngramsTable :: NgramsTable
, inputValue :: String , inputValue :: String
} }
...@@ -46,7 +46,6 @@ type State = ...@@ -46,7 +46,6 @@ type State =
initialState :: {} -> State initialState :: {} -> State
initialState {} = initialState {} =
{ document: Nothing { document: Nothing
, annotatedDocument: defaultAnnotatedDocument
, ngramsTable: testTable , ngramsTable: testTable
, inputValue: "" , inputValue: ""
} }
...@@ -136,13 +135,6 @@ data Document ...@@ -136,13 +135,6 @@ data Document
--, text :: Maybe String --, text :: Maybe String
} }
data AnnotatedDocument
= AnnotatedDocument
{ abstract :: AnnotatedField.State }
defaultAnnotatedDocument :: AnnotatedDocument
defaultAnnotatedDocument = AnnotatedDocument { abstract: AnnotatedField.defaultState }
defaultNodeDocument :: NodePoly Document defaultNodeDocument :: NodePoly Document
defaultNodeDocument = defaultNodeDocument =
NodePoly { id : 0 NodePoly { id : 0
...@@ -338,7 +330,7 @@ docview = simpleSpec performAction render ...@@ -338,7 +330,7 @@ docview = simpleSpec performAction render
] ]
] ]
where where
annotate t = AnnotatedField.annotatedField { ngrams: state.ngramsTable, text: t } annotate t = crapify $ AnnotatedField.annotatedField { ngrams: state.ngramsTable, text: t }
li' = li [className "list-group-item justify-content-between"] li' = li [className "list-group-item justify-content-between"]
text' x = text $ maybe "Nothing" identity x text' x = text $ maybe "Nothing" identity x
badge s = span [className "badge badge-default badge-pill"] [text s] badge s = span [className "badge badge-default badge-pill"] [text s]
......
module Gargantext.Utils.React where module Gargantext.Utils.React where
import Prelude import Prelude
import Data.Array ((!!)) import Data.Array ( (!!) )
import Data.FoldableWithIndex (foldMapWithIndex) import Data.FoldableWithIndex ( foldMapWithIndex )
import Data.Maybe (fromMaybe) import Data.Maybe ( fromMaybe )
import React (ReactElement, Children) import React ( ReactElement, Children )
import Reactix as R
import Unsafe.Coerce ( unsafeCoerce )
-- TODO: Upgrade thermite and reapply our changes or upstream them and get rid of this -- TODO: Upgrade thermite and reapply our changes or upstream them and get rid of this
type WithChildren props = { children :: Children | props } type WithChildren props = { children :: Children | props }
...@@ -12,3 +14,43 @@ type WithChildren props = { children :: Children | props } ...@@ -12,3 +14,43 @@ type WithChildren props = { children :: Children | props }
wrap :: (Array ReactElement -> ReactElement) -> ReactElement -> ReactElement wrap :: (Array ReactElement -> ReactElement) -> ReactElement -> ReactElement
wrap f e = f [e] wrap f e = f [e]
crapify :: R.Element -> ReactElement
crapify = unsafeCoerce
-- many ::
-- forall props extra state action.
-- Spec state { extra :: extra | WithIndex props } action
-- -> Spec state { props :: (Array props), extra :: extra } action
-- many items spec = Spec { performAction, render }
-- where
-- -- performAction :: PerformAction
-- render d p s c = foldMapWithIndex childSpec p.props
-- childSpec props i = cmapProps (\_ -> props { index = i }) spec
-- many
-- :: forall props state action
-- . (Int -> Spec state props action)
-- -> Spec state (List props) (Tuple Int action)
-- foreach f = Spec { performAction: performAction
-- , render: render
-- }
-- where
-- performAction :: PerformAction (List state) props (Tuple Int action)
-- performAction (Tuple i a) p sts =
-- for_ (sts !! i) \st ->
-- case f i of
-- Spec s -> forever (transform (_ >>= (_ !! i)))
-- `transformCoTransformL` s.performAction a p st
-- `transformCoTransformR` forever (transform (modifying i))
-- where
-- modifying :: Int -> (state -> state) -> List state -> List state
-- modifying j g sts' = fromMaybe sts' (modifyAt j g sts')
-- render :: Render (List state) props (Tuple Int action)
-- render k p sts _ = foldWithIndex (\i st els -> case f i of Spec s -> els <> s.render (k <<< Tuple i) p st []) sts []
-- foldWithIndex :: forall a r. (Int -> a -> r -> r) -> List a -> r -> r
-- foldWithIndex g = go 0
-- where
-- go _ Nil r = r
-- go i (Cons x xs) r = go (i + 1) xs (g i x r)
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