UI: upgrade HDS to 4.12.0 (#28525)

* update hds to latest version

* yield dropdown Interactive text instead of use @text arg, results after running codemod

* remaining dropdown changes

* address sidebar nav IconButton deprecation, fix secret tests

* revert

* explicitly select popupmenu

* more test changes

* fix pki toggle button

* remove tracked prop in oidc client controller

* aaand more test updates

* change to tilde

* tilde yarn lock changes

* small cleanup items
This commit is contained in:
claire bontempo
2024-10-04 13:07:48 -07:00
committed by GitHub
parent bae00721d2
commit 05f32b69ee
67 changed files with 282 additions and 419 deletions

View File

@@ -18,9 +18,11 @@
/> />
</:logo> </:logo>
<:actions> <:actions>
<Hds::SideNav::Header::IconButton <Hds::Button
@isIconOnly={{true}}
@size="large"
@icon="terminal-screen" @icon="terminal-screen"
@ariaLabel="Console toggle" @text="Console toggle"
data-test-console-toggle data-test-console-toggle
{{on "click" (fn (mut this.console.isOpen) (not this.console.isOpen))}} {{on "click" (fn (mut this.console.isOpen) (not this.console.isOpen))}}
/> />

View File

@@ -12,7 +12,7 @@
as |Dropdown| as |Dropdown|
> >
<Dropdown.Trigger data-test-user-menu-trigger> <Dropdown.Trigger data-test-user-menu-trigger>
<Hds::SideNav::Header::IconButton @icon="user" @ariaLabel="User menu" /> <Hds::Button @isIconOnly={{true}} @size="large" @icon="user" @text="User menu" />
</Dropdown.Trigger> </Dropdown.Trigger>
<Dropdown.Content> <Dropdown.Content>
<div class="popup-menu-content" data-test-user-menu-content> <div class="popup-menu-content" data-test-user-menu-content>

View File

@@ -5,22 +5,7 @@
import Controller from '@ember/controller'; import Controller from '@ember/controller';
import { service } from '@ember/service'; import { service } from '@ember/service';
import { tracked } from '@glimmer/tracking';
export default class OidcClientController extends Controller { export default class OidcClientController extends Controller {
@service router; @service router;
@tracked isEditRoute;
constructor() {
super(...arguments);
this.router.on(
'routeDidChange',
({ targetName }) => (this.isEditRoute = targetName.includes('edit') ? true : false)
);
}
get showHeader() {
// hide header when rendering the edit form
return !this.isEditRoute;
}
} }

View File

@@ -5,21 +5,7 @@
import Controller from '@ember/controller'; import Controller from '@ember/controller';
import { service } from '@ember/service'; import { service } from '@ember/service';
import { tracked } from '@glimmer/tracking';
export default class OidcKeyController extends Controller { export default class OidcKeyController extends Controller {
@service router; @service router;
@tracked isEditRoute;
constructor() {
super(...arguments);
this.router.on('routeDidChange', ({ targetName }) => {
return (this.isEditRoute = targetName.includes('edit') ? true : false);
});
}
get showHeader() {
// hide header when rendering the edit form
return !this.isEditRoute;
}
} }

View File

@@ -5,21 +5,7 @@
import Controller from '@ember/controller'; import Controller from '@ember/controller';
import { service } from '@ember/service'; import { service } from '@ember/service';
import { tracked } from '@glimmer/tracking';
export default class OidcProviderController extends Controller { export default class OidcProviderController extends Controller {
@service router; @service router;
@tracked isEditRoute;
constructor() {
super(...arguments);
this.router.on('routeDidChange', ({ targetName }) => {
return (this.isEditRoute = targetName.includes('edit') ? true : false);
});
}
get showHeader() {
// hide header when rendering the edit form
return !this.isEditRoute;
}
} }

View File

@@ -55,7 +55,8 @@
&:hover { &:hover {
background-color: $ui-gray-050; background-color: $ui-gray-050;
} }
div { div,
span {
margin-left: -$spacing-4; margin-left: -$spacing-4;
font-size: $size-7; font-size: $size-7;
font-weight: $font-weight-semibold; font-weight: $font-weight-semibold;

View File

@@ -195,8 +195,3 @@ label {
cursor: not-allowed; cursor: not-allowed;
} }
} }
// TODO remove when HDS has released fix
.hds-form-masked-input .hds-form-masked-input__toggle-button {
margin-right: $spacing-12;
}

View File

