Commit e8976359 authored by Przemyslaw Kaminski's avatar Przemyslaw Kaminski

Merge branch 'dev' into dev-file-upload

parents 6cd7a7d5 c48c056e
......@@ -15,7 +15,7 @@ import Gargantext.Components.Forest.Tree (treeView)
import Gargantext.Ends (Frontends)
import Gargantext.Routes (AppRoute)
import Gargantext.Sessions (Session(..), Sessions, OpenNodes, unSessions)
import Gargantext.Types (Reload)
import Gargantext.Types (Reload, Handed(..))
import Gargantext.Utils.Reactix as R2
type Props =
......@@ -58,6 +58,7 @@ forestCpt = R.hooksComponent "G.C.Forest.forest" cpt where
, openNodes
, reload
, session: s
, handed: RightHanded -- TODO enabling user to change it and save locally
}
plus :: R2.Setter Boolean -> R.Element
......
......@@ -31,7 +31,7 @@ import Gargantext.Components.Forest.Tree.Node.Tools.FTree (FTree, LNode(..), NTr
import Gargantext.Components.Forest.Tree.Node.Tools.Task (Tasks, tasksStruct)
import Gargantext.Ends (Frontends)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Prelude (Unit, bind, discard, map, pure, void, ($), (+), (<>))
import Gargantext.Prelude (Unit, bind, discard, map, pure, void, ($), (+), (<>), (==))
import Gargantext.Routes (AppRoute)
import Gargantext.Sessions (OpenNodes, Session, mkNodeId, get)
import Gargantext.Types (ID, Reload, isPublic, publicize)
......@@ -45,6 +45,7 @@ type CommonProps =
, openNodes :: R.State OpenNodes
, reload :: R.State Reload
, session :: Session
, handed :: GT.Handed
)
------------------------------------------------------------------------
......@@ -66,6 +67,7 @@ treeView props = R.createElement treeViewCpt props []
, openNodes
, reload
, session
, handed
} _children = pure
$ treeLoadView { root
, asyncTasks
......@@ -74,6 +76,7 @@ treeView props = R.createElement treeViewCpt props []
, openNodes
, reload
, session
, handed
}
treeLoadView :: Record Props -> R.Element
......@@ -89,6 +92,7 @@ treeLoadView p = R.createElement treeLoadViewCpt p []
, openNodes
, reload
, session
, handed
} _children = do
let fetch _ = getNodeTree session root
let paint loaded = loadedTreeView { asyncTasks
......@@ -99,6 +103,7 @@ treeLoadView p = R.createElement treeLoadViewCpt p []
, session
, tasks: tasksStruct root asyncTasks reload
, tree: loaded
, handed
}
useLoader { root, counter: fst reload } fetch paint
......@@ -127,7 +132,11 @@ loadedTreeView p = R.createElement loadedTreeViewCpt p []
, session
, tasks
, tree
} _ = pure $ H.ul { className: "tree"}
, handed
} _ = pure $ H.ul { className: "tree " <> if handed == GT.RightHanded
then "flex-start"
else "flex-end"
}
[ toHtml { asyncTasks
, frontends
, mCurrentRoute
......@@ -136,10 +145,13 @@ loadedTreeView p = R.createElement loadedTreeViewCpt p []
, session
, tasks
, tree
, handed: GT.RightHanded -- TODO enabling user to change it
}
]
------------------------------------------------------------------------
type ToHtmlProps =
( asyncTasks :: R.State GAT.Storage
, tasks :: Record Tasks
......@@ -164,6 +176,7 @@ toHtml p@{ asyncTasks
}
) ary
)
, handed
} =
R.createElement el {} []
where
......@@ -190,6 +203,7 @@ toHtml p@{ asyncTasks
, nodeType
, session
, tasks
, handed
} ]
<> childNodes ( Record.merge commonProps
{ asyncTasks
......@@ -199,6 +213,7 @@ toHtml p@{ asyncTasks
) t) ary
else ary
, folderOpen
, handed
}
)
......@@ -212,11 +227,12 @@ type ChildNodesProps =
childNodes :: Record ChildNodesProps -> Array R.Element
childNodes { children: [] } = []
childNodes { folderOpen: (false /\ _) } = []
childNodes props@{ asyncTasks, children, reload } =
childNodes props@{ asyncTasks, children, reload, handed } =
map (\ctree@(NTree (LNode {id}) _) -> H.ul {} [
toHtml (Record.merge commonProps { asyncTasks
, tasks: tasksStruct id asyncTasks reload
, tree: ctree
, handed
}
)]
) $ sorted children
......
module Gargantext.Components.Forest.Tree.Node where
import Data.Array (reverse)
import Data.Maybe (Maybe(..))
import Data.Nullable (null)
import Data.Tuple.Nested ((/\))
......@@ -25,7 +26,7 @@ import Gargantext.Components.Lang (Lang(EN))
import Gargantext.Components.Nodes.Corpus (loadCorpusWithChild)
import Gargantext.Ends (Frontends, url)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Prelude (Unit, bind, const, discard, map, pure, show, unit, void, ($), (<>), (==))
import Gargantext.Prelude (Unit, bind, const, discard, map, pure, show, unit, void, ($), (<>), (==), identity)
import Gargantext.Routes as Routes
import Gargantext.Version as GV
import Gargantext.Sessions (Session, sessionId)
......@@ -44,12 +45,13 @@ type NodeMainSpanProps =
, name :: Name
, nodeType :: GT.NodeType
, tasks :: Record Tasks
, handed :: GT.Handed
| CommonProps
)
nodeMainSpan :: Record NodeMainSpanProps
-> R.Element
nodeMainSpan p@{ dispatch, folderOpen, frontends, session } = R.createElement el p []
nodeMainSpan p@{ dispatch, folderOpen, frontends, session, handed} = R.createElement el p []
where
el = R.hooksComponent "G.C.F.T.N.NodeMainSpan" cpt
cpt props@{id, mCurrentRoute, name, nodeType, tasks: { onTaskFinish, tasks }} _ = do
......@@ -59,7 +61,11 @@ nodeMainSpan p@{ dispatch, folderOpen, frontends, session } = R.createElement el
popoverRef <- R.useRef null
pure $ H.span (dropProps droppedFile isDragOver) $
pure $ H.span (dropProps droppedFile isDragOver)
$ (if handed == GT.LeftHanded
then reverse
else identity)
$
[ chevronIcon nodeType folderOpen
, folderIcon nodeType folderOpen
, if showBox then
......
......@@ -76,7 +76,7 @@ addNodeView p@{ dispatch, nodeType, nodeTypes } = R.createElement el p []
where
defaultNt = (fromMaybe Error $ head nodeTypes)
maybeEdit = [ if edit
then formEdit "Node Name" setNodeName
then formEdit name' setNodeName
else H.div {} []
]
......
......@@ -11,7 +11,6 @@ hasStatus :: NodeType -> NodeAction -> Status
hasStatus _ SearchBox = Test
hasStatus _ Refresh = Dev
hasStatus _ Config = Dev
hasStatus _ (Link _) = Dev
hasStatus _ (Merge _) = Dev
hasStatus _ (Documentation _) = Dev
hasStatus Annuaire Upload = Dev
......
......@@ -6,17 +6,17 @@ import Data.Set (Set)
import Data.Set as Set
import Data.String as S
import Data.Tuple.Nested ((/\))
import Gargantext.Types (Name)
import Effect (Effect)
import Effect.Aff (Aff, launchAff)
import Effect.Uncurried (mkEffectFn1)
import Effect.Aff (Aff, launchAff, launchAff_)
import Reactix as R
import Reactix.DOM.HTML as H
import Gargantext.Components.Forest.Tree.Node.Action
import Gargantext.Components.InputWithEnter (inputWithEnter)
import Gargantext.Prelude (Unit, bind, const, discard, pure, show, ($), (<<<), (<>), read, map, class Read, class Show, not, class Ord)
import Gargantext.Types (ID)
import Gargantext.Types (ID, Name)
import Gargantext.Utils (toggleSet)
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
------------------------------------------------------------------------
......@@ -67,31 +67,42 @@ textInputBox p@{ boxName, boxAction, dispatch, isOpen: (true /\ setIsOpen) } = R
, cancelBtn
]
where
textInput (_ /\ setRenameNodeName) =
textInput (newName /\ setNewName) =
H.div {className: "col-md-8"}
[ H.input { type: "text"
, placeholder: (boxName <> " Node")
, defaultValue: text
[
inputWithEnter {
onEnter: submit newName
, onValueChanged: setNewName <<< const
, autoFocus: false
, className: "form-control"
, onInput: mkEffectFn1 $ setRenameNodeName
<<< const
<<< R2.unsafeEventValue
, defaultValue: text
, placeholder: (boxName <> " Node")
, type: "text"
}
-- [ H.input { type: "text"
-- , placeholder: (boxName <> " Node")
-- , defaultValue: text
-- , className: "form-control"
-- , on: { input: setRenameNodeName
-- <<< const
-- <<< R2.unsafeEventValue }
-- }
]
submitBtn (newName /\ _) =
H.a {className: "btn glyphitem glyphicon glyphicon-ok col-md-2 pull-left"
, type: "button"
, onClick: mkEffectFn1 $ \_ -> do
setIsOpen $ const false
launchAff $ dispatch ( boxAction newName )
, on: { click: submit newName }
, title: "Submit"
} []
cancelBtn =
H.a {className: "btn text-danger glyphitem glyphicon glyphicon-remove col-md-2 pull-left"
, type: "button"
, onClick: mkEffectFn1 $ \_ -> setIsOpen $ const false
, on: { click: \_ -> setIsOpen $ const false }
, title: "Cancel"
} []
submit newName _ = do
setIsOpen $ const false
launchAff_ $ dispatch ( boxAction newName )
textInputBox p@{ boxName, isOpen: (false /\ _) } = R.createElement el p []
where
el = R.hooksComponent (boxName <> "Box") cpt
......@@ -119,10 +130,9 @@ formEdit defaultValue setter =
, placeholder : defaultValue
, defaultValue: "Write" <> defaultValue
, className : "form-control"
, onInput : mkEffectFn1
$ setter
, on: { input: setter
<<< const
<<< R2.unsafeEventValue
<<< R2.unsafeEventValue }
}
]
......@@ -154,12 +164,11 @@ formChoice :: forall a b c d
formChoice nodeTypes defaultNodeType setNodeType =
H.div { className: "form-group"}
[ R2.select { className: "form-control"
, onChange : mkEffectFn1
$ setNodeType
, on: { change: \_ -> setNodeType
<<< const
<<< fromMaybe defaultNodeType
<<< read
<<< R2.unsafeEventValue
<<< R2.unsafeEventValue }
}
(map (\opt -> H.option {} [ H.text $ show opt ]) nodeTypes)
]
......@@ -180,8 +189,7 @@ formButton nodeType setNodeType =
, type : "button"
, title: "Form Button"
, style : { width: "100%" }
, onClick : mkEffectFn1
$ \_ -> setNodeType ( const nodeType )
, on: { click: \_ -> setNodeType ( const nodeType ) }
} [H.text $ "Confirmation"]
------------------------------------------------------------------------
......
module Gargantext.Components.InputWithEnter where
import Data.Tuple.Nested ((/\))
import DOM.Simple.Console (log2)
import Effect (Effect)
import Reactix as R
import Reactix.DOM.HTML as H
import Gargantext.Prelude
import Gargantext.Utils.Reactix as R2
type Props a = (
onEnter :: Unit -> Effect Unit
, onValueChanged :: String -> Effect Unit
, autoFocus :: Boolean
, className :: String
, defaultValue :: String
, placeholder :: String
, type :: String
)
inputWithEnter :: forall a. Record (Props a) -> R.Element
inputWithEnter props = R.createElement inputWithEnterCpt props []
inputWithEnterCpt :: forall a. R.Component (Props a)
inputWithEnterCpt = R.hooksComponent "G.C.IWE.inputWithEnter" cpt
where
cpt props@{ onEnter, onValueChanged
, autoFocus, className, defaultValue, placeholder } _ = do
pure $ H.input { on: { input: onInput
, keyPress: onKeyPress }
, autoFocus
, className
, defaultValue
, placeholder
, type: props.type }
where
onInput e = do
onValueChanged $ R2.unsafeEventValue e
onKeyPress e = do
char <- R2.keyCode e
if char == 13 then
onEnter unit
else
pure unit
......@@ -12,18 +12,19 @@ import Data.Tuple.Nested ((/\))
import Effect (Effect)
import Effect.Aff (Aff, launchAff_)
import Effect.Class (liftEffect)
import Reactix as R
import Reactix.DOM.HTML as H
import Gargantext.Components.InputWithEnter (inputWithEnter)
import Gargantext.Components.Nodes.Annuaire.User.Contacts.Tabs as Tabs
import Gargantext.Components.Nodes.Annuaire.User.Contacts.Types (Contact(..), ContactData, ContactTouch(..), ContactWhere(..), ContactWho(..), HyperdataContact(..), HyperdataUser(..), _city, _country, _firstName, _labTeamDeptsJoinComma, _lastName, _mail, _office, _organizationJoinComma, _ouFirst, _phone, _role, _shared, _touch, _who, defaultContactTouch, defaultContactWhere, defaultContactWho, defaultHyperdataContact, defaultHyperdataUser)
import Gargantext.Ends (Frontends)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Prelude (Unit, bind, const, discard, pure, show, unit, ($), (+), (<$>), (<<<), (<>), (==))
import Gargantext.Routes as Routes
import Gargantext.Ends (Frontends)
import Gargantext.Sessions (Session, get, put, sessionId)
import Gargantext.Types (NodeType(..))
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
display :: String -> Array R.Element -> R.Element
display title elems =
......@@ -54,16 +55,17 @@ contactInfos h onUpdateHyperdata = item <$> contactInfoItems
contactInfoItems :: Array {label:: String, defaultVal:: String, lens:: HyperdataUserLens}
contactInfoItems =
[ {label: "Last Name", defaultVal: "Empty Last Name", lens: _shared <<< _who <<< _lastName}
, {label: "First Name", defaultVal: "Empty First Name", lens: _shared <<< _who <<< _firstName}
, {label: "Organisation", defaultVal: "Empty Organisation", lens: _shared <<< _ouFirst <<< _organizationJoinComma}
[ {label: "Last Name" , defaultVal: "Empty Last Name" , lens: _shared <<< _who <<< _lastName }
, {label: "First Name" , defaultVal: "Empty First Name" , lens: _shared <<< _who <<< _firstName }
, {label: "Organisation" , defaultVal: "Empty Organisation" , lens: _shared <<< _ouFirst <<< _organizationJoinComma}
, {label: "Lab/Team/Dept", defaultVal: "Empty Lab/Team/Dept", lens: _shared <<< _ouFirst <<< _labTeamDeptsJoinComma}
, {label: "Office", defaultVal: "Empty Office", lens: _shared <<< _ouFirst <<< _office}
, {label: "City", defaultVal: "Empty City", lens: _shared <<< _ouFirst <<< _city}
, {label: "Country", defaultVal: "Empty Country", lens: _shared <<< _ouFirst <<< _country}
, {label: "Role", defaultVal: "Empty Role", lens: _shared <<< _ouFirst <<< _role}
, {label: "Phone", defaultVal: "Empty Phone", lens: _shared <<< _ouFirst <<< _touch <<< _phone}
, {label: "Mail", defaultVal: "Empty Mail", lens: _shared <<< _ouFirst <<< _touch <<< _mail} ]
, {label: "Office" , defaultVal: "Empty Office" , lens: _shared <<< _ouFirst <<< _office }
, {label: "City" , defaultVal: "Empty City" , lens: _shared <<< _ouFirst <<< _city }
, {label: "Country" , defaultVal: "Empty Country" , lens: _shared <<< _ouFirst <<< _country }
, {label: "Role" , defaultVal: "Empty Role" , lens: _shared <<< _ouFirst <<< _role }
, {label: "Phone" , defaultVal: "Empty Phone" , lens: _shared <<< _ouFirst <<< _touch <<< _phone }
, {label: "Mail" , defaultVal: "Empty Mail" , lens: _shared <<< _ouFirst <<< _touch <<< _mail }
]
type HyperdataUserLens = L.ALens' HyperdataUser String
......@@ -109,11 +111,15 @@ contactInfoItemCpt = R.hooksComponent "G.C.N.A.U.C.contactInfoItem" cpt
onClick _ = setIsEditing $ const true
item (true /\ setIsEditing) valueRef =
H.span {} [
H.input { autoFocus: true
inputWithEnter {
onEnter: onClick
, onValueChanged: R.setRef valueRef
, autoFocus: true
, className: "form-control"
, defaultValue: R.readRef valueRef
, on: {change: \e -> R.setRef valueRef $ R2.unsafeEventValue e}
, placeholder }
, placeholder
, type: "text"
}
, H.span { className: "fa fa-floppy-o"
, on: {click: onClick} } []
]
......
......@@ -19,6 +19,7 @@ import Reactix.DOM.HTML as H
import Gargantext.Prelude
import Gargantext.Components.CodeEditor as CE
import Gargantext.Components.InputWithEnter (inputWithEnter)
import Gargantext.Components.Node (NodePoly(..), HyperdataList)
import Gargantext.Components.Nodes.Corpus.Types (CorpusData, FTField, Field(..), FieldType(..), Hash, Hyperdata(..), defaultField, defaultHaskell', defaultPython', defaultJSON', defaultMarkdown')
import Gargantext.Data.Array as GDA
......@@ -278,7 +279,7 @@ renameableCpt = R.hooksComponent "G.C.N.C.renameableCpt" cpt
snd state $ const text
pure $ H.div { className: "renameable" } [
renameableText {isEditing, onRename, state}
renameableText { isEditing, onRename, state }
]
type RenameableTextProps =
......@@ -304,17 +305,24 @@ renameableTextCpt = R.hooksComponent "G.C.N.C.renameableTextCpt" cpt
]
cpt {isEditing: (true /\ setIsEditing), onRename, state: (text /\ setText)} _ = do
pure $ H.div {} [
H.input { defaultValue: text
inputWithEnter {
onEnter: submit
, onValueChanged: setText <<< const
, autoFocus: false
, className: "form-control text"
, on: { change: \e -> setText $ const $ R2.unsafeEventValue e } }
, defaultValue: text
, placeholder: ""
, type: "text"
}
, H.span { className: "btn btn-default"
, on: { click: \_ -> do
setIsEditing $ const false
onRename text
} } [
, on: { click: submit } } [
H.span { className: "fa fa-floppy-o" } []
]
]
where
submit _ = do
setIsEditing $ const false
onRename text
fieldCodeEditor :: Record FieldCodeEditorProps -> R.Element
fieldCodeEditor props = R.createElement fieldCodeEditorCpt props []
......
......@@ -15,6 +15,17 @@ import Prelude
import Prim.Row (class Union)
import URI.Query (Query)
data Handed = LeftHanded | RightHanded
derive instance genericHanded :: Generic Handed _
instance eqHanded :: Eq Handed where
eq = genericEq
-------------------------------------------------------------------------
type ID = Int
type Name = String
type Reload = Int
......
......@@ -28,3 +28,8 @@ exports._getSelection = getSelection;
exports._stringify = stringify;
exports._postMessage = postMessage;
exports._setCookie = setCookie;
exports._keyCode = function(e) {
// https://www.w3schools.com/jsref/event_key_keycode.asp
return e.which || e.keyCode;
}
......@@ -112,11 +112,17 @@ menu :: ElemFactory
menu = createDOM "menu"
effToggler :: forall e. R.State Boolean -> EffectFn1 e Unit
effToggler (value /\ setValue) = mkEffectFn1 $ \e -> setValue $ const $ not value
effToggler (value /\ setValue) = mkEffectFn1 $ \_ -> setValue $ const $ not value
unsafeEventValue :: forall event. event -> String
unsafeEventValue e = (unsafeCoerce e).target.value
keyCode :: forall event. event -> Effect Int
keyCode = runEffectFn1 _keyCode
foreign import _keyCode
:: forall e. EffectFn1 e Int
nullRef :: forall t. R.Hooks (R.Ref (Nullable t))
nullRef = R.useRef null
......
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