From b77fc6a449834367dc3b647264899d66e89f10ea Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Tue, 27 Oct 2020 17:47:59 -0400 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20add=20scope=20edit=20rou?= =?UTF-8?q?te=20and=20persistence=20actions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/core/app/components/form/scope/index.hbs | 53 +++++++++++++++++ ui/core/app/router.js | 1 + ui/core/app/routes/scopes/scope.js | 49 +++++++++++++++ ui/core/app/routes/scopes/scope/edit.js | 4 ++ ui/core/app/routes/scopes/scope/index.js | 4 +- ui/core/app/templates/scopes/scope/edit.hbs | 59 +++++++++++++++++++ .../templates/scopes/scope/scopes/index.hbs | 2 +- ui/core/tests/acceptance/scopes-test.js | 12 ++-- .../unit/routes/scopes/scope/edit-test.js | 11 ++++ 9 files changed, 189 insertions(+), 6 deletions(-) create mode 100644 ui/core/app/components/form/scope/index.hbs create mode 100644 ui/core/app/routes/scopes/scope/edit.js create mode 100644 ui/core/app/templates/scopes/scope/edit.hbs create mode 100644 ui/core/tests/unit/routes/scopes/scope/edit-test.js diff --git a/ui/core/app/components/form/scope/index.hbs b/ui/core/app/components/form/scope/index.hbs new file mode 100644 index 000000000..0e024b1fb --- /dev/null +++ b/ui/core/app/components/form/scope/index.hbs @@ -0,0 +1,53 @@ + + + + {{#if @model.errors.name}} + + {{#each @model.errors.name as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + + + {{#if @model.errors.description}} + + {{#each @model.errors.description as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + + + + diff --git a/ui/core/app/router.js b/ui/core/app/router.js index df0228147..8c575ea0e 100644 --- a/ui/core/app/router.js +++ b/ui/core/app/router.js @@ -54,6 +54,7 @@ Router.map(function () { this.route('new'); }); this.route('scopes', function() {}); + this.route('edit'); }); }); diff --git a/ui/core/app/routes/scopes/scope.js b/ui/core/app/routes/scopes/scope.js index 3bc4ecaaa..3bc2e102f 100644 --- a/ui/core/app/routes/scopes/scope.js +++ b/ui/core/app/routes/scopes/scope.js @@ -1,6 +1,10 @@ import Route from '@ember/routing/route'; import { inject as service } from '@ember/service'; import { A } from '@ember/array'; +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 ScopesScopeRoute extends Route { // =services @@ -83,4 +87,49 @@ export default class ScopesScopeRoute extends Route { outlet: 'header-nav', }); } + + // =actions + + /** + * Rollback changes on scope. + * @param {Model} scope + */ + @action + cancel(scope) { + const { isNew } = scope; + scope.rollbackAttributes(); + if (isNew) this.transitionTo('scopes.scope'); + } + + /** + * Handle save scope. + * @param {Model} scope + * @param {Event} e + */ + @action + @loading + @notifyError(({ message }) => message) + @notifySuccess(({ isNew }) => isNew ? 'notifications.create-success' : 'notifications.save-success') + async save(scope) { + const { isNew } = scope; + await scope.save(); + await this.transitionTo('scopes.scope.edit', scope); + if (isNew) this.refresh(); + } + + /** + * Deletes the scope and redirects to index. + * @param {Model} scope + */ + @action + @loading + @confirm('questions.delete-confirm') + @notifyError(({ message }) => message, { catch: true }) + @notifySuccess('notifications.delete-success') + async delete(scope) { + const { scopeID } = scope; + await scope.destroyRecord(); + await this.replaceWith('scopes.scope.scopes', scopeID); + //this.refresh(); + } } diff --git a/ui/core/app/routes/scopes/scope/edit.js b/ui/core/app/routes/scopes/scope/edit.js new file mode 100644 index 000000000..b77391dbd --- /dev/null +++ b/ui/core/app/routes/scopes/scope/edit.js @@ -0,0 +1,4 @@ +import Route from '@ember/routing/route'; + +export default class ScopesScopeEditRoute extends Route { +} diff --git a/ui/core/app/routes/scopes/scope/index.js b/ui/core/app/routes/scopes/scope/index.js index 958b958ec..8ae76d0a6 100644 --- a/ui/core/app/routes/scopes/scope/index.js +++ b/ui/core/app/routes/scopes/scope/index.js @@ -13,9 +13,11 @@ export default class ScopesScopeIndexRoute extends Route { * If already authenticated, redirects to scopes/scope/scopes to display * list of sub scopes. */ - redirect() { + redirect(model) { if (!this.session.isAuthenticated) { this.transitionTo('scopes.scope.authenticate'); + } else if (model.isProject) { + this.transitionTo('scopes.scope.edit'); } else { this.transitionTo('scopes.scope.scopes'); } diff --git a/ui/core/app/templates/scopes/scope/edit.hbs b/ui/core/app/templates/scopes/scope/edit.hbs new file mode 100644 index 000000000..610b3026e --- /dev/null +++ b/ui/core/app/templates/scopes/scope/edit.hbs @@ -0,0 +1,59 @@ + + + + + + + + {{#if @model.isOrg}} +

+ {{t "resources.org.title"}} + +

+

{{t "resources.org.description"}}

+ {{/if}} + {{#if @model.isProject}} +

+ {{t "resources.project.title"}} + +

+

{{t "resources.project.description"}}

+ {{/if}} + + {{@model.id}} + +
+ + + + + {{t 'titles.details'}} + + + + + + + + {{t 'resources.project.actions.delete'}} + + + + + + + + +
diff --git a/ui/core/app/templates/scopes/scope/scopes/index.hbs b/ui/core/app/templates/scopes/scope/scopes/index.hbs index ba21bb6b8..8f4969c7d 100644 --- a/ui/core/app/templates/scopes/scope/scopes/index.hbs +++ b/ui/core/app/templates/scopes/scope/scopes/index.hbs @@ -46,7 +46,7 @@ @title={{scope.name}} @description={{scope.description}} @id={{scope.id}} - @icon={{if @model.currentScope.isGlobal "app-icons/org" "app-icons/project"}} + @icon={{if scope.isOrg "app-icons/org" "app-icons/project"}} @route="scopes.scope" @model={{scope.id}} /> diff --git a/ui/core/tests/acceptance/scopes-test.js b/ui/core/tests/acceptance/scopes-test.js index 4473e2aee..2e8fe6a99 100644 --- a/ui/core/tests/acceptance/scopes-test.js +++ b/ui/core/tests/acceptance/scopes-test.js @@ -30,6 +30,8 @@ module('Acceptance | scopes', function (hooks) { org2Scope: null, projectScope: null, project2Scope: null, + projectScopeEdit: null, + project2ScopeEdit: null, }; hooks.beforeEach(function () { @@ -54,8 +56,10 @@ module('Acceptance | scopes', function (hooks) { urls.globalScope = `/scopes/global/scopes`; urls.orgScope = `/scopes/${instances.scopes.org.id}/scopes`; urls.org2Scope = `/scopes/${instances.scopes.org2.id}/scopes`; - urls.projectScope = `/scopes/${instances.scopes.project.id}/scopes`; - urls.project2Scope = `/scopes/${instances.scopes.project2.id}/scopes`; + urls.projectScope = `/scopes/${instances.scopes.project.id}`; + urls.project2Scope = `/scopes/${instances.scopes.project2.id}`; + urls.projectScopeEdit = `/scopes/${instances.scopes.project.id}/edit`; + urls.project2ScopeEdit = `/scopes/${instances.scopes.project2.id}/edit`; authenticateSession({}); }); @@ -110,9 +114,9 @@ module('Acceptance | scopes', function (hooks) { assert.expect(2); await visit(urls.projectScope); await a11yAudit(); - assert.equal(currentURL(), urls.projectScope); + assert.equal(currentURL(), urls.projectScopeEdit); await click('.rose-header-nav .rose-dropdown + .rose-dropdown a:nth-child(2)'); - assert.equal(currentURL(), urls.project2Scope); + assert.equal(currentURL(), urls.project2ScopeEdit); }); }); diff --git a/ui/core/tests/unit/routes/scopes/scope/edit-test.js b/ui/core/tests/unit/routes/scopes/scope/edit-test.js new file mode 100644 index 000000000..0b4334ea0 --- /dev/null +++ b/ui/core/tests/unit/routes/scopes/scope/edit-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Route | scopes/scope/edit', function(hooks) { + setupTest(hooks); + + test('it exists', function(assert) { + let route = this.owner.lookup('route:scopes/scope/edit'); + assert.ok(route); + }); +});