Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
Frontend
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Container Registry
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Arkindex
Frontend
Merge requests
!1691
Something went wrong on our end
User settings form
Code
Review changes
Check out branch
Download
Patches
Plain diff
Merged
User settings form
user-settings-form
into
master
Overview
13
Commits
5
Pipelines
0
Changes
1
All threads resolved!
Hide all comments
Merged
Valentin Rigal
requested to merge
user-settings-form
into
master
9 months ago
Overview
13
Commits
5
Pipelines
0
Changes
1
All threads resolved!
Hide all comments
Expand
Closes
#1417 (closed)
0
0
Merge request reports
Viewing commit
c930ac82
Show latest version
1 file
+
1
−
1
Inline
Compare changes
Side-by-side
Inline
Show whitespace changes
Show one file at a time
c930ac82
Nit
· c930ac82
Valentin Rigal
authored
9 months ago
src/components/Auth/Profile/Info.vue
+
178
−
23
Options
<
template
>
<table
class=
"table"
>
<thead>
<tr>
<th><span
class=
"has-text-weight-bold"
>
Email
</span></th>
<td>
{{
user
.
email
}}
</td>
</tr>
</thead>
<tbody>
<tr>
<td><span
class=
"has-text-weight-bold"
>
Display name
</span></td>
<td>
{{
user
.
display_name
}}
</td>
</tr>
<tr>
<td><span
class=
"has-text-weight-bold"
>
API Token
</span></td>
<td><samp
class=
"tag is-light"
>
{{
user
.
auth_token
}}
</samp></td>
</tr>
</tbody>
</table>
<form
v-if=
"user"
v-on:submit.prevent=
"submit"
>
<div
class=
"field"
>
<label
class=
"label"
>
Display name
</label>
<div
class=
"control is-expanded"
>
<input
type=
"text"
class=
"input"
v-model=
"displayName"
:class=
"
{ 'is-danger': !displayName || fieldErrors.display_name.length }"
:disabled="loading"
required
/>
</div>
<p
class=
"help is-danger"
v-for=
"err in fieldErrors.display_name"
:key=
"err"
>
{{
err
}}
</p>
</div>
<div
class=
"field"
>
<label
class=
"label"
>
E-mail address
</label>
<div
class=
"control"
>
<input
class=
"input"
name=
"username"
:value=
"user.email"
disabled
title=
"Your email address cannot be modified directly, please contact an administrator"
/>
</div>
</div>
<label
class=
"label"
>
API token
</label>
<div
class=
"field has-addons"
>
<div
class=
"control"
v-if=
"!showToken"
>
<button
type=
"button"
class=
"button"
v-on:click=
"showToken = true"
title=
"Reveal your personal API access token"
>
Reveal
</button>
</div>
<div
v-else
class=
"control is-clickable"
v-on:click=
"copyToken"
>
<div
class=
"input"
title=
"Copy your personal API access token"
>
{{
user
.
auth_token
}}
</div>
</div>
<div
class=
"control"
v-on:click=
"copyToken"
>
<div
class=
"button"
title=
"Copy your personal API access token"
>
Copy
<i
class=
"icon-clipboard"
></i>
</div>
</div>
</div>
<div
class=
"field"
>
<div
class=
"field"
>
<label
class=
"label"
>
New password
</label>
<div
class=
"control"
>
<input
type=
"password"
v-model=
"password"
class=
"input"
:disabled=
"loading"
/>
<p
class=
"help is-danger"
v-for=
"err in fieldErrors.password"
:key=
"err"
>
{{
err
}}
</p>
</div>
</div>
<div
class=
"field"
>
<label
class=
"label"
>
Confirm new password
</label>
<div
class=
"control"
>
<input
type=
"password"
v-model=
"confirmPassword"
class=
"input"
:disabled=
"loading"
/>
<p
class=
"help is-danger"
v-for=
"err in fieldErrors.confirm_password"
:key=
"err"
>
{{
err
}}
</p>
</div>
</div>
</div>
<div
class=
"field"
>
<p
class=
"control"
>
<button
type=
"submit"
class=
"button is-primary is-pulled-right"
:class=
"
{ 'is-loading': loading }"
:disabled="!canSubmit"
:title="canSubmit ? 'Update personal information' : 'Fields are left unchanged'"
>
Edit
</button>
</p>
</div>
</form>
</
template
>
<
script
>
import
{
mapState
}
from
'
vuex
'
export
default
{
<
script
lang=
"ts"
>
import
{
defineComponent
}
from
'
vue
'
import
{
mapState
as
mapVuexState
,
mapActions
as
mapVuexActions
}
from
'
vuex
'
import
{
mapActions
}
from
'
pinia
'
import
{
useNotificationStore
}
from
'
@/stores
'
import
{
UserUpdatePayload
}
from
'
@/api/user
'
import
{
errorParser
}
from
'
@/helpers
'
export
default
defineComponent
({
data
:
()
=>
({
displayName
:
''
,
password
:
''
,
confirmPassword
:
''
,
showToken
:
false
,
loading
:
false
,
fieldErrors
:
{
display_name
:
[],
password
:
[],
confirm_password
:
[]
}
as
Record
<
string
,
Array
<
string
>>
}),
computed
:
{
...
mapState
(
'
auth
'
,
[
'
user
'
])
...
mapVuexState
(
'
auth
'
,
[
'
user
'
]),
canSubmit
():
boolean
{
if
(
this
.
loading
)
return
false
return
(
(
this
.
displayName
!==
this
.
user
?.
display_name
)
||
(
this
.
password
!==
''
&&
this
.
confirmPassword
!==
''
)
)
}
},
methods
:
{
...
mapVuexActions
(
'
auth
'
,
[
'
updateUser
'
,
'
login
'
,
'
logout
'
]),
...
mapActions
(
useNotificationStore
,
[
'
notify
'
]),
async
copyToken
()
{
if
(
!
this
.
user
)
return
try
{
await
navigator
.
clipboard
.
writeText
(
this
.
user
.
auth_token
)
this
.
notify
({
type
:
'
success
'
,
text
:
'
API token copied to clipboard
'
})
}
catch
(
err
)
{
this
.
notify
({
type
:
'
error
'
,
text
:
'
Failed to copy API token
'
})
}
},
checkPassword
()
{
this
.
fieldErrors
.
confirm_password
=
[]
if
(
this
.
password
!==
''
&&
this
.
password
!==
this
.
confirmPassword
)
{
this
.
fieldErrors
.
confirm_password
=
[
"
Passwords don't match
"
]
return
false
}
return
true
},
async
submit
()
{
if
(
!
this
.
canSubmit
||
!
this
.
checkPassword
())
return
const
payload
:
UserUpdatePayload
=
{
display_name
:
this
.
displayName
}
if
(
this
.
password
)
payload
.
password
=
this
.
password
this
.
loading
=
true
try
{
await
this
.
updateUser
(
payload
)
this
.
notify
({
type
:
'
success
'
,
text
:
'
Your account has been updated
'
})
}
catch
(
err
)
{
this
.
notify
({
type
:
'
error
'
,
text
:
`An error occurred updating your account:
${
errorParser
(
err
)}
`
})
}
finally
{
this
.
loading
=
false
}
}
},
watch
:
{
user
:
{
handler
(
newValue
)
{
if
(
!
newValue
)
return
this
.
displayName
=
newValue
.
display_name
},
immediate
:
true
}
}
}
}
)
</
script
>
Loading