CC-5545: Side Nav (#19342)

* Initial work for sidenav

* Use HDS::Text

* Add resolution for ember-element-helper

* WIP dc selector

* Update HCP Home link

* DC selector

* Hook up remaining selectors

* Fix settings and tutorial links

* Remove comments

* Remove skip-links

* Replace auth with new dropdown

* Use href-to helper for sidenav links

* Changelog

* Add description to NavSelector

* Wrap version in footer and role

* Fix login tests

* Add data-test selectors for namespaces

* Fix datacenter disclosure menu test

* Stop rendering auth dialog if acls are disabled

* Update disabled selector state and token selector

* Fix logic in ACL selector

* Fix HCP Home integration test

* Remove toggling the sidenav in tests

* Add sidenav to eng docs

* Re-add debug navigation for eng docs

* Remove ember-in-viewport

* Remove unused styles

* Upgrade @hashicorp/design-system-componentseee

* Add translations for side-nav

* Only show back to hcp link if url is present

* Disable responsive due to a11y-dialog issue
pull/19529/head
Tyler Wendlandt 2023-11-06 08:18:48 -07:00 committed by GitHub
parent 6baf695cd9
commit e5948e8eb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
58 changed files with 986 additions and 1763 deletions

3
.changelog/19342.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:improvement
Replaces UI Side Nav with Helios Design System Side Nav. Adds dc/partition/namespace searching in Side Nav.
```

View File

@ -3,82 +3,54 @@
SPDX-License-Identifier: BUSL-1.1
}}
<li
class="acls-separator"
role="separator"
>
Access Controls
{{#if (not (can "use acls"))}}
<span
{{tooltip "ACLs are not currently enabled in this cluster"}}
></span>
{{/if}}
</li>
<li
data-test-main-nav-tokens
class={{if (is-href 'dc.acls.tokens' @dc.Name) 'is-active'}}
>
<a
href={{href-to 'dc.acls.tokens' @dc.Name}}
>
Tokens
</a>
</li>
{{#if (can "read acls")}}
<li
data-test-main-nav-policies
class={{if (is-href 'dc.acls.policies' @dc.Name) 'is-active'}}
>
<a
href={{href-to 'dc.acls.policies' @dc.Name}}
>
Policies
</a>
</li>
<li
data-test-main-nav-roles
class={{if (is-href 'dc.acls.roles' @dc.Name) 'is-active'}}
>
<a
href={{href-to 'dc.acls.roles' @dc.Name}}
>
Roles
</a>
</li>
<li
data-test-main-nav-auth-methods
class={{if (is-href 'dc.acls.auth-methods' @dc.Name) 'is-active'}}
>
<a
href={{href-to 'dc.acls.auth-methods' @dc.Name}}
>
Auth Methods
</a>
</li>
{{else if (not (can "use acls"))}}
<li
data-test-main-nav-policies
class={{if (is-href 'dc.acls.policies' @dc.Name) 'is-active'}}
>
<span>
Policies
</span>
</li>
<li
data-test-main-nav-roles
class={{if (is-href 'dc.acls.roles' @dc.Name) 'is-active'}}
>
<span>
Roles
</span>
</li>
<li
data-test-main-nav-auth-methods
class={{if (is-href 'dc.acls.auth-methods' @dc.Name) 'is-active'}}
>
<span>
Auth Methods
</span>
</li>
{{/if}}
{{#let @list as |SNL|}}
{{#if (can "use acls")}}
<SNL.Title>{{t "components.hashicorp-consul.side-nav.acls.title"}}</SNL.Title>
{{else}}
<SNL.Title {{tooltip (t "components.hashicorp-consul.side-nav.acls.tooltip")}}>
{{t "components.hashicorp-consul.side-nav.acls.title"}}
</SNL.Title>
{{/if}}
<SNL.Link
@text={{t "components.hashicorp-consul.side-nav.acls.tokens"}}
@href={{href-to "dc.acls.tokens" @dc.Name}}
@isHrefExternal={{false}}
@isActive={{is-href "dc.acls.tokens" @dc.Name}}
data-test-main-nav-tokens
/>
{{#if (can "read acls")}}
<SNL.Link
@text={{t "components.hashicorp-consul.side-nav.acls.policies"}}
@href={{href-to "dc.acls.policies" @dc.Name}}
@isHrefExternal={{false}}
@isActive={{is-href "dc.acls.policies" @dc.Name}}
data-test-main-nav-policies
/>
<SNL.Link
@text={{t "components.hashicorp-consul.side-nav.acls.roles"}}
@href={{href-to "dc.acls.roles" @dc.Name}}
@isHrefExternal={{false}}
@isActive={{is-href "dc.acls.roles" @dc.Name}}
data-test-main-nav-roles
/>
<SNL.Link
@text={{t "components.hashicorp-consul.side-nav.acls.auth-methods"}}
@href={{href-to "dc.acls.auth-methods" @dc.Name}}
@isHrefExternal={{false}}
@isActive={{is-href "dc.acls.auth-methods" @dc.Name}}
data-test-main-nav-auth-methods
/>
{{else if (not (can "use acls"))}}
<SNL.Item class="consul-disabled-nav" data-test-main-nav-policies>
{{t "components.hashicorp-consul.side-nav.acls.policies"}}
</SNL.Item>
<SNL.Item class="consul-disabled-nav" data-test-main-nav-roles>
{{t "components.hashicorp-consul.side-nav.acls.roles"}}
</SNL.Item>
<SNL.Item class="consul-disabled-nav" data-test-main-nav-auth-methods>
{{t "components.hashicorp-consul.side-nav.acls.auth-methods"}}
</SNL.Item>
{{/if}}
{{/let}}

View File

@ -2,7 +2,7 @@
A self-contained component to allow the user to 'select' their token a.k.a.
log in. The component is mostly a wrapper around a composition of `<AuthDialog
/>`, `<AuthForm />`, `<AuthProfile />` and `<ModalDialog />`. The majority of
/>`, `<AuthForm />`, and `<ModalDialog />`. The majority of
the functionality is contained in those other components. This composition
mostly orchestrates the interactions between them i.e. wires them together.

View File

@ -3,163 +3,162 @@
SPDX-License-Identifier: BUSL-1.1
}}
{{#if (can 'use acls')}}
<li data-test-main-nav-auth>
{{#if (can "use acls")}}
<AuthDialog
@src={{uri "settings://consul:token"}}
@sink={{uri "settings://consul:token"}}
@onchange={{this.reauthorize}}
>
<:unauthorized as |authDialog|>
<AuthDialog
@src={{uri 'settings://consul:token'}}
@sink={{uri 'settings://consul:token'}}
@onchange={{this.reauthorize}}
>
<:unauthorized as |authDialog|>
<Portal @target="app-before-skip-links">
<Action
{{on "click" (optional this.modal.open)}}
<ModalDialog
@name="login-toggle"
@onclose={{this.close}}
@onopen={{this.open}}
@aria={{hash label="Log in to Consul"}}
as |modal|
>
<Ref @target={{this}} @name="modal" @value={{modal}} />
<BlockSlot @name="header">
<h2>
Log in to Consul
</h2>
</BlockSlot>
<BlockSlot @name="body">
<AuthForm
@dc={{@dc.Name}}
@partition={{@partition}}
@nspace={{@nspace}}
@onsubmit={{action authDialog.login value="data"}}
as |authForm|
>
Login
</Action>
</Portal>
<Action
<Ref @target={{this}} @name="authForm" @value={{authForm}} />
{{#if (can "use SSO")}}
<authForm.Method @matches="sso">
<OidcSelect
@dc={{@dc.Name}}
@partition={{@partition}}
@nspace={{@nspace}}
@disabled={{authForm.disabled}}
@onchange={{authForm.submit}}
@onerror={{authForm.error}}
/>
</authForm.Method>
{{/if}}
</AuthForm>
</BlockSlot>
<BlockSlot @name="actions">
<Hds::Button
@color="secondary"
@text="Continue without logging in"
{{on "click" modal.close}}
/>
</BlockSlot>
</ModalDialog>
<Hds::Dropdown
class="hds-side-nav__dropdown"
@listPosition="bottom-left"
as |dd|
>
<dd.ToggleIcon @icon="user" @text="Auth menu" data-test-auth-menu />
<dd.Interactive
@href={{href-to
"settings"
params=(hash nspace=undefined partition=undefined)
}}
@text={{t "components.hashicorp-consul.side-nav.user-menu.settings"}}
@isHrefExternal={{false}}
/>
<dd.Interactive
@text={{t "components.hashicorp-consul.side-nav.user-menu.log-in"}}
data-test-auth-menu-login
{{on "click" (optional this.modal.open)}}
>
Log in
</Action>
<ModalDialog
@name="login-toggle"
@onclose={{this.close}}
@onopen={{this.open}}
@aria={{hash
label="Log in to Consul"
}}
as |modal|>
<Ref
@target={{this}}
@name="modal"
@value={{modal}}
/>
<BlockSlot @name="header">
<h2>
Log in to Consul
</h2>
</BlockSlot>
<BlockSlot @name="body">
<AuthForm
@dc={{@dc.Name}}
@partition={{@partition}}
@nspace={{@nspace}}
@onsubmit={{action authDialog.login value="data"}}
as |authForm|>
<Ref
@target={{this}}
@name="authForm"
@value={{authForm}}
/>
{{#if (can "use SSO")}}
<authForm.Method @matches="sso">
<OidcSelect
@dc={{@dc.Name}}
@partition={{@partition}}
@nspace={{@nspace}}
@disabled={{authForm.disabled}}
@onchange={{authForm.submit}}
@onerror={{authForm.error}}
/>
</authForm.Method>
{{/if}}
</AuthForm>
</BlockSlot>
<BlockSlot @name="actions">
<Hds::Button
@color='secondary'
@text='Continue without logging in'
{{on 'click' modal.close}}
/>
</BlockSlot>
</ModalDialog>
</:unauthorized>
<:authorized as |authDialog|>
<ModalDialog
@name="login-toggle"
@onclose={{this.close}}
@onopen={{this.open}}
@aria={{hash
label="Log in with a different token"
}}
as |modal|>
<Ref
@target={{this}}
@name="modal"
@value={{modal}}
/>
<BlockSlot @name="header">
<h2>
Log in with a different token
</h2>
</BlockSlot>
<BlockSlot @name="body">
<AuthForm
@dc={{@dc.Name}}
@nspace={{@nspace}}
@partition={{@partition}}
@onsubmit={{action authDialog.login value="data"}}
as |authForm|>
<Ref
@target={{this}}
@name="authForm"
@value={{authForm}}
/>
</AuthForm>
</BlockSlot>
<BlockSlot @name="actions">
<Hds::Button
@color='secondary'
@text='Continue without logging in'
{{on 'click' modal.close}}
/>
</BlockSlot>
</ModalDialog>
<Portal @target="app-before-skip-links">
<Action
{{on "click" (optional authDialog.logout)}}
>
Logout
</Action>
</Portal>
<DisclosureMenu as |disclosure|>
<disclosure.Action
{{on 'click' disclosure.toggle}}
>
Logout
</disclosure.Action>
<disclosure.Menu as |panel|>
{{#if authDialog.token.AccessorID}}
<AuthProfile
@item={{authDialog.token}}
/>
{{/if}}
<panel.Menu as |menu|>
<menu.Separator />
<menu.Item
class="dangerous"
>
<menu.Action
{{on 'click' (optional authDialog.logout)}}
>
Logout
</menu.Action>
</menu.Item>
</panel.Menu>
</disclosure.Menu>
</DisclosureMenu>
</:authorized>
</AuthDialog>
/>
</Hds::Dropdown>
</:unauthorized>
<:authorized as |authDialog|>
</li>
{{yield
(hash
open=this.modal.open
close=this.model.close
)
}}
{{/if}}
<ModalDialog
@name="login-toggle"
@onclose={{this.close}}
@onopen={{this.open}}
@aria={{hash label="Log in with a different token"}}
as |modal|
>
<Ref @target={{this}} @name="modal" @value={{modal}} />
<BlockSlot @name="header">
<h2>
Log in with a different token
</h2>
</BlockSlot>
<BlockSlot @name="body">
<AuthForm
@dc={{@dc.Name}}
@nspace={{@nspace}}
@partition={{@partition}}
@onsubmit={{action authDialog.login value="data"}}
as |authForm|
>
<Ref @target={{this}} @name="authForm" @value={{authForm}} />
</AuthForm>
</BlockSlot>
<BlockSlot @name="actions">
<Hds::Button
@color="secondary"
@text="Continue without logging in"
{{on "click" modal.close}}
/>
</BlockSlot>
</ModalDialog>
<Hds::Dropdown
class="hds-side-nav__dropdown"
@listPosition="bottom-left"
as |dd|
>
<dd.ToggleIcon @icon="user" @text="Auth menu" data-test-auth-menu />
{{#if authDialog.token.AccessorID}}
<dd.Description
@text={{t
"components.consul.token.selector.logged-in"
token=(string-substring
authDialog.token.AccessorID
(sub authDialog.token.AccessorID.length 8)
)
htmlSafe=true
}}
/>
{{/if}}
<dd.Separator />
<dd.Interactive
@href={{href-to
"settings"
params=(hash nspace=undefined partition=undefined)
}}
@text={{t "components.hashicorp-consul.side-nav.user-menu.settings"}}
@isHrefExternal={{false}}
/>
<dd.Interactive
@text={{t "components.hashicorp-consul.side-nav.user-menu.log-out"}}
data-test-auth-menu-logout
{{on "click" (optional authDialog.logout)}}
/>
</Hds::Dropdown>
</:authorized>
</AuthDialog>
{{yield (hash open=this.modal.open close=this.model.close)}}
{{else}}
<Hds::Dropdown class="hds-side-nav__dropdown" @listPosition="bottom-left" as |dd|>
<dd.ToggleIcon @icon="user" @text="Auth menu" data-test-auth-menu />
<dd.Interactive
@href={{href-to
"settings"
params=(hash nspace=undefined partition=undefined)
}}
@text={{t "components.hashicorp-consul.side-nav.user-menu.settings"}}
@isHrefExternal={{false}}
/>
</Hds::Dropdown>
{{/if}}

View File

@ -3,11 +3,14 @@
SPDX-License-Identifier: BUSL-1.1
}}
<div
class="consul-hcp-home"
...attributes
>
<a href={{env 'CONSUL_HCP_URL'}} data-native-href="true">
Back to HCP
</a>
</div>
{{#let @list (env "CONSUL_HCP_URL") as |SNL hcpUrl|}}
{{log hcpUrl}}
{{#if (and SNL hcpUrl)}}
<SNL.BackLink
@text={{t "components.hashicorp-consul.side-nav.hcp"}}
@href={{hcpUrl}}
@isHrefExternal={{true}}
data-test-back-to-hcp
/>
{{/if}}
{{/let}}

View File

@ -1,16 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
.consul-hcp-home {
position: relative;
top: -22px;
}
.consul-hcp-home a::before {
content: '';
--icon-name: icon-arrow-left;
--icon-size: icon-300;
margin-right: 8px;
}

View File

@ -35,9 +35,46 @@ module('Integration | Component | consul hcp home', function(hooks) {
}
);
await render(hbs`<Consul::Hcp::Home />`);
await render(hbs`
<Hds::SideNav::List as |SNL|>
<Consul::Hcp::Home @list={{SNL}} />
</Hds::SideNav::List>
`);
assert.dom('[data-test-back-to-hcp]').isVisible();
assert.dom('a').hasAttribute('href', 'http://hcp');
});
test('it does not output the Back to HCP link if CONSUL_HCP_URL is not present', async function(assert) {
// temporary registration until we are running as separate applications
this.owner.register(
'component:consul/hcp/home',
ConsulHcpHome
);
//
const Helper = this.owner.resolveRegistration('helper:env');
this.owner.register(
'helper:env',
class extends Helper {
compute([name, def]) {
switch(name) {
case 'CONSUL_HCP_URL':
return undefined;
}
return super.compute(...arguments);
}
}
);
await render(hbs`
<Hds::SideNav::List as |SNL|>
<Consul::Hcp::Home @list={{SNL}} />
</Hds::SideNav::List>
`);
assert.dom('[data-test-back-to-hcp]').doesNotExist();
assert.dom('a').doesNotExist();
});
});

View File

@ -3,93 +3,58 @@
SPDX-License-Identifier: BUSL-1.1
}}
{{#if (can "use nspaces")}}
{{#if (can "choose nspaces")}}
{{#let
(or @nspace 'default')
(is-href 'dc.nspaces' @dc.Name)
as |nspace isManaging|}}
<li
class="nspaces"
data-test-nspace-menu
>
<DisclosureMenu
aria-label="Namespace"
@items={{append
(hash
Name="Manage Namespaces"
href=(href-to 'dc.nspaces' @dc.Name)
)
(reject-by 'DeletedAt' @nspaces)
}}
as |disclosure|>
<disclosure.Action
{{on 'click' disclosure.toggle}}
>
{{if isManaging 'Manage Namespaces' nspace}}
</disclosure.Action>
<disclosure.Menu as |panel|>
{{#if (gt @nspaces.length 0)}}
<DataSource
@src={{uri
'/${partition}/*/${dc}/namespaces'
(hash
partition=@partition
dc=@dc.Name
)
}}
@onchange={{fn (optional @onchange)}}
/>
{{else}}
<DataSource
@src={{uri
'/${partition}/*/${dc}/namespaces'
(hash
partition=@partition
dc=@dc.Name
)
}}
@onchange={{fn (optional @onchange)}}
/>
{{/if}}
<panel.Menu as |menu|>
{{#each menu.items as |item|}}
<menu.Item
data-test-main-nav-nspaces={{not-eq item.href undefined}}
aria-current={{if
(or
(and isManaging item.href)
(and (not isManaging) (eq nspace item.Name))
)
'true'
}}
>
<menu.Action
{{on 'click' disclosure.close}}
@href={{if item.href
item.href
(if isManaging
(href-to 'dc.services.index' params=(hash
partition=(if (gt @partition.length 0) @partition undefined)
nspace=item.Name
dc=@dc.Name
))
(href-to '.' params=(hash
partition=(if (gt @partition.length 0) @partition undefined)
nspace=item.Name
))
)
}}
>
{{item.Name}}
</menu.Action>
</menu.Item>
{{/each}}
</panel.Menu>
</disclosure.Menu>
</DisclosureMenu>
</li>
{{/let}}
{{/if}}
{{/if}}
{{#if (and (can "use nspaces") (can "choose nspaces"))}}
<DataSource
@src={{uri
"/${partition}/*/${dc}/namespaces"
(hash partition=@partition dc=@dc.Name)
}}
@onchange={{fn (optional @onchange)}}
/>
{{#let
@list
(if @nspace (hash Name=@nspace) (hash Name="default"))
(is-href "dc.nspaces" @dc.Name)
as |SNL nspace isManaging|
}}
<SNL.Title class="consul-side-nav__selector-title">{{t "components.hashicorp-consul.side-nav.nspaces.title"}}</SNL.Title>
<NavSelector
@list={{@list}}
@items={{sort-by "Name:asc" (reject-by "DeletedAt" @nspaces)}}
@item={{nspace}}
@key="Name"
@icon="folder"
@placeholder={{t "components.hashicorp-consul.side-nav.nspaces.placeholder"}}
@footerLink={{href-to "dc.nspaces" @dc.Name}}
@footerLinkText={{t "components.hashicorp-consul.side-nav.nspaces.footer"}}
data-test-nspace-menu
as |Dropdown item|
>
<Dropdown.Checkmark
@selected={{eq nspace.Name item.Name}}
@href={{if
isManaging
(href-to
"dc.services.index"
params=(hash
partition=(if (gt @partition.length 0) @partition undefined)
nspace=item.Name
dc=@dc.Name
)
)
(href-to
"."
params=(hash
partition=(if (gt @partition.length 0) @partition undefined)
nspace=item.Name
)
)
}}
@isHrefExternal={{false}}
data-test-nspace-item
>
{{item.Name}}
</Dropdown.Checkmark>
</NavSelector>
{{/let}}
{{/if}}

View File

@ -4,71 +4,50 @@
}}
{{#let
(or @partition "default")
@list
(if @partition (hash Name=@partition) (hash Name="default"))
(is-href "dc.partitions" @dc.Name)
as |partition isManaging|
(can "choose partitions" dc=@dc)
as |SNL partition isManaging canChoose|
}}
{{#if (can "choose partitions" dc=@dc)}}
<li class="partitions" data-test-partition-menu>
<DisclosureMenu
aria-label="Admin Partition"
@items={{append
(hash
Name="Manage Partitions" href=(href-to "dc.partitions" @dc.Name)
<DataSource
@src={{uri "/*/*/${dc}/partitions" (hash dc=@dc.Name)}}
@onchange={{fn (optional @onchange)}}
/>
<SNL.Title class="consul-side-nav__selector-title">{{t "components.hashicorp-consul.side-nav.partitions.title"}}</SNL.Title>
<NavSelector
@list={{@list}}
@items={{sort-by "Name:asc" (reject-by "DeletedAt" @partitions)}}
@item={{partition}}
@key="Name"
@icon="users"
@placeholder={{t "components.hashicorp-consul.side-nav.partitions.placeholder"}}
@footerLink={{href-to "dc.partitions" @dc.Name}}
@footerLinkText={{t "components.hashicorp-consul.side-nav.partitions.footer"}}
@disabled={{not canChoose}}
data-test-datacenter-disclosure-menu
as |Dropdown item|
>
{{#if canChoose}}
<Dropdown.Checkmark
@selected={{eq partition.Name item.Name}}
@href={{if
item.href
item.href
(if
isManaging
(href-to
"dc.services.index"
params=(hash partition=item.Name nspace=undefined dc=@dc.Name)
)
(href-to "." params=(hash partition=item.Name nspace=undefined))
)
(reject-by "DeletedAt" @partitions)
}}
as |disclosure|
@isHrefExternal={{false}}
data-test-partiton-item
>
<disclosure.Action {{on "click" disclosure.toggle}}>
{{if isManaging "Manage Partition" partition}}
</disclosure.Action>
<disclosure.Menu as |panel|>
<DataSource
@src={{uri "/*/*/${dc}/partitions" (hash dc=@dc.Name)}}
@onchange={{fn (optional @onchange)}}
/>
<panel.Menu as |menu|>
{{#each menu.items as |item|}}
<menu.Item
aria-current={{if
(or
(and isManaging item.href)
(and (not isManaging) (eq partition item.Name))
)
"true"
}}
>
<menu.Action
{{on "click" disclosure.close}}
@href={{if
item.href
item.href
(if
isManaging
(href-to
"dc.services.index"
params=(hash
partition=item.Name nspace=undefined dc=@dc.Name
)
)
(href-to
"." params=(hash partition=item.Name nspace=undefined)
)
)
}}
>
{{item.Name}}
</menu.Action>
</menu.Item>
{{/each}}
</panel.Menu>
</disclosure.Menu>
</DisclosureMenu>
</li>
{{else}}
<li class="partition" aria-label="Admin Partition">
{{"default"}}
</li>
{{/if}}
{{item.Name}}
</Dropdown.Checkmark>
{{/if}}
</NavSelector>
{{/let}}

View File

@ -3,23 +3,14 @@
SPDX-License-Identifier: BUSL-1.1
}}
<li
class="peers-separator"
role="separator"
...attributes
>
Organization
</li>
<li
data-test-main-nav-peers
class={{if (is-href 'dc.peers' @dc.Name) 'is-active'}}
>
<a
href={{href-to 'dc.peers' @dc.Name
params=(hash peer=undefined)
}}
>
Peers
</a>
</li>
{{#let @list as |SNL|}}
<SNL.Title ...attributes>{{t "components.hashicorp-consul.side-nav.organization.title"}}</SNL.Title>
<SNL.Link
@text={{t "components.hashicorp-consul.side-nav.organization.peers"}}
@route="dc.peers"
@models={{array @dc.Name}}
@query={{hash peer=undefined}}
@isActive={{is-href "dc.peers" @dc.Name}}
data-test-main-nav-peers
/>
{{/let}}

View File

@ -3,102 +3,19 @@
SPDX-License-Identifier: BUSL-1.1
}}
{{#let (hash
main=(concat guid '-main')
Notification=(component 'app/notification')
) as |exported|}}
{{#let (hash main=(concat guid '-main') Notification=(component 'app/notification')) as |exported|}}
<div
class="app"
...attributes
>
<div class='app' ...attributes>
<ModalLayer />
<div
class="skip-links"
{{on "click" this.focus}}
>
<PortalTarget
@name="app-before-skip-links"
@multiple={{true}}
></PortalTarget>
<a href={{concat '#' exported.main}}>{{t 'components.app.skip_to_content'}}</a>
{{!--
In order to add further skip links from within other templates use:
<Portal @target="app-skip-links">
<a href="#sub-content">Skip to subcontent</a>
</Portal>
from within your template
--}}
<PortalTarget
@name="app-after-skip-links"
@multiple={{true}}
></PortalTarget>
{{yield exported to='side-nav'}}
<main id={{concat guid '-main'}}>
<div class='notifications'>
{{yield exported to='notifications'}}
<PortalTarget @name='app-notifications' @multiple={{true}} />
</div>
{{yield exported to='main'}}
</main>
</div>
<ModalLayer />
<input
type="checkbox"
id={{concat guid "-main-nav-toggle"}}
/>
<header
role="banner"
>
<label
tabindex="0"
for={{concat guid "-main-nav-toggle"}}
aria-label={{t 'components.app.toggle_menu'}}
{{on "keypress" this.keypressClick}}
{{on "mouseup" this.unfocus}}
></label>
{{yield exported to="home-nav"}}
<div
data-test-navigation
>
{{!--
The viewport tolerances here give us a 10 pixel buffer to make sure the menu
is marked as out of the viewport, we use all sides so we don't need to change
this should any CSS change
--}}
<nav
aria-label={{t 'components.app.main'}}
class={{if this.navInViewport 'in-viewport'}}
{{in-viewport
onEnter=(set this 'navInViewport' true)
onExit=(set this 'navInViewport' false)
viewportTolerance=(hash top=-10 bottom =-10 left=-10 right=-10)
}}
>
{{yield exported to="main-nav"}}
</nav>
{{!--
Whilst this has a role of navigation, it is 'complementary navigation' we
don't want to change the navigation role here, but we do want to label it as
'complementary' to the main content. The phrase 'complementary navigation' as
read by a screenreader should convey the meaning we are after here.
--}}
<nav aria-label={{t 'components.app.complementary'}}>
{{yield exported to="complementary-nav"}}
</nav>
</div>
</header>
<main id={{concat guid '-main'}}>
<div class="notifications">
{{yield exported to="notifications"}}
<PortalTarget
@name="app-notifications"
@multiple={{true}}
></PortalTarget>
</div>
{{yield exported to="main"}}
</main>
<footer
role="contentinfo"
data-test-footer
>
{{yield exported to="content-info"}}
</footer>
</div>
{{/let}}

View File

@ -3,9 +3,6 @@
* SPDX-License-Identifier: BUSL-1.1
*/
.app .skip-links {
@extend %skip-links;
}
.app .notifications {
@extend %app-notifications;
}
@ -28,125 +25,3 @@
max-width: 80%;
pointer-events: auto;
}
[role='contentinfo'] {
@extend %footer;
}
[role='banner'] {
@extend %main-header-horizontal;
}
[role='banner'] > label {
@extend %main-nav-horizontal-toggle-button;
}
.app > input[id] {
@extend %main-nav-horizontal-toggle;
}
%main-header-horizontal > div {
@extend %main-nav-horizontal-panel;
}
%main-header-horizontal nav:first-of-type {
@extend %main-nav-vertical, %main-nav-sidebar;
}
%main-header-horizontal nav:last-of-type {
@extend %main-nav-horizontal;
margin-left: auto;
}
%main-nav-vertical-hoisted {
top: 18px;
}
%main-nav-vertical-hoisted [aria-label]::before {
display: none !important;
}
%main-nav-horizontal [aria-haspopup='menu'] ~ * {
position: absolute;
right: 0;
min-width: 192px;
}
%main-nav-horizontal [aria-expanded],
%main-nav-vertical-hoisted [aria-expanded] {
@extend %main-nav-horizontal-popover-menu-trigger;
@extend %main-nav-horizontal-action;
}
%main-nav-horizontal-popover-menu-trigger {
@extend %main-nav-horizontal-action-active;
}
%footer,
%main-nav-sidebar,
%main-notifications,
main {
@extend %transition-pushover;
}
%footer {
@extend %body-100-regular;
position: fixed;
z-index: 50;
color: var(--token-color-foreground-disabled);
width: 250px;
padding-left: 25px;
}
%footer {
top: calc(100vh - 42px);
top: calc(max(100vh, 460px) - 42px);
}
html.has-partitions.has-nspaces .app [role='contentinfo'] {
top: calc(100vh - 42px);
top: calc(max(100vh, 640px) - 42px);
}
%main-nav-sidebar {
z-index: 10;
}
%footer,
%main-nav-sidebar {
transition-property: left;
}
%app-notifications,
main {
margin-top: var(--chrome-height, 64px);
transition-property: margin-left;
}
%app-notifications {
transition-property: margin-left, width;
}
@media #{$--sidebar-open} {
%main-nav-horizontal-toggle ~ main .notifications {
width: calc(100% - var(--chrome-width));
}
%main-nav-horizontal-toggle:checked ~ main .notifications {
width: 100%;
}
%main-nav-horizontal-toggle ~ footer,
%main-nav-horizontal-toggle + header > div > nav:first-of-type {
left: 0;
}
%main-nav-horizontal-toggle:checked ~ footer,
%main-nav-horizontal-toggle:checked + header > div > nav:first-of-type {
left: calc(var(--chrome-width, 280px) * -1);
}
%main-nav-horizontal-toggle ~ main {
margin-left: var(--chrome-width, 280px);
}
%main-nav-horizontal-toggle:checked ~ main .notifications,
%main-nav-horizontal-toggle:checked ~ main {
margin-left: 0;
}
}
@media #{$--lt-sidebar-open} {
%main-nav-horizontal-toggle ~ main .notifications {
width: 100%;
}
%main-nav-horizontal-toggle:checked ~ footer,
%main-nav-horizontal-toggle:checked + header > div > nav:first-of-type {
left: 0;
}
%main-nav-horizontal-toggle ~ footer,
%main-nav-horizontal-toggle + header > div > nav:first-of-type {
left: calc(var(--chrome-width, 280px) * -1);
}
%main-nav-horizontal-toggle ~ main .notifications,
%main-nav-horizontal-toggle ~ main {
margin-left: 0;
}
}

View File

@ -14,9 +14,6 @@ A component to help orchestrate a login/logout flow.
/>
</:unauthorized>
<:authorized as |api|>
<AuthProfile
@item={{api.token}}
/>
<button
{{on 'click' (fn api.logout)}}
>

View File

@ -1,24 +0,0 @@
# AuthProfile
A straightforward partial-like component for rendering a user profile.
Only the last 8 characters are shown.
```hbs preview-template
<AuthProfile
@item={{hash AccessorID='123456-1234567-123456'}}
/>
```
## Arguments
| Argument | Type | Default | Description |
| --- | --- | --- | --- |
| `item` | `Token` | | A token object (currently only requires an AccessorID property to be set |
## See
- [Component Source Code](./index.js)
- [Template Source Code](./index.hbs)
---

View File

@ -1,17 +0,0 @@
{{!
Copyright (c) HashiCorp, Inc.
SPDX-License-Identifier: BUSL-1.1
}}
<dl
class="auth-profile"
...attributes
>
<dt>
<span>My ACL Token</span><br />
AccessorID
</dt>
<dd>
{{string-substring @item.AccessorID (sub @item.AccessorID.length 8)}}
</dd>
</dl>

View File

@ -1,24 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
.auth-profile {
padding: 0.9em 1em;
}
.auth-profile {
@extend %body-100-regular;
}
.auth-profile dt span {
font-weight: var(--token-typography-font-weight-regular);
}
.auth-profile dt {
font-weight: var(--token-typography-font-weight-bold);
}
.auth-profile dt,
.auth-profile dd {
color: var(--token-color-paletter-neutral-300);
}
.auth-profile dt span {
color: var(--token-color-foreground-faint);
}

View File

@ -3,67 +3,56 @@
SPDX-License-Identifier: BUSL-1.1
}}
<li class='dcs' data-test-datacenter-menu>
{{#let @list as |SNL|}}
{{#if (gt @dcs.length 1)}}
<DisclosureMenu
aria-label='Datacenter'
<SNL.Title class='consul-side-nav__selector-title'>{{t "components.hashicorp-consul.side-nav.datacenters.title"}}</SNL.Title>
<NavSelector
@list={{SNL}}
@items={{sort-by 'Primary:desc' 'Local:desc' 'Name:asc' @dcs}}
data-test-datacenter-disclosure-menu
as |disclosure|
@item={{@dc}}
@key='Name'
@icon='server-cluster'
@placeholder={{t "components.hashicorp-consul.side-nav.datacenters.placeholder"}}
@description={{t "components.hashicorp-consul.side-nav.datacenters.description"}}
class='consul-datacenter-selector'
data-test-datacenter-menu
as |Dropdown item|
>
<disclosure.Action {{on 'click' disclosure.toggle}}>
{{@dc.Name}}
</disclosure.Action>
<disclosure.Menu as |panel|>
<DataSource
@src={{uri '/*/*/*/datacenters'}}
@onchange={{action (mut @dcs) value='data'}}
/>
<p class='dcs-message'>
Datacenters shown in this dropdown are available through WAN Federation.
</p>
<panel.Menu as |menu|>
<menu.Separator>
DATACENTERS
</menu.Separator>
{{#each menu.items as |item|}}
<menu.Item
data-test-dc-item
aria-current={{if (eq @dc.Name item.Name) 'true'}}
class={{class-map (array 'is-local' item.Local) (array 'is-primary' item.Primary)}}
>
<menu.Action
{{on 'click' disclosure.close}}
@href={{href-to
'.'
params=(hash
dc=item.Name
partition=undefined
nspace=(if (gt @nspace.length 0) @nspace undefined)
)
}}
>
{{item.Name}}
{{#if item.Primary}}
<span>Primary</span>
{{/if}}
{{#if item.Local}}
<span>Local</span>
{{/if}}
</menu.Action>
</menu.Item>
{{/each}}
</panel.Menu>
</disclosure.Menu>
</DisclosureMenu>
<Dropdown.Checkmark
@selected={{eq @dc.Name item.Name}}
@href={{href-to
'.'
params=(hash
dc=item.Name partition=undefined nspace=(if (gt @nspace.length 0) @nspace undefined)
)
}}
@isHrefExternal={{false}}
class='consul-datacenter-selector__item'
data-test-dc-item
>
<span class='consul-datacenter-selector__dc-name'>
{{item.Name}}
{{#if (or item.Local item.Primary)}}
<span class='consul-datacenter-selector__badges'>
{{#if item.Primary}}
<Hds::Badge @text='Primary' />
{{/if}}
{{#if item.Local}}
<Hds::Badge @text='Local' />
{{/if}}
</span>
{{/if}}
</span>
</Dropdown.Checkmark>
</NavSelector>
{{else}}
<div class='dc-name' data-test-datacenter-single>
{{@dcs.firstObject.Name}}
{{#let (env 'CONSUL_HCP_MANAGED_RUNTIME') as |managedRuntime|}}
{{#if managedRuntime}}
<span>{{capitalize managedRuntime}}</span>
{{/if}}
{{/let}}
</div>
<SNL.Item class='consul-side-nav__datacenter' data-test-datacenter-single>
<FlightIcon
@name='server-cluster'
@color='var(--token-form-control-disabled-foreground-color)'
/>
<Hds::Text::Display @size='200' @color='disabled'>{{@dc.Name}}</Hds::Text::Display>
</SNL.Item>
{{/if}}
</li>
{{/let}}

View File

@ -0,0 +1,22 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
export default class DatacenterSelectorComponent extends Component {
@tracked search = '';
get filteredItems() {
const lowerCaseSearch = this.search.toLowerCase();
return this.args.dcs.filter((dc) => dc.Name.toLowerCase().includes(lowerCaseSearch));
}
@action
onSearchInput(e) {
this.search = e.target.value;
}
}

View File

@ -3,6 +3,6 @@
SPDX-License-Identifier: BUSL-1.1
}}
<li>
<a href={{href-to 'docs'}} target="_blank">Eng Docs</a>
</li>
{{#let @dropdown as |DD|}}
<DD.Interactive @href={{href-to "docs"}} @isHrefExternal={{true}} @text={{t "components.hashicorp-consul.side-nav.support-menu.eng-docs" }} />
{{/let}}

View File

@ -15,20 +15,21 @@
<Hds::Toast
@color={{if (eq status 'error') 'critical' status}}
data-notification
as |T|>
as |T|
>
<T.Title>{{capitalize status}}!</T.Title>
<T.Description>
{{#if (eq type 'logout')}}
{{#if (eq status 'success')}}
You are now logged out.
{{t "components.hashicorp-consul.notifications.logged-out"}}
{{else}}
There was an error logging out.
{{t "components.hashicorp-consul.notifications.logged-out-error"}}
{{/if}}
{{else if (eq type 'authorize')}}
{{#if (eq status 'success')}}
You are now logged in.
{{t "components.hashicorp-consul.notifications.logged-in"}}
{{else}}
There was an error, please check your SecretID/Token
{{t "components.hashicorp-consul.notifications.logged-in-error"}}
{{/if}}
{{else}}
{{#if (or (eq type 'use') (eq flash.model 'token'))}}
@ -71,137 +72,162 @@
</:notifications>
<:home-nav>
<a class='w-8 h-8' href={{href-to 'index' params=(hash peer=undefined)}}>
<FlightIcon @size='24' @name='consul-color' @stretched={{true}} />
</a>
</:home-nav>
<:side-nav>
<Hds::SideNav @isResponsive={{false}} class='consul-side-nav' data-test-navigation>
<:header>
<Hds::SideNav::Header>
<:logo>
<Hds::SideNav::Header::HomeLink
@icon='consul-color'
@ariaLabel='Consul'
@route='index'
@query={{hash peer=undefined}}
/>
</:logo>
<:actions>
<Hds::Dropdown class='hds-side-nav__dropdown' @listPosition='bottom-left' as |dd|>
<dd.ToggleIcon @icon='help' @text='Help & Support menu' />
<Debug::Navigation @dropdown={{dd}} />
<dd.Interactive
@href={{env 'CONSUL_DOCS_URL'}}
@isHrefExternal={{true}}
@text={{t "components.hashicorp-consul.side-nav.support-menu.docs"}}
/>
<dd.Interactive
@href={{concat (env 'CONSUL_DOCS_LEARN_URL') '/consul'}}
@isHrefExternal={{true}}
@text={{t "components.hashicorp-consul.side-nav.support-menu.tutorials"}}
/>
<dd.Interactive
@href={{env 'CONSUL_REPO_ISSUES_URL'}}
@isHrefExternal={{true}}
@text={{t "components.hashicorp-consul.side-nav.support-menu.feedback"}}
/>
</Hds::Dropdown>
<:main-nav>
<Consul::Hcp::Home />
<ul>
<Consul::Datacenter::Selector
@dc={{@dc}}
@partition={{@partition}}
@nspace={{@nspace}}
@dcs={{@dcs}}
/>
<Consul::Partition::Selector
@dc={{@dc}}
@partition={{@partition}}
@nspace={{@nspace}}
@partitions={{this.partitions}}
@onchange={{action (mut this.partitions) value='data'}}
/>
<Consul::Nspace::Selector
@dc={{@dc}}
@partition={{@partition}}
@nspace={{@nspace}}
@nspaces={{this.nspaces}}
@onchange={{action (mut this.nspaces) value='data'}}
/>
{{#if (can 'access overview')}}
<li
data-test-main-nav-overview
class={{class-map (array 'is-active' (is-href 'dc.show' @dc.Name))}}
<Consul::Token::Selector
@dc={{@dc}}
@partition={{@partition}}
@nspace={{@nspace}}
@onchange={{@onchange}}
as |selector|
>
<Ref @target={{this}} @name='tokenSelector' @value={{selector}} />
</Consul::Token::Selector>
</:actions>
</Hds::SideNav::Header>
</:header>
<:body>
<Hds::SideNav::List
class='hds-side-nav-hide-when-minimized consul-side-nav__selector-group'
as |SNL|
>
<Action @href={{href-to 'dc.show' @dc.Name params=(hash peer=undefined)}}>
Overview
</Action>
</li>
{{/if}}
{{#if (can 'read services')}}
<li data-test-main-nav-services class={{if (is-href 'dc.services' @dc.Name) 'is-active'}}>
<a href={{href-to 'dc.services' @dc.Name params=(hash peer=undefined)}}>Services</a>
</li>
{{/if}}
{{#if (can 'read nodes')}}
<li data-test-main-nav-nodes class={{if (is-href 'dc.nodes' @dc.Name) 'is-active'}}>
<a href={{href-to 'dc.nodes' @dc.Name params=(hash peer=undefined)}}>Nodes</a>
</li>
{{/if}}
{{#if (can 'read kv')}}
<li data-test-main-nav-kvs class={{if (is-href 'dc.kv' @dc.Name) 'is-active'}}>
<a href={{href-to 'dc.kv' @dc.Name params=(hash peer=undefined)}}>Key/Value</a>
</li>
{{/if}}
{{#if (can 'read intentions')}}
<li
data-test-main-nav-intentions
class={{if (is-href 'dc.intentions' @dc.Name) 'is-active'}}
>
<a href={{href-to 'dc.intentions' @dc.Name params=(hash peer=undefined)}}>Intentions</a>
</li>
{{/if}}
<Consul::Acl::Selector @dc={{@dc}} @partition={{@partition}} @nspace={{@nspace}} />
<Consul::Peer::Selector @dc={{@dc}} @partition={{@partition}} @nspace={{@nspace}} />
</ul>
</:main-nav>
<Consul::Hcp::Home @list={{SNL}} />
<Consul::Datacenter::Selector
@list={{SNL}}
@dc={{@dc}}
@partition={{@partition}}
@nspace={{@nspace}}
@dcs={{@dcs}}
/>
<:complementary-nav>
<ul>
<Debug::Navigation />
<li data-test-main-nav-help>
<DisclosureMenu as |disclosure|>
<disclosure.Action {{on 'click' disclosure.toggle}}>
Help
</disclosure.Action>
<disclosure.Menu as |panel|>
<panel.Menu as |menu|>
<menu.Separator>
Consul v{{env 'CONSUL_VERSION'}}
</menu.Separator>
<menu.Item class='docs-link'>
<menu.Action @href={{env 'CONSUL_DOCS_URL'}} @external={{true}}>
Documentation
</menu.Action>
</menu.Item>
<menu.Item class='learn-link'>
<menu.Action
@href={{concat (env 'CONSUL_DOCS_LEARN_URL') '/consul'}}
@external={{true}}
>
HashiCorp Learn
</menu.Action>
</menu.Item>
<menu.Separator />
<menu.Item class='feedback-link'>
<menu.Action @href={{env 'CONSUL_REPO_ISSUES_URL'}} @external={{true}}>
Provide Feedback
</menu.Action>
</menu.Item>
</panel.Menu>
</disclosure.Menu>
</DisclosureMenu>
</li>
<li data-test-main-nav-settings class={{if (is-href 'settings') 'is-active'}}>
<a href={{href-to 'settings' params=(hash nspace=undefined partition=undefined)}}>
Settings
</a>
</li>
<Consul::Token::Selector
@dc={{@dc}}
@partition={{@partition}}
@nspace={{@nspace}}
@onchange={{@onchange}}
as |selector|
>
<Ref @target={{this}} @name='tokenSelector' @value={{selector}} />
</Consul::Token::Selector>
</ul>
</:complementary-nav>
<Consul::Partition::Selector
@dc={{@dc}}
@partition={{@partition}}
@nspace={{@nspace}}
@partitions={{this.partitions}}
@list={{SNL}}
@onchange={{action (mut this.partitions) value='data'}}
/>
<Consul::Nspace::Selector
@list={{SNL}}
@dc={{@dc}}
@partition={{@partition}}
@nspace={{@nspace}}
@nspaces={{this.nspaces}}
@onchange={{action (mut this.nspaces) value='data'}}
/>
</Hds::SideNav::List>
<Hds::SideNav::List class='hds-side-nav-hide-when-minimized' as |SNL|>
{{#if (can 'access overview')}}
<SNL.Link
@text={{t "components.hashicorp-consul.side-nav.overview"}}
@route='dc.show'
@models={{array @dc.Name}}
@query={{hash peer=undefined}}
@isActive={{is-href 'dc.show' @dc.Name}}
data-test-main-nav-overview
/>
{{/if}}
{{#if (can 'read services')}}
<SNL.Link
@text={{t "components.hashicorp-consul.side-nav.services"}}
@href={{href-to 'dc.services' @dc.Name params=(hash peer=undefined)}}
@isHrefExternal={{false}}
@isActive={{is-href 'dc.services' @dc.Name}}
data-test-main-nav-services
/>
{{/if}}
{{#if (can 'read nodes')}}
<SNL.Link
@text={{t "components.hashicorp-consul.side-nav.nodes"}}
@href={{href-to 'dc.nodes' @dc.Name params=(hash peer=undefined)}}
@isHrefExternal={{false}}
@isActive={{is-href 'dc.nodes' @dc.Name}}
data-test-main-nav-nodes
/>
{{/if}}
{{#if (can 'read kv')}}
<SNL.Link
@text={{t "components.hashicorp-consul.side-nav.kv"}}
@href={{href-to 'dc.kv' @dc.Name params=(hash peer=undefined)}}
@isHrefExternal={{false}}
@isActive={{is-href 'dc.kv' @dc.Name}}
data-test-main-nav-kv
/>
{{/if}}
{{#if (can 'read intentions')}}
<SNL.Link
@text={{t "components.hashicorp-consul.side-nav.intentions"}}
@href={{href-to 'dc.intentions' @dc.Name params=(hash peer=undefined)}}
@isHrefExternal={{false}}
@isActive={{is-href 'dc.intentions' @dc.Name}}
data-test-main-nav-intentions
/>
{{/if}}
<Consul::Acl::Selector
@dc={{@dc}}
@partition={{@partition}}
@nspace={{@nspace}}
@list={{SNL}}
/>
<Consul::Peer::Selector
@dc={{@dc}}
@partition={{@partition}}
@nspace={{@nspace}}
@list={{SNL}}
/>
</Hds::SideNav::List>
</:body>
<:footer>
<footer role='contentinfo' data-test-footer>
<Hds::Text::Display
class='hds-side-nav-hide-when-minimized'
@size='100'
@color='disabled'
>
{{t "components.hashicorp-consul.side-nav.footer" version=(env 'CONSUL_VERSION')}}
</Hds::Text::Display>
{{{concat '<!-- ' (env 'CONSUL_GIT_SHA') '-->'}}}
</footer>
</:footer>
</Hds::SideNav>
</:side-nav>
<:main>
{{yield
(hash login=(if this.tokenSelector this.tokenSelector (hash open=undefined close=undefined)))
}}
</:main>
<:content-info>
<p>
Consul v{{env 'CONSUL_VERSION'}}
</p>
{{{concat '<!-- ' (env 'CONSUL_GIT_SHA') '-->'}}}
</:content-info>
</App>
</App>

View File

@ -4,71 +4,71 @@
*/
%hashicorp-consul {
nav .dcs {
@extend %main-nav-vertical-hoisted;
left: 100px;
.consul-side-nav {
li.consul-disabled-nav {
width: 100%;
min-height: var(--token-side-nav-body-list-item-height);
padding: var(--token-side-nav-body-list-item-padding-vertical)
var(--token-side-nav-body-list-item-padding-horizontal);
color: var(--token-color-foreground-disabled);
}
.dcs-message {
padding: 8px 12px;
border-bottom: 1px solid var(--token-color-foreground-disabled);
max-width: fit-content;
background-color: var(--token-color-hashicorp-brand);
color: var(--token-color-palette-neutral-300);
li.consul-side-nav__selector {
.consul-side-nav__selector-toggle {
min-width: 15.5rem;
&:disabled {
color: var(--token-color-foreground-disabled);
border-color: var(--token-color-border-primary);
&:hover {
background-color: transparent;
}
}
}
.hds-dropdown__content {
min-width: 15.5rem;
max-height: 500px;
}
}
.hds-side-nav__wrapper-body {
overflow-y: unset;
overflow-x: unset;
}
li.consul-side-nav__datacenter {
display: flex;
gap: 0.5rem;
align-items: center;
padding-left: 0.5rem;
}
.consul-side-nav__selector-group {
margin-bottom: 1.5rem;
}
.consul-datacenter-selector__dc-name {
display: flex;
align-items: center;
gap: 0.5rem;
.consul-datacenter-selector__badges {
display: flex;
gap: 0.25rem;
}
}
.consul-side-nav__selector-title {
margin-top: 0.5rem;
}
.consul-side-nav__selector-description {
padding-top: 0.5rem;
}
}
nav .dcs li.is-primary span,
nav .dcs li.is-local span {
@extend %menu-panel-badge;
}
nav .dcs .dc-name {
color: var(--token-color-foreground-faint);
padding: 3.25px 0px;
font-weight: var(--token-typography-font-weight-semibold);
}
nav .dcs .dc-name span {
@extend %pill-200;
margin-left: 1rem;
background-color: var(--token-color-palette-neutral-300);
color: var(--token-color-hashicorp-brand);
}
nav li.partitions,
nav li.nspaces {
@extend %main-nav-vertical-popover-menu;
}
nav li.dcs [aria-expanded] ~ * {
min-width: 250px;
}
nav li.dcs [aria-expanded] ~ * {
max-height: 560px;
--paged-row-height: 43px;
}
nav li.partitions [aria-expanded] ~ *,
nav li.nspaces [aria-expanded] ~ * {
max-height: 360px;
--paged-row-height: 43px;
}
[role='banner'] a svg {
fill: var(--token-color-consul-brand);
}
.docs-link a::after {
@extend %with-docs-mask, %as-pseudo;
}
.learn-link a::after {
@extend %with-learn-mask, %as-pseudo;
}
.feedback-link a::after {
@extend %with-logo-github-monochrome-mask, %as-pseudo;
}
.acls-separator span {
@extend %led-icon;
color: var(--token-color-foreground-critical);
display: inline-block;
position: relative;
top: 2px;
margin-left: 2px;
}
}
.hashicorp-consul {
@extend %hashicorp-consul;
}

View File

@ -42,16 +42,19 @@ export default (collection, clickable, attribute, is, authForm, emptyState) => (
status: attribute('data-test-status', '[data-test-status]'),
},
};
page.navigation.login = clickable('[data-test-main-nav-auth] button');
page.navigation.authMenu = clickable('[data-test-auth-menu]');
page.navigation.login = clickable('[data-test-auth-menu-login]');
page.navigation.dc = clickable('[data-test-datacenter-menu] button');
page.navigation.nspace = clickable('[data-test-nspace-menu] button');
page.navigation.manageNspaces = clickable('[data-test-main-nav-nspaces] a');
page.navigation.manageNspaces = clickable(
'[data-test-nspace-menu] [data-test-nav-selector-footer-link]'
);
page.navigation.manageNspacesIsVisible = is(
':checked',
'[data-test-nspace-menu] > input[type="checkbox"]'
);
page.navigation.dcs = collection('[data-test-datacenter-menu] [data-test-dc-item]', {
name: clickable('a'),
name: clickable(),
});
return page;
};

View File

@ -1,7 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
@import './skin.scss';
@import './layout.scss';

View File

@ -1,32 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
%main-header-horizontal {
display: flex;
position: fixed;
z-index: 50;
left: 0;
padding: 0 25px;
width: calc(100% - 50px);
}
%main-header-horizontal,
%main-header-horizontal::before {
height: var(--chrome-height);
}
%main-header-horizontal {
align-items: center;
}
%main-header-horizontal::before {
content: '';
position: absolute;
z-index: -1;
left: 0;
width: 100vw;
}
%main-header-horizontal > a {
display: block;
line-height: 0;
font-size: 0;
}

View File

@ -1,8 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
%main-header-horizontal::before {
background-color: var(--token-color-hashicorp-brand);
}

View File

@ -1,36 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
@import './skin';
@import './layout';
/* things that should look like nav buttons */
%main-nav-horizontal > ul > li > a,
%main-nav-horizontal > ul > li > span,
%main-nav-horizontal > ul > li > button,
%main-nav-horizontal-popover-menu-trigger,
%main-nav-horizontal > ul > li > .popover-menu > label > button {
@extend %main-nav-horizontal-action;
}
%main-nav-horizontal .popover-menu [type='checkbox']:checked + label > *,
%main-nav-horizontal > ul > li.is-active > a,
%main-nav-horizontal > ul > li.is-active > button {
@extend %main-nav-horizontal-action-active;
}
/* Whilst we want spans to look the same as actions */
/* we don't want them to act the same */
%main-nav-horizontal-action:not(span):hover,
%main-nav-horizontal-action:not(span):focus {
@extend %main-nav-horizontal-action-intent;
}
%main-nav-horizontal > ul > li > span {
cursor: default;
}
/**/
/* menu-panels in the main navigation are treated slightly differently */
%main-nav-horizontal .disclosure-menu button + * {
@extend %main-nav-horizontal-menu-panel;
}

View File

@ -1,48 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
%main-nav-horizontal > ul,
%main-nav-horizontal-panel {
display: flex;
}
%main-nav-horizontal-toggle-button {
display: flex;
align-items: center;
height: 100%;
padding: 0 1rem;
padding-left: 5px;
}
%main-nav-horizontal-panel {
justify-content: space-between;
flex-grow: 1;
}
%main-nav-horizontal-menu-panel {
z-index: 400;
/* TODO: We should probably make menu-panel default to left hand side*/
top: 28px !important;
}
%main-nav-horizontal-action {
display: block;
padding: 5px 12px;
white-space: nowrap;
}
%main-nav-horizontal .popover-menu > label {
/* Usually there is no space between buttons which is */
/* fine as the button only highlights when its selected */
/* therefore no two siblings are highlighted at the same time */
/* which means you don't notice there is no space between the */
/* buttons. popover-menu triggers on the other hand can be */
/* at the same time as a sibling, therefore they need a little */
/* space between it and its sibling - this is a property of */
/* the main nav not the popover-menu */
padding-right: 5px;
}
%main-nav-horizontal .popover-menu > label > * {
/* less space as the chevron adds space */
padding-right: 4px !important;
}
%main-nav-horizontal .popover-menu > label > button::after {
top: 2px;
}

View File

@ -1,45 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
%main-nav-horizontal-action {
border-radius: var(--decor-radius-200);
cursor: pointer;
}
%main-nav-horizontal-action > a {
color: inherit;
}
%main-nav-horizontal-popover-menu-trigger::after {
--icon-name: icon-chevron-down;
content: '';
}
%main-nav-horizontal-popover-menu-trigger[aria-expanded='true']::after {
transform: scaleY(-100%);
}
%main-nav-horizontal-menu-panel,
%main-nav-horizontal-menu-panel > ul[role='menu'],
%main-nav-horizontal-menu-panel > ul[role='menu'] > li > [role='menuitem'] {
background-color: var(--token-color-hashicorp-brand);
color: var(--token-color-palette-neutral-300);
}
%main-nav-horizontal-menu-panel > ul[role='menu'] > li > [role='menuitem']:hover {
background-color: var(--token-color-palette-neutral-600);
}
%main-nav-horizontal-toggle {
display: none;
}
%main-nav-horizontal-toggle-button::before {
--icon-name: icon-menu;
--icon-color: var(--token-color-palette-neutral-300);
content: '';
cursor: pointer;
}
%main-nav-horizontal-action,
%main-nav-horizontal-action-intent,
%main-nav-horizontal-action-active {
color: var(--token-color-palette-neutral-300);
}

View File

@ -1,71 +0,0 @@
---
class: css
---
# MainNavVertical
Used for styles of vertically orientated main application menus/navigation.
Menu item active state is applied on `.is-active` `<li>` elements. Additionally you can use the following placeholders for setting certin states manually:
- `%menu-nav-vertical-action-active` The 'active' or currently selected state.
- `%menu-nav-vertical-action-intent` The highlighted state, usually for `:hover`
and `:focus`.
`%menu-nav-vertical-hoisted` will 'hoist' an `<li>` element to the top of the
containing block, the containing block defaults to the current viewport. If
you need to define a different ancestor for a containing block you can use
`transform` (see below).
```hbs preview-template
<div class="wrapper">
<nav class="main-nav-vertical in-viewport">
<ul>
<li role="separator">Title</li>
<li>
<a href="">One</a>
</li>
<li class="is-active">
<a href="">Two (is-active)</a>
</li>
<li class="with-intent">
<a href="">Three (with-intent)</a>
</li>
<li class="hoisted">
<a href="">Four (hoisted)</a>
</li>
<li role="separator">Title</li>
<li class="custom-active">
<a href="">One (custom-active)</a>
</li>
<li>
<a href="">Two</a>
</li>
<li>
<a href="">Three</a>
</li>
</ul>
</nav>
</div>
```
```css preview-template
.main-nav-vertical {
@extend %main-nav-vertical;
}
.main-nav-vertical li.hoisted {
@extend %main-nav-vertical-hoisted;
}
.main-nav-vertical .with-intent > * {
@extend %main-nav-vertical-action-intent;
}
.main-nav-vertical .custom-active > * {
@extend %main-nav-vertical-action-active;
}
.wrapper {
/* a transform is required to mark this element as the containing block */
/* for hoisting, otherwise the viewport is the containing block */
transform: translate(0, 0);
background-color: var(--token-color-foreground-faint);
padding-top: 64px;
}
```

View File

@ -1,34 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
#docfy-demo-preview-main-nav-vertical {
.main-nav-vertical {
@extend %main-nav-vertical;
}
.main-nav-vertical li.hoisted {
@extend %main-nav-vertical-hoisted;
}
.main-nav-vertical .with-intent > * {
@extend %main-nav-vertical-action-intent;
}
.main-nav-vertical .custom-active > * {
@extend %main-nav-vertical-action-active;
}
.wrapper {
/* a transform is required to mark this element as the containing block */
/* for hoisting, otherwise the viewport is the containing block */
transform: translate(0, 0);
background-color: var(--token-color-foreground-faint);
padding-top: 64px;
}
// TODO: Reduce the need for these debug overrides
.main-nav-vertical {
position: static;
height: auto;
}
.main-nav-vertical ul {
margin-bottom: 0 !important;
}
}

View File

@ -1,45 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
@import './skin';
@import './layout';
/* things that should look like nav buttons */
/* items are single things that look like button */
/* but aren't clickable */
%main-nav-vertical > ul > li[aria-label] {
@extend %main-nav-vertical-item;
}
/**/
/* actual clickable button-y things plus states */
%main-nav-vertical a {
@extend %main-nav-vertical-action;
}
%main-nav-vertical > ul > li.is-active > a {
@extend %main-nav-vertical-action-active;
}
%main-nav-vertical-action-active:hover:not(:active),
%main-nav-vertical-action-active:focus:not(:active) {
@extend %main-nav-vertical-action-active-intent;
}
%main-nav-vertical-action:hover,
%main-nav-vertical-action:focus {
@extend %main-nav-vertical-action-intent;
}
%main-nav-vertical > ul > li > label {
@extend %main-nav-vertical-action;
}
/* menu-panels in the main navigation are treated slightly differently */
%main-nav-vertical-popover-menu .disclosure-menu button + * {
@extend %main-nav-vertical-menu-panel;
}
/**/
%main-nav-vertical-popover-menu .disclosure-menu > button {
@extend %main-nav-vertical-popover-menu-trigger;
@extend %internal-button;
}

View File

@ -1,68 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
%main-nav-vertical {
position: absolute;
left: 0;
top: var(--chrome-height, 47px);
width: var(--chrome-width, 280px);
height: calc(100vh - var(--chrome-height, 47px) - 35px);
padding-top: 35px;
overflow: auto;
}
// disable tabbing when not visible
%main-nav-vertical:not(.in-viewport) {
visibility: hidden;
}
%main-nav-vertical li.partition,
%main-nav-vertical li.partitions,
%main-nav-vertical li.nspaces {
margin-bottom: 25px;
padding: 0 26px;
}
%main-nav-vertical li.dcs {
padding: 0 18px;
}
// TODO: We no longer have the rule that menu-panel buttons only contain two
// items, left and right aligned. We should remove this and look to use
// align-self for anything that needs right aligning instead.
%main-nav-vertical [role='menuitem'] {
justify-content: flex-start !important;
}
%main-nav-vertical [role='menuitem'] span {
margin-left: 0.5rem;
}
%main-nav-vertical-action,
%main-nav-vertical li:not([role='separator']) > span,
%main-nav-vertical [role='separator'] {
display: block;
padding: 7px 25px;
}
%main-nav-vertical > ul > [role='separator'] {
margin-top: 0.7rem;
padding-bottom: 0;
}
%main-nav-vertical-popover-menu .disclosure {
position: relative;
}
%main-nav-vertical-popover-menu-trigger {
width: 100%;
text-align: left;
padding: 10px;
}
%main-nav-vertical-popover-menu-trigger::after {
float: right;
}
%main-nav-vertical-menu-panel {
position: absolute;
z-index: 1;
width: calc(100% - 2px);
}
%main-nav-vertical-hoisted {
visibility: visible;
position: fixed;
z-index: 10;
}

View File

@ -1,114 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
%main-nav-vertical-action {
@extend %body-200-medium;
cursor: pointer;
border-right: var(--decor-border-400);
border-color: transparent;
}
%main-nav-vertical-action > a {
color: inherit;
font-size: inherit;
}
%main-nav-vertical [role='separator'] {
@extend %body-100-medium;
text-transform: uppercase;
}
%main-nav-vertical-action-intent {
text-decoration: underline;
}
%main-nav-vertical-action-active-intent {
text-decoration: none;
}
%main-nav-vertical {
background-color: var(--token-color-foreground-strong);
color: var(--token-color-foreground-faint);
}
%main-nav-vertical li:not([role='separator']) > span {
color: var(--token-color-palette-neutral-300);
}
%main-nav-vertical [role='separator'],
%main-nav-vertical-hoisted [role='separator'] {
color: var(--token-color-palette-neutral-400);
background-color: var(--token-color-foreground-strong);
}
%main-nav-vertical-action {
color: var(--token-color-palette-neutral-300);
}
%main-nav-vertical-item,
%main-nav-vertical-action-intent,
%main-nav-vertical-action-active {
color: var(--token-color-palette-neutral-0);
}
%main-nav-vertical-action-active {
background-color: var(--token-color-palette-neutral-500);
border-color: var(--token-color-palette-neutral-0);
}
%main-nav-vertical [aria-label]::before {
color: var(--token-color-palette-neutral-400);
content: attr(aria-label);
display: block;
margin-top: -0.5rem;
margin-bottom: 0.5rem;
}
%main-nav-vertical-popover-menu-trigger {
border: var(--decor-border-100);
border-color: var(--token-color-foreground-faint);
border-radius: var(--decor-radius-100);
font-weight: inherit;
background-color: var(--token-color-foreground-strong);
color: var(--token-color-palette-neutral-200);
}
%main-nav-vertical-popover-menu-trigger:hover,
%main-nav-vertical-popover-menu-trigger:focus {
color: var(--token-color-palette-neutral-300);
background-color: var(--token-color-foreground-strong);
}
%main-nav-vertical ul[role='menu'] li a[role='menuitem'] {
color: var(--token-color-palette-neutral-300);
background-color: var(--token-color-foreground-strong);
}
%main-nav-vertical ul[role='menu']li a[role='menuitem']:hover {
background-color: var(--token-color-palette-neutral-600);
}
%main-nav-vertical-popover-menu-trigger[aria-expanded='true'] {
border-bottom-left-radius: var(--decor-radius-000);
border-bottom-right-radius: var(--decor-radius-000);
}
%main-nav-horizontal %panel,
%main-nav-horizontal %panel-separator,
%main-nav-vertical %panel,
%main-nav-vertical %panel-separator {
border-color: var(--token-color-foreground-faint);
}
%main-nav-vertical-popover-menu-trigger::after {
@extend %with-chevron-down-mask, %as-pseudo;
width: 16px;
height: 16px;
position: relative;
}
%main-nav-vertical-popover-menu-trigger[aria-expanded='true']::after {
@extend %with-chevron-up-mask;
}
%main-nav-vertical-menu-panel {
border-top-left-radius: var(--decor-radius-000);
border-top-right-radius: var(--decor-radius-000);
border-top: var(--decor-border-000);
color: var(--token-color-palette-neutral-300);
background-color: var(--token-color-foreground-strong);
}
%main-nav-vertical-hoisted ul[role='menu'] {
background-color: var(--token-color-hashicorp-brand);
}

View File

@ -0,0 +1,58 @@
{{!
Copyright (c) HashiCorp, Inc.
SPDX-License-Identifier: BUSL-1.1
}}
{{#let @list as |SNL|}}
<SNL.Item class='consul-side-nav__selector'>
<Hds::Dropdown
@listPosition='bottom-left'
@width='15.5rem'
class='hds-side-nav__dropdown'
@isInline={{true}}
...attributes
as |DD|
>
<DD.ToggleButton
class='consul-side-nav__selector-toggle'
@icon={{@icon}}
@text={{get @item @key}}
disabled={{eq @disabled true}}
/>
<DD.Header @hasDivider={{true}}>
{{#if @description}}
<div class='consul-side-nav__selector-description'>
<Hds::Text::Body @size='100' @color='faint'>{{@description}}</Hds::Text::Body>
</div>
{{/if}}
<Hds::Form::TextInput::Base
@type='search'
@value={{this.search}}
placeholder={{@placeholder}}
aria-label={{@placeholder}}
{{on 'input' this.onSearchInput}}
/>
</DD.Header>
{{#if (eq this.filteredItems.length 0)}}
<DD.Description @text='No results' />
{{else}}
{{#each this.filteredItems as |item|}}
{{yield DD item}}
{{/each}}
{{/if}}
{{#if @footerLink}}
<DD.Footer @hasDivider={{true}}>
<Hds::Link::Standalone
@href={{@footerLink}}
@isHrefExternal={{false}}
@text={{@footerLinkText}}
@iconPosition='trailing'
@icon='arrow-right'
@color='secondary'
data-test-nav-selector-footer-link
/>
</DD.Footer>
{{/if}}
</Hds::Dropdown>
</SNL.Item>
{{/let}}

View File

@ -0,0 +1,29 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
export default class NavSelectorComponent extends Component {
@tracked search = '';
get filteredItems() {
const lowerCaseSearch = this.search.toLowerCase();
if (lowerCaseSearch) {
return this.args.items.filter((item) =>
item[this.args.key].toLowerCase().includes(lowerCaseSearch)
);
} else {
return this.args.items;
}
}
@action
onSearchInput(e) {
this.search = e.target.value;
}
}

View File

@ -1,7 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
@import './skin';
@import './layout';

View File

@ -1,26 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
%skip-links {
display: flex;
flex-direction: column;
position: absolute;
z-index: 10;
left: 50%;
padding: 20px;
top: -100px;
transform: translateX(-50%);
}
%skip-links div,
%skip-links button,
%skip-links a {
display: block;
width: 100%;
text-align: center;
box-sizing: border-box;
}
%skip-links:focus-within {
top: 0px;
}

View File

@ -1,14 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
%skip-links {
outline: 1px solid var(--token-color-surface-primary);
color: var(--token-color-surface-primary);
background-color: var(--token-color-foreground-action);
}
%skip-links button,
%skip-links a {
color: inherit;
}

View File

@ -75,8 +75,7 @@ export default CollectionComponent.extend(Slotted, {
if ($appContent) {
const border = 1;
const rect = $tbody.getBoundingClientRect();
const $footer = this.dom.element('footer[role="contentinfo"]');
const space = rect.top + $footer.clientHeight + border;
const space = rect.top + border;
const height = e.target.innerHeight - space;
this.set('maxHeight', Math.max(0, height));
// TODO: The row height should auto calculate properly from the CSS

View File

@ -254,6 +254,10 @@ export default class FSMWithOptionalLocation {
* performs an ember transition/refresh and browser location update using that
*/
transitionTo(url) {
if (typeof this.router === 'undefined') {
this.router = this.container.lookup('router:main');
}
if (this.router.currentRouteName.startsWith('docs') && url.startsWith('console://')) {
console.info(`location.transitionTo: ${url.substr(10)}`);
return true;

View File

@ -25,7 +25,8 @@
/* more semantically (for our project) named icons */
@import 'icons';
/* global control of themeable components */
@import 'themes';
@import './base/color/index';
/* debug only, this is empty during a production build */
/* but uses the contents of ./debug.scss during dev */
@import '_debug';

View File

@ -3,5 +3,5 @@
* SPDX-License-Identifier: BUSL-1.1
*/
@import './ui/index';
@import './semantic-variables';
@import './ui/frame-placeholders.scss';

View File

@ -1,6 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
@import './frame-placeholders';

View File

@ -8,7 +8,6 @@
@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';
@ -53,12 +52,8 @@
@import 'consul-ui/components/route/title';
@import 'consul-ui/components/app-view';
@import 'consul-ui/components/brand-loader';
@import 'consul-ui/components/skip-links';
@import 'consul-ui/components/app';
/* app chrome */
@import 'consul-ui/components/main-header-horizontal';
@import 'consul-ui/components/main-nav-horizontal';
@import 'consul-ui/components/main-nav-vertical';
@import 'consul-ui/components/hashicorp-consul';
/**/
@import 'consul-ui/components/menu-panel';
@ -113,5 +108,4 @@
@import 'consul-ui/components/consul/node/peer-info';
@import 'consul-ui/components/consul/peer/info';
@import 'consul-ui/components/consul/peer/form';
@import 'consul-ui/components/consul/hcp/home';
@import 'consul-ui/components/consul/node/agentless-notice';

View File

@ -6,7 +6,6 @@
@import 'prism-coldark-dark';
// temporary component debugging setup
@import 'consul-ui/components/main-nav-vertical/debug';
@import 'consul-ui/components/badge/debug';
@import 'consul-ui/components/panel/debug';
@import 'consul-ui/components/tile/debug';

View File

@ -103,9 +103,10 @@ html:not(.has-partitions) [class*='partition-'] {
@extend %viewport-container;
display: flex;
min-height: 100vh;
flex-direction: column;
}
main {
padding: 0 48px;
position: relative;
flex: 1;
}

View File

@ -6,7 +6,7 @@
// workaround bulma's sweeping box-sizing
%viewport-container {
box-sizing: content-box;
box-sizing: border-box;
}
%modal-dialog > *,
%content-container > * {
@ -15,10 +15,6 @@
%content-container-restricted {
max-width: 1260px;
}
%viewport-container {
padding-left: 48px;
padding-right: 48px;
}
fieldset [role='group'] {
display: flex;

View File

@ -1,16 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
@import './base/color/ui/index';
%main-nav-horizontal .dangerous button:hover,
%main-nav-horizontal .dangerous button:focus {
color: var(--token-color-surface-primary) !important;
}
%main-nav-vertical .menu-panel a:hover,
%main-nav-vertical .menu-panel a:focus {
background-color: var(--token-color-foreground-action);
}

View File

@ -15,9 +15,6 @@ fieldset > header,
%form-element > span {
@extend %display-100-semibold;
}
%main-nav-horizontal-action {
@extend %body-200-medium;
}
%definition-table dt {
line-height: var(--token-typography-body-300-line-height);
}
@ -45,7 +42,6 @@ fieldset > header,
%empty-state-anchor,
%form-element-label,
%stats-card header a span,
%footer,
%app-view h1 span.kind-proxy {
@extend %body-100-regular;
}

View File

@ -5,18 +5,18 @@
{{page-title 'Engineering Docs - Consul' separator=' - '}}
{{document-attrs class="is-debug" }}
{{document-attrs class='is-debug'}}
{{! Tell CSS what we have enabled }}
{{#if (can "use acls")}}
{{document-attrs class="has-acls" }}
{{#if (can 'use acls')}}
{{document-attrs class='has-acls'}}
{{/if}}
{{#if (can "use nspaces")}}
{{document-attrs class="has-nspaces" }}
{{#if (can 'use nspaces')}}
{{document-attrs class='has-nspaces'}}
{{/if}}
{{#if (can "use partitions")}}
{{document-attrs class="has-partitions" }}
{{#if (can 'use partitions')}}
{{document-attrs class='has-partitions'}}
{{/if}}
<App class="docs" id="wrapper">
<App class='docs' id='wrapper'>
<:notifications as |app|>
{{#each flashMessages.queue as |flash|}}
@ -31,71 +31,71 @@
{{/each}}
</:notifications>
<:main-nav>
<:side-nav>
<Hds::SideNav @isResponsive={{true}} class='consul-side-nav'>
<:header>
<Hds::SideNav::Header>
<:logo>
<Hds::SideNav::Header::HomeLink
@icon='consul-color'
@ariaLabel='Consul'
@route='index'
@query={{hash peer=undefined}}
/>
</:logo>
</Hds::SideNav::Header>
</:header>
<:body>
<DocfyOutput as |node|>
<Hds::SideNav::List class='hds-side-nav-hide-when-minimized' as |SNL|>
<SNL.Title>Docs</SNL.Title>
<DocfyOutput as |node|>
<ul>
{{#each node.children as |child|}}
{{#each child.pages as |child|}}
<SNL.Link
@href={{concat '/ui' child.url}}
@isHrefExternal={{false}}
@isActive={{is-href (to-route child.url)}}
@text={{classify child.title}}
/>
{{/each}}
{{!hardcode in docs first}}
<li role="separator">Docs</li>
{{#each node.children as |child|}}
{{#each child.pages as |child|}}
<li
class={{if (is-href (to-route child.url)) 'is-active'}}
>
<DocfyLink @to={{child.url}}>
{{classify child.title}}
</DocfyLink>
</li>
{{/each}}
{{!hardcode in styles next}}
{{#let (find-by 'label' 'styles' child.children) as |section|}}
<SNL.Title>{{section.label}}</SNL.Title>
{{#each (flatten-property section 'pages') as |child|}}
<SNL.Link
@href={{concat '/ui' child.url}}
@text={{classify child.title}}
@isHrefExternal={{false}}
@isActive={{is-href (to-route child.url)}}
/>
{{/each}}
{{/let}}
{{!hardcode in styles next}}
{{#let (find-by 'label' 'styles' child.children) as |section|}}
<li role="separator">{{section.label}}</li>
{{#each (flatten-property section 'pages') as |child|}}
<li
class={{concat
(slugify section.label) ' '
(if (is-href (to-route child.url)) 'is-active')
}}
>
<DocfyLink @to={{child.url}}>
{{classify child.title}}
</DocfyLink>
</li>
{{/each}}
{{/let}}
{{!print out the rest}}
{{#each child.children as |section|}}
{{#if (not-eq section.label 'styles')}}
<li role="separator">{{section.label}}</li>
{{#each (flatten-property section 'pages') as |child|}}
<li
class={{concat
(slugify section.label) ' '
(if (eq child.frontmatter.class 'ember') 'ember-component') ' '
(if (eq child.frontmatter.class 'css') 'css-component') ' '
(if (is-href (to-route child.url)) 'is-active')
}}
>
<DocfyLink @to={{child.url}}>
{{classify child.title}}
</DocfyLink>
</li>
{{/each}}
{{/if}}
{{/each}}
{{/each}}
</ul>
</DocfyOutput>
</:main-nav>
{{!print out the rest}}
{{#each child.children as |section|}}
{{#if (not-eq section.label 'styles')}}
<SNL.Title>{{section.label}}</SNL.Title>
{{#each (flatten-property section 'pages') as |child|}}
<SNL.Link
@href={{concat '/ui' child.url}}
@text={{classify child.title}}
@isHrefExternal={{false}}
@isActive={{is-href (to-route child.url)}}
/>
{{/each}}
{{/if}}
{{/each}}
{{/each}}
</Hds::SideNav::List>
</DocfyOutput>
</:body>
</Hds::SideNav>
</:side-nav>
<:main>
<DocfyOutput @fromCurrentURL={{true}} as |page|>
{{outlet}}
</DocfyOutput>
</:main>
</App>
</App>

View File

@ -69,10 +69,10 @@
"@ember/test-helpers": "^2.6.0",
"@glimmer/component": "^1.0.4",
"@glimmer/tracking": "^1.0.4",
"@hashicorp/design-system-components": "^2.14.1",
"@hashicorp/design-system-components": "^3.0.2",
"@hashicorp/design-system-tokens": "^1.9.0",
"@hashicorp/ember-cli-api-double": "^4.0.0",
"@hashicorp/ember-flight-icons": "^3.1.3",
"@hashicorp/ember-flight-icons": "^4.0.1",
"@html-next/vertical-collection": "^4.0.0",
"@lit/reactive-element": "^1.2.1",
"@xstate/fsm": "^1.4.0",
@ -134,7 +134,6 @@
"ember-decorators": "^6.1.1",
"ember-exam": "^6.1.0",
"ember-export-application-global": "^2.0.1",
"ember-in-viewport": "^4.0.0",
"ember-inflector": "^4.0.1",
"ember-intl": "^5.7.0",
"ember-load-initializers": "^2.1.2",
@ -217,6 +216,7 @@
"node": "18"
},
"dependencies": {
"doctoc": "^2.0.0"
"doctoc": "^2.0.0",
"ember-element-helper": "0.6.1"
}
}

View File

@ -8,6 +8,7 @@ Feature: login
dc: dc-1
---
Then the url should be /dc-1/acls/tokens
And I click authMenu on the navigation
And I click login on the navigation
And I fill in the auth form with yaml
---
@ -39,6 +40,7 @@ Feature: login
state: state-123456789/abcdefghijklmnopqrstuvwxyz
code: code-abcdefghijklmnopqrstuvwxyz/123456789
---
And I click authMenu on the navigation
And I click login on the navigation
And I click "[data-test-tab=tab_sso] button"
Then the "[name='partition']" input should have the value "default"

View File

@ -24,6 +24,7 @@ Feature: token-header
dc: dc1
---
Then the url should be /dc1/acls/tokens
And I click authMenu on the navigation
And I click login on the navigation
And I fill in the auth form with yaml
---

View File

@ -1,29 +0,0 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
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-profile', 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`<AuthProfile />`);
assert.notStrictEqual(this.element.textContent.indexOf('AccessorID'), -1);
// Template block usage:
await render(hbs`
<AuthProfile></AuthProfile>
`);
assert.notStrictEqual(this.element.textContent.indexOf('AccessorID'), -1);
});
});

View File

@ -20,10 +20,14 @@ module('Integration | Component | consul datacenter selector', function (hooks)
this.set('dcs', dcs);
this.set('dc', dcs[0]);
await render(hbs`<Consul::Datacenter::Selector @dcs={{this.dcs}} @dc={{this.dc}} />`);
await render(hbs`
<Hds::SideNav::List as |SNL|>
<Consul::Datacenter::Selector @list={{SNL}} @dcs={{this.dcs}} @dc={{this.dc}} />
</Hds::SideNav::List>
`);
assert
.dom('[data-test-datacenter-disclosure-menu]')
.dom('[data-test-datacenter-menu]')
.doesNotExist('datacenter dropdown is not displayed in nav');
assert
@ -43,12 +47,16 @@ module('Integration | Component | consul datacenter selector', function (hooks)
this.set('dcs', dcs);
this.set('dc', dcs[0]);
await render(hbs`<Consul::Datacenter::Selector @dcs={{this.dcs}} @dc={{this.dc}} />`);
await render(hbs`
<Hds::SideNav::List as |SNL|>
<Consul::Datacenter::Selector @list={{SNL}} @dcs={{this.dcs}} @dc={{this.dc}} />
</Hds::SideNav::List>
`);
assert
.dom('[data-test-datacenter-single]')
.doesNotExist('we are displaying more than just the name of the first dc');
assert.dom('[data-test-datacenter-disclosure-menu]').exists('datacenter dropdown is displayed');
assert.dom('[data-test-datacenter-menu]').exists('datacenter dropdown is displayed');
});
});

View File

@ -70,6 +70,8 @@ acl:
management: Management
client: Client
token:
selector:
logged-in: "Logged in with ACL Token'<br><'b class=consul-side-nav__acl-logged-in'>'{token}'<'/b'>'"
search-bar:
kind:
name: Type

View File

@ -0,0 +1,47 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: BUSL-1.1
notifications:
logged-out: You are now logged out.
logged-out-error: There was an error logging out.
logged-in: You are now logged in.
logged-in-error: There was an error, please check your SecretID/Token
side-nav:
support-menu:
eng-docs: Eng docs
docs: Documentation
tutorials: Tutorials
feedback: Give feedback
user-menu:
settings: Settings
log-in: Log in
Log out: Log out
hcp: Back to HCP
datacenters:
title: Datacenter
placeholder: Search datacenters
description: WAN federated datacenters
partitions:
title: Admin partition
placeholder: Search partitions
footer: View all partitions
nspaces:
title: Namespace
placeholder: Search namespaces
footer: View all namespaces
overview: Overview
services: Services
nodes: Nodes
kv: Key/Value
intentions: Intentions
acls:
title: Access Controls
tooltip: ACLs are not currently enabled in this cluster
tokens: Tokens
policies: Policies
roles: Roles
auth-methods: Auth Methods
organization:
title: Organization
peers: Peers
footer: Consul v{version}

View File

@ -1311,6 +1311,14 @@
ember-cli-version-checker "^5.1.2"
semver "^7.3.5"
"@embroider/addon-shim@1.8.3":
version "1.8.3"
resolved "https://registry.yarnpkg.com/@embroider/addon-shim/-/addon-shim-1.8.3.tgz#2368510b8ce42d50d02cb3289c32e260dfa34bd9"
integrity sha512-7pyHwzT6ESXc3nZsB8rfnirLkUhQWdvj6CkYH+0MUPN74mX4rslf7pnBqZE/KZkW3uBIaBYvU8fxi0hcKC/Paw==
dependencies:
"@embroider/shared-internals" "^1.8.3"
semver "^7.3.5"
"@embroider/addon-shim@^1.0.0", "@embroider/addon-shim@^1.2.0", "@embroider/addon-shim@^1.8.4":
version "1.8.4"
resolved "https://registry.npmjs.org/@embroider/addon-shim/-/addon-shim-1.8.4.tgz"
@ -1411,7 +1419,21 @@
resolve "^1.20.0"
semver "^7.3.2"
"@embroider/macros@^0.50.0 || ^1.0.0", "@embroider/macros@^1.0.0", "@embroider/macros@^1.10.0", "@embroider/macros@^1.2.0", "@embroider/macros@^1.8.1", "@embroider/macros@^1.8.3":
"@embroider/macros@^0.50.0 || ^1.0.0", "@embroider/macros@^1.13.0", "@embroider/macros@^1.2.0":
version "1.13.2"
resolved "https://registry.yarnpkg.com/@embroider/macros/-/macros-1.13.2.tgz#07dda11313a2539f403404881b729e622a80ca17"
integrity sha512-AUgJ71xG8kjuTx8XB1AQNBiebJuXRfhcHr318dCwnQz9VRXdYSnEEqf38XRvGYIoCvIyn/3c72LrSwzaJqknOA==
dependencies:
"@embroider/shared-internals" "2.5.0"
assert-never "^1.2.1"
babel-import-util "^2.0.0"
ember-cli-babel "^7.26.6"
find-up "^5.0.0"
lodash "^4.17.21"
resolve "^1.20.0"
semver "^7.3.2"
"@embroider/macros@^1.0.0", "@embroider/macros@^1.10.0":
version "1.10.0"
resolved "https://registry.npmjs.org/@embroider/macros/-/macros-1.10.0.tgz"
integrity sha512-LMbfQGk/a+f6xtvAv5fq/wf2LRxETnbgSCLUf/z6ebzmuskOUxrke+uP55chF/loWrARi9g6erFQ7RDOUoBMSg==
@ -1478,7 +1500,22 @@
semver "^7.3.5"
typescript-memoize "^1.0.1"
"@embroider/shared-internals@^1.0.0":
"@embroider/shared-internals@2.5.0":
version "2.5.0"
resolved "https://registry.yarnpkg.com/@embroider/shared-internals/-/shared-internals-2.5.0.tgz#4a0b5127c589718fae60fc22f81374ed558b944a"
integrity sha512-7qzrb7GVIyNqeY0umxoeIvjDC+ay1b+wb2yCVuYTUYrFfLAkLEy9FNI3iWCi3RdQ9OFjgcAxAnwsAiPIMZZ3pQ==
dependencies:
babel-import-util "^2.0.0"
debug "^4.3.2"
ember-rfc176-data "^0.3.17"
fs-extra "^9.1.0"
js-string-escape "^1.0.1"
lodash "^4.17.21"
resolve-package-path "^4.0.1"
semver "^7.3.5"
typescript-memoize "^1.0.1"
"@embroider/shared-internals@^1.0.0", "@embroider/shared-internals@^1.8.3":
version "1.8.3"
resolved "https://registry.npmjs.org/@embroider/shared-internals/-/shared-internals-1.8.3.tgz"
integrity sha512-N5Gho6Qk8z5u+mxLCcMYAoQMbN4MmH+z2jXwQHVs859bxuZTxwF6kKtsybDAASCtd2YGxEmzcc1Ja/wM28824w==
@ -1501,6 +1538,15 @@
broccoli-funnel "^3.0.5"
ember-cli-babel "^7.23.1"
"@embroider/util@^0.39.1 || ^0.40.0 || ^0.41.0 || ^1.0.0", "@embroider/util@^1.0.0":
version "1.12.0"
resolved "https://registry.yarnpkg.com/@embroider/util/-/util-1.12.0.tgz#4b7828650b55f8498f1e78bb63e27e77835e926f"
integrity sha512-P4M1QADEH9ceIYC9mwHeV+6DDgEIQQYFfZi728nVKqTAxakXoiLgu/BCyQmEGyow9fYEPYaC1boDCZxW2JQAXg==
dependencies:
"@embroider/macros" "^1.13.0"
broccoli-funnel "^3.0.5"
ember-cli-babel "^7.26.11"
"@embroider/util@^0.47.0":
version "0.47.2"
resolved "https://registry.npmjs.org/@embroider/util/-/util-0.47.2.tgz"
@ -1814,24 +1860,24 @@
faker "^4.1.0"
js-yaml "^3.13.1"
"@hashicorp/design-system-components@^2.14.1":
version "2.14.1"
resolved "https://registry.npmjs.org/@hashicorp/design-system-components/-/design-system-components-2.14.1.tgz"
integrity sha512-EgUpKUAQlTXKnJfv98RHFz1rqcb3xWE8CiLgiEcjN8RuX5P05D0llHKMlbdhsuzqe0D72c//wesk9Mlbb9tngw==
"@hashicorp/design-system-components@^3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@hashicorp/design-system-components/-/design-system-components-3.0.2.tgz#f9bf18f0f20f6396d4afc2ed138056c27dff8a38"
integrity sha512-Pt3dgCxzutIJ3LDtVgT0NSU5oTV8OFzgK9Nx1tTzIpMOfbCRzZuBmJB06ZPCdyP9Vs7lQVrn/kKzZaKJejrXiQ==
dependencies:
"@ember/render-modifiers" "^2.0.5"
"@ember/test-waiters" "^3.0.2"
"@hashicorp/design-system-tokens" "^1.9.0"
"@hashicorp/ember-flight-icons" "^3.1.3"
"@hashicorp/ember-flight-icons" "^4.0.1"
dialog-polyfill "^0.5.6"
ember-a11y-refocus "^3.0.2"
ember-auto-import "^2.6.3"
ember-cached-decorator-polyfill "^0.1.4"
ember-cli-babel "^7.26.11"
ember-cli-clipboard "^1.0.0"
ember-cli-htmlbars "^6.2.0"
ember-cli-sass "^10.0.1"
ember-composable-helpers "^4.5.0"
ember-element-helper "^0.8.5"
ember-focus-trap "^1.0.2"
ember-keyboard "^8.2.0"
ember-stargate "^0.4.3"
@ -1860,15 +1906,16 @@
pretender "^3.2.0"
recursive-readdir-sync "^1.0.6"
"@hashicorp/ember-flight-icons@^3.1.3":
version "3.1.3"
resolved "https://registry.npmjs.org/@hashicorp/ember-flight-icons/-/ember-flight-icons-3.1.3.tgz"
integrity sha512-Cy/zD6aKqwN1Q+jnF1wJ2QzRx4/6XIVM4x3qO0poi2RHBSzZS/jxwAIqyDXdKiqJha7i/vWP3aGQmDEBqoGKjA==
"@hashicorp/ember-flight-icons@^4.0.1":
version "4.0.1"
resolved "https://registry.yarnpkg.com/@hashicorp/ember-flight-icons/-/ember-flight-icons-4.0.1.tgz#08499f495f8f9ff9eb9eb6c439f1861f8411c047"
integrity sha512-8xkU+2ATX/a5pofmwO51YXgwHamG6YUpxOXxcPbA+9/TKNn1HFbrk3TWJBuDIwz2kdk9hXRZBri2XIR18BFrTA==
dependencies:
"@hashicorp/flight-icons" "^2.20.0"
ember-auto-import "^2.6.3"
ember-cli-babel "^7.26.11"
ember-cli-htmlbars "^6.2.0"
ember-get-config "^2.1.1"
"@hashicorp/flight-icons@^2.20.0":
version "2.20.0"
@ -5680,7 +5727,7 @@ debug@2.6.9, debug@^2.1.0, debug@^2.1.1, debug@^2.1.3, debug@^2.2.0, debug@^2.3.
dependencies:
ms "2.0.0"
debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2:
debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2:
version "4.3.4"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@ -6044,18 +6091,6 @@ ember-a11y-refocus@^3.0.2:
ember-cli-babel "^7.26.11"
ember-cli-htmlbars "^6.0.1"
ember-arg-types@^1.0.0:
version "1.1.0"
resolved "https://registry.npmjs.org/ember-arg-types/-/ember-arg-types-1.1.0.tgz"
integrity sha512-hWpUz0eiNkWzi3FgHW5QU6LyCDyUlTWwuIROHluEKZoa9m6LJVXbb/EVFgIG3FkAib6a5Ie00WvkXEZFXxh3+A==
dependencies:
"@embroider/macros" "^1.8.1"
ember-auto-import "^2.4.2"
ember-cli-babel "^7.26.11"
ember-cli-typescript "^5.1.1"
ember-get-config "^2.1.1"
prop-types "^15.8.1"
ember-array-fns@^1.4.0:
version "1.4.2"
resolved "https://registry.npmjs.org/ember-array-fns/-/ember-array-fns-1.4.2.tgz"
@ -6317,20 +6352,6 @@ ember-cli-babel@^7.0.0, ember-cli-babel@^7.1.3, ember-cli-babel@^7.10.0, ember-c
rimraf "^3.0.1"
semver "^5.5.0"
ember-cli-clipboard@^1.0.0:
version "1.1.0"
resolved "https://registry.npmjs.org/ember-cli-clipboard/-/ember-cli-clipboard-1.1.0.tgz"
integrity sha512-gqFMeLCMe7OKP8rtZluV3BsP03bnjqD/f1QQLdOB9gAbdiHzMIAbwIA/RhccGtGQgy5AlnxkkQ+7j/h6UDluPQ==
dependencies:
"@embroider/macros" "^1.10.0"
clipboard "^2.0.11"
ember-arg-types "^1.0.0"
ember-auto-import "^2.4.2"
ember-cli-babel "^7.26.11"
ember-cli-htmlbars "^6.1.0"
ember-modifier "^3.2.7 || ^4.1.0"
prop-types "^15.8.1"
ember-cli-code-coverage@^1.0.0-beta.4:
version "1.0.3"
resolved "https://registry.npmjs.org/ember-cli-code-coverage/-/ember-cli-code-coverage-1.0.3.tgz"
@ -6433,7 +6454,7 @@ ember-cli-htmlbars@^5.0.0, ember-cli-htmlbars@^5.1.0, ember-cli-htmlbars@^5.1.2,
strip-bom "^4.0.0"
walk-sync "^2.2.0"
ember-cli-htmlbars@^6.0.0, ember-cli-htmlbars@^6.0.1, ember-cli-htmlbars@^6.1.0, ember-cli-htmlbars@^6.1.1, ember-cli-htmlbars@^6.2.0:
ember-cli-htmlbars@^6.0.0, ember-cli-htmlbars@^6.0.1, ember-cli-htmlbars@^6.1.1, ember-cli-htmlbars@^6.2.0:
version "6.2.0"
resolved "https://registry.npmjs.org/ember-cli-htmlbars/-/ember-cli-htmlbars-6.2.0.tgz"
integrity sha512-j5EGixjGau23HrqRiW/JjoAovg5UBHfjbyN7wX5ekE90knIEqUUj1z/Mo/cTx/J2VepQ2lE6HdXW9LWQ/WdMtw==
@ -6671,7 +6692,7 @@ ember-cli-typescript@^4.0.0, ember-cli-typescript@^4.1.0, ember-cli-typescript@^
stagehand "^1.0.0"
walk-sync "^2.2.0"
ember-cli-typescript@^5.0.0, ember-cli-typescript@^5.1.0, ember-cli-typescript@^5.1.1:
ember-cli-typescript@^5.0.0, ember-cli-typescript@^5.1.0:
version "5.2.1"
resolved "https://registry.npmjs.org/ember-cli-typescript/-/ember-cli-typescript-5.2.1.tgz"
integrity sha512-qqp5TAIuPHxHiGXJKL+78Euyhy0zSKQMovPh8sJpN/ZBYx0H90pONufHR3anaMcp1snVfx4B+mb9+7ijOik8ZA==
@ -6954,6 +6975,15 @@ ember-destroyable-polyfill@^2.0.2, ember-destroyable-polyfill@^2.0.3:
ember-cli-version-checker "^5.1.1"
ember-compatibility-helpers "^1.2.1"
ember-element-helper@0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/ember-element-helper/-/ember-element-helper-0.6.1.tgz#a6fbc5be5f875b5c864ae61bf5c5f81d6de6d936"
integrity sha512-YiOdAMlzYul4ulkIoNp8z7iHDfbT1fbut/9xGFRfxDwU/FmF8HtAUB2f1veu/w50HTeZNopa1OV2PCloZ76XlQ==
dependencies:
"@embroider/util" "^0.39.1 || ^0.40.0 || ^0.41.0 || ^1.0.0"
ember-cli-babel "^7.26.11"
ember-cli-htmlbars "^6.0.1"
ember-element-helper@^0.5.5:
version "0.5.5"
resolved "https://registry.npmjs.org/ember-element-helper/-/ember-element-helper-0.5.5.tgz"
@ -6963,6 +6993,14 @@ ember-element-helper@^0.5.5:
ember-cli-babel "^7.17.2"
ember-cli-htmlbars "^5.1.0"
ember-element-helper@^0.8.5:
version "0.8.5"
resolved "https://registry.yarnpkg.com/ember-element-helper/-/ember-element-helper-0.8.5.tgz#5a53d4e3aa8379694c2002a3097269aeb7c2621b"
integrity sha512-yZYzuasn6ZC8Nwv0MpaLYGtm68ZxIBSNSe/CYxNWkDdgcuAb2lAG1gx37XkwBIiwPQET0W2agwq7++/HwdMF8g==
dependencies:
"@embroider/addon-shim" "1.8.3"
"@embroider/util" "^1.0.0"
ember-exam@^6.1.0:
version "6.1.0"
resolved "https://registry.npmjs.org/ember-exam/-/ember-exam-6.1.0.tgz"
@ -7037,20 +7075,6 @@ ember-in-element-polyfill@^1.0.0:
ember-cli-htmlbars "^5.3.1"
ember-cli-version-checker "^5.1.2"
ember-in-viewport@^4.0.0:
version "4.1.0"
resolved "https://registry.npmjs.org/ember-in-viewport/-/ember-in-viewport-4.1.0.tgz"
integrity sha512-3y6qWXuJPPc6vX2GfxWgtr+sDjb+bdZF9babstr0lTd8t8c1b42gJ13GaJqlylZIyZz2dEXFCimX9WAeudPv9g==
dependencies:
"@embroider/macros" "^1.8.3"
ember-auto-import "^2.2.3"
ember-cli-babel "^7.26.6"
ember-destroyable-polyfill "^2.0.3"
ember-modifier "^2.1.2 || ^3.0.0 || ^4.0.0"
fast-deep-equal "^2.0.1"
intersection-observer-admin "~0.3.2"
raf-pool "~0.1.4"
ember-inflector@^4.0.1, ember-inflector@^4.0.2:
version "4.0.2"
resolved "https://registry.npmjs.org/ember-inflector/-/ember-inflector-4.0.2.tgz"
@ -7156,7 +7180,7 @@ ember-modifier@^2.1.0:
ember-destroyable-polyfill "^2.0.2"
ember-modifier-manager-polyfill "^1.2.0"
"ember-modifier@^2.1.2 || ^3.0.0 || ^4.0.0", "ember-modifier@^2.1.2 || ^3.1.0 || ^4.0.0", "ember-modifier@^3.2.7 || ^4.0.0", "ember-modifier@^3.2.7 || ^4.1.0", ember-modifier@^4.1.0:
"ember-modifier@^2.1.2 || ^3.1.0 || ^4.0.0", "ember-modifier@^3.2.7 || ^4.0.0", ember-modifier@^4.1.0:
version "4.1.0"
resolved "https://registry.npmjs.org/ember-modifier/-/ember-modifier-4.1.0.tgz"
integrity sha512-YFCNpEYj6jdyy3EjslRb2ehNiDvaOrXTilR9+ngq+iUqSHYto2zKV0rleiA1XJQ27ELM1q8RihT29U6Lq5EyqQ==
@ -8194,11 +8218,6 @@ faker@^5.5.3:
resolved "https://registry.npmjs.org/faker/-/faker-5.5.3.tgz"
integrity sha512-wLTv2a28wjUyWkbnX7u/ABZBkUkIF2fCd73V6P2oFqEGEktDfzWx4UxrSqtPRw0xPRAcjeAOIiJWqZm3pP4u3g==
fast-deep-equal@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz"
integrity sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
@ -9637,11 +9656,6 @@ internmap@^1.0.0:
resolved "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz"
integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==
intersection-observer-admin@~0.3.2:
version "0.3.3"
resolved "https://registry.npmjs.org/intersection-observer-admin/-/intersection-observer-admin-0.3.3.tgz"
integrity sha512-aKMJPw/8cxybcgYTbnwGn87VgSFbSNNqeChRJahD+ai+jtwlCOdIcEvtuBd2BWO9bPuylVgeQVmGGfX2aS1NIg==
intl-messageformat-parser@^6.0.5:
version "6.4.4"
resolved "https://registry.npmjs.org/intl-messageformat-parser/-/intl-messageformat-parser-6.4.4.tgz"
@ -10808,7 +10822,7 @@ longest-streak@^2.0.0:
resolved "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz"
integrity sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==
loose-envify@^1.0.0, loose-envify@^1.4.0:
loose-envify@^1.0.0:
version "1.4.0"
resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
@ -12502,15 +12516,6 @@ promise.hash.helper@^1.0.7:
resolved "https://registry.npmjs.org/promise.hash.helper/-/promise.hash.helper-1.0.8.tgz"
integrity sha512-KYcnXctWUWyVD3W3Ye0ZDuA1N8Szrh85cVCxpG6xYrOk/0CttRtYCmU30nWsUch0NuExQQ63QXvzRE6FLimZmg==
prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
dependencies:
loose-envify "^1.4.0"
object-assign "^4.1.1"
react-is "^16.13.1"
property-information@^5.0.0:
version "5.6.0"
resolved "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz"
@ -12648,11 +12653,6 @@ qunit@^2.16.0, qunit@^2.17.2:
node-watch "0.7.3"
tiny-glob "0.2.9"
raf-pool@~0.1.4:
version "0.1.4"
resolved "https://registry.npmjs.org/raf-pool/-/raf-pool-0.1.4.tgz"
integrity sha512-BBPamTVuSprPq7CUmgxc+ycbsYUtUYnQtJYEfMHXMaostPaNpQzipLfSa/rwjmlgjBPiD7G+I+8W340sLOPu6g==
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz"
@ -12701,11 +12701,6 @@ raw-body@~1.1.0:
bytes "1"
string_decoder "0.10"
react-is@^16.13.1:
version "16.13.1"
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-is@^17.0.1:
version "17.0.2"
resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz"