Merge pull request #314 from hashicorp/feature-notify-decorators

feat: 🎸 implement notifySuccess and notifyError decorators
This commit is contained in:
Susmitha Girumala authored and GitHub committed 2020-10-09 16:54:02 -04:00
commit d88531f255
27 files changed
+301 -377

No files matched your search

+1 -1
View File
@@ -17,7 +17,7 @@ export function confirm(confirmationTextKey) {
// If user confirmed, execute the decorated method
.then(() => method.apply(this, arguments))
// If the user denied, gracefully handle promise rejection with no-op
.catch(() => {});
.catch((e) => e);
};
}
}
+81
View File
@@ -0,0 +1,81 @@
import { getOwner } from '@ember/application';
/**
* Decorates a method and, if the method does not error, shows a success
* notification via the notify service. The text of the notification is derived
* from the argument `notification`, which may be either a string or a function
* that returns a string. This string may optionally be an intl key.
* @param {string|function} notification
*/
export function notifySuccess(notification) {
return function (_target, _propertyKey, desc) {
const method = desc.value;
desc.value = async function () {
const owner = getOwner(this);
const notifyService = owner.lookup('service:notify');
const intlService = owner.lookup('service:intl');
const candidateKey = (typeof notification === 'function')
? notification.apply(this, arguments)
: notification;
// As of now, we only use translated strings for notifications,
// but this code would support both translated and arbitrary strings.
// const text = intlService.exists(candidateKey)
// ? intlService.t(candidateKey)
// : candidateKey;
const text = intlService.t(candidateKey);
const value = await method.apply(this, arguments);
notifyService.success(text);
return value;
};
}
}
/**
* Decorates a method and, if the method errors, shows an error
* notification via the notify service. The text of the notification is derived
* from the argument `notification`, which may be either a string or a function
* that returns a string. This string may optionally be an intl key.
*
* If `options.catch` is `true`, any error occurring in the decorated method
* will be rethrown after notification. The default is to rethrow errors.
*
* @param {string|function} notification
* @param {object} options
* @param {object} options.catch - defaults to false
*/
export function notifyError(notification, options={ catch: false }) {
return function (_target, _propertyKey, desc) {
const method = desc.value;
desc.value = async function () {
const owner = getOwner(this);
const notifyService = owner.lookup('service:notify');
//const intlService = owner.lookup('service:intl');
try {
return await method.apply(this, arguments);
} catch (error) {
// As of now all error notifications pass a function, but this code
// could support either a function or a string.
// const candidateKey = (typeof notification === 'function')
// ? notification.apply(this, [error])
// : notification;
const candidateKey = notification.apply(this, [error]);
// As of now, we only use untranslated strings for error notifications,
// but this code would support both translated and arbitrary strings.
// const text = intlService.exists(candidateKey)
// ? intlService.t(candidateKey)
// : candidateKey;
const text = candidateKey;
notifyService.error(text, { closeAfter: null });
if (options.catch) {
// squelch the error
} else {
// rethrow the error
throw error;
}
}
};
}
}
+10 -13
View File
@@ -1,6 +1,7 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { notifySuccess, notifyError } from '../../decorators/notify';
/**
* The change password flow is associated only with password-type auth methods.
@@ -33,20 +34,16 @@ export default class AccountChangePasswordRoute extends Route {
* @param {string} newPassword
*/
@action
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.save-success')
async changePassword(account, currentPassword, newPassword) {
try {
await account.changePassword(currentPassword, newPassword);
// Transition to index after success. We ignore errors in the transition,
// since the index route is responsible for additional
// redirects depending on the authentication context. These additional
// redirects may abort this initial transition, resulting in a
// TransitionAborted error, which we do not want to show to the user.
await this.replaceWith('index').catch(() => {});
this.notify.success(this.intl.t('notifications.save-success'));
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
await account.changePassword(currentPassword, newPassword);
// Transition to index after success. We ignore errors in the transition,
// since the index route is responsible for additional
// redirects depending on the authentication context. These additional
// redirects may abort this initial transition, resulting in a
// TransitionAborted error, which we do not want to show to the user.
await this.replaceWith('index').catch(() => {});
}
/**
+14 -25
View File
@@ -3,6 +3,7 @@ import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import loading from 'ember-loading/decorator';
import { confirm } from '../../../decorators/confirm';
import { notifySuccess, notifyError } from '../../../decorators/notify';
export default class ScopesScopeAuthMethodsRoute extends Route {
// =services
@@ -47,23 +48,15 @@ export default class ScopesScopeAuthMethodsRoute extends Route {
*/
@action
@loading
@notifyError(({ message }) => message)
@notifySuccess(({ isNew }) => isNew ? 'notifications.create-success' : 'notifications.save-success')
async save(authMethod) {
const { isNew } = authMethod;
try {
await authMethod.save();
await this.transitionTo(
'scopes.scope.auth-methods.auth-method',
authMethod
);
this.refresh();
this.notify.success(
this.intl.t(isNew ? 'notifications.create-success' : 'notifications.save-success')
);
} catch (error) {
//TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
throw error;
}
await authMethod.save();
await this.transitionTo(
'scopes.scope.auth-methods.auth-method',
authMethod
);
this.refresh();
}
/**
@@ -73,15 +66,11 @@ export default class ScopesScopeAuthMethodsRoute extends Route {
@action
@loading
@confirm('questions.delete-confirm')
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.delete-success')
async delete(authMethod) {
try {
await authMethod.destroyRecord();
await this.replaceWith('scopes.scope.auth-methods');
this.refresh();
this.notify.success(this.intl.t('notifications.delete-success'));
} catch (error) {
//TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
await authMethod.destroyRecord();
await this.replaceWith('scopes.scope.auth-methods');
this.refresh();
}
}
@@ -3,6 +3,7 @@ import { action } from '@ember/object';
import { inject as service } from '@ember/service';
import loading from 'ember-loading/decorator';
import { confirm } from '../../../../../decorators/confirm';
import { notifySuccess, notifyError } from '../../../../../decorators/notify';
export default class ScopesScopeAuthMethodsAuthMethodAccountsRoute extends Route {
// =services
@@ -43,27 +44,20 @@ export default class ScopesScopeAuthMethodsAuthMethodAccountsRoute extends Route
*/
@action
@loading
@notifyError(({ message }) => message)
@notifySuccess(({ isNew }) => isNew ? 'notifications.create-success' : 'notifications.save-success')
async save(account, password) {
const { isNew } = account;
const adapterOptions = {};
if (isNew) {
adapterOptions.password = password;
}
try {
await account.save({ adapterOptions });
await this.transitionTo(
'scopes.scope.auth-methods.auth-method.accounts.account',
account
);
this.refresh();
this.notify.success(
this.intl.t(isNew ? 'notifications.create-success' : 'notifications.save-success')
);
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
throw error;
}
await account.save({ adapterOptions });
await this.transitionTo(
'scopes.scope.auth-methods.auth-method.accounts.account',
account
);
this.refresh();
}
/**
@@ -73,15 +67,11 @@ export default class ScopesScopeAuthMethodsAuthMethodAccountsRoute extends Route
@action
@loading
@confirm('questions.delete-confirm')
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.delete-success')
async deleteAccount(account) {
try {
await account.destroyRecord();
await this.replaceWith('scopes.scope.auth-methods.auth-method.accounts');
this.refresh();
this.notify.success(this.intl.t('notifications.delete-success'));
} catch (error) {
//TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
await account.destroyRecord();
await this.replaceWith('scopes.scope.auth-methods.auth-method.accounts');
this.refresh();
}
}
@@ -2,6 +2,7 @@ import Route from '@ember/routing/route';
import { action } from '@ember/object';
import { inject as service } from '@ember/service';
import loading from 'ember-loading/decorator';
import { notifySuccess, notifyError } from '../../../../../../../decorators/notify';
export default class ScopesScopeAuthMethodsAuthMethodAccountsAccountSettingsRoute extends Route {
// =services
@@ -35,16 +36,12 @@ export default class ScopesScopeAuthMethodsAuthMethodAccountsAccountSettingsRout
*/
@action
@loading
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.save-success')
async setPassword(account, password) {
try {
await account.setPassword(password);
await this.replaceWith(
'scopes.scope.auth-methods.auth-method.accounts.account.set-password'
);
this.notify.success(this.intl.t('notifications.save-success'));
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
await account.setPassword(password);
await this.replaceWith(
'scopes.scope.auth-methods.auth-method.accounts.account.set-password'
);
}
}
+11 -22
View File
@@ -3,6 +3,7 @@ import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import loading from 'ember-loading/decorator';
import { confirm } from '../../../decorators/confirm';
import { notifySuccess, notifyError } from '../../../decorators/notify';
export default class ScopesScopeGroupsRoute extends Route {
// =services
@@ -47,20 +48,12 @@ export default class ScopesScopeGroupsRoute extends Route {
*/
@action
@loading
@notifyError(({ message }) => message)
@notifySuccess(({ isNew }) => isNew ? 'notifications.create-success' : 'notifications.save-success')
async save(group) {
const { isNew } = group;
try {
await group.save();
await this.transitionTo('scopes.scope.groups.group', group);
this.refresh();
this.notify.success(
this.intl.t(isNew ? 'notifications.create-success' : 'notifications.save-success')
);
} catch (error) {
//TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
throw error;
}
await group.save();
await this.transitionTo('scopes.scope.groups.group', group);
this.refresh();
}
/**
@@ -70,15 +63,11 @@ export default class ScopesScopeGroupsRoute extends Route {
@action
@loading
@confirm('questions.delete-confirm')
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.delete-success')
async delete(group) {
try {
await group.destroyRecord();
await this.replaceWith('scopes.scope.groups');
this.refresh();
this.notify.success(this.intl.t('notifications.delete-success'));
} catch (error) {
//TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
await group.destroyRecord();
await this.replaceWith('scopes.scope.groups');
this.refresh();
}
}
@@ -3,6 +3,7 @@ import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { hash } from 'rsvp';
import loading from 'ember-loading/decorator';
import { notifySuccess, notifyError } from '../../../../../decorators/notify';
export default class ScopesScopeGroupsGroupAddMembersRoute extends Route {
// =services
@@ -65,15 +66,11 @@ export default class ScopesScopeGroupsGroupAddMembersRoute extends Route {
*/
@action
@loading
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.add-success')
async addMembers(group, userIDs) {
try {
await group.addMembers(userIDs);
await this.replaceWith('scopes.scope.groups.group.members');
this.notify.success(this.intl.t('notifications.add-success'));
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
await group.addMembers(userIDs);
await this.replaceWith('scopes.scope.groups.group.members');
}
/**
@@ -4,6 +4,7 @@ import { inject as service } from '@ember/service';
import { hash, all } from 'rsvp';
import loading from 'ember-loading/decorator';
import { confirm } from '../../../../../decorators/confirm';
import { notifySuccess, notifyError } from '../../../../../decorators/notify';
export default class ScopesScopeGroupsGroupMembersRoute extends Route {
// =services
@@ -40,14 +41,10 @@ export default class ScopesScopeGroupsGroupMembersRoute extends Route {
@action
@loading
@confirm('questions.remove-confirm')
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.remove-success')
async removeMember(group, member) {
try {
await group.removeMember(member.id);
this.refresh();
this.notify.success(this.intl.t('notifications.remove-success'));
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
await group.removeMember(member.id);
this.refresh();
}
}
+6 -12
View File
@@ -2,6 +2,7 @@ import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import loading from 'ember-loading/decorator';
import { notifySuccess, notifyError } from '../../../decorators/notify';
export default class ScopesScopeOrgsRoute extends Route {
// =services
@@ -49,18 +50,11 @@ export default class ScopesScopeOrgsRoute extends Route {
*/
@action
@loading
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.create-success')
async save(org) {
try {
await org.save();
await this.transitionTo('scopes.scope.projects', org);
this.refresh();
this.notify.success(
this.intl.t('notifications.create-success')
);
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
throw error;
}
await org.save();
await this.transitionTo('scopes.scope.projects', org);
this.refresh();
}
}
+11 -22
View File
@@ -3,6 +3,7 @@ import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import loading from 'ember-loading/decorator';
import { confirm } from '../../../decorators/confirm';
import { notifySuccess, notifyError } from '../../../decorators/notify';
export default class ScopesScopeProjectsRoute extends Route {
// =services
@@ -64,20 +65,12 @@ export default class ScopesScopeProjectsRoute extends Route {
*/
@action
@loading
@notifyError(({ message }) => message)
@notifySuccess(({ isNew }) => isNew ? 'notifications.create-success' : 'notifications.save-success')
async save(project) {
const { isNew } = project;
try {
await project.save();
await this.transitionTo('scopes.scope.projects.project', project);
this.refresh();
this.notify.success(
this.intl.t(isNew ? 'notifications.create-success' : 'notifications.save-success')
);
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
throw error;
}
await project.save();
await this.transitionTo('scopes.scope.projects.project', project);
this.refresh();
}
/**
@@ -87,15 +80,11 @@ export default class ScopesScopeProjectsRoute extends Route {
@action
@loading
@confirm('questions.delete-confirm')
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.delete-success')
async delete(project) {
try {
await project.destroyRecord();
await this.replaceWith('scopes.scope.projects');
this.refresh();
this.notify.success(this.intl.t('notifications.delete-success'));
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
await project.destroyRecord();
await this.replaceWith('scopes.scope.projects');
this.refresh();
}
}
@@ -3,6 +3,7 @@ import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import loading from 'ember-loading/decorator';
import { confirm } from '../../../../../decorators/confirm';
import { notifySuccess, notifyError } from '../../../../../decorators/notify';
export default class ScopesScopeProjectsProjectHostCatalogsRoute extends Route {
// =services
@@ -41,23 +42,15 @@ export default class ScopesScopeProjectsProjectHostCatalogsRoute extends Route {
*/
@action
@loading
@notifyError(({ message }) => message)
@notifySuccess(({ isNew }) => isNew ? 'notifications.create-success' : 'notifications.save-success')
async save(hostCatalog) {
const { isNew } = hostCatalog;
try {
await hostCatalog.save();
await this.transitionTo(
'scopes.scope.projects.project.host-catalogs.host-catalog',
hostCatalog
);
this.refresh();
this.notify.success(
this.intl.t(isNew ? 'notifications.create-success' : 'notifications.save-success')
);
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
throw error;
}
await hostCatalog.save();
await this.transitionTo(
'scopes.scope.projects.project.host-catalogs.host-catalog',
hostCatalog
);
this.refresh();
}
/**
@@ -67,15 +60,11 @@ export default class ScopesScopeProjectsProjectHostCatalogsRoute extends Route {
@action
@loading
@confirm('questions.delete-confirm')
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.delete-success')
async delete(hostCatalog) {
try {
await hostCatalog.destroyRecord();
await this.replaceWith('scopes.scope.projects.project.host-catalogs');
this.refresh();
this.notify.success(this.intl.t('notifications.delete-success'));
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
await hostCatalog.destroyRecord();
await this.replaceWith('scopes.scope.projects.project.host-catalogs');
this.refresh();
}
}
@@ -3,6 +3,7 @@ import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import loading from 'ember-loading/decorator';
import { confirm } from '../../../../../../../decorators/confirm';
import { notifySuccess, notifyError } from '../../../../../../../decorators/notify';
export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsRoute extends Route {
// =services
@@ -46,23 +47,15 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsRo
*/
@action
@loading
@notifyError(({ message }) => message)
@notifySuccess(({ isNew }) => isNew ? 'notifications.create-success' : 'notifications.save-success')
async save(hostSet) {
try {
const { isNew } = hostSet;
await hostSet.save();
await this.transitionTo(
'scopes.scope.projects.project.host-catalogs.host-catalog.host-sets.host-set',
hostSet
);
this.refresh();
this.notify.success(
this.intl.t(isNew ? 'notifications.create-success' : 'notifications.save-success')
);
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
throw error;
}
await hostSet.save();
await this.transitionTo(
'scopes.scope.projects.project.host-catalogs.host-catalog.host-sets.host-set',
hostSet
);
this.refresh();
}
/**
@@ -72,16 +65,12 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsRo
@action
@loading
@confirm('questions.delete-confirm')
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.delete-success')
async deleteHostSet(hostSet) {
try {
await hostSet.destroyRecord();
await this.replaceWith(
'scopes.scope.projects.project.host-catalogs.host-catalog.host-sets'
);
this.notify.success(this.intl.t('notifications.delete-success'));
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
await hostSet.destroyRecord();
await this.replaceWith(
'scopes.scope.projects.project.host-catalogs.host-catalog.host-sets'
);
}
}
@@ -3,6 +3,7 @@ import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { hash } from 'rsvp';
import loading from 'ember-loading/decorator';
import { notifySuccess, notifyError } from '../../../../../../../../../decorators/notify';
export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsHostSetAddHostsRoute extends Route {
// =services
@@ -70,17 +71,13 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsHo
*/
@action
@loading
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.add-success')
async addHosts(hostSet, hostIDs) {
try {
await hostSet.addHosts(hostIDs);
await this.replaceWith(
'scopes.scope.projects.project.host-catalogs.host-catalog.host-sets.host-set.hosts'
);
this.notify.success(this.intl.t('notifications.add-success'));
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
await hostSet.addHosts(hostIDs);
await this.replaceWith(
'scopes.scope.projects.project.host-catalogs.host-catalog.host-sets.host-set.hosts'
);
}
/**
@@ -4,6 +4,7 @@ import { action } from '@ember/object';
import { inject as service } from '@ember/service';
import loading from 'ember-loading/decorator';
import { confirm } from '../../../../../../../../../decorators/confirm';
import { notifySuccess, notifyError } from '../../../../../../../../../decorators/notify';
export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsHostSetHostsRoute extends Route {
// =services
@@ -39,20 +40,16 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsHo
@action
@loading
@confirm('questions.remove-confirm')
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.remove-success')
async removeHost(hostSet, host) {
try {
const scopeID = this.modelFor('scopes.scope.projects.project').id;
const hostCatalogID = this.modelFor(
'scopes.scope.projects.project.host-catalogs.host-catalog'
).id;
await hostSet.removeHost(host.id, {
adapterOptions: { scopeID, hostCatalogID },
});
this.refresh();
this.notify.success(this.intl.t('notifications.remove-success'));
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
const scopeID = this.modelFor('scopes.scope.projects.project').id;
const hostCatalogID = this.modelFor(
'scopes.scope.projects.project.host-catalogs.host-catalog'
).id;
await hostSet.removeHost(host.id, {
adapterOptions: { scopeID, hostCatalogID },
});
this.refresh();
}
}
@@ -3,6 +3,7 @@ import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import loading from 'ember-loading/decorator';
import { confirm } from '../../../../../../../decorators/confirm';
import { notifySuccess, notifyError } from '../../../../../../../decorators/notify';
export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostsRoute extends Route {
// =services
@@ -46,23 +47,15 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostsRoute
*/
@action
@loading
@notifyError(({ message }) => message)
@notifySuccess(({ isNew }) => isNew ? 'notifications.create-success' : 'notifications.save-success')
async save(host) {
try {
const { isNew } = host;
await host.save();
await this.transitionTo(
'scopes.scope.projects.project.host-catalogs.host-catalog.hosts.host',
host
);
this.refresh();
this.notify.success(
this.intl.t(isNew ? 'notifications.create-success' : 'notifications.save-success')
);
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
throw error;
}
await host.save();
await this.transitionTo(
'scopes.scope.projects.project.host-catalogs.host-catalog.hosts.host',
host
);
this.refresh();
}
/**
@@ -72,17 +65,13 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostsRoute
@action
@loading
@confirm('questions.delete-confirm')
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.delete-success')
async deleteHost(host) {
try {
await host.destroyRecord();
await this.replaceWith(
'scopes.scope.projects.project.host-catalogs.host-catalog.hosts'
);
this.refresh();
this.notify.success(this.intl.t('notifications.delete-success'));
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
await host.destroyRecord();
await this.replaceWith(
'scopes.scope.projects.project.host-catalogs.host-catalog.hosts'
);
this.refresh();
}
}
@@ -4,6 +4,7 @@ import { action } from '@ember/object';
import { all, hash } from 'rsvp';
import { task, timeout } from 'ember-concurrency';
import { A } from '@ember/array';
import { notifySuccess, notifyError } from '../../../../../decorators/notify';
import config from '../../../../../config/environment';
const POLL_TIMEOUT_SECONDS = config.sessionPollingTimeoutSeconds;
@@ -93,14 +94,10 @@ export default class ScopesScopeProjectsProjectSessionsRoute extends Route {
* @param {SessionModel}
*/
@action
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.canceled-success')
async cancelSession(session) {
try {
await session.cancelSession();
this.notify.success(this.intl.t('notifications.canceled-success'));
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
await session.cancelSession();
}
}
@@ -3,6 +3,7 @@ import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import loading from 'ember-loading/decorator';
import { confirm } from '../../../../../decorators/confirm';
import { notifySuccess, notifyError } from '../../../../../decorators/notify';
export default class ScopesScopeProjectsProjectTargetsRoute extends Route {
// =services
@@ -41,20 +42,12 @@ export default class ScopesScopeProjectsProjectTargetsRoute extends Route {
*/
@action
@loading
@notifyError(({ message }) => message)
@notifySuccess(({ isNew }) => isNew ? 'notifications.create-success' : 'notifications.save-success')
async save(target) {
const { isNew } = target;
try {
await target.save();
await this.transitionTo('scopes.scope.projects.project.targets.target', target);
this.refresh();
this.notify.success(
this.intl.t(isNew ? 'notifications.create-success' : 'notifications.save-success')
);
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
throw error;
}
await target.save();
await this.transitionTo('scopes.scope.projects.project.targets.target', target);
this.refresh();
}
/**
@@ -64,15 +57,11 @@ export default class ScopesScopeProjectsProjectTargetsRoute extends Route {
@action
@loading
@confirm('questions.delete-confirm')
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.delete-success')
async delete(target) {
try {
await target.destroyRecord();
await this.replaceWith('scopes.scope.projects.project.targets');
this.refresh();
this.notify.success(this.intl.t('notifications.delete-success'));
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
await target.destroyRecord();
await this.replaceWith('scopes.scope.projects.project.targets');
this.refresh();
}
}
@@ -3,6 +3,7 @@ import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { all } from 'rsvp';
import loading from 'ember-loading/decorator';
import { notifySuccess, notifyError } from '../../../../../../../decorators/notify';
export default class ScopesScopeProjectsProjectTargetsTargetAddHostSetsRoute extends Route {
// =services
@@ -72,17 +73,13 @@ export default class ScopesScopeProjectsProjectTargetsTargetAddHostSetsRoute ext
@action
@loading
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.add-success')
async save(target, hostSetIDs) {
try {
await target.addHostSets(hostSetIDs);
this.replaceWith(
'scopes.scope.projects.project.targets.target.host-sets'
);
this.notify.success(this.intl.t('notifications.add-success'));
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
await target.addHostSets(hostSetIDs);
this.replaceWith(
'scopes.scope.projects.project.targets.target.host-sets'
);
}
/**
@@ -4,6 +4,7 @@ import { action } from '@ember/object';
import { inject as service } from '@ember/service';
import loading from 'ember-loading/decorator';
import { confirm } from '../../../../../../../decorators/confirm';
import { notifySuccess, notifyError } from '../../../../../../../decorators/notify';
export default class ScopesScopeProjectsProjectTargetsTargetHostSetsRoute extends Route {
// =services
@@ -57,14 +58,10 @@ export default class ScopesScopeProjectsProjectTargetsTargetHostSetsRoute extend
@action
@loading
@confirm('questions.remove-confirm')
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.remove-success')
async removeHostSet(target, hostSet) {
try {
await target.removeHostSet(hostSet.id);
this.refresh();
this.notify.success(this.intl.t('notifications.remove-success'));
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
await target.removeHostSet(hostSet.id);
this.refresh();
}
}
+11 -22
View File
@@ -3,6 +3,7 @@ import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import loading from 'ember-loading/decorator';
import { confirm } from '../../../decorators/confirm';
import { notifySuccess, notifyError } from '../../../decorators/notify';
export default class ScopesScopeRolesRoute extends Route {
// =services
@@ -47,20 +48,12 @@ export default class ScopesScopeRolesRoute extends Route {
*/
@action
@loading
@notifyError(({ message }) => message)
@notifySuccess(({ isNew }) => isNew ? 'notifications.create-success' : 'notifications.save-success')
async save(role) {
const { isNew } = role;
try {
await role.save();
await this.transitionTo('scopes.scope.roles.role', role);
this.refresh();
this.notify.success(
this.intl.t(isNew ? 'notifications.create-success' : 'notifications.save-success')
);
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
throw error;
}
await role.save();
await this.transitionTo('scopes.scope.roles.role', role);
this.refresh();
}
/**
@@ -70,15 +63,11 @@ export default class ScopesScopeRolesRoute extends Route {
@action
@loading
@confirm('questions.delete-confirm')
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.delete-success')
async delete(role) {
try {
await role.destroyRecord();
await this.replaceWith('scopes.scope.roles');
this.refresh();
this.notify.success(this.intl.t('notifications.delete-success'));
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
await role.destroyRecord();
await this.replaceWith('scopes.scope.roles');
this.refresh();
}
}
@@ -3,6 +3,7 @@ import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { hash } from 'rsvp';
import loading from 'ember-loading/decorator';
import { notifySuccess, notifyError } from '../../../../../decorators/notify';
export default class ScopesScopeRolesRoleAddPrincipalsRoute extends Route {
// =services
@@ -59,15 +60,11 @@ export default class ScopesScopeRolesRoleAddPrincipalsRoute extends Route {
*/
@action
@loading
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.add-success')
async addPrincipals(role, principalIDs) {
try {
await role.addPrincipals(principalIDs);
this.replaceWith('scopes.scope.roles.role.principals');
this.notify.success(this.intl.t('notifications.add-success'));
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
await role.addPrincipals(principalIDs);
this.replaceWith('scopes.scope.roles.role.principals');
}
/**
@@ -2,6 +2,7 @@ import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import loading from 'ember-loading/decorator';
import { notifySuccess, notifyError } from '../../../../../decorators/notify';
export default class ScopesScopeRolesRoleGrantsRoute extends Route {
// =services
@@ -56,13 +57,9 @@ export default class ScopesScopeRolesRoleGrantsRoute extends Route {
*/
@action
@loading
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.save-success')
async save(role) {
try {
await role.saveGrants();
this.notify.success(this.intl.t('notifications.save-success'));
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
}
}
@@ -4,6 +4,7 @@ import { action } from '@ember/object';
import { inject as service } from '@ember/service';
import loading from 'ember-loading/decorator';
import { confirm } from '../../../../../decorators/confirm';
import { notifySuccess, notifyError } from '../../../../../decorators/notify';
export default class ScopesScopeRolesRolePrincipalsRoute extends Route {
// =services
@@ -67,16 +68,12 @@ export default class ScopesScopeRolesRolePrincipalsRoute extends Route {
@action
@loading
@confirm('questions.remove-confirm')
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.remove-success')
async removePrincipal(principal) {
try {
const role = this.modelFor('scopes.scope.roles.role');
await role.removePrincipal(principal.id);
this.refresh();
this.notify.success(this.intl.t('notifications.remove-success'));
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
const role = this.modelFor('scopes.scope.roles.role');
await role.removePrincipal(principal.id);
this.refresh();
}
}
+11 -22
View File
@@ -3,6 +3,7 @@ import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import loading from 'ember-loading/decorator';
import { confirm } from '../../../decorators/confirm';
import { notifySuccess, notifyError } from '../../../decorators/notify';
export default class ScopesScopeUsersRoute extends Route {
// =services
@@ -48,20 +49,12 @@ export default class ScopesScopeUsersRoute extends Route {
*/
@action
@loading
@notifyError(({ message }) => message)
@notifySuccess(({ isNew }) => isNew ? 'notifications.create-success' : 'notifications.save-success')
async save(user) {
const { isNew } = user;
try {
await user.save();
await this.transitionTo('scopes.scope.users.user', user);
this.refresh();
this.notify.success(
this.intl.t(isNew ? 'notifications.create-success' : 'notifications.save-success')
);
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
throw error;
}
await user.save();
await this.transitionTo('scopes.scope.users.user', user);
this.refresh();
}
/**
@@ -71,15 +64,11 @@ export default class ScopesScopeUsersRoute extends Route {
@action
@loading
@confirm('questions.delete-confirm')
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.delete-success')
async delete(user) {
try {
await user.destroyRecord();
await this.replaceWith('scopes.scope.users');
this.refresh();
this.notify.success(this.intl.t('notifications.delete-success'));
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
await user.destroyRecord();
await this.replaceWith('scopes.scope.users');
this.refresh();
}
}
@@ -3,6 +3,7 @@ import { action } from '@ember/object';
import { inject as service } from '@ember/service';
import { hash, all } from 'rsvp';
import loading from 'ember-loading/decorator';
import { notifySuccess, notifyError } from '../../../../../decorators/notify';
export default class ScopesScopeUsersUserAccountsRoute extends Route {
// =services
@@ -38,14 +39,10 @@ export default class ScopesScopeUsersUserAccountsRoute extends Route {
*/
@action
@loading
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.remove-success')
async removeAccount(user, account) {
try {
await user.removeAccount(account.id);
await this.refresh();
this.notify.success(this.intl.t('notifications.remove-success'));
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
await user.removeAccount(account.id);
await this.refresh();
}
}
@@ -3,6 +3,7 @@ import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { all } from 'rsvp';
import loading from 'ember-loading/decorator';
import { notifySuccess, notifyError } from '../../../../../decorators/notify';
export default class ScopesScopeUsersUserAddAccountsRoute extends Route {
// =services
@@ -69,15 +70,11 @@ export default class ScopesScopeUsersUserAddAccountsRoute extends Route {
*/
@action
@loading
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.add-success')
async addAccounts(user, accountIDs) {
try {
await user.addAccounts(accountIDs);
await this.replaceWith('scopes.scope.users.user.accounts');
this.notify.success(this.intl.t('notifications.add-success'));
} catch (error) {
// TODO: replace with translated strings
this.notify.error(error.message, { closeAfter: null });
}
await user.addAccounts(accountIDs);
await this.replaceWith('scopes.scope.users.user.accounts');
}
/**