Translations for the profile page components
This commit is contained in:
parent
0bec18825e
commit
3e3e4e3ef3
@ -41,7 +41,7 @@ const template = `
|
||||
<th scope="row">{{ index + 1 }}</th>
|
||||
<td v-for="col of definition.columns">
|
||||
<span v-if="typeof col.renderer === 'function'">{{ col.renderer(row[col.field]) }}</span>
|
||||
<span v-if="col.renderer === 'boolean'">{{ row[col.field] ? 'Yes' : 'No' }}</span>
|
||||
<span v-if="col.renderer === 'boolean'">{{ row[col.field] ? t['common.yes'] : t['common.no'] }}</span>
|
||||
<span v-if="col.renderer !== 'boolean' && typeof col.renderer !== 'function'">{{ col.field in row ? row[col.field] : '-' }}</span>
|
||||
</td>
|
||||
<td>
|
||||
@ -71,14 +71,26 @@ export default class ListingComponent extends Component {
|
||||
|
||||
access_msg = ''
|
||||
can_access = false
|
||||
t = {}
|
||||
|
||||
async vue_on_create() {
|
||||
this.t = await T(
|
||||
'common.yes',
|
||||
'common.no',
|
||||
'common.not_permission',
|
||||
'common.view',
|
||||
'common.are_you_sure',
|
||||
'common.action_resource_confirm',
|
||||
'common.cancel',
|
||||
'common.continue'
|
||||
)
|
||||
|
||||
// Load the resource
|
||||
this.resource_class = await resource_service.get(this.resource)
|
||||
|
||||
// Make sure we have permission
|
||||
if ( !(await this.resource_class.can('list')) ) {
|
||||
this.access_msg = 'Sorry, you do not have permission to view this resource.'
|
||||
this.access_msg = this.t['common.not_permission'].replace('ACTION', this.t['common.view'])
|
||||
this.can_access = false
|
||||
return
|
||||
} else {
|
||||
@ -97,15 +109,15 @@ export default class ListingComponent extends Component {
|
||||
async perform($event, action, row = undefined) {
|
||||
if ( action.confirm ) {
|
||||
message_service.modal({
|
||||
title: 'Are you sure?',
|
||||
message: `You are about to ${action.action}${row ? ' this '+this.resource_class.item : ''}. Do you want to continue?`,
|
||||
title: this.t['common.are_you_sure'],
|
||||
message: this.t['common.action_resource_confirm'].replace('ACTION', action.action).replace('RESOURCE', this.resource_class.item),
|
||||
buttons: [
|
||||
{
|
||||
text: 'Cancel',
|
||||
text: this.t['common.cancel'],
|
||||
type: 'close',
|
||||
},
|
||||
{
|
||||
text: 'Continue',
|
||||
text: this.t['common.continue'],
|
||||
class: ['btn', 'btn-primary'],
|
||||
type: 'close',
|
||||
on_click: async () => {
|
||||
|
@ -13,9 +13,9 @@ const template = `
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-8 offset-2 col-sm-4 offset-sm-0">
|
||||
<img src="/api/v1/profile/me/photo" alt="Profile Image" ref="photo" class="img-fluid">
|
||||
<img src="/api/v1/profile/me/photo" :alt="t['profile.profile_photo']" ref="photo" class="img-fluid">
|
||||
<div class="overlay">
|
||||
<button class="btn btn-outline-light" @click="on_profile_change_click">Change</button>
|
||||
<button class="btn btn-outline-light" @click="on_profile_change_click">{{ t['common.change'] }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-8 offset-sm-0 col-12 text-sm-left text-center pad-top">
|
||||
@ -26,26 +26,26 @@ const template = `
|
||||
</div>
|
||||
<ul class="list-group list-group-flush">
|
||||
<li class="list-group-item">
|
||||
<h4>Basic Profile</h4>
|
||||
<h4>{{ t['profile.basic_profile'] }}</h4>
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-6 form-group">
|
||||
<label for="coreid-profile-first-input">First Name</label>
|
||||
<label for="coreid-profile-first-input">{{ t['register.first_name'] }}</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="coreid-profile-first-input"
|
||||
placeholder="John"
|
||||
:placeholder="t['profile.placeholder_first']"
|
||||
v-model="profile_first"
|
||||
@keyup="on_key_up($event)"
|
||||
>
|
||||
</div>
|
||||
<div class="col-12 col-md-6 form-group">
|
||||
<label for="coreid-profile-last-input">Last Name</label>
|
||||
<label for="coreid-profile-last-input">{{ t['register.last_name'] }}</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="coreid-profile-last-input"
|
||||
placeholder="Doe"
|
||||
:placeholder="t['profile.placeholder_last']"
|
||||
v-model="profile_last"
|
||||
@keyup="on_key_up($event)"
|
||||
>
|
||||
@ -53,12 +53,12 @@ const template = `
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 form-group">
|
||||
<label for="coreid-profile-email-input">E-Mail Address</label>
|
||||
<label for="coreid-profile-email-input">{{ t['register.email'] }}</label>
|
||||
<input
|
||||
type="email"
|
||||
class="form-control"
|
||||
id="coreid-profile-email-input"
|
||||
placeholder="john.doe@contoso.com"
|
||||
:placeholder="t['profile.placeholder_email'] "
|
||||
v-model="profile_email"
|
||||
ref="email_input"
|
||||
@keyup="on_key_up($event)"
|
||||
@ -67,7 +67,7 @@ const template = `
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 form-group">
|
||||
<label for="coreid-profile-tag-input">Tagline</label>
|
||||
<label for="coreid-profile-tag-input">{{ t['profile.tagline'] }}</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
@ -82,13 +82,13 @@ const template = `
|
||||
{{ form_message }}
|
||||
</li>
|
||||
<li class="list-group-item" v-if="!user_id || user_id === 'me'">
|
||||
<h4>Password</h4>
|
||||
<p class="font-italic" v-if="last_reset">Your password was last changed on {{ last_reset }}.</p>
|
||||
<h4>{{ t['password.password'] }}</h4>
|
||||
<p class="font-italic" v-if="last_reset">{{ t['profile.pw_last_reset'].replace('LAST_RESET', last_reset) }}</p>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary btn-sm"
|
||||
@click="change_password"
|
||||
>Change Password</button>
|
||||
>{{ t['password.change'] }}</button>
|
||||
</li>
|
||||
<li class="list-group-item" v-if="!has_mfa && (!user_id || user_id === 'me')">
|
||||
<h4>Multi-factor Authentication</h4>
|
||||
@ -97,49 +97,49 @@ const template = `
|
||||
<button class="btn btn-success btn-sm" type="button" @click="enable_mfa">Enable MFA</button>
|
||||
</li>
|
||||
<li class="list-group-item" v-if="has_mfa && (!user_id || user_id === 'me')">
|
||||
<h4>Multi-factor Authentication</h4>
|
||||
<p class="font-italic">MFA was enabled for your account on {{ mfa_enable_date }}.</p>
|
||||
<h4>{{ t['mfa.mfa'] }}</h4>
|
||||
<p class="font-italic">{{ t['profile.mfa_enabled_on'].replace('MFA_ENABLED', mfa_enable_date) }}</p>
|
||||
<button
|
||||
class="btn btn-danger btn-sm"
|
||||
type="button"
|
||||
@click="disable_mfa"
|
||||
>Disable MFA</button>
|
||||
>{{ t['mfa.disable'] }}</button>
|
||||
|
||||
<h6 class="pad-top">App Passwords</h6>
|
||||
<p>App passwords are specially generated passwords that allow you to sign into legacy services with your {{ app_name }} account.</p>
|
||||
<p>You should only use this to authenticate against a service that needs to repeatedly use your password on your behalf (e.g. e-mail clients).</p>
|
||||
<p>Use these with caution, as they can bypass your multi-factor authentication.</p>
|
||||
<h6 class="pad-top">{{ t['profile.app_pws'] }}</h6>
|
||||
<p>{{ t['profile.app_pw_1'].replace('APP_NAME', app_name) }}</p>
|
||||
<p>{{ t['profile.app_pw_2'] }}</p>
|
||||
<p>{{ t['profile.app_pw_3'] }}</p>
|
||||
|
||||
<p class="font-italic text-muted" v-if="app_passwords.length > 0">You have {{ app_passwords.length }} app {{ app_passwords.length === 1 ? 'password' : 'passwords' }} associated with your account.</p>
|
||||
<p class="font-italic text-muted" v-if="app_passwords.length > 0">{{ t['profile.app_pw_remaining.'+(app_passwords.length === 1 ? 'one' : 'many')].replace('NUM_PWS', app_passwords.length) }}</p>
|
||||
<ul class="list-group mb-4" v-if="app_passwords.length > 0">
|
||||
<li class="list-group-item" v-for="pw of app_passwords">
|
||||
<div class="row">
|
||||
<div class="col-9">
|
||||
{{ pw.name }}
|
||||
<br><span class="text-muted font-italic">Issued: {{ pw.created }}</span>
|
||||
<br><span class="text-muted font-italic">{{ t['profile.issued'] }} {{ pw.created }}</span>
|
||||
</div>
|
||||
<div class="col-3 my-auto">
|
||||
<button
|
||||
class="btn btn-sm btn-danger"
|
||||
type="button"
|
||||
@click="deactivate_app_password($event, pw)"
|
||||
>Deactivate</button>
|
||||
>{{ t['common.deactivate'] }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<button class="btn btn-sm btn-primary" @click="on_click_generate_app_password">Generate New</button>
|
||||
<button class="btn btn-sm btn-primary" @click="on_click_generate_app_password">{{ t['profile.gen_new'] }}</button>
|
||||
|
||||
<h6 class="pad-top">Recovery Codes</h6>
|
||||
<p>Recovery codes can be used to regain access to your account in the event that you lose access to the device that generates your MFA codes.</p>
|
||||
<h6 class="pad-top">{{ t['profile.recovery_codes'] }}</h6>
|
||||
<p>{{ t['profile.recovery_1'] }}</p>
|
||||
<span v-if="!has_mfa_recovery">
|
||||
<p class="font-italic">No recovery codes have been generated for your account.</p>
|
||||
<button class="btn btn-sm btn-success" @click="on_mfa_recovery_generate">Generate Recovery Codes</button>
|
||||
<p class="font-italic">{{ t['profile.no_recovery'] }}</p>
|
||||
<button class="btn btn-sm btn-success" @click="on_mfa_recovery_generate">{{ t['profile.generate_recovery'] }}</button>
|
||||
</span>
|
||||
<span v-if="has_mfa_recovery">
|
||||
<p class="font-italic">Recovery codes were generate for your account on {{ mfa_recovery_date }}. <span v-if="mfa_recovery_codes === 1">There is only 1 recovery code remaining.</span><span v-if="mfa_recovery_codes !== 1">There are {{ mfa_recovery_codes }} recovery codes remaining.</span></p>
|
||||
<button class="btn btn-sm btn-success" @click="on_mfa_recovery_generate">Re-generate Recovery Codes</button>
|
||||
<p class="font-italic">{{ t['profile.recovery_gen_on'].replace('MFA_RECOVERY', mfa_recovery_date) }} {{ t['profile.codes_remaining.'+(mfa_recovery_codes === 1 ? 'one' : 'many')].replace('NUM_CODES', mfa_recovery_codes) }}</p>
|
||||
<button class="btn btn-sm btn-success" @click="on_mfa_recovery_generate">{{ t['profile.regenerate_recovery'] }}</button>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
@ -179,10 +179,48 @@ export default class EditProfileComponent extends Component {
|
||||
ready = false
|
||||
|
||||
app_passwords = []
|
||||
app_name = ''
|
||||
t = {}
|
||||
|
||||
on_key_up = ($event) => {}
|
||||
|
||||
vue_on_create() {
|
||||
async vue_on_create() {
|
||||
this.t = await T(
|
||||
'profile.profile_photo',
|
||||
'common.change',
|
||||
'profile.basic_profile',
|
||||
'register.first_name',
|
||||
'profile.placeholder_first',
|
||||
'register.last_name',
|
||||
'profile.placeholder_last',
|
||||
'register.email',
|
||||
'profile.placeholder_email',
|
||||
'profile.tagline',
|
||||
'password.password',
|
||||
'password.change',
|
||||
'profile.pw_last_reset',
|
||||
'mfa.mfa',
|
||||
'profile.mfa_enabled_on',
|
||||
'mfa.disable',
|
||||
'profile.app_pws',
|
||||
'profile.issued',
|
||||
'common.deactivate',
|
||||
'profile.app_pw_remaining.one',
|
||||
'profile.app_pw_remaining.many',
|
||||
'profile.gen_new',
|
||||
'profile.recovery_codes',
|
||||
'profile.recovery_1',
|
||||
'profile.no_recovery',
|
||||
'profile.generate_recovery',
|
||||
'profile.recovery_gen_on',
|
||||
'profile.codes_remaining.one',
|
||||
'profile.codes_remaining.many',
|
||||
'profile.regenerate_recovery',
|
||||
'profile.app_pw_1',
|
||||
'profile.app_pw_2',
|
||||
'profile.app_pw_3'
|
||||
)
|
||||
|
||||
this.app_name = session.get('app.name')
|
||||
this.load().then(() => {
|
||||
this.ready = true
|
||||
|
@ -13,27 +13,27 @@ const template = `
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Generate App-Password</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<h5 class="modal-title">{{ t['profile.generate_app_pw'] }}</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" :aria-label="t['common.close']">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group" v-if="!display_password">
|
||||
<label :for="uuid">App Name</label>
|
||||
<label :for="uuid">{{ t['profile.app_name'] }}</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
:id="uuid"
|
||||
v-model="name"
|
||||
@keyup="on_name_change"
|
||||
placeholder="My really cool e-mail client"
|
||||
:placeholder="t['profile.cool_email_client']"
|
||||
:disabled="!enable_form"
|
||||
ref="input"
|
||||
>
|
||||
</div>
|
||||
<div v-if="display_password">
|
||||
The app password for <code>{{ name }}</code> was generated successfully. Copy the password below and use it in <code>{{ name }}</code> to sign in. Note that, once you close this window, you will no longer be able to view this password.
|
||||
{{ t['profile.app_pw_success'].replace(/APP_NAME/g, name) }}
|
||||
</div>
|
||||
<div v-if="display_password" class="text-center pad-top">
|
||||
<pre><code>{{ display_password }}</code></pre>
|
||||
@ -46,21 +46,21 @@ const template = `
|
||||
data-dismiss="modal"
|
||||
@click="$emit('modal-cancel')"
|
||||
v-if="!display_password"
|
||||
>Cancel</button>
|
||||
>{{ t['common.cancel'] }}</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary"
|
||||
:disabled="!valid || !enable_form"
|
||||
@click="generate_pw"
|
||||
v-if="!display_password"
|
||||
>Generate</button>
|
||||
>{{ t['common.generate'] }}</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary"
|
||||
v-if="display_password"
|
||||
data-dismiss="modal"
|
||||
@click="$emit('modal-success')"
|
||||
>Close</button>
|
||||
>{{ t['common.close'] }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -77,8 +77,19 @@ export default class AppPasswordFormComponent extends Component {
|
||||
uuid = ''
|
||||
enable_form = true
|
||||
display_password = ''
|
||||
t = {}
|
||||
|
||||
async vue_on_create() {
|
||||
this.t = await T(
|
||||
'profile.generate_app_pw',
|
||||
'profile.app_name',
|
||||
'profile.cool_email_client',
|
||||
'profile.app_pw_success',
|
||||
'common.cancel',
|
||||
'common.generate',
|
||||
'common.close'
|
||||
)
|
||||
|
||||
vue_on_create() {
|
||||
this.uuid = utility.uuid()
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,8 @@ const template = `
|
||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||
<div class="modal-content" v-if="ready">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Change Profile Photo</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<h5 class="modal-title">{{ t['profile.change_photo'] }}</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" :aria-label="t['common.close']">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
@ -17,7 +17,7 @@ const template = `
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
@click="do_upload"
|
||||
>Change</button>
|
||||
>{{ t['common.change'] }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -30,6 +30,15 @@ export default class ProfilePhotoUploaderComponent extends Component {
|
||||
static get params() { return [] }
|
||||
|
||||
ready = false
|
||||
t = {}
|
||||
|
||||
async vue_on_create() {
|
||||
this.t = await T(
|
||||
'profile.change_photo',
|
||||
'common.change',
|
||||
'common.close'
|
||||
)
|
||||
}
|
||||
|
||||
show() {
|
||||
this.ready = true
|
||||
|
@ -8,6 +8,8 @@ module.exports = exports = {
|
||||
invalid: 'Invalid',
|
||||
unnamed: '(unnamed)',
|
||||
|
||||
yes: 'Yes',
|
||||
no: 'No',
|
||||
deny: 'Deny',
|
||||
grant: 'Grant Access',
|
||||
back: 'Back',
|
||||
@ -15,6 +17,11 @@ module.exports = exports = {
|
||||
cancel: 'Cancel',
|
||||
request: 'Request',
|
||||
continue: 'Continue',
|
||||
generate: 'Generate',
|
||||
close: 'Close',
|
||||
change: 'Change',
|
||||
deactivate: 'Deactivate',
|
||||
view: 'View',
|
||||
unknown_error: 'An unknown error has occurred, and we are unable to continue at this time.',
|
||||
|
||||
invalid_resolver: 'Invalid locale resolver.',
|
||||
@ -26,4 +33,7 @@ module.exports = exports = {
|
||||
invalid_json: 'must be valid JSON.',
|
||||
not_permission: 'Sorry, you do not have permission to ACTION this resource.',
|
||||
item_saved: 'The ITEM was saved.',
|
||||
|
||||
are_you_sure: 'Are you sure?',
|
||||
action_resource_confirm: 'You are about to ACTION this RESOURCE. Do you want to continue?',
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
module.exports = exports = {
|
||||
mfa: 'Multi-factor Authentication',
|
||||
challenge_prompt: 'Your account has multi-factor authentication enabled. Please enter the code generated by your authenticator app to continue.',
|
||||
mfa_code: { one: 'MFA Code', many: 'MFA Codes' },
|
||||
lost_device: 'Lost your MFA device?',
|
||||
|
@ -7,5 +7,6 @@ module.exports = exports = {
|
||||
new_password: 'New Password',
|
||||
confirm_password: 'Confirm the Password',
|
||||
change: 'Change Password',
|
||||
password: 'Password',
|
||||
reset_success: 'Your password was reset. For security reasons, you will be asked to sign-in again.',
|
||||
}
|
||||
|
42
locale/en_US/profile.locale.js
Normal file
42
locale/en_US/profile.locale.js
Normal file
@ -0,0 +1,42 @@
|
||||
module.exports = exports = {
|
||||
generate_app_pw: 'Generate App-Password',
|
||||
app_pws: 'App Passwords',
|
||||
app_name: 'App Name',
|
||||
cool_email_client: 'My really cool e-mail client',
|
||||
app_pw_success: 'The app password for <code>APP_NAME</code> was generated successfully. Copy the password below and use it in <code>APP_NAME</code> to sign in. Note that, once you close this window, you will no longer be able to view this password.',
|
||||
|
||||
change_photo: 'Change Profile Photo',
|
||||
profile_photo: 'Profile Photo',
|
||||
|
||||
placeholder_first: 'John',
|
||||
placeholder_last: 'Doe',
|
||||
placeholder_email: 'john.doe@contoso.com',
|
||||
|
||||
tagline: 'Tagline',
|
||||
basic_profile: 'Basic Profile',
|
||||
|
||||
pw_last_reset: 'Your password was last changed on LAST_RESET.',
|
||||
mfa_enabled_on: 'MFA was enabled for your account on MFA_ENABLED.',
|
||||
|
||||
app_pw_1: 'App passwords are specially generated passwords that allow you to sign into legacy services with your APP_NAME account.',
|
||||
app_pw_2: 'You should only use this to authenticate against a service that needs to repeatedly use your password on your behalf (e.g. e-mail clients).',
|
||||
app_pw_3: 'Use these with caution, as they can bypass your multi-factor authentication.',
|
||||
|
||||
app_pw_remaining: {
|
||||
one: 'You have NUM_PWS app password associated with your account.',
|
||||
many: 'You have NUM_PWS app passwords associated with your account.',
|
||||
},
|
||||
|
||||
issued: 'Issued:',
|
||||
gen_new: 'Generate New',
|
||||
recovery_codes: 'Recovery Codes',
|
||||
recovery_1: 'Recovery codes can be used to regain access to your account in the event that you lose access to the device that generates your MFA codes.',
|
||||
no_recovery: 'No recovery codes have been generated for your account.',
|
||||
generate_recovery: 'Generate Recovery Codes',
|
||||
recovery_gen_on: 'Recovery codes were generate for your account on MFA_RECOVERY.',
|
||||
codes_remaining: {
|
||||
one: 'There is only 1 recovery code remaining.',
|
||||
many: 'There are NUM_CODES recovery codes remaining.',
|
||||
},
|
||||
regenerate_recovery: 'Re-generate Recovery Codes',
|
||||
}
|
Loading…
Reference in New Issue
Block a user