Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
purescript-gargantext
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
148
Issues
148
List
Board
Labels
Milestones
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
gargantext
purescript-gargantext
Commits
1530ca76
Commit
1530ca76
authored
Sep 14, 2022
by
Karen Konou
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[WIP] [User] Image upload API functions
parent
35381e2c
Pipeline
#3191
failed with stage
in 0 seconds
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
76 additions
and
29 deletions
+76
-29
User.purs
src/Gargantext/Components/GraphQL/User.purs
+13
-4
User.js
src/Gargantext/Components/Nodes/Annuaire/User.js
+7
-0
User.purs
src/Gargantext/Components/Nodes/Annuaire/User.purs
+25
-10
Sessions.purs
src/Gargantext/Sessions.purs
+31
-15
No files found.
src/Gargantext/Components/GraphQL/User.purs
View file @
1530ca76
...
@@ -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 ::
...
...
src/Gargantext/Components/Nodes/Annuaire/User.js
0 → 100644
View file @
1530ca76
"use strict"
;
exports
.
handleRef
=
handleRef
;
function
handleRef
(
ref
)
{
return
ref
.
current
.
files
[
0
]
};
\ No newline at end of file
src/Gargantext/Components/Nodes/Annuaire/User.purs
View file @
1530ca76
...
@@ -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", enct
ype: "multipart/form-data" }
, H.form {
on: {submit: onSubmit session fileRef}, className: "row", encT
ype: "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
...
...
src/Gargantext/Sessions.purs
View file @
1530ca76
-- | 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)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment