Skip to content

Commit

Permalink
Top nav auth dropdown (#15055)
Browse files Browse the repository at this point in the history
* Basic dropdown styles

* Some cleanup

* delog

* Default nomad hover state styles

* Component separation-of-concerns and acceptance tests for auth dropdown

* lintfix
  • Loading branch information
philrenaud authored Oct 27, 2022
1 parent 75736b6 commit a50d93d
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 7 deletions.
24 changes: 24 additions & 0 deletions ui/app/components/profile-navbar-item.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{{#if this.token.selfToken}}
<PowerSelect
data-test-header-profile-dropdown
{{keyboard-shortcut menuLevel=true pattern=(array "g" "p") }}
@options={{this.profileOptions}}
@onChange={{action (queue
(fn (mut this.profileSelection))
this.profileSelection.action
)}}
@dropdownClass="dropdown-options"
@matchTriggerWidth={{false}}
@selected={{get this.profileSelection "key"}}
class="profile-dropdown navbar-item"
as |option|>
<span class="ember-power-select-prefix">Profile</span>
<span class="dropdown-label" data-test-dropdown-option={{option.key}}>{{option.label}}</span>
</PowerSelect>
{{else}}
<LinkTo data-test-header-signin-link @route="settings.tokens" class="navbar-item" {{keyboard-shortcut menuLevel=true pattern=(array "g" "p") }}>
Sign In
</LinkTo>
{{/if}}

{{yield}}
36 changes: 36 additions & 0 deletions ui/app/components/profile-navbar-item.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// @ts-check

import Component from '@glimmer/component';
import { inject as service } from '@ember/service';

export default class ProfileNavbarItemComponent extends Component {
@service token;
@service router;
@service store;

profileOptions = [
{
label: 'Authorization',
key: 'authorization',
action: () => {
this.router.transitionTo('settings.tokens');
},
},
{
label: 'Sign Out',
key: 'sign-out',
action: () => {
this.token.setProperties({
secret: undefined,
});

// Clear out all data to ensure only data the anonymous token is privileged to see is shown
this.store.unloadAll();
this.token.reset();
this.router.transitionTo('jobs.index');
},
},
];

profileSelection = this.profileOptions[0];
}
4 changes: 2 additions & 2 deletions ui/app/services/keyboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export default class KeyboardService extends Service {
'Go to Clients': ['g', 'c'],
'Go to Topology': ['g', 't'],
'Go to Evaluations': ['g', 'e'],
'Go to ACL Tokens': ['g', 'a'],
'Go to Profile': ['g', 'p'],
'Next Subnav': ['Shift+ArrowRight'],
'Previous Subnav': ['Shift+ArrowLeft'],
'Previous Main Section': ['Shift+ArrowUp'],
Expand Down Expand Up @@ -126,7 +126,7 @@ export default class KeyboardService extends Service {
rebindable: true,
},
{
label: 'Go to ACL Tokens',
label: 'Go to Profile',
action: () => this.router.transitionTo('settings.tokens'),
rebindable: true,
},
Expand Down
29 changes: 28 additions & 1 deletion ui/app/styles/core/navbar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
align-items: center;

&.is-primary {
background: linear-gradient(to right, $nomad-green-darker, $nomad-green-dark);
background: linear-gradient(
to right,
$nomad-green-darker,
$nomad-green-dark
);
height: 3.5rem;
color: $primary-invert;
padding-left: 20px;
Expand Down Expand Up @@ -147,4 +151,27 @@
}
}
}

.profile-dropdown {
padding: 0.5rem 1rem 0.5rem 0.75rem;
background-color: transparent;
border: none !important;
height: auto;
box-shadow: none !important;

&:focus {
background-color: #21a572;
}

.ember-power-select-prefix {
color: rgba($primary-invert, 0.8);
}
.ember-power-select-selected-item {
margin-left: 0;
border: none;
}
.ember-power-select-status-icon {
border-top-color: white;
}
}
}
4 changes: 1 addition & 3 deletions ui/app/templates/components/global-header.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,7 @@
>
Documentation
</a>
<LinkTo @route="settings.tokens" class="navbar-item" {{keyboard-shortcut menuLevel=true pattern=(array "g" "a") }}>
ACL Tokens
</LinkTo>
<ProfileNavbarItem />
</div>
</nav>
<div class="navbar is-secondary">
Expand Down
37 changes: 36 additions & 1 deletion ui/tests/acceptance/global-header-test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
/* eslint-disable ember-a11y-testing/a11y-audit-called */
import { module, test } from 'qunit';
import { visit } from '@ember/test-helpers';
import { click, visit, currentURL } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';
import Layout from 'nomad-ui/tests/pages/layout';

let managementToken;

module('Acceptance | global header', function (hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
Expand Down Expand Up @@ -46,4 +48,37 @@ module('Acceptance | global header', function (hooks) {
assert.equal(Layout.navbar.end.vaultLink.text, 'Vault');
assert.equal(Layout.navbar.end.vaultLink.link, 'http://localhost:8200/ui');
});

test('it diplays SignIn', async function (assert) {
managementToken = server.create('token');

window.localStorage.clear();

await visit('/');
assert.true(Layout.navbar.end.signInLink.isVisible);
assert.false(Layout.navbar.end.profileDropdown.isVisible);
});

test('it diplays a Profile dropdown', async function (assert) {
managementToken = server.create('token');

window.localStorage.nomadTokenSecret = managementToken.secretId;

await visit('/');
assert.true(Layout.navbar.end.profileDropdown.isVisible);
assert.false(Layout.navbar.end.signInLink.isVisible);
await Layout.navbar.end.profileDropdown.open();

await click('.dropdown-options .ember-power-select-option:nth-child(1)');
assert.equal(
currentURL(),
'/settings/tokens',
'Authroization link takes you to the tokens page'
);

await Layout.navbar.end.profileDropdown.open();
await click('.dropdown-options .ember-power-select-option:nth-child(2)');
assert.equal(window.localStorage.nomadTokenSecret, null, 'Token is wiped');
assert.equal(currentURL(), '/jobs', 'After signout, back on the jobs page');
});
});
16 changes: 16 additions & 0 deletions ui/tests/pages/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,22 @@ export default create({
text: text(),
link: property('href'),
},

signInLink: {
scope: '[data-test-header-signin-link]',
text: text(),
link: property('href'),
},

profileDropdown: {
scope: '[data-test-header-profile-dropdown]',
text: text(),
open: clickable(),
options: collection('.dropdown-label', {
label: text(),
choose: clickable(),
}),
},
},
},

Expand Down

0 comments on commit a50d93d

Please sign in to comment.