diff --git a/addons/api/addon/adapters/auth-method.js b/addons/api/addon/adapters/auth-method.js
new file mode 100644
index 000000000..2da687841
--- /dev/null
+++ b/addons/api/addon/adapters/auth-method.js
@@ -0,0 +1,16 @@
+import ApplicationAdapter from './application';
+import ScopeAdapterMixin from '../mixins/scope-adapter';
+
+export default class AuthMethodAdapter extends ApplicationAdapter.extend(
+ ScopeAdapterMixin
+) {
+
+ // =attributes
+
+ /**
+ * Auth method is scoped to org only.
+ * @type {boolean}
+ */
+ includeProject = false;
+
+}
diff --git a/addons/api/addon/generated/models/auth-method.js b/addons/api/addon/generated/models/auth-method.js
new file mode 100644
index 000000000..c006b935c
--- /dev/null
+++ b/addons/api/addon/generated/models/auth-method.js
@@ -0,0 +1,37 @@
+import BaseModel from '../../models/base';
+import { attr } from '@ember-data/model';
+
+/**
+ *
+ */
+export default class GeneratedOrganizationModel extends BaseModel {
+
+ // =attributes
+
+ @attr('string', {
+ description: 'The type of the resource, to help differentiate schemas'
+ }) type;
+
+ @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;
+
+}
diff --git a/addons/api/addon/generated/models/organization.js b/addons/api/addon/generated/models/organization.js
new file mode 100644
index 000000000..773afb70f
--- /dev/null
+++ b/addons/api/addon/generated/models/organization.js
@@ -0,0 +1,33 @@
+import BaseModel from '../../models/base';
+import { attr } from '@ember-data/model';
+
+/**
+ *
+ */
+export default class GeneratedOrganizationModel extends BaseModel {
+
+ // =attributes
+
+ @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;
+
+}
diff --git a/addons/api/addon/models/auth-method.js b/addons/api/addon/models/auth-method.js
new file mode 100644
index 000000000..ad795fd7d
--- /dev/null
+++ b/addons/api/addon/models/auth-method.js
@@ -0,0 +1,3 @@
+import GeneratedAuthMethodModel from '../generated/models/auth-method';
+
+export default class AuthMethodModel extends GeneratedAuthMethodModel {}
diff --git a/addons/api/addon/models/organization.js b/addons/api/addon/models/organization.js
new file mode 100644
index 000000000..a9478f967
--- /dev/null
+++ b/addons/api/addon/models/organization.js
@@ -0,0 +1,3 @@
+import GeneratedOrganizationModel from '../generated/models/organization';
+
+export default class OrganizationModel extends GeneratedOrganizationModel {}
diff --git a/addons/api/app/adapters/auth-method.js b/addons/api/app/adapters/auth-method.js
new file mode 100644
index 000000000..02c325d6e
--- /dev/null
+++ b/addons/api/app/adapters/auth-method.js
@@ -0,0 +1 @@
+export { default } from 'api/adapters/auth-method';
diff --git a/addons/api/app/models/auth-method.js b/addons/api/app/models/auth-method.js
new file mode 100644
index 000000000..7dfb3b20c
--- /dev/null
+++ b/addons/api/app/models/auth-method.js
@@ -0,0 +1 @@
+export { default } from 'api/models/auth-method';
diff --git a/addons/api/app/models/organization.js b/addons/api/app/models/organization.js
new file mode 100644
index 000000000..f9e7429d3
--- /dev/null
+++ b/addons/api/app/models/organization.js
@@ -0,0 +1 @@
+export { default } from 'api/models/organization';
diff --git a/addons/api/tests/unit/adapters/auth-method-test.js b/addons/api/tests/unit/adapters/auth-method-test.js
new file mode 100644
index 000000000..d7c2f176c
--- /dev/null
+++ b/addons/api/tests/unit/adapters/auth-method-test.js
@@ -0,0 +1,16 @@
+import { module, test } from 'qunit';
+import { setupTest } from 'ember-qunit';
+import config from 'ember-get-config';
+
+module('Unit | Adapter | auth method', function (hooks) {
+ setupTest(hooks);
+
+ 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:auth-method');
+ assert.equal(adapter.urlPrefix(), `${config.api.namespace}/orgs/1`);
+ });
+});
diff --git a/addons/api/tests/unit/models/auth-method-test.js b/addons/api/tests/unit/models/auth-method-test.js
new file mode 100644
index 000000000..3de95883a
--- /dev/null
+++ b/addons/api/tests/unit/models/auth-method-test.js
@@ -0,0 +1,13 @@
+import { module, test } from 'qunit';
+import { setupTest } from 'ember-qunit';
+
+module('Unit | Model | auth method', 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('auth-method', {});
+ assert.ok(model);
+ });
+});
diff --git a/addons/api/tests/unit/models/organization-test.js b/addons/api/tests/unit/models/organization-test.js
new file mode 100644
index 000000000..9d94b9ea4
--- /dev/null
+++ b/addons/api/tests/unit/models/organization-test.js
@@ -0,0 +1,13 @@
+import { module, test } from 'qunit';
+import { setupTest } from 'ember-qunit';
+
+module('Unit | Model | organization', 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('organization', {});
+ assert.ok(model);
+ });
+});
diff --git a/addons/rose/addon/components/rose/link-button.js b/addons/rose/addon/components/rose/link-button.js
index 32e084f7e..f2e283b63 100644
--- a/addons/rose/addon/components/rose/link-button.js
+++ b/addons/rose/addon/components/rose/link-button.js
@@ -1,14 +1,26 @@
-import Component from '@ember/component';
+import LinkComponent from '@ember/routing/link-component';
import layout from '../../templates/components/rose/link-button';
+import { computed } from '@ember/object';
/**
* An achor element based on `rose-button` component styles
+ * An empty model cannot be passed in to `link-to` component when a route
+ * is defined. Thus, `link-to` component is used to generate this component.
*
* @example
* Save
* Disabled
*/
-export default Component.extend({
+export default LinkComponent.extend({
layout,
- tagName: '',
+ classNames: ['rose-link-button'],
+ classNameBindings: [
+ 'linkButtonStyle',
+ 'iconOnly:has-icon-only',
+ 'iconLeft:has-icon-left',
+ 'iconRight:has-icon-right',
+ ],
+ linkButtonStyle: computed(function () {
+ return this.style ? `rose-button-${this.style}` : '';
+ }),
});
diff --git a/addons/rose/addon/components/rose/link-button.stories.mdx b/addons/rose/addon/components/rose/link-button.stories.mdx
index cb6b13001..0ca00a2ee 100644
--- a/addons/rose/addon/components/rose/link-button.stories.mdx
+++ b/addons/rose/addon/components/rose/link-button.stories.mdx
@@ -12,7 +12,7 @@ Styles supported: primary, secondary, warning, and ghost.
Disabling link button is not supported as it is an action on form components only.
```html
-
+
Content
```
@@ -21,6 +21,7 @@ Disabling link button is not supported as it is an action on form components onl
{{
template: hbs`
+
```
{{
template: hbs`
-
+
`,
context: {
style: select(
diff --git a/addons/rose/addon/templates/components/rose/link-button.hbs b/addons/rose/addon/templates/components/rose/link-button.hbs
index 9db7c752c..20ea6c6a5 100644
--- a/addons/rose/addon/templates/components/rose/link-button.hbs
+++ b/addons/rose/addon/templates/components/rose/link-button.hbs
@@ -1,34 +1,26 @@
-
+
+ {{#if @iconLeft}}
+
+ {{/if}}
-
- {{#if @iconLeft}}
-
- {{/if}}
-
-
- {{yield}}
-
-
- {{#if @iconOnly}}
-
- {{/if}}
-
- {{#if @iconRight}}
-
- {{/if}}
+
+ {{yield}}
-
+
+ {{#if @iconOnly}}
+
+ {{/if}}
+
+ {{#if @iconRight}}
+
+ {{/if}}
+
diff --git a/addons/rose/tests/dummy/app/templates/index.hbs b/addons/rose/tests/dummy/app/templates/index.hbs
index 8df466fc3..2422caa03 100644
--- a/addons/rose/tests/dummy/app/templates/index.hbs
+++ b/addons/rose/tests/dummy/app/templates/index.hbs
@@ -1,9 +1,9 @@
-Primary
-Secondary
-Warning
-Ghost
+Primary
+Secondary
+Warning
+Ghost
-Left Icon
-Right Icon
-
+Left Icon
+Right Icon
+
diff --git a/addons/rose/tests/integration/components/rose/link-button-test.js b/addons/rose/tests/integration/components/rose/link-button-test.js
index d7d3c8497..617f76ed0 100644
--- a/addons/rose/tests/integration/components/rose/link-button-test.js
+++ b/addons/rose/tests/integration/components/rose/link-button-test.js
@@ -7,19 +7,19 @@ module('Integration | Component | rose/link-button', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
- await render(hbs``);
+ await render(hbs``);
assert.ok(find('a'));
assert.notOk(find('.rose-button'));
assert.ok(find('.rose-link-button'));
});
test('it renders with attributes', async function (assert) {
- await render(hbs``);
+ await render(hbs``);
assert.ok(find('#link-button'));
});
test('it renders with content', async function (assert) {
- await render(hbs`Link button content`);
+ await render(hbs`Link button content`);
assert.ok(
find('.rose-link-button').textContent.trim(),
'Link button content'
@@ -27,28 +27,24 @@ module('Integration | Component | rose/link-button', function (hooks) {
});
test('it renders with rose button styles', async function (assert) {
- this.set('style', 'primary');
- await render(hbs``);
- assert.ok(find(`.rose-button-primary`));
-
- this.set('style', 'sample');
+ await render(hbs``);
assert.ok(find(`.rose-button-sample`));
});
test('it supports left icon with @iconLeft', async function (assert) {
- await render(hbs``);
+ await render(hbs``);
assert.ok(find('.rose-icon'));
assert.ok(find('.has-icon-left'));
});
test('it supports left icon with @iconRight', async function (assert) {
- await render(hbs``);
+ await render(hbs``);
assert.ok(find('.rose-icon'));
assert.ok(find('.has-icon-right'));
});
test('it supports only icon with @iconOnly', async function (assert) {
- await render(hbs``);
+ await render(hbs``);
assert.ok(find('.rose-icon'));
assert.ok(find('.has-icon-only'));
});
diff --git a/ui/core/app/templates/orgs/org/projects/index.hbs b/ui/core/app/templates/orgs/org/projects/index.hbs
index 1723da8a6..e95b565bd 100644
--- a/ui/core/app/templates/orgs/org/projects/index.hbs
+++ b/ui/core/app/templates/orgs/org/projects/index.hbs
@@ -9,7 +9,7 @@
- {{t 'titles.new'}}
+ {{t 'titles.new'}}
diff --git a/ui/core/app/templates/orgs/org/projects/project/host-catalogs/host-catalog/index.hbs b/ui/core/app/templates/orgs/org/projects/project/host-catalogs/host-catalog/index.hbs
index b80d3f9b0..735397eef 100644
--- a/ui/core/app/templates/orgs/org/projects/project/host-catalogs/host-catalog/index.hbs
+++ b/ui/core/app/templates/orgs/org/projects/project/host-catalogs/host-catalog/index.hbs
@@ -14,7 +14,7 @@
@submit={{route-action "save" @model}}
@cancel={{route-action "cancel" @model}}
/>
-
+
-
+
{{t 'titles.new'}}
-
+
diff --git a/ui/core/app/templates/orgs/org/projects/project/index.hbs b/ui/core/app/templates/orgs/org/projects/project/index.hbs
index 5c297e624..77050cd72 100644
--- a/ui/core/app/templates/orgs/org/projects/project/index.hbs
+++ b/ui/core/app/templates/orgs/org/projects/project/index.hbs
@@ -22,7 +22,7 @@
@submit={{route-action "save" @model}}
@cancel={{route-action "cancel" @model}}
/>
-
+