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); + }); +});
{{t "resources.org.description"}}
{{t "resources.project.description"}}
{{@model.id}}