From 748e42a64fddde5eaa3d19305977190c5fd20352 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Fri, 21 Aug 2020 11:48:24 -0400 Subject: [PATCH 1/8] chore: Add target model to addons/api --- addons/api/addon/generated/models/target.js | 37 +++++++++++++++++++++ addons/api/addon/models/target.js | 3 ++ addons/api/app/models/target.js | 1 + addons/api/tests/unit/models/target-test.js | 13 ++++++++ 4 files changed, 54 insertions(+) create mode 100644 addons/api/addon/generated/models/target.js create mode 100644 addons/api/addon/models/target.js create mode 100644 addons/api/app/models/target.js create mode 100644 addons/api/tests/unit/models/target-test.js diff --git a/addons/api/addon/generated/models/target.js b/addons/api/addon/generated/models/target.js new file mode 100644 index 000000000..5c053d46a --- /dev/null +++ b/addons/api/addon/generated/models/target.js @@ -0,0 +1,37 @@ +import BaseModel from '../../models/base'; +import { attr } from '@ember-data/model'; + +/** + * Target + */ +export default class GeneratedTargetModel extends BaseModel { + + // =attributes + + @attr('string', { + description: 'The protocol used in the target' + }) protocol; + + @attr('string', { + description: 'Optional name for identification purposes' + }) name; + + @attr('string', { + description: 'Optional user-set description for identification purposes' + }) description; + + @attr('date', { + description: 'The time this resource was created\nOutput only.', + readOnly: true + }) created_time; + + @attr('date', { + description: 'The time this resource was last updated\nOutput only.', + readOnly: true + }) updated_time; + + @attr('boolean', { + description: 'Whether the catalog is disabled' + }) disabled; + +} diff --git a/addons/api/addon/models/target.js b/addons/api/addon/models/target.js new file mode 100644 index 000000000..68ac7904f --- /dev/null +++ b/addons/api/addon/models/target.js @@ -0,0 +1,3 @@ +import GeneratedUserModel from '../generated/models/target'; + +export default class TargetModel extends GeneratedTargetModel {} diff --git a/addons/api/app/models/target.js b/addons/api/app/models/target.js new file mode 100644 index 000000000..a5b0bca2f --- /dev/null +++ b/addons/api/app/models/target.js @@ -0,0 +1 @@ +export { default } from 'api/models/target'; diff --git a/addons/api/tests/unit/models/target-test.js b/addons/api/tests/unit/models/target-test.js new file mode 100644 index 000000000..78fc71e43 --- /dev/null +++ b/addons/api/tests/unit/models/target-test.js @@ -0,0 +1,13 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Model | target', function(hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function(assert) { + let store = this.owner.lookup('service:store'); + let model = store.createRecord('target', {}); + assert.ok(model); + }); +}); From 639325ddd6836644778e4215bb96998624b146c3 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Fri, 21 Aug 2020 11:53:53 -0400 Subject: [PATCH 2/8] chore: Add target mirage config --- addons/api/addon/models/target.js | 2 +- ui/core/mirage/config.js | 8 ++++++++ ui/core/mirage/factories/target.js | 3 +++ ui/core/mirage/generated/factories/target.js | 16 ++++++++++++++++ ui/core/mirage/scenarios/default.js | 4 ++++ ui/core/mirage/serializers/target.js | 5 +++++ 6 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 ui/core/mirage/factories/target.js create mode 100644 ui/core/mirage/generated/factories/target.js create mode 100644 ui/core/mirage/serializers/target.js diff --git a/addons/api/addon/models/target.js b/addons/api/addon/models/target.js index 68ac7904f..84b2658dc 100644 --- a/addons/api/addon/models/target.js +++ b/addons/api/addon/models/target.js @@ -1,3 +1,3 @@ -import GeneratedUserModel from '../generated/models/target'; +import GeneratedTargetModel from '../generated/models/target'; export default class TargetModel extends GeneratedTargetModel {} diff --git a/ui/core/mirage/config.js b/ui/core/mirage/config.js index 4f69c6f33..56ebd68d0 100644 --- a/ui/core/mirage/config.js +++ b/ui/core/mirage/config.js @@ -123,6 +123,14 @@ export default function() { return hostSet.update(attrs); }); + // target + + this.get('/scopes/:scope_id/targets'); + this.post('/scopes/:scope_id/targets'); + this.get('/scopes/:scope_id/targets/:id'); + this.patch('/scopes/:scope_id/targets/:id'); + this.del('/scopes/:scope_id/targets/:id'); + // Uncomment the following line and the Response import above // Then change the response code to simulate error responses. // this.get('/scopes/:scope_id/projects', () => new Response(505)); diff --git a/ui/core/mirage/factories/target.js b/ui/core/mirage/factories/target.js new file mode 100644 index 000000000..b664ff88a --- /dev/null +++ b/ui/core/mirage/factories/target.js @@ -0,0 +1,3 @@ +import factory from '../generated/factories/target'; + +export default factory.extend(); diff --git a/ui/core/mirage/generated/factories/target.js b/ui/core/mirage/generated/factories/target.js new file mode 100644 index 000000000..5033064c8 --- /dev/null +++ b/ui/core/mirage/generated/factories/target.js @@ -0,0 +1,16 @@ +import { Factory } from 'ember-cli-mirage'; +import { random, date } from 'faker'; + +/** + * GeneratedTargetModelFactory + */ +export default Factory.extend({ + + protocol: 'SSH', + 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 a4fec0451..f09f7dac8 100644 --- a/ui/core/mirage/scenarios/default.js +++ b/ui/core/mirage/scenarios/default.js @@ -35,4 +35,8 @@ export default function(server) { server.createList('host-catalog', 2, { scope }, 'withChildren'); }); + // Target + + server.createList('target', 5, { scope }); + } diff --git a/ui/core/mirage/serializers/target.js b/ui/core/mirage/serializers/target.js new file mode 100644 index 000000000..3d4bc5f3e --- /dev/null +++ b/ui/core/mirage/serializers/target.js @@ -0,0 +1,5 @@ +import ApplicationSerializer from './application'; + +export default ApplicationSerializer.extend({ + modelName: 'target' +}); From b63cd95cc2d7888e9fe318b516d3460f0c0c71e1 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Fri, 21 Aug 2020 12:21:14 -0400 Subject: [PATCH 3/8] chore: List targets under a project scope --- ui/core/app/router.js | 1 + .../scopes/scope/projects/project/targets.js | 14 +++++ .../scope/projects/project/targets/index.js | 4 ++ .../scope/projects/project/_sidebar.hbs | 3 ++ .../scopes/scope/projects/project/targets.hbs | 3 ++ .../scope/projects/project/targets/index.hbs | 53 +++++++++++++++++++ ui/core/mirage/scenarios/default.js | 7 +-- .../scope/projects/project/targets-test.js | 11 ++++ .../projects/project/targets/index-test.js | 11 ++++ ui/core/translations/en-us.yaml | 9 ++++ 10 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 ui/core/app/routes/scopes/scope/projects/project/targets.js create mode 100644 ui/core/app/routes/scopes/scope/projects/project/targets/index.js create mode 100644 ui/core/app/templates/scopes/scope/projects/project/targets.hbs create mode 100644 ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs create mode 100644 ui/core/tests/unit/routes/scopes/scope/projects/project/targets-test.js create mode 100644 ui/core/tests/unit/routes/scopes/scope/projects/project/targets/index-test.js diff --git a/ui/core/app/router.js b/ui/core/app/router.js index 4243d97b5..eb486f950 100644 --- a/ui/core/app/router.js +++ b/ui/core/app/router.js @@ -29,6 +29,7 @@ Router.map(function () { }); }); }); + this.route('targets', function() {}); }); this.route('new'); }); diff --git a/ui/core/app/routes/scopes/scope/projects/project/targets.js b/ui/core/app/routes/scopes/scope/projects/project/targets.js new file mode 100644 index 000000000..91f399648 --- /dev/null +++ b/ui/core/app/routes/scopes/scope/projects/project/targets.js @@ -0,0 +1,14 @@ +import Route from '@ember/routing/route'; + +export default class ScopesScopeProjectsProjectTargetsRoute extends Route { + // =methods + + /** + * Loads all targets under current project scope. + * @return {Promise{[TargetModel]}} + */ + async model() { + const scopeID = this.modelFor('scopes.scope.projects.project').id; + return this.store.findAll('target', { adapterOptions: { scopeID } }); + } +} diff --git a/ui/core/app/routes/scopes/scope/projects/project/targets/index.js b/ui/core/app/routes/scopes/scope/projects/project/targets/index.js new file mode 100644 index 000000000..0506aa8da --- /dev/null +++ b/ui/core/app/routes/scopes/scope/projects/project/targets/index.js @@ -0,0 +1,4 @@ +import Route from '@ember/routing/route'; + +export default class ScopesScopeProjectsProjectTargetsIndexRoute extends Route { +} diff --git a/ui/core/app/templates/scopes/scope/projects/project/_sidebar.hbs b/ui/core/app/templates/scopes/scope/projects/project/_sidebar.hbs index 8f46f6113..ae4f79e0b 100644 --- a/ui/core/app/templates/scopes/scope/projects/project/_sidebar.hbs +++ b/ui/core/app/templates/scopes/scope/projects/project/_sidebar.hbs @@ -1,4 +1,7 @@ + + {{t "resources.targets"}} + {{t "resources.host-catalogs"}} diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets.hbs new file mode 100644 index 000000000..744cee2b2 --- /dev/null +++ b/ui/core/app/templates/scopes/scope/projects/project/targets.hbs @@ -0,0 +1,3 @@ +{{title (t "resources.targets")}} + +{{outlet}} diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs new file mode 100644 index 000000000..113b126dc --- /dev/null +++ b/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs @@ -0,0 +1,53 @@ + + + +

{{t "resources.targets"}}

+
+ + + + {{#if @model}} + + + + + {{t "form.label.name"}} + {{t "form.label.protocol"}} + {{t "form.label.id"}} + + + + {{#each @model as |target|}} + + + {{target.displayName}} +

{{target.description}}

+
+ + + {{t (concat "target.protocols." target.protocol)}} + + + + {{target.id}} + +
+ {{/each}} +
+
+ + {{else}} + + + + + {{t "descriptions.targets-welcome"}} + + + + + {{/if}} + +
+ +
diff --git a/ui/core/mirage/scenarios/default.js b/ui/core/mirage/scenarios/default.js index f09f7dac8..439b9fd01 100644 --- a/ui/core/mirage/scenarios/default.js +++ b/ui/core/mirage/scenarios/default.js @@ -33,10 +33,7 @@ export default function(server) { server.db.scopes.where({type: 'project'}).forEach(({ id, type }) => { const scope = { id, type }; server.createList('host-catalog', 2, { scope }, 'withChildren'); + server.createList('target', 2, { scope }); }); - - // Target - - server.createList('target', 5, { scope }); - + } diff --git a/ui/core/tests/unit/routes/scopes/scope/projects/project/targets-test.js b/ui/core/tests/unit/routes/scopes/scope/projects/project/targets-test.js new file mode 100644 index 000000000..ca2ead9ca --- /dev/null +++ b/ui/core/tests/unit/routes/scopes/scope/projects/project/targets-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Route | scopes/scope/projects/project/targets', function(hooks) { + setupTest(hooks); + + test('it exists', function(assert) { + let route = this.owner.lookup('route:scopes/scope/projects/project/targets'); + assert.ok(route); + }); +}); diff --git a/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/index-test.js b/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/index-test.js new file mode 100644 index 000000000..fa478cbe9 --- /dev/null +++ b/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/index-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Route | scopes/scope/projects/project/targets/index', function(hooks) { + setupTest(hooks); + + test('it exists', function(assert) { + let route = this.owner.lookup('route:scopes/scope/projects/project/targets/index'); + assert.ok(route); + }); +}); diff --git a/ui/core/translations/en-us.yaml b/ui/core/translations/en-us.yaml index 125b3b75c..b2d630279 100644 --- a/ui/core/translations/en-us.yaml +++ b/ui/core/translations/en-us.yaml @@ -31,6 +31,10 @@ auth: host-set: types: static: Static +target: + protocols: + ssh: SSH + SSH: SSH resources: user: User users: Users @@ -48,6 +52,7 @@ resources: auth-methods: Auth Methods host-set: Host Set host-sets: Host Sets + targets: Targets titles: iam: IAM new: New @@ -64,10 +69,12 @@ titles: roles-welcome: Welcome to Roles groups-welcome: Welcome to Groups auth-methods-welcome: Welcome to Auth Methods + targets-welcome: Create your first Target grants: Permissions new-grant: New Grant principals: Principals host-sets: Host Sets + targets: Targets global: Global descriptions: host-catalogs: Overview of collections of hosts and host sets. @@ -79,6 +86,7 @@ descriptions: roles-welcome: Roles are collections of capabilities that can be granted to user and/or groups. groups-welcome: Groups are collections of users. auth-methods-welcome: Auth methods are configurations to authenticate users. + targets-welcome: Targets provide Users the means to connect to and interact networked services. A Target contains a collection of Hosts and a collection of Credentials. states: info: Info success: Success @@ -95,6 +103,7 @@ form: manage: Manage grant: Grant principal: Principal + protocol: Protocol errors: titles: unauthenticated-error: You are not signed in From 56a059ba962c4eeabaaed749665643ba68d400c5 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Fri, 21 Aug 2020 12:52:23 -0400 Subject: [PATCH 4/8] chore: Add save and delete workflow to a target --- ui/core/app/components/form/target/index.hbs | 49 +++++++++++++++ ui/core/app/router.js | 4 +- .../project/host-catalogs/host-catalog.js | 2 +- .../scopes/scope/projects/project/targets.js | 60 +++++++++++++++++++ .../scope/projects/project/targets/target.js | 18 ++++++ .../projects/project/targets/target/index.js | 4 ++ .../scope/projects/project/targets/index.hbs | 7 ++- .../scope/projects/project/targets/target.hbs | 1 + .../projects/project/targets/target/index.hbs | 35 +++++++++++ .../components/form/target-test.js | 23 +++++++ .../projects/project/targets/target-test.js | 11 ++++ .../project/targets/target/index-test.js | 11 ++++ ui/core/translations/en-us.yaml | 2 + 13 files changed, 224 insertions(+), 3 deletions(-) create mode 100644 ui/core/app/components/form/target/index.hbs create mode 100644 ui/core/app/routes/scopes/scope/projects/project/targets/target.js create mode 100644 ui/core/app/routes/scopes/scope/projects/project/targets/target/index.js create mode 100644 ui/core/app/templates/scopes/scope/projects/project/targets/target.hbs create mode 100644 ui/core/app/templates/scopes/scope/projects/project/targets/target/index.hbs create mode 100644 ui/core/tests/integration/components/form/target-test.js create mode 100644 ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target-test.js create mode 100644 ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target/index-test.js diff --git a/ui/core/app/components/form/target/index.hbs b/ui/core/app/components/form/target/index.hbs new file mode 100644 index 000000000..45adc26d0 --- /dev/null +++ b/ui/core/app/components/form/target/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/router.js b/ui/core/app/router.js index eb486f950..34435c631 100644 --- a/ui/core/app/router.js +++ b/ui/core/app/router.js @@ -29,7 +29,9 @@ Router.map(function () { }); }); }); - this.route('targets', function() {}); + this.route('targets', function() { + this.route('target', { path: ':target_id' }, function() {}); + }); }); this.route('new'); }); diff --git a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog.js b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog.js index 7247e9446..b9afbdf98 100644 --- a/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog.js +++ b/ui/core/app/routes/scopes/scope/projects/project/host-catalogs/host-catalog.js @@ -17,7 +17,7 @@ export default class ScopesScopeProjectsProjectHostCatalogsHostCatalogRoute exte }); } - /** + /** * Renders the host-catalog specific templates for header, navigation, and actions page sections. * @override * @param {object} controller 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 91f399648..acb1e07cc 100644 --- a/ui/core/app/routes/scopes/scope/projects/project/targets.js +++ b/ui/core/app/routes/scopes/scope/projects/project/targets.js @@ -1,6 +1,14 @@ import Route from '@ember/routing/route'; +import { inject as service } from '@ember/service'; +import { action } from '@ember/object'; export default class ScopesScopeProjectsProjectTargetsRoute extends Route { + + // =services + + @service intl; + @service notify; + // =methods /** @@ -11,4 +19,56 @@ export default class ScopesScopeProjectsProjectTargetsRoute extends Route { const scopeID = this.modelFor('scopes.scope.projects.project').id; return this.store.findAll('target', { adapterOptions: { scopeID } }); } + + // =actions + + /** + * Rollback changes on a target. + * @param {TargetModel} target + */ + @action + cancel(target) { + const { isNew } = target; + target.rollbackAttributes(); + if (isNew) this.transitionTo('scopes.scope.projects.project.targets'); + } + + /** + * Handle save. + * @param {TargetModel} target + * @param {Event} e + */ + @action + async save(target) { + const { isNew } = target; + try { + await target.save(); + this.refresh(); + this.notify.success( + this.intl.t(isNew ? 'notify.create-success' : 'notify.save-success') + ); + this.transitionTo('scopes.scope.projects.project.targets.target', target); + } catch (error) { + // TODO: replace with translated strings + this.notify.error(error.message, { closeAfter: null }); + } + } + + /** + * Deletes a target and redirects to targets index. + * @param {TargetModel} target + */ + @action + async delete(target) { + try { + await target.destroyRecord(); + this.refresh(); + this.notify.success(this.intl.t('notify.delete-success')); + this.transitionTo('scopes.scope.projects.project.targets'); + } catch (error) { + // TODO: replace with translated strings + this.notify.error(error.message, { closeAfter: null }); + } + } + } diff --git a/ui/core/app/routes/scopes/scope/projects/project/targets/target.js b/ui/core/app/routes/scopes/scope/projects/project/targets/target.js new file mode 100644 index 000000000..8b5cf77ab --- /dev/null +++ b/ui/core/app/routes/scopes/scope/projects/project/targets/target.js @@ -0,0 +1,18 @@ +import Route from '@ember/routing/route'; + +export default class ScopesScopeProjectsProjectTargetsTargetRoute extends Route { + + // =methods + + /** + * Load a target. + * @param {object} params + * @param {string} params.target_id + * @return {TargetModel} + */ + async model({ target_id }) { + const { id: scopeID } = this.modelFor('scopes.scope.projects.project'); + return this.store.findRecord('target', target_id, { adapterOptions: { scopeID } }); + } + +} diff --git a/ui/core/app/routes/scopes/scope/projects/project/targets/target/index.js b/ui/core/app/routes/scopes/scope/projects/project/targets/target/index.js new file mode 100644 index 000000000..ff772f61f --- /dev/null +++ b/ui/core/app/routes/scopes/scope/projects/project/targets/target/index.js @@ -0,0 +1,4 @@ +import Route from '@ember/routing/route'; + +export default class ScopesScopeProjectsProjectTargetsTargetIndexRoute extends Route { +} diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs index 113b126dc..8d330854c 100644 --- a/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs +++ b/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs @@ -20,7 +20,12 @@ {{#each @model as |target|}} - {{target.displayName}} + + {{target.displayName}} +

{{target.description}}

diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/target.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/target.hbs new file mode 100644 index 000000000..e2147cab0 --- /dev/null +++ b/ui/core/app/templates/scopes/scope/projects/project/targets/target.hbs @@ -0,0 +1 @@ +{{outlet}} \ No newline at end of file diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/target/index.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/target/index.hbs new file mode 100644 index 000000000..64fc6b7d2 --- /dev/null +++ b/ui/core/app/templates/scopes/scope/projects/project/targets/target/index.hbs @@ -0,0 +1,35 @@ + + + +

{{t "resources.target"}}

+
+ + + + + {{t 'titles.details'}} + + + + + + + + {{t 'actions.delete-target'}} + + + + + + + + +
diff --git a/ui/core/tests/integration/components/form/target-test.js b/ui/core/tests/integration/components/form/target-test.js new file mode 100644 index 000000000..e0246833f --- /dev/null +++ b/ui/core/tests/integration/components/form/target-test.js @@ -0,0 +1,23 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, find } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Component | form/target', function (hooks) { + setupRenderingTest(hooks); + + test('it renders', async function (assert) { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.set('myAction', function(val) { ... }); + this.submit = () => {}; + this.cancel = () => {}; + + await render(hbs` + `); + + assert.ok(find('form')); + }); +}); diff --git a/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target-test.js b/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target-test.js new file mode 100644 index 000000000..0fa4c6fc5 --- /dev/null +++ b/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Route | scopes/scope/projects/project/targets/target', function(hooks) { + setupTest(hooks); + + test('it exists', function(assert) { + let route = this.owner.lookup('route:scopes/scope/projects/project/targets/target'); + assert.ok(route); + }); +}); diff --git a/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target/index-test.js b/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target/index-test.js new file mode 100644 index 000000000..5b1f35962 --- /dev/null +++ b/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/target/index-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Route | scopes/scope/projects/project/targets/target/index', function(hooks) { + setupTest(hooks); + + test('it exists', function(assert) { + let route = this.owner.lookup('route:scopes/scope/projects/project/targets/target/index'); + assert.ok(route); + }); +}); diff --git a/ui/core/translations/en-us.yaml b/ui/core/translations/en-us.yaml index b2d630279..20114979f 100644 --- a/ui/core/translations/en-us.yaml +++ b/ui/core/translations/en-us.yaml @@ -16,6 +16,7 @@ actions: delete-host-catalog: Delete host catalog delete-auth-method: Delete auth method delete-host-set: Delete host set + delete-target: Delete target add-host-set: Create Host Set auth: titles: @@ -52,6 +53,7 @@ resources: auth-methods: Auth Methods host-set: Host Set host-sets: Host Sets + target: Target targets: Targets titles: iam: IAM From 286a994896333f75341caf21f2fb5fee10fa6c4c Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Fri, 21 Aug 2020 13:14:21 -0400 Subject: [PATCH 5/8] chore: Add new target route --- ui/core/app/router.js | 1 + .../scope/projects/project/targets/new.js | 16 +++++++++++++++ .../scope/projects/project/targets/index.hbs | 20 ++++++++++++++++--- .../scope/projects/project/targets/new.hbs | 17 ++++++++++++++++ .../projects/project/targets/new-test.js | 11 ++++++++++ 5 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 ui/core/app/routes/scopes/scope/projects/project/targets/new.js create mode 100644 ui/core/app/templates/scopes/scope/projects/project/targets/new.hbs create mode 100644 ui/core/tests/unit/routes/scopes/scope/projects/project/targets/new-test.js diff --git a/ui/core/app/router.js b/ui/core/app/router.js index 34435c631..a047d9042 100644 --- a/ui/core/app/router.js +++ b/ui/core/app/router.js @@ -31,6 +31,7 @@ Router.map(function () { }); this.route('targets', function() { this.route('target', { path: ':target_id' }, function() {}); + this.route('new'); }); }); this.route('new'); diff --git a/ui/core/app/routes/scopes/scope/projects/project/targets/new.js b/ui/core/app/routes/scopes/scope/projects/project/targets/new.js new file mode 100644 index 000000000..000752c13 --- /dev/null +++ b/ui/core/app/routes/scopes/scope/projects/project/targets/new.js @@ -0,0 +1,16 @@ +import Route from '@ember/routing/route'; + +export default class ScopesScopeProjectsProjectTargetsNewRoute extends Route { + + // =methods + + /** + * Creates a new unsaved target in current project scope. + * @return {TargetModel} + */ + model() { + const scopeModel = this.modelFor('scopes.scope.projects.project'); + return this.store.createRecord('target', { scopeModel }); + } + +} diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs index 8d330854c..20b6f19ee 100644 --- a/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs +++ b/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs @@ -4,6 +4,14 @@

{{t "resources.targets"}}

+ + {{#if @model}} + + {{t "titles.new"}} + + {{/if}} + + {{#if @model}} @@ -29,9 +37,11 @@

{{target.description}}

- - {{t (concat "target.protocols." target.protocol)}} - + {{#if target.protocol}} + + {{t (concat "target.protocols." target.protocol)}} + + {{/if}} {{target.id}} @@ -48,6 +58,10 @@ {{t "descriptions.targets-welcome"}} + + + {{t "titles.new"}} + diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/new.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/new.hbs new file mode 100644 index 000000000..df5cde8f1 --- /dev/null +++ b/ui/core/app/templates/scopes/scope/projects/project/targets/new.hbs @@ -0,0 +1,17 @@ +{{title (t 'titles.new')}} + + + + +

{{t "titles.new"}}

+
+ + + + + +
diff --git a/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/new-test.js b/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/new-test.js new file mode 100644 index 000000000..dea235c50 --- /dev/null +++ b/ui/core/tests/unit/routes/scopes/scope/projects/project/targets/new-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Route | scopes/scope/projects/project/targets/new', function(hooks) { + setupTest(hooks); + + test('it exists', function(assert) { + let route = this.owner.lookup('route:scopes/scope/projects/project/targets/new'); + assert.ok(route); + }); +}); From 786f8b884713f449a8f536429ee5f0eb740e21f4 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Fri, 21 Aug 2020 13:18:14 -0400 Subject: [PATCH 6/8] chore: Add target breadcrumbs --- .../scopes/scope/projects/project/targets.js | 20 +++++++++++++++++++ .../scope/projects/project/targets/new.js | 20 +++++++++++++++++++ .../scope/projects/project/targets/target.js | 15 ++++++++++++++ .../scope/projects/project/targets/index.hbs | 4 ++++ .../scope/projects/project/targets/new.hbs | 4 ++++ .../projects/project/targets/target/index.hbs | 4 ++++ .../scope/projects/project/targets-test.js | 12 +++++++++++ .../projects/project/targets/new-test.js | 12 +++++++++++ .../projects/project/targets/target-test.js | 12 +++++++++++ 9 files changed, 103 insertions(+) create mode 100644 ui/core/app/controllers/scopes/scope/projects/project/targets.js create mode 100644 ui/core/app/controllers/scopes/scope/projects/project/targets/new.js create mode 100644 ui/core/app/controllers/scopes/scope/projects/project/targets/target.js create mode 100644 ui/core/tests/unit/controllers/scopes/scope/projects/project/targets-test.js create mode 100644 ui/core/tests/unit/controllers/scopes/scope/projects/project/targets/new-test.js create mode 100644 ui/core/tests/unit/controllers/scopes/scope/projects/project/targets/target-test.js diff --git a/ui/core/app/controllers/scopes/scope/projects/project/targets.js b/ui/core/app/controllers/scopes/scope/projects/project/targets.js new file mode 100644 index 000000000..a0d75250f --- /dev/null +++ b/ui/core/app/controllers/scopes/scope/projects/project/targets.js @@ -0,0 +1,20 @@ +import Controller from '@ember/controller'; +import { inject as service } from '@ember/service'; + +export default class ScopesScopeProjectsProjectTargetsController extends Controller { + + // =services + + @service intl; + + // =attributes + + /** + * Targets breadcrumb + * @type {string} + */ + get breadCrumb() { + return this.intl.t('resources.targets'); + } + +} diff --git a/ui/core/app/controllers/scopes/scope/projects/project/targets/new.js b/ui/core/app/controllers/scopes/scope/projects/project/targets/new.js new file mode 100644 index 000000000..035a83756 --- /dev/null +++ b/ui/core/app/controllers/scopes/scope/projects/project/targets/new.js @@ -0,0 +1,20 @@ +import Controller from '@ember/controller'; +import { inject as service } from '@ember/service'; + +export default class ScopesScopeProjectsProjectTargetsNewController extends Controller { + + // =services + + @service intl; + + // =attributes + + /** + * Translated new target breadcrumb + * @type {string} + */ + get breadCrumb() { + return this.intl.t('titles.new'); + } + +} diff --git a/ui/core/app/controllers/scopes/scope/projects/project/targets/target.js b/ui/core/app/controllers/scopes/scope/projects/project/targets/target.js new file mode 100644 index 000000000..0da51ffa4 --- /dev/null +++ b/ui/core/app/controllers/scopes/scope/projects/project/targets/target.js @@ -0,0 +1,15 @@ +import Controller from '@ember/controller'; + +export default class ScopesScopeProjectsProjectTargetsTargetController extends Controller { + + // =attributes + + /** + * A target breadcrumb + * @type {string} + */ + get breadCrumb() { + return this.model.displayName; + } + +} diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs index 20b6f19ee..184dd9910 100644 --- a/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs +++ b/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs @@ -1,5 +1,9 @@ + + + +

{{t "resources.targets"}}

diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/new.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/new.hbs index df5cde8f1..4ac91435b 100644 --- a/ui/core/app/templates/scopes/scope/projects/project/targets/new.hbs +++ b/ui/core/app/templates/scopes/scope/projects/project/targets/new.hbs @@ -2,6 +2,10 @@ + + + +

{{t "titles.new"}}

diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/target/index.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/target/index.hbs index 64fc6b7d2..da4860986 100644 --- a/ui/core/app/templates/scopes/scope/projects/project/targets/target/index.hbs +++ b/ui/core/app/templates/scopes/scope/projects/project/targets/target/index.hbs @@ -1,5 +1,9 @@ + + + +

{{t "resources.target"}}

diff --git a/ui/core/tests/unit/controllers/scopes/scope/projects/project/targets-test.js b/ui/core/tests/unit/controllers/scopes/scope/projects/project/targets-test.js new file mode 100644 index 000000000..908c813bf --- /dev/null +++ b/ui/core/tests/unit/controllers/scopes/scope/projects/project/targets-test.js @@ -0,0 +1,12 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Controller | scopes/scope/projects/project/targets', function(hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function(assert) { + let controller = this.owner.lookup('controller:scopes/scope/projects/project/targets'); + assert.ok(controller); + }); +}); diff --git a/ui/core/tests/unit/controllers/scopes/scope/projects/project/targets/new-test.js b/ui/core/tests/unit/controllers/scopes/scope/projects/project/targets/new-test.js new file mode 100644 index 000000000..d7634fb8c --- /dev/null +++ b/ui/core/tests/unit/controllers/scopes/scope/projects/project/targets/new-test.js @@ -0,0 +1,12 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Controller | scopes/scope/projects/project/targets/new', function(hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function(assert) { + let controller = this.owner.lookup('controller:scopes/scope/projects/project/targets/new'); + assert.ok(controller); + }); +}); diff --git a/ui/core/tests/unit/controllers/scopes/scope/projects/project/targets/target-test.js b/ui/core/tests/unit/controllers/scopes/scope/projects/project/targets/target-test.js new file mode 100644 index 000000000..839332da1 --- /dev/null +++ b/ui/core/tests/unit/controllers/scopes/scope/projects/project/targets/target-test.js @@ -0,0 +1,12 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Controller | scopes/scope/projects/project/targets/target', function(hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function(assert) { + let controller = this.owner.lookup('controller:scopes/scope/projects/project/targets/target'); + assert.ok(controller); + }); +}); From 0d93a839c73aabf97204640403cc38f0abda1ef3 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Fri, 21 Aug 2020 13:22:00 -0400 Subject: [PATCH 7/8] chore: Update target tests --- ui/core/tests/acceptance/host-sets-test.js | 4 +- ui/core/tests/acceptance/targets-test.js | 61 ++++++++++++++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 ui/core/tests/acceptance/targets-test.js diff --git a/ui/core/tests/acceptance/host-sets-test.js b/ui/core/tests/acceptance/host-sets-test.js index f7ba7226d..b018fc1d8 100644 --- a/ui/core/tests/acceptance/host-sets-test.js +++ b/ui/core/tests/acceptance/host-sets-test.js @@ -47,7 +47,7 @@ module('Acceptance | host sets', function (hooks) { assert.expect(0); }); - test('errors are displayed when save on auth method fails', async function (assert) { + test('errors are displayed when save on host set fails', async function (assert) { assert.expect(0); }); @@ -55,7 +55,7 @@ module('Acceptance | host sets', function (hooks) { assert.expect(0); }); - test('saving an existing auth method with invalid fields displays error messages', async function (assert) { + test('saving an existing host set with invalid fields displays error messages', async function (assert) { assert.expect(0); }); }); diff --git a/ui/core/tests/acceptance/targets-test.js b/ui/core/tests/acceptance/targets-test.js new file mode 100644 index 000000000..8ff26fa7f --- /dev/null +++ b/ui/core/tests/acceptance/targets-test.js @@ -0,0 +1,61 @@ +import { module, test } from 'qunit'; +//import { visit, currentURL } 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 { +// authenticateSession, +// // These are left here intentionally for future reference. +// //currentSession, +// //invalidateSession, +// } from 'ember-simple-auth/test-support'; + +module('Acceptance | targets', function (hooks) { + setupApplicationTest(hooks); + setupMirage(hooks); + + hooks.beforeEach(function () { + // Setup Mirage mock resources for this test + // Generate route URLs for resources + }); + + test('visiting targets', async function (assert) { + assert.expect(0); + }); + + test('can navigate to a target form', async function (assert) { + assert.expect(0); + }); + + test('can update a target and save changes', async function (assert) { + assert.expect(0); + }); + + test('can update a target and cancel changes', async function (assert) { + assert.expect(0); + }); + + test('can create new target', async function (assert) { + assert.expect(0); + }); + + test('can cancel new target creation', async function (assert) { + assert.expect(0); + }); + + test('saving a new target with invalid fields displays error messages', async function (assert) { + assert.expect(0); + }); + + test('errors are displayed when save on target fails', async function (assert) { + assert.expect(0); + }); + + test('errors are displayed when delete on a target fails', async function (assert) { + assert.expect(0); + }); + + test('saving an existing target with invalid fields displays error messages', async function (assert) { + assert.expect(0); + }); +}); From 710dd98da0ea2d7f255afc089ac003001c099cd6 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Fri, 21 Aug 2020 15:13:55 -0400 Subject: [PATCH 8/8] chore: Add version attribute to target Update target table header cells --- addons/api/addon/generated/models/target.js | 4 ++++ .../scopes/scope/projects/project/targets/index.hbs | 10 +++++----- ui/core/mirage/generated/factories/target.js | 1 + ui/core/translations/en-us.yaml | 1 - 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/addons/api/addon/generated/models/target.js b/addons/api/addon/generated/models/target.js index 5c053d46a..f80ea83cc 100644 --- a/addons/api/addon/generated/models/target.js +++ b/addons/api/addon/generated/models/target.js @@ -34,4 +34,8 @@ export default class GeneratedTargetModel extends BaseModel { description: 'Whether the catalog is disabled' }) disabled; + @attr('number', { + description: 'Current version number of this resource.', + }) + version; } diff --git a/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs b/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs index 184dd9910..16511299f 100644 --- a/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs +++ b/ui/core/app/templates/scopes/scope/projects/project/targets/index.hbs @@ -23,15 +23,15 @@ - {{t "form.label.name"}} - {{t "form.label.protocol"}} - {{t "form.label.id"}} + {{t "form.label.name"}} + {{t "form.label.protocol"}} + {{t "form.label.id"}} {{#each @model as |target|}} - +

{{target.description}}

-
+ {{#if target.protocol}} diff --git a/ui/core/mirage/generated/factories/target.js b/ui/core/mirage/generated/factories/target.js index 5033064c8..134cc7c02 100644 --- a/ui/core/mirage/generated/factories/target.js +++ b/ui/core/mirage/generated/factories/target.js @@ -12,5 +12,6 @@ export default Factory.extend({ created_time: () => date.recent(), updated_time: () => date.recent(), disabled: () => random.boolean(), + version: () => random.number(), }); diff --git a/ui/core/translations/en-us.yaml b/ui/core/translations/en-us.yaml index fea3cd671..d9aa82900 100644 --- a/ui/core/translations/en-us.yaml +++ b/ui/core/translations/en-us.yaml @@ -36,7 +36,6 @@ host-set: static: Static target: protocols: - ssh: SSH SSH: SSH host: types: