Commit e92c9ef5 authored by Alexandre Delanoë's avatar Alexandre Delanoë

Merge remote-tracking branch 'origin/513-dev-pin-tree' into dev-merge

parents f562b68f 7f3965da
...@@ -10318,6 +10318,23 @@ input[type=range]:-moz-focusring { ...@@ -10318,6 +10318,23 @@ input[type=range]:-moz-focusring {
left: 16px; left: 16px;
} }
.mainleaf__pin-icon {
visibility: hidden;
position: absolute;
}
.mainleaf:hover .mainleaf__pin-icon {
visibility: visible;
}
.right-handed .mainleaf:hover .mainleaf__pin-icon {
margin-left: 14px;
right: 64px;
}
.left-handed .mainleaf:hover .mainleaf__pin-icon {
margin-right: 14px;
left: 64px;
}
.mainleaf__update-icon { .mainleaf__update-icon {
position: absolute; position: absolute;
} }
......
...@@ -10122,6 +10122,23 @@ input[type=range]:-moz-focusring { ...@@ -10122,6 +10122,23 @@ input[type=range]:-moz-focusring {
left: 16px; left: 16px;
} }
.mainleaf__pin-icon {
visibility: hidden;
position: absolute;
}
.mainleaf:hover .mainleaf__pin-icon {
visibility: visible;
}
.right-handed .mainleaf:hover .mainleaf__pin-icon {
margin-left: 14px;
right: 64px;
}
.left-handed .mainleaf:hover .mainleaf__pin-icon {
margin-right: 14px;
left: 64px;
}
.mainleaf__update-icon { .mainleaf__update-icon {
position: absolute; position: absolute;
} }
......
...@@ -9884,6 +9884,23 @@ input[type=range]:-moz-focusring { ...@@ -9884,6 +9884,23 @@ input[type=range]:-moz-focusring {
left: 16px; left: 16px;
} }
.mainleaf__pin-icon {
visibility: hidden;
position: absolute;
}
.mainleaf:hover .mainleaf__pin-icon {
visibility: visible;
}
.right-handed .mainleaf:hover .mainleaf__pin-icon {
margin-left: 14px;
right: 64px;
}
.left-handed .mainleaf:hover .mainleaf__pin-icon {
margin-right: 14px;
left: 64px;
}
.mainleaf__update-icon { .mainleaf__update-icon {
position: absolute; position: absolute;
} }
......
...@@ -10132,6 +10132,23 @@ input[type=range]:-moz-focusring { ...@@ -10132,6 +10132,23 @@ input[type=range]:-moz-focusring {
left: 16px; left: 16px;
} }
.mainleaf__pin-icon {
visibility: hidden;
position: absolute;
}
.mainleaf:hover .mainleaf__pin-icon {
visibility: visible;
}
.right-handed .mainleaf:hover .mainleaf__pin-icon {
margin-left: 14px;
right: 64px;
}
.left-handed .mainleaf:hover .mainleaf__pin-icon {
margin-right: 14px;
left: 64px;
}
.mainleaf__update-icon { .mainleaf__update-icon {
position: absolute; position: absolute;
} }
......
...@@ -10133,6 +10133,23 @@ input[type=range]:-moz-focusring { ...@@ -10133,6 +10133,23 @@ input[type=range]:-moz-focusring {
left: 16px; left: 16px;
} }
.mainleaf__pin-icon {
visibility: hidden;
position: absolute;
}
.mainleaf:hover .mainleaf__pin-icon {
visibility: visible;
}
.right-handed .mainleaf:hover .mainleaf__pin-icon {
margin-left: 14px;
right: 64px;
}
.left-handed .mainleaf:hover .mainleaf__pin-icon {
margin-right: 14px;
left: 64px;
}
.mainleaf__update-icon { .mainleaf__update-icon {
position: absolute; position: absolute;
} }
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
"css-greyson-theme": "sass src/sass/themes/greyson.scss:dist/styles/bootstrap-greyson.css", "css-greyson-theme": "sass src/sass/themes/greyson.scss:dist/styles/bootstrap-greyson.css",
"css-herbie-theme": "sass src/sass/themes/herbie.scss:dist/styles/bootstrap-herbie.css", "css-herbie-theme": "sass src/sass/themes/herbie.scss:dist/styles/bootstrap-herbie.css",
"css-monotony-theme": "sass src/sass/themes/monotony.scss:dist/styles/bootstrap-monotony.css", "css-monotony-theme": "sass src/sass/themes/monotony.scss:dist/styles/bootstrap-monotony.css",
"css-npm": "npm run css-themes-npm",
"css-themes-npm": "npm run css-default-theme && npm run css-dark-theme && npm run css-darkster-theme && npm run css-greyson-theme && npm run css-herbie-theme && npm run css-monotony-theme",
"docs": "pulp docs -- --format html", "docs": "pulp docs -- --format html",
"repl": "pulp repl", "repl": "pulp repl",
"clean": "rm -Rf output node_modules", "clean": "rm -Rf output node_modules",
......
...@@ -14,8 +14,11 @@ import Gargantext.Prelude ...@@ -14,8 +14,11 @@ import Gargantext.Prelude
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..))
import Data.Set as Set import Data.Set as Set
import Data.Map (Map)
import Data.Map as Map
import Gargantext.AsyncTasks as GAT import Gargantext.AsyncTasks as GAT
import Gargantext.Components.Lang as Lang import Gargantext.Components.Lang as Lang
import Gargantext.Components.Login.Types (TreeId)
import Gargantext.Components.Nodes.Lists.Types as ListsT import Gargantext.Components.Nodes.Lists.Types as ListsT
import Gargantext.Components.Nodes.Texts.Types as TextsT import Gargantext.Components.Nodes.Texts.Types as TextsT
import Gargantext.Components.Themes as Themes import Gargantext.Components.Themes as Themes
...@@ -59,6 +62,7 @@ type Store = ...@@ -59,6 +62,7 @@ type Store =
, theme :: T.Box Themes.Theme , theme :: T.Box Themes.Theme
, tileAxisXList :: T.Box (Array (Record Tile)) , tileAxisXList :: T.Box (Array (Record Tile))
, tileAxisYList :: T.Box (Array (Record Tile)) , tileAxisYList :: T.Box (Array (Record Tile))
, pinnedTreeId :: T.Box (Map String Int)
) )
type State = type State =
...@@ -85,6 +89,7 @@ type State = ...@@ -85,6 +89,7 @@ type State =
, theme :: Themes.Theme , theme :: Themes.Theme
, tileAxisXList :: Array (Record Tile) , tileAxisXList :: Array (Record Tile)
, tileAxisYList :: Array (Record Tile) , tileAxisYList :: Array (Record Tile)
, pinnedTreeId :: Map String Int
) )
options :: Record State options :: Record State
...@@ -112,6 +117,7 @@ options = ...@@ -112,6 +117,7 @@ options =
, theme : Themes.defaultTheme , theme : Themes.defaultTheme
, tileAxisXList : mempty , tileAxisXList : mempty
, tileAxisYList : mempty , tileAxisYList : mempty
, pinnedTreeId : Map.empty
} }
context :: R.Context (Record Store) context :: R.Context (Record Store)
......
...@@ -6,7 +6,9 @@ module Gargantext.Components.Forest ...@@ -6,7 +6,9 @@ module Gargantext.Components.Forest
import Gargantext.Prelude import Gargantext.Prelude
import Data.Array as A import Data.Array as A
import Data.Maybe (Maybe(..)) import Data.Map (empty)
import Data.Map as Map
import Data.Maybe (Maybe(..), fromMaybe)
import Gargantext.Components.App.Store (Boxes) import Gargantext.Components.App.Store (Boxes)
import Gargantext.Components.Bootstrap as B import Gargantext.Components.Bootstrap as B
import Gargantext.Components.Bootstrap.Types (ButtonVariant(..), Position(..), TooltipPosition(..), Variant(..)) import Gargantext.Components.Bootstrap.Types (ButtonVariant(..), Position(..), TooltipPosition(..), Variant(..))
...@@ -36,7 +38,8 @@ forestLayoutCpt :: R.Component Props ...@@ -36,7 +38,8 @@ forestLayoutCpt :: R.Component Props
forestLayoutCpt = here.component "forest" cpt where forestLayoutCpt = here.component "forest" cpt where
cpt { boxes: boxes@{ handed cpt { boxes: boxes@{ handed
, reloadForest , reloadForest
, sessions } , sessions
, pinnedTreeId }
, frontends } _ = do , frontends } _ = do
-- TODO Fix this. I think tasks shouldn't be a Box but only a Reductor -- TODO Fix this. I think tasks shouldn't be a Box but only a Reductor
-- tasks' <- GAT.useTasks reloadRoot reloadForest -- tasks' <- GAT.useTasks reloadRoot reloadForest
...@@ -44,6 +47,7 @@ forestLayoutCpt = here.component "forest" cpt where ...@@ -44,6 +47,7 @@ forestLayoutCpt = here.component "forest" cpt where
-- T.write_ (Just tasks') tasks -- T.write_ (Just tasks') tasks
handed' <- T.useLive T.unequal handed handed' <- T.useLive T.unequal handed
sessions' <- T.useLive T.unequal sessions sessions' <- T.useLive T.unequal sessions
pinnedTreeId' <- T.useLive T.unequal pinnedTreeId
-- forestOpen' <- T.useLive T.unequal forestOpen -- forestOpen' <- T.useLive T.unequal forestOpen
-- reloadRoot' <- T.useLive T.unequal reloadRoot -- reloadRoot' <- T.useLive T.unequal reloadRoot
-- route' <- T.useLive T.unequal route -- route' <- T.useLive T.unequal route
...@@ -54,10 +58,10 @@ forestLayoutCpt = here.component "forest" cpt where ...@@ -54,10 +58,10 @@ forestLayoutCpt = here.component "forest" cpt where
H.div H.div
{ className: "forest-layout" } { className: "forest-layout" }
(A.cons (plus { boxes }) (trees handed' sessions')) (A.cons (plus { boxes }) (trees handed' pinnedTreeId' sessions'))
where where
trees handed' sessions' = (tree handed') <$> unSessions sessions' trees handed' pinnedTreeId' sessions' = (tree handed' pinnedTreeId') <$> unSessions sessions'
tree handed' s@(Session { treeId }) = tree handed' pinnedTreeId' s@(Session { treeId }) =
H.div H.div
{ className: "forest-layout__tree" } { className: "forest-layout__tree" }
[ [
...@@ -66,11 +70,13 @@ forestLayoutCpt = here.component "forest" cpt where ...@@ -66,11 +70,13 @@ forestLayoutCpt = here.component "forest" cpt where
, frontends , frontends
, handed: handed' , handed: handed'
, reload: reloadForest , reload: reloadForest
, root: treeId , root: r
, session: s , session: s
, key: "tree-" <> (show treeId) , key: "tree-" <> (show treeId)
} }
] ]
where
r = fromMaybe treeId (Map.lookup (show s) pinnedTreeId')
type Plus = ( boxes :: Boxes ) type Plus = ( boxes :: Boxes )
...@@ -78,7 +84,7 @@ plus :: R2.Leaf Plus ...@@ -78,7 +84,7 @@ plus :: R2.Leaf Plus
plus = R2.leaf plusCpt plus = R2.leaf plusCpt
plusCpt :: R.Component Plus plusCpt :: R.Component Plus
plusCpt = here.component "plus" cpt where plusCpt = here.component "plus" cpt where
cpt { boxes: { backend, showLogin } } _ = do cpt { boxes: { backend, showLogin, pinnedTreeId} } _ = do
-- Hooks -- Hooks
{ goToRoute } <- useLinkHandler { goToRoute } <- useLinkHandler
...@@ -97,7 +103,7 @@ plusCpt = here.component "plus" cpt where ...@@ -97,7 +103,7 @@ plusCpt = here.component "plus" cpt where
[ [
B.tooltipContainer B.tooltipContainer
{ delayShow: 600 { delayShow: 600
, position: TooltipPosition Top , position: TooltipPosition Right
, tooltipSlot: , tooltipSlot:
B.span_ "Back to home" B.span_ "Back to home"
, defaultSlot: , defaultSlot:
...@@ -113,7 +119,23 @@ plusCpt = here.component "plus" cpt where ...@@ -113,7 +119,23 @@ plusCpt = here.component "plus" cpt where
, ,
B.tooltipContainer B.tooltipContainer
{ delayShow: 600 { delayShow: 600
, position: TooltipPosition Top , position: TooltipPosition Right
, tooltipSlot:
B.span_ "Reset pins"
, defaultSlot:
B.button
{ className: "forest-layout__action__button"
, callback: \_ -> T.write_ empty pinnedTreeId
, variant: ButtonVariant Light
}
[
B.icon { name: "refresh" }
]
}
,
B.tooltipContainer
{ delayShow: 600
, position: TooltipPosition Right
, tooltipSlot: , tooltipSlot:
B.span_ "Add or remove connection to the server(s)" B.span_ "Add or remove connection to the server(s)"
, defaultSlot: , defaultSlot:
......
...@@ -5,8 +5,10 @@ module Gargantext.Components.Forest.Tree.Node ...@@ -5,8 +5,10 @@ module Gargantext.Components.Forest.Tree.Node
import Gargantext.Prelude import Gargantext.Prelude
import DOM.Simple.Console (log2)
import Data.Array.NonEmpty as NArray import Data.Array.NonEmpty as NArray
import Data.Foldable (intercalate) import Data.Foldable (intercalate)
import Data.Map as Map
import Data.Maybe (Maybe(..), maybe) import Data.Maybe (Maybe(..), maybe)
import Data.String.Regex as Regex import Data.String.Regex as Regex
import Data.Tuple.Nested ((/\)) import Data.Tuple.Nested ((/\))
...@@ -75,11 +77,7 @@ nodeSpan = R2.leaf nodeSpanCpt ...@@ -75,11 +77,7 @@ nodeSpan = R2.leaf nodeSpanCpt
nodeSpanCpt :: R.Component NodeSpanProps nodeSpanCpt :: R.Component NodeSpanProps
nodeSpanCpt = here.component "nodeSpan" cpt nodeSpanCpt = here.component "nodeSpan" cpt
where where
cpt props@{ boxes: boxes@{ errors cpt props@{ boxes
, reloadMainPage
, reloadRoot
, route
, tasks }
, dispatch , dispatch
, folderOpen , folderOpen
, frontends , frontends
...@@ -92,14 +90,14 @@ nodeSpanCpt = here.component "nodeSpan" cpt ...@@ -92,14 +90,14 @@ nodeSpanCpt = here.component "nodeSpan" cpt
} _ = do } _ = do
-- States -- States
route' <- T.useLive T.unequal route route' <- T.useLive T.unequal boxes.route
-- only 1 popup at a time is allowed to be opened -- only 1 popup at a time is allowed to be opened
droppedFile <- T.useBox (Nothing :: Maybe DroppedFile) droppedFile <- T.useBox (Nothing :: Maybe DroppedFile)
droppedFile' <- T.useLive T.unequal droppedFile droppedFile' <- T.useLive T.unequal droppedFile
isDragOver <- T.useBox false isDragOver <- T.useBox false
isDragOver' <- T.useLive T.unequal isDragOver isDragOver' <- T.useLive T.unequal isDragOver
currentTasks <- GAT.focus id tasks currentTasks <- GAT.focus id boxes.tasks
currentTasks' <- T.useLive T.unequal currentTasks currentTasks' <- T.useLive T.unequal currentTasks
folderOpen' <- R2.useLive' folderOpen folderOpen' <- R2.useLive' folderOpen
...@@ -168,10 +166,10 @@ nodeSpanCpt = here.component "nodeSpan" cpt ...@@ -168,10 +166,10 @@ nodeSpanCpt = here.component "nodeSpan" cpt
-> Unit -> Unit
-> Effect Unit -> Effect Unit
onTaskFinish id' t _ = do onTaskFinish id' t _ = do
GAT.finish id' t tasks GAT.finish id' t boxes.tasks
if GAT.asyncTaskTTriggersAppReload t then do if GAT.asyncTaskTTriggersAppReload t then do
here.log2 "reloading root for task" t here.log2 "reloading root for task" t
T2.reload reloadRoot T2.reload boxes.reloadRoot
else do else do
if GAT.asyncTaskTTriggersTreeReload t then do if GAT.asyncTaskTTriggersTreeReload t then do
here.log2 "reloading tree for task" t here.log2 "reloading tree for task" t
...@@ -181,7 +179,7 @@ nodeSpanCpt = here.component "nodeSpan" cpt ...@@ -181,7 +179,7 @@ nodeSpanCpt = here.component "nodeSpan" cpt
pure unit pure unit
if GAT.asyncTaskTTriggersMainPageReload t then do if GAT.asyncTaskTTriggersMainPageReload t then do
here.log2 "reloading main page for task" t here.log2 "reloading main page for task" t
T2.reload reloadMainPage T2.reload boxes.reloadMainPage
else do else do
here.log2 "task doesn't trigger a main page reload" t here.log2 "task doesn't trigger a main page reload" t
pure unit pure unit
...@@ -304,23 +302,35 @@ nodeSpanCpt = here.component "nodeSpan" cpt ...@@ -304,23 +302,35 @@ nodeSpanCpt = here.component "nodeSpan" cpt
} [] } []
, ,
R2.when (showBox) $ R2.when (showBox) $
R.fragment [
B.iconButton B.iconButton
{ name: "flower-7" { name: "anchor"
, className: "mainleaf__settings-icon" , className: "mainleaf__pin-icon"
, callback: \_ -> T.write_ true isBoxVisible , callback: \_ -> do
, title: log2 "[Pinning tree ID]" id
"Each node of the Tree can perform some actions.\n" T.modify_ (Map.insert (show session) id) boxes.pinnedTreeId
<> "Click here to execute one of them." , title: "Pin the tree to this node"
, variant: Secondary , variant: Secondary
, elevation: Level1 , elevation: Level1
} }
,
B.iconButton
{ name: "flower-7"
, className: "mainleaf__settings-icon"
, callback: \_ -> T.write_ true isBoxVisible
, title:
"Each node of the Tree can perform some actions.\n"
<> "Click here to execute one of them."
, variant: Secondary
, elevation: Level1
}
]
, ,
R.fragment $ flip map currentTasks' \task -> R.fragment $ flip map currentTasks' \task ->
asyncProgress asyncProgress
{ asyncTask: task { asyncTask: task
, errors , errors: boxes.errors
, nodeId: id , nodeId: id
, onFinish: onTaskFinish id task , onFinish: onTaskFinish id task
, session , session
......
...@@ -250,6 +250,20 @@ $node-popup-width: 544px ...@@ -250,6 +250,20 @@ $node-popup-width: 544px
margin-right: $icon-button-margin margin-right: $icon-button-margin
left: space-x(2) left: space-x(2)
&__pin-icon
visibility: hidden
position: absolute
&:hover &__pin-icon
visibility: visible
@include right-handed
margin-left: $icon-button-margin
right: space-x(8)
@include left-handed
margin-right: $icon-button-margin
left: space-x(8)
&__update-icon &__update-icon
position: absolute position: absolute
......
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