From fe21a661222f0a48ee773c0dafae574779796209 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Wed, 24 Jun 2020 16:52:03 -0400 Subject: [PATCH 1/8] =?UTF-8?q?chore:=20=F0=9F=A4=96=20Add=20groups=20rout?= =?UTF-8?q?es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/core/app/router.js | 5 +++++ ui/core/app/routes/orgs/org/groups.js | 4 ++++ ui/core/app/routes/orgs/org/groups/group.js | 4 ++++ ui/core/app/routes/orgs/org/groups/index.js | 4 ++++ ui/core/app/routes/orgs/org/groups/new.js | 4 ++++ ui/core/app/templates/orgs/org/groups.hbs | 1 + ui/core/app/templates/orgs/org/groups/group.hbs | 1 + ui/core/app/templates/orgs/org/groups/index.hbs | 1 + ui/core/app/templates/orgs/org/groups/new.hbs | 1 + ui/core/tests/unit/routes/orgs/org/groups-test.js | 11 +++++++++++ .../tests/unit/routes/orgs/org/groups/group-test.js | 11 +++++++++++ .../tests/unit/routes/orgs/org/groups/index-test.js | 11 +++++++++++ ui/core/tests/unit/routes/orgs/org/groups/new-test.js | 11 +++++++++++ 13 files changed, 69 insertions(+) create mode 100644 ui/core/app/routes/orgs/org/groups.js create mode 100644 ui/core/app/routes/orgs/org/groups/group.js create mode 100644 ui/core/app/routes/orgs/org/groups/index.js create mode 100644 ui/core/app/routes/orgs/org/groups/new.js create mode 100644 ui/core/app/templates/orgs/org/groups.hbs create mode 100644 ui/core/app/templates/orgs/org/groups/group.hbs create mode 100644 ui/core/app/templates/orgs/org/groups/index.hbs create mode 100644 ui/core/app/templates/orgs/org/groups/new.hbs create mode 100644 ui/core/tests/unit/routes/orgs/org/groups-test.js create mode 100644 ui/core/tests/unit/routes/orgs/org/groups/group-test.js create mode 100644 ui/core/tests/unit/routes/orgs/org/groups/index-test.js create mode 100644 ui/core/tests/unit/routes/orgs/org/groups/new-test.js diff --git a/ui/core/app/router.js b/ui/core/app/router.js index b9360c541..e75a090bf 100644 --- a/ui/core/app/router.js +++ b/ui/core/app/router.js @@ -22,6 +22,11 @@ Router.map(function () { this.route('role', { path: ':role_id' }, function() {}); this.route('new'); }); + + this.route('groups', function() { + this.route('group', { path: 'group_id' }, function() {}); + this.route('new'); + }); }); }); }); diff --git a/ui/core/app/routes/orgs/org/groups.js b/ui/core/app/routes/orgs/org/groups.js new file mode 100644 index 000000000..1defe3d01 --- /dev/null +++ b/ui/core/app/routes/orgs/org/groups.js @@ -0,0 +1,4 @@ +import Route from '@ember/routing/route'; + +export default class OrgsOrgGroupsRoute extends Route { +} diff --git a/ui/core/app/routes/orgs/org/groups/group.js b/ui/core/app/routes/orgs/org/groups/group.js new file mode 100644 index 000000000..c6eba762d --- /dev/null +++ b/ui/core/app/routes/orgs/org/groups/group.js @@ -0,0 +1,4 @@ +import Route from '@ember/routing/route'; + +export default class OrgsOrgGroupsGroupRoute extends Route { +} diff --git a/ui/core/app/routes/orgs/org/groups/index.js b/ui/core/app/routes/orgs/org/groups/index.js new file mode 100644 index 000000000..c15b0d470 --- /dev/null +++ b/ui/core/app/routes/orgs/org/groups/index.js @@ -0,0 +1,4 @@ +import Route from '@ember/routing/route'; + +export default class OrgsOrgGroupsIndexRoute extends Route { +} diff --git a/ui/core/app/routes/orgs/org/groups/new.js b/ui/core/app/routes/orgs/org/groups/new.js new file mode 100644 index 000000000..b784e95aa --- /dev/null +++ b/ui/core/app/routes/orgs/org/groups/new.js @@ -0,0 +1,4 @@ +import Route from '@ember/routing/route'; + +export default class OrgsOrgGroupsNewRoute extends Route { +} diff --git a/ui/core/app/templates/orgs/org/groups.hbs b/ui/core/app/templates/orgs/org/groups.hbs new file mode 100644 index 000000000..e2147cab0 --- /dev/null +++ b/ui/core/app/templates/orgs/org/groups.hbs @@ -0,0 +1 @@ +{{outlet}} \ No newline at end of file diff --git a/ui/core/app/templates/orgs/org/groups/group.hbs b/ui/core/app/templates/orgs/org/groups/group.hbs new file mode 100644 index 000000000..e2147cab0 --- /dev/null +++ b/ui/core/app/templates/orgs/org/groups/group.hbs @@ -0,0 +1 @@ +{{outlet}} \ No newline at end of file diff --git a/ui/core/app/templates/orgs/org/groups/index.hbs b/ui/core/app/templates/orgs/org/groups/index.hbs new file mode 100644 index 000000000..e2147cab0 --- /dev/null +++ b/ui/core/app/templates/orgs/org/groups/index.hbs @@ -0,0 +1 @@ +{{outlet}} \ No newline at end of file diff --git a/ui/core/app/templates/orgs/org/groups/new.hbs b/ui/core/app/templates/orgs/org/groups/new.hbs new file mode 100644 index 000000000..e2147cab0 --- /dev/null +++ b/ui/core/app/templates/orgs/org/groups/new.hbs @@ -0,0 +1 @@ +{{outlet}} \ No newline at end of file diff --git a/ui/core/tests/unit/routes/orgs/org/groups-test.js b/ui/core/tests/unit/routes/orgs/org/groups-test.js new file mode 100644 index 000000000..a56f69e76 --- /dev/null +++ b/ui/core/tests/unit/routes/orgs/org/groups-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Route | orgs/org/groups', function(hooks) { + setupTest(hooks); + + test('it exists', function(assert) { + let route = this.owner.lookup('route:orgs/org/groups'); + assert.ok(route); + }); +}); diff --git a/ui/core/tests/unit/routes/orgs/org/groups/group-test.js b/ui/core/tests/unit/routes/orgs/org/groups/group-test.js new file mode 100644 index 000000000..cec8245a8 --- /dev/null +++ b/ui/core/tests/unit/routes/orgs/org/groups/group-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Route | orgs/org/groups/group', function(hooks) { + setupTest(hooks); + + test('it exists', function(assert) { + let route = this.owner.lookup('route:orgs/org/groups/group'); + assert.ok(route); + }); +}); diff --git a/ui/core/tests/unit/routes/orgs/org/groups/index-test.js b/ui/core/tests/unit/routes/orgs/org/groups/index-test.js new file mode 100644 index 000000000..c2f9135eb --- /dev/null +++ b/ui/core/tests/unit/routes/orgs/org/groups/index-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Route | orgs/org/groups/index', function(hooks) { + setupTest(hooks); + + test('it exists', function(assert) { + let route = this.owner.lookup('route:orgs/org/groups/index'); + assert.ok(route); + }); +}); diff --git a/ui/core/tests/unit/routes/orgs/org/groups/new-test.js b/ui/core/tests/unit/routes/orgs/org/groups/new-test.js new file mode 100644 index 000000000..09f10c831 --- /dev/null +++ b/ui/core/tests/unit/routes/orgs/org/groups/new-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Route | orgs/org/groups/new', function(hooks) { + setupTest(hooks); + + test('it exists', function(assert) { + let route = this.owner.lookup('route:orgs/org/groups/new'); + assert.ok(route); + }); +}); From 17057fcb18eed66dc09231b5c176b87f22a27bd3 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Wed, 24 Jun 2020 16:56:28 -0400 Subject: [PATCH 2/8] =?UTF-8?q?chore:=20=F0=9F=A4=96=20Add=20groups=20rout?= =?UTF-8?q?e=20to=20sidebar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/core/app/templates/orgs/org.hbs | 4 ++++ ui/core/app/templates/orgs/org/groups.hbs | 4 +++- ui/core/translations/en-us.yaml | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ui/core/app/templates/orgs/org.hbs b/ui/core/app/templates/orgs/org.hbs index 17926a1aa..91937621c 100644 --- a/ui/core/app/templates/orgs/org.hbs +++ b/ui/core/app/templates/orgs/org.hbs @@ -11,6 +11,10 @@ {{outlet "sidebar"}} + + {{t "resources.groups"}} + + {{t "resources.roles"}} diff --git a/ui/core/app/templates/orgs/org/groups.hbs b/ui/core/app/templates/orgs/org/groups.hbs index e2147cab0..c53da7f4b 100644 --- a/ui/core/app/templates/orgs/org/groups.hbs +++ b/ui/core/app/templates/orgs/org/groups.hbs @@ -1 +1,3 @@ -{{outlet}} \ No newline at end of file +{{title (t "resources.groups")}} + +{{outlet}} diff --git a/ui/core/translations/en-us.yaml b/ui/core/translations/en-us.yaml index d8151b25b..21882f489 100644 --- a/ui/core/translations/en-us.yaml +++ b/ui/core/translations/en-us.yaml @@ -7,6 +7,8 @@ actions: resources: role: Role roles: Roles + group: Group + groups: Groups projects: Projects project: Project host-catalog: Host Catalog From 98c7d003a08ac6140053614bda28585c3b02df3e Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Wed, 24 Jun 2020 17:07:32 -0400 Subject: [PATCH 3/8] =?UTF-8?q?chore:=20=F0=9F=A4=96=20List=20groups=20und?= =?UTF-8?q?er=20/groups=20page?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/api/addon/adapters/group.js | 14 +++++ addons/api/app/adapters/group.js | 1 + addons/api/tests/unit/adapters/group-test.js | 12 ++++ ui/core/app/routes/orgs/org/groups.js | 9 +++ ui/core/app/routes/orgs/org/roles/index.js | 2 +- .../app/templates/orgs/org/groups/index.hbs | 60 ++++++++++++++++++- ui/core/mirage/config.js | 7 +++ ui/core/mirage/factories/group.js | 3 + ui/core/mirage/generated/factories/group.js | 16 +++++ ui/core/mirage/scenarios/default.js | 2 + ui/core/mirage/serializers/group.js | 5 ++ ui/core/translations/en-us.yaml | 2 + 12 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 addons/api/addon/adapters/group.js create mode 100644 addons/api/app/adapters/group.js create mode 100644 addons/api/tests/unit/adapters/group-test.js create mode 100644 ui/core/mirage/factories/group.js create mode 100644 ui/core/mirage/generated/factories/group.js create mode 100644 ui/core/mirage/serializers/group.js diff --git a/addons/api/addon/adapters/group.js b/addons/api/addon/adapters/group.js new file mode 100644 index 000000000..b077634f4 --- /dev/null +++ b/addons/api/addon/adapters/group.js @@ -0,0 +1,14 @@ +import ApplicationAdapter from './application'; +import ScopeAdapterMixin from '../mixins/scope-adapter'; + +export default class GroupAdapter extends ApplicationAdapter.extend( + ScopeAdapterMixin +) { + // =attributes + + /** + * Group is scoped to org only, for now. + * @type {boolean} + */ + includeProject = false; +} diff --git a/addons/api/app/adapters/group.js b/addons/api/app/adapters/group.js new file mode 100644 index 000000000..bb77ff26c --- /dev/null +++ b/addons/api/app/adapters/group.js @@ -0,0 +1 @@ +export { default } from 'api/adapters/group'; diff --git a/addons/api/tests/unit/adapters/group-test.js b/addons/api/tests/unit/adapters/group-test.js new file mode 100644 index 000000000..d39297843 --- /dev/null +++ b/addons/api/tests/unit/adapters/group-test.js @@ -0,0 +1,12 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Adapter | group', function(hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function(assert) { + let adapter = this.owner.lookup('adapter:group'); + assert.ok(adapter); + }); +}); diff --git a/ui/core/app/routes/orgs/org/groups.js b/ui/core/app/routes/orgs/org/groups.js index 1defe3d01..c17d210d1 100644 --- a/ui/core/app/routes/orgs/org/groups.js +++ b/ui/core/app/routes/orgs/org/groups.js @@ -1,4 +1,13 @@ import Route from '@ember/routing/route'; export default class OrgsOrgGroupsRoute extends Route { + // =methods + + /** + * Returns all roles from store. + * @return {Promise[RoleModel]} + */ + model() { + return this.store.findAll('group'); + } } diff --git a/ui/core/app/routes/orgs/org/roles/index.js b/ui/core/app/routes/orgs/org/roles/index.js index 89b868927..92a715a56 100644 --- a/ui/core/app/routes/orgs/org/roles/index.js +++ b/ui/core/app/routes/orgs/org/roles/index.js @@ -1,3 +1,3 @@ import Route from '@ember/routing/route'; -export default class OrgsOrgRolesIndexRoute extends Route { } +export default class OrgsOrgRolesIndexRoute extends Route {} diff --git a/ui/core/app/templates/orgs/org/groups/index.hbs b/ui/core/app/templates/orgs/org/groups/index.hbs index e2147cab0..c56fcb134 100644 --- a/ui/core/app/templates/orgs/org/groups/index.hbs +++ b/ui/core/app/templates/orgs/org/groups/index.hbs @@ -1 +1,59 @@ -{{outlet}} \ No newline at end of file + + + +

{{t "resources.groups"}}

+
+ + + {{#if @model}} + {{t 'titles.new'}} + {{/if}} + + + + + {{#if @model}} + + + + + {{t 'form.label.name'}} + {{t 'form.label.description'}} + + + + {{#each @model as |group|}} + + + + {{group.name}} + + + {{group.description}} + + {{/each}} + + + + {{else}} + + + + + {{t 'descriptions.groups-welcome'}} + + + + {{t 'titles.new'}} + + + + + {{/if}} + + + +
diff --git a/ui/core/mirage/config.js b/ui/core/mirage/config.js index 8a3e0f49c..0805efcea 100644 --- a/ui/core/mirage/config.js +++ b/ui/core/mirage/config.js @@ -47,6 +47,13 @@ export default function() { this.patch('/orgs/:org_id/roles/:id'); this.del('/orgs/:org_id/roles/:id'); + // group + this.get('/orgs/:org_id/groups'); + this.post('/orgs/:org_id/groups'); + this.get('/orgs/:org_id/groups/:id'); + this.patch('/orgs/:org_id/groups/:id'); + this.del('/orgs/:org_id/groups/:id'); + // Other resources // host-catalog diff --git a/ui/core/mirage/factories/group.js b/ui/core/mirage/factories/group.js new file mode 100644 index 000000000..e5f474099 --- /dev/null +++ b/ui/core/mirage/factories/group.js @@ -0,0 +1,3 @@ +import factory from '../generated/factories/group'; + +export default factory.extend(); diff --git a/ui/core/mirage/generated/factories/group.js b/ui/core/mirage/generated/factories/group.js new file mode 100644 index 000000000..7c78ee7ec --- /dev/null +++ b/ui/core/mirage/generated/factories/group.js @@ -0,0 +1,16 @@ +import { Factory } from 'ember-cli-mirage'; +import { random, date } from 'faker'; + +/** + * GeneratedGroupModelFactory + * Group contains all fields related to a Group resource + */ +export default Factory.extend({ + + name: () => random.words(), + description: () => random.words(), + created_time: () => date.recent(), + updated_time: () => date.recent(), + disabled: () => random.boolean(), + +}); diff --git a/ui/core/mirage/scenarios/default.js b/ui/core/mirage/scenarios/default.js index ef06c6ee4..904f43936 100644 --- a/ui/core/mirage/scenarios/default.js +++ b/ui/core/mirage/scenarios/default.js @@ -15,6 +15,8 @@ export default function(server) { // IAM // Roles server.createList('role', 5); + // Groups + server.createList('group', 5); // Other resources diff --git a/ui/core/mirage/serializers/group.js b/ui/core/mirage/serializers/group.js new file mode 100644 index 000000000..13ec42167 --- /dev/null +++ b/ui/core/mirage/serializers/group.js @@ -0,0 +1,5 @@ +import ApplicationSerializer from './application'; + +export default ApplicationSerializer.extend({ + modelName: 'group' +}); diff --git a/ui/core/translations/en-us.yaml b/ui/core/translations/en-us.yaml index 21882f489..2498e9983 100644 --- a/ui/core/translations/en-us.yaml +++ b/ui/core/translations/en-us.yaml @@ -23,12 +23,14 @@ titles: projects-welcome: Welcome to Projects host-catalogs-welcome: Welcome to Host Catalogs roles-welcome: Welcome to Roles + groups-welcome: Welcome to Groups descriptions: host-catalogs: Overview of collections of hosts and host sets. empty-set: There are no items to display yet. You may be able to add items or try back later. projects-welcome: Projects allow you to create and manage host catalogs. To start, create a project. host-catalogs-welcome: Host catalogs allow you to configure to collect and create hosts and host sets. To start, create a host catalog. roles-welcome: Roles are collections of capabilities that can be granted to user and/or groups. + groups-welcome: Groups are collections of users. states: info: Info success: Success From a3af648e436f59a936515e742f0b5ae338fb9289 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Wed, 24 Jun 2020 17:10:54 -0400 Subject: [PATCH 4/8] =?UTF-8?q?chore:=20=F0=9F=A4=96=20Add=20new=20group?= =?UTF-8?q?=20view?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/core/app/components/form/group/index.hbs | 49 +++++++++++++++++++ ui/core/app/routes/orgs/org/groups/new.js | 46 +++++++++++++++++ ui/core/app/templates/orgs/org/groups/new.hbs | 14 +++++- ui/core/translations/en-us.yaml | 2 + 4 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 ui/core/app/components/form/group/index.hbs diff --git a/ui/core/app/components/form/group/index.hbs b/ui/core/app/components/form/group/index.hbs new file mode 100644 index 000000000..9db695baa --- /dev/null +++ b/ui/core/app/components/form/group/index.hbs @@ -0,0 +1,49 @@ + + + + {{#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/routes/orgs/org/groups/new.js b/ui/core/app/routes/orgs/org/groups/new.js index b784e95aa..6f353d368 100644 --- a/ui/core/app/routes/orgs/org/groups/new.js +++ b/ui/core/app/routes/orgs/org/groups/new.js @@ -1,4 +1,50 @@ import Route from '@ember/routing/route'; +import { inject as service } from '@ember/service'; +import { action } from '@ember/object'; export default class OrgsOrgGroupsNewRoute extends Route { + // =services + + @service intl; + @service notify; + + // =methods + + /** + * Returns a new unsaved group. + * @return {Promise{GroupModel}} + */ + model() { + return this.store.createRecord('group'); + } + + // =actions + + /** + * Rollback changes on group by destroying unsaved instance + * and redirect to group index. + * @param {GroupModel} group + */ + @action + cancel(group) { + group.rollbackAttributes(); + this.transitionTo('orgs.org.groups'); + } + + /** + * Handle saving a group. + * @param {GroupModel} group + * @param {Event} e + */ + @action + async save(group) { + try { + await group.save(); + this.transitionTo('orgs.org.groups.group', group); + this.notify.success(this.intl.t('notify.group.create-success')); + } catch (error) { + // TODO: replace with translated strings + this.notify.error(error.message, { closeAfter: null }); + } + } } diff --git a/ui/core/app/templates/orgs/org/groups/new.hbs b/ui/core/app/templates/orgs/org/groups/new.hbs index e2147cab0..d2b85b3a2 100644 --- a/ui/core/app/templates/orgs/org/groups/new.hbs +++ b/ui/core/app/templates/orgs/org/groups/new.hbs @@ -1 +1,13 @@ -{{outlet}} \ No newline at end of file + + +

{{t "titles.new"}}

+
+ + + + +
diff --git a/ui/core/translations/en-us.yaml b/ui/core/translations/en-us.yaml index 2498e9983..ab1aaf9c4 100644 --- a/ui/core/translations/en-us.yaml +++ b/ui/core/translations/en-us.yaml @@ -59,6 +59,8 @@ notify: role: create-success: Role created succesfully. delete-success: Deleted role successfully. + group: + create-success: Group created succesfully. dev: default-org: Default Org menu-item: Menu item From 56f618e8aeffcc45bbea005ef3adfb26560a5a5c Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Wed, 24 Jun 2020 17:32:25 -0400 Subject: [PATCH 5/8] =?UTF-8?q?chore:=20=F0=9F=A4=96=20Add=20group=20edit?= =?UTF-8?q?=20view?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/core/app/router.js | 2 +- ui/core/app/routes/orgs/org/groups/group.js | 60 +++++++++++++++++++ .../app/routes/orgs/org/groups/group/index.js | 4 ++ ui/core/app/routes/orgs/org/groups/index.js | 3 +- .../app/templates/orgs/org/groups/group.hbs | 4 +- .../templates/orgs/org/groups/group/index.hbs | 23 +++++++ .../orgs/org/groups/group/index-test.js | 11 ++++ ui/core/translations/en-us.yaml | 1 + 8 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 ui/core/app/routes/orgs/org/groups/group/index.js create mode 100644 ui/core/app/templates/orgs/org/groups/group/index.hbs create mode 100644 ui/core/tests/unit/routes/orgs/org/groups/group/index-test.js diff --git a/ui/core/app/router.js b/ui/core/app/router.js index e75a090bf..3bb38ebbe 100644 --- a/ui/core/app/router.js +++ b/ui/core/app/router.js @@ -24,7 +24,7 @@ Router.map(function () { }); this.route('groups', function() { - this.route('group', { path: 'group_id' }, function() {}); + this.route('group', { path: ':group_id' }, function() {}); this.route('new'); }); }); diff --git a/ui/core/app/routes/orgs/org/groups/group.js b/ui/core/app/routes/orgs/org/groups/group.js index c6eba762d..98c6b65c9 100644 --- a/ui/core/app/routes/orgs/org/groups/group.js +++ b/ui/core/app/routes/orgs/org/groups/group.js @@ -1,4 +1,64 @@ import Route from '@ember/routing/route'; +import { inject as service } from '@ember/service'; +import { action } from '@ember/object'; export default class OrgsOrgGroupsGroupRoute extends Route { + // =services + + @service intl; + @service notify; + + // =methods + + /** + * Return a group with id + * @param {object} params + * @return {Promise{GroupModel}} + */ + model({ group_id: id }) { + return this.store.findRecord('group', id); + } + + // =actions + + /** + * Rollback changes on group. + * @param {GroupModel} group + */ + @action + cancel(group) { + group.rollbackAttributes(); + } + + /** + * Handle saving a group. + * @param {GroupModel} group + * @param {Event} e + */ + @action + async save(group) { + try { + await group.save(); + this.notify.success(this.intl.t('notify.save-success')); + } catch (error) { + // TODO: replace with translated strings + this.notify.error(error.message, { closeAfter: null }); + } + } + + /** + * Delete group and redirect to groups index. + * @param {GroupModel} group + */ + @action + async delete(group) { + try { + await group.destroyRecord(); + this.transitionTo('orgs.org.groups'); + this.notify.success(this.intl.t('notify.group.delete-success')); + } catch (error) { + // TODO: replace with translated strings + this.notify.error(error.message, { closeAfter: null }); + } + } } diff --git a/ui/core/app/routes/orgs/org/groups/group/index.js b/ui/core/app/routes/orgs/org/groups/group/index.js new file mode 100644 index 000000000..521f73a9c --- /dev/null +++ b/ui/core/app/routes/orgs/org/groups/group/index.js @@ -0,0 +1,4 @@ +import Route from '@ember/routing/route'; + +export default class OrgsOrgGroupsGroupIndexRoute extends Route { +} diff --git a/ui/core/app/routes/orgs/org/groups/index.js b/ui/core/app/routes/orgs/org/groups/index.js index c15b0d470..9c566dfa0 100644 --- a/ui/core/app/routes/orgs/org/groups/index.js +++ b/ui/core/app/routes/orgs/org/groups/index.js @@ -1,4 +1,3 @@ import Route from '@ember/routing/route'; -export default class OrgsOrgGroupsIndexRoute extends Route { -} +export default class OrgsOrgGroupsIndexRoute extends Route {} diff --git a/ui/core/app/templates/orgs/org/groups/group.hbs b/ui/core/app/templates/orgs/org/groups/group.hbs index e2147cab0..2b05f838d 100644 --- a/ui/core/app/templates/orgs/org/groups/group.hbs +++ b/ui/core/app/templates/orgs/org/groups/group.hbs @@ -1 +1,3 @@ -{{outlet}} \ No newline at end of file +{{title @model.name}} + +{{outlet}} diff --git a/ui/core/app/templates/orgs/org/groups/group/index.hbs b/ui/core/app/templates/orgs/org/groups/group/index.hbs new file mode 100644 index 000000000..71b756e0c --- /dev/null +++ b/ui/core/app/templates/orgs/org/groups/group/index.hbs @@ -0,0 +1,23 @@ + + + +

{{t "resources.group"}}

+
+ + + + + + {{t 'actions.delete'}} + + + +
diff --git a/ui/core/tests/unit/routes/orgs/org/groups/group/index-test.js b/ui/core/tests/unit/routes/orgs/org/groups/group/index-test.js new file mode 100644 index 000000000..2496b24bf --- /dev/null +++ b/ui/core/tests/unit/routes/orgs/org/groups/group/index-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Route | orgs/org/groups/group/index', function(hooks) { + setupTest(hooks); + + test('it exists', function(assert) { + let route = this.owner.lookup('route:orgs/org/groups/group/index'); + assert.ok(route); + }); +}); diff --git a/ui/core/translations/en-us.yaml b/ui/core/translations/en-us.yaml index ab1aaf9c4..2ba26634a 100644 --- a/ui/core/translations/en-us.yaml +++ b/ui/core/translations/en-us.yaml @@ -61,6 +61,7 @@ notify: delete-success: Deleted role successfully. group: create-success: Group created succesfully. + delete-success: Deleted group successfully. dev: default-org: Default Org menu-item: Menu item From 30f97e93fc545877e817eea16712dd5a85273f63 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Wed, 24 Jun 2020 17:42:09 -0400 Subject: [PATCH 6/8] =?UTF-8?q?chore:=20=F0=9F=A4=96=20Add=20breadcrumbs?= =?UTF-8?q?=20to=20groups=20pages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add missing role breadcrumb tests --- ui/core/app/controllers/orgs/org/groups.js | 17 +++++ .../app/controllers/orgs/org/groups/group.js | 12 +++ .../app/controllers/orgs/org/groups/new.js | 18 +++++ .../templates/orgs/org/groups/group/index.hbs | 4 + .../app/templates/orgs/org/groups/index.hbs | 4 + ui/core/app/templates/orgs/org/groups/new.hbs | 5 ++ ui/core/tests/acceptance/bread-crumbs-test.js | 73 ++++++++++++++++--- .../unit/controllers/orgs/org/groups-test.js | 12 +++ .../controllers/orgs/org/groups/group-test.js | 12 +++ .../controllers/orgs/org/groups/new-test.js | 12 +++ 10 files changed, 158 insertions(+), 11 deletions(-) create mode 100644 ui/core/app/controllers/orgs/org/groups.js create mode 100644 ui/core/app/controllers/orgs/org/groups/group.js create mode 100644 ui/core/app/controllers/orgs/org/groups/new.js create mode 100644 ui/core/tests/unit/controllers/orgs/org/groups-test.js create mode 100644 ui/core/tests/unit/controllers/orgs/org/groups/group-test.js create mode 100644 ui/core/tests/unit/controllers/orgs/org/groups/new-test.js diff --git a/ui/core/app/controllers/orgs/org/groups.js b/ui/core/app/controllers/orgs/org/groups.js new file mode 100644 index 000000000..b6c1716e9 --- /dev/null +++ b/ui/core/app/controllers/orgs/org/groups.js @@ -0,0 +1,17 @@ +import Controller from '@ember/controller'; +import { inject as service } from '@ember/service'; + +export default class OrgsOrgGroupsController extends Controller { + // =services + + @service intl; + + // =attributes + + /** + * @type {string} + */ + get breadCrumb() { + return this.intl.t('resources.groups'); + } +} diff --git a/ui/core/app/controllers/orgs/org/groups/group.js b/ui/core/app/controllers/orgs/org/groups/group.js new file mode 100644 index 000000000..60ed4c93c --- /dev/null +++ b/ui/core/app/controllers/orgs/org/groups/group.js @@ -0,0 +1,12 @@ +import Controller from '@ember/controller'; +import { alias } from '@ember/object/computed'; + +export default class OrgsOrgGroupsGroupController extends Controller { + // =attributes + + /** + * @type {string} + */ + @alias('model.name') breadCrumb; + +} diff --git a/ui/core/app/controllers/orgs/org/groups/new.js b/ui/core/app/controllers/orgs/org/groups/new.js new file mode 100644 index 000000000..9ca97fbe5 --- /dev/null +++ b/ui/core/app/controllers/orgs/org/groups/new.js @@ -0,0 +1,18 @@ +import Controller from '@ember/controller'; +import { inject as service } from '@ember/service'; + +export default class OrgsOrgGroupsNewController extends Controller { + // =services + + @service intl; + + // =attributes + + /** + * @type {string} + */ + get breadCrumb() { + return this.intl.t('titles.new'); + } + +} diff --git a/ui/core/app/templates/orgs/org/groups/group/index.hbs b/ui/core/app/templates/orgs/org/groups/group/index.hbs index 71b756e0c..576796dae 100644 --- a/ui/core/app/templates/orgs/org/groups/group/index.hbs +++ b/ui/core/app/templates/orgs/org/groups/group/index.hbs @@ -1,5 +1,9 @@ + + + +

{{t "resources.group"}}

diff --git a/ui/core/app/templates/orgs/org/groups/index.hbs b/ui/core/app/templates/orgs/org/groups/index.hbs index c56fcb134..cf02056b2 100644 --- a/ui/core/app/templates/orgs/org/groups/index.hbs +++ b/ui/core/app/templates/orgs/org/groups/index.hbs @@ -1,5 +1,9 @@ + + + +

{{t "resources.groups"}}

diff --git a/ui/core/app/templates/orgs/org/groups/new.hbs b/ui/core/app/templates/orgs/org/groups/new.hbs index d2b85b3a2..64602883c 100644 --- a/ui/core/app/templates/orgs/org/groups/new.hbs +++ b/ui/core/app/templates/orgs/org/groups/new.hbs @@ -1,4 +1,9 @@ + + + + +

{{t "titles.new"}}

diff --git a/ui/core/tests/acceptance/bread-crumbs-test.js b/ui/core/tests/acceptance/bread-crumbs-test.js index 2b134ae0a..fdce9f1c8 100644 --- a/ui/core/tests/acceptance/bread-crumbs-test.js +++ b/ui/core/tests/acceptance/bread-crumbs-test.js @@ -10,12 +10,12 @@ module('Acceptance | breadcrumbs', function (hooks) { let org; let project; let hostCatalog; - let projectsURL; - let newProjectURL; - let projectURL; - let hostCatalogsURL; - let newHostCatalogURL; - let hostCatalogURL; + let role; + let group; + let projectsURL, projectURL, newProjectURL; + let hostCatalogsURL, hostCatalogURL, newHostCatalogURL; + let rolesURL, roleURL, newRoleURL; + let groupsURL, groupURL, newGroupURL; let crumbPath; @@ -23,18 +23,30 @@ module('Acceptance | breadcrumbs', function (hooks) { org = this.server.create('org'); project = this.server.create('project'); hostCatalog = this.server.create('host-catalog'); + role = this.server.create('role'); + group = this.server.create('group'); + projectsURL = `/orgs/${org.id}/projects`; newProjectURL = `${projectsURL}/new`; projectURL = `${projectsURL}/${project.id}`; + hostCatalogsURL = `${projectURL}/host-catalogs`; newHostCatalogURL = `${hostCatalogsURL}/new`; hostCatalogURL = `${hostCatalogsURL}/${hostCatalog.id}`; + + rolesURL = `/orgs/${org.id}/roles`; + newRoleURL = `${rolesURL}/new`; + roleURL = `${rolesURL}/${role.id}`; + + groupsURL = `/orgs/${org.id}/groups`; + newGroupURL = `${groupsURL}/new`; + groupURL = `${groupsURL}/${group.id}`; }); test('can navigate via breadcrumbs to projects from project', async function (assert) { assert.expect(3); await visit(projectURL); - assert.equal(currentURL(), projectURL, 'We begin on th expected page.'); + assert.equal(currentURL(), projectURL, 'We begin on the expected page.'); crumbPath = new URL(find('.rose-nav-breadcrumbs-link:last-child').href).pathname; assert.equal(crumbPath, projectURL, 'Last crumb has expected URL.'); await click(find('.rose-nav-breadcrumbs-link:first-child')); @@ -44,7 +56,7 @@ module('Acceptance | breadcrumbs', function (hooks) { test('can navigate via breadcrumbs to projects from new project', async function (assert) { assert.expect(3); await visit(newProjectURL); - assert.equal(currentURL(), newProjectURL, 'We begin on th expected page.'); + assert.equal(currentURL(), newProjectURL, 'We begin on the expected page.'); crumbPath = new URL(find('.rose-nav-breadcrumbs-link:last-child').href).pathname; assert.equal(crumbPath, newProjectURL, 'Last crumb has expected URL.'); await click(find('.rose-nav-breadcrumbs-link:first-child')); @@ -54,7 +66,7 @@ module('Acceptance | breadcrumbs', function (hooks) { test('can navigate via breadcrumbs to project from host catalogs', async function (assert) { assert.expect(3); await visit(hostCatalogsURL); - assert.equal(currentURL(), hostCatalogsURL, 'We begin on th expected page.'); + assert.equal(currentURL(), hostCatalogsURL, 'We begin on the expected page.'); crumbPath = new URL(find('.rose-nav-breadcrumbs-link:last-child').href).pathname; assert.equal(crumbPath, hostCatalogsURL, 'Last crumb has expected URL.'); await click(findAll('.rose-nav-breadcrumbs-link')[1]); @@ -64,7 +76,7 @@ module('Acceptance | breadcrumbs', function (hooks) { test('can navigate via breadcrumbs to host catalogs from host catalog', async function (assert) { assert.expect(3); await visit(hostCatalogURL); - assert.equal(currentURL(), hostCatalogURL, 'We begin on th expected page.'); + assert.equal(currentURL(), hostCatalogURL, 'We begin on the expected page.'); crumbPath = new URL(find('.rose-nav-breadcrumbs-link:last-child').href).pathname; assert.equal(crumbPath, hostCatalogURL, 'Last crumb has expected URL.'); await click(findAll('.rose-nav-breadcrumbs-link')[2]); @@ -74,11 +86,50 @@ module('Acceptance | breadcrumbs', function (hooks) { test('can navigate via breadcrumbs to host catalogs from new host catalog', async function (assert) { assert.expect(3); await visit(newHostCatalogURL); - assert.equal(currentURL(), newHostCatalogURL, 'We begin on th expected page.'); + assert.equal(currentURL(), newHostCatalogURL, 'We begin on the expected page.'); crumbPath = new URL(find('.rose-nav-breadcrumbs-link:last-child').href).pathname; assert.equal(crumbPath, newHostCatalogURL, 'Last crumb has expected URL.'); await click(findAll('.rose-nav-breadcrumbs-link')[2]); assert.equal(currentURL(), hostCatalogsURL, 'After navigating via breadcrumbs, we are one level up.'); }); + test('can navigate via breadcrumbs to roles from role', async function (assert) { + assert.expect(3); + await visit(roleURL); + assert.equal(currentURL(), roleURL, 'We begin on the expected page.'); + crumbPath = new URL(find('.rose-nav-breadcrumbs-link:last-child').href).pathname; + assert.equal(crumbPath, roleURL, 'Last crumb has expected URL.'); + await click(find('.rose-nav-breadcrumbs-link:first-child')); + assert.equal(currentURL(), rolesURL, 'After navigating via breadcrumbs, we are one level up.'); + }); + + test('can navigate via breadcrumbs to roles from new role', async function (assert) { + assert.expect(3); + await visit(newRoleURL); + assert.equal(currentURL(), newRoleURL, 'We begin on the expected page.'); + crumbPath = new URL(find('.rose-nav-breadcrumbs-link:last-child').href).pathname; + assert.equal(crumbPath, newRoleURL, 'Last crumb has expected URL.'); + await click(find('.rose-nav-breadcrumbs-link:first-child')); + assert.equal(currentURL(), rolesURL, 'After navigating via breadcrumbs, we are one level up.'); + }); + + test('can navigate via breadcrumbs to groups from group', async function (assert) { + assert.expect(3); + await visit(groupURL); + assert.equal(currentURL(), groupURL, 'We begin on the expected page.'); + crumbPath = new URL(find('.rose-nav-breadcrumbs-link:last-child').href).pathname; + assert.equal(crumbPath, groupURL, 'Last crumb has expected URL.'); + await click(find('.rose-nav-breadcrumbs-link:first-child')); + assert.equal(currentURL(), groupsURL, 'After navigating via breadcrumbs, we are one level up.'); + }); + + test('can navigate via breadcrumbs to groups from new group', async function (assert) { + assert.expect(3); + await visit(newGroupURL); + assert.equal(currentURL(), newGroupURL, 'We begin on the expected page.'); + crumbPath = new URL(find('.rose-nav-breadcrumbs-link:last-child').href).pathname; + assert.equal(crumbPath, newGroupURL, 'Last crumb has expected URL.'); + await click(find('.rose-nav-breadcrumbs-link:first-child')); + assert.equal(currentURL(), groupsURL, 'After navigating via breadcrumbs, we are one level up.'); + }); }); diff --git a/ui/core/tests/unit/controllers/orgs/org/groups-test.js b/ui/core/tests/unit/controllers/orgs/org/groups-test.js new file mode 100644 index 000000000..0ca58eed0 --- /dev/null +++ b/ui/core/tests/unit/controllers/orgs/org/groups-test.js @@ -0,0 +1,12 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Controller | orgs/org/groups', function(hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function(assert) { + let controller = this.owner.lookup('controller:orgs/org/groups'); + assert.ok(controller); + }); +}); diff --git a/ui/core/tests/unit/controllers/orgs/org/groups/group-test.js b/ui/core/tests/unit/controllers/orgs/org/groups/group-test.js new file mode 100644 index 000000000..49cf5b3a6 --- /dev/null +++ b/ui/core/tests/unit/controllers/orgs/org/groups/group-test.js @@ -0,0 +1,12 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Controller | orgs/org/groups/group', function(hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function(assert) { + let controller = this.owner.lookup('controller:orgs/org/groups/group'); + assert.ok(controller); + }); +}); diff --git a/ui/core/tests/unit/controllers/orgs/org/groups/new-test.js b/ui/core/tests/unit/controllers/orgs/org/groups/new-test.js new file mode 100644 index 000000000..ef02542c9 --- /dev/null +++ b/ui/core/tests/unit/controllers/orgs/org/groups/new-test.js @@ -0,0 +1,12 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Controller | orgs/org/groups/new', function(hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function(assert) { + let controller = this.owner.lookup('controller:orgs/org/groups/new'); + assert.ok(controller); + }); +}); From 14e3373398b0d5ed68605750332ed86e0b57819c Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Wed, 24 Jun 2020 17:51:01 -0400 Subject: [PATCH 7/8] =?UTF-8?q?chore:=20=F0=9F=A4=96=20Add=20groups=20acce?= =?UTF-8?q?ptance=20testcase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/core/tests/acceptance/groups-test.js | 192 ++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 ui/core/tests/acceptance/groups-test.js diff --git a/ui/core/tests/acceptance/groups-test.js b/ui/core/tests/acceptance/groups-test.js new file mode 100644 index 000000000..7f3f2ec69 --- /dev/null +++ b/ui/core/tests/acceptance/groups-test.js @@ -0,0 +1,192 @@ +import { module, test } from 'qunit'; +import { visit, currentURL, click, fillIn, find } from '@ember/test-helpers'; +import { setupApplicationTest } from 'ember-qunit'; +import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; +import a11yAudit from 'ember-a11y-testing/test-support/audit'; +import { Response } from 'miragejs'; + + +module('Acceptance | groups', function(hooks) { + setupApplicationTest(hooks); + setupMirage(hooks); + + hooks.beforeEach(function () { + this.server.create('org'); + }); + + test('visiting groups', async function (assert) { + assert.expect(1); + await visit('/orgs/1/groups'); + await a11yAudit(); + assert.equal(currentURL(), '/orgs/1/groups'); + }); + + test('can create new group', async function (assert) { + assert.expect(4); + assert.equal(this.server.db.groups.length, 0); + await visit('/orgs/1/groups/new'); + await fillIn('[name="name"]', 'group name'); + await click('[type="submit"]'); + assert.equal(currentURL(), '/orgs/1/groups/1'); + assert.equal(this.server.db.groups.length, 1); + assert.equal(this.server.db.groups[0].name, 'group name'); + }); + + test('can cancel new group creation', async function (assert) { + assert.expect(3); + assert.equal(this.server.db.groups.length, 0); + await visit('/orgs/1/groups/new'); + await fillIn('[name="name"]', 'group name'); + await click('.rose-form-actions [type="button"]'); + assert.equal(currentURL(), '/orgs/1/groups'); + assert.equal(this.server.db.groups.length, 0); + }); + + test('saving a new group with invalid fields displays error messages', async function (assert) { + assert.expect(2); + this.server.post('/orgs/:org_id/groups', () => { + return new Response( + 400, + {}, + { + status: 400, + code: 'invalid_argument', + message: 'The request was invalid.', + details: { + fields: [ + { + name: 'name', + message: 'Name is required.', + }, + ], + }, + } + ); + }); + await visit('/orgs/1/groups/new'); + await fillIn('[name="name"]', 'group name'); + await click('[type="submit"]'); + assert.ok( + find('[role="alert"]').textContent.trim(), + 'The request was invalid.', + 'Displays primary error message.' + ); + assert.ok( + find('.rose-form-error-message').textContent.trim(), + 'Name is required.', + 'Displays field-level errors.' + ); + }); + + test('can save changes to an existing group', async function (assert) { + assert.expect(2); + this.server.createList('group', 1, {name: 'Admin group'}); + await visit('/orgs/1/groups/1'); + await fillIn('[name="name"]', 'Updated admin group'); + await click('.rose-form-actions [type="submit"]'); + assert.equal(currentURL(), '/orgs/1/groups/1'); + assert.equal(this.server.db.groups[0].name, 'Updated admin group'); + }); + + test('can cancel changes to an existing group', async function (assert) { + assert.expect(1); + this.server.createList('group', 1, {name: 'Admin group'}); + await visit('/orgs/1/groups/1'); + await fillIn('[name="name"]', 'Updated admin group'); + await click('.rose-form-actions [type="button"]'); + assert.equal(find('[name="name"]').value, 'Admin group'); + }); + + test('can delete a group', async function(assert) { + assert.expect(2); + this.server.createList('group', 1); + assert.equal(this.server.db.groups.length, 1); + await visit('/orgs/1/groups/1'); + await click('.rose-button-warning'); + assert.equal(this.server.db.groups.length, 0); + }); + + test('saving an existing group with invalid fields displays error messages', async function (assert) { + assert.expect(2); + this.server.createList('group', 1); + this.server.patch('/orgs/:org_id/groups/:id', () => { + return new Response( + 400, + {}, + { + status: 400, + code: 'invalid_argument', + message: 'The request was invalid.', + details: { + fields: [ + { + name: 'name', + message: 'Name is required.', + }, + ], + }, + } + ); + }); + await visit('/orgs/1/groups/1'); + await fillIn('[name="name"]', 'random string'); + await click('[type="submit"]'); + assert.ok( + find('[role="alert"]').textContent.trim(), + 'The request was invalid.', + 'Displays primary error message.' + ); + assert.ok( + find('.rose-form-error-message').textContent.trim(), + 'Name is required.', + 'Displays field-level errors.' + ); + }); + + test('errors are displayed when save project fails', async function (assert) { + assert.expect(1); + this.server.createList('group', 1); + this.server.patch('/orgs/:org_id/groups/:id', () => { + return new Response( + 490, + {}, + { + status: 490, + code: 'error', + message: 'Oops.', + } + ); + }); + await visit('/orgs/1/groups/1'); + await fillIn('[name="name"]', 'Role name'); + await click('[type="submit"]'); + assert.ok( + find('[role="alert"]').textContent.trim(), + 'Oops.', + 'Displays primary error message.' + ); + }); + + test('errors are displayed when delete project fails', async function (assert) { + assert.expect(1); + this.server.createList('group', 1); + this.server.del('/orgs/:org_id/groups/:id', () => { + return new Response( + 490, + {}, + { + status: 490, + code: 'error', + message: 'Oops.', + } + ); + }); + await visit('/orgs/1/groups/1'); + await click('.rose-button-warning'); + assert.ok( + find('[role="alert"]').textContent.trim(), + 'Oops.', + 'Displays primary error message.' + ); + }); +}); From d688f55d714ac1c9d23b223f6bde26ada3fc1621 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Mon, 29 Jun 2020 10:38:02 -0400 Subject: [PATCH 8/8] =?UTF-8?q?chore:=20=F0=9F=A4=96=20Update=20groups=20b?= =?UTF-8?q?readcrumbs=20after=20refresh=20from=20develop?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update form errors in ui/core to use model errors object --- addons/api/tests/unit/adapters/group-test.js | 11 ++++++++++- ui/core/app/components/form/group/index.hbs | 2 +- ui/core/app/components/form/host-catalog/index.hbs | 2 +- ui/core/app/components/form/project/index.hbs | 2 +- ui/core/app/components/form/role/index.hbs | 2 +- ui/core/app/controllers/orgs/org/groups/group.js | 2 +- ui/core/app/routes/orgs/org/groups.js | 4 ++-- 7 files changed, 17 insertions(+), 8 deletions(-) diff --git a/addons/api/tests/unit/adapters/group-test.js b/addons/api/tests/unit/adapters/group-test.js index d39297843..2c1c53d3c 100644 --- a/addons/api/tests/unit/adapters/group-test.js +++ b/addons/api/tests/unit/adapters/group-test.js @@ -1,12 +1,21 @@ import { module, test } from 'qunit'; import { setupTest } from 'ember-qunit'; +import config from 'ember-get-config'; module('Unit | Adapter | group', function(hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function(assert) { let adapter = this.owner.lookup('adapter:group'); assert.ok(adapter); }); + + test('it generates URL prefixes without project scope', function (assert) { + assert.expect(1); + const service = this.owner.lookup('service:scope'); + service.org = { id: 1 }; + service.project = { id: 2 }; + const adapter = this.owner.lookup('adapter:group'); + assert.equal(adapter.urlPrefix(), `${config.api.namespace}/orgs/1`); + }); }); diff --git a/ui/core/app/components/form/group/index.hbs b/ui/core/app/components/form/group/index.hbs index 9db695baa..e8d100b60 100644 --- a/ui/core/app/components/form/group/index.hbs +++ b/ui/core/app/components/form/group/index.hbs @@ -2,7 +2,7 @@ @onSubmit={{@submit}} @cancel={{@cancel}} @disabled={{@model.isSaving}} - @error={{true}} + @error={{@model.errors.base}} as |form| > diff --git a/ui/core/app/components/form/host-catalog/index.hbs b/ui/core/app/components/form/host-catalog/index.hbs index 9db695baa..e8d100b60 100644 --- a/ui/core/app/components/form/host-catalog/index.hbs +++ b/ui/core/app/components/form/host-catalog/index.hbs @@ -2,7 +2,7 @@ @onSubmit={{@submit}} @cancel={{@cancel}} @disabled={{@model.isSaving}} - @error={{true}} + @error={{@model.errors.base}} as |form| > diff --git a/ui/core/app/components/form/project/index.hbs b/ui/core/app/components/form/project/index.hbs index 9db695baa..e8d100b60 100644 --- a/ui/core/app/components/form/project/index.hbs +++ b/ui/core/app/components/form/project/index.hbs @@ -2,7 +2,7 @@ @onSubmit={{@submit}} @cancel={{@cancel}} @disabled={{@model.isSaving}} - @error={{true}} + @error={{@model.errors.base}} as |form| > diff --git a/ui/core/app/components/form/role/index.hbs b/ui/core/app/components/form/role/index.hbs index 9db695baa..e8d100b60 100644 --- a/ui/core/app/components/form/role/index.hbs +++ b/ui/core/app/components/form/role/index.hbs @@ -2,7 +2,7 @@ @onSubmit={{@submit}} @cancel={{@cancel}} @disabled={{@model.isSaving}} - @error={{true}} + @error={{@model.errors.base}} as |form| > diff --git a/ui/core/app/controllers/orgs/org/groups/group.js b/ui/core/app/controllers/orgs/org/groups/group.js index 60ed4c93c..972fb39ed 100644 --- a/ui/core/app/controllers/orgs/org/groups/group.js +++ b/ui/core/app/controllers/orgs/org/groups/group.js @@ -7,6 +7,6 @@ export default class OrgsOrgGroupsGroupController extends Controller { /** * @type {string} */ - @alias('model.name') breadCrumb; + @alias('model.displayName') breadCrumb; } diff --git a/ui/core/app/routes/orgs/org/groups.js b/ui/core/app/routes/orgs/org/groups.js index c17d210d1..80bb0af1a 100644 --- a/ui/core/app/routes/orgs/org/groups.js +++ b/ui/core/app/routes/orgs/org/groups.js @@ -4,8 +4,8 @@ export default class OrgsOrgGroupsRoute extends Route { // =methods /** - * Returns all roles from store. - * @return {Promise[RoleModel]} + * Returns all groups from store. + * @return {Promise[GroupModel]} */ model() { return this.store.findAll('group');