Commit 1530ca76 authored by Karen Konou's avatar Karen Konou

[WIP] [User] Image upload API functions

parent 35381e2c
Pipeline #3191 failed with stage
in 0 seconds
...@@ -25,7 +25,8 @@ type UserInfo ...@@ -25,7 +25,8 @@ type UserInfo
, ui_cwRole :: Maybe String , ui_cwRole :: Maybe String
, ui_cwTouchPhone :: Maybe String , ui_cwTouchPhone :: Maybe String
, ui_cwTouchMail :: Maybe String , ui_cwTouchMail :: Maybe String
, ui_cwDescription :: Maybe String } , ui_cwDescription :: Maybe String
, ui_cwImagePath :: Maybe String }
type UserInfoM type UserInfoM
= { token :: NotNull String = { token :: NotNull String
, ui_id :: NotNull Int , ui_id :: NotNull Int
...@@ -43,7 +44,8 @@ type UserInfoM ...@@ -43,7 +44,8 @@ type UserInfoM
, ui_cwRole :: String , ui_cwRole :: String
, ui_cwTouchPhone :: String , ui_cwTouchPhone :: String
, ui_cwTouchMail :: String , ui_cwTouchMail :: String
, ui_cwDescription :: String } , ui_cwDescription :: String
, ui_cwImagePath :: String }
userInfoQuery = { user_infos: { user_id: Var :: _ "id" Int } =>> userInfoQuery = { user_infos: { user_id: Var :: _ "id" Int } =>>
{ ui_id: unit { ui_id: unit
...@@ -61,7 +63,8 @@ userInfoQuery = { user_infos: { user_id: Var :: _ "id" Int } =>> ...@@ -61,7 +63,8 @@ userInfoQuery = { user_infos: { user_id: Var :: _ "id" Int } =>>
, ui_cwRole: unit , ui_cwRole: unit
, ui_cwTouchMail: unit , ui_cwTouchMail: unit
, ui_cwTouchPhone: unit , ui_cwTouchPhone: unit
, ui_cwDescription: unit } , ui_cwDescription: unit
, ui_cwImagePath: unit }
} }
_ui_cwFirstName :: Lens' UserInfo String _ui_cwFirstName :: Lens' UserInfo String
...@@ -128,9 +131,15 @@ _ui_cwTouchPhone = lens getter setter ...@@ -128,9 +131,15 @@ _ui_cwTouchPhone = lens getter setter
_ui_cwDescription :: Lens' UserInfo String _ui_cwDescription :: Lens' UserInfo String
_ui_cwDescription = lens getter setter _ui_cwDescription = lens getter setter
where where
getter ({ui_cwDescription: val}) = fromMaybe "" val getter ({ ui_cwDescription: val }) = fromMaybe "" val
setter ui val = ui { ui_cwDescription = Just val } setter ui val = ui { ui_cwDescription = Just val }
_ui_cwImagePath :: Lens' UserInfo String
_ui_cwImagePath = lens getter setter
where
getter ({ ui_cwImagePath: val }) = fromMaybe "" val
setter ui val = ui { ui_cwImagePath = Just val }
type User type User
= { u_id :: Int = { u_id :: Int
, u_hyperdata :: , u_hyperdata ::
......
"use strict";
exports.handleRef = handleRef;
function handleRef(ref) {
return ref.current.files[0]
};
\ No newline at end of file
...@@ -7,9 +7,12 @@ module Gargantext.Components.Nodes.Annuaire.User ...@@ -7,9 +7,12 @@ module Gargantext.Components.Nodes.Annuaire.User
import Gargantext.Prelude import Gargantext.Prelude
import DOM.Simple as DOM
import DOM.Simple.Event as DE
import Data.Either (Either(..)) import Data.Either (Either(..))
import Data.Lens as L import Data.Lens as L
import Data.Maybe (Maybe(..), fromMaybe) import Data.Maybe (Maybe(..), fromMaybe)
import Data.Nullable (Nullable, null)
import Effect (Effect) import Effect (Effect)
import Effect.Aff (launchAff_) import Effect.Aff (launchAff_)
import Effect.Class (liftEffect) import Effect.Class (liftEffect)
...@@ -21,11 +24,11 @@ import Gargantext.Components.InputWithEnter (inputWithEnter) ...@@ -21,11 +24,11 @@ import Gargantext.Components.InputWithEnter (inputWithEnter)
import Gargantext.Components.Nodes.Annuaire.Tabs as Tabs import Gargantext.Components.Nodes.Annuaire.Tabs as Tabs
import Gargantext.Components.Nodes.Annuaire.User.Contacts.Types (Contact(..), ContactData, ContactTouch(..), ContactWhere(..), ContactWho(..), HyperdataContact(..), HyperdataUser(..), _city, _country, _firstName, _labTeamDeptsJoinComma, _lastName, _mail, _office, _organizationJoinComma, _ouFirst, _phone, _role, _shared, _touch, _who, defaultContactTouch, defaultContactWhere, defaultContactWho, defaultHyperdataContact, defaultHyperdataUser) import Gargantext.Components.Nodes.Annuaire.User.Contacts.Types (Contact(..), ContactData, ContactTouch(..), ContactWhere(..), ContactWho(..), HyperdataContact(..), HyperdataUser(..), _city, _country, _firstName, _labTeamDeptsJoinComma, _lastName, _mail, _office, _organizationJoinComma, _ouFirst, _phone, _role, _shared, _touch, _who, defaultContactTouch, defaultContactWhere, defaultContactWho, defaultHyperdataContact, defaultHyperdataUser)
import Gargantext.Components.Nodes.Lists.Types as LT import Gargantext.Components.Nodes.Lists.Types as LT
import Gargantext.Config.REST (AffRESTError, logRESTError) import Gargantext.Config.REST (AffRESTError, RESTError, logRESTError)
import Gargantext.Config.Utils (handleRESTError) import Gargantext.Config.Utils (handleRESTError)
import Gargantext.Ends (Frontends) import Gargantext.Ends (Frontends)
import Gargantext.Hooks.Loader (useLoader) import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Sessions (Session(..), WithSession, WithSessionContext, sessionId) import Gargantext.Sessions (Session(..), WithSession, WithSessionContext, postMultipart, sessionId, sessionUrl)
import Gargantext.Types (FrontendError) import Gargantext.Types (FrontendError)
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Toestand as T2 import Gargantext.Utils.Toestand as T2
...@@ -36,17 +39,21 @@ import Reactix.DOM.HTML as H ...@@ -36,17 +39,21 @@ import Reactix.DOM.HTML as H
import Record as Record import Record as Record
import Toestand as T import Toestand as T
foreign import handleRef :: R.Ref (Nullable DOM.Element) -> String
here :: R2.Here here :: R2.Here
here = R2.here "Gargantext.Components.Nodes.Annuaire.User" here = R2.here "Gargantext.Components.Nodes.Annuaire.User"
type DisplayProps = ( title :: String ) type DisplayProps = ( title :: String, image :: String, session :: Session)
display :: R2.Component DisplayProps display :: R2.Component DisplayProps
display = R.createElement displayCpt display = R.createElement displayCpt
displayCpt :: R.Component DisplayProps displayCpt :: R.Component DisplayProps
displayCpt = here.component "display" cpt displayCpt = here.component "display" cpt
where where
cpt { title } children = do cpt { title, image, session } children = do
fileRef <- R.useRef null
pure $ H.div { className: "container-fluid" } pure $ H.div { className: "container-fluid" }
[ H.div { className: "row", id: "contact-page-header" } [ H.div { className: "row", id: "contact-page-header" }
[ H.div { className: "col-md-6"} [ H.h3 {} [ H.text title ] ] [ H.div { className: "col-md-6"} [ H.h3 {} [ H.text title ] ]
...@@ -57,11 +64,11 @@ displayCpt = here.component "display" cpt ...@@ -57,11 +64,11 @@ displayCpt = here.component "display" cpt
[ H.div { className: "col-md-12" } [ H.div { className: "col-md-12" }
[ H.div { className: "row" } [ H.div { className: "row" }
[ H.div { className: "col-md-2" } [ H.div { className: "container-fluid" } [ H.div { className: "col-md-2" } [ H.div { className: "container-fluid" }
[ H.div { className: "row" } [ H.img { src: "/images/Gargantextuel-212x300.jpg"} ] [ H.div { className: "row" } [ H.img { src: image} ]
, H.form { className: "row", enctype: "multipart/form-data" } , H.form { on: {submit: onSubmit session fileRef}, className: "row", encType: "multipart/form-data" }
[ H.label { for: "avatar" } [H.text "Choose your profile picture:"] [ H.label { for: "avatar" } [H.text "Choose your profile picture:"]
, H.input { type: "file", id: "avatar", accept: "image/png, image/jpeg" } , H.input { type: "file", ref: fileRef, accept: "image/png, image/jpeg" }
, H.button {} [ H.text "save" ] , H.button { className: "btn btn-secondary" } [ H.text "save" ]
] ]
] ]
] ]
...@@ -71,6 +78,14 @@ displayCpt = here.component "display" cpt ...@@ -71,6 +78,14 @@ displayCpt = here.component "display" cpt
] ]
] ]
] ]
where
onSubmit :: Session -> R.Ref (Nullable DOM.Element) -> DE.Event -> Effect Unit
onSubmit session fileRef e = do
let body = handleRef fileRef
R2.preventDefault e
launchAff_ $ do
aff :: Either RESTError Int <- postMultipart session "image" body
pure aff
{- {-
listElement :: Array R.Element -> R.Element listElement :: Array R.Element -> R.Element
...@@ -116,9 +131,9 @@ userLayoutWithKeyCpt = here.component "userLayoutWithKey" cpt where ...@@ -116,9 +131,9 @@ userLayoutWithKeyCpt = here.component "userLayoutWithKey" cpt where
useLoader { errorHandler useLoader { errorHandler
, loader: getUserInfoWithReload , loader: getUserInfoWithReload
, path: { nodeId: userId, reload: reload', session } , path: { nodeId: userId, reload: reload', session }
, render: \userInfo@{ ui_username } -> , render: \userInfo@{ ui_username, ui_cwImagePath} ->
H.ul { className: "col-md-12 list-group" } [ H.ul { className: "col-md-12 list-group" } [
display { title: fromMaybe "no name" (Just ui_username) } display { session, title: fromMaybe "no name" (Just ui_username), image: fromMaybe "/images/Gargantextuel-212x300.jpg" ui_cwImagePath}
(contactInfos userInfo (onUpdateUserInfo boxes.errors reload)) (contactInfos userInfo (onUpdateUserInfo boxes.errors reload))
, Tabs.tabs { , Tabs.tabs {
boxes boxes
......
-- | A module for authenticating to create sessions and handling them -- | A module for authenticating to create sessions and handling them
module Gargantext.Sessions module Gargantext.Sessions
( module Gargantext.Sessions.Types ( Action(..)
, WithSession, WithSessionContext , WithSession
, load, change , WithSessionContext
, Action(..), act, delete, get, post, put, put_ , act
, postAuthRequest, postForgotPasswordRequest , change
, deleteWithBody, postWwwUrlencoded , delete
, getCacheState, setCacheState , deleteWithBody
) where , get
, getCacheState
, load
, module Gargantext.Sessions.Types
, post
, postAuthRequest
, postForgotPasswordRequest
, postMultipart
, postWwwUrlencoded
, put
, put_
, setCacheState
)
where
import Gargantext.Prelude
import DOM.Simple.Console (log2) import DOM.Simple.Console (log2)
import Data.Either (Either(..), hush) import Data.Either (Either(..), hush)
...@@ -15,19 +30,16 @@ import Data.Map as Map ...@@ -15,19 +30,16 @@ import Data.Map as Map
import Data.Maybe (Maybe(..), fromMaybe) import Data.Maybe (Maybe(..), fromMaybe)
import Effect (Effect) import Effect (Effect)
import Effect.Aff (Aff) import Effect.Aff (Aff)
import Reactix as R
import Simple.JSON as JSON
import Toestand as T
import Web.Storage.Storage (getItem, removeItem, setItem)
import Gargantext.Prelude
import Gargantext.Components.Login.Types (AuthData(..), AuthInvalid(..), AuthRequest(..), AuthResponse(..)) import Gargantext.Components.Login.Types (AuthData(..), AuthInvalid(..), AuthRequest(..), AuthResponse(..))
import Gargantext.Components.Nodes.Lists.Types as NT import Gargantext.Components.Nodes.Lists.Types as NT
import Gargantext.Config.REST as REST import Gargantext.Config.REST as REST
import Gargantext.Ends (class ToUrl, Backend, toUrl) import Gargantext.Ends (class ToUrl, Backend, toUrl)
import Gargantext.Sessions.Types (Session(..), Sessions(..), OpenNodes, NodeId, mkNodeId, sessionUrl, sessionId, empty, null, unSessions, lookup, cons, tryCons, update, remove, tryRemove) import Gargantext.Sessions.Types (Session(..), Sessions(..), OpenNodes, NodeId, mkNodeId, sessionUrl, sessionId, empty, null, unSessions, lookup, cons, tryCons, update, remove, tryRemove)
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
import Reactix as R
import Simple.JSON as JSON
import Toestand as T
import Web.Storage.Storage (getItem, removeItem, setItem)
type WithSession c = type WithSession c =
( session :: Session ( session :: Session
...@@ -157,3 +169,7 @@ post session@(Session {token}) p = REST.post (Just token) (toUrl session p) ...@@ -157,3 +169,7 @@ post session@(Session {token}) p = REST.post (Just token) (toUrl session p)
postWwwUrlencoded :: forall b p. JSON.ReadForeign b => ToUrl Session p => postWwwUrlencoded :: forall b p. JSON.ReadForeign b => ToUrl Session p =>
Session -> p -> REST.FormDataParams -> REST.AffRESTError b Session -> p -> REST.FormDataParams -> REST.AffRESTError b
postWwwUrlencoded session@(Session {token}) p = REST.postWwwUrlencoded (Just token) (toUrl session p) postWwwUrlencoded session@(Session {token}) p = REST.postWwwUrlencoded (Just token) (toUrl session p)
postMultipart :: forall b p. JSON.ReadForeign b => ToUrl Session p =>
Session -> p -> String -> REST.AffRESTError b
postMultipart session@(Session {token}) p = REST.postMultipartFormData (Just token) (toUrl session p)
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