From f1ebeaf23e99415b0c923660e25965a276c547cf Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Wed, 7 Oct 2020 15:42:43 -0400 Subject: [PATCH 01/11] update readme to reflect github flow process --- README.md | 35 +---------------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/README.md b/README.md index ee90261dc..b9dbc642f 100644 --- a/README.md +++ b/README.md @@ -68,39 +68,7 @@ List of available project commands. `yarn run ` ### Branching -We follow [A Successful Git Branching Model][nvie-git], otherwise known as -Gitflow. Branches `main` and `develop` are sacred mainlines into which we do -not commit directly. Instead, these branches have special meaning defining what -code may be found within. The `develop` branch contains code _for the next -release_. Code in `main` is _released, tagged, and ready for -production deployment_. - -To start contributing: -1. Start a new **topic branch** off `develop`. -2. Commit work. -3. When work is complete, create a PR from the topic branch into `develop`. -4. Code review and automated checks occur. If checks fail or changes are - requested, commit more work. Rinse and repeat until all checks pass and no - changes are requested. -5. A core team member may merge the PR into `develop`. At this point, the code - is unreleased but considered "releasable". -6. **Releasing**: when it's time to release, create a PR from `develop` into - `main` (we skip Gitflow's `release` branch). This is tantamount to - requesting a new release (version) of the product. Ensure the body of the PR - includes well-documented changes slated for release. -7. Code review and automated checks occur. -8. A core team member may merge the PR into `main` to initiate a release. -9. Tag the merge commit in `main` with version number of the release and cut - a release in GitHub. - -While Gitflow may seem heavy, most of its process can be automated. Gitflow is -similar to its lighter-weight sibling [GitHub Flow][github-flow]. In essence, -Gitflow differs only by adding an second mainline branch (`main`) that is -designated as _always containing production code_. Another happy characteristic -of Gitflow is that it's easy to track the project's release history, since -_every commit to `main` is a release by definition_. The well-defined nature -of releases assists in cross-team collaboration, ensuring everyone has -confidence about the state of the project. +We follow [GitHub Flow][github-flow]. ### Building ToC @@ -150,5 +118,4 @@ in `package.json` _as long as it is not a GPL variant or UNLICENSED_. The change will be verified upon PR. GPL variants and UNLICENSED dependencies will not be accepted. -[nvie-git]: https://nvie.com/posts/a-successful-git-branching-model/ [github-flow]: https://guides.github.com/introduction/flow/ From 0c1aee7381e70fe1eb51b3fe5f35a2bafd4224c7 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Wed, 7 Oct 2020 17:03:15 -0400 Subject: [PATCH 02/11] =?UTF-8?q?chore:=20=F0=9F=A4=96=20rename=20utilitie?= =?UTF-8?q?s/=20to=20decorators/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/core/app/{utilities => decorators}/confirm.js | 0 ui/core/app/routes/scopes/scope/auth-methods.js | 2 +- .../routes/scopes/scope/auth-methods/auth-method/accounts.js | 2 +- ui/core/app/routes/scopes/scope/groups.js | 2 +- ui/core/app/routes/scopes/scope/groups/group/members.js | 2 +- ui/core/app/routes/scopes/scope/projects.js | 2 +- .../app/routes/scopes/scope/projects/project/host-catalogs.js | 2 +- .../projects/project/host-catalogs/host-catalog/host-sets.js | 2 +- .../host-catalogs/host-catalog/host-sets/host-set/hosts.js | 2 +- .../scope/projects/project/host-catalogs/host-catalog/hosts.js | 2 +- ui/core/app/routes/scopes/scope/projects/project/targets.js | 2 +- .../scopes/scope/projects/project/targets/target/host-sets.js | 2 +- ui/core/app/routes/scopes/scope/roles.js | 2 +- ui/core/app/routes/scopes/scope/roles/role/principals.js | 2 +- ui/core/app/routes/scopes/scope/users.js | 2 +- 15 files changed, 14 insertions(+), 14 deletions(-) rename ui/core/app/{utilities => decorators}/confirm.js (100%) diff --git a/ui/core/app/utilities/confirm.js b/ui/core/app/decorators/confirm.js similarity index 100% rename from ui/core/app/utilities/confirm.js rename to ui/core/app/decorators/confirm.js diff --git a/ui/core/app/routes/scopes/scope/auth-methods.js b/ui/core/app/routes/scopes/scope/auth-methods.js index 0b4072276..c91387c71 100644 --- a/ui/core/app/routes/scopes/scope/auth-methods.js +++ b/ui/core/app/routes/scopes/scope/auth-methods.js @@ -2,7 +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 { confirm } from '../../../utilities/confirm'; +import { confirm } from '../../../decorators/confirm'; export default class ScopesScopeAuthMethodsRoute extends Route { // =services diff --git a/ui/core/app/routes/scopes/scope/auth-methods/auth-method/accounts.js b/ui/core/app/routes/scopes/scope/auth-methods/auth-method/accounts.js index 306acb0b8..93cbefd58 100644 --- a/ui/core/app/routes/scopes/scope/auth-methods/auth-method/accounts.js +++ b/ui/core/app/routes/scopes/scope/auth-methods/auth-method/accounts.js @@ -2,7 +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 { confirm } from '../../../../../utilities/confirm'; +import { confirm } from '../../../../../decorators/confirm'; export default class ScopesScopeAuthMethodsAuthMethodAccountsRoute extends Route { // =services diff --git a/ui/core/app/routes/scopes/scope/groups.js b/ui/core/app/routes/scopes/scope/groups.js index 26b5a3f61..1d04d7bb5 100644 --- a/ui/core/app/routes/scopes/scope/groups.js +++ b/ui/core/app/routes/scopes/scope/groups.js @@ -2,7 +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 { confirm } from '../../../utilities/confirm'; +import { confirm } from '../../../decorators/confirm'; export default class ScopesScopeGroupsRoute extends Route { // =services diff --git a/ui/core/app/routes/scopes/scope/groups/group/members.js b/ui/core/app/routes/scopes/scope/groups/group/members.js index c7f6d52ff..4cf76322c 100644 --- a/ui/core/app/routes/scopes/scope/groups/group/members.js +++ b/ui/core/app/routes/scopes/scope/groups/group/members.js @@ -3,7 +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 { confirm } from '../../../../../utilities/confirm'; +import { confirm } from '../../../../../decorators/confirm'; export default class ScopesScopeGroupsGroupMembersRoute extends Route { // =services diff --git a/ui/core/app/routes/scopes/scope/projects.js b/ui/core/app/routes/scopes/scope/projects.js index 77f57f12d..c28b137a0 100644 --- a/ui/core/app/routes/scopes/scope/projects.js +++ b/ui/core/app/routes/scopes/scope/projects.js @@ -2,7 +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 { confirm } from '../../../utilities/confirm'; +import { confirm } from '../../../decorators/confirm'; export default class ScopesScopeProjectsRoute extends Route { // =services diff --git a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs.js b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs.js index 28058850f..c8fce1129 100644 --- a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs.js +++ b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs.js @@ -2,7 +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 { confirm } from '../../../../../utilities/confirm'; +import { confirm } from '../../../../../decorators/confirm'; export default class ScopesScopeProjectsProjectHostCatalogsRoute extends Route { // =services diff --git a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets.js b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets.js index 3591b4a4b..3c003bd50 100644 --- a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets.js +++ b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets.js @@ -2,7 +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 { confirm } from '../../../../../../../utilities/confirm'; +import { confirm } from '../../../../../../../decorators/confirm'; export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsRoute extends Route { // =services diff --git a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/host-set/hosts.js b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/host-set/hosts.js index de4743209..a4476caf1 100644 --- a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/host-set/hosts.js +++ b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/host-set/hosts.js @@ -3,7 +3,7 @@ import { hash, all } from 'rsvp'; import { action } from '@ember/object'; import { inject as service } from '@ember/service'; import loading from 'ember-loading/decorator'; -import { confirm } from '../../../../../../../../../utilities/confirm'; +import { confirm } from '../../../../../../../../../decorators/confirm'; export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostSetsHostSetHostsRoute extends Route { // =services diff --git a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts.js b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts.js index 42dd70019..86b7e1c75 100644 --- a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts.js +++ b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts.js @@ -2,7 +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 { confirm } from '../../../../../../../utilities/confirm'; +import { confirm } from '../../../../../../../decorators/confirm'; export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogHostsRoute extends Route { // =services diff --git a/ui/core/app/routes/scopes/scope/projects/project/targets.js b/ui/core/app/routes/scopes/scope/projects/project/targets.js index 64f254467..b2670942c 100644 --- a/ui/core/app/routes/scopes/scope/projects/project/targets.js +++ b/ui/core/app/routes/scopes/scope/projects/project/targets.js @@ -2,7 +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 { confirm } from '../../../../../utilities/confirm'; +import { confirm } from '../../../../../decorators/confirm'; export default class ScopesScopeProjectsProjectTargetsRoute extends Route { // =services diff --git a/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js b/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js index c87abdf0a..dd9e52f0e 100644 --- a/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js +++ b/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js @@ -3,7 +3,7 @@ import { all, hash } from 'rsvp'; import { action } from '@ember/object'; import { inject as service } from '@ember/service'; import loading from 'ember-loading/decorator'; -import { confirm } from '../../../../../../../utilities/confirm'; +import { confirm } from '../../../../../../../decorators/confirm'; export default class ScopesScopeProjectsProjectTargetsTargetHostSetsRoute extends Route { // =services diff --git a/ui/core/app/routes/scopes/scope/roles.js b/ui/core/app/routes/scopes/scope/roles.js index b7eb93adc..99cf3061c 100644 --- a/ui/core/app/routes/scopes/scope/roles.js +++ b/ui/core/app/routes/scopes/scope/roles.js @@ -2,7 +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 { confirm } from '../../../utilities/confirm'; +import { confirm } from '../../../decorators/confirm'; export default class ScopesScopeRolesRoute extends Route { // =services diff --git a/ui/core/app/routes/scopes/scope/roles/role/principals.js b/ui/core/app/routes/scopes/scope/roles/role/principals.js index 8fde07b08..dc6b27677 100644 --- a/ui/core/app/routes/scopes/scope/roles/role/principals.js +++ b/ui/core/app/routes/scopes/scope/roles/role/principals.js @@ -3,7 +3,7 @@ import { all, hash } from 'rsvp'; import { action } from '@ember/object'; import { inject as service } from '@ember/service'; import loading from 'ember-loading/decorator'; -import { confirm } from '../../../../../utilities/confirm'; +import { confirm } from '../../../../../decorators/confirm'; export default class ScopesScopeRolesRolePrincipalsRoute extends Route { // =services diff --git a/ui/core/app/routes/scopes/scope/users.js b/ui/core/app/routes/scopes/scope/users.js index 5628a5179..5cb1f0d4e 100644 --- a/ui/core/app/routes/scopes/scope/users.js +++ b/ui/core/app/routes/scopes/scope/users.js @@ -2,7 +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 { confirm } from '../../../utilities/confirm'; +import { confirm } from '../../../decorators/confirm'; export default class ScopesScopeUsersRoute extends Route { // =services From 7758099ca408bd7f090c89c511848eb868c34e82 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Wed, 7 Oct 2020 18:02:14 -0400 Subject: [PATCH 03/11] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20implement=20notify?= =?UTF-8?q?Success=20and=20notifyError=20decorators?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit and apply initially to projects route to simplify persistence methods --- ui/core/app/decorators/confirm.js | 2 +- ui/core/app/decorators/notify.js | 81 +++++++++++++++++++++ ui/core/app/routes/scopes/scope/projects.js | 33 +++------ 3 files changed, 93 insertions(+), 23 deletions(-) create mode 100644 ui/core/app/decorators/notify.js diff --git a/ui/core/app/decorators/confirm.js b/ui/core/app/decorators/confirm.js index 755ff2f59..49db19c97 100644 --- a/ui/core/app/decorators/confirm.js +++ b/ui/core/app/decorators/confirm.js @@ -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); }; } } diff --git a/ui/core/app/decorators/notify.js b/ui/core/app/decorators/notify.js new file mode 100644 index 000000000..7232dfffd --- /dev/null +++ b/ui/core/app/decorators/notify.js @@ -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; + } + } + }; + } +} diff --git a/ui/core/app/routes/scopes/scope/projects.js b/ui/core/app/routes/scopes/scope/projects.js index c28b137a0..7a43e0e71 100644 --- a/ui/core/app/routes/scopes/scope/projects.js +++ b/ui/core/app/routes/scopes/scope/projects.js @@ -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(); } } From 82ed8cb70364cb8e9802197c981a3d1dae1c5a55 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Thu, 8 Oct 2020 16:37:53 -0400 Subject: [PATCH 04/11] feat: Update users route to use notify decorators --- ui/core/app/routes/scopes/scope/users.js | 33 ++++++++---------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/ui/core/app/routes/scopes/scope/users.js b/ui/core/app/routes/scopes/scope/users.js index 5cb1f0d4e..d65f2d35f 100644 --- a/ui/core/app/routes/scopes/scope/users.js +++ b/ui/core/app/routes/scopes/scope/users.js @@ -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(); } } From 30a64d9e3f6dc59478188efdd6b4e7b0d7875cb4 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Thu, 8 Oct 2020 17:24:20 -0400 Subject: [PATCH 05/11] feat: Update user account routes to use notify decorator --- .../app/routes/scopes/scope/users/user/accounts.js | 13 +++++-------- .../routes/scopes/scope/users/user/add-accounts.js | 13 +++++-------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/ui/core/app/routes/scopes/scope/users/user/accounts.js b/ui/core/app/routes/scopes/scope/users/user/accounts.js index cb00ca24e..4408bdd5c 100644 --- a/ui/core/app/routes/scopes/scope/users/user/accounts.js +++ b/ui/core/app/routes/scopes/scope/users/user/accounts.js @@ -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(); } } diff --git a/ui/core/app/routes/scopes/scope/users/user/add-accounts.js b/ui/core/app/routes/scopes/scope/users/user/add-accounts.js index bdb7b0e9c..3a1e22f4e 100644 --- a/ui/core/app/routes/scopes/scope/users/user/add-accounts.js +++ b/ui/core/app/routes/scopes/scope/users/user/add-accounts.js @@ -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'); } /** From 870dc788a4d9a644b803113a6fcbbcf2428bfdf9 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Thu, 8 Oct 2020 17:45:28 -0400 Subject: [PATCH 06/11] feat: Update roles routes for notify decorator --- ui/core/app/routes/scopes/scope/roles.js | 33 +++++++------------ .../scopes/scope/roles/role/add-principals.js | 13 +++----- .../routes/scopes/scope/roles/role/grants.js | 9 ++--- .../scopes/scope/roles/role/principals.js | 15 ++++----- 4 files changed, 25 insertions(+), 45 deletions(-) diff --git a/ui/core/app/routes/scopes/scope/roles.js b/ui/core/app/routes/scopes/scope/roles.js index 99cf3061c..fd6991171 100644 --- a/ui/core/app/routes/scopes/scope/roles.js +++ b/ui/core/app/routes/scopes/scope/roles.js @@ -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(); } } diff --git a/ui/core/app/routes/scopes/scope/roles/role/add-principals.js b/ui/core/app/routes/scopes/scope/roles/role/add-principals.js index 6d0bb1d46..861ceb1c5 100644 --- a/ui/core/app/routes/scopes/scope/roles/role/add-principals.js +++ b/ui/core/app/routes/scopes/scope/roles/role/add-principals.js @@ -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'); } /** diff --git a/ui/core/app/routes/scopes/scope/roles/role/grants.js b/ui/core/app/routes/scopes/scope/roles/role/grants.js index d09901515..af56f1990 100644 --- a/ui/core/app/routes/scopes/scope/roles/role/grants.js +++ b/ui/core/app/routes/scopes/scope/roles/role/grants.js @@ -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 }); - } } } diff --git a/ui/core/app/routes/scopes/scope/roles/role/principals.js b/ui/core/app/routes/scopes/scope/roles/role/principals.js index dc6b27677..1bc8e3969 100644 --- a/ui/core/app/routes/scopes/scope/roles/role/principals.js +++ b/ui/core/app/routes/scopes/scope/roles/role/principals.js @@ -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(); } } From 07151862cd13a361adf337f81cdcea29811d259d Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Thu, 8 Oct 2020 18:01:27 -0400 Subject: [PATCH 07/11] feat: Update groups route for notify decorator --- ui/core/app/routes/scopes/scope/groups.js | 33 +++++++------------ .../scopes/scope/groups/group/add-members.js | 13 +++----- .../scopes/scope/groups/group/members.js | 13 +++----- 3 files changed, 21 insertions(+), 38 deletions(-) diff --git a/ui/core/app/routes/scopes/scope/groups.js b/ui/core/app/routes/scopes/scope/groups.js index 1d04d7bb5..38085bfc7 100644 --- a/ui/core/app/routes/scopes/scope/groups.js +++ b/ui/core/app/routes/scopes/scope/groups.js @@ -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(); } } diff --git a/ui/core/app/routes/scopes/scope/groups/group/add-members.js b/ui/core/app/routes/scopes/scope/groups/group/add-members.js index 240e0a442..d4f392684 100644 --- a/ui/core/app/routes/scopes/scope/groups/group/add-members.js +++ b/ui/core/app/routes/scopes/scope/groups/group/add-members.js @@ -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'); } /** diff --git a/ui/core/app/routes/scopes/scope/groups/group/members.js b/ui/core/app/routes/scopes/scope/groups/group/members.js index 4cf76322c..be4f97343 100644 --- a/ui/core/app/routes/scopes/scope/groups/group/members.js +++ b/ui/core/app/routes/scopes/scope/groups/group/members.js @@ -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(); } } From 0ef7be5e5854f9b29f0e4e042e0a0e7fdc74b5a3 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Thu, 8 Oct 2020 18:11:48 -0400 Subject: [PATCH 08/11] feat: Update auth method route for notify decorator --- .../app/routes/scopes/scope/auth-methods.js | 39 +++++++------------ .../auth-methods/auth-method/accounts.js | 38 +++++++----------- .../accounts/account/set-password.js | 17 ++++---- 3 files changed, 35 insertions(+), 59 deletions(-) diff --git a/ui/core/app/routes/scopes/scope/auth-methods.js b/ui/core/app/routes/scopes/scope/auth-methods.js index c91387c71..020ed8b9f 100644 --- a/ui/core/app/routes/scopes/scope/auth-methods.js +++ b/ui/core/app/routes/scopes/scope/auth-methods.js @@ -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(); } } diff --git a/ui/core/app/routes/scopes/scope/auth-methods/auth-method/accounts.js b/ui/core/app/routes/scopes/scope/auth-methods/auth-method/accounts.js index 93cbefd58..94871fd6f 100644 --- a/ui/core/app/routes/scopes/scope/auth-methods/auth-method/accounts.js +++ b/ui/core/app/routes/scopes/scope/auth-methods/auth-method/accounts.js @@ -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(); } } diff --git a/ui/core/app/routes/scopes/scope/auth-methods/auth-method/accounts/account/set-password.js b/ui/core/app/routes/scopes/scope/auth-methods/auth-method/accounts/account/set-password.js index 900c5eaba..2f5886030 100644 --- a/ui/core/app/routes/scopes/scope/auth-methods/auth-method/accounts/account/set-password.js +++ b/ui/core/app/routes/scopes/scope/auth-methods/auth-method/accounts/account/set-password.js @@ -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' + ); } } From 0684571564d51492cccf531cd5217d501bc96ff6 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Thu, 8 Oct 2020 18:25:54 -0400 Subject: [PATCH 09/11] feat: Update target routes for notify decorator --- .../scopes/scope/projects/project/targets.js | 33 +++++++------------ .../project/targets/target/add-host-sets.js | 17 ++++------ .../project/targets/target/host-sets.js | 13 +++----- 3 files changed, 23 insertions(+), 40 deletions(-) diff --git a/ui/core/app/routes/scopes/scope/projects/project/targets.js b/ui/core/app/routes/scopes/scope/projects/project/targets.js index b2670942c..68e0b98d0 100644 --- a/ui/core/app/routes/scopes/scope/projects/project/targets.js +++ b/ui/core/app/routes/scopes/scope/projects/project/targets.js @@ -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(); } } diff --git a/ui/core/app/routes/scopes/scope/projects/project/targets/target/add-host-sets.js b/ui/core/app/routes/scopes/scope/projects/project/targets/target/add-host-sets.js index 5736ae317..b747fda00 100644 --- a/ui/core/app/routes/scopes/scope/projects/project/targets/target/add-host-sets.js +++ b/ui/core/app/routes/scopes/scope/projects/project/targets/target/add-host-sets.js @@ -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' + ); } /** diff --git a/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js b/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js index dd9e52f0e..08d839f1f 100644 --- a/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js +++ b/ui/core/app/routes/scopes/scope/projects/project/targets/target/host-sets.js @@ -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(); } } From ec72a17512529e99f8b18d523c723bfc42db9ddc Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Thu, 8 Oct 2020 18:36:37 -0400 Subject: [PATCH 10/11] feat: Update host-catalog routes for notify decorator --- .../scope/projects/project/host-catalogs.js | 39 ++++++----------- .../host-catalogs/host-catalog/host-sets.js | 41 +++++++----------- .../host-sets/host-set/add-hosts.js | 17 +++----- .../host-catalog/host-sets/host-set/hosts.js | 25 +++++------ .../host-catalogs/host-catalog/hosts.js | 43 +++++++------------ 5 files changed, 63 insertions(+), 102 deletions(-) diff --git a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs.js b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs.js index c8fce1129..ab01b5b7e 100644 --- a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs.js +++ b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs.js @@ -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(); } } diff --git a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets.js b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets.js index 3c003bd50..380250c3e 100644 --- a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets.js +++ b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets.js @@ -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' + ); } } diff --git a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/host-set/add-hosts.js b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/host-set/add-hosts.js index d892490ab..3b398fcec 100644 --- a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/host-set/add-hosts.js +++ b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/host-set/add-hosts.js @@ -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' + ); } /** diff --git a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/host-set/hosts.js b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/host-set/hosts.js index a4476caf1..8b4a5514d 100644 --- a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/host-set/hosts.js +++ b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/host-sets/host-set/hosts.js @@ -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(); } } diff --git a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts.js b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts.js index 86b7e1c75..9b9732e2a 100644 --- a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts.js +++ b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog/hosts.js @@ -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(); } } From 38416cfeb0b88c38d75777094a62bfb24d42623a Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Fri, 9 Oct 2020 16:45:49 -0400 Subject: [PATCH 11/11] =?UTF-8?q?chore:=20=F0=9F=A4=96=20apply=20notify=20?= =?UTF-8?q?decorators=20to=20remaining=20routes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/core/app/routes/account/change-password.js | 23 ++++++++----------- ui/core/app/routes/scopes/scope/orgs.js | 18 +++++---------- .../scopes/scope/projects/project/sessions.js | 11 ++++----- 3 files changed, 20 insertions(+), 32 deletions(-) diff --git a/ui/core/app/routes/account/change-password.js b/ui/core/app/routes/account/change-password.js index f17ec6e84..e4247da8e 100644 --- a/ui/core/app/routes/account/change-password.js +++ b/ui/core/app/routes/account/change-password.js @@ -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(() => {}); } /** diff --git a/ui/core/app/routes/scopes/scope/orgs.js b/ui/core/app/routes/scopes/scope/orgs.js index 626de80fa..5aad80343 100644 --- a/ui/core/app/routes/scopes/scope/orgs.js +++ b/ui/core/app/routes/scopes/scope/orgs.js @@ -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(); } } diff --git a/ui/core/app/routes/scopes/scope/projects/project/sessions.js b/ui/core/app/routes/scopes/scope/projects/project/sessions.js index b537560a7..3e01b9f44 100644 --- a/ui/core/app/routes/scopes/scope/projects/project/sessions.js +++ b/ui/core/app/routes/scopes/scope/projects/project/sessions.js @@ -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(); } }