Commit c82a7f6b authored by Przemyslaw Kaminski's avatar Przemyslaw Kaminski

[errors] implement errors view in various places

parent 85f4f9f2
Pipeline #1710 canceled with stage
-- TODO: this module should be replaced by FacetsTable
module Gargantext.Components.DocsTable where
import Gargantext.Prelude
import Prelude
import Control.Monad.Error.Class (throwError)
import DOM.Simple.Console (log2)
import DOM.Simple.Event as DE
import Data.Argonaut (class EncodeJson, jsonEmptyObject, (:=), (~>))
import Data.Array as A
import Data.Either (Either(..))
import Data.Either (Either)
import Data.Generic.Rep (class Generic)
import Data.Lens ((^.))
import Data.Lens.At (at)
......@@ -24,7 +19,7 @@ import Data.String as Str
import Data.Symbol (SProxy(..))
import Data.Tuple (Tuple(..))
import Effect (Effect)
import Effect.Aff (Aff, error, launchAff_)
import Effect.Aff (Aff)
import Effect.Class (liftEffect)
import Gargantext.Components.Category (rating)
import Gargantext.Components.Category.Types (Star(..))
......@@ -36,11 +31,11 @@ import Gargantext.Components.Table.Types as TT
import Gargantext.Config.REST (RESTError)
import Gargantext.Ends (Frontends, url)
import Gargantext.Hooks.Loader (useLoader, useLoaderWithCacheAPI, HashedResponse(..))
import Gargantext.Prelude (class Ord, Unit, bind, const, discard, identity, mempty, otherwise, pure, show, unit, ($), (/=), (<$>), (<<<), (<>), (==))
import Gargantext.Prelude
import Gargantext.Routes (SessionRoute(NodeAPI))
import Gargantext.Routes as Routes
import Gargantext.Sessions (Session, sessionId, get, delete)
import Gargantext.Types (ListId, NodeID, NodeType(..), OrderBy(..), SidePanelState(..), TableResult, TabSubType, TabType, showTabType')
import Gargantext.Types (FrontendError, ListId, NodeID, NodeType(..), OrderBy(..), SidePanelState(..), TabSubType, TabType, TableResult, showTabType')
import Gargantext.Utils (sortWith)
import Gargantext.Utils.CacheAPI as GUC
import Gargantext.Utils.QueryString (joinQueryStrings, mQueryParam, mQueryParamS, queryParam, queryParamS)
......@@ -66,6 +61,7 @@ type Path a =
type CommonProps =
( cacheState :: T.Box NT.CacheState
, errors :: T.Box (Array FrontendError)
, frontends :: Frontends
, listId :: Int
, mCorpusId :: Maybe Int
......@@ -101,7 +97,6 @@ _localCategories = prop (SProxy :: SProxy "localCategories")
docViewLayout :: Record LayoutProps -> R.Element
docViewLayout props = R.createElement docViewLayoutCpt props []
docViewLayoutCpt :: R.Component LayoutProps
docViewLayoutCpt = here.component "docViewLayout" cpt
where
......@@ -118,11 +113,11 @@ type Props = (
docView :: R2.Component Props
docView = R.createElement docViewCpt
docViewCpt :: R.Component Props
docViewCpt = here.component "docView" cpt where
cpt { layout: { cacheState
, chart
, errors
, frontends
, listId
, mCorpusId
......@@ -147,6 +142,7 @@ docViewCpt = here.component "docView" cpt where
, if showSearch then searchBar { query } [] else H.div {} []
, H.div {className: "col-md-12"}
[ pageLayout { cacheState
, errors
, frontends
, key: "docView-" <> (show cacheState')
, listId
......@@ -167,7 +163,6 @@ type SearchBarProps =
searchBar :: R2.Component SearchBarProps
searchBar = R.createElement searchBarCpt
searchBarCpt :: R.Component SearchBarProps
searchBarCpt = here.component "searchBar" cpt
where
......@@ -268,6 +263,7 @@ pageLayout = R.createElement pageLayoutCpt
pageLayoutCpt :: R.Component PageLayoutProps
pageLayoutCpt = here.component "pageLayout" cpt where
cpt props@{ cacheState
, errors
, frontends
, listId
, mCorpusId
......@@ -303,6 +299,7 @@ pageLayoutCpt = here.component "pageLayout" cpt where
case cacheState' of
NT.CacheOn -> do
let paint (Tuple count docs) = page { documents: docs
, errors
, layout: props { totalRecords = count }
, params } []
mkRequest :: PageParams -> GUC.Request
......@@ -310,6 +307,7 @@ pageLayoutCpt = here.component "pageLayout" cpt where
useLoaderWithCacheAPI {
cacheEndpoint: getPageHash session
, errors
, handleResponse
, mkRequest
, path
......@@ -339,13 +337,13 @@ pageLayoutCpt = here.component "pageLayout" cpt where
type PageProps = (
documents :: Array DocumentsView
, layout :: Record PageLayoutProps
, params :: TT.Params
, errors :: T.Box (Array FrontendError)
, layout :: Record PageLayoutProps
, params :: TT.Params
)
page :: R2.Component PageProps
page = R.createElement pageCpt
pageCpt :: R.Component PageProps
pageCpt = here.component "pageCpt" cpt where
cpt { documents, layout, params } _ = do
......@@ -361,7 +359,6 @@ type PagePaintProps = (
pagePaint :: R2.Component PagePaintProps
pagePaint = R.createElement pagePaintCpt
pagePaintCpt :: R.Component PagePaintProps
pagePaintCpt = here.component "pagePaintCpt" cpt
where
......
module Gargantext.Components.ErrorsView where
import Gargantext.Prelude
import Data.Array (deleteAt)
import Data.FunctorWithIndex (mapWithIndex)
import Data.Maybe (Maybe(..))
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
import Gargantext.Types (FrontendError(..))
import Gargantext.Utils.ReactBootstrap as RB
import Gargantext.Utils.Reactix as R2
here :: R2.Here
here = R2.here "Gargantext.Components.ErrorsView"
type ErrorsProps =
( errors :: T.Box (Array FrontendError) )
errorsView :: R2.Component ErrorsProps
errorsView = R.createElement errorsViewCpt
errorsViewCpt :: R.Component ErrorsProps
errorsViewCpt = here.component "errorsView" cpt
where
cpt { errors } _ = do
errors' <- T.useLive T.unequal errors
pure $ H.div {}
( mapWithIndex (showError errors) errors' )
showError errors i (FStringError { error }) =
RB.alert { dismissible: true
, onClose
, variant: "danger" } [ H.text error ]
where
onClose = do
here.log2 "click!" error
T.modify_ (\es -> case deleteAt i es of
Nothing -> es
Just es' -> es'
) errors
showError errors i (FRESTError { error }) =
RB.alert { dismissible: true
, onClose
, variant: "danger" } [ H.text $ show error ]
where
onClose = do
here.log2 "click!" error
T.modify_ (\es -> case deleteAt i es of
Nothing -> es
Just es' -> es'
) errors
This diff is collapsed.
......@@ -14,7 +14,7 @@ import Gargantext.Components.Forest.Tree (treeLoader)
import Gargantext.Ends (Frontends, Backend)
import Gargantext.Routes (AppRoute)
import Gargantext.Sessions (Session(..), Sessions, OpenNodes, unSessions)
import Gargantext.Types (Handed, switchHanded)
import Gargantext.Types (FrontendError, Handed, switchHanded)
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Toestand as T2
import Reactix as R
......@@ -36,6 +36,7 @@ type Common =
type Props =
( backend :: T.Box (Maybe Backend)
, errors :: T.Box (Array FrontendError)
, forestOpen :: T.Box OpenNodes
, reloadForest :: T2.ReloadS
, sessions :: T.Box Sessions
......@@ -53,6 +54,7 @@ forest = R.createElement forestCpt
forestCpt :: R.Component Props
forestCpt = here.component "forest" cpt where
cpt props@{ backend
, errors
, forestOpen
, frontends
, handed
......@@ -81,7 +83,8 @@ forestCpt = here.component "forest" cpt where
common = RX.pick props :: Record Common
trees handed' sessions' = (tree handed') <$> unSessions sessions'
tree handed' s@(Session {treeId}) =
treeLoader { forestOpen
treeLoader { errors
, forestOpen
, frontends
, handed: handed'
, reload: reloadForest
......
This diff is collapsed.
......@@ -10,12 +10,6 @@ import Data.Tuple.Nested ((/\))
import Effect (Effect)
import Effect.Aff (Aff, launchAff)
import Effect.Class (liftEffect)
import React.SyntheticEvent as E
import Reactix as R
import Reactix.DOM.HTML as H
import Record as Record
import Toestand as T
import Gargantext.AsyncTasks as GAT
import Gargantext.Components.Forest.Tree.Node.Action (Action(..))
import Gargantext.Components.Forest.Tree.Node.Action.Upload (DroppedFile(..), fileTypeView)
......@@ -33,19 +27,25 @@ import Gargantext.Ends (Frontends)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Routes as Routes
import Gargantext.Sessions (Session, sessionId)
import Gargantext.Types (Name, ID, reverseHanded)
import Gargantext.Types (FrontendError, ID, Name, reverseHanded)
import Gargantext.Types as GT
import Gargantext.Utils.Popover as Popover
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Toestand as T2
import Gargantext.Version as GV
import React.SyntheticEvent as E
import Reactix as R
import Reactix.DOM.HTML as H
import Record as Record
import Toestand as T
here :: R2.Here
here = R2.here "Gargantext.Components.Forest.Tree.Node"
-- Main Node
type NodeMainSpanProps =
( folderOpen :: T.Box Boolean
( errors :: T.Box (Array FrontendError)
, folderOpen :: T.Box Boolean
, frontends :: Frontends
, id :: ID
, isLeaf :: IsLeaf
......@@ -64,7 +64,6 @@ type IsLeaf = Boolean
nodeSpan :: R2.Component NodeMainSpanProps
nodeSpan = R.createElement nodeSpanCpt
nodeSpanCpt :: R.Component NodeMainSpanProps
nodeSpanCpt = here.component "nodeSpan" cpt
where
......@@ -77,11 +76,11 @@ nodeSpanCpt = here.component "nodeSpan" cpt
nodeMainSpan :: R2.Component NodeMainSpanProps
nodeMainSpan = R.createElement nodeMainSpanCpt
nodeMainSpanCpt :: R.Component NodeMainSpanProps
nodeMainSpanCpt = here.component "nodeMainSpan" cpt
where
cpt props@{ dispatch
, errors
, folderOpen
, frontends
, handed
......@@ -129,10 +128,11 @@ nodeMainSpanCpt = here.component "nodeMainSpan" cpt
, fileTypeView { dispatch, droppedFile, id, isDragOver, nodeType }
, H.div {} (map (\t -> asyncProgressBar { asyncTask: t
, barType: Pie
, nodeId: id
, onFinish: onTaskFinish id t
, session } []
, barType: Pie
, errors
, nodeId: id
, onFinish: onTaskFinish id t
, session } []
) currentTasks'
)
, if nodeType == GT.NodeUser
......@@ -188,7 +188,7 @@ nodeMainSpanCpt = here.component "nodeMainSpan" cpt
name' {name: n, nodeType: nt} = if nt == GT.NodeUser then show session else n
mNodePopupView props'@{ id: i, nodeType: nt, handed: h } opc =
nodePopupView { dispatch, handed: h, id: i, name: name' props'
nodePopupView { dispatch, errors, handed: h, id: i, name: name' props'
, nodeType: nt, onPopoverClose: opc, session }
popOverIcon =
......
module Gargantext.Components.Forest.Tree.Node.Action where
import Data.Generic.Rep (class Generic)
import Data.Eq.Generic (genericEq)
import Data.Maybe (Maybe(..))
import Effect.Aff (Aff)
......
......@@ -2,7 +2,6 @@ module Gargantext.Components.Forest.Tree.Node.Action.Add where
import Gargantext.Prelude
import Control.Monad.Error.Class (throwError)
import Data.Array (head, length)
import Data.Either (Either(..))
import Data.Generic.Rep (class Generic)
......@@ -11,16 +10,7 @@ import Data.Newtype (class Newtype)
import Data.String (Pattern(..), indexOf)
import Data.Tuple.Nested ((/\))
import Effect (Effect)
import Effect.Aff (Aff, error, launchAff_)
import Effect.Class (liftEffect)
import Reactix as R
import Reactix.DOM.HTML as H
import Simple.JSON as JSON
import Toestand as T
import Web.HTML (window)
import Web.HTML.Navigator (userAgent)
import Web.HTML.Window (navigator)
import Effect.Aff (Aff, launchAff_)
import Gargantext.Components.Forest.Tree.Node.Action (Action(..))
import Gargantext.Components.Forest.Tree.Node.Settings (SettingsBox(..), settingsBox)
import Gargantext.Components.Forest.Tree.Node.Tools (formChoiceSafe, panel, submitButton)
......@@ -33,6 +23,13 @@ import Gargantext.Types (NodeType(..), charCodeIcon)
import Gargantext.Types as GT
import Gargantext.Utils (nbsp)
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
import Simple.JSON as JSON
import Toestand as T
import Web.HTML (window)
import Web.HTML.Navigator (userAgent)
import Web.HTML.Window (navigator)
here :: R2.Here
here = R2.here "Gargantext.Components.Forest.Tree.Node.Action.Add"
......@@ -43,12 +40,12 @@ addNode session parentId = post session $ GR.NodeAPI GT.Node (Just parentId) ""
addNodeAsync :: Session
-> GT.ID
-> AddNodeValue
-> Aff GT.AsyncTaskWithType
-> Aff (Either RESTError GT.AsyncTaskWithType)
addNodeAsync session parentId q = do
eTask :: Either RESTError GT.AsyncTask <- post session p q
case eTask of
Left _err -> liftEffect $ throwError $ error "[addNodeAsync] RESTError"
Right task -> pure $ GT.AsyncTaskWithType { task, typ: GT.AddNode }
Left err -> pure $ Left err
Right task -> pure $ Right $ GT.AsyncTaskWithType { task, typ: GT.AddNode }
where
p = GR.NodeAPI GT.Node (Just parentId) (GT.asyncTaskTypePath GT.AddNode)
......
......@@ -2,19 +2,11 @@ module Gargantext.Components.Forest.Tree.Node.Action.Link where
import Gargantext.Prelude
import Control.Monad.Error.Class (throwError)
import Data.Either (Either(..))
import Data.Either (Either)
import Data.Generic.Rep (class Generic)
import Data.Maybe (Maybe(..))
import Data.Show.Generic (genericShow)
import Effect.Aff (Aff)
import Effect.Class (liftEffect)
import Effect.Exception (error)
import Reactix as R
import Reactix.DOM.HTML as H
import Simple.JSON as JSON
import Toestand as T
import Gargantext.Components.Forest.Tree.Node.Action (Action(..))
import Gargantext.Components.Forest.Tree.Node.Tools (submitButton, panel)
import Gargantext.Components.Forest.Tree.Node.Tools.SubTree (subTreeView, SubTreeParamsIn)
......@@ -23,6 +15,10 @@ import Gargantext.Routes (SessionRoute(..))
import Gargantext.Sessions (Session, post)
import Gargantext.Types as GT
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
import Simple.JSON as JSON
import Toestand as T
here :: R2.Here
here = R2.here "Gargantext.Components.Forest.Tree.Node.Action.Link"
......@@ -35,13 +31,11 @@ derive newtype instance JSON.ReadForeign LinkNodeReq
derive newtype instance JSON.WriteForeign LinkNodeReq
linkNodeReq :: Session -> Maybe GT.NodeType -> GT.ID -> GT.ID -> Aff GT.AsyncTaskWithType
linkNodeReq :: Session -> Maybe GT.NodeType -> GT.ID -> GT.ID -> Aff (Either RESTError GT.AsyncTaskWithType)
linkNodeReq session nt fromId toId = do
eTask :: Either RESTError GT.AsyncTask <- post session (NodeAPI GT.Node (Just fromId) "update")
(LinkNodeReq { nodeType: linkNodeType nt, id: toId })
case eTask of
Left _err -> liftEffect $ throwError $ error "[linkNodeReq] RESTError"
Right task -> pure $ GT.AsyncTaskWithType { task, typ: GT.UpdateNode }
pure $ (\task -> GT.AsyncTaskWithType { task, typ: GT.UpdateNode }) <$> eTask
linkNodeType :: Maybe GT.NodeType -> GT.NodeType
linkNodeType (Just GT.Corpus) = GT.Annuaire
......
module Gargantext.Components.Forest.Tree.Node.Action.Search where
import Gargantext.Prelude
import Data.Maybe (Maybe)
import Effect (Effect)
import Effect.Aff (Aff, launchAff)
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
import Gargantext.Prelude
import Gargantext.Components.Forest.Tree.Node.Action (Action(..))
import Gargantext.Components.Forest.Tree.Node.Action.Add (NodePopup)
import Gargantext.Components.Forest.Tree.Node.Action.Search.SearchBar (searchBar)
import Gargantext.Components.Forest.Tree.Node.Action.Search.SearchField (defaultSearch)
import Gargantext.Components.Lang (allLangs)
import Gargantext.Sessions (Session)
import Gargantext.Types (ID)
import Gargantext.Types (FrontendError, ID)
import Gargantext.Types as GT
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
here :: R2.Here
here = R2.here "Gargantext.Components.Forest.Tree.Node.Action.Search"
......@@ -25,6 +24,7 @@ here = R2.here "Gargantext.Components.Forest.Tree.Node.Action.Search"
type Props =
( dispatch :: Action -> Aff Unit
, errors :: T.Box (Array FrontendError)
, id :: Maybe ID
, nodePopup :: Maybe NodePopup
, session :: Session )
......@@ -35,12 +35,13 @@ actionSearch = R.createElement actionSearchCpt
actionSearchCpt :: R.Component Props
actionSearchCpt = here.component "actionSearch" cpt
where
cpt { dispatch, id, nodePopup, session } _ = do
cpt { dispatch, errors, id, nodePopup, session } _ = do
search <- T.useBox $ defaultSearch { node_id = id }
pure $ R.fragment [ H.p { className: "action-search" }
[ H.text $ "Search and create a private "
<> "corpus with the search query as corpus name." ]
, searchBar { langs: allLangs
, searchBar { errors
, langs: allLangs
, onSearch: searchOn dispatch nodePopup
, search
, session
......
......@@ -3,24 +3,25 @@ module Gargantext.Components.Forest.Tree.Node.Action.Search.SearchBar
, searchBar
) where
import Data.Tuple.Nested ((/\))
import Effect (Effect)
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
import Gargantext.Components.Forest.Tree.Node.Action.Search.Types
import Effect (Effect)
import Gargantext.Components.Forest.Tree.Node.Action.Search.SearchField (searchField)
import Gargantext.Components.Forest.Tree.Node.Action.Search.Types -- (Database, SearchQuery(..), defaultSearchQuery, performSearch, Lang(..))
import Gargantext.Components.Lang (Lang)
import Gargantext.Prelude (Unit, pure, ($))
import Gargantext.Sessions (Session)
import Gargantext.Types (FrontendError)
import Gargantext.Types as GT
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
here :: R2.Here
here = R2.here "Gargantext.Components.Forest.Tree.Node.Action.Search.SearchBar"
type Props = ( langs :: Array Lang
type Props = ( errors :: T.Box (Array FrontendError)
, langs :: Array Lang
, onSearch :: GT.AsyncTaskWithType -> Effect Unit
, search :: T.Box Search
, session :: Session
......@@ -28,14 +29,14 @@ type Props = ( langs :: Array Lang
searchBar :: R2.Component Props
searchBar = R.createElement searchBarCpt
searchBarCpt :: R.Component Props
searchBarCpt = here.component "searchBar" cpt
where
cpt { langs, onSearch, search, session } _ = do
cpt { errors, langs, onSearch, search, session } _ = do
--onSearchChange session s
pure $ H.div { className: "search-bar" }
[ searchField { databases:allDatabases
, errors
, langs
, onSearch
, search
......
module Gargantext.Components.Forest.Tree.Node.Action.Search.SearchField where
import Gargantext.Prelude
import DOM.Simple.Console (log, log2)
import Data.Maybe (Maybe(..), maybe, fromMaybe)
import Data.Nullable (null)
import Data.Newtype (over)
import Data.Nullable (null)
import Data.Set as Set
import Data.Tuple.Nested ((/\))
import Effect (Effect)
import Effect.Aff (launchAff_)
import Effect.Class (liftEffect)
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
import Gargantext.Prelude
import Gargantext.Components.Forest.Tree.Node.Action.Search.Frame (searchIframes)
import Gargantext.Components.Forest.Tree.Node.Action.Search.Types (DataField(..), Database(..), IMT_org(..), Org(..), SearchQuery(..), allIMTorgs, allOrgs, dataFields, defaultSearchQuery, doc, performSearch, datafield2database, Search)
import Gargantext.Components.InputWithEnter (inputWithEnter)
import Gargantext.Components.Lang (Lang)
import Gargantext.Config.Utils (handleRESTError)
import Gargantext.Sessions (Session)
import Gargantext.Components.Forest.Tree.Node.Action.Search.Frame (searchIframes)
import Gargantext.Types (FrontendError)
import Gargantext.Types as GT
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
here :: R2.Here
here = R2.here "Gargantext.Components.Forest.Tree.Node.Action.Search.SearchField"
......@@ -38,6 +39,7 @@ defaultSearch = { databases: Empty
type Props =
-- list of databases to search, or parsers to use on uploads
( databases :: Array Database
, errors :: T.Box (Array FrontendError)
, langs :: Array Lang
-- State hook for a search, how we get data in and out
, onSearch :: GT.AsyncTaskWithType -> Effect Unit
......@@ -47,11 +49,10 @@ type Props =
searchField :: R2.Component Props
searchField = R.createElement searchFieldCpt
searchFieldCpt :: R.Component Props
searchFieldCpt = here.component "searchField" cpt
where
cpt props@{ onSearch, search } _ = do
cpt props@{ errors, onSearch, search, session } _ = do
search' <- T.useLive T.unequal search
iframeRef <- R.useRef null
let params =
......@@ -86,7 +87,7 @@ searchFieldCpt = here.component "searchField" cpt
]
]
let button = submitButton {onSearch, search, session: props.session} []
let button = submitButton { errors, onSearch, search, session } []
pure $
......@@ -103,7 +104,6 @@ type ComponentProps =
componentIMT :: R2.Component ComponentProps
componentIMT = R.createElement componentIMTCpt
componentIMTCpt :: R.Component ComponentProps
componentIMTCpt = here.component "componentIMT" cpt
where
......@@ -242,7 +242,6 @@ type LangNavProps =
langNav :: R2.Component LangNavProps
langNav = R.createElement langNavCpt
langNavCpt :: R.Component LangNavProps
langNavCpt = here.component "langNav" cpt
where
......@@ -267,7 +266,6 @@ type DataFieldNavProps =
dataFieldNav :: R2.Component DataFieldNavProps
dataFieldNav = R.createElement dataFieldNavCpt
dataFieldNavCpt :: R.Component DataFieldNavProps
dataFieldNavCpt = here.component "dataFieldNav" cpt
where
......@@ -306,7 +304,6 @@ type DatabaseInputProps = (
databaseInput :: R2.Component DatabaseInputProps
databaseInput = R.createElement databaseInputCpt
databaseInputCpt :: R.Component DatabaseInputProps
databaseInputCpt = here.component "databaseInput" cpt
where
......@@ -347,7 +344,6 @@ type OrgInputProps =
orgInput :: R2.Component OrgInputProps
orgInput = R.createElement orgInputCpt
orgInputCpt :: R.Component OrgInputProps
orgInputCpt = here.component "orgInput" cpt
where
......@@ -390,7 +386,6 @@ type SearchInputProps =
searchInput :: R2.Component SearchInputProps
searchInput = R.createElement searchInputCpt
searchInputCpt :: R.Component SearchInputProps
searchInputCpt = here.component "searchInput" cpt
where
......@@ -429,39 +424,40 @@ searchInputCpt = here.component "searchInput" cpt
-- setSearch $ _ { term = value }
type SubmitButtonProps =
( onSearch :: GT.AsyncTaskWithType -> Effect Unit
( errors :: T.Box (Array FrontendError)
, onSearch :: GT.AsyncTaskWithType -> Effect Unit
, search :: T.Box Search
, session :: Session
)
submitButton :: R2.Component SubmitButtonProps
submitButton = R.createElement submitButtonComponent
submitButtonComponent :: R.Component SubmitButtonProps
submitButtonComponent = here.component "submitButton" cpt
where
cpt { onSearch, search, session } _ = do
cpt { errors, onSearch, search, session } _ = do
search' <- T.useLive T.unequal search
pure $
H.button { className: "btn btn-primary"
, "type" : "button"
, on : { click: doSearch onSearch session search' }
, on : { click: doSearch onSearch errors session search' }
, style : { width: "100%" }
} [ H.text "Launch Search" ]
doSearch os s q = \_ -> do
doSearch os errors s q = \_ -> do
log2 "[submitButton] searching" q
triggerSearch os s q
triggerSearch os errors s q
--case search.term of
-- "" -> setSearch $ const defaultSearch
-- _ -> setSearch $ const q
triggerSearch :: (GT.AsyncTaskWithType -> Effect Unit)
-> T.Box (Array FrontendError)
-> Session
-> Search
-> Effect Unit
triggerSearch os s q =
triggerSearch os errors s q =
launchAff_ $ do
liftEffect $ do
let here' = "[triggerSearch] Searching "
......@@ -473,8 +469,8 @@ triggerSearch os s q =
case q.node_id of
Nothing -> liftEffect $ log "[triggerSearch] node_id is Nothing, don't know what to do"
Just id -> do
task <- performSearch s id $ searchQuery q
liftEffect $ do
eTask <- performSearch s id $ searchQuery q
handleRESTError errors eTask $ \task -> liftEffect $ do
log2 "[triggerSearch] task" task
os task
......
module Gargantext.Components.Forest.Tree.Node.Action.Search.Types where
import Control.Monad.Error.Class (throwError)
import Data.Array (concat)
import Data.Either (Either(..))
import Data.Either (Either)
import Data.Generic.Rep (class Generic)
import Data.Maybe (Maybe(..), fromMaybe, maybe)
import Data.Newtype (class Newtype)
......@@ -11,8 +10,7 @@ import Data.Set as Set
import Data.String as String
import Data.Tuple (Tuple)
import Data.Tuple.Nested ((/\))
import Effect.Aff (Aff, error)
import Effect.Class (liftEffect)
import Effect.Aff (Aff)
import Simple.JSON as JSON
import URI.Extra.QueryPairs as QP
import URI.Query as Q
......@@ -363,18 +361,16 @@ instance GT.ToQuery SearchQuery where
pair k = maybe [] $ \v ->
[ QP.keyFromString k /\ Just (QP.valueFromString $ show v) ]
instance JSON.WriteForeign SearchQuery where
writeImpl (SearchQuery { datafield, databases, lang, node_id, query }) =
writeImpl (SearchQuery { databases, lang, node_id, query }) =
JSON.writeImpl { query: String.replace (String.Pattern "\"") (String.Replacement "\\\"") query
, databases: databases
, lang: maybe "EN" show lang
, node_id: fromMaybe 0 node_id
}
performSearch :: Session -> Int -> SearchQuery -> Aff GT.AsyncTaskWithType
performSearch :: Session -> Int -> SearchQuery -> Aff (Either RESTError GT.AsyncTaskWithType)
performSearch session nodeId q = do
eTask :: Either RESTError GT.AsyncTask <- post session p q
case eTask of
Left _err -> liftEffect $ throwError $ error "[performSearch] RESTError"
Right task -> pure $ GT.AsyncTaskWithType { task, typ: GT.Query }
pure $ (\task -> GT.AsyncTaskWithType { task, typ: GT.Query }) <$> eTask
where
p = GR.NodeAPI GT.Corpus (Just nodeId) $ GT.asyncTaskTypePath GT.Query
module Gargantext.Components.Forest.Tree.Node.Action.Update where
import Control.Monad.Error.Class (throwError)
import Data.Either (Either(..))
import Data.Maybe (Maybe(..))
import Effect.Aff (Aff)
import Effect.Class (liftEffect)
import Effect.Exception (error)
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
......@@ -25,12 +22,12 @@ import Gargantext.Utils.Reactix as R2
here :: R2.Here
here = R2.here "Gargantext.Components.Forest.Tree.Node.Action.Update"