Skip to content

Commit

Permalink
Splits Settings into 2 sections, sign-in/profile and user settings (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
philrenaud committed May 6, 2024
1 parent cd8bacc commit 3877fbf
Show file tree
Hide file tree
Showing 14 changed files with 147 additions and 66 deletions.
11 changes: 0 additions & 11 deletions ui/app/components/global-header.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,6 @@ export default class GlobalHeader extends Component {
'data-test-global-header' = true;
onHamburgerClick() {}

// Show sign-in if:
// - User can't load agent config (meaning ACLs are enabled but they're not signed in)
// - User can load agent config in and ACLs are enabled (meaning ACLs are enabled and they're signed in)
// The excluded case here is if there is both an agent config and ACLs are disabled
get shouldShowProfileNav() {
return (
!this.system.agent?.get('config') ||
this.system.agent?.get('config.ACL.Enabled') === true
);
}

get labelStyles() {
return htmlSafe(
`
Expand Down
16 changes: 13 additions & 3 deletions ui/app/components/profile-navbar-item.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,19 @@
<dd.Interactive {{on "click" this.signOut}} @text="Sign Out" @color="critical" data-test-profile-dropdown-sign-out-link />
</Hds::Dropdown>
{{else}}
<LinkTo data-test-header-signin-link @route="settings.tokens" class="navbar-item" {{keyboard-shortcut menuLevel=true pattern=(array "g" "p") }}>
Sign In
</LinkTo>
<span class="profile-link"
{{keyboard-shortcut menuLevel=true pattern=(array "g" "p") }}
>
<Hds::Button
data-test-header-signin-link
@route="settings.tokens"
@text="Profile and Sign In"
@icon="user-circle"
@isIconOnly={{true}}
@color="secondary"
@size="medium"
/>
</span>
{{/if}}

{{yield}}
28 changes: 28 additions & 0 deletions ui/app/controllers/settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/

// @ts-check
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
import { alias } from '@ember/object/computed';

export default class SettingsController extends Controller {
@service keyboard;
@service token;
@service system;

@alias('token.selfToken') tokenRecord;

// Show sign-in if:
// - User can't load agent config (meaning ACLs are enabled but they're not signed in)
// - User can load agent config in and ACLs are enabled (meaning ACLs are enabled and they're signed in)
// The excluded case here is if there is both an agent config and ACLs are disabled
get shouldShowProfileLink() {
return (
!this.system.agent?.get('config') ||
this.system.agent?.get('config.ACL.Enabled') === true
);
}
}
6 changes: 0 additions & 6 deletions ui/app/controllers/settings/tokens.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { action } from '@ember/object';
import classic from 'ember-classic-decorator';
import { tracked } from '@glimmer/tracking';
import Ember from 'ember';
import localStorageProperty from 'nomad-ui/utils/properties/local-storage';

/**
* @type {RegExp}
Expand Down Expand Up @@ -280,9 +279,4 @@ export default class Tokens extends Controller {
get shouldShowPolicies() {
return this.tokenRecord;
}

// #region settings
@localStorageProperty('nomadShouldWrapCode', false) wordWrap;
@localStorageProperty('nomadLiveUpdateJobsIndex', true) liveUpdateJobsIndex;
// #endregion settings
}
13 changes: 13 additions & 0 deletions ui/app/controllers/settings/user-settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/

// @ts-check
import Controller from '@ember/controller';
import localStorageProperty from 'nomad-ui/utils/properties/local-storage';

export default class SettingsUserSettingsController extends Controller {
@localStorageProperty('nomadShouldWrapCode', false) wordWrap;
@localStorageProperty('nomadLiveUpdateJobsIndex', true) liveUpdateJobsIndex;
}
2 changes: 0 additions & 2 deletions ui/app/models/job.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,6 @@ export default class Job extends Model {
};
}

// console.log('allocBlocks for', this.name, 'is', allocationsOfShowableType);

return allocationsOfShowableType;
}

Expand Down
1 change: 1 addition & 0 deletions ui/app/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ Router.map(function () {

this.route('settings', function () {
this.route('tokens');
this.route('user-settings');
});

// if we don't include function() the outlet won't render
Expand Down
16 changes: 16 additions & 0 deletions ui/app/routes/settings/tokens.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,22 @@ import { inject as service } from '@ember/service';

export default class SettingsTokensRoute extends Route {
@service store;
@service system;
@service router;

// before model hook: if there is an agent config, and ACLs are disabled,
// guard against this route. Redirect the user to the "profile settings" page instead.
async beforeModel() {
await this.system.agent;
if (
this.system.agent?.get('config') &&
!this.system.agent?.get('config.ACL.Enabled')
) {
this.router.transitionTo('settings.user-settings');
return;
}
}

model() {
return {
authMethods: this.store.findAll('auth-method'),
Expand Down
20 changes: 11 additions & 9 deletions ui/app/styles/core/navbar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -163,15 +163,17 @@ $secondaryNavbarHeight: 4.5rem;
.profile-dropdown {
padding: 0.5rem 1rem 0.5rem 0.75rem;
z-index: $z-gutter;
button.hds-dropdown-toggle-icon {
border-color: var(--token-color-palette-neutral-200);
background-color: transparent;
color: var(--token-color-surface-primary);

&.hds-dropdown-toggle-icon--is-open {
background-color: var(--token-color-surface-primary);
color: var(--token-color-foreground-primary);
}
}

.profile-dropdown button.hds-dropdown-toggle-icon,
.profile-link .hds-button {
border-color: var(--token-color-palette-neutral-200);
background-color: transparent;
color: var(--token-color-surface-primary);

&.hds-dropdown-toggle-icon--is-open {
background-color: var(--token-color-surface-primary);
color: var(--token-color-foreground-primary);
}
}

Expand Down
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 @@ -70,9 +70,7 @@
>
Documentation
</a>
{{#if this.shouldShowProfileNav}}
<ProfileNavbarItem />
{{/if}}
<ProfileNavbarItem />
</div>
</nav>
<div class="navbar is-secondary">
Expand Down
15 changes: 15 additions & 0 deletions ui/app/templates/settings.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,21 @@
SPDX-License-Identifier: BUSL-1.1
~}}

<Breadcrumb @crumb={{hash label="Settings" args=(array "settings.tokens")}} />
<PageLayout>
<div class="tabs is-subnav" {{did-insert this.keyboard.registerNav type="subnav"}} {{will-destroy this.keyboard.unregisterSubnav}}>
<ul>
{{#if this.shouldShowProfileLink}}
<li><LinkTo @route="settings.tokens" @activeClass="is-active">
{{#if this.tokenRecord}}
Profile
{{else}}
Sign In
{{/if}}
</LinkTo></li>
{{/if}}
<li><LinkTo @route="settings.user-settings" @activeClass="is-active">User Settings</LinkTo></li>
</ul>
</div>
{{outlet}}
</PageLayout>
33 changes: 1 addition & 32 deletions ui/app/templates/settings/tokens.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -34,37 +34,6 @@
</Hds::PageHeader>

<div class="status-notifications">

<Hds::Alert @type="inline" @title="Local Storage Settings" as |A|>
<A.Title>User Settings</A.Title>
<A.Description>These settings will be saved to your browser settings via Local Storage.</A.Description>
<A.Generic>
<Hds::Separator/>
<Hds::Form::Toggle::Group as |G|>
<G.Legend>UI</G.Legend>
<G.Toggle::Field
name="word-wrap"
@id="word-wrap"
checked={{this.wordWrap}}
{{on "change" (action (mut this.wordWrap) (not this.wordWrap))}}
as |F|>
<F.Label>Word Wrap</F.Label>
<F.HelperText>Wrap lines of text in logs and exec terminals in the UI</F.HelperText>
</G.Toggle::Field>
<G.Toggle::Field
name="jostle"
@id="jostle"
checked={{this.liveUpdateJobsIndex}}
{{on "change" (action (mut this.liveUpdateJobsIndex) (not this.liveUpdateJobsIndex))}}
as |F|>
<F.Label>Live Updates to <LinkTo @route="jobs.index">Jobs Index</LinkTo></F.Label>
<F.HelperText>When enabled, new or removed jobs will pop into and out of view on your jobs page. When disabled, you will be notified that changes are pending.</F.HelperText>
</G.Toggle::Field>
</Hds::Form::Toggle::Group>
</A.Generic>
</Hds::Alert>


{{#if (eq this.signInStatus "failure")}}
<Hds::Alert data-test-token-error @type="inline" @color="critical"
@onDismiss={{action (mut this.signInStatus) null}}
Expand Down Expand Up @@ -125,7 +94,7 @@
</div>

{{#if this.canSignIn}}
<div class="column sign-in-methods">
<div class="sign-in-methods">
{{#if this.nonTokenAuthMethods.length}}
<h3 class="title is-4">Sign in with SSO</h3>
<p>Sign in to Nomad using the configured authorization provider. After logging in, the policies and rules for the token will be listed.</p>
Expand Down
35 changes: 35 additions & 0 deletions ui/app/templates/settings/user-settings.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{{!
Copyright (c) HashiCorp, Inc.
SPDX-License-Identifier: BUSL-1.1
~}}

{{page-title "User Settings"}}
<section class="section">
<Hds::Alert @type="inline" @title="Local Storage Settings" as |A|>
<A.Title>User Settings</A.Title>
<A.Description>These settings will be saved to your browser settings via Local Storage.</A.Description>
<A.Generic>
<Hds::Separator/>
<Hds::Form::Toggle::Group as |G|>
<G.Toggle::Field
name="word-wrap"
@id="word-wrap"
checked={{this.wordWrap}}
{{on "change" (action (mut this.wordWrap) (not this.wordWrap))}}
as |F|>
<F.Label>Word Wrap</F.Label>
<F.HelperText>Wrap lines of text in logs and exec terminals in the UI</F.HelperText>
</G.Toggle::Field>
<G.Toggle::Field
name="jostle"
@id="jostle"
checked={{this.liveUpdateJobsIndex}}
{{on "change" (action (mut this.liveUpdateJobsIndex) (not this.liveUpdateJobsIndex))}}
as |F|>
<F.Label>Live Updates to <LinkTo @route="jobs.index">Jobs Index</LinkTo></F.Label>
<F.HelperText>When enabled, new or removed jobs will pop into and out of view on your jobs page. When disabled, you will be notified that changes are pending.</F.HelperText>
</G.Toggle::Field>
</Hds::Form::Toggle::Group>
</A.Generic>
</Hds::Alert>
</section>
13 changes: 13 additions & 0 deletions ui/tests/acceptance/token-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,19 @@ module('Acceptance | tokens', function (hooks) {
);
});

test('When ACLs are disabled, the user is redirected to the profile settings page', async function (assert) {
// Update the existing agent to have ACLs set to false
server.db.agents.update(server.db.agents[0].id, {
config: {
ACL: {
Enabled: false,
},
},
});
await visit('/settings/tokens');
assert.equal(currentURL(), '/settings/user-settings');
});

test('Tokens are shown on the Access Control Policies index page', async function (assert) {
allScenarios.policiesTestCluster(server);
let firstPolicy = server.db.policies.sort((a, b) => {
Expand Down

0 comments on commit 3877fbf

Please sign in to comment.