@@ -24,8 +24,9 @@
{{yield (hash
- link=(component "link-to" class="rose-dropdown-link")
- button=(component "rose/button" style="dropdown")
+ link=(component "rose/dropdown/link" style=this.style)
+ button=(component "rose/dropdown/button" style=this.style)
+ separator=(component "rose/anonymous" tagName="hr" class="rose-dropdown-separator")
)}}
diff --git a/addons/rose/addon/templates/components/rose/dropdown/button.hbs b/addons/rose/addon/templates/components/rose/dropdown/button.hbs
new file mode 100644
index 000000000..364a2ef18
--- /dev/null
+++ b/addons/rose/addon/templates/components/rose/dropdown/button.hbs
@@ -0,0 +1,19 @@
+
diff --git a/addons/rose/addon/templates/components/rose/dropdown/link.hbs b/addons/rose/addon/templates/components/rose/dropdown/link.hbs
new file mode 100644
index 000000000..6b3bd413a
--- /dev/null
+++ b/addons/rose/addon/templates/components/rose/dropdown/link.hbs
@@ -0,0 +1,8 @@
+
+ {{yield}}
+
\ No newline at end of file
diff --git a/addons/rose/addon/templates/components/rose/header/dropdown.hbs b/addons/rose/addon/templates/components/rose/header/dropdown.hbs
deleted file mode 100644
index cc874c284..000000000
--- a/addons/rose/addon/templates/components/rose/header/dropdown.hbs
+++ /dev/null
@@ -1,32 +0,0 @@
-
diff --git a/addons/rose/addon/templates/components/rose/header/nav.hbs b/addons/rose/addon/templates/components/rose/header/nav.hbs
index 2b2978e00..a0858cc1a 100644
--- a/addons/rose/addon/templates/components/rose/header/nav.hbs
+++ b/addons/rose/addon/templates/components/rose/header/nav.hbs
@@ -1,6 +1,6 @@
diff --git a/addons/rose/addon/templates/components/rose/header/utilities.hbs b/addons/rose/addon/templates/components/rose/header/utilities.hbs
index 6ee49e33f..e00d45e75 100644
--- a/addons/rose/addon/templates/components/rose/header/utilities.hbs
+++ b/addons/rose/addon/templates/components/rose/header/utilities.hbs
@@ -1,5 +1,5 @@
diff --git a/addons/rose/app/components/rose/dropdown/button.js b/addons/rose/app/components/rose/dropdown/button.js
new file mode 100644
index 000000000..0def7a1c0
--- /dev/null
+++ b/addons/rose/app/components/rose/dropdown/button.js
@@ -0,0 +1 @@
+export { default } from 'rose/components/rose/dropdown/button';
\ No newline at end of file
diff --git a/addons/rose/app/components/rose/dropdown/link.js b/addons/rose/app/components/rose/dropdown/link.js
new file mode 100644
index 000000000..99ec355d3
--- /dev/null
+++ b/addons/rose/app/components/rose/dropdown/link.js
@@ -0,0 +1 @@
+export { default } from 'rose/components/rose/dropdown/link';
\ No newline at end of file
diff --git a/addons/rose/app/components/rose/header/dropdown.js b/addons/rose/app/components/rose/header/dropdown.js
deleted file mode 100644
index 16d89ac10..000000000
--- a/addons/rose/app/components/rose/header/dropdown.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from 'rose/components/rose/header/dropdown';
diff --git a/addons/rose/tests/dummy/app/templates/index.hbs b/addons/rose/tests/dummy/app/templates/index.hbs
index 5c6efcf85..529b6c7c5 100644
--- a/addons/rose/tests/dummy/app/templates/index.hbs
+++ b/addons/rose/tests/dummy/app/templates/index.hbs
@@ -1,23 +1,38 @@
-
-
-
- Address
- Host Set
- Name
- Description
-
-
-
-
- 1.1.1.1
- host-set-1, host-set-2
- optional name
- description
-
-
-
-
- Footer
-
-
-
\ No newline at end of file
+
+
+
+
+
+ Menu item
+ Menu item - danger
+
+ Button menu item
+
+
+ Section
+ Section
+
+
+
+
+ Menu item
+ Menu item - danger
+ Button - default
+
+ Button - danger
+
+
+
+
+
+ Menu item
+ Menu item - danger
+
+
+ Button menu item
+ Button - danger
+
diff --git a/addons/rose/tests/integration/components/rose/dropdown-test.js b/addons/rose/tests/integration/components/rose/dropdown-test.js
index 3d4597c95..0c0c22695 100644
--- a/addons/rose/tests/integration/components/rose/dropdown-test.js
+++ b/addons/rose/tests/integration/components/rose/dropdown-test.js
@@ -9,6 +9,7 @@ module('Integration | Component | rose/dropdown', function (hooks) {
test('it renders', async function (assert) {
await render(hbs``);
assert.ok(find('.rose-dropdown'));
+ assert.notOk(find('.rose-dropdown-right'));
});
test('it renders with html attributes', async function (assert) {
@@ -32,6 +33,13 @@ module('Integration | Component | rose/dropdown', function (hooks) {
assert.ok(find('.has-icon-only'));
});
+ test('it supports right aligned content', async function (assert) {
+ await render(hbs`
+
+ `);
+ assert.ok(find('.rose-dropdown-right'));
+ });
+
test('it renders with content', async function (assert) {
await render(hbs`
diff --git a/addons/rose/tests/integration/components/rose/dropdown/button-test.js b/addons/rose/tests/integration/components/rose/dropdown/button-test.js
new file mode 100644
index 000000000..11fc945a6
--- /dev/null
+++ b/addons/rose/tests/integration/components/rose/dropdown/button-test.js
@@ -0,0 +1,38 @@
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'ember-qunit';
+import { render, find } from '@ember/test-helpers';
+import hbs from 'htmlbars-inline-precompile';
+
+module('Integration | Component | rose/dropdown/button', function(hooks) {
+ setupRenderingTest(hooks);
+
+ test('it renders', async function (assert) {
+ await render(hbs``);
+ assert.ok(find('.rose-dropdown-button'));
+ });
+
+ test('it is type="button" by default', async function (assert) {
+ await render(hbs``);
+ assert.equal(find('button').type, 'button');
+ });
+
+ test('it is type="submit" when @submit={{true}}', async function (assert) {
+ await render(hbs``);
+ assert.equal(find('button').type, 'submit');
+ });
+
+ test('it is disabled when @disabled={{true}}', async function (assert) {
+ await render(hbs``);
+ assert.equal(find('button').disabled, true);
+ });
+
+ test('it adds a style class', async function (assert) {
+ await render(hbs``);
+ assert.ok(find('.rose-dropdown-button-warning'));
+ });
+
+ test('it supports an icon-only type', async function (assert) {
+ await render(hbs``);
+ assert.ok(find('.has-icon-only .rose-icon'));
+ });
+});
diff --git a/addons/rose/tests/integration/components/rose/dropdown/link-test.js b/addons/rose/tests/integration/components/rose/dropdown/link-test.js
new file mode 100644
index 000000000..a64b51bf8
--- /dev/null
+++ b/addons/rose/tests/integration/components/rose/dropdown/link-test.js
@@ -0,0 +1,31 @@
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'ember-qunit';
+import { render, find } from '@ember/test-helpers';
+import hbs from 'htmlbars-inline-precompile';
+
+module('Integration | Component | rose/dropdown/link', function(hooks) {
+ setupRenderingTest(hooks);
+
+ test('it renders', async function (assert) {
+ await render(hbs``);
+ assert.ok(find('a'));
+ assert.ok(find('.rose-dropdown-link'));
+ });
+
+ test('it renders with attributes', async function (assert) {
+ await render(hbs``);
+ assert.ok(find('#dropdown'));
+ });
+
+ test('it renders with content', async function (assert) {
+ await render(hbs`
+ content
+ `);
+ assert.equal(find('.rose-dropdown-link').textContent.trim(), 'content');
+ });
+
+ test('it supports style', async function (assert) {
+ await render(hbs``);
+ assert.ok('.rose-dropdown-link-warning');
+ });
+});
diff --git a/addons/rose/tests/integration/components/rose/header-test.js b/addons/rose/tests/integration/components/rose/header-test.js
index 7e0f57da7..2feb23438 100644
--- a/addons/rose/tests/integration/components/rose/header-test.js
+++ b/addons/rose/tests/integration/components/rose/header-test.js
@@ -53,6 +53,6 @@ module('Integration | Component | rose/header', function (hooks) {
`);
- assert.ok(find('.rose-header-dropdown'));
+ assert.ok(find('.rose-dropdown'));
});
});
diff --git a/addons/rose/tests/integration/components/rose/header/dropdown-test.js b/addons/rose/tests/integration/components/rose/header/dropdown-test.js
deleted file mode 100644
index 96806b98b..000000000
--- a/addons/rose/tests/integration/components/rose/header/dropdown-test.js
+++ /dev/null
@@ -1,80 +0,0 @@
-import { module, test } from 'qunit';
-import { setupRenderingTest } from 'ember-qunit';
-import { render, click, find, findAll } from '@ember/test-helpers';
-import hbs from 'htmlbars-inline-precompile';
-
-module('Integration | Component | rose/header/dropdown', function (hooks) {
- setupRenderingTest(hooks);
-
- test('it renders', async function (assert) {
- await render(hbs``);
- assert.ok(find('.rose-header-dropdown'));
- });
-
- test('it renders with html attributes', async function (assert) {
- await render(
- hbs``
- );
- assert.ok(find('#custom-id'));
- assert.ok(find('.custom-class'));
- });
-
- test('it renders with trigger', async function (assert) {
- await render(hbs``);
- assert.equal(
- find('.rose-header-dropdown-trigger').textContent.trim(),
- 'Click me'
- );
- });
-
- test('it supports an icon', async function (assert) {
- await render(hbs``);
- assert.ok(find('svg'));
- });
-
- test('it supports icon-only display', async function (assert) {
- await render(hbs``);
- assert.ok(find('.icon-only'));
- });
-
- test('it supports right-aligned content', async function (assert) {
- await render(hbs``);
- assert.ok(find('.dropdown-right'));
- });
-
- test('it renders with content', async function (assert) {
- await render(hbs`
-
-
-
-
-
- `);
- assert.ok(find('.rose-header-dropdown-content'));
- assert.equal(findAll('a').length, 2);
- assert.equal(findAll('button').length, 3);
- });
-
- test('it is toggled on click on trigger content', async function (assert) {
- await render(hbs``);
-
- assert.notOk(find('#dropdown').open);
- await click('summary');
- assert.ok(find('#dropdown').open);
- await click('summary');
- assert.notOk(find('#dropdown').open);
- });
-
- test('it is closed with outside click is triggered', async function (assert) {
- await render(hbs`
-
-
-
- `);
-
- await click('summary');
- assert.ok(find('#dropdown').open);
- await click('#wrapper');
- assert.notOk(find('#dropdown').open);
- });
-});
diff --git a/addons/rose/tests/integration/components/rose/header/nav-test.js b/addons/rose/tests/integration/components/rose/header/nav-test.js
index d1c5a688d..fd713c0db 100644
--- a/addons/rose/tests/integration/components/rose/header/nav-test.js
+++ b/addons/rose/tests/integration/components/rose/header/nav-test.js
@@ -24,6 +24,6 @@ module('Integration | Component | rose/header/nav', function (hooks) {
`);
- assert.equal(findAll('.rose-header-dropdown').length, 2);
+ assert.equal(findAll('.rose-dropdown').length, 2);
});
});
diff --git a/addons/rose/tests/integration/components/rose/header/utilities-test.js b/addons/rose/tests/integration/components/rose/header/utilities-test.js
index 884266d8f..1bb44de8e 100644
--- a/addons/rose/tests/integration/components/rose/header/utilities-test.js
+++ b/addons/rose/tests/integration/components/rose/header/utilities-test.js
@@ -16,6 +16,13 @@ module('Integration | Component | rose/header/utilities', function (hooks) {
`);
- assert.equal(findAll('.rose-header-dropdown').length, 2);
+ assert.equal(findAll('.rose-dropdown').length, 2);
+ });
+
+ test('it renders nav dropdown elements as right aligned', async function (assert) {
+ await render(hbs`
+
+ `);
+ assert.ok(find('.rose-dropdown.rose-dropdown-right'));
});
});
diff --git a/ui/core/app/templates/application.hbs b/ui/core/app/templates/application.hbs
index 15d146e9a..2422a624e 100644
--- a/ui/core/app/templates/application.hbs
+++ b/ui/core/app/templates/application.hbs
@@ -14,7 +14,9 @@
@iconOnly={{true}}
@icon="user-square-fill" as |dropdown|
>
-
+
{{t 'actions.deauthenticate'}}
diff --git a/ui/core/app/templates/scopes/scope/groups/group/index.hbs b/ui/core/app/templates/scopes/scope/groups/group/index.hbs
index ac8915f59..e78a0c548 100644
--- a/ui/core/app/templates/scopes/scope/groups/group/index.hbs
+++ b/ui/core/app/templates/scopes/scope/groups/group/index.hbs
@@ -16,20 +16,24 @@
+
+
+
+ {{t 'actions.delete-group'}}
+
+
+
+
-
-
- {{t 'actions.delete'}}
-
diff --git a/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/index.hbs b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/index.hbs
index cb0a4a0cf..6d7c05659 100644
--- a/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/index.hbs
+++ b/ui/core/app/templates/scopes/scope/projects/project/host-catalogs/host-catalog/index.hbs
@@ -16,20 +16,24 @@
+
+
+
+ {{t 'actions.delete-host-catalog'}}
+
+
+
+
-
-
- {{t 'actions.delete'}}
-
diff --git a/ui/core/app/templates/scopes/scope/projects/project/index.hbs b/ui/core/app/templates/scopes/scope/projects/project/index.hbs
index 5dccae834..c3bec3790 100644
--- a/ui/core/app/templates/scopes/scope/projects/project/index.hbs
+++ b/ui/core/app/templates/scopes/scope/projects/project/index.hbs
@@ -16,20 +16,24 @@
+
+
+
+ {{t 'actions.delete-project'}}
+
+
+
+
-
-
- {{t 'actions.delete'}}
-
diff --git a/ui/core/app/templates/scopes/scope/roles/role.hbs b/ui/core/app/templates/scopes/scope/roles/role.hbs
index 0cd189b0a..397e9f504 100644
--- a/ui/core/app/templates/scopes/scope/roles/role.hbs
+++ b/ui/core/app/templates/scopes/scope/roles/role.hbs
@@ -10,6 +10,18 @@
{{t "resources.role"}}
+
+
+
+ {{t 'actions.delete-role'}}
+
+
+
+
diff --git a/ui/core/app/templates/scopes/scope/roles/role/index.hbs b/ui/core/app/templates/scopes/scope/roles/role/index.hbs
index bbb671abe..e72610ec6 100644
--- a/ui/core/app/templates/scopes/scope/roles/role/index.hbs
+++ b/ui/core/app/templates/scopes/scope/roles/role/index.hbs
@@ -3,11 +3,4 @@
@submit={{route-action "save" @model}}
@cancel={{route-action "cancel" @model}}
/>
-
-
- {{t 'actions.delete'}}
-
+
diff --git a/ui/core/app/templates/scopes/scope/users/user/index.hbs b/ui/core/app/templates/scopes/scope/users/user/index.hbs
index d80978336..6392e84f7 100644
--- a/ui/core/app/templates/scopes/scope/users/user/index.hbs
+++ b/ui/core/app/templates/scopes/scope/users/user/index.hbs
@@ -8,6 +8,18 @@
{{t "resources.user"}}
+
+
+
+ {{t 'actions.delete-user'}}
+
+
+
+
@@ -17,19 +29,11 @@
-
-
-
- {{t 'actions.delete'}}
-
diff --git a/ui/core/tests/acceptance/authentication-test.js b/ui/core/tests/acceptance/authentication-test.js
index 04107a7a9..fa43f2247 100644
--- a/ui/core/tests/acceptance/authentication-test.js
+++ b/ui/core/tests/acceptance/authentication-test.js
@@ -1,5 +1,5 @@
import { module, test } from 'qunit';
-import { visit, currentURL, fillIn, click, find } from '@ember/test-helpers';
+import { visit, currentURL, fillIn, click, find, findAll } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
import { Response } from 'miragejs';
@@ -172,7 +172,11 @@ module('Acceptance | authentication', function (hooks) {
await fillIn('[name="password"]', 'test');
await click('[type="submit"]');
assert.ok(currentSession().isAuthenticated);
- await click('.rose-button-header-dropdown');
+ // Open header utilities dropdown
+ await click('.rose-header-utilities .rose-dropdown summary');
+ // Find and click on last element in dropdown - should be deauthenticate button
+ const menu = findAll('.rose-header-utilities .rose-dropdown .rose-dropdown-content button');
+ await click(menu[menu.length - 1]);
assert.notOk(currentSession().isAuthenticated);
assert.equal(currentURL(), authMethodGlobalAuthenticateURL);
});
diff --git a/ui/core/tests/acceptance/groups-test.js b/ui/core/tests/acceptance/groups-test.js
index b619d09ce..0d622f1f0 100644
--- a/ui/core/tests/acceptance/groups-test.js
+++ b/ui/core/tests/acceptance/groups-test.js
@@ -133,7 +133,7 @@ module('Acceptance | groups', function (hooks) {
assert.expect(1);
const groupsCount = this.server.db.groups.length;
await visit(groupURL);
- await click('.rose-button-warning');
+ await click('.rose-layout-page-actions .rose-dropdown-button-danger');
assert.equal(this.server.db.groups.length, groupsCount - 1);
});
@@ -210,7 +210,7 @@ module('Acceptance | groups', function (hooks) {
);
});
await visit(groupURL);
- await click('.rose-button-warning');
+ await click('.rose-layout-page-actions .rose-dropdown-button-danger');
assert.ok(
find('[role="alert"]').textContent.trim(),
'Oops.',
diff --git a/ui/core/tests/acceptance/host-catalogs-test.js b/ui/core/tests/acceptance/host-catalogs-test.js
index 59bc08dcc..fada1730e 100644
--- a/ui/core/tests/acceptance/host-catalogs-test.js
+++ b/ui/core/tests/acceptance/host-catalogs-test.js
@@ -80,7 +80,7 @@ module('Acceptance | host catalogs', function (hooks) {
authenticateSession({});
await visit(urls.hostCatalog);
assert.equal(currentURL(), urls.hostCatalog);
- await click('.rose-button-warning');
+ await click('.rose-layout-page-actions .rose-dropdown-button-danger');
assert.equal(this.server.db.hostCatalogs.length, hostCatalogsCount - 1);
});
@@ -162,7 +162,7 @@ module('Acceptance | host catalogs', function (hooks) {
});
authenticateSession({});
await visit(urls.hostCatalog);
- await click('.rose-button-warning');
+ await click('.rose-layout-page-actions .rose-dropdown-button-danger');
await a11yAudit();
assert.ok(
find('[role="alert"]').textContent.trim(),
diff --git a/ui/core/tests/acceptance/projects-test.js b/ui/core/tests/acceptance/projects-test.js
index ced4a8f13..4af813592 100644
--- a/ui/core/tests/acceptance/projects-test.js
+++ b/ui/core/tests/acceptance/projects-test.js
@@ -135,7 +135,7 @@ module('Acceptance | projects', function (hooks) {
test('can delete project', async function (assert) {
assert.expect(1);
await visit(existingProjectURL);
- await click('.rose-button-warning');
+ await click('.rose-layout-page-actions .rose-dropdown-button-danger');
assert.equal(getProjectScopesCount(), initialProjectScopesCount - 1);
});
@@ -212,7 +212,7 @@ module('Acceptance | projects', function (hooks) {
);
});
await visit(existingProjectURL);
- await click('.rose-button-warning');
+ await click('.rose-layout-page-actions .rose-dropdown-button-danger');
assert.ok(
find('[role="alert"]').textContent.trim(),
'Oops.',
diff --git a/ui/core/tests/acceptance/roles-test.js b/ui/core/tests/acceptance/roles-test.js
index 2aa364f1b..14bd45a24 100644
--- a/ui/core/tests/acceptance/roles-test.js
+++ b/ui/core/tests/acceptance/roles-test.js
@@ -133,7 +133,7 @@ module('Acceptance | roles', function (hooks) {
assert.expect(1);
const rolesCount = this.server.db.roles.length;
await visit(roleURL);
- await click('.rose-button-warning');
+ await click('.rose-layout-page-actions .rose-dropdown-button-danger');
assert.equal(this.server.db.roles.length, rolesCount - 1);
});
@@ -210,7 +210,7 @@ module('Acceptance | roles', function (hooks) {
);
});
await visit(roleURL);
- await click('.rose-button-warning');
+ await click('.rose-layout-page-actions .rose-dropdown-button-danger');
assert.ok(
find('[role="alert"]').textContent.trim(),
'Oops.',
diff --git a/ui/core/tests/acceptance/users-test.js b/ui/core/tests/acceptance/users-test.js
index 31fa5c98e..55e4ac108 100644
--- a/ui/core/tests/acceptance/users-test.js
+++ b/ui/core/tests/acceptance/users-test.js
@@ -133,7 +133,7 @@ module('Acceptance | users', function (hooks) {
assert.expect(1);
const usersCount = this.server.db.users.length;
await visit(userURL);
- await click('.rose-button-warning');
+ await click('.rose-layout-page-actions .rose-dropdown-button-danger');
assert.equal(this.server.db.users.length, usersCount - 1);
});
@@ -210,7 +210,7 @@ module('Acceptance | users', function (hooks) {
);
});
await visit(userURL);
- await click('.rose-button-warning');
+ await click('.rose-layout-page-actions .rose-dropdown-button-danger');
assert.ok(
find('[role="alert"]').textContent.trim(),
'Oops.',
diff --git a/ui/core/translations/en-us.yaml b/ui/core/translations/en-us.yaml
index 7f207f658..cd73f8bbb 100644
--- a/ui/core/translations/en-us.yaml
+++ b/ui/core/translations/en-us.yaml
@@ -9,6 +9,11 @@ actions:
deauthenticate: Deauthenticate
choose-org: Choose Scope
choose-different-org: Choose a Different Scope
+ delete-user: Delete user
+ delete-group: Delete group
+ delete-role: Delete role
+ delete-project: Delete project
+ delete-host-catalog: Delete host catalog
auth:
titles:
no-scopes: No Scopes Available
@@ -76,6 +81,7 @@ form:
type: Type
identification: Username
password: Password
+ manage: Manage
grant: Grant
principal: Principal
errors: