diff --git a/ui/packages/consul-acls/app/components/consul/acl/selector/index.hbs b/ui/packages/consul-acls/app/components/consul/acl/selector/index.hbs new file mode 100644 index 0000000000..f5e6bae348 --- /dev/null +++ b/ui/packages/consul-acls/app/components/consul/acl/selector/index.hbs @@ -0,0 +1,79 @@ + +
  • + + Tokens + +
  • +{{#if (can "read acls")}} +
  • + + Policies + +
  • +
  • + + Roles + +
  • +
  • + + Auth Methods + +
  • +{{else if (not (can "use acls"))}} +
  • + + Policies + +
  • +
  • + + Roles + +
  • +
  • + + Auth Methods + +
  • +{{/if}} + diff --git a/ui/packages/consul-acls/app/components/consul/token/selector/index.hbs b/ui/packages/consul-acls/app/components/consul/token/selector/index.hbs new file mode 100644 index 0000000000..9245366284 --- /dev/null +++ b/ui/packages/consul-acls/app/components/consul/token/selector/index.hbs @@ -0,0 +1,158 @@ +{{#if (can 'use acls')}} +
  • + + + <:unauthorized as |authDialog|> + + + Login + + + + Log in + + + + +

    + Log in to Consul +

    +
    + + + + {{#if (can "use SSO")}} + + + + {{/if}} + + + + + Continue without logging in + + +
    + + <:authorized as |authDialog|> + + + +

    + Log in with a different token +

    +
    + + + + + + + + Continue without logging in + + +
    + + + Logout + + + + + Logout + + + {{#let components.MenuItem components.MenuSeparator as |MenuItem MenuSeparator|}} +{{!TODO: It might be nice to use one of our recursive components here}} +{{#if @token.AccessorID}} +
  • + +
  • + +{{/if}} + + + Logout + + + {{/let}} + + + + + + +{{yield + (hash + modal=this.modal + ) +}} +{{/if}} + diff --git a/ui/packages/consul-acls/app/components/consul/token/selector/index.js b/ui/packages/consul-acls/app/components/consul/token/selector/index.js new file mode 100644 index 0000000000..bfdcaaae66 --- /dev/null +++ b/ui/packages/consul-acls/app/components/consul/token/selector/index.js @@ -0,0 +1,20 @@ +import Component from '@glimmer/component'; +import { action } from '@ember/object'; + +export default class ConsulAclsTokensSelector extends Component { + @action + open() { + this.authForm.focus(); + } + + @action + close() { + this.authForm.reset(); + } + + @action + reauthorize(e) { + this.modal.close(); + this.args.onchange(e); + } +} diff --git a/ui/packages/consul-ui/app/abilities/authenticate.js b/ui/packages/consul-ui/app/abilities/authenticate.js deleted file mode 100644 index 99d3ae040f..0000000000 --- a/ui/packages/consul-ui/app/abilities/authenticate.js +++ /dev/null @@ -1,8 +0,0 @@ -import BaseAbility from './base'; -import { inject as service } from '@ember/service'; -export default class AuthenticateAbility extends BaseAbility { - @service('env') env; - get can() { - return this.env.var('CONSUL_ACLS_ENABLED'); - } -} diff --git a/ui/packages/consul-ui/app/components/auth-dialog/README.mdx b/ui/packages/consul-ui/app/components/auth-dialog/README.mdx index d09f7fbfb6..da916cbb34 100644 --- a/ui/packages/consul-ui/app/components/auth-dialog/README.mdx +++ b/ui/packages/consul-ui/app/components/auth-dialog/README.mdx @@ -1,63 +1,55 @@ ---- -class: ember ---- # AuthDialog -```hbs preview-template - - {{#let components.AuthForm components.AuthProfile as |AuthForm AuthProfile|}} - - Here's the login form: - - - - Here's your profile: - - - - {{/let}} - -``` - -### Arguments - A component to help orchestrate a login/logout flow. +```hbs preview-template + + <:unauthorized as |api|> + + + <:authorized as |api|> + + + + +``` + +## Arguments + | Argument | Type | Default | Description | | --- | --- | --- | --- | -| `dc` | `String` | | The name of the current datacenter | -| `nspace` | `String` | | The name of the current namespace | -| `partition` | `String` | | The name of the current partition | | `onchange` | `Function` | | An action to fire when the users token has changed (logged in/logged out/token changed) | +| `src` | `URI` | | DataSource URI used to retrive/watch for changes on the users token | +| `sink` | `URI` | | DataSink URI used to save the users token to | -### Methods/Actions/api +## Exports -| Method/Action | Description | -| --- | --- | -| `login` | Login with a specified token | -| `logout` | Logout (delete token) | -| `token` | The current token itself (as a property not a method) | +| Name | Type | Description | +| --- | --- | --- | +| `login` | `Function` | Login with a specified token | +| `logout` | `Function` | Logout (delete token) | +| `token` | `Token` | The current token itself | -### Components - -| Name | Description | -| --- | --- | -| [`AuthForm`](../auth-form/README.mdx) | Renders an Authorization form | -| [`AuthProfile`](../auth-profile/README.mdx) | Renders a User Profile | - -### Slots +## Slots | Name | Description | | --- | --- | | `unauthorized` | This slot is only rendered when the user doesn't have a token | -| `authorized` | This slot is only rendered whtn the user has a token.| +| `authorized` | This slot is only rendered when the user has a token.| -### See +## See - [Component Source Code](./index.js) - [Template Source Code](./index.hbs) diff --git a/ui/packages/consul-ui/app/components/auth-dialog/index.hbs b/ui/packages/consul-ui/app/components/auth-dialog/index.hbs index 2e8470208e..1428ec5bb9 100644 --- a/ui/packages/consul-ui/app/components/auth-dialog/index.hbs +++ b/ui/packages/consul-ui/app/components/auth-dialog/index.hbs @@ -18,39 +18,29 @@ as |State Guard Action dispatch state|> {{! This DataSource just permanently listens to any changes to the users }} {{! token, whether thats a new token, a changed token or a deleted token }} {{! This DataSink is just used for logging in from the form, }} {{! or logging out via the exposed logout function }} - {{yield}} {{#let (hash login=(action sink.open) logout=(action sink.open null) token=token - ) (hash - AuthProfile=(component 'auth-profile' item=token) - AuthForm=(component 'auth-form' - dc=dc - partition=partition - nspace=nspace - onsubmit=(action sink.open value="data")) - ) as |api components|}} + ) as |api|}} + - {{#yield-slot name="authorized"}} - {{yield api components}} - {{/yield-slot}} + {{yield api to="authorized"}} - {{#yield-slot name="unauthorized"}} - {{yield api components}} - {{/yield-slot}} + {{yield api to="unauthorized"}} + {{/let}} diff --git a/ui/packages/consul-ui/app/components/auth-dialog/index.js b/ui/packages/consul-ui/app/components/auth-dialog/index.js index 041fee483b..fd0120f0c5 100644 --- a/ui/packages/consul-ui/app/components/auth-dialog/index.js +++ b/ui/packages/consul-ui/app/components/auth-dialog/index.js @@ -1,42 +1,45 @@ -import Component from '@ember/component'; -import Slotted from 'block-slots'; +import Component from '@glimmer/component'; import { inject as service } from '@ember/service'; -import { get } from '@ember/object'; +import { get, action } from '@ember/object'; import chart from './chart.xstate'; -export default Component.extend(Slotted, { - tagName: '', - repo: service('repository/oidc-provider'), - init: function() { - this._super(...arguments); +export default class AuthDialog extends Component { + @service('repository/oidc-provider') repo; + + constructor() { + super(...arguments); this.chart = chart; - }, - actions: { - hasToken: function() { - return typeof this.token.AccessorID !== 'undefined'; - }, - login: function() { - let prev = get(this, 'previousToken.AccessorID'); - let current = get(this, 'token.AccessorID'); - if (prev === null) { - prev = get(this, 'previousToken.SecretID'); - } - if (current === null) { - current = get(this, 'token.SecretID'); - } - let type = 'authorize'; - if (typeof prev !== 'undefined' && prev !== current) { - type = 'use'; - } - this.onchange({ data: get(this, 'token'), type: type }); - }, - logout: function() { - if (typeof get(this, 'previousToken.AuthMethod') !== 'undefined') { - // we are ok to fire and forget here - this.repo.logout(get(this, 'previousToken.SecretID')); - } - this.previousToken = null; - this.onchange({ data: null, type: 'logout' }); - }, - }, -}); + } + + @action + hasToken() { + return typeof this.token.AccessorID !== 'undefined'; + } + + @action + login() { + let prev = get(this, 'previousToken.AccessorID'); + let current = get(this, 'token.AccessorID'); + if (prev === null) { + prev = get(this, 'previousToken.SecretID'); + } + if (current === null) { + current = get(this, 'token.SecretID'); + } + let type = 'authorize'; + if (typeof prev !== 'undefined' && prev !== current) { + type = 'use'; + } + this.args.onchange({ data: get(this, 'token'), type: type }); + } + + @action + logout() { + if (typeof get(this, 'previousToken.AuthMethod') !== 'undefined') { + // we are ok to fire and forget here + this.repo.logout(get(this, 'previousToken.SecretID')); + } + this.previousToken = null; + this.args.onchange({ data: null, type: 'logout' }); + } +} diff --git a/ui/packages/consul-ui/app/components/auth-profile/README.mdx b/ui/packages/consul-ui/app/components/auth-profile/README.mdx index cda8cd0319..59c70cdb4f 100644 --- a/ui/packages/consul-ui/app/components/auth-profile/README.mdx +++ b/ui/packages/consul-ui/app/components/auth-profile/README.mdx @@ -1,23 +1,22 @@ ---- -class: ember ---- # AuthProfile -```hbs preview-template - -``` - A straightforward partial-like component for rendering a user profile. Only the last 8 characters are shown. -### Arguments +```hbs preview-template + +``` + +## Arguments | Argument | Type | Default | Description | | --- | --- | --- | --- | -| `item` | `Object` | | A Consul shaped token object (currently only requires an AccessorID property to be set | +| `item` | `Token` | | A token object (currently only requires an AccessorID property to be set | -### See +## See - [Component Source Code](./index.js) - [Template Source Code](./index.hbs) diff --git a/ui/packages/consul-ui/app/components/auth-profile/index.hbs b/ui/packages/consul-ui/app/components/auth-profile/index.hbs index 6f46fd37cb..0595136e45 100644 --- a/ui/packages/consul-ui/app/components/auth-profile/index.hbs +++ b/ui/packages/consul-ui/app/components/auth-profile/index.hbs @@ -1,9 +1,12 @@ -
    +
    My ACL Token
    AccessorID
    - {{substr item.AccessorID -8}} + {{string-substring @item.AccessorID (sub @item.AccessorID.length 8)}}
    \ No newline at end of file diff --git a/ui/packages/consul-ui/app/components/auth-profile/index.js b/ui/packages/consul-ui/app/components/auth-profile/index.js deleted file mode 100644 index 4798652642..0000000000 --- a/ui/packages/consul-ui/app/components/auth-profile/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import Component from '@ember/component'; - -export default Component.extend({ - tagName: '', -}); diff --git a/ui/packages/consul-ui/app/components/auth-profile/index.scss b/ui/packages/consul-ui/app/components/auth-profile/index.scss new file mode 100644 index 0000000000..ebc4837a35 --- /dev/null +++ b/ui/packages/consul-ui/app/components/auth-profile/index.scss @@ -0,0 +1,19 @@ +.auth-profile { + padding: 0.9em 1em; +} +.auth-profile { + @extend %p2; +} +.auth-profile dt span { + font-weight: var(--typo-weight-normal); +} +.auth-profile dt { + font-weight: var(--typo-weight-bold); +} +.auth-profile dt, +.auth-profile dd { + color: rgb(var(--tone-gray-800)); +} +.auth-profile dt span { + color: rgb(var(--tone-gray-600)); +} diff --git a/ui/packages/consul-ui/app/components/hashicorp-consul/index.hbs b/ui/packages/consul-ui/app/components/hashicorp-consul/index.hbs index 95eca1b73e..2e610a8a98 100644 --- a/ui/packages/consul-ui/app/components/hashicorp-consul/index.hbs +++ b/ui/packages/consul-ui/app/components/hashicorp-consul/index.hbs @@ -1,397 +1,263 @@ -{{#let (unique-id) as |guid|}} - + + <:notifications as |app|> +{{#each flashMessages.queue as |flash|}} + - <:notifications as |app|> - {{#each flashMessages.queue as |flash|}} - - {{#if flash.dom}} - {{{flash.dom}}} - {{else}} + {{#if flash.dom}} + {{{flash.dom}}} + {{else}} {{#let (lowercase flash.type) (lowercase flash.action) as |status type|}} - - - - {{capitalize status}}! - - - -

    - {{#if (eq type 'logout')}} - {{#if (eq status 'success') }} - You are now logged out. - {{else}} - There was an error logging out. - {{/if}} - {{else if (eq type 'authorize')}} - {{#if (eq status 'success') }} - You are now logged in. - {{else}} - There was an error, please check your SecretID/Token - {{/if}} + + + + {{capitalize status}}! + + + +

    + {{#if (eq type 'logout')}} + {{#if (eq status 'success') }} + You are now logged out. {{else}} - {{#if (or (eq type 'use') (eq flash.model 'token'))}} - - {{else if (eq flash.model 'intention')}} - - {{else if (eq flash.model 'role')}} - - {{else if (eq flash.model 'policy')}} - - {{/if}} + There was an error logging out. {{/if}} -

    -
    -
    + {{else if (eq type 'authorize')}} + {{#if (eq status 'success') }} + You are now logged in. + {{else}} + There was an error, please check your SecretID/Token + {{/if}} + {{else}} + {{#if (or (eq type 'use') (eq flash.model 'token'))}} + + {{else if (eq flash.model 'intention')}} + + {{else if (eq flash.model 'role')}} + + {{else if (eq flash.model 'policy')}} + + {{/if}} + {{/if}} +

    + + {{/let}} - {{/if}} -
    - {{/each}} + {{/if}} +
    +{{/each}} - - <:home-nav> - - + - <:main-nav> -
      + <:home-nav> + + + + <:main-nav> +
        +
      • + + + {{@dc.Name}} + + +{{#let components.MenuItem components.MenuSeparator as |MenuItem MenuSeparator|}} + +{{#each (sort-by 'Name' @dcs) as |item|}} + + + {{item.Name}} + {{#if item.Primary}} + Primary + {{/if}} + {{#if item.Local}} + Local + {{/if}} + + +{{/each}} +{{/let}} + + +
      • + + +{{#if (can "read services")}} +
      • + Services +
      • +{{/if}} +{{#if (can "read nodes")}} +
      • + Nodes +
      • +{{/if}} +{{#if (can "read kv")}} +
      • + Key/Value +
      • +{{/if}} +{{#if (can "read intentions")}} +
      • + Intentions +
      • +{{/if}} + +
      + + + <:complementary-nav> +
        +
      • - + - {{@dc.Name}} + Help -{{#let components.MenuItem components.MenuSeparator as |MenuItem MenuSeparator|}} - - {{#each (sort-by 'Name' @dcs) as |item|}} + {{#let components.MenuItem components.MenuSeparator as |MenuItem MenuSeparator|}} + + + Consul v{{env 'CONSUL_VERSION'}} + + - {{item.Name}} - {{#if item.Primary}} - Primary - {{/if}} - {{#if item.Local}} - Local - {{/if}} + Documentation - {{/each}} -{{/let}} + + + HashiCorp Learn + + + + + + Provide Feedback + + + {{/let}}
      • - - -{{#if (can "read services")}} -
      • - Services -
      • -{{/if}} -{{#if (can "read nodes")}} -
      • - Nodes -
      • -{{/if}} -{{#if (can "read kv")}} -
      • - Key/Value -
      • -{{/if}} -{{#if (can "read intentions")}} -
      • - Intentions -
      • -{{/if}} - -
      • - Tokens -
      • -{{#if (can "read acls")}} -
      • - Policies -
      • -
      • - Roles -
      • -
      • - Auth Methods -
      • -{{else if (not (can "use acls"))}} -
      • - Policies -
      • -
      • - Roles -
      • -
      • - Auth Methods -
      • -{{/if}} -
      - - - <:complementary-nav> -
        - -
      • - - - Help - - - {{#let components.MenuItem components.MenuSeparator as |MenuItem MenuSeparator|}} - - - Consul v{{env 'CONSUL_VERSION'}} - - - - - Documentation - - - - - HashiCorp Learn - - - - - - Provide Feedback - - - {{/let}} - - -
      • -
      • - + Settings -
      • - {{#if (can 'authenticate')}} -
      • - - {{#let components.AuthForm components.AuthProfile as |AuthForm AuthProfile|}} - - - - - - - - -

        Log in to Consul

        -
        - - - - {{#if (can "use SSO")}} - - - - {{/if}} - - - - - -
        -
        - - - - -

        Log in with a different token

        -
        - - - - - - - - -
        - - - - - - Logout - - - {{#let components.MenuItem components.MenuSeparator as |MenuItem MenuSeparator|}} - {{!TODO: It might be nice to use one of our recursive components here}} - {{#if authDialog.token.AccessorID}} -
      • - -
      • - - {{/if}} - - - Logout - - - {{/let}} - - - - {{/let}} - - - {{/if}} -
      - + Settings + + + + {{did-insert (set this 'modal')}} + +
    + - <:main> - {{yield (hash - login=(if (env 'CONSUL_ACLS_ENABLED') this.modal (hash open=undefined)) - )}} - + <:main> + {{yield (hash + login=(if this.modal this.modal (hash open=undefined)) + )}} + - <:content-info> -

    - Consul v{{env 'CONSUL_VERSION'}} -

    - {{{concat ''}}} - -
    -{{/let}} \ No newline at end of file + <:content-info> +

    + Consul v{{env 'CONSUL_VERSION'}} +

    + {{{concat ''}}} + + + \ No newline at end of file diff --git a/ui/packages/consul-ui/app/components/hashicorp-consul/index.js b/ui/packages/consul-ui/app/components/hashicorp-consul/index.js index 6d1578d165..38e7edd518 100644 --- a/ui/packages/consul-ui/app/components/hashicorp-consul/index.js +++ b/ui/packages/consul-ui/app/components/hashicorp-consul/index.js @@ -1,28 +1,6 @@ import Component from '@glimmer/component'; -import { action } from '@ember/object'; import { inject as service } from '@ember/service'; export default class HashiCorpConsul extends Component { @service('flashMessages') flashMessages; - - @action - open() { - this.authForm.focus(); - } - - @action - close() { - this.authForm.reset(); - } - - @action - reauthorize(e) { - this.modal.close(); - this.args.onchange(e); - } - - @action - keypressClick(e) { - e.target.dispatchEvent(new MouseEvent('click')); - } } diff --git a/ui/packages/consul-ui/app/components/menu-panel/layout.scss b/ui/packages/consul-ui/app/components/menu-panel/layout.scss index 6974243c08..ac953aeb8a 100644 --- a/ui/packages/consul-ui/app/components/menu-panel/layout.scss +++ b/ui/packages/consul-ui/app/components/menu-panel/layout.scss @@ -45,9 +45,6 @@ display: block; } /**/ -%menu-panel dl { - padding: 0.9em 1em; -} %menu-panel > ul > li > div[role='menu'] { @extend %menu-panel-sub-panel; } diff --git a/ui/packages/consul-ui/app/components/menu-panel/skin.scss b/ui/packages/consul-ui/app/components/menu-panel/skin.scss index aff64474c5..bf759cd401 100644 --- a/ui/packages/consul-ui/app/components/menu-panel/skin.scss +++ b/ui/packages/consul-ui/app/components/menu-panel/skin.scss @@ -6,10 +6,6 @@ %menu-panel > ul > li { list-style-type: none; } -%menu-panel dt { - font-weight: var(--typo-weight-bold); -} -%menu-panel dl, %menu-panel-header { @extend %p2; } @@ -18,9 +14,6 @@ text-transform: uppercase; font-weight: var(--typo-weight-medium); } -%menu-panel dt span { - font-weight: var(--typo-weight-normal); -} %menu-panel-header + ul, %menu-panel-separator:not(:first-child) { border-top: var(--decor-border-100); @@ -32,13 +25,6 @@ border-color: rgb(var(--tone-gray-300)); background-color: rgb(var(--tone-gray-000)); } -%menu-panel dt, -%menu-panel dd { - color: rgb(var(--tone-gray-800)); -} -%menu-panel dt span { - color: rgb(var(--tone-gray-600)); -} %menu-panel-separator { color: rgb(var(--tone-gray-600)); } diff --git a/ui/packages/consul-ui/app/styles/components.scss b/ui/packages/consul-ui/app/styles/components.scss index 197e909631..00e9d2981d 100644 --- a/ui/packages/consul-ui/app/styles/components.scss +++ b/ui/packages/consul-ui/app/styles/components.scss @@ -3,6 +3,7 @@ @import 'consul-ui/components/anchors'; @import 'consul-ui/components/auth-form'; @import 'consul-ui/components/auth-modal'; +@import 'consul-ui/components/auth-profile'; @import 'consul-ui/components/breadcrumbs'; @import 'consul-ui/components/buttons'; @import 'consul-ui/components/card'; diff --git a/ui/packages/consul-ui/app/styles/typography.scss b/ui/packages/consul-ui/app/styles/typography.scss index 2e9bd6370f..8bf6a3238e 100644 --- a/ui/packages/consul-ui/app/styles/typography.scss +++ b/ui/packages/consul-ui/app/styles/typography.scss @@ -78,7 +78,6 @@ pre code, /**/ /* resets */ -%menu-panel dt span, %empty-state-subheader, %main-content label a[rel*='help'], %pill, diff --git a/ui/packages/consul-ui/tests/integration/components/auth-dialog-test.js b/ui/packages/consul-ui/tests/integration/components/auth-dialog-test.js deleted file mode 100644 index 32b6594032..0000000000 --- a/ui/packages/consul-ui/tests/integration/components/auth-dialog-test.js +++ /dev/null @@ -1,26 +0,0 @@ -import { module, test } from 'qunit'; -import { setupRenderingTest } from 'ember-qunit'; -import { render } from '@ember/test-helpers'; -import { hbs } from 'ember-cli-htmlbars'; - -module('Integration | Component | auth-dialog', 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) { ... }); - - await render(hbs``); - - assert.equal(this.element.textContent.trim(), ''); - - // Template block usage: - await render(hbs` - - template block text - - `); - - assert.equal(this.element.textContent.trim(), 'template block text'); - }); -});