Commit 4fd69d45 authored by Przemyslaw Kaminski's avatar Przemyslaw Kaminski

[CodeEditor] moveUp/Down fix solved with key props

Also, changed codeRef, codeTypeRef to state.
parent e274104c
...@@ -8,8 +8,9 @@ import Data.Generic.Rep.Show (genericShow) ...@@ -8,8 +8,9 @@ import Data.Generic.Rep.Show (genericShow)
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..))
import Data.Nullable (Nullable, null, toMaybe) import Data.Nullable (Nullable, null, toMaybe)
import Data.String.Utils (endsWith) import Data.String.Utils (endsWith)
import Data.Tuple (fst) import Data.Tuple (fst, snd)
import Data.Tuple.Nested ((/\)) import Data.Tuple.Nested ((/\))
import DOM.Simple.Console (log2)
import DOM.Simple.Types (Element) import DOM.Simple.Types (Element)
import Effect (Effect) import Effect (Effect)
import FFI.Simple ((.=), delay) import FFI.Simple ((.=), delay)
...@@ -98,6 +99,20 @@ codeEditorCpt = R.hooksComponent "G.C.CE.CodeEditor" cpt ...@@ -98,6 +99,20 @@ codeEditorCpt = R.hooksComponent "G.C.CE.CodeEditor" cpt
where where
cpt {code, defaultCodeType, onChange} _ = do cpt {code, defaultCodeType, onChange} _ = do
controls <- initControls code defaultCodeType controls <- initControls code defaultCodeType
-- codeRef <- R.useRef code
-- defaultCodeTypeRef <- R.useRef defaultCodeType
-- R.useEffect2' code defaultCodeType $ do
-- if R.readRef codeRef == code && R.readRef defaultCodeTypeRef == defaultCodeType then
-- pure unit
-- else do
-- log2 "[codeEditorCpt] code" code
-- log2 "[codeEditorCpt] defaultCodeType" defaultCodeType
-- R.setRef codeRef code
-- R.setRef defaultCodeTypeRef defaultCodeType
-- reinitControls controls code defaultCodeType
-- setCodeOverlay controls code
-- renderHtml code controls
-- Initial rendering of elements with given data -- Initial rendering of elements with given data
...@@ -127,7 +142,7 @@ codeEditorCpt = R.hooksComponent "G.C.CE.CodeEditor" cpt ...@@ -127,7 +142,7 @@ codeEditorCpt = R.hooksComponent "G.C.CE.CodeEditor" cpt
-- , contentEditable: "true" -- , contentEditable: "true"
, ref: controls.codeOverlayElRef , ref: controls.codeOverlayElRef
, rows: 30 , rows: 30
--, on: { input: onEditChange (fst codeType) codeElRef htmlRef editorCodeRef error } --, on: { input: onEditChange (fst codeType) codeElRef htmlRef codeRef error }
} [] } []
] ]
] ]
...@@ -158,11 +173,11 @@ codeEditorCpt = R.hooksComponent "G.C.CE.CodeEditor" cpt ...@@ -158,11 +173,11 @@ codeEditorCpt = R.hooksComponent "G.C.CE.CodeEditor" cpt
previewHidden _ = " hidden" previewHidden _ = " hidden"
onEditChange :: forall e. Record Controls -> (CodeType -> Code -> Effect Unit) -> e -> Effect Unit onEditChange :: forall e. Record Controls -> (CodeType -> Code -> Effect Unit) -> e -> Effect Unit
onEditChange controls@{codeElRef, codeOverlayElRef, codeType: (codeType /\ _), editorCodeRef} onChange e = do onEditChange controls@{codeElRef, codeOverlayElRef, codeType: (codeType /\ _), codeS} onChange e = do
let code = R2.unsafeEventValue e let code = R2.unsafeEventValue e
R.setRef editorCodeRef code snd codeS $ const code
setCodeOverlay controls code setCodeOverlay controls code
renderHtml (R.readRef controls.editorCodeRef) controls renderHtml (fst codeS) controls
onChange codeType code onChange codeType code
setCodeOverlay :: Record Controls -> Code -> Effect Unit setCodeOverlay :: Record Controls -> Code -> Effect Unit
...@@ -218,7 +233,7 @@ toolbarCpt = R.hooksComponent "G.C.CE.toolbar" cpt ...@@ -218,7 +233,7 @@ toolbarCpt = R.hooksComponent "G.C.CE.toolbar" cpt
renderHtml code controls renderHtml code controls
onChange (fst controls.codeType) code onChange (fst controls.codeType) code
where where
code = R.readRef controls.editorCodeRef code = fst controls.codeS
type ErrorComponentProps = type ErrorComponentProps =
...@@ -310,9 +325,9 @@ viewTypeSelectorCpt = R.hooksComponent "G.C.CE.ViewTypeSelector" cpt ...@@ -310,9 +325,9 @@ viewTypeSelectorCpt = R.hooksComponent "G.C.CE.ViewTypeSelector" cpt
type Controls = type Controls =
( (
codeElRef :: R.Ref (Nullable Element) codeElRef :: R.Ref (Nullable Element)
, codeS :: R.State Code
, codeType :: R.State CodeType , codeType :: R.State CodeType
, codeOverlayElRef :: R.Ref (Nullable Element) , codeOverlayElRef :: R.Ref (Nullable Element)
, editorCodeRef :: R.Ref Code
, error :: R.State (Maybe Error) , error :: R.State (Maybe Error)
, htmlElRef :: R.Ref (Nullable Element) , htmlElRef :: R.Ref (Nullable Element)
, viewType :: R.State ViewType , viewType :: R.State ViewType
...@@ -321,19 +336,25 @@ type Controls = ...@@ -321,19 +336,25 @@ type Controls =
initControls :: Code -> CodeType -> R.Hooks (Record Controls) initControls :: Code -> CodeType -> R.Hooks (Record Controls)
initControls code defaultCodeType = do initControls code defaultCodeType = do
htmlElRef <- R.useRef null htmlElRef <- R.useRef null
codeS <- R.useState' code
codeElRef <- R.useRef null codeElRef <- R.useRef null
codeOverlayElRef <- R.useRef null codeOverlayElRef <- R.useRef null
codeType <- R.useState' defaultCodeType codeType <- R.useState' defaultCodeType
editorCodeRef <- R.useRef code
error <- R.useState' Nothing error <- R.useState' Nothing
viewType <- R.useState' Both viewType <- R.useState' Both
pure $ { pure $ {
codeElRef codeElRef
, codeS
, codeType , codeType
, codeOverlayElRef , codeOverlayElRef
, editorCodeRef
, error , error
, htmlElRef , htmlElRef
, viewType , viewType
} }
reinitControls :: Record Controls -> Code -> CodeType -> Effect Unit
reinitControls c@{codeType, codeS, error} code defaultCodeType = do
snd codeType $ const defaultCodeType
snd codeS $ const code
snd error $ const Nothing
...@@ -6,7 +6,7 @@ import Data.Array as A ...@@ -6,7 +6,7 @@ import Data.Array as A
import Data.Either (Either(..)) import Data.Either (Either(..))
import Data.List as List import Data.List as List
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..))
import Data.Tuple (Tuple(..), fst) import Data.Tuple (Tuple(..), fst, snd)
import Data.Tuple.Nested ((/\)) import Data.Tuple.Nested ((/\))
import DOM.Simple.Console (log2) import DOM.Simple.Console (log2)
import Effect (Effect) import Effect (Effect)
...@@ -20,7 +20,7 @@ import Gargantext.Prelude ...@@ -20,7 +20,7 @@ import Gargantext.Prelude
import Gargantext.Components.CodeEditor as CE import Gargantext.Components.CodeEditor as CE
import Gargantext.Components.Node (NodePoly(..), HyperdataList) import Gargantext.Components.Node (NodePoly(..), HyperdataList)
import Gargantext.Components.Nodes.Corpus.Types (CorpusData, FTField, Field(..), FieldType(..), Hash, Hyperdata(..), defaultField, defaultHaskell', defaultJSON', defaultMarkdown') import Gargantext.Components.Nodes.Corpus.Types (CorpusData, FTField, Field(..), FieldType(..), Hyperdata(..), defaultField, defaultHaskell', defaultJSON', defaultMarkdown')
import Gargantext.Data.Array as GDA import Gargantext.Data.Array as GDA
import Gargantext.Hooks.Loader (useLoader) import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Routes (SessionRoute(NodeAPI, Children)) import Gargantext.Routes (SessionRoute(NodeAPI, Children))
...@@ -69,6 +69,15 @@ corpusLayoutViewCpt = R.hooksComponent "G.C.N.C.corpusLayoutView" cpt ...@@ -69,6 +69,15 @@ corpusLayoutViewCpt = R.hooksComponent "G.C.N.C.corpusLayoutView" cpt
cpt {corpus: (NodePoly {hyperdata: Hyperdata {fields}}), nodeId, reload, session} _ = do cpt {corpus: (NodePoly {hyperdata: Hyperdata {fields}}), nodeId, reload, session} _ = do
let fieldsWithIndex = List.mapWithIndex (\idx -> \t -> Tuple idx t) fields let fieldsWithIndex = List.mapWithIndex (\idx -> \t -> Tuple idx t) fields
fieldsS <- R.useState' fieldsWithIndex fieldsS <- R.useState' fieldsWithIndex
fieldsRef <- R.useRef fields
-- handle props change of fields
R.useEffect1' fields $ do
if R.readRef fieldsRef == fields then
pure unit
else do
R.setRef fieldsRef fields
snd fieldsS $ const fieldsWithIndex
pure $ H.div {} [ pure $ H.div {} [
H.div { className: "row" } [ H.div { className: "row" } [
...@@ -122,16 +131,20 @@ fieldsCodeEditorCpt :: R.Component FieldsCodeEditorProps ...@@ -122,16 +131,20 @@ fieldsCodeEditorCpt :: R.Component FieldsCodeEditorProps
fieldsCodeEditorCpt = R.hooksComponent "G.C.N.C.fieldsCodeEditorCpt" cpt fieldsCodeEditorCpt = R.hooksComponent "G.C.N.C.fieldsCodeEditorCpt" cpt
where where
cpt {nodeId, fields: fS@(fields /\ _), session} _ = do cpt {nodeId, fields: fS@(fields /\ _), session} _ = do
pure $ H.div {} $ List.toUnfoldable editors masterKey <- R.useState' 0
pure $ H.div {} $ List.toUnfoldable (editors masterKey)
where where
editors = (\idxField@(Tuple idx field) -> editors masterKey =
(\idxField@(Tuple idx field) ->
fieldCodeEditorWrapper { canMoveDown: idx < (List.length fields - 1) fieldCodeEditorWrapper { canMoveDown: idx < (List.length fields - 1)
, canMoveUp: idx > 0 , canMoveUp: idx > 0
, field , field
, hash: hash idxField , hash: hash idxField
, key: (show $ fst masterKey) <> "-" <> (show idx)
, onChange: onChange fS idx , onChange: onChange fS idx
, onMoveDown: onMoveDown fS idx , onMoveDown: onMoveDown masterKey fS idx
, onMoveUp: onMoveUp fS idx , onMoveUp: onMoveUp masterKey fS idx
, onRemove: onRemove fS idx , onRemove: onRemove fS idx
, onRename: onRename fS idx , onRename: onRename fS idx
}) <$> fields }) <$> fields
...@@ -143,13 +156,15 @@ fieldsCodeEditorCpt = R.hooksComponent "G.C.N.C.fieldsCodeEditorCpt" cpt ...@@ -143,13 +156,15 @@ fieldsCodeEditorCpt = R.hooksComponent "G.C.N.C.fieldsCodeEditorCpt" cpt
Nothing -> fields Nothing -> fields
Just newFields -> newFields Just newFields -> newFields
onMoveDown :: R.State FTFieldsWithIndex -> Index -> Unit -> Effect Unit onMoveDown :: R.State Int -> R.State FTFieldsWithIndex -> Index -> Unit -> Effect Unit
onMoveDown (fs /\ setFields) idx _ = do onMoveDown (_ /\ setMasterKey) (fs /\ setFields) idx _ = do
setFields $ recomputeIndices <<< (GDA.swapList idx (idx + 1)) setFields $ recomputeIndices <<< (GDA.swapList idx (idx + 1))
setMasterKey $ (+) 1
onMoveUp :: R.State FTFieldsWithIndex -> Index -> Unit -> Effect Unit onMoveUp :: R.State Int -> R.State FTFieldsWithIndex -> Index -> Unit -> Effect Unit
onMoveUp (_ /\ setFields) idx _ = do onMoveUp (_ /\ setMasterKey) (_ /\ setFields) idx _ = do
setFields $ recomputeIndices <<< (GDA.swapList idx (idx - 1)) setFields $ recomputeIndices <<< (GDA.swapList idx (idx - 1))
setMasterKey $ (+) 1
onRemove :: R.State FTFieldsWithIndex -> Index -> Unit -> Effect Unit onRemove :: R.State FTFieldsWithIndex -> Index -> Unit -> Effect Unit
onRemove (_ /\ setFields) idx _ = do onRemove (_ /\ setFields) idx _ = do
...@@ -176,7 +191,8 @@ type FieldCodeEditorProps = ...@@ -176,7 +191,8 @@ type FieldCodeEditorProps =
canMoveDown :: Boolean canMoveDown :: Boolean
, canMoveUp :: Boolean , canMoveUp :: Boolean
, field :: FTField , field :: FTField
, hash :: Hash , hash :: Hash -- TODO this isn't needed anymore
, key :: String
, onChange :: FieldType -> Effect Unit , onChange :: FieldType -> Effect Unit
, onMoveDown :: Unit -> Effect Unit , onMoveDown :: Unit -> Effect Unit
, onMoveUp :: Unit -> Effect Unit , onMoveUp :: Unit -> Effect Unit
...@@ -241,20 +257,43 @@ renameableCpt = R.hooksComponent "G.C.N.C.renameableCpt" cpt ...@@ -241,20 +257,43 @@ renameableCpt = R.hooksComponent "G.C.N.C.renameableCpt" cpt
cpt {onRename, text} _ = do cpt {onRename, text} _ = do
isEditing <- R.useState' false isEditing <- R.useState' false
state <- R.useState' text state <- R.useState' text
textRef <- R.useRef text
-- handle props change of text
R.useEffect1' text $ do
if R.readRef textRef == text then
pure unit
else do
R.setRef textRef text
snd state $ const text
pure $ H.div { className: "renameable" } [ pure $ H.div { className: "renameable" } [
textCpt isEditing state renameableText {isEditing, onRename, state}
] ]
type RenameableTextProps =
(
isEditing :: R.State Boolean
, onRename :: String -> Effect Unit
, state :: R.State String
)
renameableText :: Record RenameableTextProps -> R.Element
renameableText props = R.createElement renameableTextCpt props []
renameableTextCpt :: R.Component RenameableTextProps
renameableTextCpt = R.hooksComponent "G.C.N.C.renameableTextCpt" cpt
where where
textCpt :: R.State Boolean -> R.State String -> R.Element cpt {isEditing: (false /\ setIsEditing), state: (text /\ _)} _ = do
textCpt (false /\ setIsEditing) (text /\ _) = H.div {} [ pure $ H.div {} [
H.span { className: "text" } [ H.text text ] H.span { className: "text" } [ H.text text ]
, H.span { className: "btn btn-default" , H.span { className: "btn btn-default"
, on: { click: \_ -> setIsEditing $ const true } } [ , on: { click: \_ -> setIsEditing $ const true } } [
H.span { className: "glyphicon glyphicon-pencil" } [] H.span { className: "glyphicon glyphicon-pencil" } []
] ]
] ]
textCpt (true /\ setIsEditing) (text /\ setText) = H.div {} [ cpt {isEditing: (true /\ setIsEditing), onRename, state: (text /\ setText)} _ = do
pure $ H.div {} [
H.input { defaultValue: text H.input { defaultValue: text
, className: "form-control text" , className: "form-control text"
, on: { change: \e -> setText $ const $ R2.unsafeEventValue e } } , on: { change: \e -> setText $ const $ R2.unsafeEventValue e } }
......
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