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
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
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
Grégoire Locqueville
purescript-gargantext
Commits
88ba14e3
Commit
88ba14e3
authored
Nov 03, 2020
by
Nicolas Pouillard
Committed by
Alexandre Delanoë
Nov 03, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Document] refactor the annotated field menu
parent
2d431463
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
77 additions
and
128 deletions
+77
-128
AnnotatedField.purs
src/Gargantext/Components/Annotation/AnnotatedField.purs
+56
-103
Menu.purs
src/Gargantext/Components/Annotation/Menu.purs
+5
-5
ContextMenu.purs
src/Gargantext/Components/ContextMenu/ContextMenu.purs
+16
-20
No files found.
src/Gargantext/Components/Annotation/AnnotatedField.purs
View file @
88ba14e3
...
@@ -13,9 +13,9 @@ module Gargantext.Components.Annotation.AnnotatedField where
...
@@ -13,9 +13,9 @@ module Gargantext.Components.Annotation.AnnotatedField where
import Prelude
import Prelude
import Data.Maybe ( Maybe(..), maybe )
import Data.Maybe ( Maybe(..), maybe )
import Data.Tuple ( Tuple
(..)
)
import Data.Tuple ( Tuple )
import Data.Tuple.Nested ( (/\) )
import Data.Tuple.Nested ( (/\) )
import DOM.Simple.Console (log2)
--
import DOM.Simple.Console (log2)
import DOM.Simple.Event as DE
import DOM.Simple.Event as DE
import Effect ( Effect )
import Effect ( Effect )
import Reactix as R
import Reactix as R
...
@@ -25,7 +25,7 @@ import Reactix.SyntheticEvent as E
...
@@ -25,7 +25,7 @@ import Reactix.SyntheticEvent as E
import Gargantext.Types (CTabNgramType(..), TermList)
import Gargantext.Types (CTabNgramType(..), TermList)
import Gargantext.Components.Annotation.Utils ( termBootstrapClass )
import Gargantext.Components.Annotation.Utils ( termBootstrapClass )
import Gargantext.Components.NgramsTable.Core (NgramsTable, NgramsTerm, findNgramTermList, highlightNgrams, normNgram)
import Gargantext.Components.NgramsTable.Core (NgramsTable, NgramsTerm, findNgramTermList, highlightNgrams, normNgram)
import Gargantext.Components.Annotation.Menu (
AnnotationMenu,
annotationMenu, MenuType(..) )
import Gargantext.Components.Annotation.Menu ( annotationMenu, MenuType(..) )
import Gargantext.Utils.Selection as Sel
import Gargantext.Utils.Selection as Sel
thisModule :: String
thisModule :: String
...
@@ -48,110 +48,65 @@ annotatedField p = R.createElement annotatedFieldComponent p []
...
@@ -48,110 +48,65 @@ annotatedField p = R.createElement annotatedFieldComponent p []
annotatedFieldComponent :: R.Component Props
annotatedFieldComponent :: R.Component Props
annotatedFieldComponent = R.hooksComponentWithModule thisModule "annotatedField" cpt
annotatedFieldComponent = R.hooksComponentWithModule thisModule "annotatedField" cpt
where
where
cpt {ngrams,setTermList,text} _ = do
cpt {ngrams,setTermList,text
: fieldText
} _ = do
mMenu@(_ /\ setMenu) <- R.useState' Nothing
(_ /\ setRedrawMenu) <- R.useState' false
menuRef <- R.useRef Nothing
menuRef <- R.useRef Nothing
let wrapperProps = { className: "annotated-field-wrapper" }
let wrapperProps = { className: "annotated-field-wrapper" }
onSelect :: String -> Maybe TermList -> MouseEvent -> Effect Uni
t
redrawMenu = setRedrawMenu no
t
onSelect text' Nothing event = do
--log2 "[onSelect] text'" text'
hideMenu = do
maybeShowMenu setMenu menuRef setTermList ngrams event
R.setRef menuRef Nothing
onSelect text' (Just list) event = do
redrawMenu
--log2 "[onSelect] text'" text'
--log2 "[onSelect] list" (show list)
showMenu { event, text, getList, menuType } = do
let x = E.clientX event
let x = E.clientX event
y = E.clientY event
y = E.clientY event
n = normNgram CTabTerms text
list = getList n
setList t = do
setList t = do
R.setRef menuRef Nothing
setTermList n list t
setTermList (normNgram CTabTerms text') (Just list) t
hideMenu
--setMenu (const Nothing)
E.preventDefault event
menu = Just {
--range <- Sel.getRange sel 0
x
--log2 "[showMenu] selection range" $ Sel.rangeToTuple range
let menu = Just
{ x
, y
, y
, list
: Just list
, list
, menuType
: SetTermListItem
, menuType
, onClose:
\_ -> R.setRef menuRef Nothing
, onClose:
hideMenu
, setList
, setList
}
}
R.setRef menuRef menu
R.setRef menuRef menu
setMenu $ const menu
redrawMenu
mapCompile (Tuple t l) = {text: t, list: l, onSelect}
compiled = map mapCompile $ compile ngrams text
runs =
HTML.div { className: "annotated-field-runs" } $ map annotateRun compiled
--pure $ HTML.div wrapperProps [maybeAddMenu mMenu runs]
pure $ HTML.div wrapperProps [ addMenu { menuRef }, runs ]
type AddMenuProps = (
menuRef :: R.Ref (Maybe AnnotationMenu)
)
onSelect :: String -> Maybe TermList -> MouseEvent -> Effect Unit
addMenu :: Record AddMenuProps -> R.Element
onSelect text mList event =
addMenu p = R.createElement addMenuCpt p []
case mList of
Just list ->
addMenuCpt :: R.Component AddMenuProps
showMenu { event, text, getList: const (Just list), menuType: SetTermListItem }
addMenuCpt = R.hooksComponentWithModule thisModule "addMenu" cpt
Nothing -> do
where
s <- Sel.getSelection
cpt { menuRef } _ = do
case s of
(mMenu /\ setmMenu) <- R.useState' (Nothing :: Maybe AnnotationMenu)
Just sel -> do
case Sel.selectionToString sel of
R.useEffect' $ do
"" -> hideMenu
let m = R.readRef menuRef
sel' -> do
--log2 "[addMenu] menuRef" m
showMenu { event, text: sel', getList: findNgramTermList ngrams, menuType: NewNgram }
--log2 "[addMenu] mMenu" mMenu
Nothing -> hideMenu
setmMenu $ const m
wrap (text /\ list) = {text, list, onSelect}
pure $ case mMenu of
Nothing -> HTML.div {} []
pure $ HTML.div wrapperProps
Just menu -> annotationMenu setmMenu menu
[ maybe (HTML.div {} []) annotationMenu $ R.readRef menuRef
, HTML.div { className: "annotated-field-runs" }
-- forall e. IsMouseEvent e => R.Setter (Maybe AnnotationMenu) -> R.Setter ? -> ? -> e -> Effect Unit
$ annotateRun
maybeShowMenu setMenu menuRef setTermList ngrams event = do
<$> wrap
s <- Sel.getSelection
<$> compile ngrams fieldText
--log2 "[maybeShowMenu] s" s
]
case s of
Just sel -> do
case Sel.selectionToString sel of
"" -> pure unit
sel' -> do
let x = E.clientX event
y = E.clientY event
n = normNgram CTabTerms sel'
list = findNgramTermList ngrams n
setList t = do
setTermList n list t
R.setRef menuRef Nothing
--setMenu (const Nothing)
E.preventDefault event
range <- Sel.getRange sel 0
--log2 "[maybeShowMenu] selection range" $ Sel.rangeToTuple range
let menu = Just {
x
, y
, list
, menuType: NewNgram
, onClose: \_ -> R.setRef menuRef Nothing
, setList
}
R.setRef menuRef menu
setMenu $ const $ menu
Nothing -> pure unit
-- Nothing -> do
-- R.setRef menuRef Nothing
maybeAddMenu
:: R.State (Maybe AnnotationMenu)
-> R.Element
-> R.Element
maybeAddMenu (Just props /\ setMenu) e = annotationMenu setMenu props <> e
maybeAddMenu _ e = e
compile :: NgramsTable -> Maybe String -> Array (Tuple String (Maybe TermList))
compile :: NgramsTable -> Maybe String -> Array (Tuple String (Maybe TermList))
compile ngrams = maybe [] (highlightNgrams CTabTerms ngrams)
compile ngrams = maybe [] (highlightNgrams CTabTerms ngrams)
...
@@ -170,13 +125,11 @@ annotateRun p = R.createElement annotatedRunComponent p []
...
@@ -170,13 +125,11 @@ annotateRun p = R.createElement annotatedRunComponent p []
annotatedRunComponent :: R.Component Run
annotatedRunComponent :: R.Component Run
annotatedRunComponent = R.staticComponent "AnnotatedRun" cpt
annotatedRunComponent = R.staticComponent "AnnotatedRun" cpt
where
where
cpt { list: Nothing, onSelect, text } _ =
cpt { list, onSelect, text } _ = elt [ HTML.text text ]
HTML.span { on: { mouseUp: \e -> onSelect text Nothing e } } [ HTML.text text ]
cpt { list: (Just list), onSelect, text } _ =
HTML.span { className: className list
, on: { click: \e -> onSelect text (Just list) e } } [ HTML.text text ]
where
where
className list' = "annotation-run bg-" <> termBootstrapClass list'
cb = onSelect text list
elt =
case list of
Nothing -> HTML.span { on: { mouseUp: cb } }
Just l -> HTML.span { className: "annotation-run bg-" <> termBootstrapClass l
, on: { click: cb } }
\ No newline at end of file
src/Gargantext/Components/Annotation/Menu.purs
View file @
88ba14e3
...
@@ -30,16 +30,16 @@ type Props =
...
@@ -30,16 +30,16 @@ type Props =
type AnnotationMenu = {
type AnnotationMenu = {
x :: Number
x :: Number
, y :: Number
, y :: Number
, onClose ::
Unit ->
Effect Unit
, onClose :: Effect Unit
| Props
| Props
}
}
-- | An Annotation Menu is parameterised by a Maybe Termlist of the
-- | An Annotation Menu is parameterised by a Maybe Termlist of the
-- | TermList the currently selected text belongs to
-- | TermList the currently selected text belongs to
annotationMenu ::
R.Setter (Maybe AnnotationMenu) ->
AnnotationMenu -> R.Element
annotationMenu :: AnnotationMenu -> R.Element
annotationMenu
setMenu { x,y,list,menuType, onClose,setList
} =
annotationMenu
{x, y, list, menuType, onClose, setList
} =
CM.contextMenu {
x,y, onClose, setMenu
} [
CM.contextMenu {
x, y, onClose
} [
R.createElement annotationMenuCpt {list,
menuType,
setList} []
R.createElement annotationMenuCpt {list,
menuType,
setList} []
]
]
annotationMenuCpt :: R.Component Props
annotationMenuCpt :: R.Component Props
...
...
src/Gargantext/Components/ContextMenu/ContextMenu.purs
View file @
88ba14e3
...
@@ -26,8 +26,7 @@ thisModule = "Gargantext.Components.ContextMenu.ContextMenu"
...
@@ -26,8 +26,7 @@ thisModule = "Gargantext.Components.ContextMenu.ContextMenu"
type Props t = (
type Props t = (
x :: Number
x :: Number
, y :: Number
, y :: Number
, onClose :: Unit -> Effect Unit
, onClose :: Effect Unit
, setMenu :: R.Setter (Maybe t)
)
)
contextMenu :: forall t. Record (Props t) -> Array R.Element -> R.Element
contextMenu :: forall t. Record (Props t) -> Array R.Element -> R.Element
...
@@ -36,7 +35,7 @@ contextMenu = R.createElement contextMenuCpt
...
@@ -36,7 +35,7 @@ contextMenu = R.createElement contextMenuCpt
contextMenuCpt :: forall t. R.Component (Props t)
contextMenuCpt :: forall t. R.Component (Props t)
contextMenuCpt = R.hooksComponentWithModule thisModule "contextMenu" cpt
contextMenuCpt = R.hooksComponentWithModule thisModule "contextMenu" cpt
where
where
cpt menu@{ x, y, onClose
, setMenu
} children = do
cpt menu@{ x, y, onClose } children = do
host <- R2.getPortalHost
host <- R2.getPortalHost
root <- R.useRef null
root <- R.useRef null
rect /\ setRect <- R.useState $ \_ -> Nothing
rect /\ setRect <- R.useState $ \_ -> Nothing
...
@@ -45,7 +44,7 @@ contextMenuCpt = R.hooksComponentWithModule thisModule "contextMenu" cpt
...
@@ -45,7 +44,7 @@ contextMenuCpt = R.hooksComponentWithModule thisModule "contextMenu" cpt
(\r -> setRect (\_ -> Just (Element.boundingRect r)))
(\r -> setRect (\_ -> Just (Element.boundingRect r)))
(toMaybe $ R.readRef root)
(toMaybe $ R.readRef root)
pure $ pure unit
pure $ pure unit
R.useLayoutEffect2 root rect (contextMenuEffect onClose
setMenu
root)
R.useLayoutEffect2 root rect (contextMenuEffect onClose root)
let cs = [
let cs = [
HTML.div { className: "popover-content" }
HTML.div { className: "popover-content" }
[ HTML.div { className: "panel panel-default" }
[ HTML.div { className: "panel panel-default" }
...
@@ -57,27 +56,28 @@ contextMenuCpt = R.hooksComponentWithModule thisModule "contextMenu" cpt
...
@@ -57,27 +56,28 @@ contextMenuCpt = R.hooksComponentWithModule thisModule "contextMenu" cpt
pure $ R.createPortal [ elems root menu rect $ cs ] host
pure $ R.createPortal [ elems root menu rect $ cs ] host
elems ref menu (Just rect) = HTML.div
elems ref menu (Just rect) = HTML.div
{ ref
{ ref
, key: "context-menu"
, className: "context-menu"
, className: "context-menu"
, style: position menu rect
, style: position menu rect
, data: {toggle: "popover", placement: "right"}
, data: {toggle: "popover", placement: "right"}
}
}
elems ref _ _ = HTML.div
elems ref _ _ = HTML.div
{ ref
{ ref
, key: "context-menu"
, className: "context-menu"
, className: "context-menu"
, data: {toggle: "popover", placement: "right"}
, data: {toggle: "popover", placement: "right"}
}
}
contextMenuEffect
contextMenuEffect
:: forall t.
:: forall t.
(Unit -> Effect Unit)
Effect Unit
-> R.Setter (Maybe t)
-> R.Ref (Nullable DOM.Element)
-> R.Ref (Nullable DOM.Element)
-> Effect (Effect Unit)
-> Effect (Effect Unit)
contextMenuEffect onClose
setMenu
rootRef =
contextMenuEffect onClose rootRef =
case R.readNullableRef rootRef of
case R.readNullableRef rootRef of
Just root -> do
Just root -> do
let onClick = documentClickHandler onClose
setMenu
root
let onClick = documentClickHandler onClose root
let onScroll = documentScrollHandler
setMenu
let onScroll = documentScrollHandler
onClose
DOM.addEventListener document "click" onClick
DOM.addEventListener document "click" onClick
DOM.addEventListener document "scroll" onScroll
DOM.addEventListener document "scroll" onScroll
pure $ do
pure $ do
...
@@ -85,18 +85,14 @@ contextMenuEffect onClose setMenu rootRef =
...
@@ -85,18 +85,14 @@ contextMenuEffect onClose setMenu rootRef =
DOM.removeEventListener document "scroll" onScroll
DOM.removeEventListener document "scroll" onScroll
Nothing -> pure R.nothing
Nothing -> pure R.nothing
documentClickHandler ::
forall t. (Unit -> Effect Unit) -> R.Setter (Maybe t)
-> DOM.Element -> Callback DE.MouseEvent
documentClickHandler ::
Effect Unit
-> DOM.Element -> Callback DE.MouseEvent
documentClickHandler onClose
hide
menu =
documentClickHandler onClose menu =
R2.named "hideMenuOnClickOutside" $ callback $ \e ->
R2.named "hideMenuOnClickOutside" $ callback $ \e ->
if Element.contains menu (DE.target e)
when (Element.contains menu (DE.target e)) onClose
then pure unit
else do
documentScrollHandler :: Effect Unit -> Callback DE.MouseEvent
hide (const Nothing)
documentScrollHandler onClose =
onClose unit
R2.named "hideMenuOnScroll" $ callback $ \e -> onClose
documentScrollHandler :: forall t. R.Setter (Maybe t) -> Callback DE.MouseEvent
documentScrollHandler hide =
R2.named "hideMenuOnScroll" $ callback $ \e -> hide (const Nothing)
position :: forall t. Record (Props t) -> DOMRect -> { left :: Number, top :: Number }
position :: forall t. Record (Props t) -> DOMRect -> { left :: Number, top :: Number }
position mouse {width: menuWidth, height: menuHeight} = {left, top}
position mouse {width: menuWidth, height: menuHeight} = {left, top}
...
...
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