Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions addon/components/modals/change-user-email.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Modal::Default @modalIsOpened={{@modalIsOpened}} @options={{@options}} @confirm={{@onConfirm}} @decline={{@onDecline}}>
<div class="px-4 text-gray-900 dark:text-gray-50">
<div class="mb-1 text-base font-semibold">
{{t "iam.components.modals.change-user-email.heading" userName=this.user.name}}
</div>
<div class="text-sm mb-4">
{{t "iam.components.modals.change-user-email.prompt"}}
</div>
<InputGroup>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
<InputGroup @name={{t "iam.components.modals.change-user-email.current-email"}} @type="email" @value={{this.user.email}} @disabled={{true}} @wrapperClass="mb-0i" />
<InputGroup @name={{t "iam.components.modals.change-user-email.new-email"}} @type="email" @value={{this.email}} @wrapperClass="mb-0i" />
</div>
</InputGroup>
</div>
</Modal::Default>
52 changes: 52 additions & 0 deletions addon/components/modals/change-user-email.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { isBlank } from '@ember/utils';

export default class ModalsChangeUserEmailComponent extends Component {
@service fetch;
@service intl;
@service notifications;

@tracked options = {};
@tracked email;
@tracked user;

constructor(owner, { options }) {
super(...arguments);
this.user = options.user;
this.options = options;
this.setupOptions();
}

setupOptions() {
this.options.title = this.intl.t('iam.components.modals.change-user-email.title');
this.options.acceptButtonText = this.intl.t('iam.components.modals.change-user-email.send-verification');
this.options.declineButtonHidden = true;
this.options.confirm = async (modal) => {
modal.startLoading();

if (isBlank(this.email)) {
this.notifications.warning(this.intl.t('iam.components.modals.change-user-email.email-required'));
return modal.stopLoading();
}

try {
await this.fetch.post(`users/${this.user.id}/change-email`, {
email: this.email,
});

this.notifications.success(this.intl.t('iam.components.modals.change-user-email.verification-sent'));

if (typeof this.options.onEmailChangeComplete === 'function') {
this.options.onEmailChangeComplete();
}

modal.done();
} catch (error) {
this.notifications.serverError(error);
modal.stopLoading();
}
};
}
}
4 changes: 2 additions & 2 deletions addon/components/modals/user-form.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<div class="flex-1">
<div class="grid grid-cols-2 gap-2 text-xs dark:text-gray-100 mb-2">
<InputGroup @name={{t "iam.common.name"}} @value={{@options.user.name}} @disabled={{cannot @options.formPermission}} />
<InputGroup @name={{t "iam.common.email"}} @type="email" @value={{@options.user.email}} @disabled={{cannot @options.formPermission}} />
<InputGroup @name={{t "iam.common.email"}} @type="email" @value={{@options.user.email}} @disabled={{or (cannot @options.formPermission) (not @options.allowEmailEdit)}} />
<InputGroup @name={{t "iam.common.phone"}}>
<PhoneInput @value={{@options.user.phone}} @onInput={{fn (mut @options.user.phone)}} disabled={{cannot @options.formPermission}} class="form-input w-full" />
</InputGroup>
Expand Down Expand Up @@ -48,4 +48,4 @@
</div>
</div>
</div>
</Modal::Default>
</Modal::Default>
23 changes: 23 additions & 0 deletions addon/controllers/users/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,12 @@ export default class UsersIndexController extends Controller {
className: 'text-danger',
isVisible: (user) => this.abilities.can('iam change-password-for user') || user.role_name === 'Administrator' || user.is_admin === true,
},
{
label: this.intl.t('iam.users.index.change-user-email'),
fn: this.changeUserEmail,
className: 'text-danger',
isVisible: () => this.abilities.can('iam change-email-for user') || this.currentUser.user.role_name === 'Administrator' || this.currentUser.user.is_admin === true,
},
{
label: this.intl.t('iam.users.index.delete-user'),
fn: this.deleteUser,
Expand Down Expand Up @@ -371,6 +377,7 @@ export default class UsersIndexController extends Controller {
acceptButtonDisabled: this.abilities.cannot(formPermission),
acceptButtonHelpText: this.abilities.cannot(formPermission) ? this.intl.t('common.unauthorized') : null,
formPermission,
allowEmailEdit: true,
confirm: async (modal) => {
modal.startLoading();

Expand Down Expand Up @@ -407,6 +414,7 @@ export default class UsersIndexController extends Controller {
acceptButtonHelpText: this.abilities.cannot(formPermission) ? this.intl.t('common.unauthorized') : null,
keepOpen: true,
formPermission,
allowEmailEdit: false,
user,
uploadNewPhoto: (file) => {
this.fetch.uploadFile.perform(
Expand Down Expand Up @@ -565,6 +573,21 @@ export default class UsersIndexController extends Controller {
});
}

/**
* Change email for a user
*
* @void
*/
@action changeUserEmail(user) {
this.modalsManager.show('modals/change-user-email', {
keepOpen: true,
user,
onEmailChangeComplete: () => {
return this.hostRouter.refresh();
},
});
}

/**
* Resends invite for a user to join.
*
Expand Down
1 change: 1 addition & 0 deletions app/components/modals/change-user-email.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '@fleetbase/iam-engine/components/modals/change-user-email';
11 changes: 3 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@fleetbase/iam-engine",
"version": "0.1.10",
"version": "0.1.11",
"description": "Fleetbase IAM extension provides identity and access management module for managing users, permissions and policies.",
"fleetbase": {
"route": "iam"
Expand Down Expand Up @@ -42,8 +42,8 @@
},
"dependencies": {
"@babel/core": "^7.23.2",
"@fleetbase/ember-core": "^0.3.22",
"@fleetbase/ember-ui": "^0.3.34",
"@fleetbase/ember-core": "^0.3.24",
"@fleetbase/ember-ui": "^0.3.41",
"@fortawesome/ember-fontawesome": "^2.0.0",
"@fortawesome/fontawesome-svg-core": "6.4.0",
"@fortawesome/free-brands-svg-icons": "6.4.0",
Expand Down Expand Up @@ -110,11 +110,6 @@
"ember-addon": {
"configPath": "tests/dummy/config"
},
"pnpm": {
"overrides": {
"broccoli-funnel": "3.0.8"
}
},
"prettier": {
"trailingComma": "es5",
"tabWidth": 4,
Expand Down
Loading
Loading