@@ -79,20 +79,17 @@
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
<dd.Interactive <dd.Interactive
@text="View {{singularize @itemType}}"
@route="vault.cluster.access.method.item.show" @route="vault.cluster.access.method.item.show"
@models={{array @methodModel.id @itemType list.item.id}} @models={{array @methodModel.id @itemType list.item.id}}
/> >View {{singularize @itemType}}</dd.Interactive>
<dd.Interactive <dd.Interactive
@text="Edit {{singularize @itemType}}"
@route="vault.cluster.access.method.item.edit" @route="vault.cluster.access.method.item.edit"
@models={{array @methodModel.id @itemType list.item.id}} @models={{array @methodModel.id @itemType list.item.id}}
/> >Edit {{singularize @itemType}}</dd.Interactive>
<dd.Interactive <dd.Interactive @color="critical" {{on "click" (fn (mut this.itemToDelete) list.item)}}>
@text="Delete {{singularize @itemType}}" Delete
@color="critical" {{singularize @itemType}}
{{on "click" (fn (mut this.itemToDelete) list.item)}} </dd.Interactive>
/>
</Hds::Dropdown> </Hds::Dropdown>
</Item.menu> </Item.menu>
{{#if (eq list.item this.itemToDelete)}} {{#if (eq list.item this.itemToDelete)}}

View File

@@ -12,10 +12,9 @@
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
<dd.Interactive <dd.Interactive
@text="Details"
@route="vault.cluster.access.identity.aliases.show" @route="vault.cluster.access.identity.aliases.show"
@models={{array (pluralize @item.parentType) @item.id "details"}} @models={{array (pluralize @item.parentType) @item.id "details"}}
/> >Details</dd.Interactive>
{{#if @item.updatePath.isPending}} {{#if @item.updatePath.isPending}}
<dd.Generic class="has-text-center"> <dd.Generic class="has-text-center">
<LoadingDropdownOption /> <LoadingDropdownOption />
@@ -23,18 +22,16 @@
{{else}} {{else}}
{{#if @item.canEdit}} {{#if @item.canEdit}}
<dd.Interactive <dd.Interactive
@text="Edit"
@route="vault.cluster.access.identity.aliases.edit" @route="vault.cluster.access.identity.aliases.edit"
@models={{array (pluralize @item.parentType) @item.id}} @models={{array (pluralize @item.parentType) @item.id}}
/> >Edit</dd.Interactive>
{{/if}} {{/if}}
{{#if @item.canDelete}} {{#if @item.canDelete}}
<dd.Interactive <dd.Interactive
@text="Remove"
@color="critical" @color="critical"
{{on "click" (fn (mut this.showConfirmModal) true)}} {{on "click" (fn (mut this.showConfirmModal) true)}}
data-test-popup-menu="delete" data-test-popup-menu="delete"
/> >Remove</dd.Interactive>
{{/if}} {{/if}}
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>

View File

@@ -11,7 +11,7 @@
@hasChevron={{false}} @hasChevron={{false}}
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
<dd.Interactive @text="Remove" @color="critical" {{on "click" (fn (mut this.showConfirmModal) true)}} /> <dd.Interactive @color="critical" {{on "click" (fn (mut this.showConfirmModal) true)}}>Remove</dd.Interactive>
</Hds::Dropdown> </Hds::Dropdown>
</div> </div>

View File

@@ -6,7 +6,7 @@
<div class="has-text-right"> <div class="has-text-right">
<Hds::Dropdown @isInline={{true}} @listPosition="bottom-right" as |dd|> <Hds::Dropdown @isInline={{true}} @listPosition="bottom-right" as |dd|>
<dd.ToggleIcon @icon="more-horizontal" @text="Metadata options" @hasChevron={{false}} data-test-popup-menu-trigger /> <dd.ToggleIcon @icon="more-horizontal" @text="Metadata options" @hasChevron={{false}} data-test-popup-menu-trigger />
<dd.Interactive @text="Remove" @color="critical" {{on "click" (fn (mut this.showConfirmModal) true)}} /> <dd.Interactive @color="critical" {{on "click" (fn (mut this.showConfirmModal) true)}}>Remove</dd.Interactive>
</Hds::Dropdown> </Hds::Dropdown>
</div> </div>

View File

@@ -11,13 +11,12 @@
@hasChevron={{false}} @hasChevron={{false}}
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
<dd.Interactive @text="View policy" @route="vault.cluster.policy.show" @models={{array "acl" @policyName}} /> <dd.Interactive @route="vault.cluster.policy.show" @models={{array "acl" @policyName}}>View policy</dd.Interactive>
<dd.Interactive @text="Edit policy" @route="vault.cluster.policy.edit" @models={{array "acl" @policyName}} /> <dd.Interactive @route="vault.cluster.policy.edit" @models={{array "acl" @policyName}}>Edit policy</dd.Interactive>
<dd.Interactive <dd.Interactive @color="critical" {{on "click" (fn (mut this.showConfirmModal) true)}}>
@text="Remove from {{@model.identityType}}" Remove from
@color="critical" {{@model.identityType}}
{{on "click" (fn (mut this.showConfirmModal) true)}} </dd.Interactive>
/>
</Hds::Dropdown> </Hds::Dropdown>
</div> </div>

View File

@@ -27,17 +27,15 @@
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
<dd.Interactive <dd.Interactive
@text="Details"
@route="vault.cluster.access.mfa.enforcements.enforcement" @route="vault.cluster.access.mfa.enforcements.enforcement"
@model={{@model.name}} @model={{@model.name}}
data-test-list-item-link="details" data-test-list-item-link="details"
/> >Details</dd.Interactive>
<dd.Interactive <dd.Interactive
@text="Edit"
@route="vault.cluster.access.mfa.enforcements.enforcement.edit" @route="vault.cluster.access.mfa.enforcements.enforcement.edit"
@model={{@model.name}} @model={{@model.name}}
data-test-list-item-link="edit" data-test-list-item-link="edit"
/> >Edit</dd.Interactive>
</Hds::Dropdown> </Hds::Dropdown>
</div> </div>
</div> </div>

View File

@@ -38,17 +38,15 @@
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
<dd.Interactive <dd.Interactive
@text="Details"
@route="vault.cluster.access.mfa.methods.method" @route="vault.cluster.access.mfa.methods.method"
@model={{@model.id}} @model={{@model.id}}
data-test-mfa-method-menu-link="details" data-test-mfa-method-menu-link="details"
/> >Details</dd.Interactive>
<dd.Interactive <dd.Interactive
@text="Edit"
@route="vault.cluster.access.mfa.methods.method.edit" @route="vault.cluster.access.mfa.methods.method.edit"
@model={{@model.id}} @model={{@model.id}}
data-test-mfa-method-menu-link="edit" data-test-mfa-method-menu-link="edit"
/> >Edit</dd.Interactive>
</Hds::Dropdown> </Hds::Dropdown>
</div> </div>
</div> </div>

View File

@@ -34,19 +34,17 @@
/> />
{{#if client.canRead}} {{#if client.canRead}}
<dd.Interactive <dd.Interactive
@text="Details"
@route="vault.cluster.access.oidc.clients.client.details" @route="vault.cluster.access.oidc.clients.client.details"
@model={{client.name}} @model={{client.name}}
data-test-oidc-client-menu-link="details" data-test-oidc-client-menu-link="details"
/> >Details</dd.Interactive>
{{/if}} {{/if}}
{{#if client.canEdit}} {{#if client.canEdit}}
<dd.Interactive <dd.Interactive
@text="Edit"
@route="vault.cluster.access.oidc.clients.client.edit" @route="vault.cluster.access.oidc.clients.client.edit"
@model={{client.name}} @model={{client.name}}
data-test-oidc-client-menu-link="edit" data-test-oidc-client-menu-link="edit"
/> >Edit</dd.Interactive>
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>
{{/if}} {{/if}}

View File

@@ -34,19 +34,17 @@
/> />
{{#if provider.canRead}} {{#if provider.canRead}}
<dd.Interactive <dd.Interactive
@text="Details"
@route="vault.cluster.access.oidc.providers.provider.details" @route="vault.cluster.access.oidc.providers.provider.details"
@model={{provider.name}} @model={{provider.name}}
data-test-oidc-provider-menu-link="details" data-test-oidc-provider-menu-link="details"
/> >Details</dd.Interactive>
{{/if}} {{/if}}
{{#if provider.canEdit}} {{#if provider.canEdit}}
<dd.Interactive <dd.Interactive
@text="Edit"
@route="vault.cluster.access.oidc.providers.provider.edit" @route="vault.cluster.access.oidc.providers.provider.edit"
@model={{provider.name}} @model={{provider.name}}
data-test-oidc-provider-menu-link="edit" data-test-oidc-provider-menu-link="edit"
/> >Edit</dd.Interactive>
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>
{{/if}} {{/if}}

View File

@@ -12,13 +12,12 @@
<dd.Interactive <dd.Interactive
@href="/v1/sys/storage/raft/snapshot" @href="/v1/sys/storage/raft/snapshot"
@isHrefExternal={{false}} @isHrefExternal={{false}}
@text="Download"
{{on "click" (action "downloadViaServiceWorker")}} {{on "click" (action "downloadViaServiceWorker")}}
/> >Download</dd.Interactive>
{{else}} {{else}}
<dd.Interactive @text="Download" {{on "click" (action "downloadSnapshot")}} /> <dd.Interactive {{on "click" (action "downloadSnapshot")}}>Download</dd.Interactive>
{{/if}} {{/if}}
<dd.Interactive @text="Restore" @route="vault.cluster.storage-restore" /> <dd.Interactive @route="vault.cluster.storage-restore">Restore</dd.Interactive>
</Hds::Dropdown> </Hds::Dropdown>
</PH.Actions> </PH.Actions>
</Hds::PageHeader> </Hds::PageHeader>

View File

@@ -36,11 +36,10 @@
</dd.Generic> </dd.Generic>
{{else if @item.canGenerate}} {{else if @item.canGenerate}}
<dd.Interactive <dd.Interactive
@text="Generate credentials"
@route="vault.cluster.secrets.backend.credentials" @route="vault.cluster.secrets.backend.credentials"
@model={{@item.id}} @model={{@item.id}}
data-test-role-aws-link="generate" data-test-role-aws-link="generate"
/> >Generate credentials</dd.Interactive>
{{/if}} {{/if}}
{{#if @item.updatePath.isPending}} {{#if @item.updatePath.isPending}}
<dd.Generic class="has-text-center"> <dd.Generic class="has-text-center">
@@ -49,27 +48,24 @@
{{else}} {{else}}
{{#if @item.canRead}} {{#if @item.canRead}}
<dd.Interactive <dd.Interactive
@text="Details"
@route="vault.cluster.secrets.backend.show" @route="vault.cluster.secrets.backend.show"
@model={{@item.id}} @model={{@item.id}}
data-test-role-ssh-link="show" data-test-role-ssh-link="show"
/> >Details</dd.Interactive>
{{/if}} {{/if}}
{{#if @item.canEdit}} {{#if @item.canEdit}}
<dd.Interactive <dd.Interactive
@text="Edit"
@route="vault.cluster.secrets.backend.edit" @route="vault.cluster.secrets.backend.edit"
@model={{@item.id}} @model={{@item.id}}
data-test-role-ssh-link="edit" data-test-role-ssh-link="edit"
/> >Edit</dd.Interactive>
{{/if}} {{/if}}
{{#if @item.canDelete}} {{#if @item.canDelete}}
<dd.Interactive <dd.Interactive
@text="Delete"
@color="critical" @color="critical"
{{on "click" (fn (mut this.showConfirmModal) true)}} {{on "click" (fn (mut this.showConfirmModal) true)}}
data-test-aws-role-delete={{@item.id}} data-test-aws-role-delete={{@item.id}}
/> >Delete</dd.Interactive>
{{/if}} {{/if}}
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>

View File

@@ -34,46 +34,41 @@
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
{{#if @item.canEdit}} {{#if @item.canEdit}}
<dd.Interactive @text="Edit connection" @route="vault.cluster.secrets.backend.edit" @model={{@item.id}} /> <dd.Interactive @route="vault.cluster.secrets.backend.edit" @model={{@item.id}}>Edit connection</dd.Interactive>
{{/if}} {{/if}}
{{#if @item.canEditRole}} {{#if @item.canEditRole}}
<dd.Interactive @text="Edit Role" @route="vault.cluster.secrets.backend.edit" @model={{concat "role/" @item.id}} /> <dd.Interactive @route="vault.cluster.secrets.backend.edit" @model={{concat "role/" @item.id}}>Edit Role</dd.Interactive>
{{/if}} {{/if}}
{{#if @item.canReset}} {{#if @item.canReset}}
<dd.Interactive <dd.Interactive
@text="Reset connection"
@icon={{if (eq this.actionRunning "reset") "loading"}} @icon={{if (eq this.actionRunning "reset") "loading"}}
{{on "click" (fn this.resetConnection @item.id)}} {{on "click" (fn this.resetConnection @item.id)}}
/> >Reset connection</dd.Interactive>
{{/if}} {{/if}}
{{#if (and (eq @item.type "dynamic") @item.canGenerateCredentials)}} {{#if (and (eq @item.type "dynamic") @item.canGenerateCredentials)}}
<dd.Interactive <dd.Interactive
@text="Generate credentials"
@route="vault.cluster.secrets.backend.credentials" @route="vault.cluster.secrets.backend.credentials"
@model={{@item.id}} @model={{@item.id}}
@query={{hash roleType=this.keyTypeValue}} @query={{hash roleType=this.keyTypeValue}}
/> >Generate credentials</dd.Interactive>
{{else if (and (eq @item.type "static") @item.canGetCredentials)}} {{else if (and (eq @item.type "static") @item.canGetCredentials)}}
<dd.Interactive <dd.Interactive
@text="Get credentials"
@route="vault.cluster.secrets.backend.credentials" @route="vault.cluster.secrets.backend.credentials"
@model={{@item.id}} @model={{@item.id}}
@query={{hash roleType=this.keyTypeValue}} @query={{hash roleType=this.keyTypeValue}}
/> >Get credentials</dd.Interactive>
{{/if}} {{/if}}
{{#if (and @item.canRotateRoleCredentials (eq this.keyTypeValue "static"))}} {{#if (and @item.canRotateRoleCredentials (eq this.keyTypeValue "static"))}}
<dd.Interactive <dd.Interactive
@text="Rotate credentials"
@icon={{if (eq this.actionRunning "rotateRole") "loading"}} @icon={{if (eq this.actionRunning "rotateRole") "loading"}}
{{on "click" (fn this.rotateRoleCred @item.id)}} {{on "click" (fn this.rotateRoleCred @item.id)}}
/> >Rotate credentials</dd.Interactive>
{{/if}} {{/if}}
{{#if @item.canRotateRoot}} {{#if @item.canRotateRoot}}
<dd.Interactive <dd.Interactive
@text="Rotate root credentials"
@icon={{if (eq this.actionRunning "rotateRoot") "loading"}} @icon={{if (eq this.actionRunning "rotateRoot") "loading"}}
{{on "click" (fn this.rotateRootCred @item.id)}} {{on "click" (fn this.rotateRootCred @item.id)}}
/> >Rotate root credentials</dd.Interactive>
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>
</div> </div>

View File

@@ -21,6 +21,7 @@
@backend={{@backendModel.id}} @backend={{@backendModel.id}}
@queryParams={{secret-query-params @backendModel.type @item.type asQueryParams=true}} @queryParams={{secret-query-params @backendModel.type @item.type asQueryParams=true}}
class="has-text-black has-text-weight-semibold" class="has-text-black has-text-weight-semibold"
data-test-secret-item-link={{@item.id}}
> >
{{#if (eq @backendModel.type "transit")}} {{#if (eq @backendModel.type "transit")}}
<Icon @name="key" class="has-text-grey-light" /> <Icon @name="key" class="has-text-grey-light" />
@@ -39,7 +40,7 @@
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
{{#if @item.isFolder}} {{#if @item.isFolder}}
<dd.Interactive @text="Contents" @route="vault.cluster.secrets.backend.list" @model={{@item.id}} /> <dd.Interactive @route="vault.cluster.secrets.backend.list" @model={{@item.id}}>Contents</dd.Interactive>
{{else}} {{else}}
{{#if (or @item.versionPath.isLoading @item.secretPath.isLoading)}} {{#if (or @item.versionPath.isLoading @item.secretPath.isLoading)}}
<dd.Generic class="has-text-center"> <dd.Generic class="has-text-center">
@@ -48,27 +49,24 @@
{{else}} {{else}}
{{#if @item.canRead}} {{#if @item.canRead}}
<dd.Interactive <dd.Interactive
@text="Details"
@route="vault.cluster.secrets.backend.show" @route="vault.cluster.secrets.backend.show"
@model={{@item.id}} @model={{@item.id}}
@query={{secret-query-params @backendModel.type @item.type asQueryParams=true}} @query={{secret-query-params @backendModel.type @item.type asQueryParams=true}}
/> >Details</dd.Interactive>
{{/if}} {{/if}}
{{#if @item.canEdit}} {{#if @item.canEdit}}
<dd.Interactive <dd.Interactive
@text="Edit"
@route="vault.cluster.secrets.backend.edit" @route="vault.cluster.secrets.backend.edit"
@model={{@item.id}} @model={{@item.id}}
@query={{secret-query-params @backendModel.type @item.type asQueryParams=true}} @query={{secret-query-params @backendModel.type @item.type asQueryParams=true}}
/> >Edit</dd.Interactive>
{{/if}} {{/if}}
{{#if @item.canDelete}} {{#if @item.canDelete}}
<dd.Interactive <dd.Interactive
@text="Delete"
@color="critical" @color="critical"
data-test-confirm-action-trigger data-test-confirm-action-trigger
{{on "click" (fn (mut this.showConfirmModal) true)}} {{on "click" (fn (mut this.showConfirmModal) true)}}
/> >Delete</dd.Interactive>
{{/if}} {{/if}}
{{/if}} {{/if}}
{{/if}} {{/if}}

View File

@@ -50,11 +50,10 @@
</dd.Generic> </dd.Generic>
{{else if @item.canGenerate}} {{else if @item.canGenerate}}
<dd.Interactive <dd.Interactive
@text="Generate credentials"
@route="vault.cluster.secrets.backend.credentials" @route="vault.cluster.secrets.backend.credentials"
@model={{@item.id}} @model={{@item.id}}
data-test-role-ssh-link="generate" data-test-role-ssh-link="generate"
/> >Generate credentials</dd.Interactive>
{{/if}} {{/if}}
{{else if (eq @item.keyType "ca")}} {{else if (eq @item.keyType "ca")}}
{{#if @item.signPath.isPending}} {{#if @item.signPath.isPending}}
@@ -63,11 +62,10 @@
</dd.Generic> </dd.Generic>
{{else if @item.canGenerate}} {{else if @item.canGenerate}}
<dd.Interactive <dd.Interactive
@text="Sign Keys"
@route="vault.cluster.secrets.backend.sign" @route="vault.cluster.secrets.backend.sign"
@model={{@item.id}} @model={{@item.id}}
data-test-role-ssh-link="generate" data-test-role-ssh-link="generate"
/> >Sign Keys</dd.Interactive>
{{/if}} {{/if}}
{{/if}} {{/if}}
{{#if @loadingToggleZeroAddress}} {{#if @loadingToggleZeroAddress}}
@@ -75,10 +73,9 @@
<LoadingDropdownOption /> <LoadingDropdownOption />
</dd.Generic> </dd.Generic>
{{else if @item.canEditZeroAddress}} {{else if @item.canEditZeroAddress}}
<dd.Interactive <dd.Interactive {{on "click" @toggleZeroAddress}}>
@text={{if @item.zeroAddress "Disable Zero Address" "Enable Zero Address"}} {{if @item.zeroAddress "Disable Zero Address" "Enable Zero Address"}}
{{on "click" @toggleZeroAddress}} </dd.Interactive>
/>
{{/if}} {{/if}}
{{#if @item.updatePath.isPending}} {{#if @item.updatePath.isPending}}
<dd.Generic class="has-text-center"> <dd.Generic class="has-text-center">
@@ -87,27 +84,24 @@
{{else}} {{else}}
{{#if @item.canRead}} {{#if @item.canRead}}
<dd.Interactive <dd.Interactive
@text="Details"
@route="vault.cluster.secrets.backend.show" @route="vault.cluster.secrets.backend.show"
@model={{@item.id}} @model={{@item.id}}
data-test-role-ssh-link="show" data-test-role-ssh-link="show"
/> >Details</dd.Interactive>
{{/if}} {{/if}}
{{#if @item.canEdit}} {{#if @item.canEdit}}
<dd.Interactive <dd.Interactive
@text="Edit"
@route="vault.cluster.secrets.backend.edit" @route="vault.cluster.secrets.backend.edit"
@model={{@item.id}} @model={{@item.id}}
data-test-role-ssh-link="edit" data-test-role-ssh-link="edit"
/> >Edit</dd.Interactive>
{{/if}} {{/if}}
{{#if @item.canDelete}} {{#if @item.canDelete}}
<dd.Interactive <dd.Interactive
@text="Delete"
@color="critical" @color="critical"
{{on "click" (fn (mut this.showConfirmModal) true)}} {{on "click" (fn (mut this.showConfirmModal) true)}}
data-test-ssh-role-delete data-test-ssh-role-delete
/> >Delete</dd.Interactive>
{{/if}} {{/if}}
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>

View File

@@ -33,10 +33,10 @@
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
{{#if @item.updatePath.canRead}} {{#if @item.updatePath.canRead}}
<dd.Interactive @text="Details" @route="vault.cluster.secrets.backend.show" @model={{@itemPath}} /> <dd.Interactive @route="vault.cluster.secrets.backend.show" @model={{@itemPath}}>Details</dd.Interactive>
{{/if}} {{/if}}
{{#if @item.updatePath.canUpdate}} {{#if @item.updatePath.canUpdate}}
<dd.Interactive @text="Edit" @route="vault.cluster.secrets.backend.edit" @model={{@itemPath}} /> <dd.Interactive @route="vault.cluster.secrets.backend.edit" @model={{@itemPath}}>Edit</dd.Interactive>
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>
{{/if}} {{/if}}

View File

@@ -33,10 +33,10 @@
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
{{#if @item.updatePath.canRead}} {{#if @item.updatePath.canRead}}
<dd.Interactive @text="Details" @route="vault.cluster.secrets.backend.show" @model={{@item.id}} /> <dd.Interactive @route="vault.cluster.secrets.backend.show" @model={{@item.id}}>Details</dd.Interactive>
{{/if}} {{/if}}
{{#if @item.updatePath.canUpdate}} {{#if @item.updatePath.canUpdate}}
<dd.Interactive @text="Edit" @route="vault.cluster.secrets.backend.edit" @model={{@item.id}} /> <dd.Interactive @route="vault.cluster.secrets.backend.edit" @model={{@item.id}}>Edit</dd.Interactive>
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>
{{/if}} {{/if}}

View File

@@ -15,7 +15,7 @@
<Hds::SideNav::Header::HomeLink @icon="vault" @route="vault" @ariaLabel="Vault dashboard" /> <Hds::SideNav::Header::HomeLink @icon="vault" @route="vault" @ariaLabel="Vault dashboard" />
</:logo> </:logo>
<:actions> <:actions>
<Hds::SideNav::Header::IconButton @icon="home" @ariaLabel="Docs index" @route="docs" /> <Hds::Button @isIconOnly={{true}} @icon="home" @text="Docs index" @route="docs" />
</:actions> </:actions>
</Hds::SideNav::Header> </Hds::SideNav::Header>
</:header> </:header>

View File

@@ -41,10 +41,9 @@
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
<dd.Interactive <dd.Interactive
@text="Details"
@route="vault.cluster.access.identity.show" @route="vault.cluster.access.identity.show"
@models={{array item.id "details"}} @models={{array item.id "details"}}
/> >Details</dd.Interactive>
{{#if (or item.isReloading item.updatePath.isPending item.aliasPath.isPending)}} {{#if (or item.isReloading item.updatePath.isPending item.aliasPath.isPending)}}
<dd.Generic class="has-text-center"> <dd.Generic class="has-text-center">
<LoadingDropdownOption /> <LoadingDropdownOption />
@@ -55,27 +54,28 @@
{{#if (or (eq this.identityType "entity") (and (eq item.type "external") (not item.alias)))}} {{#if (or (eq this.identityType "entity") (and (eq item.type "external") (not item.alias)))}}
<dd.Interactive <dd.Interactive
data-test-popup-menu="create alias" data-test-popup-menu="create alias"
@text="Create alias"
@route="vault.cluster.access.identity.aliases.add" @route="vault.cluster.access.identity.aliases.add"
@models={{array (pluralize this.identityType) item.id}} @models={{array (pluralize this.identityType) item.id}}
/> >Create alias</dd.Interactive>
{{/if}} {{/if}}
{{/if}} {{/if}}
{{#if item.canEdit}} {{#if item.canEdit}}
<dd.Interactive @text="Edit" @route="vault.cluster.access.identity.edit" @model={{item.id}} /> <dd.Interactive @route="vault.cluster.access.identity.edit" @model={{item.id}}>Edit</dd.Interactive>
{{#if item.disabled}} {{#if item.disabled}}
<dd.Interactive @text="Enable" {{on "click" (action "toggleDisabled" item)}} /> <dd.Interactive {{on "click" (action "toggleDisabled" item)}}>Enable</dd.Interactive>
{{else if (eq this.identityType "entity")}} {{else if (eq this.identityType "entity")}}
<dd.Interactive @text="Disable" @color="critical" {{on "click" (fn (mut this.entityToDisable) item)}} /> <dd.Interactive
@color="critical"
{{on "click" (fn (mut this.entityToDisable) item)}}
>Disable</dd.Interactive>
{{/if}} {{/if}}
{{/if}} {{/if}}
{{#if item.canDelete}} {{#if item.canDelete}}
<dd.Interactive <dd.Interactive
@text="Delete"
@color="critical" @color="critical"
{{on "click" (fn (mut this.itemToDelete) item)}} {{on "click" (fn (mut this.itemToDelete) item)}}
data-test-popup-menu="delete" data-test-popup-menu="delete"
/> >Delete</dd.Interactive>
{{/if}} {{/if}}
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>

View File

@@ -76,20 +76,19 @@
@hasChevron={{false}} @hasChevron={{false}}
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
<dd.Interactive <dd.Interactive @route="vault.cluster.access.method.section" @models={{array method.id "configuration"}}>
@text="View configuration" View configuration
@route="vault.cluster.access.method.section" </dd.Interactive>
@models={{array method.id "configuration"}}
/>
{{#if (or method.canEdit (and (eq method.methodType "aws") method.canEditAws))}} {{#if (or method.canEdit (and (eq method.methodType "aws") method.canEditAws))}}
<dd.Interactive <dd.Interactive @route="vault.cluster.settings.auth.configure" @model={{method.id}}>
@text="Edit configuration" Edit configuration
@route="vault.cluster.settings.auth.configure" </dd.Interactive>
@model={{method.id}}
/>
{{/if}} {{/if}}
{{#if (and (not-eq method.methodType "token") method.canDisable)}} {{#if (and (not-eq method.methodType "token") method.canDisable)}}
<dd.Interactive @text="Disable" @color="critical" {{on "click" (fn (mut this.methodToDisable) method)}} /> <dd.Interactive
@color="critical"
{{on "click" (fn (mut this.methodToDisable) method)}}
>Disable</dd.Interactive>
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>
</div> </div>

View File

@@ -93,11 +93,10 @@
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
<dd.Interactive <dd.Interactive
@text="Details"
@route={{target.link}} @route={{target.link}}
@models={{target.linkModels}} @models={{target.linkModels}}
data-test-target-link={{target.title}} data-test-target-link={{target.title}}
/> >Details</dd.Interactive>
</Hds::Dropdown> </Hds::Dropdown>
</div> </div>
</div> </div>

View File

@@ -46,7 +46,7 @@
</dd.Generic> </dd.Generic>
{{/if}} {{/if}}
{{/let}} {{/let}}
<dd.Interactive @text="Delete" @color="critical" {{on "click" (fn (mut this.nsToDelete) list.item)}} /> <dd.Interactive @color="critical" {{on "click" (fn (mut this.nsToDelete) list.item)}}>Delete</dd.Interactive>
</Hds::Dropdown> </Hds::Dropdown>
{{#if (eq this.nsToDelete list.item)}} {{#if (eq this.nsToDelete list.item)}}
<ConfirmModal <ConfirmModal

View File

@@ -46,19 +46,17 @@
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
<dd.Interactive <dd.Interactive
@text="Details"
@route="vault.cluster.access.oidc.assignments.assignment.details" @route="vault.cluster.access.oidc.assignments.assignment.details"
@model={{model.name}} @model={{model.name}}
@disabled={{eq model.canRead false}} @disabled={{eq model.canRead false}}
data-test-oidc-assignment-menu-link="details" data-test-oidc-assignment-menu-link="details"
/> >Details</dd.Interactive>
<dd.Interactive <dd.Interactive
@text="Edit"
@route="vault.cluster.access.oidc.assignments.assignment.edit" @route="vault.cluster.access.oidc.assignments.assignment.edit"
@model={{model.name}} @model={{model.name}}
@disabled={{eq model.canEdit false}} @disabled={{eq model.canEdit false}}
data-test-oidc-assignment-menu-link="edit" data-test-oidc-assignment-menu-link="edit"
/> >Edit</dd.Interactive>
</Hds::Dropdown> </Hds::Dropdown>
</div> </div>
</div> </div>

View File

@@ -3,7 +3,7 @@
SPDX-License-Identifier: BUSL-1.1 SPDX-License-Identifier: BUSL-1.1
~}} ~}}
{{#if this.showHeader}} {{#if (not-eq this.router.currentRoute.localName "edit")}}
<PageHeader as |p|> <PageHeader as |p|>
<p.top> <p.top>
<Hds::Breadcrumb> <Hds::Breadcrumb>

View File

@@ -21,7 +21,7 @@
<div class="level-left"> <div class="level-left">
<div> <div>
<Icon @name="key" class="has-text-grey-light" /> <Icon @name="key" class="has-text-grey-light" />
<span class="has-text-weight-semibold is-underline"> <span class="has-text-weight-semibold is-underline" data-test-item>
{{model.name}} {{model.name}}
</span> </span>
</div> </div>
@@ -36,19 +36,17 @@
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
<dd.Interactive <dd.Interactive
@text="Details"
@route="vault.cluster.access.oidc.keys.key.details" @route="vault.cluster.access.oidc.keys.key.details"
@model={{model.name}} @model={{model.name}}
@disabled={{eq model.canRead false}} @disabled={{eq model.canRead false}}
data-test-oidc-key-menu-link="details" data-test-oidc-key-menu-link="details"
/> >Details</dd.Interactive>
<dd.Interactive <dd.Interactive
@text="Edit"
@route="vault.cluster.access.oidc.keys.key.edit" @route="vault.cluster.access.oidc.keys.key.edit"
@model={{model.name}} @model={{model.name}}
@disabled={{eq model.canEdit false}} @disabled={{eq model.canEdit false}}
data-test-oidc-key-menu-link="edit" data-test-oidc-key-menu-link="edit"
/> >Edit</dd.Interactive>
</Hds::Dropdown> </Hds::Dropdown>
</div> </div>
</div> </div>

View File

@@ -3,7 +3,7 @@
SPDX-License-Identifier: BUSL-1.1 SPDX-License-Identifier: BUSL-1.1
~}} ~}}
{{#if this.showHeader}} {{#if (not-eq this.router.currentRoute.localName "edit")}}
<PageHeader as |p|> <PageHeader as |p|>
<p.top> <p.top>
<Hds::Breadcrumb> <Hds::Breadcrumb>

View File

@@ -3,7 +3,7 @@
SPDX-License-Identifier: BUSL-1.1 SPDX-License-Identifier: BUSL-1.1
~}} ~}}
{{#if this.showHeader}} {{#if (not-eq this.router.currentRoute.localName "edit")}}
<PageHeader as |p|> <PageHeader as |p|>
<p.top> <p.top>
<Hds::Breadcrumb> <Hds::Breadcrumb>

View File

@@ -37,19 +37,17 @@
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
<dd.Interactive <dd.Interactive
@text="Details"
@route="vault.cluster.access.oidc.scopes.scope.details" @route="vault.cluster.access.oidc.scopes.scope.details"
@model={{model.name}} @model={{model.name}}
@disabled={{eq model.canRead false}} @disabled={{eq model.canRead false}}
data-test-oidc-scope-menu-link="details" data-test-oidc-scope-menu-link="details"
/> >Details</dd.Interactive>
<dd.Interactive <dd.Interactive
@text="Edit"
@route="vault.cluster.access.oidc.scopes.scope.edit" @route="vault.cluster.access.oidc.scopes.scope.edit"
@model={{model.name}} @model={{model.name}}
@disabled={{eq model.canEdit false}} @disabled={{eq model.canEdit false}}
data-test-oidc-scope-menu-link="edit" data-test-oidc-scope-menu-link="edit"
/> >Edit</dd.Interactive>
</Hds::Dropdown> </Hds::Dropdown>
</div> </div>
</div> </div>

View File

@@ -105,27 +105,24 @@
{{else}} {{else}}
{{#if item.canRead}} {{#if item.canRead}}
<dd.Interactive <dd.Interactive
@text="Details"
@route="vault.cluster.policy.show" @route="vault.cluster.policy.show"
@models={{array this.policyType item.id}} @models={{array this.policyType item.id}}
data-test-policy-link="show" data-test-policy-link="show"
/> >Details</dd.Interactive>
{{/if}} {{/if}}
{{#if item.canEdit}} {{#if item.canEdit}}
<dd.Interactive <dd.Interactive
@text="Edit"
@route="vault.cluster.policy.edit" @route="vault.cluster.policy.edit"
@models={{array this.policyType item.id}} @models={{array this.policyType item.id}}
data-test-policy-link="edit" data-test-policy-link="edit"
/> >Edit</dd.Interactive>
{{/if}} {{/if}}
{{#if (and item.canDelete (not-eq item.name "default"))}} {{#if (and item.canDelete (not-eq item.name "default"))}}
<dd.Interactive <dd.Interactive
@text="Delete"
@color="critical" @color="critical"
data-test-confirm-action-trigger data-test-confirm-action-trigger
{{on "click" (fn (mut this.policyToDelete) item)}} {{on "click" (fn (mut this.policyToDelete) item)}}
/> >Delete</dd.Interactive>
{{/if}} {{/if}}
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>

View File

@@ -94,19 +94,15 @@
@hasChevron={{false}} @hasChevron={{false}}
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
<dd.Interactive <dd.Interactive @route={{backend.backendConfigurationLink}} @model={{backend.id}} data-test-engine-config>
@text="View configuration" View configuration
@route={{backend.backendConfigurationLink}} </dd.Interactive>
@model={{backend.id}}
data-test-engine-config
/>
{{#if (not-eq backend.type "cubbyhole")}} {{#if (not-eq backend.type "cubbyhole")}}
<dd.Interactive <dd.Interactive
@text="Disable"
@color="critical" @color="critical"
{{on "click" (fn (mut this.engineToDisable) backend)}} {{on "click" (fn (mut this.engineToDisable) backend)}}
data-test-confirm-action-trigger data-test-confirm-action-trigger
/> >Disable</dd.Interactive>
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>
</div> </div>

View File

@@ -113,10 +113,13 @@
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
{{#if message.canEditCustomMessages}} {{#if message.canEditCustomMessages}}
<dd.Interactive @text="Edit" @route="messages.message.edit" @model={{message.id}} /> <dd.Interactive @route="messages.message.edit" @model={{message.id}}>Edit</dd.Interactive>
{{/if}} {{/if}}
{{#if message.canDeleteCustomMessages}} {{#if message.canDeleteCustomMessages}}
<dd.Interactive @text="Delete" @color="critical" {{on "click" (fn (mut this.messageToDelete) message)}} /> <dd.Interactive
@color="critical"
{{on "click" (fn (mut this.messageToDelete) message)}}
>Delete</dd.Interactive>
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>
{{/if}} {{/if}}

View File

@@ -7,13 +7,14 @@
{{! Hds component renders <li> and <button> elements }} {{! Hds component renders <li> and <button> elements }}
<Hds::Dropdown::ListItem::Interactive <Hds::Dropdown::ListItem::Interactive
data-test-confirm-action-trigger data-test-confirm-action-trigger
@text={{@buttonText}}
@color="critical" @color="critical"
{{on "click" (fn (mut this.showConfirmModal) true)}} {{on "click" (fn (mut this.showConfirmModal) true)}}
...attributes ...attributes
{{! remove class when dropdown/popup menus are replaced with Hds::Dropdown }} {{! remove class when dropdown/popup menus are replaced with Hds::Dropdown }}
class="hds-confirm-action-critical" class="hds-confirm-action-critical"
/> >
{{@buttonText}}
</Hds::Dropdown::ListItem::Interactive>
{{else}} {{else}}
<Hds::Button <Hds::Button
data-test-confirm-action-trigger data-test-confirm-action-trigger

View File

@@ -71,22 +71,17 @@
<Item.menu> <Item.menu>
<Hds::Dropdown @isInline={{true}} @listPosition="bottom-right" as |dd|> <Hds::Dropdown @isInline={{true}} @listPosition="bottom-right" as |dd|>
<dd.ToggleIcon @icon="more-horizontal" @text="More options" @hasChevron={{false}} data-test-popup-menu-trigger /> <dd.ToggleIcon @icon="more-horizontal" @text="More options" @hasChevron={{false}} data-test-popup-menu-trigger />
<dd.Interactive <dd.Interactive @route="credentials.show" @models={{array this.scope this.role list.item.id}}>View credentials</dd.Interactive>
@text="View credentials"
@route="credentials.show"
@models={{array this.scope this.role list.item.id}}
/>
{{#if list.item.deletePath.isPending}} {{#if list.item.deletePath.isPending}}
<dd.Generic> <dd.Generic>
<LoadingDropdownOption /> <LoadingDropdownOption />
</dd.Generic> </dd.Generic>
{{else if list.item.deletePath.canDelete}} {{else if list.item.deletePath.canDelete}}
<dd.Interactive <dd.Interactive
@text="Revoke credentials"
@color="critical" @color="critical"
{{on "click" (fn (mut this.credToRevoke) list.item)}} {{on "click" (fn (mut this.credToRevoke) list.item)}}
data-test-confirm-action-trigger data-test-confirm-action-trigger
/> >Revoke credentials</dd.Interactive>
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>
{{#if (eq this.credToRevoke list.item)}} {{#if (eq this.credToRevoke list.item)}}

View File

@@ -71,23 +71,22 @@
<Item.menu> <Item.menu>
<Hds::Dropdown @isInline={{true}} @listPosition="bottom-right" as |dd|> <Hds::Dropdown @isInline={{true}} @listPosition="bottom-right" as |dd|>
<dd.ToggleIcon @icon="more-horizontal" @text="More options" @hasChevron={{false}} data-test-popup-menu-trigger /> <dd.ToggleIcon @icon="more-horizontal" @text="More options" @hasChevron={{false}} data-test-popup-menu-trigger />
<dd.Interactive @text="View credentials" @route="credentials" @models={{array this.scope list.item.id}} /> <dd.Interactive @route="credentials" @models={{array this.scope list.item.id}}>View credentials</dd.Interactive>
<dd.Interactive @text="View role" @route="role" @models={{array this.scope list.item.id}} /> <dd.Interactive @route="role" @models={{array this.scope list.item.id}}>View role</dd.Interactive>
{{#if list.item.updatePath.isPending}} {{#if list.item.updatePath.isPending}}
<dd.Generic> <dd.Generic>
<LoadingDropdownOption /> <LoadingDropdownOption />
</dd.Generic> </dd.Generic>
{{else}} {{else}}
{{#if list.item.updatePath.canUpdate}} {{#if list.item.updatePath.canUpdate}}
<dd.Interactive @text="Edit role" @route="role.edit" @models={{array this.scope list.item.id}} /> <dd.Interactive @route="role.edit" @models={{array this.scope list.item.id}}>Edit role</dd.Interactive>
{{/if}} {{/if}}
{{#if list.item.updatePath.canDelete}} {{#if list.item.updatePath.canDelete}}
<dd.Interactive <dd.Interactive
@text="Delete role"
@color="critical" @color="critical"
{{on "click" (fn (mut this.roleToDelete) list.item)}} {{on "click" (fn (mut this.roleToDelete) list.item)}}
data-test-confirm-action-trigger data-test-confirm-action-trigger
/> >Delete role</dd.Interactive>
{{/if}} {{/if}}
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>

View File

@@ -60,18 +60,17 @@
<Item.menu> <Item.menu>
<Hds::Dropdown @isInline={{true}} @listPosition="bottom-right" as |dd|> <Hds::Dropdown @isInline={{true}} @listPosition="bottom-right" as |dd|>
<dd.ToggleIcon @icon="more-horizontal" @text="More options" @hasChevron={{false}} data-test-popup-menu-trigger /> <dd.ToggleIcon @icon="more-horizontal" @text="More options" @hasChevron={{false}} data-test-popup-menu-trigger />
<dd.Interactive @text="View scope" @route="scope" @model={{list.item.id}} /> <dd.Interactive @route="scope" @model={{list.item.id}}>View scope</dd.Interactive>
{{#if list.item.updatePath.isPending}} {{#if list.item.updatePath.isPending}}
<dd.Generic> <dd.Generic>
<LoadingDropdownOption /> <LoadingDropdownOption />
</dd.Generic> </dd.Generic>
{{else if list.item.updatePath.canDelete}} {{else if list.item.updatePath.canDelete}}
<dd.Interactive <dd.Interactive
@text="Delete scope"
@color="critical" @color="critical"
{{on "click" (fn (mut this.scopeToDelete) list.item)}} {{on "click" (fn (mut this.scopeToDelete) list.item)}}
data-test-confirm-action-trigger data-test-confirm-action-trigger
/> >Delete scope</dd.Interactive>
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>
{{#if (eq this.scopeToDelete list.item)}} {{#if (eq this.scopeToDelete list.item)}}

View File

@@ -49,18 +49,17 @@
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
{{#if role.canRead}} {{#if role.canRead}}
<dd.Interactive @text="Details" @route="roles.role.details" @model={{role}} data-test-details /> <dd.Interactive @route="roles.role.details" @model={{role}} data-test-details>Details</dd.Interactive>
{{/if}} {{/if}}
{{#if role.canEdit}} {{#if role.canEdit}}
<dd.Interactive @text="Edit" data-test-edit @route="roles.role.edit" @model={{role}} /> <dd.Interactive data-test-edit @route="roles.role.edit" @model={{role}}>Edit</dd.Interactive>
{{/if}} {{/if}}
{{#if role.canDelete}} {{#if role.canDelete}}
<dd.Interactive <dd.Interactive
@text="Delete"
data-test-delete data-test-delete
@color="critical" @color="critical"
{{on "click" (fn (mut this.roleToDelete) role)}} {{on "click" (fn (mut this.roleToDelete) role)}}
/> >Delete</dd.Interactive>
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>
{{/if}} {{/if}}

View File

@@ -84,7 +84,7 @@
<div class="level-left"> <div class="level-left">
<div> <div>
<Icon @name={{if metadata.pathIsDirectory "folder" "file"}} class="has-text-grey-light" /> <Icon @name={{if metadata.pathIsDirectory "folder" "file"}} class="has-text-grey-light" />
<span class="has-text-weight-semibold is-underline"> <span class="has-text-weight-semibold is-underline" data-test-path>
{{metadata.path}} {{metadata.path}}
</span> </span>
</div> </div>
@@ -100,35 +100,25 @@
/> />
{{#if metadata.pathIsDirectory}} {{#if metadata.pathIsDirectory}}
<dd.Interactive <dd.Interactive
@text="Content"
@route="list-directory" @route="list-directory"
@models={{array @backend metadata.fullSecretPath}} @models={{array @backend metadata.fullSecretPath}}
/> >Content</dd.Interactive>
{{else}} {{else}}
<dd.Interactive <dd.Interactive
@text="Overview"
@route="secret.index" @route="secret.index"
@models={{array @backend metadata.fullSecretPath}} @models={{array @backend metadata.fullSecretPath}}
/> >Overview</dd.Interactive>
<dd.Interactive <dd.Interactive @route="secret.details" @models={{array @backend metadata.fullSecretPath}}>Secret data</dd.Interactive>
@text="Secret data"
@route="secret.details"
@models={{array @backend metadata.fullSecretPath}}
/>
{{#if metadata.canReadMetadata}} {{#if metadata.canReadMetadata}}
<dd.Interactive <dd.Interactive @route="secret.metadata.versions" @models={{array @backend metadata.fullSecretPath}}>
@text="View version history" View version history</dd.Interactive>
@route="secret.metadata.versions"
@models={{array @backend metadata.fullSecretPath}}
/>
{{/if}} {{/if}}
{{#if metadata.canDeleteMetadata}} {{#if metadata.canDeleteMetadata}}
<dd.Interactive <dd.Interactive
@text="Permanently delete"
@color="critical" @color="critical"
{{on "click" (fn (mut this.metadataToDelete) metadata)}} {{on "click" (fn (mut this.metadataToDelete) metadata)}}
data-test-popup-metadata-delete data-test-popup-metadata-delete
/> >Permanently delete</dd.Interactive>
{{/if}} {{/if}}
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>

View File

@@ -98,19 +98,17 @@
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
<dd.Interactive <dd.Interactive
@text="View version {{versionData.version}}"
@route="secret.details" @route="secret.details"
@models={{array @backend @path}} @models={{array @backend @path}}
@query={{hash version=versionData.version}} @query={{hash version=versionData.version}}
/> >View version {{versionData.version}}</dd.Interactive>
{{#if (and @metadata.canCreateVersionData (not versionData.destroyed) (not versionData.isSecretDeleted))}} {{#if (and @metadata.canCreateVersionData (not versionData.destroyed) (not versionData.isSecretDeleted))}}
<dd.Interactive <dd.Interactive
@text="Create new version from {{versionData.version}}"
@route="secret.details.edit" @route="secret.details.edit"
@models={{array @backend @path}} @models={{array @backend @path}}
@query={{hash version=versionData.version}} @query={{hash version=versionData.version}}
data-test-create-new-version-from={{versionData.version}} data-test-create-new-version-from={{versionData.version}}
/> >Create new version from {{versionData.version}}</dd.Interactive>
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>
</div> </div>

View File

@@ -58,18 +58,21 @@
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
{{#if library.canEdit}} {{#if library.canEdit}}
<dd.Interactive @text="Edit" data-test-edit @route="libraries.library.edit" @model={{library}} /> <dd.Interactive data-test-edit @route="libraries.library.edit" @model={{library}}>Edit</dd.Interactive>
{{/if}} {{/if}}
{{#if library.canRead}} {{#if library.canRead}}
<dd.Interactive @text="Details" data-test-details @route="libraries.library.details" @model={{library}} /> <dd.Interactive
data-test-details
@route="libraries.library.details"
@model={{library}}
>Details</dd.Interactive>
{{/if}} {{/if}}
{{#if library.canDelete}} {{#if library.canDelete}}
<dd.Interactive <dd.Interactive
@text="Delete"
data-test-delete data-test-delete
@color="critical" @color="critical"
{{on "click" (fn (mut this.libraryToDelete) library)}} {{on "click" (fn (mut this.libraryToDelete) library)}}
/> >Delete</dd.Interactive>
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>
{{/if}} {{/if}}

View File

@@ -53,38 +53,36 @@
<Hds::Dropdown @isInline={{true}} @listPosition="bottom-right" as |dd|> <Hds::Dropdown @isInline={{true}} @listPosition="bottom-right" as |dd|>
<dd.ToggleIcon @icon="more-horizontal" @text="More options" @hasChevron={{false}} data-test-popup-menu-trigger /> <dd.ToggleIcon @icon="more-horizontal" @text="More options" @hasChevron={{false}} data-test-popup-menu-trigger />
{{#if role.canEdit}} {{#if role.canEdit}}
<dd.Interactive @text="Edit" data-test-edit @route="roles.role.edit" @models={{array role.type role.name}} /> <dd.Interactive
data-test-edit
@route="roles.role.edit"
@models={{array role.type role.name}}
>Edit</dd.Interactive>
{{/if}} {{/if}}
{{#if role.canReadCreds}} {{#if role.canReadCreds}}
<dd.Interactive <dd.Interactive data-test-get-creds @route="roles.role.credentials" @models={{array role.type role.name}}>
@text="Get credentials" Get credentials
data-test-get-creds </dd.Interactive>
@route="roles.role.credentials"
@models={{array role.type role.name}}
/>
{{/if}} {{/if}}
{{#if role.canRotateStaticCreds}} {{#if role.canRotateStaticCreds}}
<dd.Interactive <dd.Interactive
@text="Rotate credentials"
data-test-rotate-creds data-test-rotate-creds
@color="critical" @color="critical"
{{on "click" (fn (mut this.credsToRotate) role)}} {{on "click" (fn (mut this.credsToRotate) role)}}
/> >Rotate credentials</dd.Interactive>
{{/if}} {{/if}}
<dd.Interactive <dd.Interactive
@text="Details"
data-test-details data-test-details
@route="roles.role.details" @route="roles.role.details"
{{! this will force the roles.role model hook to fire since we may only have a partial model loaded in the list view }} {{! this will force the roles.role model hook to fire since we may only have a partial model loaded in the list view }}
@models={{array role.type role.name}} @models={{array role.type role.name}}
/> >Details</dd.Interactive>
{{#if role.canDelete}} {{#if role.canDelete}}
<dd.Interactive <dd.Interactive
@text="Delete"
data-test-delete data-test-delete
@color="critical" @color="critical"
{{on "click" (fn (mut this.roleToDelete) role)}} {{on "click" (fn (mut this.roleToDelete) role)}}
/> >Delete</dd.Interactive>
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>
</Item.menu> </Item.menu>

View File

@@ -108,12 +108,11 @@
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
<dd.Interactive <dd.Interactive
@text="Details"
@route="issuers.issuer.details" @route="issuers.issuer.details"
@models={{array @backend pkiIssuer.id}} @models={{array @backend pkiIssuer.id}}
data-test-pki-issuer-details data-test-pki-issuer-details
/> >Details</dd.Interactive>
<dd.Interactive @text="Edit" @route="issuers.issuer.edit" @models={{array @backend pkiIssuer.id}} /> <dd.Interactive @route="issuers.issuer.edit" @models={{array @backend pkiIssuer.id}}>Edit</dd.Interactive>
</Hds::Dropdown> </Hds::Dropdown>
</div> </div>
</div> </div>

View File

@@ -54,19 +54,17 @@
/> />
{{#if @canRead}} {{#if @canRead}}
<dd.Interactive <dd.Interactive
@text="Details"
@route="keys.key.details" @route="keys.key.details"
@models={{array @backend pkiKey.keyId}} @models={{array @backend pkiKey.keyId}}
data-test-key-menu-link="details" data-test-key-menu-link="details"
/> >Details</dd.Interactive>
{{/if}} {{/if}}
{{#if @canEdit}} {{#if @canEdit}}
<dd.Interactive <dd.Interactive
@text="Edit"
@route="keys.key.edit" @route="keys.key.edit"
@models={{array @backend pkiKey.keyId}} @models={{array @backend pkiKey.keyId}}
data-test-key-menu-link="edit" data-test-key-menu-link="edit"
/> >Edit</dd.Interactive>
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>
{{/if}} {{/if}}

View File

@@ -38,7 +38,10 @@
@hasChevron={{false}} @hasChevron={{false}}
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
<dd.Interactive @text="Details" @route="certificates.certificate.details" @model={{pkiCertificate.id}} /> <dd.Interactive
@route="certificates.certificate.details"
@model={{pkiCertificate.id}}
>Details</dd.Interactive>
</Hds::Dropdown> </Hds::Dropdown>
</div> </div>
</div> </div>

View File

@@ -44,15 +44,13 @@
data-test-popup-menu-trigger data-test-popup-menu-trigger
/> />
<dd.Interactive <dd.Interactive
@text="Details"
@route="roles.role.details" @route="roles.role.details"
@models={{array this.model.parentModel.id pkiRole.id}} @models={{array this.model.parentModel.id pkiRole.id}}
/> >Details</dd.Interactive>
<dd.Interactive <dd.Interactive
@text="Edit"
@route="roles.role.edit" @route="roles.role.edit"
@models={{array this.model.parentModel.id pkiRole.id}} @models={{array this.model.parentModel.id pkiRole.id}}
/> >Edit</dd.Interactive>
</Hds::Dropdown> </Hds::Dropdown>
</div> </div>
</div> </div>

View File

@@ -38,18 +38,16 @@
/> />
{{#if (eq this.replicationMode "performance")}} {{#if (eq this.replicationMode "performance")}}
<dd.Interactive <dd.Interactive
@text="Path filter config"
@route="mode.secondaries.config-show" @route="mode.secondaries.config-show"
@models={{array this.replicationMode secondary}} @models={{array this.replicationMode secondary}}
data-test-replication-path-filter-link={{true}} data-test-replication-path-filter-link={{true}}
/> >Path filter config</dd.Interactive>
{{/if}} {{/if}}
{{#if this.model.canRevokeSecondary}} {{#if this.model.canRevokeSecondary}}
<dd.Interactive <dd.Interactive
@text="Revoke"
@color="critical" @color="critical"
{{on "click" (fn (mut this.secondaryToRevoke) secondary)}} {{on "click" (fn (mut this.secondaryToRevoke) secondary)}}
/> >Revoke</dd.Interactive>
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>
{{/if}} {{/if}}

View File

@@ -83,27 +83,24 @@
</dd.Generic> </dd.Generic>
{{else}} {{else}}
<dd.Interactive <dd.Interactive
@text="Details"
data-test-details data-test-details
@route="secrets.destinations.destination.details" @route="secrets.destinations.destination.details"
@models={{array destination.type destination.name}} @models={{array destination.type destination.name}}
@disabled={{not destination.canRead}} @disabled={{not destination.canRead}}
/> >Details</dd.Interactive>
{{#if destination.canEdit}} {{#if destination.canEdit}}
<dd.Interactive <dd.Interactive
@text="Edit"
data-test-edit data-test-edit
@route="secrets.destinations.destination.edit" @route="secrets.destinations.destination.edit"
@models={{array destination.type destination.name}} @models={{array destination.type destination.name}}
/> >Edit</dd.Interactive>
{{/if}} {{/if}}
{{#if destination.canDelete}} {{#if destination.canDelete}}
<dd.Interactive <dd.Interactive
data-test-delete data-test-delete
@text="Delete"
@color="critical" @color="critical"
{{on "click" (fn (mut this.destinationToDelete) destination)}} {{on "click" (fn (mut this.destinationToDelete) destination)}}
/> >Delete</dd.Interactive>
{{/if}} {{/if}}
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>

View File

@@ -53,26 +53,21 @@
<dd.Separator /> <dd.Separator />
{{/if}} {{/if}}
{{#if association.canSync}} {{#if association.canSync}}
<dd.Interactive <dd.Interactive data-test-association-action="sync" {{on "click" (fn this.update association "set")}}>
@text="Sync now" Sync now</dd.Interactive>
data-test-association-action="sync"
{{on "click" (fn this.update association "set")}}
/>
{{/if}} {{/if}}
<dd.Interactive <dd.Interactive
@text="View secret"
data-test-association-action="view" data-test-association-action="view"
@route="kvSecretOverview" @route="kvSecretOverview"
@isRouteExternal={{true}} @isRouteExternal={{true}}
@models={{array association.mount association.secretName}} @models={{array association.mount association.secretName}}
/> >View secret</dd.Interactive>
{{#if association.canUnsync}} {{#if association.canUnsync}}
<dd.Interactive <dd.Interactive
data-test-association-action="unsync" data-test-association-action="unsync"
@color="critical" @color="critical"
@text="Unsync"
{{on "click" (fn (mut this.secretToUnsync) association)}} {{on "click" (fn (mut this.secretToUnsync) association)}}
/> >Unsync</dd.Interactive>
{{/if}} {{/if}}
{{/if}} {{/if}}
</Hds::Dropdown> </Hds::Dropdown>

View File

@@ -142,15 +142,13 @@
<dd.Interactive <dd.Interactive
@route="secrets.destinations.destination.sync" @route="secrets.destinations.destination.sync"
@models={{array data.type data.name}} @models={{array data.type data.name}}
@text="Sync secrets"
data-test-overview-table-action="sync" data-test-overview-table-action="sync"
/> >Sync secrets</dd.Interactive>
<dd.Interactive <dd.Interactive
@route="secrets.destinations.destination.secrets" @route="secrets.destinations.destination.secrets"
@models={{array data.type data.name}} @models={{array data.type data.name}}
@text="View synced secrets"
data-test-overview-table-action="details" data-test-overview-table-action="details"
/> >View synced secrets</dd.Interactive>
</Hds::Dropdown> </Hds::Dropdown>
</B.Td> </B.Td>
</B.Tr> </B.Tr>

View File

@@ -234,7 +234,7 @@
}, },
"dependencies": { "dependencies": {
"@babel/core": "^7.24.0", "@babel/core": "^7.24.0",
"@hashicorp/design-system-components": "~4.7.0", "@hashicorp/design-system-components": "~4.12.0",
"@hashicorp/ember-flight-icons": "^5.1.3", "@hashicorp/ember-flight-icons": "^5.1.3",
"ember-auto-import": "^2.7.2", "ember-auto-import": "^2.7.2",
"handlebars": "4.7.7", "handlebars": "4.7.7",

View File

@@ -13,7 +13,7 @@ import { GENERAL } from 'vault/tests/helpers/general-selectors';
const SELECTORS = { const SELECTORS = {
identityRow: (name) => `[data-test-identity-row="${name}"]`, identityRow: (name) => `[data-test-identity-row="${name}"]`,
popupMenu: '[data-test-popup-menu-trigger]', popupMenu: '[data-test-popup-menu-trigger]',
menuDelete: '[data-test-popup-menu="delete"]', menuDelete: (name) => `[data-test-identity-row="${name}"] [data-test-popup-menu="delete"]`,
}; };
export const testCRUD = async (name, itemType, assert) => { export const testCRUD = async (name, itemType, assert) => {
await page.visit({ item_type: itemType }); await page.visit({ item_type: itemType });
@@ -36,8 +36,8 @@ export const testCRUD = async (name, itemType, assert) => {
); );
await click(`${SELECTORS.identityRow(name)} ${SELECTORS.popupMenu}`); await click(`${SELECTORS.identityRow(name)} ${SELECTORS.popupMenu}`);
await waitUntil(() => find(SELECTORS.menuDelete)); await waitUntil(() => find(SELECTORS.menuDelete(name)));
await click(SELECTORS.menuDelete); await click(SELECTORS.menuDelete(name));
await indexPage.confirmDelete(); await indexPage.confirmDelete();
await settled(); await settled();
assert.dom(GENERAL.latestFlashContent).includesText('Successfully deleted'); assert.dom(GENERAL.latestFlashContent).includesText('Successfully deleted');
@@ -57,7 +57,7 @@ export const testDeleteFromForm = async (name, itemType, assert) => {
await click('[data-test-tab-subnav="policies"]'); await click('[data-test-tab-subnav="policies"]');
assert.dom('.list-item-row').exists({ count: 1 }, 'One item is under policies'); assert.dom('.list-item-row').exists({ count: 1 }, 'One item is under policies');
await click('[data-test-tab-subnav="metadata"]'); await click('[data-test-tab-subnav="metadata"]');
assert.dom('.info-table-row').hasText('hello goodbye', 'Metadata shows on tab'); assert.dom('.info-table-row').hasTextContaining('hello goodbye', 'Metadata shows on tab');
await showPage.edit(); await showPage.edit();
assert.strictEqual( assert.strictEqual(
currentRouteName(), currentRouteName(),

View File

@@ -95,7 +95,7 @@ module('Acceptance | auth backend list', function (hooks) {
const itemCount = type === 'token' ? 2 : 3; const itemCount = type === 'token' ? 2 : 3;
await click(`[data-test-auth-backend-link="${path}"] [data-test-popup-menu-trigger]`); await click(`[data-test-auth-backend-link="${path}"] [data-test-popup-menu-trigger]`);
assert assert
.dom('.hds-dropdown-list-item') .dom(`[data-test-auth-backend-link="${path}"] .hds-dropdown-list-item`)
.exists({ count: itemCount }, `shows ${itemCount} dropdown items for ${type}`); .exists({ count: itemCount }, `shows ${itemCount} dropdown items for ${type}`);
// all auth methods should be linkable // all auth methods should be linkable

View File

@@ -214,10 +214,12 @@ module('Acceptance | mfa-method', function (hooks) {
'Route transitions to method on save' 'Route transitions to method on save'
); );
await click('[data-test-tab="enforcements"]'); await click('[data-test-tab="enforcements"]');
assert.dom('[data-test-list-item]').hasText('bar', 'Enforcement is listed in method view'); assert.dom('[data-test-list-item]').hasTextContaining('bar', 'Enforcement is listed in method view');
await click('[data-test-sidebar-nav-link="Multi-Factor Authentication"]'); await click('[data-test-sidebar-nav-link="Multi-Factor Authentication"]');
await click('[data-test-tab="enforcements"]'); await click('[data-test-tab="enforcements"]');
assert.dom('[data-test-list-item="bar"]').hasText('bar', 'Enforcement is listed in enforcements view'); assert
.dom('[data-test-list-item="bar"]')
.hasTextContaining('bar', 'Enforcement is listed in enforcements view');
await click('[data-test-list-item="bar"]'); await click('[data-test-list-item="bar"]');
await click('[data-test-tab="methods"]'); await click('[data-test-tab="methods"]');
assert assert
@@ -242,7 +244,7 @@ module('Acceptance | mfa-method', function (hooks) {
'Route transitions to method on save' 'Route transitions to method on save'
); );
await click('[data-test-tab="enforcements"]'); await click('[data-test-tab="enforcements"]');
assert.dom('[data-test-list-item]').hasText(name, 'Enforcement is listed in method view'); assert.dom('[data-test-list-item]').hasTextContaining(name, 'Enforcement is listed in method view');
}); });
test('it should edit methods', async function (assert) { test('it should edit methods', async function (assert) {

View File

@@ -72,7 +72,7 @@ module('Acceptance | oidc-config clients', function (hooks) {
assert.dom('[data-test-tab="keys"]').hasClass('active', 'keys tab is active'); assert.dom('[data-test-tab="keys"]').hasClass('active', 'keys tab is active');
assert.strictEqual(currentRouteName(), 'vault.cluster.access.oidc.keys.index'); assert.strictEqual(currentRouteName(), 'vault.cluster.access.oidc.keys.index');
assert assert
.dom('[data-test-oidc-key-linked-block="default"]') .dom('[data-test-oidc-key-linked-block="default"] [data-test-item]')
.hasText('default', 'index page lists default key'); .hasText('default', 'index page lists default key');
// navigate to default key details from pop-up menu // navigate to default key details from pop-up menu
@@ -132,7 +132,7 @@ module('Acceptance | oidc-config clients', function (hooks) {
// edit key and limit applications // edit key and limit applications
await visit(OIDC_BASE_URL + '/keys'); await visit(OIDC_BASE_URL + '/keys');
await click('[data-test-oidc-key-linked-block="test-key"] [data-test-popup-menu-trigger]'); await click('[data-test-oidc-key-linked-block="test-key"] [data-test-popup-menu-trigger]');
await click('[data-test-oidc-key-menu-link="edit"]'); await click('[data-test-oidc-key-linked-block="test-key"] [data-test-oidc-key-menu-link="edit"]');
assert.strictEqual( assert.strictEqual(
currentRouteName(), currentRouteName(),
'vault.cluster.access.oidc.keys.key.edit', 'vault.cluster.access.oidc.keys.key.edit',

View File

@@ -64,10 +64,11 @@ module('Acceptance | raft storage', function (hooks) {
return {}; return {};
}); });
const row = '[data-raft-row]:nth-child(2) [data-test-raft-actions]';
await visit('/vault/storage/raft'); await visit('/vault/storage/raft');
assert.dom('[data-raft-row]').exists({ count: 2 }, '2 raft peers render in table'); assert.dom('[data-raft-row]').exists({ count: 2 }, '2 raft peers render in table');
await click('[data-raft-row]:nth-child(2) [data-test-raft-actions] button'); await click(`${row} button`);
await click('[data-test-confirm-action-trigger]'); await click(`${row} [data-test-confirm-action-trigger]`);
await click('[data-test-confirm-button]'); await click('[data-test-confirm-button]');
assert.dom('[data-raft-row]').exists({ count: 1 }, 'Raft peer successfully removed'); assert.dom('[data-raft-row]').exists({ count: 1 }, 'Raft peer successfully removed');
}); });

View File

@@ -3,69 +3,55 @@
* SPDX-License-Identifier: BUSL-1.1 * SPDX-License-Identifier: BUSL-1.1
*/ */
import { currentRouteName, settled } from '@ember/test-helpers'; import { click, find, findAll, currentRouteName, visit } from '@ember/test-helpers';
import { clickTrigger } from 'ember-power-select/test-support/helpers'; import { clickTrigger } from 'ember-power-select/test-support/helpers';
import { create } from 'ember-cli-page-object';
import { module, test } from 'qunit'; import { module, test } from 'qunit';
import consoleClass from 'vault/tests/pages/components/console/ui-panel';
import { setupApplicationTest } from 'ember-qunit'; import { setupApplicationTest } from 'ember-qunit';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import mountSecrets from 'vault/tests/pages/settings/mount-secret-backend'; import { GENERAL } from 'vault/tests/helpers/general-selectors';
import backendsPage from 'vault/tests/pages/secrets/backends'; import { deleteEngineCmd, mountEngineCmd, runCmd } from 'vault/tests/helpers/commands';
import authPage from 'vault/tests/pages/auth'; import { login } from 'vault/tests/helpers/auth/auth-helpers';
import ss from 'vault/tests/pages/components/search-select';
const consoleComponent = create(consoleClass); const SELECTORS = {
const searchSelect = create(ss); backendLink: (path) =>
path ? `[data-test-secrets-backend-link="${path}"]` : '[data-test-secrets-backend-link]',
};
module('Acceptance | secret-engine list view', function (hooks) { module('Acceptance | secret-engine list view', function (hooks) {
setupApplicationTest(hooks); setupApplicationTest(hooks);
hooks.beforeEach(function () { hooks.beforeEach(function () {
this.uid = uuidv4(); this.uid = uuidv4();
return authPage.login(); return login();
}); });
test('it allows you to disable an engine', async function (assert) { test('it allows you to disable an engine', async function (assert) {
// first mount an engine so we can disable it. // first mount an engine so we can disable it.
const enginePath = `alicloud-disable-${this.uid}`; const enginePath = `alicloud-disable-${this.uid}`;
await mountSecrets.enable('alicloud', enginePath); await runCmd(mountEngineCmd('alicloud', enginePath));
await settled(); await visit('/vault/secrets');
assert.ok(backendsPage.rows.filterBy('path', `${enginePath}/`)[0], 'shows the mounted engine'); assert.dom(SELECTORS.backendLink(enginePath)).exists();
const row = SELECTORS.backendLink(enginePath);
await backendsPage.visit(); await click(`${row} ${GENERAL.menuTrigger}`);
await settled(); await click(`${row} ${GENERAL.confirmTrigger}`);
const row = backendsPage.rows.filterBy('path', `${enginePath}/`)[0]; await click(GENERAL.confirmButton);
await row.menu();
await settled();
await backendsPage.disableButton();
await settled();
await backendsPage.confirmDisable();
await settled();
assert.strictEqual( assert.strictEqual(
currentRouteName(), currentRouteName(),
'vault.cluster.secrets.backends', 'vault.cluster.secrets.backends',
'redirects to the backends page' 'redirects to the backends page'
); );
assert.strictEqual( assert.dom(SELECTORS.backendLink(enginePath)).doesNotExist('does not show the disabled engine');
backendsPage.rows.filterBy('path', `${enginePath}/`).length,
0,
'does not show the disabled engine'
);
}); });
test('it adds disabled css styling to unsupported secret engines', async function (assert) { test('it adds disabled css styling to unsupported secret engines', async function (assert) {
assert.expect(2); assert.expect(2);
// first mount engine that is not supported // first mount engine that is not supported
const enginePath = `nomad-${this.uid}`; const enginePath = `nomad-${this.uid}`;
await runCmd(mountEngineCmd('nomad', enginePath));
await visit('/vault/secrets');
await mountSecrets.enable('nomad', enginePath); const rows = findAll(SELECTORS.backendLink());
await settled();
await backendsPage.visit();
await settled();
const rows = document.querySelectorAll('[data-test-secrets-backend-link]');
const rowUnsupported = Array.from(rows).filter((row) => row.innerText.includes('nomad')); const rowUnsupported = Array.from(rows).filter((row) => row.innerText.includes('nomad'));
const rowSupported = Array.from(rows).filter((row) => row.innerText.includes('cubbyhole')); const rowSupported = Array.from(rows).filter((row) => row.innerText.includes('cubbyhole'));
assert assert
@@ -77,7 +63,7 @@ module('Acceptance | secret-engine list view', function (hooks) {
assert.dom(rowSupported[0]).hasClass('linked-block', `linked-block class is added to supported engines.`); assert.dom(rowSupported[0]).hasClass('linked-block', `linked-block class is added to supported engines.`);
// cleanup // cleanup
await consoleComponent.runCommands([`delete sys/mounts/${enginePath}`]); await runCmd(deleteEngineCmd(enginePath));
}); });
test('it filters by name and engine type', async function (assert) { test('it filters by name and engine type', async function (assert) {
@@ -85,32 +71,31 @@ module('Acceptance | secret-engine list view', function (hooks) {
const enginePath1 = `aws-1-${this.uid}`; const enginePath1 = `aws-1-${this.uid}`;
const enginePath2 = `aws-2-${this.uid}`; const enginePath2 = `aws-2-${this.uid}`;
await mountSecrets.enable('aws', enginePath1); await await runCmd(mountEngineCmd('aws', enginePath1));
await mountSecrets.enable('aws', enginePath2); await await runCmd(mountEngineCmd('aws', enginePath2));
await backendsPage.visit(); await visit('/vault/secrets');
await settled();
// filter by type // filter by type
await clickTrigger('#filter-by-engine-type'); await clickTrigger('#filter-by-engine-type');
await searchSelect.options.objectAt(0).click(); await click(GENERAL.searchSelect.option());
const rows = document.querySelectorAll('[data-test-secrets-backend-link]'); const rows = findAll(SELECTORS.backendLink());
const rowsAws = Array.from(rows).filter((row) => row.innerText.includes('aws')); const rowsAws = Array.from(rows).filter((row) => row.innerText.includes('aws'));
assert.strictEqual(rows.length, rowsAws.length, 'all rows returned are aws'); assert.strictEqual(rows.length, rowsAws.length, 'all rows returned are aws');
// filter by name // filter by name
await clickTrigger('#filter-by-engine-name'); await clickTrigger('#filter-by-engine-name');
const firstItemToSelect = searchSelect.options.objectAt(0).text; const firstItemToSelect = find(GENERAL.searchSelect.option()).innerText;
await searchSelect.options.objectAt(0).click(); await click(GENERAL.searchSelect.option());
const singleRow = document.querySelectorAll('[data-test-secrets-backend-link]'); const singleRow = document.querySelectorAll('[data-test-secrets-backend-link]');
assert.strictEqual(singleRow.length, 1, 'returns only one row'); assert.strictEqual(singleRow.length, 1, 'returns only one row');
assert.dom(singleRow[0]).includesText(firstItemToSelect, 'shows the filtered by name engine'); assert.dom(singleRow[0]).includesText(firstItemToSelect, 'shows the filtered by name engine');
// clear filter by engine name // clear filter by engine name
await searchSelect.deleteButtons.objectAt(1).click(); await click(`#filter-by-engine-name ${GENERAL.searchSelect.removeSelected}`);
const rowsAgain = document.querySelectorAll('[data-test-secrets-backend-link]'); const rowsAgain = document.querySelectorAll('[data-test-secrets-backend-link]');
assert.ok(rowsAgain.length > 1, 'filter has been removed'); assert.ok(rowsAgain.length > 1, 'filter has been removed');
// cleanup // cleanup
await consoleComponent.runCommands([`delete sys/mounts/${enginePath1}`]); await runCmd(deleteEngineCmd(enginePath1));
await consoleComponent.runCommands([`delete sys/mounts/${enginePath2}`]); await runCmd(deleteEngineCmd(enginePath2));
}); });
}); });

View File

@@ -48,17 +48,17 @@ module('Acceptance | kv-v2 workflow | secret and version create', function (hook
const backend = this.backend; const backend = this.backend;
await visit(`/vault/secrets/${backend}/kv/list`); await visit(`/vault/secrets/${backend}/kv/list`);
assert.dom(PAGE.list.item()).exists({ count: 1 }, 'single secret exists on list'); assert.dom(PAGE.list.item()).exists({ count: 1 }, 'single secret exists on list');
assert.dom(PAGE.list.item('app/')).hasText('app/', 'expected list item'); assert.dom(`${PAGE.list.item('app/')} [data-test-path]`).hasText('app/', 'expected list item');
await click(PAGE.list.createSecret); await click(PAGE.list.createSecret);
await fillIn(FORM.inputByAttr('path'), 'jk'); await fillIn(FORM.inputByAttr('path'), 'jk');
await click(FORM.cancelBtn); await click(FORM.cancelBtn);
assert.dom(PAGE.list.item()).exists({ count: 1 }, 'same amount of secrets'); assert.dom(PAGE.list.item()).exists({ count: 1 }, 'same amount of secrets');
assert.dom(PAGE.list.item('app/')).hasText('app/', 'expected list item'); assert.dom(`${PAGE.list.item('app/')} [data-test-path]`).hasText('app/', 'expected list item');
await click(PAGE.list.createSecret); await click(PAGE.list.createSecret);
await fillIn(FORM.inputByAttr('path'), 'psych'); await fillIn(FORM.inputByAttr('path'), 'psych');
await click(PAGE.breadcrumbAtIdx(1)); await click(PAGE.breadcrumbAtIdx(1));
assert.dom(PAGE.list.item()).exists({ count: 1 }, 'same amount of secrets'); assert.dom(PAGE.list.item()).exists({ count: 1 }, 'same amount of secrets');
assert.dom(PAGE.list.item('app/')).hasText('app/', 'expected list item'); assert.dom(`${PAGE.list.item('app/')} [data-test-path]`).hasText('app/', 'expected list item');
}); });
test('cancel on new version rolls back model (a)', async function (assert) { test('cancel on new version rolls back model (a)', async function (assert) {
const backend = this.backend; const backend = this.backend;
@@ -500,17 +500,17 @@ module('Acceptance | kv-v2 workflow | secret and version create', function (hook
const backend = this.backend; const backend = this.backend;
await visit(`/vault/secrets/${backend}/kv/list`); await visit(`/vault/secrets/${backend}/kv/list`);
assert.dom(PAGE.list.item()).exists({ count: 1 }, 'single secret exists on list'); assert.dom(PAGE.list.item()).exists({ count: 1 }, 'single secret exists on list');
assert.dom(PAGE.list.item('app/')).hasText('app/', 'expected list item'); assert.dom(`${PAGE.list.item('app/')} [data-test-path]`).hasText('app/', 'expected list item');
await click(PAGE.list.createSecret); await click(PAGE.list.createSecret);
await fillIn(FORM.inputByAttr('path'), 'jk'); await fillIn(FORM.inputByAttr('path'), 'jk');
await click(FORM.cancelBtn); await click(FORM.cancelBtn);
assert.dom(PAGE.list.item()).exists({ count: 1 }, 'same amount of secrets'); assert.dom(PAGE.list.item()).exists({ count: 1 }, 'same amount of secrets');
assert.dom(PAGE.list.item('app/')).hasText('app/', 'expected list item'); assert.dom(`${PAGE.list.item('app/')} [data-test-path]`).hasText('app/', 'expected list item');
await click(PAGE.list.createSecret); await click(PAGE.list.createSecret);
await fillIn(FORM.inputByAttr('path'), 'psych'); await fillIn(FORM.inputByAttr('path'), 'psych');
await click(PAGE.breadcrumbAtIdx(1)); await click(PAGE.breadcrumbAtIdx(1));
assert.dom(PAGE.list.item()).exists({ count: 1 }, 'same amount of secrets'); assert.dom(PAGE.list.item()).exists({ count: 1 }, 'same amount of secrets');
assert.dom(PAGE.list.item('app/')).hasText('app/', 'expected list item'); assert.dom(`${PAGE.list.item('app/')} [data-test-path]`).hasText('app/', 'expected list item');
}); });
test('cancel on new version rolls back model (dlr)', async function (assert) { test('cancel on new version rolls back model (dlr)', async function (assert) {
const backend = this.backend; const backend = this.backend;
@@ -649,17 +649,17 @@ module('Acceptance | kv-v2 workflow | secret and version create', function (hook
const backend = this.backend; const backend = this.backend;
await visit(`/vault/secrets/${backend}/kv/list`); await visit(`/vault/secrets/${backend}/kv/list`);
assert.dom(PAGE.list.item()).exists({ count: 1 }, 'single secret exists on list'); assert.dom(PAGE.list.item()).exists({ count: 1 }, 'single secret exists on list');
assert.dom(PAGE.list.item('app/')).hasText('app/', 'expected list item'); assert.dom(`${PAGE.list.item('app/')} [data-test-path]`).hasText('app/', 'expected list item');
await click(PAGE.list.createSecret); await click(PAGE.list.createSecret);
await fillIn(FORM.inputByAttr('path'), 'jk'); await fillIn(FORM.inputByAttr('path'), 'jk');
await click(FORM.cancelBtn); await click(FORM.cancelBtn);
assert.dom(PAGE.list.item()).exists({ count: 1 }, 'same amount of secrets'); assert.dom(PAGE.list.item()).exists({ count: 1 }, 'same amount of secrets');
assert.dom(PAGE.list.item('app/')).hasText('app/', 'expected list item'); assert.dom(`${PAGE.list.item('app/')} [data-test-path]`).hasText('app/', 'expected list item');
await click(PAGE.list.createSecret); await click(PAGE.list.createSecret);
await fillIn(FORM.inputByAttr('path'), 'psych'); await fillIn(FORM.inputByAttr('path'), 'psych');
await click(PAGE.breadcrumbAtIdx(1)); await click(PAGE.breadcrumbAtIdx(1));
assert.dom(PAGE.list.item()).exists({ count: 1 }, 'same amount of secrets'); assert.dom(PAGE.list.item()).exists({ count: 1 }, 'same amount of secrets');
assert.dom(PAGE.list.item('app/')).hasText('app/', 'expected list item'); assert.dom(`${PAGE.list.item('app/')} [data-test-path]`).hasText('app/', 'expected list item');
}); });
test('cancel on new version rolls back model (mm)', async function (assert) { test('cancel on new version rolls back model (mm)', async function (assert) {
const backend = this.backend; const backend = this.backend;

View File

@@ -20,6 +20,7 @@ import { runCmd } from 'vault/tests/helpers/commands';
import { PAGE } from 'vault/tests/helpers/kv/kv-selectors'; import { PAGE } from 'vault/tests/helpers/kv/kv-selectors';
import codemirror from 'vault/tests/helpers/codemirror'; import codemirror from 'vault/tests/helpers/codemirror';
import { GENERAL } from 'vault/tests/helpers/general-selectors'; import { GENERAL } from 'vault/tests/helpers/general-selectors';
import { SECRET_ENGINE_SELECTORS as SS } from 'vault/tests/helpers/secret-engine/secret-engine-selectors';
const deleteEngine = async function (enginePath, assert) { const deleteEngine = async function (enginePath, assert) {
await logout.visit(); await logout.visit();
@@ -180,9 +181,8 @@ module('Acceptance | secrets/secret/create, read, delete', function (hooks) {
assert.dom('[data-test-secret-link]').exists({ count: 2 }); assert.dom('[data-test-secret-link]').exists({ count: 2 });
// delete the items // delete the items
await listPage.secrets.objectAt(0).menuToggle(); await click(SS.secretLinkMenu('1/2/3/4'));
await settled(); await click(SS.secretLinkMenuDelete('1/2/3/4'));
await listPage.delete();
await listPage.confirmDelete(); await listPage.confirmDelete();
await settled(); await settled();
assert.strictEqual(currentRouteName(), 'vault.cluster.secrets.backend.list'); assert.strictEqual(currentRouteName(), 'vault.cluster.secrets.backend.list');
@@ -219,7 +219,7 @@ module('Acceptance | secrets/secret/create, read, delete', function (hooks) {
'(', '(',
')', ')',
'"', '"',
//"'", // "'",
'!', '!',
'#', '#',
'$', '$',
@@ -243,8 +243,8 @@ module('Acceptance | secrets/secret/create, read, delete', function (hooks) {
await runCmd([...commands, 'refresh']); await runCmd([...commands, 'refresh']);
for (const path of paths) { for (const path of paths) {
await listPage.visit({ backend, id: path }); await listPage.visit({ backend, id: path });
assert.ok(listPage.secrets.filterBy('text', '2')[0], `${path}: secret is displayed properly`); assert.dom(SS.secretLinkATag()).hasText('2', `${path}: secret is displayed properly`);
await listPage.secrets.filterBy('text', '2')[0].click(); await click(SS.secretLink());
assert.strictEqual( assert.strictEqual(
currentRouteName(), currentRouteName(),
'vault.cluster.secrets.backend.show', 'vault.cluster.secrets.backend.show',
@@ -301,8 +301,8 @@ module('Acceptance | secrets/secret/create, read, delete', function (hooks) {
await listPage.create(); await listPage.create();
await editPage.createSecret(`${path}/2`, 'foo', 'bar'); await editPage.createSecret(`${path}/2`, 'foo', 'bar');
await listPage.visit({ backend, id: path }); await listPage.visit({ backend, id: path });
assert.ok(listPage.secrets.filterBy('text', '2')[0], `${path}: secret is displayed properly`); assert.dom(SS.secretLinkATag()).hasText('2', `${path}: secret is displayed properly`);
await listPage.secrets.filterBy('text', '2')[0].click(); await click(SS.secretLink());
assert.strictEqual( assert.strictEqual(
currentRouteName(), currentRouteName(),
'vault.cluster.secrets.backend.show', 'vault.cluster.secrets.backend.show',

View File

@@ -19,6 +19,11 @@ export const SECRET_ENGINE_SELECTORS = {
mountSubmit: '[data-test-mount-submit]', mountSubmit: '[data-test-mount-submit]',
secretHeader: '[data-test-secret-header]', secretHeader: '[data-test-secret-header]',
secretLink: (name: string) => (name ? `[data-test-secret-link="${name}"]` : '[data-test-secret-link]'), secretLink: (name: string) => (name ? `[data-test-secret-link="${name}"]` : '[data-test-secret-link]'),
secretLinkMenu: (name: string) => `[data-test-secret-link="${name}"] [data-test-popup-menu-trigger]`,
secretLinkMenuDelete: (name: string) =>
`[data-test-secret-link="${name}"] [data-test-confirm-action-trigger]`,
secretLinkATag: (name: string) =>
name ? `[data-test-secret-item-link="${name}"]` : '[data-test-secret-item-link]',
viewBackend: '[data-test-backend-view-link]', viewBackend: '[data-test-backend-view-link]',
warning: '[data-test-warning]', warning: '[data-test-warning]',
aws: { aws: {

View File

@@ -70,6 +70,7 @@ module('Integration | Component | kv | Page::List', function (hooks) {
@failedDirectoryQuery={{this.failedDirectoryQuery}} @failedDirectoryQuery={{this.failedDirectoryQuery}}
@breadcrumbs={{this.breadcrumbs}} @breadcrumbs={{this.breadcrumbs}}
@meta={{this.model.meta}} @meta={{this.model.meta}}
@currentRouteParams={{array this.backend}}
/>`, />`,
{ {
owner: this.engine, owner: this.engine,

View File

@@ -110,7 +110,9 @@ module('Integration | Component | ldap | Page::Roles', function (hooks) {
assert.dom('[data-test-delete]').hasText('Delete', 'Details link renders in menu'); assert.dom('[data-test-delete]').hasText('Delete', 'Details link renders in menu');
await click('[data-test-popup-menu-trigger]:last-of-type'); await click('[data-test-popup-menu-trigger]:last-of-type');
assert.dom('[data-test-rotate-creds]').doesNotExist('Rotate credentials link is hidden for dynamic type'); assert
.dom('[data-test-popup-menu-trigger]:last-of-type [data-test-rotate-creds]')
.doesNotExist('Rotate credentials link is hidden for dynamic type');
}); });
test('it should filter roles', async function (assert) { test('it should filter roles', async function (assert) {

View File

@@ -2029,7 +2029,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@embroider/addon-shim@npm:^1.0.0, @embroider/addon-shim@npm:^1.2.0, @embroider/addon-shim@npm:^1.6.0, @embroider/addon-shim@npm:^1.8.0, @embroider/addon-shim@npm:^1.8.3, @embroider/addon-shim@npm:^1.8.4, @embroider/addon-shim@npm:^1.8.6, @embroider/addon-shim@npm:^1.8.7, @embroider/addon-shim@npm:^1.8.9": "@embroider/addon-shim@npm:^1.0.0, @embroider/addon-shim@npm:^1.2.0, @embroider/addon-shim@npm:^1.6.0, @embroider/addon-shim@npm:^1.8.0, @embroider/addon-shim@npm:^1.8.3, @embroider/addon-shim@npm:^1.8.6, @embroider/addon-shim@npm:^1.8.7, @embroider/addon-shim@npm:^1.8.9":
version: 1.8.9 version: 1.8.9
resolution: "@embroider/addon-shim@npm:1.8.9" resolution: "@embroider/addon-shim@npm:1.8.9"
dependencies: dependencies:
@@ -2458,25 +2458,24 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@hashicorp/design-system-components@npm:~4.7.0": "@hashicorp/design-system-components@npm:~4.12.0":
version: 4.7.0 version: 4.12.0
resolution: "@hashicorp/design-system-components@npm:4.7.0" resolution: "@hashicorp/design-system-components@npm:4.12.0"
dependencies: dependencies:
"@ember/render-modifiers": ^2.0.5 "@ember/render-modifiers": ^2.0.5
"@ember/string": ^3.1.1 "@ember/string": ^3.1.1
"@ember/test-waiters": ^3.1.0 "@ember/test-waiters": ^3.1.0
"@embroider/addon-shim": ^1.8.7 "@embroider/addon-shim": ^1.8.7
"@floating-ui/dom": ^1.6.3 "@floating-ui/dom": ^1.6.3
"@hashicorp/design-system-tokens": ^2.1.0 "@hashicorp/design-system-tokens": ^2.2.1
"@hashicorp/ember-flight-icons": ^5.1.3 "@hashicorp/flight-icons": ^3.6.0
"@hashicorp/flight-icons": ^3.5.0
decorator-transforms: ^1.1.0 decorator-transforms: ^1.1.0
ember-a11y-refocus: ^4.1.0 ember-a11y-refocus: ^4.1.3
ember-cli-sass: ^11.0.1 ember-cli-sass: ^11.0.1
ember-composable-helpers: ^5.0.0 ember-composable-helpers: ^5.0.0
ember-element-helper: ^0.8.5 ember-element-helper: ^0.8.5
ember-focus-trap: ^1.1.0 ember-focus-trap: ^1.1.0
ember-keyboard: ^8.2.1 ember-get-config: ^2.1.1
ember-modifier: ^4.1.0 ember-modifier: ^4.1.0
ember-power-select: ^8.2.0 ember-power-select: ^8.2.0
ember-stargate: ^0.4.3 ember-stargate: ^0.4.3
@@ -2487,14 +2486,14 @@ __metadata:
tippy.js: ^6.3.7 tippy.js: ^6.3.7
peerDependencies: peerDependencies:
ember-source: ^3.28.0 || ^4.0.0 || ^5.3.0 ember-source: ^3.28.0 || ^4.0.0 || ^5.3.0
checksum: 88cafa21f11d761a226d9b065af715d632b1ea38699aac8294d035a7f7ab5518263c894813d0d4dc23f11dea440aaf6e58408531c7bbb3d9b2455a9dc9a9ba5c checksum: ed7c79a43e3b286b5a4d543064dc566159909bee7052700eebe160a93f99b64dfc41291cd4d81c5dd558b415fc9033bc8937b0d751b191283ce404c407d1388b
languageName: node languageName: node
linkType: hard linkType: hard
"@hashicorp/design-system-tokens@npm:^2.1.0": "@hashicorp/design-system-tokens@npm:^2.2.1":
version: 2.2.0 version: 2.2.1
resolution: "@hashicorp/design-system-tokens@npm:2.2.0" resolution: "@hashicorp/design-system-tokens@npm:2.2.1"
checksum: 654978be98a94c1f478e472793b9c1b62762bb30f9e0a097c2e1effd4fb2b4619eeef347e39599aea4dd63c451e0f41e698d887827ca2496de83a9e1e1dd8525 checksum: 0e4348ab27b2da4725068b5dab83474ad496895d2b422708b2c08cfc39289830f3756a1b352aff6e6095f64e3476ac227034ab02c7d2e0cc49d13a81ef69f6f3
languageName: node languageName: node
linkType: hard linkType: hard
@@ -2517,6 +2516,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@hashicorp/flight-icons@npm:^3.6.0":
version: 3.6.0
resolution: "@hashicorp/flight-icons@npm:3.6.0"
checksum: 5c09574c3e44b5662665271f4aaec8e9d50d0eecb858ba5e9d4d669baf0d98d0e875ce440d84ea7911bf81ff35a01440f79dd27cb78af706ca85341101d61073
languageName: node
linkType: hard
"@humanwhocodes/config-array@npm:^0.11.14": "@humanwhocodes/config-array@npm:^0.11.14":
version: 0.11.14 version: 0.11.14
resolution: "@humanwhocodes/config-array@npm:0.11.14" resolution: "@humanwhocodes/config-array@npm:0.11.14"
@@ -7445,13 +7451,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"ember-a11y-refocus@npm:^4.1.0": "ember-a11y-refocus@npm:^4.1.3":
version: 4.1.1 version: 4.1.4
resolution: "ember-a11y-refocus@npm:4.1.1" resolution: "ember-a11y-refocus@npm:4.1.4"
dependencies: dependencies:
ember-cli-babel: ^7.26.11 ember-cli-babel: ^7.26.11
ember-cli-htmlbars: ^6.0.1 ember-cli-htmlbars: ^6.0.1
checksum: b9f861f1359e8c720bf844161da3eecbe2218149739211961d216b6fcaec5e78dfd51debe5ec2707ae0d31fdbbd9cf692349e3f0f5b47d1f12bd963c021494ac checksum: c1a79f9b7792f3bac674e010b231561da4ca5fc2f3f6a9a6e2263908a6c781546e1baccdb84838f367ac9104e2c76b7f688a57f06f0bd6c194a6f1a71910e422
languageName: node languageName: node
linkType: hard linkType: hard
@@ -8283,7 +8289,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"ember-destroyable-polyfill@npm:^2.0.1, ember-destroyable-polyfill@npm:^2.0.3": "ember-destroyable-polyfill@npm:^2.0.1":
version: 2.0.3 version: 2.0.3
resolution: "ember-destroyable-polyfill@npm:2.0.3" resolution: "ember-destroyable-polyfill@npm:2.0.3"
dependencies: dependencies:
@@ -8425,23 +8431,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"ember-keyboard@npm:^8.2.1":
version: 8.2.1
resolution: "ember-keyboard@npm:8.2.1"
dependencies:
"@embroider/addon-shim": ^1.8.4
ember-destroyable-polyfill: ^2.0.3
ember-modifier: ^2.1.2 || ^3.1.0 || ^4.0.0
ember-modifier-manager-polyfill: ^1.2.0
peerDependencies:
"@ember/test-helpers": ^2.6.0 || ^3.0.0
peerDependenciesMeta:
"@ember/test-helpers":
optional: true
checksum: cfb4120aaf3b1ff3aba8ba1619b0597c6738abde31d1e0719d8bbf69512fb9967fc76bc85557351ec42856bb9b6c47354634f22f0accab0e15743d9f0e3f2be4
languageName: node
linkType: hard
"ember-lifeline@npm:^7.0.0": "ember-lifeline@npm:^7.0.0":
version: 7.0.0 version: 7.0.0
resolution: "ember-lifeline@npm:7.0.0" resolution: "ember-lifeline@npm:7.0.0"
@@ -8497,7 +8486,20 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"ember-modifier@npm:^2.1.2 || ^3.1.0 || ^4.0.0, ember-modifier@npm:^3.2.7 || ^4.0.0, ember-modifier@npm:^4.1.0": "ember-modifier@npm:^3.2.0, ember-modifier@npm:^3.2.7":
version: 3.2.7
resolution: "ember-modifier@npm:3.2.7"
dependencies:
ember-cli-babel: ^7.26.6
ember-cli-normalize-entity-name: ^1.0.0
ember-cli-string-utils: ^1.1.0
ember-cli-typescript: ^5.0.0
ember-compatibility-helpers: ^1.2.5
checksum: 2e96d9ec3939de178a9ce704d5a9360fd73f0276ffa4a9cce9f100a4087fdc8fae4a8b28bf1be22b05a4d1c61e1bb1ab93ca60576810c6556bc4d9323864c66a
languageName: node
linkType: hard
"ember-modifier@npm:^3.2.7 || ^4.0.0, ember-modifier@npm:^4.1.0":
version: 4.2.0 version: 4.2.0
resolution: "ember-modifier@npm:4.2.0" resolution: "ember-modifier@npm:4.2.0"
dependencies: dependencies:
@@ -8514,19 +8516,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"ember-modifier@npm:^3.2.0, ember-modifier@npm:^3.2.7":
version: 3.2.7
resolution: "ember-modifier@npm:3.2.7"
dependencies:
ember-cli-babel: ^7.26.6
ember-cli-normalize-entity-name: ^1.0.0
ember-cli-string-utils: ^1.1.0
ember-cli-typescript: ^5.0.0
ember-compatibility-helpers: ^1.2.5
checksum: 2e96d9ec3939de178a9ce704d5a9360fd73f0276ffa4a9cce9f100a4087fdc8fae4a8b28bf1be22b05a4d1c61e1bb1ab93ca60576810c6556bc4d9323864c66a
languageName: node
linkType: hard
"ember-page-title@npm:^8.0.0": "ember-page-title@npm:^8.0.0":
version: 8.2.3 version: 8.2.3
resolution: "ember-page-title@npm:8.2.3" resolution: "ember-page-title@npm:8.2.3"
@@ -18776,7 +18765,7 @@ __metadata:
"@ember/test-waiters": ^3.1.0 "@ember/test-waiters": ^3.1.0
"@glimmer/component": ^1.1.2 "@glimmer/component": ^1.1.2
"@glimmer/tracking": ^1.1.2 "@glimmer/tracking": ^1.1.2
"@hashicorp/design-system-components": ~4.7.0 "@hashicorp/design-system-components": ~4.12.0
"@hashicorp/ember-flight-icons": ^5.1.3 "@hashicorp/ember-flight-icons": ^5.1.3
"@icholy/duration": ^5.1.0 "@icholy/duration": ^5.1.0
"@lineal-viz/lineal": ^0.5.1 "@lineal-viz/lineal": ^0.5.1