mirror of https://github.com/hashicorp/consul
Backport of CC-5545: side nav (#19573)
* 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 issuepull/19582/head
parent
5b6e6d404d
commit
43ae89e12b
|
@ -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.
|
||||
```
|
|
@ -0,0 +1,3 @@
|
|||
```release-note:bug
|
||||
ui: clear peer on home logo link
|
||||
```
|
|
@ -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}}
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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}}
|
|
@ -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}}
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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}}
|
|
@ -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}}
|
||||
|
|
|
@ -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}}
|
|
@ -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}}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)}}
|
||||
>
|
||||
|
|
|
@ -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)
|
||||
|
||||
---
|
|
@ -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>
|
|
@ -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);
|
||||
}
|
|
@ -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}}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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}}
|
||||
|
|
|
@ -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'
|
||||
@href={{href-to 'index' params=(hash peer=undefined)}}
|
||||
@isHrefExternal={{false}}
|
||||
/>
|
||||
</: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>
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
@import './skin.scss';
|
||||
@import './layout.scss';
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
```
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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}}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
@import './skin';
|
||||
@import './layout';
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
@import './ui/index';
|
||||
@import './semantic-variables';
|
||||
@import './ui/frame-placeholders.scss';
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
@import './frame-placeholders';
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
---
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
|
@ -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');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}
|
167
ui/yarn.lock
167
ui/yarn.lock
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue