Commit 729f7840 authored by Alexandre Delanoë's avatar Alexandre Delanoë

Merge branch 'dev-doc-table-columns' into dev

parents 88cdabd4 74638ba3
...@@ -22,15 +22,17 @@ import Data.Set (Set) ...@@ -22,15 +22,17 @@ import Data.Set (Set)
import Data.Set as Set import Data.Set as Set
import Data.Int (fromString) import Data.Int (fromString)
import Data.Symbol (SProxy(..)) import Data.Symbol (SProxy(..))
import Data.Tuple (Tuple(..)) import Data.Tuple (Tuple(..), fst)
import Data.Tuple.Nested ((/\)) import Data.Tuple.Nested ((/\))
import DOM.Simple.Event as DE
import Effect (Effect) import Effect (Effect)
import Effect.Aff (Aff, launchAff) import Effect.Aff (Aff, launchAff)
import Effect.Class (liftEffect) import Effect.Class (liftEffect)
import Effect.Uncurried (mkEffectFn1) import Effect.Uncurried (EffectFn1, mkEffectFn1)
import React as React import React as React
import React (ReactClass, ReactElement, Children) import React (ReactClass, ReactElement, Children)
import Reactix as R import Reactix as R
import Reactix.SyntheticEvent as RE
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
import Unsafe.Coerce (unsafeCoerce) import Unsafe.Coerce (unsafeCoerce)
------------------------------------------------------------------------ ------------------------------------------------------------------------
...@@ -76,6 +78,7 @@ type Props = ...@@ -76,6 +78,7 @@ type Props =
, tabType :: TabType , tabType :: TabType
, listId :: Int , listId :: Int
, corpusId :: Maybe Int , corpusId :: Maybe Int
, showSearch :: Boolean
-- ^ tabType is not ideal here since it is too much entangled with tabs and -- ^ tabType is not ideal here since it is too much entangled with tabs and
-- ngramtable. Let's see how this evolves. -- ngramtable. Let's see how this evolves.
} }
...@@ -86,12 +89,11 @@ type PageLoaderProps = ...@@ -86,12 +89,11 @@ type PageLoaderProps =
, tabType :: TabType , tabType :: TabType
, listId :: Int , listId :: Int
, corpusId :: Maybe Int , corpusId :: Maybe Int
, mQuery :: MQuery , query :: Query
} }
type DocumentIdsDeleted = Set Int
type LocalCategories = Map Int Category type LocalCategories = Map Int Category
type MQuery = Maybe String type Query = String
_documentIdsDeleted = prop (SProxy :: SProxy "documentIdsDeleted") _documentIdsDeleted = prop (SProxy :: SProxy "documentIdsDeleted")
_localCategories = prop (SProxy :: SProxy "localCategories") _localCategories = prop (SProxy :: SProxy "localCategories")
...@@ -162,30 +164,23 @@ docViewSpec p = R.createElement el p [] ...@@ -162,30 +164,23 @@ docViewSpec p = R.createElement el p []
where where
el = R.hooksComponent "DocView" cpt el = R.hooksComponent "DocView" cpt
cpt p _children = do cpt p _children = do
documentIdsDeleted <- R.useState' (mempty :: DocumentIdsDeleted) query <- R.useState' ("" :: Query)
localCategories <- R.useState' (mempty :: LocalCategories)
mQuery <- R.useState' (Nothing :: MQuery)
tableParams <- R.useState' T.initialParams tableParams <- R.useState' T.initialParams
pure $ layoutDocview documentIdsDeleted localCategories mQuery tableParams p pure $ layoutDocview query tableParams p
-- | Main layout of the Documents Tab of a Corpus -- | Main layout of the Documents Tab of a Corpus
layoutDocview :: R.State DocumentIdsDeleted -> R.State LocalCategories -> R.State MQuery -> R.State T.Params -> Props -> R.Element layoutDocview :: R.State Query -> R.State T.Params -> Props -> R.Element
layoutDocview documentIdsDeleted@(_ /\ setDocumentIdsDeleted) localCategories (mQuery /\ setMQuery) tableParams@(params /\ _) p = R.createElement el p [] layoutDocview query tableParams@(params /\ _) p = R.createElement el p []
where where
el = R.hooksComponent "LayoutDocView" cpt el = R.hooksComponent "LayoutDocView" cpt
cpt {nodeId, tabType, listId, corpusId, totalRecords, chart} _children = do cpt {nodeId, tabType, listId, corpusId, totalRecords, chart, showSearch} _children = do
pure $ H.div {className: "container1"} pure $ H.div {className: "container1"}
[ H.div {className: "row"} [ H.div {className: "row"}
[ chart [ chart
, H.div {} , if showSearch then searchBar query else H.div {} []
[ H.input { type: "text"
, onChange: onChangeQuery
, placeholder: maybe "" identity mQuery}
]
, H.div {className: "col-md-12"} , H.div {className: "col-md-12"}
[ pageLoader localCategories tableParams {nodeId, totalRecords, tabType, listId, corpusId, mQuery} [ pageLoader tableParams {nodeId, totalRecords, tabType, listId, corpusId, query: fst query} ]
]
, H.div {className: "col-md-1 col-md-offset-11"} , H.div {className: "col-md-1 col-md-offset-11"}
[ H.button { className: "btn" [ H.button { className: "btn"
, style: {backgroundColor: "peru", color : "white", border : "white"} , style: {backgroundColor: "peru", color : "white", border : "white"}
...@@ -197,12 +192,46 @@ layoutDocview documentIdsDeleted@(_ /\ setDocumentIdsDeleted) localCategories (m ...@@ -197,12 +192,46 @@ layoutDocview documentIdsDeleted@(_ /\ setDocumentIdsDeleted) localCategories (m
] ]
] ]
] ]
onChangeQuery = mkEffectFn1 $ \e -> do
setMQuery $ const $ if (unsafeEventValue e) == "" then Nothing else Just $ unsafeEventValue e
onClickTrashAll nodeId = mkEffectFn1 $ \_ -> do onClickTrashAll nodeId = mkEffectFn1 $ \_ -> do
launchAff $ deleteAllDocuments nodeId launchAff $ deleteAllDocuments nodeId
-- TODO
-- setDocumentIdsDeleted $ \dids -> Set.union dids (Set.fromFoldable ids) searchBar :: R.State Query -> R.Element
searchBar (query /\ setQuery) = R.createElement el {} []
where
el = R.hooksComponent "SearchBar" cpt
cpt {} _children = do
queryText <- R.useState' query
pure $ H.div {className: "row"}
[ H.div {className: "col col-md-3 form-group"}
[ H.input { type: "text"
, className: "form-control"
, on: {change: onSearchChange queryText, keyUp: onSearchKeyup queryText}
, placeholder: query}
]
, H.div {className: "col col-md-1"}
[ H.button { type: "submit"
, className: "btn btn-default"
, on: {click: onSearchClick queryText}}
[ H.text "Search" ]
]
]
onSearchChange :: forall e. R.State Query -> e -> Effect Unit
onSearchChange (_ /\ setQueryText) = \e ->
setQueryText $ const $ R2.unsafeEventValue e
onSearchKeyup :: R.State Query -> DE.KeyboardEvent -> Effect Unit
onSearchKeyup (queryText /\ _) = \e ->
if DE.key e == "Enter" then
setQuery $ const queryText
else
pure $ unit
onSearchClick :: forall e. R.State Query -> e -> Effect Unit
onSearchClick (queryText /\ _) = \e ->
setQuery $ const queryText
mock :: Boolean mock :: Boolean
mock = false mock = false
...@@ -211,20 +240,20 @@ type PageParams = { nodeId :: Int ...@@ -211,20 +240,20 @@ type PageParams = { nodeId :: Int
, listId :: Int , listId :: Int
, corpusId :: Maybe Int , corpusId :: Maybe Int
, tabType :: TabType , tabType :: TabType
, mQuery :: Maybe String , query :: Query
, params :: T.Params} , params :: T.Params}
loadPage :: PageParams -> Aff (Array DocumentsView) loadPage :: PageParams -> Aff (Array DocumentsView)
loadPage {nodeId, tabType, mQuery, listId, corpusId, params: {limit, offset, orderBy}} = do loadPage {nodeId, tabType, query, listId, corpusId, params: {limit, offset, orderBy}} = do
logs "loading documents page: loadPage with Offset and limit" logs "loading documents page: loadPage with Offset and limit"
-- res <- get $ toUrl Back (Tab tabType offset limit (convOrderBy <$> orderBy)) (Just nodeId) -- res <- get $ toUrl Back (Tab tabType offset limit (convOrderBy <$> orderBy)) (Just nodeId)
let url = (toUrl Back Node (Just nodeId)) <> "/table" let url = (toUrl Back Node (Just nodeId)) <> "/table"
res <- post url $ TabPostQuery { res <- post url $ TabPostQuery {
offset offset
, limit , limit
, orderBy: convOrderBy <$> orderBy , orderBy: convOrderBy orderBy
, tabType , tabType
, mQuery , query
} }
let docs = res2corpus <$> res let docs = res2corpus <$> res
pure $ pure $
...@@ -241,17 +270,17 @@ loadPage {nodeId, tabType, mQuery, listId, corpusId, params: {limit, offset, ord ...@@ -241,17 +270,17 @@ loadPage {nodeId, tabType, mQuery, listId, corpusId, params: {limit, offset, ord
, category : r.category , category : r.category
, ngramCount : r.ngramCount , ngramCount : r.ngramCount
} }
convOrderBy (T.ASC (T.ColumnName "Date")) = DateAsc convOrderBy (Just (T.ASC (T.ColumnName "Date"))) = DateAsc
convOrderBy (T.DESC (T.ColumnName "Date")) = DateDesc convOrderBy (Just (T.DESC (T.ColumnName "Date"))) = DateDesc
convOrderBy (T.ASC (T.ColumnName "Title")) = TitleAsc convOrderBy (Just (T.ASC (T.ColumnName "Title"))) = TitleAsc
convOrderBy (T.DESC (T.ColumnName "Title")) = TitleDesc convOrderBy (Just (T.DESC (T.ColumnName "Title"))) = TitleDesc
convOrderBy (T.ASC (T.ColumnName "Source")) = SourceAsc convOrderBy (Just (T.ASC (T.ColumnName "Source"))) = SourceAsc
convOrderBy (T.DESC (T.ColumnName "Source")) = SourceDesc convOrderBy (Just (T.DESC (T.ColumnName "Source"))) = SourceDesc
convOrderBy _ = DateAsc -- TODO convOrderBy _ = DateAsc -- TODO
renderPage :: R.State LocalCategories -> R.State T.Params -> PageLoaderProps -> Array DocumentsView -> R.Element renderPage :: R.State T.Params -> PageLoaderProps -> Array DocumentsView -> R.Element
renderPage (localCategories /\ setLocalCategories) (_ /\ setTableParams) p res = R.createElement el p [] renderPage (_ /\ setTableParams) p res = R.createElement el p []
where where
el = R.hooksComponent "RenderPage" cpt el = R.hooksComponent "RenderPage" cpt
...@@ -259,14 +288,15 @@ renderPage (localCategories /\ setLocalCategories) (_ /\ setTableParams) p res = ...@@ -259,14 +288,15 @@ renderPage (localCategories /\ setLocalCategories) (_ /\ setTableParams) p res =
gi _ = "glyphicon glyphicon-star-empty" gi _ = "glyphicon glyphicon-star-empty"
trashStyle Trash = {textDecoration: "line-through"} trashStyle Trash = {textDecoration: "line-through"}
trashStyle _ = {textDecoration: "none"} trashStyle _ = {textDecoration: "none"}
getCategory {_id, category} = maybe category identity (localCategories ^. at _id)
corpusDocument (Just corpusId) = Router.CorpusDocument corpusId corpusDocument (Just corpusId) = Router.CorpusDocument corpusId
corpusDocument _ = Router.Document corpusDocument _ = Router.Document
cpt {nodeId, corpusId, listId} _children = do cpt {nodeId, corpusId, listId} _children = do
localCategories <- R.useState' (mempty :: LocalCategories)
pure $ R2.buff $ T.tableElt pure $ R2.buff $ T.tableElt
{ rows { rows: rows localCategories
-- , setParams: \params -> liftEffect $ loaderDispatch (Loader.SetPath {nodeId, tabType, listId, corpusId, params, mQuery}) -- , setParams: \params -> liftEffect $ loaderDispatch (Loader.SetPath {nodeId, tabType, listId, corpusId, params, query})
, setParams: \params -> setTableParams $ const params , setParams: \params -> setTableParams $ const params
, container: T.defaultContainer { title: "Documents" } , container: T.defaultContainer { title: "Documents" }
, colNames: , colNames:
...@@ -281,19 +311,20 @@ renderPage (localCategories /\ setLocalCategories) (_ /\ setTableParams) p res = ...@@ -281,19 +311,20 @@ renderPage (localCategories /\ setLocalCategories) (_ /\ setTableParams) p res =
, totalRecords: 1000 -- TODO , totalRecords: 1000 -- TODO
} }
where where
rows = (\(DocumentsView r) -> getCategory (localCategories /\ _) {_id, category} = maybe category identity (localCategories ^. at _id)
let cat = getCategory r rows localCategories = (\(DocumentsView r) ->
let cat = getCategory localCategories r
isDel = Trash == cat in isDel = Trash == cat in
{ row: map R2.scuff $ [ { row: map R2.scuff $ [
H.div {} H.div {}
[ H.a { className: gi cat [ H.a { className: gi cat
, style: trashStyle cat , style: trashStyle cat
, onClick: onClick Favorite r._id cat , on: {click: onClick localCategories Favorite r._id cat}
} [] } []
] ]
, H.input { type: "checkbox" , H.input { type: "checkbox"
, checked: isDel , checked: isDel
, onClick: onClick Trash r._id cat , on: {click: onClick localCategories Trash r._id cat}
} }
-- TODO show date: Year-Month-Day only -- TODO show date: Year-Month-Day only
, H.div { style: trashStyle cat } [ H.text (show r.date) ] , H.div { style: trashStyle cat } [ H.text (show r.date) ]
...@@ -305,18 +336,18 @@ renderPage (localCategories /\ setLocalCategories) (_ /\ setTableParams) p res = ...@@ -305,18 +336,18 @@ renderPage (localCategories /\ setLocalCategories) (_ /\ setTableParams) p res =
] ]
, delete: true , delete: true
}) <$> res }) <$> res
onClick catType nid cat = mkEffectFn1 $ \_-> do onClick (_ /\ setLocalCategories) catType nid cat = \_-> do
let newCat = if (catType == Favorite) then (favCategory cat) else (trashCategory cat) let newCat = if (catType == Favorite) then (favCategory cat) else (trashCategory cat)
setLocalCategories $ insert nid newCat setLocalCategories $ insert nid newCat
void $ launchAff $ putCategories nodeId $ CategoryQuery {nodeIds: [nid], category: newCat} void $ launchAff $ putCategories nodeId $ CategoryQuery {nodeIds: [nid], category: newCat}
pageLoader :: R.State LocalCategories -> R.State T.Params -> PageLoaderProps -> R.Element pageLoader :: R.State T.Params -> PageLoaderProps -> R.Element
pageLoader localCategories tableParams@(pageParams /\ _) p = R.createElement el p [] pageLoader tableParams@(pageParams /\ _) p = R.createElement el p []
where where
el = R.hooksComponent "PageLoader" cpt el = R.hooksComponent "PageLoader" cpt
cpt p@{nodeId, listId, corpusId, tabType, mQuery} _children = do cpt p@{nodeId, listId, corpusId, tabType, query} _children = do
useLoader {nodeId, listId, corpusId, tabType, mQuery, params: pageParams} loadPage $ \{loaded} -> useLoader {nodeId, listId, corpusId, tabType, query, params: pageParams} loadPage $ \{loaded} ->
renderPage localCategories tableParams p loaded renderPage tableParams p loaded
--------------------------------------------------------- ---------------------------------------------------------
sampleData' :: DocumentsView sampleData' :: DocumentsView
...@@ -389,6 +420,3 @@ toggleSet :: forall a. Ord a => a -> Set a -> Set a ...@@ -389,6 +420,3 @@ toggleSet :: forall a. Ord a => a -> Set a -> Set a
toggleSet a s toggleSet a s
| Set.member a s = Set.delete a s | Set.member a s = Set.delete a s
| otherwise = Set.insert a s | otherwise = Set.insert a s
unsafeEventValue :: forall event. event -> String
unsafeEventValue e = (unsafeCoerce e).target.value
...@@ -22,6 +22,7 @@ import Gargantext.Config (toUrl, Path(..), End(..)) ...@@ -22,6 +22,7 @@ import Gargantext.Config (toUrl, Path(..), End(..))
import Gargantext.Config.REST (post) import Gargantext.Config.REST (post)
import Gargantext.Components.Modals.Modal (modalHide) import Gargantext.Components.Modals.Modal (modalHide)
import Gargantext.Components.Login.Types import Gargantext.Components.Login.Types
import Gargantext.Utils.Reactix as R2
-- TODO: ask for login (modal) or account creation after 15 mn when user -- TODO: ask for login (modal) or account creation after 15 mn when user
-- is not logged and has made one search at least -- is not logged and has made one search at least
...@@ -128,10 +129,10 @@ renderSpec = simpleSpec performAction render ...@@ -128,10 +129,10 @@ renderSpec = simpleSpec performAction render
, div [className "form-group"] , div [className "form-group"]
[ p [] [text state.errorMessage] [ p [] [text state.errorMessage]
, input [className "form-control", _id "id_username",maxLength "254", name "username", placeholder "username", _type "text",value state.username, onInput \e -> dispatch (SetUserName (unsafeEventValue e))] , input [className "form-control", _id "id_username",maxLength "254", name "username", placeholder "username", _type "text",value state.username, onInput \e -> dispatch (SetUserName $ R2.unsafeEventValue e)]
] ]
, div [className "form-group"] , div [className "form-group"]
[ input [className "form-control", _id "id_password", name "password", placeholder "password", _type "password",value state.password,onInput \e -> dispatch (SetPassword (unsafeEventValue e))] [ input [className "form-control", _id "id_password", name "password", placeholder "password", _type "password",value state.password,onInput \e -> dispatch (SetPassword $ R2.unsafeEventValue e)]
, div [className "clearfix"] [] , div [className "clearfix"] []
] ]
, div [className "center"] , div [className "center"]
...@@ -186,10 +187,6 @@ renderSpec = simpleSpec performAction render ...@@ -186,10 +187,6 @@ renderSpec = simpleSpec performAction render
-- ] -- ]
unsafeEventValue :: forall event. event -> String
unsafeEventValue e = (unsafeCoerce e).target.value
getAuthData :: Effect (Maybe AuthData) getAuthData :: Effect (Maybe AuthData)
getAuthData = do getAuthData = do
w <- window w <- window
......
...@@ -40,6 +40,7 @@ import Gargantext.Components.Table as T ...@@ -40,6 +40,7 @@ import Gargantext.Components.Table as T
import Gargantext.Prelude import Gargantext.Prelude
import Gargantext.Components.Loader as Loader import Gargantext.Components.Loader as Loader
import Gargantext.Components.NgramsTable.Core import Gargantext.Components.NgramsTable.Core
import Gargantext.Utils.Reactix as R2
type State = type State =
CoreState CoreState
...@@ -119,7 +120,7 @@ tableContainer { pageParams ...@@ -119,7 +120,7 @@ tableContainer { pageParams
, name "search", placeholder "Search" , name "search", placeholder "Search"
, _type "value" , _type "value"
, value pageParams.searchQuery , value pageParams.searchQuery
, onInput \e -> setSearchQuery (unsafeEventValue e) , onInput \e -> setSearchQuery (R2.unsafeEventValue e)
] ]
, div [] ( , div [] (
if A.null props.tableBody && pageParams.searchQuery /= "" then [ if A.null props.tableBody && pageParams.searchQuery /= "" then [
...@@ -134,7 +135,7 @@ tableContainer { pageParams ...@@ -134,7 +135,7 @@ tableContainer { pageParams
[ select [ _id "picklistmenu" [ select [ _id "picklistmenu"
, className "form-control custom-select" , className "form-control custom-select"
, value (maybe "" show pageParams.termListFilter) , value (maybe "" show pageParams.termListFilter)
, onChange (\e -> setTermListFilter $ readTermList $ unsafeEventValue e) , onChange (\e -> setTermListFilter $ readTermList $ R2.unsafeEventValue e)
] $ map optps1 termLists ] $ map optps1 termLists
] ]
] ]
...@@ -143,7 +144,7 @@ tableContainer { pageParams ...@@ -143,7 +144,7 @@ tableContainer { pageParams
[ select [ _id "picktermtype" [ select [ _id "picktermtype"
, className "form-control custom-select" , className "form-control custom-select"
, value (maybe "" show pageParams.termSizeFilter) , value (maybe "" show pageParams.termSizeFilter)
, onChange (\e -> setTermSizeFilter $ readTermSize $ unsafeEventValue e) , onChange (\e -> setTermSizeFilter $ readTermSize $ R2.unsafeEventValue e)
] $ map optps1 termSizes ] $ map optps1 termSizes
] ]
] ]
...@@ -420,6 +421,3 @@ optps1 :: forall a. Show a => { desc :: String, mval :: Maybe a } -> ReactElemen ...@@ -420,6 +421,3 @@ optps1 :: forall a. Show a => { desc :: String, mval :: Maybe a } -> ReactElemen
optps1 { desc, mval } = option [value val] [text desc] optps1 { desc, mval } = option [value val] [text desc]
where where
val = maybe "" show mval val = maybe "" show mval
unsafeEventValue :: forall event. event -> String
unsafeEventValue e = (unsafeCoerce e).target.value
...@@ -14,6 +14,7 @@ import Thermite (PerformAction, Render, Spec, modifyState_, simpleSpec, StateCoT ...@@ -14,6 +14,7 @@ import Thermite (PerformAction, Render, Spec, modifyState_, simpleSpec, StateCoT
import Unsafe.Coerce (unsafeCoerce) import Unsafe.Coerce (unsafeCoerce)
import Gargantext.Prelude import Gargantext.Prelude
import Gargantext.Utils.Reactix as R2
type TableContainerProps = type TableContainerProps =
{ pageSizeControl :: ReactElement { pageSizeControl :: ReactElement
...@@ -218,7 +219,7 @@ sizeDD :: PageSizes -> (Action -> Effect Unit) -> ReactElement ...@@ -218,7 +219,7 @@ sizeDD :: PageSizes -> (Action -> Effect Unit) -> ReactElement
sizeDD ps d sizeDD ps d
= span [] = span []
[ select [ className "form-control" [ select [ className "form-control"
, onChange (\e -> d (ChangePageSize $ string2PageSize $ (unsafeCoerce e).target.value)) , onChange (\e -> d (ChangePageSize $ string2PageSize $ R2.unsafeEventValue e))
] $ map (optps ps) aryPS ] $ map (optps ps) aryPS
] ]
......
...@@ -695,6 +695,3 @@ uploadFile id fileType (UploadFileContents fileContents) = postWwwUrlencoded url ...@@ -695,6 +695,3 @@ uploadFile id fileType (UploadFileContents fileContents) = postWwwUrlencoded url
fnTransform :: LNode -> FTree fnTransform :: LNode -> FTree
fnTransform n = NTree n [] fnTransform n = NTree n []
unsafeEventValue :: forall event. event -> String
unsafeEventValue e = (unsafeCoerce e).target.value
...@@ -142,9 +142,9 @@ showTabType' (TabPairing t) = show t ...@@ -142,9 +142,9 @@ showTabType' (TabPairing t) = show t
data TabPostQuery = TabPostQuery { data TabPostQuery = TabPostQuery {
offset :: Int offset :: Int
, limit :: Int , limit :: Int
, orderBy :: Maybe OrderBy , orderBy :: OrderBy
, tabType :: TabType , tabType :: TabType
, mQuery :: Maybe String , query :: String
} }
instance encodeJsonTabPostQuery :: EncodeJson TabPostQuery where instance encodeJsonTabPostQuery :: EncodeJson TabPostQuery where
...@@ -153,7 +153,7 @@ instance encodeJsonTabPostQuery :: EncodeJson TabPostQuery where ...@@ -153,7 +153,7 @@ instance encodeJsonTabPostQuery :: EncodeJson TabPostQuery where
~> "offset" := post.offset ~> "offset" := post.offset
~> "limit" := post.limit ~> "limit" := post.limit
~> "orderBy" := show post.orderBy ~> "orderBy" := show post.orderBy
~> "query" := post.mQuery ~> "query" := post.query
~> jsonEmptyObject ~> jsonEmptyObject
pathUrl :: Config -> Path -> Maybe Id -> UrlPath pathUrl :: Config -> Path -> Maybe Id -> UrlPath
......
...@@ -78,7 +78,9 @@ statefulTabs = ...@@ -78,7 +78,9 @@ statefulTabs =
, tabType: TabPairing TabDocs , tabType: TabPairing TabDocs
, totalRecords: 4736 , totalRecords: 4736
, listId: defaultListId , listId: defaultListId
, corpusId: Nothing} , corpusId: Nothing
, showSearch: true
}
ngramsViewSpec :: {mode :: Mode} -> Spec Tab.State Props Tab.Action ngramsViewSpec :: {mode :: Mode} -> Spec Tab.State Props Tab.Action
ngramsViewSpec {mode} = ngramsViewSpec {mode} =
......
...@@ -419,7 +419,7 @@ specOld = fold [treespec treeSpec, graphspec $ simpleSpec performAction render'] ...@@ -419,7 +419,7 @@ specOld = fold [treespec treeSpec, graphspec $ simpleSpec performAction render']
Nothing -> Nothing ->
simpleSpec defaultPerformAction defaultRender simpleSpec defaultPerformAction defaultRender
Just treeId -> Just treeId ->
(cmapProps (const {root: treeId, mCurrentRoute: Nothing}) (noState Tree.treeview)) cmapProps (const {root: treeId, mCurrentRoute: Nothing}) $ noState $ Tree.treeview
render' :: Render State {} Action render' :: Render State {} Action
......
...@@ -5,8 +5,10 @@ import Data.Lens (over) ...@@ -5,8 +5,10 @@ import Data.Lens (over)
import Data.Maybe (Maybe(Nothing, Just)) import Data.Maybe (Maybe(Nothing, Just))
import Effect (Effect) import Effect (Effect)
import React (ReactElement) import React (ReactElement)
import React.DOM (a, button, div, footer, hr', img, li, p, span, text, ul) import React.DOM (button, div, text)
import React.DOM.Props (_data, _id, aria, className, href, onClick, role, src, style, tabIndex, target, title, height, width) import React.DOM.Props (_id, className, onClick, role, style)
import Reactix as R
import Reactix.DOM.HTML as H
import Thermite (Render, Spec, _render, defaultPerformAction, defaultRender, focus, simpleSpec, withState, noState, cmapProps) import Thermite (Render, Spec, _render, defaultPerformAction, defaultRender, focus, simpleSpec, withState, noState, cmapProps)
-- import Unsafe.Coerce (unsafeCoerce) -- import Unsafe.Coerce (unsafeCoerce)
...@@ -31,7 +33,7 @@ import Gargantext.Pages.Layout.Specs.Search as S ...@@ -31,7 +33,7 @@ import Gargantext.Pages.Layout.Specs.Search as S
import Gargantext.Pages.Layout.Specs.SearchBar as SB import Gargantext.Pages.Layout.Specs.SearchBar as SB
import Gargantext.Pages.Layout.States (AppState, _addCorpusState, _graphExplorerState, _loginState, _searchState) import Gargantext.Pages.Layout.States (AppState, _addCorpusState, _graphExplorerState, _loginState, _searchState)
import Gargantext.Router (Routes(..)) import Gargantext.Router (Routes(..))
import Gargantext.Utils.Reactix (scuff) import Gargantext.Utils.Reactix as R2
layoutSpec :: Spec AppState {} Action layoutSpec :: Spec AppState {} Action
layoutSpec = layoutSpec =
...@@ -83,7 +85,7 @@ layout0 layout = ...@@ -83,7 +85,7 @@ layout0 layout =
fold fold
[ searchBar [ searchBar
, outerLayout , outerLayout
, layoutFooter , noState layoutFooter
] ]
where where
outerLayout1 = simpleSpec defaultPerformAction defaultRender outerLayout1 = simpleSpec defaultPerformAction defaultRender
...@@ -94,7 +96,7 @@ layout0 layout = ...@@ -94,7 +96,7 @@ layout0 layout =
withState \st -> withState \st ->
case st.loginState.authData of case st.loginState.authData of
Just (AuthData {tree_id}) -> Just (AuthData {tree_id}) ->
ls $ cmapProps (const {root: tree_id, mCurrentRoute: st.currentRoute}) as ls $ cmapProps (const {root: tree_id, mCurrentRoute: st.currentRoute}) $ noState $ Tree.treeview
Nothing -> Nothing ->
outerLayout1 outerLayout1
, rs bs , rs bs
...@@ -111,8 +113,6 @@ layout0 layout = ...@@ -111,8 +113,6 @@ layout0 layout =
] (render d p s c) ] ] (render d p s c) ]
cont = over _render \render d p s c -> [ div [className "row" ] (render d p s c) ] cont = over _render \render d p s c -> [ div [className "row" ] (render d p s c) ]
as = noState Tree.treeview
bs = innerLayout $ layout bs = innerLayout $ layout
innerLayout :: Spec AppState {} Action innerLayout :: Spec AppState {} Action
...@@ -132,7 +132,7 @@ layout1 layout = ...@@ -132,7 +132,7 @@ layout1 layout =
[ searchBar [ searchBar
, layout , layout
-- , outerLayout -- , outerLayout
, layoutFooter , noState layoutFooter
] ]
where where
outerLayout1 = simpleSpec defaultPerformAction defaultRender outerLayout1 = simpleSpec defaultPerformAction defaultRender
...@@ -142,7 +142,7 @@ layout1 layout = ...@@ -142,7 +142,7 @@ layout1 layout =
[ withState \st -> [ withState \st ->
case st.loginState.authData of case st.loginState.authData of
Just (AuthData {tree_id}) -> Just (AuthData {tree_id}) ->
ls $ cmapProps (const {root: tree_id, mCurrentRoute: st.currentRoute}) as ls $ cmapProps (const {root: tree_id, mCurrentRoute: st.currentRoute}) $ noState $ Tree.treeview
Nothing -> Nothing ->
outerLayout1 outerLayout1
, rs bs , rs bs
...@@ -156,8 +156,6 @@ layout1 layout = ...@@ -156,8 +156,6 @@ layout1 layout =
rs = over _render \render d p s c -> [ div [if (s.showTree) then className "col-md-10" else className "col-md-12"] (render d p s c) ] rs = over _render \render d p s c -> [ div [if (s.showTree) then className "col-md-10" else className "col-md-12"] (render d p s c) ]
cont = over _render \render d p s c -> [ div [className "row" ] (render d p s c) ] cont = over _render \render d p s c -> [ div [className "row" ] (render d p s c) ]
as = noState Tree.treeview
bs = innerLayout $ layout bs = innerLayout $ layout
innerLayout :: Spec AppState {} Action innerLayout :: Spec AppState {} Action
...@@ -180,29 +178,29 @@ searchBar = simpleSpec defaultPerformAction render ...@@ -180,29 +178,29 @@ searchBar = simpleSpec defaultPerformAction render
] [ div [className "container-fluid" ] [ div [className "container-fluid"
] ]
[ div [ className "navbar-inner" ] [ div [ className "navbar-inner" ]
[ divLogo [ R2.scuff divLogo
, div [ className "collapse navbar-collapse" , div [ className "collapse navbar-collapse"
] ]
$ [ divDropdownLeft ] $ [ R2.scuff divDropdownLeft ]
<> [ scuff (SB.searchBar SB.defaultProps) ] <> [ R2.scuff (SB.searchBar SB.defaultProps) ]
<> [ divDropdownRight d s ] <> [ R2.scuff $ divDropdownRight d s ]
] ]
] ]
] ]
] ]
divLogo :: ReactElement divLogo :: R.Element
divLogo = a [ className "navbar-brand logoSmall" divLogo = H.a { className: "navbar-brand logoSmall"
, href "#/" , href: "#/"
] [ img [ src "images/logoSmall.png" } [ H.img { src: "images/logoSmall.png"
, title "Back to home." , title: "Back to home."
, width "30" , width: "30"
, height "28" , height: "28"
] }
] ]
divDropdownLeft :: ReactElement divDropdownLeft :: R.Element
divDropdownLeft = divDropdownLeft' (LiNav { title : "About Gargantext" divDropdownLeft = divDropdownLeft' (LiNav { title : "About Gargantext"
, href : "#" , href : "#"
, icon : "glyphicon glyphicon-info-sign" , icon : "glyphicon glyphicon-info-sign"
...@@ -210,32 +208,33 @@ divDropdownLeft = divDropdownLeft' (LiNav { title : "About Gargantext" ...@@ -210,32 +208,33 @@ divDropdownLeft = divDropdownLeft' (LiNav { title : "About Gargantext"
} }
) )
divDropdownLeft' :: LiNav -> ReactElement divDropdownLeft' :: LiNav -> R.Element
divDropdownLeft' mb = ul [className "nav navbar-nav"] divDropdownLeft' mb = H.ul {className: "nav navbar-nav"}
[ ul [className "nav navbar-nav pull-left"] [ H.ul {className: "nav navbar-nav pull-left"}
[ li [className "dropdown"] [ H.li {className: "dropdown"}
[ menuButton mb [ menuButton mb
, menuElements' , menuElements'
] ]
] ]
] ]
menuButton :: LiNav -> ReactElement menuButton :: LiNav -> R.Element
menuButton (LiNav { title : title' menuButton (LiNav { title : title'
, href : href' , href : href'
, icon : icon' , icon : icon'
, text : text' , text : text'
}) = a [ className "dropdown-toggle navbar-text" }) = H.a { className: "dropdown-toggle navbar-text"
, _data {toggle: "dropdown"} , data: {toggle: "dropdown"}
, href href', role "button" , href: href'
, title title' , role: "button"
][ span [ aria {hidden : true} , title: title'
, className icon' } [ H.span { aria: {hidden : true}
] [] , className: icon'
, text (" " <> text') } []
] , H.text (" " <> text')
]
menuElements' :: ReactElement
menuElements' :: R.Element
menuElements' = menuElements-- title, icon, text menuElements' = menuElements-- title, icon, text
[ -- =========================================================== [ -- ===========================================================
[ LiNav { title : "Quick start, tutorials and methodology" [ LiNav { title : "Quick start, tutorials and methodology"
...@@ -271,14 +270,14 @@ menuElements' = menuElements-- title, icon, text ...@@ -271,14 +270,14 @@ menuElements' = menuElements-- title, icon, text
] -- =========================================================== ] -- ===========================================================
-- | Menu in the sidebar, syntactic sugar -- | Menu in the sidebar, syntactic sugar
menuElements :: Array (Array LiNav) -> ReactElement menuElements :: Array (Array LiNav) -> R.Element
menuElements ns = dropDown $ intercalate divider $ map (map liNav) ns menuElements ns = dropDown $ intercalate divider $ map (map liNav) ns
where where
dropDown :: Array ReactElement -> ReactElement dropDown :: Array R.Element -> R.Element
dropDown = ul [className "dropdown-menu"] dropDown = H.ul {className: "dropdown-menu"}
divider :: Array ReactElement divider :: Array R.Element
divider = [li [className "divider"] []] divider = [H.li {className: "divider"} []]
-- | surgar for target : "blank" -- | surgar for target : "blank"
--data LiNav_ = LiNav_ { title :: String --data LiNav_ = LiNav_ { title :: String
...@@ -294,77 +293,78 @@ data LiNav = LiNav { title :: String ...@@ -294,77 +293,78 @@ data LiNav = LiNav { title :: String
, text :: String , text :: String
} }
liNav :: LiNav -> ReactElement liNav :: LiNav -> R.Element
liNav (LiNav { title : title' liNav (LiNav { title : title'
, href : href' , href : href'
, icon : icon' , icon : icon'
, text : text' , text : text'
} }
) = li [] [ a [ tabIndex (-1) ) = H.li {} [ H.a { tabIndex: (-1)
, target "blank" , target: "blank"
, title title' , title: title'
, href href' , href: href'
] [ span [ className icon' ] [] } [ H.span { className: icon' } []
, text $ " " <> text' , H.text $ " " <> text'
] ]
] ]
logLinks :: (Action -> Effect Unit) -> AppState -> ReactElement logLinks :: (Action -> Effect Unit) -> AppState -> R.Element
logLinks d s = case s.loginState.authData of logLinks d s = case s.loginState.authData of
Nothing -> loginLink Nothing -> loginLink
Just _ -> logoutLink Just _ -> logoutLink
where where
loginLink = loginLink =
a [ aria {hidden : true} H.a { aria: {hidden : true}
, className "glyphicon glyphicon-log-in" , className: "glyphicon glyphicon-log-in"
, onClick $ \e -> d ShowLogin , on: {click: \e -> d ShowLogin}
, style {color:"white"} , style: {color:"white"}
, title "Log in and save your time" , title: "Log in and save your time"
-- TODO hover: bold -- TODO hover: bold
] }
[text " Login / Signup"] [H.text " Login / Signup"]
-- TODO dropdown to logout -- TODO dropdown to logout
logoutLink = logoutLink =
a [ aria {hidden : true} H.a { aria: {hidden : true}
, className "glyphicon glyphicon-log-out" , className: "glyphicon glyphicon-log-out"
, onClick $ \e -> d Logout , on: {click: \e -> d Logout}
, style {color:"white"} , style: {color:"white"}
, title "Log out" -- TODO , title: "Log out" -- TODO
-- TODO hover: bold -- TODO hover: bold
] }
[text " Logout"] [H.text " Logout"]
divDropdownRight :: (Action -> Effect Unit) -> AppState -> ReactElement divDropdownRight :: (Action -> Effect Unit) -> AppState -> R.Element
divDropdownRight d s = divDropdownRight d s =
ul [className "nav navbar-nav pull-right"] H.ul {className: "nav navbar-nav pull-right"}
[ li [className "dropdown"] [ H.li {className: "dropdown"}
[ logLinks d s ] [ logLinks d s ]
] ]
layoutFooter :: Spec AppState {} Action layoutFooter :: Spec {} {} Void
layoutFooter = simpleSpec performAction render layoutFooter = R2.elSpec $ R.hooksComponent "LayoutFooter" cpt
where where
render :: Render AppState {} Action cpt {} _children = do
render dispatch _ state _ = [div [ className "container" ] [ hr', footerLegalInfo']] pure $ H.div { className: "container" } [ H.hr {}, footerLegalInfo']
where
footerLegalInfo' = footer [] [ p [] [ text "Gargantext " footerLegalInfo' = H.footer {}
, span [className "glyphicon glyphicon-registration-mark" ] [] [ H.p {} [ H.text "Gargantext "
, text ", version 4.0" , H.span {className: "glyphicon glyphicon-registration-mark"} []
, a [ href "http://www.cnrs.fr" , H.text ", version 4.0"
, target "blank" , H.a { href: "http://www.cnrs.fr"
, title "Project hosted by CNRS." , target: "blank"
] , title: "Project hosted by CNRS."
[ text ", Copyrights " }
, span [ className "glyphicon glyphicon-copyright-mark" ] [] [ H.text ", Copyrights "
, text " CNRS 2017-Present" , H.span { className: "glyphicon glyphicon-copyright-mark" } []
] , H.text " CNRS 2017-Present"
, a [ href "http://gitlab.iscpif.fr/humanities/gargantext/blob/stable/LICENSE" ]
, target "blank" , H.a { href: "http://gitlab.iscpif.fr/humanities/gargantext/blob/stable/LICENSE"
, title "Legal instructions of the project." , target: "blank"
] , title: "Legal instructions of the project."
[ text ", Licences aGPLV3 and CECILL variant Affero compliant" ] }
, text "." [ H.text ", Licences aGPLV3 and CECILL variant Affero compliant" ]
] , H.text "."
] ]
]
...@@ -7,7 +7,8 @@ import React.DOM (br', button, div, input, text) ...@@ -7,7 +7,8 @@ import React.DOM (br', button, div, input, text)
import React.DOM.Props (_id, _type, className, name, onClick, onInput, placeholder, value) import React.DOM.Props (_id, _type, className, name, onClick, onInput, placeholder, value)
import Routing.Hash (setHash) import Routing.Hash (setHash)
import Thermite (PerformAction, Render, Spec, modifyState, simpleSpec) import Thermite (PerformAction, Render, Spec, modifyState, simpleSpec)
import Unsafe.Coerce (unsafeCoerce)
import Gargantext.Utils.Reactix as R2
type State = type State =
{ {
...@@ -26,20 +27,16 @@ data Action ...@@ -26,20 +27,16 @@ data Action
= GO = GO
| SetQuery String | SetQuery String
performAction :: PerformAction State {} Action
performAction (SetQuery q) _ _ = void do
modifyState $ _ { query = q }
unsafeEventValue :: forall event. event -> String performAction GO _ _ = void do
unsafeEventValue e = (unsafeCoerce e).target.value liftEffect $ setHash "/addCorpus"
searchSpec :: Spec State {} Action searchSpec :: Spec State {} Action
searchSpec = simpleSpec performAction render searchSpec = simpleSpec performAction render
where where
performAction :: PerformAction State {} Action
performAction (SetQuery q) _ _ = void do
modifyState $ _ { query = q }
performAction GO _ _ = void do
liftEffect $ setHash "/addCorpus"
render :: Render State {} Action render :: Render State {} Action
render dispatch _ state _ = render dispatch _ state _ =
[ div [className "container1"] [] [ div [className "container1"] []
...@@ -56,7 +53,7 @@ searchSpec = simpleSpec performAction render ...@@ -56,7 +53,7 @@ searchSpec = simpleSpec performAction render
, placeholder "Query, URL or FILE (works best with Firefox or Chromium browsers)" , placeholder "Query, URL or FILE (works best with Firefox or Chromium browsers)"
, _type "text" , _type "text"
, value state.query , value state.query
, onInput \e -> dispatch (SetQuery (unsafeEventValue e)) , onInput \e -> dispatch (SetQuery (R2.unsafeEventValue e))
] ]
, br' , br'
] ]
......
...@@ -89,6 +89,7 @@ docViewSpec tst = R2.elSpec $ R.hooksComponent "DocViewSpecWithCorpus" cpt ...@@ -89,6 +89,7 @@ docViewSpec tst = R2.elSpec $ R.hooksComponent "DocViewSpecWithCorpus" cpt
, totalRecords: 4737 , totalRecords: 4737
, listId: defaultListId , listId: defaultListId
, corpusId: Just corpusId , corpusId: Just corpusId
, showSearch: true
} }
params TabMoreLikeFav = { params TabMoreLikeFav = {
nodeId: corpusId nodeId: corpusId
...@@ -98,6 +99,7 @@ docViewSpec tst = R2.elSpec $ R.hooksComponent "DocViewSpecWithCorpus" cpt ...@@ -98,6 +99,7 @@ docViewSpec tst = R2.elSpec $ R.hooksComponent "DocViewSpecWithCorpus" cpt
, totalRecords: 4737 , totalRecords: 4737
, listId: defaultListId , listId: defaultListId
, corpusId: Just corpusId , corpusId: Just corpusId
, showSearch: false
} }
params TabMoreLikeTrash = { params TabMoreLikeTrash = {
nodeId: corpusId nodeId: corpusId
...@@ -107,6 +109,7 @@ docViewSpec tst = R2.elSpec $ R.hooksComponent "DocViewSpecWithCorpus" cpt ...@@ -107,6 +109,7 @@ docViewSpec tst = R2.elSpec $ R.hooksComponent "DocViewSpecWithCorpus" cpt
, totalRecords: 4737 , totalRecords: 4737
, listId: defaultListId , listId: defaultListId
, corpusId: Just corpusId , corpusId: Just corpusId
, showSearch: false
} }
params TabTrash = { params TabTrash = {
nodeId: corpusId nodeId: corpusId
...@@ -116,6 +119,7 @@ docViewSpec tst = R2.elSpec $ R.hooksComponent "DocViewSpecWithCorpus" cpt ...@@ -116,6 +119,7 @@ docViewSpec tst = R2.elSpec $ R.hooksComponent "DocViewSpecWithCorpus" cpt
, totalRecords: 4737 , totalRecords: 4737
, listId: defaultListId , listId: defaultListId
, corpusId: Nothing , corpusId: Nothing
, showSearch: true
} }
-- DUMMY -- DUMMY
params _ = { params _ = {
...@@ -126,4 +130,5 @@ docViewSpec tst = R2.elSpec $ R.hooksComponent "DocViewSpecWithCorpus" cpt ...@@ -126,4 +130,5 @@ docViewSpec tst = R2.elSpec $ R.hooksComponent "DocViewSpecWithCorpus" cpt
, totalRecords: 4737 , totalRecords: 4737
, listId: defaultListId , listId: defaultListId
, corpusId: Nothing , corpusId: Nothing
, showSearch: true
} }
...@@ -89,3 +89,7 @@ select = createDOMElement "select" ...@@ -89,3 +89,7 @@ select = createDOMElement "select"
effToggler :: forall e. R.State Boolean -> EffectFn1 e Unit effToggler :: forall e. R.State Boolean -> EffectFn1 e Unit
effToggler (value /\ setValue) = mkEffectFn1 $ \e -> setValue $ const $ not value effToggler (value /\ setValue) = mkEffectFn1 $ \e -> setValue $ const $ not value
unsafeEventValue :: forall event. event -> String
unsafeEventValue e = (unsafeCoerce e).target.value
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