Commit 7f6413fc authored by Przemyslaw Kaminski's avatar Przemyslaw Kaminski

[popup] implement more proper popups in tree view

parent a2556465
......@@ -1480,7 +1480,7 @@
"precise"
],
"repo": "https://github.com/poorscript/purescript-markdown",
"version": "master"
"version": "2020-03-04"
},
"markdown-smolder": {
"dependencies": [
......@@ -1488,7 +1488,7 @@
"smolder"
],
"repo": "https://github.com/poorscript/purescript-markdown-smolder",
"version": "master"
"version": "2020-03-04"
},
"math": {
"dependencies": [],
......@@ -2061,7 +2061,7 @@
"prelude"
],
"repo": "https://github.com/purescript-contrib/purescript-precise",
"version": "master"
"version": "v4.0.0"
},
"prelude": {
"dependencies": [],
......@@ -2370,7 +2370,7 @@
"unsafe-coerce"
],
"repo": "https://github.com/irresponsible/purescript-reactix",
"version": "v0.4.2"
"version": "v0.4.3"
},
"read": {
"dependencies": [
......@@ -2988,8 +2988,8 @@
"react",
"react-dom"
],
"repo": "https://github.com/np/purescript-thermite.git",
"version": "hide"
"repo": "https://github.com/poorscript/purescript-thermite.git",
"version": "hide-2020-03-04"
},
"these": {
"dependencies": [
......
#dafixedtop {
z-index: 999;
}
.logoSmall {
line-height: 15px;
height: 10px;
......@@ -46,9 +50,7 @@ li#rename #rename-a {
}
#node-popup-tooltip {
position: fixed;
background-color: white;
z-index: 1000;
}
#node-popup-tooltip:hover {
border: none;
......@@ -61,6 +63,7 @@ li#rename #rename-a {
#node-popup-tooltip .popup-container .panel {
border: 1px solid rgba(0, 0, 0, 0.2);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
margin-bottom: 0px;
}
#node-popup-tooltip .popup-container .panel .glyphicon-pencil {
color: black;
......@@ -110,6 +113,8 @@ li a#rename-leaf {
position: absolute;
text-decoration: none;
margin-left: 20px;
cursor: pointer;
z-index: 1;
}
li:hover a#rename {
display: block;
......@@ -135,17 +140,6 @@ li:hover a#rename-leaf {
transform: scale(1.4);
}
#arrow {
width: 0;
height: 0;
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-right: 10px solid darkgray;
position: relative;
top: 55px;
left: -9px;
}
#sp-container {
-webkit-transition: width 2s;
transition: width 2s;
......
#dafixedtop
z-index: 999 // correction for the popover
.logoSmall
line-height: 15px
height: 10px
......@@ -45,12 +48,7 @@ li#rename
#node-popup-tooltip
//position : absolute
position: fixed
//left : 96px
//top: -64px
background-color: white
z-index: 1000
&:hover
border: none
text-decoration: none
......@@ -60,6 +58,7 @@ li#rename
.panel
border: 1px solid rgba(0,0,0,0.2)
box-shadow: 0 2px 5px rgba(0,0,0,0.2)
margin-bottom: 0px
.glyphicon-pencil
color: black
.panel-body
......@@ -107,6 +106,8 @@ li
position: absolute
text-decoration: none
margin-left: 20px
cursor: pointer
z-index: 1
&:hover
a#rename
......@@ -132,16 +133,6 @@ li
opacity: 1
transform: scale(1.4)
#arrow
width: 0
height: 0
border-top: 10px solid transparent
border-bottom: 10px solid transparent
border-right:10px solid darkgray
position : relative
top: 55px
left: -9px
#sp-container
-webkit-transition: width 2s // For Safari 3.1 to 6.0
transition: width 2s
......
......@@ -106,7 +106,7 @@ let additions =
, "unsafe-coerce"
]
"https://github.com/irresponsible/purescript-reactix"
"v0.4.2"
"v0.4.3"
, tuples-native =
mkPackage
[ "generics-rep", "prelude", "typelevel", "unsafe-coerce" ]
......
......@@ -26,10 +26,9 @@ type CreateNodeProps =
createNodeView :: (Action -> Aff Unit)
-> Record CreateNodeProps
-> R.State (Maybe NodePopup)
-> Array NodeType
-> R.Element
createNodeView d p@{nodeType} (_ /\ setPopupOpen) nodeTypes = R.createElement el p []
createNodeView d p@{nodeType} nodeTypes = R.createElement el p []
where
el = R.hooksComponent "CreateNodeView" cpt
cpt {id, name} _ = do
......@@ -94,7 +93,8 @@ createNodeView d p@{nodeType} (_ /\ setPopupOpen) nodeTypes = R.createElement el
[ H.button {className: "btn btn-primary text-center"
, type: "button"
, onClick: mkEffectFn1 $ \_ -> do
setPopupOpen $ const Nothing
-- TODO
--setPopupOpen $ const Nothing
launchAff $ d $ CreateSubmit name' nt
} [H.text "Add"]
]
......
......@@ -3,6 +3,7 @@ module Gargantext.Components.Forest.Tree.Node.Box where
import Gargantext.Prelude
import Data.Maybe (Maybe(..))
import Data.Nullable (null)
import Data.Tuple (Tuple(..), snd)
import Data.Tuple.Nested ((/\))
import DOM.Simple.Console (log2)
......@@ -10,6 +11,13 @@ import Effect (Effect)
import Effect.Aff (Aff, launchAff)
import Effect.Class (liftEffect)
import Effect.Uncurried (mkEffectFn1)
import React.SyntheticEvent as E
import Reactix as R
import Reactix.DOM.HTML as H
import URI.Extra.QueryPairs as NQP
import URI.Query as Query
import Web.File.FileReader.Aff (readAsText)
import Gargantext.Components.Data.Lang (allLangs, Lang(EN))
import Gargantext.Components.Forest.Tree.Node (NodeAction(..), SettingsBox(..), glyphiconNodeAction, settingsBox)
import Gargantext.Components.Forest.Tree.Node.Action (Action(..), DroppedFile(..), FileType(..), ID, Name, UploadFileContents(..))
......@@ -26,13 +34,8 @@ import Gargantext.Sessions (Session, sessionId)
import Gargantext.Types (NodeType(..))
import Gargantext.Types as GT
import Gargantext.Utils (glyphicon, glyphiconActive)
import Gargantext.Utils.Popover as Popover
import Gargantext.Utils.Reactix as R2
import React.SyntheticEvent as E
import Reactix as R
import Reactix.DOM.HTML as H
import URI.Extra.QueryPairs as NQP
import URI.Query as Query
import Web.File.FileReader.Aff (readAsText)
type Dispatch = Action -> Aff Unit
......@@ -59,11 +62,11 @@ nodeMainSpan d p folderOpen session frontends = R.createElement el p []
el = R.hooksComponent "G.C.F.T.N.B.NodeMainSpan" cpt
cpt props@{id, asyncTasks, mCurrentRoute, name, nodeType, onAsyncTaskFinish} _ = do
-- only 1 popup at a time is allowed to be opened
popupOpen <- R.useState' (Nothing :: Maybe NodePopup)
popupPosition <- R.useState' (Nothing :: Maybe R2.Point)
droppedFile <- R.useState' (Nothing :: Maybe DroppedFile)
isDragOver <- R.useState' false
popperRef <- R.useRef null
pure $ H.span (dropProps droppedFile isDragOver) $
[ folderIcon nodeType folderOpen
, H.a { href: (url frontends (GT.NodePath (sessionId session) nodeType (Just id)))
......@@ -74,8 +77,10 @@ nodeMainSpan d p folderOpen session frontends = R.createElement el p []
}
[ nodeText { isSelected: (mCorpusId mCurrentRoute) == (Just id)
, name: name' props} ]
, popOverIcon showBox popupOpen popupPosition
, mNodePopupView props showBox popupOpen popupPosition
, Popover.popover {} [
popOverIcon true
, mNodePopupView props showBox
]
, fileTypeView {action: d, droppedFile, id, isDragOver, nodeType}
, H.div {} (map (\t -> asyncProgressBar { asyncTask: t
, corpusId: id
......@@ -91,30 +96,18 @@ nodeMainSpan d p folderOpen session frontends = R.createElement el p []
H.a {onClick: R2.effToggler folderOpen'}
[ H.i {className: GT.fldr nodeType open} [] ]
popOverIcon false _ _ = H.div {} []
popOverIcon true (popOver /\ setPopOver) (_ /\ setPopupPosition) =
popOverIcon false = H.div {} []
popOverIcon true =
H.a { className: "glyphicon glyphicon-cog"
, id: "rename-leaf"
, on: { click: toggle popOver }
} []
where
toggle Nothing e = do
setPopupPosition $ const $ Just $ R2.mousePosition e
setPopOver $ const $ Just NodePopup
toggle _ _ = do
setPopupPosition $ const Nothing
setPopOver $ const Nothing
mNodePopupView _ false _ _ = H.div {} []
mNodePopupView _ _ (Nothing /\ _) _ = H.div {} []
mNodePopupView _ _ _ (Nothing /\ _) = H.div {} []
mNodePopupView props@{asyncTasks, id, nodeType} true popupOpen (Just position /\ _) =
mNodePopupView _ false = H.div {} []
mNodePopupView props@{asyncTasks, id, nodeType} true =
nodePopupView { id
, dispatch: d
, name: name' props
, nodePopupState: popupOpen
, nodeType
, position
, session
}
......@@ -189,12 +182,18 @@ type NodePopupProps =
( id :: ID
, dispatch :: Dispatch
, name :: Name
, nodePopupState :: R.State (Maybe NodePopup)
, nodeType :: GT.NodeType
, position :: R2.Point
, session :: Session
)
type NodePopupS =
(
action :: Maybe NodeAction
, id :: ID
, name :: Name
, nodeType :: GT.NodeType
)
iconAStyle :: { color :: String, paddingTop :: String, paddingBottom :: String}
iconAStyle = { color : "black"
, paddingTop : "6px"
......@@ -207,13 +206,12 @@ nodePopupView p = R.createElement nodePopupCpt p []
nodePopupCpt :: R.Component NodePopupProps
nodePopupCpt = R.hooksComponent "G.C.F.T.N.B.nodePopupView" cpt
where
cpt p@{nodePopupState: mPop@(Just NodePopup /\ setPopupOpen)} _ = do
cpt p _ = do
renameBoxOpen <- R.useState' false
nodePopupState@(nodePopup /\ setNodePopup) <- R.useState' {action: Nothing, id: p.id, name: p.name, nodeType: p.nodeType}
search <- R.useState' $ defaultSearch { node_id = Just p.id }
pure $ H.div (tooltipProps p.position) $
[ H.div {id: "arrow"} []
, H.div { className: "popup-container" }
pure $ H.div tooltipProps $
[ H.div { className: "popup-container" }
[ H.div { className: "panel panel-default" }
[ H.div {className: ""}
[ H.div { className : "col-md-11"}
......@@ -223,7 +221,7 @@ nodePopupCpt = R.hooksComponent "G.C.F.T.N.B.nodePopupView" cpt
]
, panelHeading renameBoxOpen p
, panelBody nodePopupState p
, mPanelAction nodePopup.action p search
, mPanelAction nodePopupState p search
]
, if nodePopup.action == Just SearchBox then
H.div {}
......@@ -235,13 +233,13 @@ nodePopupCpt = R.hooksComponent "G.C.F.T.N.B.nodePopupView" cpt
]
]
where
tooltipProps (R2.Point {x, y}) = {
tooltipProps = {
className: ""
, id: "node-popup-tooltip"
, title: "Node settings"
, data: { toggle: "tooltip"
, placement: "right"},
style: { top: y - 65.0, left: x + 10.0 }
, placement: "right"}
--, style: { top: y - 65.0, left: x + 10.0 }
}
panelHeading renameBoxOpen@(open /\ _) {dispatch: d, id, name, nodeType} =
......@@ -255,8 +253,6 @@ nodePopupCpt = R.hooksComponent "G.C.F.T.N.B.nodePopupView" cpt
, H.div {className: "col-md-1"}
[ H.a { "type" : "button"
, className: glyphicon "remove-circle"
, onClick : mkEffectFn1
$ \_ -> setPopupOpen $ const Nothing
, title : "Close"} []
]
]
......@@ -288,15 +284,15 @@ nodePopupCpt = R.hooksComponent "G.C.F.T.N.B.nodePopupView" cpt
where
SettingsBox {edit, doc, buttons} = settingsBox nodeType
mPanelAction :: Maybe NodeAction -> Record NodePopupProps -> R.State Search -> R.Element
mPanelAction Nothing _ _ = H.div {} []
mPanelAction (Just a) p search =
mPanelAction :: R.State (Record NodePopupS) -> Record NodePopupProps -> R.State Search -> R.Element
mPanelAction ({action: Nothing} /\ _) _ _ = H.div {} []
mPanelAction ({action: Just action} /\ _) p search =
panelAction {
action: a
action
, dispatch: p.dispatch
, id: p.id
, name: p.name
, nodePopupState: mPop
, nodePopup: Just NodePopup
, nodeType: p.nodeType
, search
, session: p.session
......@@ -324,8 +320,6 @@ nodePopupCpt = R.hooksComponent "G.C.F.T.N.B.nodePopupView" cpt
Tuple (NQP.keyFromString "query") (Just (NQP.valueFromString term))
]
cpt _ _ = pure $ H.div {} []
type ActionState =
(
......@@ -383,7 +377,7 @@ type PanelActionProps =
, action :: NodeAction
, dispatch :: Dispatch
, name :: Name
, nodePopupState :: R.State (Maybe NodePopup)
, nodePopup :: Maybe NodePopup
, nodeType :: GT.NodeType
, session :: Session
, search :: R.State Search
......@@ -440,8 +434,8 @@ panelActionCpt = R.hooksComponent "G.C.F.T.N.B.panelAction" cpt
H.div {style: {margin: "10px"}} (map (\t -> H.p {} [H.text t]) ["Are your sure you want to delete it ?", "If yes, click again below."])
, reallyDelete d
]
cpt {action: Add xs, dispatch: d, id, name, nodePopupState: p, nodeType} _ = do
pure $ createNodeView d {id, name, nodeType} p xs
cpt {action: Add xs, dispatch: d, id, name, nodePopup: p, nodeType} _ = do
pure $ createNodeView d {id, name, nodeType} xs
cpt {action: CopyFromCorpus, dispatch, id, nodeType, session} _ = do
pure $ copyFromCorpusView {dispatch, id, nodeType, session}
cpt _ _ = do
......@@ -450,10 +444,11 @@ panelActionCpt = R.hooksComponent "G.C.F.T.N.B.panelAction" cpt
fragmentPT text = H.div {style: {margin: "10px"}} [H.text text]
onSearch :: Record PanelActionProps -> GT.AsyncTaskWithType -> Effect Unit
onSearch {dispatch: d, nodePopupState: p} task = do
onSearch {dispatch: d, nodePopup: p} task = do
_ <- launchAff $ d (SearchQuery task)
-- close popup
snd p $ const Nothing
-- TODO
--snd p $ const Nothing
pure unit
......
'use strict';
const popover = require('react-awesome-popover');
if (typeof window !== 'undefined') {
window.Popover = popover;
}
exports.popoverCpt = popover;
module Gargantext.Utils.Popover where
import Data.Nullable (Nullable)
import DOM.Simple.Types (Element)
import Reactix as R
import Type.Row as TR
import Gargantext.Prelude
type Props = ()
foreign import popoverCpt :: R.Component Props
popover :: Record Props -> Array R.Element -> R.Element
popover = R.rawCreateElement popoverCpt
......@@ -5388,6 +5388,13 @@ raw-body@2.4.0:
iconv-lite "0.4.24"
unpipe "1.0.0"
react-awesome-popover@^6.1.1:
version "6.1.1"
resolved "https://registry.yarnpkg.com/react-awesome-popover/-/react-awesome-popover-6.1.1.tgz#3e37d3d3d4ad49d23b0e73a8d247dc3b1a5260e0"
integrity sha512-jBLcTpd6NaCBwWVfONzDqry4rowBgnHh7DW4bWJAd2GxMif6XAbIIBk2UDBWLjLqjhaFeL/c0QCLGElJpyDPZg==
dependencies:
react "^16.9.0"
react-dom@^16.10:
version "16.12.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.12.0.tgz#0da4b714b8d13c2038c9396b54a92baea633fe11"
......@@ -5420,6 +5427,15 @@ react@^16.10:
object-assign "^4.1.1"
prop-types "^15.6.2"
react@^16.9.0:
version "16.13.0"
resolved "https://registry.yarnpkg.com/react/-/react-16.13.0.tgz#d046eabcdf64e457bbeed1e792e235e1b9934cf7"
integrity sha512-TSavZz2iSLkq5/oiE7gnFzmURKZMltmi193rm5HEoUDAXpzT9Kzw6oNZnGoai/4+fUnm7FqS5dwgUL34TujcWQ==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
prop-types "^15.6.2"
read-only-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/read-only-stream/-/read-only-stream-2.0.0.tgz#2724fd6a8113d73764ac288d4386270c1dbf17f0"
......
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