...
 
Commits (4)
......@@ -8676,10 +8676,6 @@ a:focus, a:hover {
user-select: none;
}
.cache-toggle {
cursor: pointer;
}
.side-panel {
background-color: #fff;
padding: 0.3em;
......@@ -8882,6 +8878,15 @@ select.form-control {
top: 6px;
}
.nodes-lists-layout-tabs .nav.nav-tabs,
.nodes-texts-layout-tabs .nav.nav-tabs,
.nodes-annuaire-layout-tabs .nav.nav-tabs {
margin-left: -32px;
margin-right: -32px;
padding-left: 32px;
padding-right: 32px;
}
.jitsi-iframe {
height: 70em;
}
......@@ -8955,7 +8960,7 @@ select.form-control {
margin-right: 8px;
}
.search-button-prepend .input-group-text {
.ngrams-table-search-button .input-group-text {
width: 41px;
z-index: initial;
}
......@@ -8998,6 +9003,9 @@ select.form-control {
.ngrams-tree-edit-real__actions .b-button {
margin-right: 8px;
}
.ngrams-tree-edit-real .ngrams-tree-loaded-node a:hover {
text-decoration: line-through;
}
.loaded-ngrams-table-header {
text-align: center;
......@@ -9033,6 +9041,60 @@ select.form-control {
margin-left: 13px;
}
.table-header-rename {
margin-bottom: 8px;
}
.table-header-rename__header {
display: flex;
align-items: center;
}
.table-header-rename__header__line {
border-bottom: 1px solid #343A40;
border-top: none;
height: 0;
flex-grow: 1;
margin-left: 32px;
}
.table-header-rename__cache {
margin-top: 16px;
}
.table-header-rename__cache--on {
font-weight: bold;
}
.table-header-rename__cache__button {
margin-left: 16px;
color: #303030;
}
.table-header-rename__cache__text {
cursor: pointer;
}
.table-header-rename__cache__text:focus {
outline: 0;
}
.table-header-rename__calendar__icon {
margin-right: 4px;
width: 16px;
}
.table-header-rename .renameable-wrapper--emphase .renameable-container__text {
font-size: 1.75rem;
font-family: "Comfortaa";
}
.renameable-container {
display: flex;
align-items: baseline;
margin-bottom: 6px;
}
.renameable-container__icon {
margin-right: 4px;
font-size: 14px;
width: 16px;
text-align: center;
}
.renameable-container__button {
margin-left: 16px;
}
.annotation-run {
cursor: pointer;
}
......
......@@ -8629,10 +8629,6 @@ a:focus, a:hover {
user-select: none;
}
.cache-toggle {
cursor: pointer;
}
.side-panel {
background-color: #fff;
padding: 0.3em;
......@@ -8835,6 +8831,15 @@ select.form-control {
top: 6px;
}
.nodes-lists-layout-tabs .nav.nav-tabs,
.nodes-texts-layout-tabs .nav.nav-tabs,
.nodes-annuaire-layout-tabs .nav.nav-tabs {
margin-left: -32px;
margin-right: -32px;
padding-left: 32px;
padding-right: 32px;
}
.jitsi-iframe {
height: 70em;
}
......@@ -8908,7 +8913,7 @@ select.form-control {
margin-right: 8px;
}
.search-button-prepend .input-group-text {
.ngrams-table-search-button .input-group-text {
width: 41px;
z-index: initial;
}
......@@ -8951,6 +8956,9 @@ select.form-control {
.ngrams-tree-edit-real__actions .b-button {
margin-right: 8px;
}
.ngrams-tree-edit-real .ngrams-tree-loaded-node a:hover {
text-decoration: line-through;
}
.loaded-ngrams-table-header {
text-align: center;
......@@ -8985,6 +8993,59 @@ select.form-control {
margin-left: 13px;
}
.table-header-rename {
margin-bottom: 8px;
}
.table-header-rename__header {
display: flex;
align-items: center;
}
.table-header-rename__header__line {
border-bottom: 1px solid #E9ECEF;
border-top: none;
height: 0;
flex-grow: 1;
margin-left: 32px;
}
.table-header-rename__cache {
margin-top: 16px;
}
.table-header-rename__cache--on {
font-weight: bold;
}
.table-header-rename__cache__button {
margin-left: 16px;
color: #007bff;
}
.table-header-rename__cache__text {
cursor: pointer;
}
.table-header-rename__cache__text:focus {
outline: 0;
}
.table-header-rename__calendar__icon {
margin-right: 4px;
width: 16px;
}
.table-header-rename .renameable-wrapper--emphase .renameable-container__text {
font-size: 1.75rem;
}
.renameable-container {
display: flex;
align-items: baseline;
margin-bottom: 6px;
}
.renameable-container__icon {
margin-right: 4px;
font-size: 14px;
width: 16px;
text-align: center;
}
.renameable-container__button {
margin-left: 16px;
}
.annotation-run {
cursor: pointer;
}
......
......@@ -8385,10 +8385,6 @@ a:focus, a:hover {
user-select: none;
}
.cache-toggle {
cursor: pointer;
}
.side-panel {
background-color: #fff;
padding: 0.3em;
......@@ -8591,6 +8587,15 @@ select.form-control {
top: 6px;
}
.nodes-lists-layout-tabs .nav.nav-tabs,
.nodes-texts-layout-tabs .nav.nav-tabs,
.nodes-annuaire-layout-tabs .nav.nav-tabs {
margin-left: -32px;
margin-right: -32px;
padding-left: 32px;
padding-right: 32px;
}
.jitsi-iframe {
height: 70em;
}
......@@ -8664,7 +8669,7 @@ select.form-control {
margin-right: 8px;
}
.search-button-prepend .input-group-text {
.ngrams-table-search-button .input-group-text {
width: 41px;
z-index: initial;
}
......@@ -8707,6 +8712,9 @@ select.form-control {
.ngrams-tree-edit-real__actions .b-button {
margin-right: 8px;
}
.ngrams-tree-edit-real .ngrams-tree-loaded-node a:hover {
text-decoration: line-through;
}
.loaded-ngrams-table-header {
text-align: center;
......@@ -8742,6 +8750,60 @@ select.form-control {
margin-left: 13px;
}
.table-header-rename {
margin-bottom: 8px;
}
.table-header-rename__header {
display: flex;
align-items: center;
}
.table-header-rename__header__line {
border-bottom: 1px solid #E9ECEF;
border-top: none;
height: 0;
flex-grow: 1;
margin-left: 32px;
}
.table-header-rename__cache {
margin-top: 16px;
}
.table-header-rename__cache--on {
font-weight: bold;
}
.table-header-rename__cache__button {
margin-left: 16px;
color: #6f7f8c;
}
.table-header-rename__cache__text {
cursor: pointer;
}
.table-header-rename__cache__text:focus {
outline: 0;
}
.table-header-rename__calendar__icon {
margin-right: 4px;
width: 16px;
}
.table-header-rename .renameable-wrapper--emphase .renameable-container__text {
font-size: 1.75rem;
font-family: "Oswald";
}
.renameable-container {
display: flex;
align-items: baseline;
margin-bottom: 6px;
}
.renameable-container__icon {
margin-right: 4px;
font-size: 14px;
width: 16px;
text-align: center;
}
.renameable-container__button {
margin-left: 16px;
}
.annotation-run {
cursor: pointer;
}
......
......@@ -8633,10 +8633,6 @@ a:focus, a:hover {
user-select: none;
}
.cache-toggle {
cursor: pointer;
}
.side-panel {
background-color: #fff;
padding: 0.3em;
......@@ -8839,6 +8835,15 @@ select.form-control {
top: 6px;
}
.nodes-lists-layout-tabs .nav.nav-tabs,
.nodes-texts-layout-tabs .nav.nav-tabs,
.nodes-annuaire-layout-tabs .nav.nav-tabs {
margin-left: -32px;
margin-right: -32px;
padding-left: 32px;
padding-right: 32px;
}
.jitsi-iframe {
height: 70em;
}
......@@ -8912,7 +8917,7 @@ select.form-control {
margin-right: 8px;
}
.search-button-prepend .input-group-text {
.ngrams-table-search-button .input-group-text {
width: 41px;
z-index: initial;
}
......@@ -8955,6 +8960,9 @@ select.form-control {
.ngrams-tree-edit-real__actions .b-button {
margin-right: 8px;
}
.ngrams-tree-edit-real .ngrams-tree-loaded-node a:hover {
text-decoration: line-through;
}
.loaded-ngrams-table-header {
text-align: center;
......@@ -8990,6 +8998,60 @@ select.form-control {
margin-left: 13px;
}
.table-header-rename {
margin-bottom: 8px;
}
.table-header-rename__header {
display: flex;
align-items: center;
}
.table-header-rename__header__line {
border-bottom: 1px solid #E9ECEF;
border-top: none;
height: 0;
flex-grow: 1;
margin-left: 32px;
}
.table-header-rename__cache {
margin-top: 16px;
}
.table-header-rename__cache--on {
font-weight: bold;
}
.table-header-rename__cache__button {
margin-left: 16px;
color: #F67280;
}
.table-header-rename__cache__text {
cursor: pointer;
}
.table-header-rename__cache__text:focus {
outline: 0;
}
.table-header-rename__calendar__icon {
margin-right: 4px;
width: 16px;
}
.table-header-rename .renameable-wrapper--emphase .renameable-container__text {
font-size: 1.75rem;
font-family: "Crete Round";
}
.renameable-container {
display: flex;
align-items: baseline;
margin-bottom: 6px;
}
.renameable-container__icon {
margin-right: 4px;
font-size: 14px;
width: 16px;
text-align: center;
}
.renameable-container__button {
margin-left: 16px;
}
.annotation-run {
cursor: pointer;
}
......
......@@ -8634,10 +8634,6 @@ a:focus, a:hover {
user-select: none;
}
.cache-toggle {
cursor: pointer;
}
.side-panel {
background-color: #fff;
padding: 0.3em;
......@@ -8840,6 +8836,15 @@ select.form-control {
top: 6px;
}
.nodes-lists-layout-tabs .nav.nav-tabs,
.nodes-texts-layout-tabs .nav.nav-tabs,
.nodes-annuaire-layout-tabs .nav.nav-tabs {
margin-left: -32px;
margin-right: -32px;
padding-left: 32px;
padding-right: 32px;
}
.jitsi-iframe {
height: 70em;
}
......@@ -8913,7 +8918,7 @@ select.form-control {
margin-right: 8px;
}
.search-button-prepend .input-group-text {
.ngrams-table-search-button .input-group-text {
width: 41px;
z-index: initial;
}
......@@ -8956,6 +8961,9 @@ select.form-control {
.ngrams-tree-edit-real__actions .b-button {
margin-right: 8px;
}
.ngrams-tree-edit-real .ngrams-tree-loaded-node a:hover {
text-decoration: line-through;
}
.loaded-ngrams-table-header {
text-align: center;
......@@ -8991,6 +8999,60 @@ select.form-control {
margin-left: 13px;
}
.table-header-rename {
margin-bottom: 8px;
}
.table-header-rename__header {
display: flex;
align-items: center;
}
.table-header-rename__header__line {
border-bottom: 1px solid #E9ECEF;
border-top: none;
height: 0;
flex-grow: 1;
margin-left: 32px;
}
.table-header-rename__cache {
margin-top: 16px;
}
.table-header-rename__cache--on {
font-weight: bold;
}
.table-header-rename__cache__button {
margin-left: 16px;
color: #666666;
}
.table-header-rename__cache__text {
cursor: pointer;
}
.table-header-rename__cache__text:focus {
outline: 0;
}
.table-header-rename__calendar__icon {
margin-right: 4px;
width: 16px;
}
.table-header-rename .renameable-wrapper--emphase .renameable-container__text {
font-size: 1.75rem;
font-family: "Open Sans";
}
.renameable-container {
display: flex;
align-items: baseline;
margin-bottom: 6px;
}
.renameable-container__icon {
margin-right: 4px;
font-size: 14px;
width: 16px;
text-align: center;
}
.renameable-container__button {
margin-left: 16px;
}
.annotation-run {
cursor: pointer;
}
......
......@@ -398,8 +398,8 @@ type Props =
type LoadedNgramsTableHeaderProps =
( searchQuery :: T.Box SearchQuery )
loadedNgramsTableHeader :: R2.Component LoadedNgramsTableHeaderProps
loadedNgramsTableHeader = R.createElement loadedNgramsTableHeaderCpt
loadedNgramsTableHeader :: R2.Leaf LoadedNgramsTableHeaderProps
loadedNgramsTableHeader = R2.leaf loadedNgramsTableHeaderCpt
loadedNgramsTableHeaderCpt :: R.Component LoadedNgramsTableHeaderProps
loadedNgramsTableHeaderCpt = here.component "loadedNgramsTableHeader" cpt where
cpt { searchQuery } _ = pure $
......@@ -740,17 +740,17 @@ mainNgramsTable = R.createElement mainNgramsTableCpt
mainNgramsTableCpt :: R.Component MainNgramsTableProps
mainNgramsTableCpt = here.component "mainNgramsTable" cpt
where
cpt props@{ cacheState, path, session, tabType, treeEdit } _ = do
cpt props@{ cacheState, path, treeEdit } _ = do
searchQuery <- T.useFocused (_.searchQuery) (\a b -> b { searchQuery = a }) path
cacheState' <- T.useLive T.unequal cacheState
onCancelRef <- R.useRef Nothing
onNgramsClickRef <- R.useRef Nothing
onSaveRef <- R.useRef Nothing
-- onCancelRef <- R.useRef Nothing
-- onNgramsClickRef <- R.useRef Nothing
-- onSaveRef <- R.useRef Nothing
state <- T.useBox initialState
ngramsLocalPatch <- T.useFocused (_.ngramsLocalPatch) (\a b -> b { ngramsLocalPatch = a }) state
-- ngramsLocalPatch <- T.useFocused (_.ngramsLocalPatch) (\a b -> b { ngramsLocalPatch = a }) state
nodeId <- T.useFocused (_.nodeId) (\a b -> b { nodeId = a }) path
nodeId' <- T.useLive T.unequal nodeId
-- nodeId <- T.useFocused (_.nodeId) (\a b -> b { nodeId = a }) path
-- nodeId' <- T.useLive T.unequal nodeId
-- let treeEdit = { box: treeEditBox
-- , getNgramsChildren: getNgramsChildrenAff session nodeId' tabType
......@@ -763,17 +763,17 @@ mainNgramsTableCpt = here.component "mainNgramsTable" cpt
case cacheState' of
NT.CacheOn -> pure $ R.fragment
[
loadedNgramsTableHeader { searchQuery } []
, mainNgramsTableCacheOn (Record.merge props { state }) []
[ loadedNgramsTableHeader { searchQuery }
, ngramsTreeEdit (treeEdit)
, mainNgramsTableCacheOn (Record.merge props { state })
]
NT.CacheOff -> pure $ R.fragment
[
loadedNgramsTableHeader { searchQuery } []
, ngramsTreeEdit (treeEdit) []
, mainNgramsTableCacheOff (Record.merge props { state }) []
[loadedNgramsTableHeader { searchQuery }
, ngramsTreeEdit (treeEdit)
, mainNgramsTableCacheOff (Record.merge props { state })
]
type NgramsTreeEditProps =
( box :: T.Box TreeEdit
, getNgramsChildren :: NgramsTerm -> Aff (Array NgramsTerm)
......@@ -783,8 +783,8 @@ type NgramsTreeEditProps =
, onSaveRef :: NgramsActionRef
)
ngramsTreeEdit :: R2.Component NgramsTreeEditProps
ngramsTreeEdit = R.createElement ngramsTreeEditCpt
ngramsTreeEdit :: R2.Leaf NgramsTreeEditProps
ngramsTreeEdit = R2.leaf ngramsTreeEditCpt
ngramsTreeEditCpt :: R.Component NgramsTreeEditProps
ngramsTreeEditCpt = here.component "ngramsTreeEdit" cpt where
cpt props@{ box } _ = do
......@@ -799,15 +799,15 @@ ngramsTreeEditCpt = here.component "ngramsTreeEdit" cpt where
pure $ if isEditingFocused'
then case ngramsParentFocused' of
Nothing -> gutter
Just ngramsParent' -> ngramsTreeEditReal (Record.merge props { ngramsParent' }) []
Just ngramsParent' -> ngramsTreeEditReal (Record.merge props { ngramsParent' })
else gutter
type NgramsTreeEditRealProps =
( ngramsParent' :: NgramsTerm
| NgramsTreeEditProps )
ngramsTreeEditReal :: R2.Component NgramsTreeEditRealProps
ngramsTreeEditReal = R.createElement ngramsTreeEditRealCpt
ngramsTreeEditReal :: R2.Leaf NgramsTreeEditRealProps
ngramsTreeEditReal = R2.leaf ngramsTreeEditRealCpt
ngramsTreeEditRealCpt :: R.Component NgramsTreeEditRealProps
ngramsTreeEditRealCpt = here.component "ngramsTreeEditReal" cpt where
cpt { box
......@@ -922,8 +922,8 @@ type MainNgramsTableCacheProps =
( state :: T.Box State
| MainNgramsTableProps )
mainNgramsTableCacheOn :: R2.Component MainNgramsTableCacheProps
mainNgramsTableCacheOn = R.createElement mainNgramsTableCacheOnCpt
mainNgramsTableCacheOn :: R2.Leaf MainNgramsTableCacheProps
mainNgramsTableCacheOn = R2.leaf mainNgramsTableCacheOnCpt
mainNgramsTableCacheOnCpt :: R.Component MainNgramsTableCacheProps
mainNgramsTableCacheOnCpt = here.component "mainNgramsTableCacheOn" cpt where
cpt { afterSync
......@@ -969,8 +969,8 @@ mainNgramsTableCacheOnCpt = here.component "mainNgramsTableCacheOn" cpt where
handleResponse :: VersionedNgramsTable -> VersionedNgramsTable
handleResponse v = v
mainNgramsTableCacheOff :: R2.Component MainNgramsTableCacheProps
mainNgramsTableCacheOff = R.createElement mainNgramsTableCacheOffCpt
mainNgramsTableCacheOff :: R2.Leaf MainNgramsTableCacheProps
mainNgramsTableCacheOff = R2.leaf mainNgramsTableCacheOffCpt
mainNgramsTableCacheOffCpt :: R.Component MainNgramsTableCacheProps
mainNgramsTableCacheOffCpt = here.component "mainNgramsTableCacheOff" cpt where
cpt { afterSync
......
......@@ -45,42 +45,73 @@ type SearchButtonProps =
searchButton :: R2.Component SearchButtonProps
searchButton = R.createElement searchButtonCpt
searchButtonCpt :: R.Component SearchButtonProps
searchButtonCpt = here.component "searchButton" cpt where
cpt { inputRef, searchQuery } _ = do
-- | States
-- |
searchQuery' <- T.useLive T.unequal searchQuery
-- | Behaviors
-- |
let
onReset _ = do
R2.setInputValue inputRef ""
T.write_ "" searchQuery
onSubmit _ = do
T.write_ (R2.getInputValue inputRef) searchQuery
-- | Render
-- |
pure $
H.div
{ className: "search-button-append input-group-append" }
{ className: intercalate " "
[ "ngrams-table-search-button"
, "input-group-append"
]
}
[
if searchQuery' /= ""
then
R.fragment
[ B.button
[
B.button
{ variant: ButtonVariant Light
, callback: \_ -> do
R2.setInputValue inputRef ""
T.write_ "" searchQuery
, className: "input-group-text" }
[ B.icon
, callback: onReset
, className: "input-group-text"
}
[
B.icon
{ name: "times"
, className: "text-danger"
}
]
, B.button { callback: \_ -> T.write_ (R2.getInputValue inputRef) searchQuery
, className: "input-group-text" }
[ B.icon { name: "search" }
,
B.button
{ variant: ButtonVariant Light
, callback: onSubmit
, className: "input-group-text"
}
[ B.icon
{ name: "search"
, className: "text-secondary"
}
]
]
else
B.button { callback: \_ -> T.write_ (R2.getInputValue inputRef) searchQuery
, className: "input-group-text" }
[ B.icon
{ name: "search" }
]
B.button
{ variant: ButtonVariant Light
, callback: onSubmit
, className: "input-group-text"
}
[ B.icon
{ name: "search"
, className: "text-secondary"
}
]
]
type SearchFieldInputProps =
......@@ -109,4 +140,3 @@ searchFieldInputCpt = here.component "searchFieldInput" cpt where
T.write_ (R2.getInputValue inputRef) searchQuery
else
pure unit
......@@ -68,7 +68,12 @@ tabsCpt = here.component "tabs" cpt where
yearFilter <- T.useBox (Nothing :: Maybe Year)
chartReload <- T.useBox T2.newReload
pure $ Tab.tabs { activeTab, tabs: tabs' yearFilter chartReload props }
pure $
Tab.tabs
{ activeTab
, tabs: tabs' yearFilter chartReload props
, className: "nodes-annuaire-layout-tabs"
}
tabs' yearFilter chartReload props@{ boxes, defaultListId, sidePanel } =
[ "Documents" /\ docs
, "Patents" /\ ngramsView (viewProps Patents)
......
......@@ -45,7 +45,9 @@ tabsCpt :: R.Component ( key :: String | Props )
tabsCpt = here.component "tabs" cpt where
cpt props@{ activeTab } _ = do
pure $ Tab.tabs { activeTab
, tabs: tabs' } where
, tabs: tabs'
, className: "nodes-lists-layout-tabs"
} where
tabs' = [ "Terms" /\ view Terms []
, "Authors" /\ view Authors []
, "Institutes" /\ view Institutes []
......@@ -74,7 +76,7 @@ tabCpt = here.component "tab" cpt where
, listId
, tabType
}
type NgramsViewProps = ( path :: T.Box PageParams | TabProps )
......
......@@ -209,8 +209,10 @@ tabsCpt = here.component "tabs" cpt
chartReload <- T.useBox T2.newReload
pure $ Tab.tabs {
activeTab
pure $
Tab.tabs
{ className: "nodes-texts-layout-tabs"
, activeTab
, tabs: [
"Documents" /\ R.fragment [
histoRender { boxes, path, onClick, onInit, reload: chartReload, session } []
......
module Gargantext.Components.Renameable where
module Gargantext.Components.Renameable
( RenameableProps
, RenameableTextProps
, RenameableOptions
, editingCpt
, here
, notEditing
, notEditingCpt
, renameable
, renameableCpt
, renameableText
, renameableTextCpt
)
where
import Gargantext.Prelude
import Data.Foldable (intercalate)
import Data.Maybe (Maybe(..))
import Effect (Effect)
import Gargantext.Components.Bootstrap as B
import Gargantext.Components.Bootstrap.Types (ButtonVariant(..), Elevation(..), Variant(..))
import Gargantext.Components.InputWithEnter (inputWithEnter)
import Gargantext.Utils.Reactix as R2
import Reactix as R
......@@ -14,100 +31,215 @@ here :: R2.Here
here = R2.here "Gargantext.Components.Renameable"
type RenameableProps =
(
onRename :: String -> Effect Unit
( onRename :: String -> Effect Unit
, text :: String
, icon :: String
| RenameableOptions
)
renameable :: R2.Component RenameableProps
renameable = R.createElement renameableCpt
type RenameableOptions =
( className :: String
, icon :: Maybe String
)
renameableOptions :: Record RenameableOptions
renameableOptions =
{ className : ""
, icon : Nothing
}
renameable :: forall r. R2.OptLeaf RenameableOptions RenameableProps r
renameable = R2.optLeaf renameableCpt renameableOptions
renameableCpt :: R.Component RenameableProps
renameableCpt = here.component "renameableCpt" cpt
where
cpt { onRename, text, icon } _ = do
isEditing <- T.useBox false
state <- T.useBox 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
T.write_ text state
pure $ H.div { className: "renameable" } [
renameableText { isEditing, onRename, state, icon } []
renameableCpt = here.component "renameableCpt" cpt where
cpt { onRename, text, icon, className } _ = do
isEditing <- T.useBox false
state <- T.useBox 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
T.write_ text state
pure $
H.div
{ className: intercalate " "
[ "renameable-wrapper"
, className
]
}
[
renameableText
{ isEditing, onRename, state, icon }
]
----------------------------------------------------------------
type RenameableTextProps =
(
isEditing :: T.Box Boolean
, onRename :: String -> Effect Unit
, state :: T.Box String
, icon :: String
, icon :: Maybe String
)
renameableText :: R2.Component RenameableTextProps
renameableText = R.createElement renameableTextCpt
renameableText :: R2.Leaf RenameableTextProps
renameableText = R2.leaf renameableTextCpt
renameableTextCpt :: R.Component RenameableTextProps
renameableTextCpt = here.component "renameableText" cpt
where
cpt props@{ isEditing } _ = do
isEditing' <- T.useLive T.unequal isEditing
renameableTextCpt = here.component "renameableText" cpt where
cpt props@{ isEditing } _ = do
isEditing' <- T.useLive T.unequal isEditing
pure $
pure $ if isEditing' then
editing props []
else
notEditing props []
if isEditing' then
editing props
else
notEditing props
------------------------------------------------------
notEditing :: R2.Leaf RenameableTextProps
notEditing = R2.leaf notEditingCpt
notEditing :: R2.Component RenameableTextProps
notEditing = R.createElement notEditingCpt
notEditingCpt :: R.Component RenameableTextProps
notEditingCpt = here.component "notEditing" cpt
where
cpt { isEditing, state, icon} _ = do
state' <- T.useLive T.unequal state
pure $ H.div { className: "input-group" }
[ H.span {className: icon} []
, H.text state'
, H.button { className: "btn input-group-append"
, on: { click: \_ -> T.write_ true isEditing } }
[ H.span { className: "fa fa-pencil" } []
notEditingCpt = here.component "notEditing" cpt where
cpt { isEditing, state, icon} _ = do
-- | States
-- |
state' <- T.useLive T.unequal state
-- | Behaviors
-- |
let
onClick _ = T.write_ true isEditing
-- | Render
-- |
pure $
H.div
{ className: intercalate " "
[ "renameable-container"
, "renameable-container--no-editing"
]
]
}
[
R2.fromMaybe icon \icon' ->
B.icon
{ name: icon'
, className: "renameable-container__icon"
}
,
B.span'
{ className: "renameable-container__text" }
state'
,
B.iconButton
{ name: "pencil"
, variant: Dark
, callback: onClick
, elevation: Level1
, className: "renameable-container__button"
}
]
-------------------------------------------------------------------
editing :: R2.Leaf RenameableTextProps
editing = R2.leaf editingCpt
editing :: R2.Component RenameableTextProps
editing = R.createElement editingCpt
editingCpt :: R.Component RenameableTextProps
editingCpt = here.component "editing" cpt
where
cpt { isEditing, onRename, state, icon } _ = do
state' <- T.useLive T.unequal state
pure $ H.div { className: "input-group" }
[ H.span {className: icon} []
, inputWithEnter {
autoFocus: false
, className: "form-control text"
editingCpt = here.component "editing" cpt where
cpt { isEditing, onRename, state, icon } _ = do
-- | States
-- |
state' <- T.useLive T.unequal state
-- | Behaviors
-- |
let
onSubmit text _ = do
T.write_ false isEditing
onRename text
onReset _ = do
T.write_ false isEditing
-- | Render
-- |
pure $
H.div
{ className: intercalate " "
[ "renameable-container"
, "renameable-container--editing"
]
}
[
R2.fromMaybe icon \icon' ->
B.icon
{ name: icon'
, className: "renameable-container__icon"
}
,
H.div
{ className: intercalate " "
[ "renameable-container__input"
, "input-group input-group-sm"
]
}
[
inputWithEnter
{ autoFocus: false
, className: "form-control"
, defaultValue: state'
, onBlur: \s -> T.write_ s state
, onEnter: submit state'
, onEnter: onSubmit state'
, onValueChanged: \s -> T.write_ s state
, placeholder: ""
, type: "text"
}
, H.button { className: "btn input-group-append"
, on: { click: submit state' } }
[ H.span { className: "fa fa-floppy-o" } []
,
-- @TODO make a "reset" CTA
-- H.div
-- { className: "input-group-append" }
-- [
-- B.button
-- { variant: ButtonVariant Light
-- , callback: onReset
-- , className: "input-group-text"
-- }
-- [
-- B.icon
-- { name: "times"
-- , className: "text-danger"
-- }
-- ]
-- ]
-- ,
H.div
{ className: "input-group-append" }
[
B.button
{ variant: ButtonVariant Light
, callback: onSubmit state'
, className: "input-group-text"
}
[
B.icon
{ name: "floppy-o"
, className: "text-primary"
}
]
]
]
where
submit text _ = do
T.write_ false isEditing
onRename text
]
......@@ -14,21 +14,32 @@ import Gargantext.Utils.Reactix as R2
here :: R2.Here
here = R2.here "Gargantext.Components.Tab"
type TabsProps = (
activeTab :: T.Box Int
type TabsProps =
( activeTab :: T.Box Int
, tabs :: Array (Tuple String R.Element)
| TabsOptions
)
tabs :: R2.Leaf TabsProps
tabs = R2.leafComponent tabsCpt
type TabsOptions =
( className :: String
)
tabsOptions :: Record TabsOptions
tabsOptions =
{ className: ""
}
tabs :: forall r. R2.OptLeaf TabsOptions TabsProps r
tabs = R2.optLeaf tabsCpt tabsOptions
-- this is actually just the list of tabs, not the tab contents itself
tabsCpt :: R.Component TabsProps
tabsCpt = here.component "tabs" cpt where
cpt { activeTab
, tabs: tabs' } _ = do
cpt props@{ activeTab
, tabs: tabs'
} _ = do
activeTab' <- T.useLive T.unequal activeTab
pure $ H.div {}
pure $ H.div { className: props.className }
[ H.nav {}
[ H.br {}
, H.div { className: "nav nav-tabs", title: "Search result" }
......@@ -58,4 +69,3 @@ tabCpt = here.component "tab" cpt
same = selected == index
className = "tab-pane" <> (if same then "show active" else "fade")
children' = if same then children else []
......@@ -4,11 +4,14 @@ import Gargantext.Prelude
import Data.Array as A
import Data.Either (Either(..))
import Data.Foldable (intercalate)
import Data.Maybe (Maybe(..))
import Data.Sequence as Seq
import Effect (Effect)
import Effect.Aff (launchAff_)
import Effect.Class (liftEffect)
import Gargantext.Components.Bootstrap as B
import Gargantext.Components.Bootstrap.Types (Elevation(..), Variant(..))
import Gargantext.Components.FolderView as FV
import Gargantext.Components.Forest.Tree.Node.Action.Rename (RenameValue(..), rename)
import Gargantext.Components.Nodes.Corpus (saveCorpus)
......@@ -20,6 +23,7 @@ import Gargantext.Components.Search (SearchType(..))
import Gargantext.Components.Table.Types (ColumnName, OrderBy, OrderByDirection(..), Params, Props, TableContainerProps, columnName)
import Gargantext.Sessions.Types (Session)
import Gargantext.Types (NodeID)
import Gargantext.Utils ((?))
import Gargantext.Utils.Reactix (effectLink)
import Gargantext.Utils.Reactix as R2
import Reactix as R
......@@ -106,42 +110,95 @@ tableHeaderWithRenameBoxedLayoutCpt = here.component "tableHeaderWithRenameBoxed
cacheState' <- T.useLive T.unequal cacheState
CorpusInfo {title, desc, query, authors} <- T.read corpusInfoS
pure $ R.fragment
[ R2.row [FV.backButton {} []]
,
R2.row
[ H.div {className: "col-md-3"} [ H.h3 {} [renameable {icon: "", text: name, onRename: onRenameCorpus} []] ]
, H.div {className: "col-md-9"}
[ H.hr {style: {height: "2px", backgroundColor: "black"}} ]
pure $
H.div
{ className: "table-header-rename" }
[
-- R2.row
-- [
-- FV.backButton {} []
-- ]
-- ,
H.div
{ className: "table-header-rename__header" }
[
renameable
{ text: name
, onRename: onRenameCorpus
, className: "renameable-wrapper--emphase"
}
,
H.hr
{ className: "table-header-rename__header__line" }
]
, R2.row
[ H.div {className: "col-md-8 content"}
[ H.div {}
[
renameable {icon: "fa fa-info", text: title, onRename: onRenameTitle} []
]
, H.div {}
[
H.div
{ className: "col-md-8" }
[
renameable
{ icon: Just "info"
, text: title
, onRename: onRenameTitle
}
,
renameable
{ icon: Just "globe"
, text: desc
, onRename: onRenameDesc
}
,
renameable
{ icon: Just "search-plus"
, text: query
, onRename: onRenameQuery
}
,
H.div
{ className: intercalate " "
[ "table-header-rename__cache"
, cacheState' == NT.CacheOn ?
"table-header-rename__cache--on" $
""
]
}
[
renameable {icon: "fa fa-globe", text: desc, onRename: onRenameDesc} []
]
, H.div {}
[
renameable {icon: "fa fa-search-plus", text: query, onRename: onRenameQuery} []
]
, H.div { className: "cache-toggle"
, on: { click: cacheClick cacheState } }
[ H.span { className: "fa " <> (cacheToggle cacheState') } []
, H.text $ cacheText cacheState'
H.span
{ className: "table-header-rename__cache__text"
, on: { click: cacheClick cacheState }
}
[
H.text $ cacheText cacheState'
]
,
B.iconButton
{ name: cacheToggle cacheState'
, className: "table-header-rename__cache__button"
, variant: Secondary
, elevation: Level1
, callback: cacheClick cacheState
}
]
]
, H.div {className: "col-md-4 content"}
[ H.div {}
,
H.div {className: "col-md-4"}
[
renameable
{ icon: Just "user"
, text: authors
, onRename: onRenameAuthors
}
,
H.div
{ className: "table-header-rename__calendar" }
[
renameable {icon: "fa fa-user", text: authors, onRename: onRenameAuthors} []
]
, H.div {}
[ H.span {className: "fa fa-calendar"} []
, H.text $ " " <> date
B.icon
{ name: "calendar"
, className: "table-header-rename__calendar__icon"
}
,
B.span_ date
]
]
]
......@@ -175,14 +232,13 @@ tableHeaderWithRenameBoxedLayoutCpt = here.component "tableHeaderWithRenameBoxed
save {fields: newFields, session, nodeId}
cacheToggle NT.CacheOn = "fa-toggle-on"
cacheToggle NT.CacheOff = "fa-toggle-off"
cacheToggle NT.CacheOn = "toggle-on"
cacheToggle NT.CacheOff = "toggle-off"
cacheText NT.CacheOn = "Cache On"
cacheText NT.CacheOff = "Cache Off"
cacheClick cacheState _ = do
T.modify cacheStateToggle cacheState
cacheClick cacheState _ = T.modify_ cacheStateToggle cacheState
cacheStateToggle NT.CacheOn = NT.CacheOff
cacheStateToggle NT.CacheOff = NT.CacheOn
......
......@@ -52,7 +52,7 @@
///////////////////////////////////////////////////:
.search-button-prepend
.ngrams-table-search-button
.input-group-text
// @XXX Glyphicon icons lack of homogeneous width
......@@ -104,7 +104,6 @@
margin-top: space-x(2)
margin-bottom: space-x(2)
&__actions
display: flex
margin-top: space-x(2)
......@@ -112,6 +111,9 @@
.b-button
margin-right: space-x(1)
.ngrams-tree-loaded-node a:hover
text-decoration: line-through
//////////////////////////////////////////////////
.loaded-ngrams-table-header
......@@ -154,3 +156,71 @@
$child-offset: 13px
margin-left: 13px
////////////////////////////////////////////////////////
$renameable-icon-margin: space-x(0.5)
$renameable-button-margin: space-x(2)
// @XXX Glyphicon icons lack of homogeneous width
$renameable-icon-width: 16px
.table-header-rename
margin-bottom: space-x(1)
&__header
display: flex
align-items: center
&__line
// (?) This is a peculiar line directly coming from the legacy style
// It originaly was a solid 2px black one, that added to much
// emphasize comparing to the surrounding gray border and lighter
// element (font, icon, etc)
//
// As far as it goes, we kept it for inheritance, but without more
// previous decision on it, we can only make assumption here. Maybe
// the line was intended to bring the page title out, as we can see
// on the likes on some academing print paper
border-bottom: 1px solid $gray-200
border-top: none
// (?) strange behavior where browser engine add it by itself
height: 0
flex-grow: 1
margin-left: space-x(4)
&__cache
margin-top: space-x(2)
&--on
font-weight: bold
&__button
margin-left: $renameable-button-margin
color: $secondary
&__text
@include clickable
&__calendar
&__icon
margin-right: $renameable-icon-margin
width: $renameable-icon-width
.renameable-wrapper--emphase
.renameable-container__text
font-size: $h3-font-size
font-family: $headings-font-family
.renameable-container
display: flex
align-items: baseline
margin-bottom: space-x(0.75)
&__icon
margin-right: $renameable-icon-margin
font-size: 14px
width: $renameable-icon-width
text-align: center
&__button
margin-left: $renameable-button-margin
......@@ -2,9 +2,6 @@
.no-user-select
user-select: none
.cache-toggle
cursor: pointer
.side-panel
background-color: #fff
padding: 0.3em
......@@ -70,6 +67,7 @@
select.form-control
cursor: pointer
#app
width: 100%
......@@ -201,6 +199,20 @@ select.form-control
left: $spinner-left-offset
top: $spinner-top-offset
// @TODO expand <tabs> to fit a ".main-page__main-route" with its padding
// really KISS solution, better prevent the whole padding set (as the
// likes of many pages, such as the Graph Explorer one)
.nodes-lists-layout-tabs,
.nodes-texts-layout-tabs,
.nodes-annuaire-layout-tabs
.nav.nav-tabs
margin-left: -32px
margin-right: -32px
padding-left: 32px
padding-right: 32px
.jitsi-iframe
height: 70em
......