[team share] autofocus on username, fixes to errors

parent 3ce1b08e
Pipeline #5469 failed with stage
in 0 seconds
......@@ -325,7 +325,7 @@ renameNode name p@{ boxes: { errors }, session, tree: (NTree (LNode {id}) _) } =
handleRESTError here errors eTask $ \_task -> pure unit
refreshTree p
shareTeam username { boxes: { errors }, session, tree: (NTree (LNode {id}) _)} = do
shareTeam username { boxes: { errors }, session, tree: (NTree (LNode {id}) _) } = do
eTask <- Share.shareReq session id $ Share.ShareTeamParams { username }
handleRESTError here errors eTask $ \_task -> pure unit
......
......@@ -73,7 +73,7 @@ shareNodeCpt = here.component "shareNode" cpt
useLoader {
loader: getCompletionsReq
, path: { session }
, render: \completions -> shareNodeInner {completions, dispatch} []
, render: \completions -> shareNodeInner { completions, dispatch } []
, errorHandler
}
where
......@@ -94,15 +94,16 @@ shareNodeInnerCpt = here.component "shareNodeInner" cpt
text' /\ text <- R2.useBox' ""
pure $ Tools.panel
[ inputWithAutocomplete { autocompleteSearch
[ inputWithAutocomplete { autoFocus: true
, autocompleteSearch
, classes: "share-users-completions d-flex align-items-center"
, onAutocompleteClick
, onEnterPress: onEnterPress text
, placeholder: "username or email"
, pattern: "^\\S+$" -- pattern doesn't allow space characters
, title: "Enter a username or an email address (space characters are not allowed)"
, title
, state }
[ B.iconButton { callback: submit state' text
[ B.iconButton { callback: \_ -> onEnterPress text state'
, elevation: Level1
, name: "send"
, title: "Submit" } ]
......@@ -110,10 +111,10 @@ shareNodeInnerCpt = here.component "shareNodeInner" cpt
where
autocompleteSearch input = pure $ nub $ filter (contains (Pattern input)) completions
onAutocompleteClick _ = pure unit
onEnterPress text val = T.write_ ("Invited " <> val <> " to the team") text
submit val text _ = do
onEnterPress text val
onEnterPress text val = do
launchAff_ $ dispatch (shareAction val)
T.write_ ("Invited " <> val <> " to the team") text
title = "Enter a username or an email address (space characters are not allowed)"
------------------------------------------------------------------------
publishNode :: R2.Component SubTreeParamsIn
publishNode = R.createElement publishNodeCpt
......
......@@ -61,7 +61,8 @@ nodeSearchControlCpt = here.component "nodeSearchControl" cpt
}
[
inputWithAutocomplete
{ autocompleteSearch: autocompleteSearch graph
{ autoFocus: true
, autocompleteSearch: autocompleteSearch graph
, onAutocompleteClick: doSearch
, onEnterPress: doSearch
, classes: "filter-results-completions rounded-circle-2 text-small py-0"
......
......@@ -27,7 +27,8 @@ type Completions = Array String
type Props =
(
autocompleteSearch :: String -> Effect Completions
autoFocus :: Boolean
, autocompleteSearch :: String -> Effect Completions
, classes :: String
, onAutocompleteClick :: String -> Effect Unit
, onEnterPress :: String -> Effect Unit
......@@ -42,7 +43,8 @@ inputWithAutocomplete = R2.component inputWithAutocompleteCpt
inputWithAutocompleteCpt :: R.Component Props
inputWithAutocompleteCpt = here.component "inputWithAutocomplete" cpt
where
cpt { autocompleteSearch
cpt { autoFocus
, autocompleteSearch
, classes
, onAutocompleteClick
, onEnterPress
......@@ -71,10 +73,11 @@ inputWithAutocompleteCpt = here.component "inputWithAutocomplete" cpt
completionsCpt { completions, onAutocompleteClick, state } []
, H.input { type: "text"
, ref: inputRef
, autoFocus
, className: "form-control"
, value: state'
, pattern: pattern
, title: title
, pattern
, title
, placeholder
, on: { focus: onFocus completions state'
, input: onInput completions
......
......@@ -139,7 +139,8 @@ component = here.component "main" cpt where
}
[
inputWithAutocomplete
{ autocompleteSearch: searchCallback
{ autoFocus: true
, autocompleteSearch: searchCallback
, onAutocompleteClick: autocompleteClickCallback
, onEnterPress: \s -> do
cs <- searchCallback s
......
......@@ -5,6 +5,7 @@ import Affjax as Affjax
import Affjax.RequestBody (formData, formURLEncoded, string)
import Affjax.RequestHeader as ARH
import Affjax.ResponseFormat as ResponseFormat
import Affjax.StatusCode (StatusCode(..))
import Data.Argonaut.Core as AC
import Data.Either (Either(..))
import Data.Foldable (foldMap)
......@@ -23,29 +24,36 @@ import Gargantext.Utils.Reactix as R2
import Simple.JSON as JSON
import Web.XHR.FormData as XHRFormData
here :: R2.Here
here = R2.here "Gargantext.Config.REST"
type Token = String
data RESTError =
SendResponseError Affjax.Error
| ReadJSONError Foreign.MultipleErrors
| CustomError String
CustomError String
| ReadJSONError Foreign.MultipleErrors
| SendResponseError Affjax.Error
| ServerError String
| UnknownServerError String
derive instance Generic RESTError _
instance Show RESTError where
show (CustomError s) = "CustomError " <> s
show (ReadJSONError e) = "ReadJSONError " <> show e
show (SendResponseError e) = "SendResponseError " <> showError e
where
showError (RequestContentError e') = "(RequestContentError " <> show e' <> ")"
showError (ResponseBodyError fe _) = "(ResponseBodyError " <> show fe <> " (rf)" -- <> show rf <> ")"
showError (TimeoutError) = "(TimeoutError)"
showError (RequestFailedError) = "(RequestFailedError)"
showError (XHROtherError e') = "(XHROtherError " <> show e' <> ")"
show (ReadJSONError e) = "ReadJSONError " <> show e
show (CustomError s) = "CustomError " <> s
showError (RequestContentError e') = "(RequestContentError " <> show e' <> ")"
showError (RequestFailedError) = "(RequestFailedError)"
showError (TimeoutError) = "(TimeoutError)"
showError (XHROtherError e') = "(XHROtherError " <> show e' <> ")"
show (ServerError e) = "ServerError: " <> e
show (UnknownServerError e) = "UnknownServerError: " <> e
instance Eq RESTError where
-- this is crude but we need it only because of useLoader
eq _ _ = false
logRESTError :: R2.Here -> String -> RESTError -> Effect Unit
logRESTError here prefix e = here.warn2 (prefix <> " " <> show e) e
logRESTError here' prefix e = here'.warn2 (prefix <> " " <> show e) e
-- logRESTError here prefix (SendResponseError e) = here.warn2 (prefix <> " SendResponseError ") e -- TODO: No show
-- logRESTError here prefix (ReadJSONError e) = here.warn2 (prefix <> " ReadJSONError ") $ show e
-- logRESTError here prefix (CustomError e) = here.warn2 (prefix <> " CustomError ") $ e
......@@ -53,11 +61,9 @@ logRESTError here prefix e = here.warn2 (prefix <> " " <> show e) e
type AffRESTError a = Aff (Either RESTError a)
readJSON :: forall a b. JSON.ReadForeign a =>
Either Affjax.Error
{ body :: AC.Json
| b
} -> Either RESTError a
readJSON :: forall a. JSON.ReadForeign a =>
Either Affjax.Error (Affjax.Response AC.Json)
-> Either RESTError a
readJSON affResp =
case affResp of
Left err -> do
......@@ -68,9 +74,15 @@ readJSON affResp =
--_ <- liftEffect $ log json.status
--_ <- liftEffect $ log json.headers
--_ <- liftEffect $ log json.body
case (JSON.readJSON $ AC.stringify resp.body) of
Left err -> Left $ ReadJSONError err
Right r -> Right r
case resp.status of
StatusCode 500 ->
case (JSON.readJSON $ AC.stringify resp.body :: JSON.E { error :: String }) of
Right ({ error }) -> Left $ ServerError error
Left _ -> Left $ UnknownServerError $ AC.stringify resp.body
_ ->
case (JSON.readJSON $ AC.stringify resp.body) of
Left err -> Left $ ReadJSONError err
Right r -> Right r
-- TODO too much duplicate code in `postWwwUrlencoded`
send :: forall body res. JSON.WriteForeign body => JSON.ReadForeign res =>
......@@ -94,6 +106,7 @@ send m mtoken url reqbody = do
let cookie = "JWT-Cookie=" <> token <> "; Path=/;" --" HttpOnly; Secure; SameSite=Lax"
R2.setCookie cookie
affResp <- request req
liftEffect $ here.log2 "[send] affResp" affResp
pure $ readJSON affResp
noReqBody :: Maybe String
......
......@@ -147,7 +147,7 @@ newtype Point = Point { x :: Number, y :: Number }
-- a reducer function living in effector, for useReductor
type Actor s a = (a -> s -> Effect s)
-- | Turns a ReactElement into aReactix Element
-- | Turns a ReactElement into a Reactix Element
-- | buff (v.) to polish
buff :: ReactElement -> R.Element
buff = unsafeCoerce
......
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