diff --git a/dist/styles/bootstrap-darkster.css b/dist/styles/bootstrap-darkster.css index adbeb322d6f92c397e07a14b93afb48792a145b7..ab88d77293580a7da4661bd9ed3cca9f1d9ddadf 100644 --- a/dist/styles/bootstrap-darkster.css +++ b/dist/styles/bootstrap-darkster.css @@ -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; } diff --git a/dist/styles/bootstrap-default.css b/dist/styles/bootstrap-default.css index 4e4723cd170730da5bffd30003e9424c211c97db..0c2c96215d92bc8c5f95927f115b768aafb40074 100644 --- a/dist/styles/bootstrap-default.css +++ b/dist/styles/bootstrap-default.css @@ -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; } diff --git a/dist/styles/bootstrap-greyson.css b/dist/styles/bootstrap-greyson.css index 2c9078bd670d1d713ba5417ad05623f0ac754106..03659de9ec9c2145489ca6f008a8ec05fe26b595 100644 --- a/dist/styles/bootstrap-greyson.css +++ b/dist/styles/bootstrap-greyson.css @@ -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; } diff --git a/dist/styles/bootstrap-herbie.css b/dist/styles/bootstrap-herbie.css index fcc15e1dc5ac48fc9c5118422f33209571fbd86e..fa382871c91e968655b230b217eba1b3239c3a92 100644 --- a/dist/styles/bootstrap-herbie.css +++ b/dist/styles/bootstrap-herbie.css @@ -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; } diff --git a/dist/styles/bootstrap-monotony.css b/dist/styles/bootstrap-monotony.css index 5882f49e6d48c021cd03346d8bb5aaa489b133d4..b1d66d77b4077c30944589ac1c53b7f9b16bf5e4 100644 --- a/dist/styles/bootstrap-monotony.css +++ b/dist/styles/bootstrap-monotony.css @@ -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; } diff --git a/src/Gargantext/Components/NgramsTable.purs b/src/Gargantext/Components/NgramsTable.purs index 23184ec75427beb5e18cda54f55144efb1df216d..d628a713430256480f1c816c4271b4be7e89ab3a 100644 --- a/src/Gargantext/Components/NgramsTable.purs +++ b/src/Gargantext/Components/NgramsTable.purs @@ -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 diff --git a/src/Gargantext/Components/NgramsTable/Search.purs b/src/Gargantext/Components/NgramsTable/Search.purs index 6ea9be91743f112447f81b173edd50bb92c79626..159fd730ecd5f4279e8e819c6910ac2c6c75f411 100644 --- a/src/Gargantext/Components/NgramsTable/Search.purs +++ b/src/Gargantext/Components/NgramsTable/Search.purs @@ -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 - diff --git a/src/Gargantext/Components/Nodes/Annuaire/Tabs.purs b/src/Gargantext/Components/Nodes/Annuaire/Tabs.purs index ab78c3efb1b09cf46e8265f2aa0b9fbde225f8de..032bd0b1b49f30ebaa3cb7718c9d727a8ced73ee 100644 --- a/src/Gargantext/Components/Nodes/Annuaire/Tabs.purs +++ b/src/Gargantext/Components/Nodes/Annuaire/Tabs.purs @@ -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) diff --git a/src/Gargantext/Components/Nodes/Lists/Tabs.purs b/src/Gargantext/Components/Nodes/Lists/Tabs.purs index 876cb4399af7b4b367b71127b7dbb49635e605ff..43dcc45e976856a110a4445379159995bd742ea8 100644 --- a/src/Gargantext/Components/Nodes/Lists/Tabs.purs +++ b/src/Gargantext/Components/Nodes/Lists/Tabs.purs @@ -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 ) diff --git a/src/Gargantext/Components/Nodes/Texts.purs b/src/Gargantext/Components/Nodes/Texts.purs index dc2573c155947b437d4fba63683f50ae54f25e3e..fd69ec0b508412195c0d8cd2d85bb69d7e6bfdae 100644 --- a/src/Gargantext/Components/Nodes/Texts.purs +++ b/src/Gargantext/Components/Nodes/Texts.purs @@ -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 } [] diff --git a/src/Gargantext/Components/Renameable.purs b/src/Gargantext/Components/Renameable.purs index e15cbc20f43c73415240830524d98ba0e06642b6..7ce3ec14c47f814bee70df0413c25d275c575f18 100644 --- a/src/Gargantext/Components/Renameable.purs +++ b/src/Gargantext/Components/Renameable.purs @@ -1,8 +1,25 @@ -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 + ] diff --git a/src/Gargantext/Components/Tab.purs b/src/Gargantext/Components/Tab.purs index 8c2957ac9a393e0833db618a96633fd883609355..b4e3d334bc057061710e345c095d03582d2c11bc 100644 --- a/src/Gargantext/Components/Tab.purs +++ b/src/Gargantext/Components/Tab.purs @@ -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 [] - diff --git a/src/Gargantext/Components/Table.purs b/src/Gargantext/Components/Table.purs index 867b65d620880b1fe749bbd3236a59d47cf9c15c..94744e386caa8e27db09210b5efb85e0f891c468 100644 --- a/src/Gargantext/Components/Table.purs +++ b/src/Gargantext/Components/Table.purs @@ -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 diff --git a/src/sass/_legacy/_list.sass b/src/sass/_legacy/_list.sass index 04edfbc76940784a988f86fed06acf0072949fb2..e2963aef1da6bbef3629bf01ef8b91b5a17bab97 100644 --- a/src/sass/_legacy/_list.sass +++ b/src/sass/_legacy/_list.sass @@ -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 diff --git a/src/sass/_legacy/_styles.sass b/src/sass/_legacy/_styles.sass index c8a427fd783d1b203399e054bf2c8974aa6e9a1f..f45b8162b76d9030c6ee61bbb4dbf1f492f463f1 100644 --- a/src/sass/_legacy/_styles.sass +++ b/src/sass/_legacy/_styles.sass @@ -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 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