Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
purescript-gargantext
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
142
Issues
142
List
Board
Labels
Milestones
Merge Requests
4
Merge Requests
4
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
gargantext
purescript-gargantext
Commits
c3bba506
Commit
c3bba506
authored
Jan 28, 2020
by
Alexandre Delanoë
Browse files
Options
Browse Files
Download
Plain Diff
[FIX] merge.
parents
6fe64380
4c9ce917
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
141 additions
and
87 deletions
+141
-87
packages.json
.psc-package/local/.set/packages.json
+1
-1
CodeEditor.css
dist/styles/CodeEditor.css
+1
-0
CodeEditor.sass
dist/styles/CodeEditor.sass
+1
-0
CodeEditor.purs
src/Gargantext/Components/CodeEditor.purs
+20
-25
Forest.purs
src/Gargantext/Components/Forest.purs
+8
-10
Tree.purs
src/Gargantext/Components/Forest/Tree.purs
+33
-11
Corpus.purs
src/Gargantext/Components/Nodes/Corpus.purs
+77
-40
No files found.
.psc-package/local/.set/packages.json
View file @
c3bba506
...
...
@@ -3336,4 +3336,4 @@
"repo"
:
"https://github.com/paf31/purescript-yargs.git"
,
"version"
:
"v4.0.0"
}
}
}
\ No newline at end of file
dist/styles/CodeEditor.css
View file @
c3bba506
...
...
@@ -24,6 +24,7 @@
.code-editor
.editor
.code-area
{
flex-grow
:
1
;
max-height
:
200px
;
min-width
:
25%
;
overflow
:
auto
;
}
.code-editor
.editor
.code-area
.code-container
{
...
...
dist/styles/CodeEditor.sass
View file @
c3bba506
...
...
@@ -41,6 +41,7 @@
.code-area
flex-grow
:
1
max-height
:
200px
min-width
:
25%
overflow
:
auto
.code-container
background-color
:
#fafafa
...
...
src/Gargantext/Components/CodeEditor.purs
View file @
c3bba506
module Gargantext.Components.CodeEditor where
import DOM.Simple.Types (Element)
import Data.Argonaut.Parser (jsonParser)
import Data.Either (either, Either(..))
import Data.Generic.Rep (class Generic)
...
...
@@ -8,11 +9,10 @@ import Data.Generic.Rep.Show (genericShow)
import Data.Maybe (Maybe(..))
import Data.Nullable (Nullable, null, toMaybe)
import Data.String.Utils (endsWith)
import Data.Tuple (fst)
import Data.Tuple (fst
, snd
)
import Data.Tuple.Nested ((/\))
import DOM.Simple.Types (Element)
import Effect (Effect)
import FFI.Simple ((.=)
, delay
)
import FFI.Simple ((.=))
import Reactix as R
import Reactix.DOM.HTML as H
import Text.Markdown.SlamDown.Parser (parseMd)
...
...
@@ -99,17 +99,10 @@ codeEditorCpt = R.hooksComponent "G.C.CE.CodeEditor" cpt
cpt {code, defaultCodeType, onChange} _ = do
controls <- initControls code defaultCodeType
-- Initial rendering of elements with given data
-- Note: delay is necessary here, otherwise initially the HTML won't get
-- rendered (DOM Element refs are still null)
R.useEffectOnce $ delay unit $ \_ -> do
_ <- renderHtml code controls
pure $ pure unit
R.useEffectOnce $ delay unit $ \_ -> do
_ <- setCodeOverlay controls code
pure $ pure unit
R.useEffect2' (fst controls.codeS) (fst controls.codeType) $ do
let code' = fst controls.codeS
setCodeOverlay controls code'
renderHtml code' controls
pure $ H.div { className: "code-editor" } [
toolbar {controls, onChange}
...
...
@@ -127,7 +120,7 @@ codeEditorCpt = R.hooksComponent "G.C.CE.CodeEditor" cpt
-- , contentEditable: "true"
, ref: controls.codeOverlayElRef
, rows: 30
--, on: { input: onEditChange (fst codeType) codeElRef htmlRef
editorC
odeRef error }
--, on: { input: onEditChange (fst codeType) codeElRef htmlRef
c
odeRef error }
} []
]
]
...
...
@@ -158,11 +151,9 @@ codeEditorCpt = R.hooksComponent "G.C.CE.CodeEditor" cpt
previewHidden _ = " hidden"
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
R.setRef editorCodeRef code
setCodeOverlay controls code
renderHtml (R.readRef controls.editorCodeRef) controls
snd codeS $ const code
onChange codeType code
setCodeOverlay :: Record Controls -> Code -> Effect Unit
...
...
@@ -214,11 +205,9 @@ toolbarCpt = R.hooksComponent "G.C.CE.toolbar" cpt
-- Handle rerendering of preview when viewType changed
onChangeCodeType :: forall e. Record ToolbarProps -> e -> Effect Unit
onChangeCodeType {controls, onChange} _ = do
setCodeOverlay controls code
renderHtml code controls
onChange (fst controls.codeType) code
where
code =
R.readRef controls.editorCodeRef
code =
fst controls.codeS
type ErrorComponentProps =
...
...
@@ -310,9 +299,9 @@ viewTypeSelectorCpt = R.hooksComponent "G.C.CE.ViewTypeSelector" cpt
type Controls =
(
codeElRef :: R.Ref (Nullable Element)
, codeS :: R.State Code
, codeType :: R.State CodeType
, codeOverlayElRef :: R.Ref (Nullable Element)
, editorCodeRef :: R.Ref Code
, error :: R.State (Maybe Error)
, htmlElRef :: R.Ref (Nullable Element)
, viewType :: R.State ViewType
...
...
@@ -321,19 +310,25 @@ type Controls =
initControls :: Code -> CodeType -> R.Hooks (Record Controls)
initControls code defaultCodeType = do
htmlElRef <- R.useRef null
codeS <- R.useState' code
codeElRef <- R.useRef null
codeOverlayElRef <- R.useRef null
codeType <- R.useState' defaultCodeType
editorCodeRef <- R.useRef code
error <- R.useState' Nothing
viewType <- R.useState' Both
pure $ {
codeElRef
, codeS
, codeType
, codeOverlayElRef
, editorCodeRef
, error
, htmlElRef
, 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
src/Gargantext/Components/Forest.purs
View file @
c3bba506
...
...
@@ -9,6 +9,7 @@ import Data.Set as Set
import Data.Tuple (fst)
import Data.Tuple.Nested ((/\))
import Gargantext.Components.Forest.Tree (treeView)
import Gargantext.Components.Forest.Tree.Node.Action (Reload)
import Gargantext.Components.Login.Types (TreeId)
import Gargantext.Ends (Frontends)
import Gargantext.Routes (AppRoute)
...
...
@@ -30,21 +31,18 @@ forest props = R.createElement forestCpt props []
forestCpt :: R.Component Props
forestCpt = R.hooksComponent "G.C.Forest.forest" cpt where
cpt {frontends, route, sessions, showLogin } _ = do
-- NOTE: this is a hack to reload the tree view on demand
reload <- R.useState' (0 :: Reload)
openNodes <- R2.useLocalStorageState R2.openNodesKey (Set.empty :: Set TreeId)
reload <- R.useState' (0 :: Int)
R2.useCache (frontends /\ route /\ sessions /\ fst openNodes) (cpt' reload openNodes showLogin)
cpt' reload openNodes showLogin (frontends /\ route /\ sessions /\ openNodesState) = do
R2.useCache
(frontends /\ route /\ sessions /\ fst openNodes /\ fst reload)
(cpt' openNodes reload showLogin)
cpt' openNodes reload showLogin (frontends /\ route /\ sessions /\ _ /\ _) = do
pure $ R.fragment $ A.cons (plus showLogin) trees
where
trees = tree <$> unSessions sessions
tree s@(Session {treeId}) =
treeView { root: treeId
, frontends
, mCurrentRoute: Just route
, session: s
, openNodes
, reload
}
treeView { root: treeId, frontends, mCurrentRoute: Just route, session: s, openNodes, reload }
plus :: R2.Setter Boolean -> R.Element
plus showLogin =
...
...
src/Gargantext/Components/Forest/Tree.purs
View file @
c3bba506
...
...
@@ -31,7 +31,7 @@ type Props = ( root :: ID
, session :: Session
, frontends :: Frontends
, openNodes :: R.State (Set TreeId)
, reload :: R.State
Int
, reload :: R.State
Reload
)
treeView :: Record Props -> R.Element
...
...
@@ -40,9 +40,7 @@ treeView props = R.createElement treeViewCpt props []
treeViewCpt :: R.Component Props
treeViewCpt = R.hooksComponent "G.C.Tree.treeView" cpt
where
cpt { root, mCurrentRoute, session, frontends, openNodes } _children = do
-- NOTE: this is a hack to reload the tree view on demand
reload <- R.useState' (0 :: Reload)
cpt { root, mCurrentRoute, session, frontends, openNodes, reload } _children = do
pure $ treeLoadView
{ root, mCurrentRoute, session, frontends, openNodes, reload }
...
...
@@ -69,7 +67,7 @@ type TreeViewProps = ( tree :: FTree
, frontends :: Frontends
, session :: Session
, openNodes :: R.State (Set TreeId)
, reload
:: R.State Reload
, reload :: R.State Reload
)
...
...
@@ -96,7 +94,7 @@ toHtml :: R.State Reload
toHtml reload treeState@(ts@{tree: (NTree (LNode {id, name, nodeType}) ary), asyncTasks} /\ setTreeState) session frontends mCurrentRoute openNodes = R.createElement el {} []
where
el = R.hooksComponent "NodeView" cpt
pAction = performAction session reload treeState
pAction = performAction session reload
openNodes
treeState
cpt props _ = do
let folderIsOpen = Set.member id (fst openNodes)
...
...
@@ -148,26 +146,50 @@ childNodes session frontends reload (true /\ _) mCurrentRoute openNodes ary =
performAction :: Session
-> R.State Int
-> R.State (Set TreeId)
-> R.State Tree
-> Action
-> Aff Unit
-- <<<<<<< HEAD
{-
performAction session (_ /\ setReload) (s@{tree: NTree (LNode {id}) _} /\ setTree) (CreateSubmit name nodeType) = do
void $ createNode session id $ CreateValue {name, nodeType}
liftEffect $ setReload (_ + 1)
performAction session (_ /\ setReload) (s@{tree: NTree (LNode {id}) _} /\ setTree) DeleteNode = do
-}
-- performAction session (_ /\ setReload) (s@{tree: NTree (LNode {id}) _} /\ setTree) DeleteNode = do
-- =======
performAction session (_ /\ setReload) (_ /\ setOpenNodes) (s@{tree: NTree (LNode {id}) _} /\ setTree) DeleteNode = do
-- >>>>>>> dev
void $ deleteNode session id
liftEffect $ setReload (_ + 1)
liftEffect do
setOpenNodes (Set.delete id)
setReload (_ + 1)
performAction session _ ({tree: NTree (LNode {id}) _} /\ setTree) (SearchQuery task) = do
-- <<<<<<< HEAD
performAction session (_ /\ setReload) _ ({tree: NTree (LNode {id}) _} /\ setTree) (SearchQuery task) = do
liftEffect $ setTree $ \t@{asyncTasks} -> t { asyncTasks = A.cons task asyncTasks }
liftEffect $ log2 "[performAction] SearchQuery task:" task
liftEffect $ setReload (_ + 1)
{-
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}
-- =======
--}
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}
performAction session (_ /\ setReload) (_ /\ setOpenNodes) (s@{tree: NTree (LNode {id}) _} /\ setTree) (CreateSubmit name nodeType) = do
void $ createNode session id $ CreateValue {name, nodeType}
liftEffect do
setOpenNodes (Set.insert id)
setReload (_ + 1)
performAction session _ ({tree: NTree (LNode {id}) _} /\ setTree) (UploadFile fileType contents) = do
-- performAction session _ ({tree: NTree (LNode {id}) _} /\ setTree) (UploadFile fileType contents) = do
performAction session _ _ ({tree: NTree (LNode {id}) _} /\ setTree) (UploadFile fileType contents) = do
-- >>>>>>> dev
task <- uploadFile session id fileType contents
liftEffect $ setTree $ \t@{asyncTasks} -> t { asyncTasks = A.cons task asyncTasks }
liftEffect $ log2 "uploaded, task:" task
src/Gargantext/Components/Nodes/Corpus.purs
View file @
c3bba506
...
...
@@ -6,7 +6,7 @@ import Data.Array as A
import Data.Either (Either(..))
import Data.List as List
import Data.Maybe (Maybe(..))
import Data.Tuple (Tuple(..), fst)
import Data.Tuple (Tuple(..), fst
, snd
)
import Data.Tuple.Nested ((/\))
import DOM.Simple.Console (log2)
import Effect (Effect)
...
...
@@ -69,6 +69,15 @@ corpusLayoutViewCpt = R.hooksComponent "G.C.N.C.corpusLayoutView" cpt
cpt {corpus: (NodePoly {hyperdata: Hyperdata {fields}}), nodeId, reload, session} _ = do
let fieldsWithIndex = List.mapWithIndex (\idx -> \t -> Tuple idx t) fields
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 {} [
H.div { className: "row" } [
...
...
@@ -122,19 +131,22 @@ fieldsCodeEditorCpt :: R.Component FieldsCodeEditorProps
fieldsCodeEditorCpt = R.hooksComponent "G.C.N.C.fieldsCodeEditorCpt" cpt
where
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
editors = (\idxField@(Tuple idx field) ->
fieldCodeEditorWrapper { canMoveDown: idx < (List.length fields - 1)
, canMoveUp: idx > 0
, field
, hash: hash idxField
, onChange: onChange fS idx
, onMoveDown: onMoveDown fS idx
, onMoveUp: onMoveUp fS idx
, onRemove: onRemove fS idx
, onRename: onRename fS idx
}) <$> fields
editors masterKey =
(\(Tuple idx field) ->
fieldCodeEditorWrapper { canMoveDown: idx < (List.length fields - 1)
, canMoveUp: idx > 0
, field
, key: (show $ fst masterKey) <> "-" <> (show idx)
, onChange: onChange fS idx
, onMoveDown: onMoveDown masterKey fS idx
, onMoveUp: onMoveUp masterKey fS idx
, onRemove: onRemove fS idx
, onRename: onRename fS idx
}) <$> fields
onChange :: R.State FTFieldsWithIndex -> Index -> FieldType -> Effect Unit
onChange (_ /\ setFields) idx typ = do
...
...
@@ -143,12 +155,14 @@ fieldsCodeEditorCpt = R.hooksComponent "G.C.N.C.fieldsCodeEditorCpt" cpt
Nothing -> fields
Just newFields -> newFields
onMoveDown :: R.State FTFieldsWithIndex -> Index -> Unit -> Effect Unit
onMoveDown (fs /\ setFields) idx _ = do
onMoveDown :: R.State Int -> R.State FTFieldsWithIndex -> Index -> Unit -> Effect Unit
onMoveDown (_ /\ setMasterKey) (fs /\ setFields) idx _ = do
setMasterKey $ (+) 1
setFields $ recomputeIndices <<< (GDA.swapList idx (idx + 1))
onMoveUp :: R.State FTFieldsWithIndex -> Index -> Unit -> Effect Unit
onMoveUp (_ /\ setFields) idx _ = do
onMoveUp :: R.State Int -> R.State FTFieldsWithIndex -> Index -> Unit -> Effect Unit
onMoveUp (_ /\ setMasterKey) (_ /\ setFields) idx _ = do
setMasterKey $ (+) 1
setFields $ recomputeIndices <<< (GDA.swapList idx (idx - 1))
onRemove :: R.State FTFieldsWithIndex -> Index -> Unit -> Effect Unit
...
...
@@ -176,7 +190,7 @@ type FieldCodeEditorProps =
canMoveDown :: Boolean
, canMoveUp :: Boolean
, field :: FTField
,
hash :: Hash
,
key :: String
, onChange :: FieldType -> Effect Unit
, onMoveDown :: Unit -> Effect Unit
, onMoveUp :: Unit -> Effect Unit
...
...
@@ -190,8 +204,8 @@ fieldCodeEditorWrapper props = R.createElement fieldCodeEditorWrapperCpt props [
fieldCodeEditorWrapperCpt :: R.Component FieldCodeEditorProps
fieldCodeEditorWrapperCpt = R.hooksComponent "G.C.N.C.fieldCodeEditorWrapperCpt" cpt
where
cpt props@{canMoveDown, canMoveUp, field: Field {name, typ},
hash,
onMoveDown, onMoveUp, onRemove, onRename} _ = do
pure $ H.div { className: "row panel panel-default
hash-" <> hash
} [
cpt props@{canMoveDown, canMoveUp, field: Field {name, typ}, onMoveDown, onMoveUp, onRemove, onRename} _ = do
pure $ H.div { className: "row panel panel-default
"
} [
H.div { className: "panel-heading" } [
H.div { className: "code-editor-heading" } [
renameable {onRename, text: name}
...
...
@@ -241,30 +255,53 @@ renameableCpt = R.hooksComponent "G.C.N.C.renameableCpt" cpt
cpt {onRename, text} _ = do
isEditing <- R.useState' false
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" } [
textCpt isEditing state
renameableText {isEditing, onRename, state}
]
where
textCpt :: R.State Boolean -> R.State String -> R.Element
textCpt (false /\ setIsEditing) (text /\ _) = H.div {} [
H.span { className: "text" } [ H.text text ]
, H.span { className: "btn btn-default"
, on: { click: \_ -> setIsEditing $ const true } } [
H.span { className: "glyphicon glyphicon-pencil" } []
]
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
cpt {isEditing: (false /\ setIsEditing), state: (text /\ _)} _ = do
pure $ H.div {} [
H.span { className: "text" } [ H.text text ]
, H.span { className: "btn btn-default"
, on: { click: \_ -> setIsEditing $ const true } } [
H.span { className: "glyphicon glyphicon-pencil" } []
]
]
textCpt (true /\ setIsEditing) (text /\ setText) = H.div {} [
H.input { defaultValue: text
, className: "form-control text"
, on: { change: \e -> setText $ const $ R2.unsafeEventValue e } }
, H.span { className: "btn btn-default"
, on: { click: \_ -> do
setIsEditing $ const false
onRename text
} } [
H.span { className: "glyphicon glyphicon-floppy-disk" } []
]
cpt {isEditing: (true /\ setIsEditing), onRename, state: (text /\ setText)} _ = do
pure $ H.div {} [
H.input { defaultValue: text
, className: "form-control text"
, on: { change: \e -> setText $ const $ R2.unsafeEventValue e } }
, H.span { className: "btn btn-default"
, on: { click: \_ -> do
setIsEditing $ const false
onRename text
} } [
H.span { className: "glyphicon glyphicon-floppy-disk" } []
]
]
fieldCodeEditor :: Record FieldCodeEditorProps -> R.Element
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment