mirror of
https://github.com/hashicorp/vault.git
synced 2026-05-05 04:16:31 +02:00
UI: HDS adoption replace <ConfirmAction> component (#21520)
* replace confirm-action dropdown with button+modal * add modal frame to sidebar * fix weird paragraph indent * pass button text as arg * add warning color to rotate modals * update seal action and config ssh * cleanup confirm action * edit form * add dropdown arg * put back seal text * put back confirm button text * fix toolbar stylinggp * popup member group * move up title * finish popup- components * keymgmt * fix modal button logic * remaining app template components * add period for angel * vault cluster items * add button text assertion * remaining instances * remove arg for passing confirm text * contextual confirm action components * delete old components * update docs * ammend dropdown loading states, add getter for confirm button color * address feedback * remove @disabled arg and add @disabledMessage * add changelog; * mfa tests * update test selectors * lol cleanup selectors * start confirm action tests WIP * move dropdown class directly to component * add default color of isInDropdown * final cleanup * add tests * remove @buttonColor as arg for dropdown * update confirm action tests * updae modals with disabled message * refactor provider edit test
This commit is contained in:
parent
24f5807da4
commit
4ac07e1d97
3
changelog/21520.txt
Normal file
3
changelog/21520.txt
Normal file
@ -0,0 +1,3 @@
|
||||
```release-note:improvement
|
||||
ui: Replace inline confirm alert inside a popup-menu dropdown with confirm alert modal
|
||||
```
|
||||
@ -21,14 +21,10 @@
|
||||
|
||||
<div class="field is-grouped box is-fullwidth is-bottomless">
|
||||
<ConfirmAction
|
||||
@buttonClasses="button is-primary"
|
||||
@buttonText="Seal"
|
||||
@confirmTitle="Seal this cluster?"
|
||||
@confirmMessage="You will not be able to read or write any data until the cluster is unsealed again."
|
||||
@confirmButtonText="Seal"
|
||||
@horizontalPosition="auto-left"
|
||||
@onConfirmAction={{this.handleSeal}}
|
||||
data-test-seal
|
||||
>
|
||||
Seal
|
||||
</ConfirmAction>
|
||||
/>
|
||||
</div>
|
||||
@ -15,83 +15,78 @@
|
||||
<Hds::SideNav::Header::IconButton @icon="user" @ariaLabel="User menu" />
|
||||
</Dropdown.Trigger>
|
||||
<Dropdown.Content>
|
||||
<Confirm as |c|>
|
||||
<div class="popup-menu-content" data-test-user-menu-content>
|
||||
<div class="box">
|
||||
<div class="menu-label">
|
||||
{{capitalize this.auth.authData.displayName}}
|
||||
</div>
|
||||
<nav class="menu">
|
||||
<ul class="menu-list">
|
||||
{{#if this.auth.allowExpiration}}
|
||||
<li class="token-alert is-flex" data-test-user-menu-item="token alert">
|
||||
<span><Icon @name="alert-triangle-fill" class="has-text-highlight" /></span>
|
||||
<span class="is-size-8 has-text-semibold">
|
||||
We've stopped auto-renewing your token due to inactivity. It will expire on
|
||||
{{date-format this.auth.tokenExpirationDate "MMMM do yyyy, h:mm:ss a"}}.
|
||||
</span>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if this.hasEntityId}}
|
||||
<li class="action">
|
||||
<LinkTo @route="vault.cluster.mfa-setup" data-test-user-menu-item="mfa">
|
||||
Multi-factor authentication
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if this.isUserpass}}
|
||||
<li class="action">
|
||||
<LinkTo @route="vault.cluster.access.reset-password" data-test-user-menu-item="reset-password">
|
||||
Reset password
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
<li class="action" id="container">
|
||||
{{! container is required in navbar collapsed state }}
|
||||
<Hds::Copy::Button
|
||||
@text="Copy token"
|
||||
@textToCopy={{this.auth.currentToken}}
|
||||
@isFullWidth={{true}}
|
||||
@container="#container"
|
||||
class="in-dropdown link is-flex-start"
|
||||
{{on "click" (fn (set-flash-message "Token copied!"))}}
|
||||
/>
|
||||
<div class="popup-menu-content" data-test-user-menu-content>
|
||||
<div class="box">
|
||||
<div class="menu-label">
|
||||
{{capitalize this.auth.authData.displayName}}
|
||||
</div>
|
||||
<nav class="menu">
|
||||
<ul class="menu-list">
|
||||
{{#if this.auth.allowExpiration}}
|
||||
<li class="token-alert is-flex" data-test-user-menu-item="token alert">
|
||||
<span><Icon @name="alert-triangle-fill" class="has-text-highlight" /></span>
|
||||
<span class="is-size-8 has-text-semibold">
|
||||
We've stopped auto-renewing your token due to inactivity. It will expire on
|
||||
{{date-format this.auth.tokenExpirationDate "MMMM do yyyy, h:mm:ss a"}}.
|
||||
</span>
|
||||
</li>
|
||||
{{#if (is-before (now interval=1000) this.auth.tokenExpirationDate)}}
|
||||
{{#if this.auth.authData.renewable}}
|
||||
<li class="action">
|
||||
{{! TODO Hds::Button replacement skipped in favor of updating it when there is a Hds::Dropdown swapout }}
|
||||
<button
|
||||
type="button"
|
||||
{{on "click" this.renewToken}}
|
||||
class="link button {{if this.isRenewing 'is-loading'}}"
|
||||
data-test-user-menu-item="renew token"
|
||||
>
|
||||
Renew token
|
||||
</button>
|
||||
</li>
|
||||
{{/if}}
|
||||
<li class="action">
|
||||
<c.Message
|
||||
@id={{get this.auth "authData.displayName"}}
|
||||
@title={{concat "Revoke " (get this.auth "authData.displayName") "?"}}
|
||||
@onConfirm={{action "revokeToken"}}
|
||||
@message="You will not be able to log in again with this token."
|
||||
@triggerText="Revoke token"
|
||||
@confirmButtonText="Revoke"
|
||||
data-test-user-menu-item="revoke token"
|
||||
/>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if this.hasEntityId}}
|
||||
<li class="action">
|
||||
<LinkTo @route="vault.cluster.logout" @model={{this.currentCluster.cluster.name}} id="logout">
|
||||
Log out
|
||||
<LinkTo @route="vault.cluster.mfa-setup" data-test-user-menu-item="mfa">
|
||||
Multi-factor authentication
|
||||
</LinkTo>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if this.isUserpass}}
|
||||
<li class="action">
|
||||
<LinkTo @route="vault.cluster.access.reset-password" data-test-user-menu-item="reset-password">
|
||||
Reset password
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
<li class="action" id="container">
|
||||
{{! container is required in navbar collapsed state }}
|
||||
<Hds::Copy::Button
|
||||
@text="Copy token"
|
||||
@textToCopy={{this.auth.currentToken}}
|
||||
@isFullWidth={{true}}
|
||||
@container="#container"
|
||||
class="in-dropdown link is-flex-start"
|
||||
{{on "click" (fn (set-flash-message "Token copied!"))}}
|
||||
/>
|
||||
</li>
|
||||
{{#if (is-before (now interval=1000) this.auth.tokenExpirationDate)}}
|
||||
{{#if this.auth.authData.renewable}}
|
||||
<li class="action">
|
||||
{{! TODO Hds::Button replacement skipped in favor of updating it when there is a Hds::Dropdown swapout }}
|
||||
<button
|
||||
type="button"
|
||||
{{on "click" this.renewToken}}
|
||||
class="link button {{if this.isRenewing 'is-loading'}}"
|
||||
data-test-user-menu-item="renew token"
|
||||
>
|
||||
Renew token
|
||||
</button>
|
||||
</li>
|
||||
{{/if}}
|
||||
<ConfirmAction
|
||||
@isInDropdown={{true}}
|
||||
@confirmTitle="Revoke {{get this.auth 'authData.displayName'}}?"
|
||||
@onConfirmAction={{action "revokeToken"}}
|
||||
@buttonText="Revoke token"
|
||||
@confirmMessage="You will not be able to log in again with this token."
|
||||
data-test-user-menu-item="revoke token"
|
||||
/>
|
||||
{{/if}}
|
||||
<li class="action">
|
||||
<LinkTo @route="vault.cluster.logout" @model={{this.currentCluster.cluster.name}} id="logout">
|
||||
Log out
|
||||
</LinkTo>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</Confirm>
|
||||
</div>
|
||||
</Dropdown.Content>
|
||||
</BasicDropdown>
|
||||
@ -1,139 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
.confirm-wrapper {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border-radius: $radius;
|
||||
box-shadow: $box-shadow, $box-shadow-middle;
|
||||
}
|
||||
|
||||
.confirm {
|
||||
transition: transform $speed;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.show-confirm {
|
||||
transform: translateX(-100%);
|
||||
transition: transform $speed;
|
||||
}
|
||||
|
||||
.confirm.show-confirm {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.confirm-overlay {
|
||||
position: absolute;
|
||||
background-color: white;
|
||||
top: 0;
|
||||
left: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.confirm,
|
||||
.confirm-overlay {
|
||||
button.link,
|
||||
a {
|
||||
background-color: $white;
|
||||
color: $grey-darkest;
|
||||
|
||||
&:hover {
|
||||
background-color: $ui-gray-050;
|
||||
color: $ui-gray-900;
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
background-color: $blue-500;
|
||||
color: $blue;
|
||||
}
|
||||
|
||||
&.is-destroy {
|
||||
color: $red;
|
||||
|
||||
&:hover {
|
||||
background-color: $red;
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.5;
|
||||
|
||||
&:hover {
|
||||
background: transparent;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.confirm-action span .button {
|
||||
display: block;
|
||||
margin: 0.25rem auto;
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
.confirm-action > span {
|
||||
@include from($mobile) {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
* {
|
||||
margin-left: $spacing-12;
|
||||
}
|
||||
|
||||
.confirm-action-text:not(.is-block) {
|
||||
text-align: right;
|
||||
|
||||
@include until($mobile) {
|
||||
display: block;
|
||||
margin-bottom: $spacing-12;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
.confirm-action-text.is-block {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
.confirm-action-message {
|
||||
margin: 0;
|
||||
|
||||
.message {
|
||||
border: 0;
|
||||
font-size: $size-8;
|
||||
line-height: 1.33;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.message-title {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.hs-icon {
|
||||
color: $yellow;
|
||||
}
|
||||
|
||||
p {
|
||||
font-weight: $font-weight-semibold;
|
||||
margin-left: $spacing-24;
|
||||
padding-left: $spacing-4;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.confirm-action-options {
|
||||
border-top: $light-border;
|
||||
display: flex;
|
||||
padding: $spacing-4;
|
||||
|
||||
.link {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
width: auto;
|
||||
padding: $spacing-8;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -48,6 +48,19 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// TODO HDS polish - temp styling fix for ConfirmAction dropdown buttons
|
||||
// so they match other dropdown elements until we replace popup-menu with Hds::Dropdown
|
||||
.hds-confirm-action-critical {
|
||||
&:hover {
|
||||
background-color: $ui-gray-050;
|
||||
}
|
||||
div {
|
||||
margin-left: -$spacing-4;
|
||||
font-size: $size-7;
|
||||
font-weight: $font-weight-semibold;
|
||||
}
|
||||
}
|
||||
|
||||
button.link,
|
||||
.ember-power-select-option,
|
||||
.ember-power-select-option[aria-current='true'],
|
||||
|
||||
@ -61,7 +61,6 @@
|
||||
@import './components/calendar-widget';
|
||||
@import './components/cluster-banners';
|
||||
@import './components/codemirror';
|
||||
@import './components/confirm';
|
||||
@import './components/console-ui-panel';
|
||||
@import './components/control-group';
|
||||
@import './components/doc-link';
|
||||
|
||||
@ -22,18 +22,15 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="field is-grouped-split box is-fullwidth is-bottomless">
|
||||
<div class="control">
|
||||
<Hds::ButtonSet>
|
||||
<Hds::Copy::Button @text="Copy" @textToCopy={{@model.publicKey}} class="primary" />
|
||||
</div>
|
||||
<div class="control">
|
||||
<ConfirmAction
|
||||
@buttonClasses="button"
|
||||
@buttonText="Delete"
|
||||
@buttonColor="secondary"
|
||||
@confirmMessage="This will remove the CA certificate information."
|
||||
@onConfirmAction={{this.delete}}
|
||||
>
|
||||
Delete
|
||||
</ConfirmAction>
|
||||
</div>
|
||||
/>
|
||||
</Hds::ButtonSet>
|
||||
</div>
|
||||
{{else}}
|
||||
<form {{on "submit" this.saveConfig}} data-test-ssh-configure-form="true">
|
||||
|
||||
@ -35,15 +35,14 @@
|
||||
{{/if}}
|
||||
{{#if @model.canReset}}
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
@buttonText="Reset connection"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{action "reset"}}
|
||||
@confirmTitle="Reset connection?"
|
||||
@confirmMessage="This will close the connection and its underlying plugin and restart it with the configuration stored in the barrier."
|
||||
@confirmButtonText="Reset"
|
||||
data-test-database-connection-reset
|
||||
>
|
||||
Reset connection
|
||||
</ConfirmAction>
|
||||
/>
|
||||
{{/if}}
|
||||
{{#if (or @model.canReset @model.canDelete)}}
|
||||
<div class="toolbar-separator"></div>
|
||||
@ -51,15 +50,15 @@
|
||||
{{#if @model.canRotateRoot}}
|
||||
{{! template-lint-disable quotes }}
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
@buttonText="Rotate root credentials"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{this.rotate}}
|
||||
@confirmTitle="Rotate credentials?"
|
||||
@confirmMessage='This will rotate the "root" user credentials stored for the database connection. The password will not be accessible once rotated.'
|
||||
@confirmButtonText="Rotate"
|
||||
@modalColor="warning"
|
||||
data-test-database-connection-rotate
|
||||
>
|
||||
Rotate root credentials
|
||||
</ConfirmAction>
|
||||
/>
|
||||
{{! template-lint-enable }}
|
||||
{{/if}}
|
||||
{{#if @model.canAddRole}}
|
||||
|
||||
@ -25,15 +25,14 @@
|
||||
<ToolbarActions>
|
||||
{{#if @model.canDelete}}
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
@buttonText="Delete role"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{action "delete"}}
|
||||
@confirmTitle="Delete role?"
|
||||
@confirmMessage="This role will be permanently deleted. You will need to recreate it to use it again."
|
||||
@confirmButtonText="Delete"
|
||||
data-test-database-role-delete
|
||||
>
|
||||
Delete role
|
||||
</ConfirmAction>
|
||||
/>
|
||||
<div class="toolbar-separator"></div>
|
||||
{{/if}}
|
||||
{{#if (and @model.canRotateRoleCredentials (eq @model.type "static"))}}
|
||||
|
||||
@ -75,7 +75,7 @@
|
||||
<Item.content>
|
||||
<Icon @name="folder" class="has-text-grey-light" />{{list.item.id}}
|
||||
</Item.content>
|
||||
<Item.menu as |Menu|>
|
||||
<Item.menu>
|
||||
<li class="action">
|
||||
<LinkTo @route="vault.cluster.access.method.item.show" @model={{list.item.id}} class="is-block">
|
||||
View
|
||||
@ -88,25 +88,22 @@
|
||||
{{singularize this.itemType}}
|
||||
</LinkTo>
|
||||
</li>
|
||||
<li>
|
||||
<Menu.Message
|
||||
@id={{list.item.id}}
|
||||
@buttonClasses="link is-destroy"
|
||||
@onConfirm={{action
|
||||
(perform
|
||||
Item.callMethod
|
||||
"destroyRecord"
|
||||
list.item
|
||||
(concat "Successfully deleted " (singularize this.itemType) " " list.item.id ".")
|
||||
(concat "There was an error deleting this " (singularize this.itemType))
|
||||
(action "refreshItemList")
|
||||
)
|
||||
}}
|
||||
@message={{concat "Are you sure you want to delete " (singularize this.itemType) " " list.item.id "?"}}
|
||||
data-test-secret-delete="true"
|
||||
@triggerText={{concat "Delete " (singularize this.itemType)}}
|
||||
/>
|
||||
</li>
|
||||
<ConfirmAction
|
||||
@isInDropdown={{true}}
|
||||
@onConfirmAction={{action
|
||||
(perform
|
||||
Item.callMethod
|
||||
"destroyRecord"
|
||||
list.item
|
||||
(concat "Successfully deleted " (singularize this.itemType) " " list.item.id ".")
|
||||
(concat "There was an error deleting this " (singularize this.itemType))
|
||||
(action "refreshItemList")
|
||||
)
|
||||
}}
|
||||
@confirmTitle="Delete {{singularize this.itemType}}?"
|
||||
@confirmMessage="Are you sure you want to delete {{singularize this.itemType}} {{list.item.id}}?"
|
||||
@buttonText="Delete {{singularize this.itemType}}"
|
||||
/>
|
||||
</Item.menu>
|
||||
</ListItem>
|
||||
{{/if}}
|
||||
|
||||
@ -38,15 +38,12 @@
|
||||
<Toolbar>
|
||||
<ToolbarActions>
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
@buttonText="Delete {{this.itemType}}"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{action "deleteItem"}}
|
||||
@confirmMessage={{concat "Are you sure you want to delete " this.itemType " " this.model.id "?"}}
|
||||
@cancelButtonText="Cancel"
|
||||
data-test-secret-delete="true"
|
||||
>
|
||||
Delete
|
||||
{{this.itemType}}
|
||||
</ConfirmAction>
|
||||
@confirmMessage="Are you sure you want to delete {{this.itemType}} {{this.model.id}}?"
|
||||
/>
|
||||
<div class="toolbar-separator"></div>
|
||||
<ToolbarLink
|
||||
@route="vault.cluster.access.method.item.edit"
|
||||
|
||||
@ -7,13 +7,13 @@
|
||||
<Toolbar>
|
||||
<ToolbarActions>
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@buttonText="Delete {{this.model.identityType}}"
|
||||
@confirmTitle="Delete this {{this.model.identityType}}?"
|
||||
@onConfirmAction={{action "deleteItem" this.model}}
|
||||
data-test-entity-item-delete="true"
|
||||
>
|
||||
Delete
|
||||
{{this.model.identityType}}
|
||||
</ConfirmAction>
|
||||
/>
|
||||
</ToolbarActions>
|
||||
</Toolbar>
|
||||
{{/if}}
|
||||
|
||||
@ -4,41 +4,42 @@
|
||||
~}}
|
||||
|
||||
<PopupMenu @name="alias-menu">
|
||||
<Confirm as |c|>
|
||||
{{#let (get this.params "0") as |item|}}
|
||||
<nav class="menu">
|
||||
<ul class="menu-list">
|
||||
{{#let (get this.params "0") as |item|}}
|
||||
<nav class="menu">
|
||||
<ul class="menu-list">
|
||||
<li class="action">
|
||||
<LinkTo
|
||||
@route="vault.cluster.access.identity.aliases.show"
|
||||
@models={{array (pluralize item.parentType) item.id "details"}}
|
||||
>
|
||||
Details
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{#if item.updatePath.isPending}}
|
||||
<li class="action">
|
||||
<LinkTo
|
||||
@route="vault.cluster.access.identity.aliases.show"
|
||||
@models={{array (pluralize item.parentType) item.id "details"}}
|
||||
>
|
||||
Details
|
||||
</LinkTo>
|
||||
<LoadingDropdownOption />
|
||||
</li>
|
||||
{{#if item.updatePath.isPending}}
|
||||
{{else}}
|
||||
{{#if item.canEdit}}
|
||||
<li class="action">
|
||||
<LoadingDropdownOption />
|
||||
<LinkTo
|
||||
@route="vault.cluster.access.identity.aliases.edit"
|
||||
@models={{array (pluralize item.parentType) item.id}}
|
||||
>
|
||||
Edit
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{else}}
|
||||
{{#if item.canEdit}}
|
||||
<li class="action">
|
||||
<LinkTo
|
||||
@route="vault.cluster.access.identity.aliases.edit"
|
||||
@models={{array (pluralize item.parentType) item.id}}
|
||||
>
|
||||
Edit
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if item.canDelete}}
|
||||
<li class="action">
|
||||
<c.Message @id={{item.id}} @onConfirm={{action "performTransaction" item}} data-test-item-delete />
|
||||
</li>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</ul>
|
||||
</nav>
|
||||
{{/let}}
|
||||
</Confirm>
|
||||
{{#if item.canDelete}}
|
||||
<ConfirmAction
|
||||
@buttonText="Delete"
|
||||
@isInDropdown={{true}}
|
||||
@onConfirmAction={{action "performTransaction" item}}
|
||||
data-test-item-delete
|
||||
/>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</ul>
|
||||
</nav>
|
||||
{{/let}}
|
||||
</PopupMenu>
|
||||
@ -8,13 +8,12 @@
|
||||
<ul class="menu-list">
|
||||
<li class="action">
|
||||
<ConfirmAction
|
||||
@buttonClasses="link is-destroy"
|
||||
@confirmButtonText="Remove this group?"
|
||||
@buttonText="Remove"
|
||||
@confirmTitle="Remove this group?"
|
||||
@isInDropdown={{true}}
|
||||
@confirmMessage="This may affect permissions for this group."
|
||||
@onConfirmAction={{action "performTransaction" this.model this.groupArray this.memberId}}
|
||||
>
|
||||
Remove
|
||||
</ConfirmAction>
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
@ -8,14 +8,12 @@
|
||||
<ul class="menu-list">
|
||||
<li class="action">
|
||||
<ConfirmAction
|
||||
@buttonClasses="link is-destroy"
|
||||
@buttonText="Remove"
|
||||
@confirmTitle="Remove metadata?"
|
||||
@isInDropdown={{true}}
|
||||
@confirmMessage="This data may be used outside of Vault."
|
||||
@confirmButtonText="Remove"
|
||||
@onConfirmAction={{action "performTransaction" this.model this.key}}
|
||||
>
|
||||
Remove
|
||||
</ConfirmAction>
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
@ -18,14 +18,12 @@
|
||||
</li>
|
||||
<li class="action">
|
||||
<ConfirmAction
|
||||
@buttonClasses="link is-destroy"
|
||||
@confirmButtonText="Remove"
|
||||
@buttonText="Remove from {{this.model.identityType}}"
|
||||
@confirmTitle="Remove this policy?"
|
||||
@isInDropdown={{true}}
|
||||
@confirmMessage="This policy may affect permissions to access Vault data."
|
||||
@onConfirmAction={{action "performTransaction" this.model this.policyName}}
|
||||
>
|
||||
Remove from
|
||||
{{this.model.identityType}}
|
||||
</ConfirmAction>
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
@ -75,31 +75,31 @@
|
||||
{{/if}}
|
||||
{{#if @model.provider}}
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
class="toolbar-button"
|
||||
@buttonText="Remove key"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{perform this.removeKey}}
|
||||
@confirmTitle="Remove this key?"
|
||||
@confirmMessage="This will remove all versions of the key from the KMS provider. The key will stay in Vault."
|
||||
@confirmButtonText="Remove"
|
||||
@isRunning={{this.removeKey.isRunning}}
|
||||
data-test-keymgmt-key-remove
|
||||
>
|
||||
Remove key
|
||||
</ConfirmAction>
|
||||
/>
|
||||
{{/if}}
|
||||
{{#if (or @model.canDelete @model.provider)}}
|
||||
<div class="toolbar-separator"></div>
|
||||
{{/if}}
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
@buttonText="Rotate key"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@modalColor="warning"
|
||||
@onConfirmAction={{perform this.rotateKey}}
|
||||
@confirmTitle="Rotate this key?"
|
||||
@confirmMessage="After rotation, all key actions will default to using the newest version of the key."
|
||||
@confirmButtonText="Rotate"
|
||||
@color="warning"
|
||||
@isRunning={{this.rotateKey.isRunning}}
|
||||
data-test-keymgmt-key-rotate
|
||||
>
|
||||
Rotate key
|
||||
</ConfirmAction>
|
||||
/>
|
||||
{{#if @model.canEdit}}
|
||||
<ToolbarSecretLink
|
||||
@secret={{@model.id}}
|
||||
|
||||
@ -47,27 +47,22 @@
|
||||
<Toolbar data-test-kms-provider-details-actions>
|
||||
<ToolbarActions>
|
||||
{{#if @model.canDelete}}
|
||||
<ToolTip @verticalPosition="above" @horizontalPosition="center" as |T|>
|
||||
<T.Trigger data-test-tooltip-trigger>
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
@onConfirmAction={{this.onDelete}}
|
||||
@disabled={{@model.keys.length}}
|
||||
data-test-kms-provider-delete={{true}}
|
||||
>
|
||||
Delete provider
|
||||
</ConfirmAction>
|
||||
</T.Trigger>
|
||||
{{#if @model.keys.length}}
|
||||
<T.Content class="tool-tip">
|
||||
<div class="box" data-test-kms-provider-delete-tooltip>
|
||||
This provider cannot be deleted until all
|
||||
{{@model.keys.length}}
|
||||
key(s) distributed to it are revoked. This can be done from the Keys tab.
|
||||
</div>
|
||||
</T.Content>
|
||||
{{/if}}
|
||||
</ToolTip>
|
||||
<ConfirmAction
|
||||
@buttonText="Delete provider"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@confirmTitle="Delete this provider?"
|
||||
@onConfirmAction={{this.onDelete}}
|
||||
@disabledMessage={{if
|
||||
@model.keys.length
|
||||
(concat
|
||||
"This provider cannot be deleted until all "
|
||||
@model.keys.length
|
||||
" key(s) distributed to it are revoked. This can be done from the Keys tab."
|
||||
)
|
||||
}}
|
||||
data-test-kms-provider-delete
|
||||
/>
|
||||
{{/if}}
|
||||
{{#if (and @model.canDelete (or @model.canListKeys @model.canEdit))}}
|
||||
<div class="toolbar-separator"></div>
|
||||
|
||||
@ -78,6 +78,7 @@
|
||||
{{/each}}
|
||||
<div class="is-flex-row {{if this.targets 'has-top-padding-s has-border-top-light'}}">
|
||||
<Select
|
||||
class="is-marginless"
|
||||
@options={{this.targetTypes}}
|
||||
@labelAttribute="label"
|
||||
@valueAttribute="type"
|
||||
@ -128,7 +129,7 @@
|
||||
/>
|
||||
</div>
|
||||
{{#if this.errors.targets.errors}}
|
||||
<AlertInline @type="danger" @message={{join ", " this.errors.targets.errors}} />
|
||||
<AlertInline class="has-top-padding-s" @type="danger" @message={{join ", " this.errors.targets.errors}} />
|
||||
{{/if}}
|
||||
</div>
|
||||
{{#unless @isInline}}
|
||||
|
||||
@ -81,22 +81,17 @@
|
||||
</td>
|
||||
<td class="middle no-padding has-text-right">
|
||||
<PopupMenu>
|
||||
<Confirm as |c|>
|
||||
<nav aria-label="remove peer">
|
||||
<ul>
|
||||
<li class="action">
|
||||
<c.Message
|
||||
@id={{server.nodeId}}
|
||||
@onConfirm={{action "removePeer" server}}
|
||||
@triggerText="Remove Peer"
|
||||
@confirmButtonText="Remove"
|
||||
@title={{concat "Remove " server.nodeId "?"}}
|
||||
@message="This will remove the server from the raft cluster."
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</Confirm>
|
||||
<nav aria-label="remove peer">
|
||||
<ul>
|
||||
<ConfirmAction
|
||||
@isInDropdown={{true}}
|
||||
@onConfirmAction={{action "removePeer" server}}
|
||||
@buttonText="Remove Peer"
|
||||
@confirmTitle="Remove {{server.nodeId}}?"
|
||||
@confirmMessage="This will remove the server from the raft cluster."
|
||||
/>
|
||||
</ul>
|
||||
</nav>
|
||||
</PopupMenu>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@ -32,9 +32,12 @@
|
||||
<Toolbar>
|
||||
<ToolbarActions>
|
||||
{{#if this.model.canDelete}}
|
||||
<ConfirmAction @buttonClasses="toolbar-link" @onConfirmAction={{action "delete"}}>
|
||||
Delete role
|
||||
</ConfirmAction>
|
||||
<ConfirmAction
|
||||
@buttonText="Delete role"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{action "delete"}}
|
||||
/>
|
||||
<div class="toolbar-separator"></div>
|
||||
{{/if}}
|
||||
{{#if this.model.canGenerate}}
|
||||
|
||||
@ -31,9 +31,12 @@
|
||||
<Toolbar>
|
||||
<ToolbarActions>
|
||||
{{#if this.model.canDelete}}
|
||||
<ConfirmAction @buttonClasses="toolbar-link" @onConfirmAction={{action "delete"}}>
|
||||
Delete role
|
||||
</ConfirmAction>
|
||||
<ConfirmAction
|
||||
@buttonText="Delete role"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{action "delete"}}
|
||||
/>
|
||||
<div class="toolbar-separator"></div>
|
||||
{{/if}}
|
||||
{{#if (eq this.model.keyType "otp")}}
|
||||
|
||||
@ -20,14 +20,14 @@
|
||||
<ToolbarActions>
|
||||
{{#if (and (eq @mode "show") @model.canDelete)}}
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
@buttonText="Delete"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@confirmTitle="Delete secret?"
|
||||
@confirmMessage="You will not be able to recover this secret data later."
|
||||
@onConfirmAction={{this.handleDelete}}
|
||||
data-test-secret-v1-delete="true"
|
||||
>
|
||||
Delete
|
||||
</ConfirmAction>
|
||||
data-test-secret-v1-delete
|
||||
/>
|
||||
<div class="toolbar-separator"></div>
|
||||
{{/if}}
|
||||
{{#if (and (eq @mode "show") @canUpdateSecret)}}
|
||||
|
||||
@ -24,55 +24,56 @@
|
||||
</div>
|
||||
<div class="column has-text-right">
|
||||
<PopupMenu @name="role-aws-nav" @contentClass="is-wide">
|
||||
<Confirm as |c|>
|
||||
<nav class="menu">
|
||||
<ul class="menu-list">
|
||||
{{#if @item.generatePath.isPending}}
|
||||
<nav class="menu">
|
||||
<ul class="menu-list">
|
||||
{{#if @item.generatePath.isPending}}
|
||||
<li class="action">
|
||||
<LoadingDropdownOption />
|
||||
</li>
|
||||
{{else if @item.canGenerate}}
|
||||
<li class="action">
|
||||
<LinkTo
|
||||
@route="vault.cluster.secrets.backend.credentials"
|
||||
@model={{@item.id}}
|
||||
data-test-role-aws-link="generate"
|
||||
>
|
||||
Generate credentials
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if @item.updatePath.isPending}}
|
||||
<li class="action">
|
||||
<LoadingDropdownOption />
|
||||
</li>
|
||||
<li class="action">
|
||||
<LoadingDropdownOption />
|
||||
</li>
|
||||
{{else}}
|
||||
{{#if @item.canRead}}
|
||||
<li class="action">
|
||||
<LoadingDropdownOption />
|
||||
</li>
|
||||
{{else if @item.canGenerate}}
|
||||
<li class="action">
|
||||
<LinkTo
|
||||
@route="vault.cluster.secrets.backend.credentials"
|
||||
@model={{@item.id}}
|
||||
data-test-role-aws-link="generate"
|
||||
>
|
||||
Generate credentials
|
||||
<LinkTo @route="vault.cluster.secrets.backend.show" @model={{@item.id}} data-test-role-ssh-link="show">
|
||||
Details
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if @item.updatePath.isPending}}
|
||||
{{#if @item.canEdit}}
|
||||
<li class="action">
|
||||
<LoadingDropdownOption />
|
||||
<LinkTo @route="vault.cluster.secrets.backend.edit" @model={{@item.id}} data-test-role-ssh-link="edit">
|
||||
Edit
|
||||
</LinkTo>
|
||||
</li>
|
||||
<li class="action">
|
||||
<LoadingDropdownOption />
|
||||
</li>
|
||||
{{else}}
|
||||
{{#if @item.canRead}}
|
||||
<li class="action">
|
||||
<LinkTo @route="vault.cluster.secrets.backend.show" @model={{@item.id}} data-test-role-ssh-link="show">
|
||||
Details
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if @item.canEdit}}
|
||||
<li class="action">
|
||||
<LinkTo @route="vault.cluster.secrets.backend.edit" @model={{@item.id}} data-test-role-ssh-link="edit">
|
||||
Edit
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if @item.canDelete}}
|
||||
<li class="action">
|
||||
<c.Message @id={{@item.id}} @onConfirm={{@delete}} data-test-aws-role-delete={{@item.id}} />
|
||||
</li>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</ul>
|
||||
</nav>
|
||||
</Confirm>
|
||||
{{#if @item.canDelete}}
|
||||
<ConfirmAction
|
||||
@buttonText="Delete"
|
||||
@isInDropdown={{true}}
|
||||
@onConfirmAction={{@delete}}
|
||||
data-test-aws-role-delete={{@item.id}}
|
||||
/>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</ul>
|
||||
</nav>
|
||||
</PopupMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -31,58 +31,54 @@
|
||||
</div>
|
||||
<div class="column has-text-right">
|
||||
<PopupMenu name="secret-menu">
|
||||
<Confirm as |c|>
|
||||
<nav class="menu">
|
||||
<ul class="menu-list">
|
||||
{{#if @item.isFolder}}
|
||||
<SecretLink @mode="list" @secret={{@item.id}} class="has-text-black has-text-weight-semibold">
|
||||
Contents
|
||||
</SecretLink>
|
||||
<nav class="menu">
|
||||
<ul class="menu-list">
|
||||
{{#if @item.isFolder}}
|
||||
<SecretLink @mode="list" @secret={{@item.id}} class="has-text-black has-text-weight-semibold">
|
||||
Contents
|
||||
</SecretLink>
|
||||
{{else}}
|
||||
{{#if (or @item.versionPath.isLoading @item.secretPath.isLoading)}}
|
||||
<li class="action">
|
||||
<LoadingDropdownOption />
|
||||
</li>
|
||||
{{else}}
|
||||
{{#if (or @item.versionPath.isLoading @item.secretPath.isLoading)}}
|
||||
{{#if @item.canRead}}
|
||||
<li class="action">
|
||||
<LoadingDropdownOption />
|
||||
<SecretLink
|
||||
@mode="show"
|
||||
@secret={{@item.id}}
|
||||
@queryParams={{secret-query-params @backendModel.type @item.type asQueryParams=true}}
|
||||
class="has-text-black has-text-weight-semibold"
|
||||
>
|
||||
Details
|
||||
</SecretLink>
|
||||
</li>
|
||||
{{else}}
|
||||
{{#if @item.canRead}}
|
||||
<li class="action">
|
||||
<SecretLink
|
||||
@mode="show"
|
||||
@secret={{@item.id}}
|
||||
@queryParams={{secret-query-params @backendModel.type @item.type asQueryParams=true}}
|
||||
class="has-text-black has-text-weight-semibold"
|
||||
>
|
||||
Details
|
||||
</SecretLink>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if @item.canEdit}}
|
||||
<li class="action">
|
||||
<SecretLink
|
||||
@mode="edit"
|
||||
@secret={{@item.id}}
|
||||
@queryParams={{secret-query-params @backendModel.type @item.type asQueryParams=true}}
|
||||
class="has-text-black has-text-weight-semibold"
|
||||
>
|
||||
Edit
|
||||
</SecretLink>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if @item.canDelete}}
|
||||
<li class="action">
|
||||
<c.Message
|
||||
@id={{@item.id}}
|
||||
@triggerText="Delete"
|
||||
@message="This will permanently delete this secret."
|
||||
@onConfirm={{@delete}}
|
||||
/>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if @item.canEdit}}
|
||||
<li class="action">
|
||||
<SecretLink
|
||||
@mode="edit"
|
||||
@secret={{@item.id}}
|
||||
@queryParams={{secret-query-params @backendModel.type @item.type asQueryParams=true}}
|
||||
class="has-text-black has-text-weight-semibold"
|
||||
>
|
||||
Edit
|
||||
</SecretLink>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if @item.canDelete}}
|
||||
<ConfirmAction
|
||||
@isInDropdown={{true}}
|
||||
@buttonText="Delete"
|
||||
@confirmMessage="This will permanently delete this secret."
|
||||
@onConfirmAction={{@delete}}
|
||||
/>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</ul>
|
||||
</nav>
|
||||
</Confirm>
|
||||
{{/if}}
|
||||
</ul>
|
||||
</nav>
|
||||
</PopupMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -37,85 +37,86 @@
|
||||
<div class="column has-text-right">
|
||||
{{#if (eq @backendType "ssh")}}
|
||||
<PopupMenu @name="role-ssh-nav">
|
||||
<Confirm as |c|>
|
||||
<nav class="menu">
|
||||
<ul class="menu-list">
|
||||
{{#if (eq @item.keyType "otp")}}
|
||||
{{#if @item.generatePath.isPending}}
|
||||
<nav class="menu">
|
||||
<ul class="menu-list">
|
||||
{{#if (eq @item.keyType "otp")}}
|
||||
{{#if @item.generatePath.isPending}}
|
||||
<li class="action">
|
||||
<Hds::Button disabled @color="tertiary" @icon="loading" @text="loading" @isIconOnly={{true}} />
|
||||
</li>
|
||||
{{else if @item.canGenerate}}
|
||||
<li class="action">
|
||||
<LinkTo
|
||||
@route="vault.cluster.secrets.backend.credentials"
|
||||
@model={{@item.id}}
|
||||
data-test-role-ssh-link="generate"
|
||||
>
|
||||
Generate Credentials
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{else if (eq @item.keyType "ca")}}
|
||||
{{#if @item.signPath.isPending}}
|
||||
<li class="action">
|
||||
<li class="action">
|
||||
<Hds::Button disabled @color="tertiary" @icon="loading" @text="loading" @isIconOnly={{true}} />
|
||||
</li>
|
||||
{{else if @item.canGenerate}}
|
||||
<li class="action">
|
||||
<LinkTo
|
||||
@route="vault.cluster.secrets.backend.credentials"
|
||||
@model={{@item.id}}
|
||||
data-test-role-ssh-link="generate"
|
||||
>
|
||||
Generate Credentials
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{else if (eq @item.keyType "ca")}}
|
||||
{{#if @item.signPath.isPending}}
|
||||
<li class="action">
|
||||
<li class="action">
|
||||
<Hds::Button disabled @color="tertiary" @icon="loading" @text="loading" @isIconOnly={{true}} />
|
||||
</li>
|
||||
</li>
|
||||
{{else if @item.canGenerate}}
|
||||
<li class="action">
|
||||
<LinkTo
|
||||
@route="vault.cluster.secrets.backend.sign"
|
||||
@model={{@item.id}}
|
||||
data-test-role-ssh-link="generate"
|
||||
>
|
||||
Sign Keys
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if @item.canEditZeroAddress}}
|
||||
</li>
|
||||
{{else if @item.canGenerate}}
|
||||
<li class="action">
|
||||
<Hds::Button
|
||||
disabled={{@loadingToggleZeroAddress}}
|
||||
class="link"
|
||||
@icon={{if @loadingToggleZeroAddress "loading"}}
|
||||
@isIconOnly={{@loadingToggleZeroAddress}}
|
||||
{{on "click" @toggleZeroAddress}}
|
||||
@text={{if @item.zeroAddress "Disable Zero Address" "Enable Zero Address"}}
|
||||
/>
|
||||
<LinkTo
|
||||
@route="vault.cluster.secrets.backend.sign"
|
||||
@model={{@item.id}}
|
||||
data-test-role-ssh-link="generate"
|
||||
>
|
||||
Sign Keys
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if @item.updatePath.isPending}}
|
||||
{{/if}}
|
||||
{{#if @item.canEditZeroAddress}}
|
||||
<li class="action">
|
||||
<Hds::Button
|
||||
disabled={{@loadingToggleZeroAddress}}
|
||||
class="link"
|
||||
@icon={{if @loadingToggleZeroAddress "loading"}}
|
||||
@isIconOnly={{@loadingToggleZeroAddress}}
|
||||
{{on "click" @toggleZeroAddress}}
|
||||
@text={{if @item.zeroAddress "Disable Zero Address" "Enable Zero Address"}}
|
||||
/>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if @item.updatePath.isPending}}
|
||||
<li class="action">
|
||||
<Hds::Button disabled @color="tertiary" @icon="loading" @text="loading" @isIconOnly={{true}} />
|
||||
<Hds::Button disabled @color="tertiary" @icon="loading" @text="loading" @isIconOnly={{true}} />
|
||||
</li>
|
||||
{{else}}
|
||||
{{#if @item.canRead}}
|
||||
<li class="action">
|
||||
<Hds::Button disabled @color="tertiary" @icon="loading" @text="loading" @isIconOnly={{true}} />
|
||||
<Hds::Button disabled @color="tertiary" @icon="loading" @text="loading" @isIconOnly={{true}} />
|
||||
<LinkTo @route="vault.cluster.secrets.backend.show" @model={{@item.id}} data-test-role-ssh-link="show">
|
||||
Details
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{else}}
|
||||
{{#if @item.canRead}}
|
||||
<li class="action">
|
||||
<LinkTo @route="vault.cluster.secrets.backend.show" @model={{@item.id}} data-test-role-ssh-link="show">
|
||||
Details
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if @item.canEdit}}
|
||||
<li class="action">
|
||||
<LinkTo @route="vault.cluster.secrets.backend.edit" @model={{@item.id}} data-test-role-ssh-link="edit">
|
||||
Edit
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if @item.canDelete}}
|
||||
<li class="action">
|
||||
<c.Message @id={{@item.id}} @onConfirm={{@delete}} data-test-ssh-role-delete />
|
||||
</li>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</ul>
|
||||
</nav>
|
||||
</Confirm>
|
||||
{{#if @item.canEdit}}
|
||||
<li class="action">
|
||||
<LinkTo @route="vault.cluster.secrets.backend.edit" @model={{@item.id}} data-test-role-ssh-link="edit">
|
||||
Edit
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if @item.canDelete}}
|
||||
<ConfirmAction
|
||||
@buttonText="Delete"
|
||||
@isInDropdown={{true}}
|
||||
@onConfirmAction={{@delete}}
|
||||
data-test-ssh-role-delete
|
||||
/>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</ul>
|
||||
</nav>
|
||||
</PopupMenu>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
@ -32,15 +32,13 @@
|
||||
<ToolbarActions>
|
||||
{{#if this.capabilities.canDelete}}
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
@buttonText="Delete role"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{action "delete"}}
|
||||
@confirmTitle="Are you sure?"
|
||||
@confirmMessage="Deleting this role means that you’ll need to recreate it and reassign any existing transformations to use it again."
|
||||
@confirmButtonText="Delete"
|
||||
data-test-transformation-role-delete
|
||||
>
|
||||
Delete role
|
||||
</ConfirmAction>
|
||||
/>
|
||||
<div class="toolbar-separator"></div>
|
||||
{{/if}}
|
||||
{{#if this.capabilities.canUpdate}}
|
||||
|
||||
@ -104,9 +104,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{{#if (and @key.canDelete @capabilities.canDelete)}}
|
||||
<ConfirmAction @buttonClasses="button" @onConfirmAction={{@deleteKey}}>
|
||||
Delete transit key
|
||||
</ConfirmAction>
|
||||
<ConfirmAction @buttonText="Delete transit key" @onConfirmAction={{@deleteKey}} />
|
||||
{{/if}}
|
||||
</div>
|
||||
</form>
|
||||
@ -6,15 +6,15 @@
|
||||
{{#if (eq this.selectedAction "rotate")}}
|
||||
{{#if this.key.canRotate}}
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
@buttonText="Rotate encryption key"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@confirmTitle="Rotate this key?"
|
||||
@confirmMessage="After rotation, all key actions will default to using the newest version of the key."
|
||||
@confirmButtonText="Rotate"
|
||||
@modalColor="warning"
|
||||
@onConfirmAction={{action "doSubmit"}}
|
||||
data-test-transit-key-rotate
|
||||
>
|
||||
Rotate encryption key
|
||||
</ConfirmAction>
|
||||
/>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<MessageError @errors={{this.errors}} />
|
||||
|
||||
@ -33,63 +33,66 @@
|
||||
</div>
|
||||
<div class="column has-text-right">
|
||||
<PopupMenu @name="identity-item" @onOpen={{action "reloadRecord" item}}>
|
||||
<Confirm as |c|>
|
||||
<nav class="menu">
|
||||
<ul class="menu-list">
|
||||
<nav class="menu">
|
||||
<ul class="menu-list">
|
||||
<li class="action">
|
||||
<LinkTo @route="vault.cluster.access.identity.show" @models={{array item.id "details"}}>
|
||||
Details
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{#if (or item.isReloading item.updatePath.isPending item.aliasPath.isPending)}}
|
||||
<li class="action">
|
||||
<LinkTo @route="vault.cluster.access.identity.show" @models={{array item.id "details"}}>
|
||||
Details
|
||||
</LinkTo>
|
||||
<LoadingDropdownOption />
|
||||
</li>
|
||||
{{#if (or item.isReloading item.updatePath.isPending item.aliasPath.isPending)}}
|
||||
{{else}}
|
||||
{{#if item.canAddAlias}}
|
||||
<li class="action">
|
||||
<LoadingDropdownOption />
|
||||
<LinkTo
|
||||
@route="vault.cluster.access.identity.aliases.add"
|
||||
@models={{array (pluralize this.identityType) item.id}}
|
||||
>
|
||||
Create alias
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{else}}
|
||||
{{#if item.canAddAlias}}
|
||||
<li class="action">
|
||||
<LinkTo
|
||||
@route="vault.cluster.access.identity.aliases.add"
|
||||
@models={{array (pluralize this.identityType) item.id}}
|
||||
>
|
||||
Create alias
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if item.canEdit}}
|
||||
<li class="action">
|
||||
<LinkTo @route="vault.cluster.access.identity.edit" @model={{item.id}}>
|
||||
Edit
|
||||
</LinkTo>
|
||||
</li>
|
||||
<li class="action">
|
||||
{{#if item.disabled}}
|
||||
{{! TODO Hds::Button replacement skipped in favor of updating it when there is a Hds::Dropdown swapout }}
|
||||
<button type="button" {{action "toggleDisabled" item}} class="link">
|
||||
Enable
|
||||
</button>
|
||||
{{else if (eq this.identityType "entity")}}
|
||||
<c.Message
|
||||
@id="{{item.id}}-disable"
|
||||
@triggerText="Disable"
|
||||
@message="Associated tokens will not be revoked, but cannot be used"
|
||||
@title="Disable this?"
|
||||
@confirmButtonText="Disable"
|
||||
@onConfirm={{action "toggleDisabled" item}}
|
||||
data-test-engine-disable="true"
|
||||
/>
|
||||
{{/if}}
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if item.canDelete}}
|
||||
<li class="action">
|
||||
<c.Message @id={{item.id}} @onConfirm={{action "delete" item}} data-test-item-delete="true" />
|
||||
</li>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</ul>
|
||||
</nav>
|
||||
</Confirm>
|
||||
{{#if item.canEdit}}
|
||||
<li class="action">
|
||||
<LinkTo @route="vault.cluster.access.identity.edit" @model={{item.id}}>
|
||||
Edit
|
||||
</LinkTo>
|
||||
</li>
|
||||
<li class="action">
|
||||
{{#if item.disabled}}
|
||||
<Hds::Button
|
||||
@text="Enable"
|
||||
type="button"
|
||||
{{on "click" (action "toggleDisabled" item)}}
|
||||
class="link"
|
||||
/>
|
||||
{{else if (eq this.identityType "entity")}}
|
||||
<ConfirmAction
|
||||
@isInDropdown={{true}}
|
||||
@buttonText="Disable"
|
||||
@confirmMessage="Associated tokens will not be revoked, but cannot be used"
|
||||
@confirmTitle="Disable this entity?"
|
||||
@onConfirmAction={{action "toggleDisabled" item}}
|
||||
@modalColor="warning"
|
||||
/>
|
||||
{{/if}}
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if item.canDelete}}
|
||||
<ConfirmAction
|
||||
@isInDropdown={{true}}
|
||||
@buttonText="Delete"
|
||||
@onConfirmAction={{action "delete" item}}
|
||||
@confirmTitle="Delete this {{this.identityType}}?"
|
||||
data-test-item-delete
|
||||
/>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</ul>
|
||||
</nav>
|
||||
</PopupMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -57,28 +57,26 @@
|
||||
<div class="control">
|
||||
{{#if (and this.capabilities.forceRevokePrefix.canUpdate (not this.confirmingRevoke))}}
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
@confirmTitle="Disable this?"
|
||||
@confirmMessage={{concat "All leases under this one will also be removed and disregard any errors encountered."}}
|
||||
@confirmButtonText="Revoke"
|
||||
@buttonText="Force revoke prefix"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@confirmTitle="Revoke this?"
|
||||
@confirmMessage="All leases under this one will also be removed and any errors encountered will be disregarded."
|
||||
@onConfirmAction={{action "revokePrefix" this.baseKey.id true}}
|
||||
>
|
||||
Force revoke prefix
|
||||
</ConfirmAction>
|
||||
/>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="control">
|
||||
{{#if (and this.capabilities.revokePrefix.canUpdate (not this.confirmingForceRevoke))}}
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
@buttonText="Revoke prefix"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@confirmTitle="Revoke this?"
|
||||
@confirmMessage={{concat "All leases under this one will also be removed"}}
|
||||
@confirmButtonText="Revoke"
|
||||
@confirmMessage="All leases under this one will also be removed."
|
||||
@onConfirmAction={{action "revokePrefix" this.baseKey.id}}
|
||||
data-test-lease-revoke-prefix="true"
|
||||
>
|
||||
Revoke prefix
|
||||
</ConfirmAction>
|
||||
data-test-lease-revoke-prefix
|
||||
/>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
@ -26,15 +26,14 @@
|
||||
<Toolbar>
|
||||
<ToolbarActions>
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
@buttonText="Revoke lease"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@confirmTitle="Revoke this?"
|
||||
@confirmMessage={{concat "All leases under this one will also be removed"}}
|
||||
@confirmButtonText="Confirm"
|
||||
@confirmMessage="All leases under this one will also be removed."
|
||||
@onConfirmAction={{action "revokeLease" this.model}}
|
||||
data-test-lease-revoke="true"
|
||||
>
|
||||
Revoke lease
|
||||
</ConfirmAction>
|
||||
data-test-lease-revoke
|
||||
/>
|
||||
</ToolbarActions>
|
||||
</Toolbar>
|
||||
{{/if}}
|
||||
|
||||
@ -84,36 +84,32 @@
|
||||
<div class="level-right is-flex is-paddingless is-marginless">
|
||||
<div class="level-item">
|
||||
<PopupMenu @name="auth-backend-nav">
|
||||
<Confirm as |c|>
|
||||
<nav class="menu">
|
||||
<ul class="menu-list">
|
||||
<nav class="menu">
|
||||
<ul class="menu-list">
|
||||
<li>
|
||||
<LinkTo @route="vault.cluster.access.method.section" @models={{array method.id "configuration"}}>
|
||||
View configuration
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{#if method.canEdit}}
|
||||
<li>
|
||||
<LinkTo @route="vault.cluster.access.method.section" @models={{array method.id "configuration"}}>
|
||||
View configuration
|
||||
<LinkTo @route="vault.cluster.settings.auth.configure" @model={{method.id}}>
|
||||
Edit configuration
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{#if method.canEdit}}
|
||||
<li>
|
||||
<LinkTo @route="vault.cluster.settings.auth.configure" @model={{method.id}}>
|
||||
Edit configuration
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
{{#if (and (not-eq method.methodType "token") method.canDisable)}}
|
||||
<li class="action">
|
||||
<c.Message
|
||||
@id={{method.id}}
|
||||
@title="Disable method?"
|
||||
@message="This may affect access to Vault data."
|
||||
@triggerText="Disable"
|
||||
@onConfirm={{perform this.disableMethod method}}
|
||||
/>
|
||||
</li>
|
||||
{{/if}}
|
||||
</ul>
|
||||
</nav>
|
||||
</Confirm>
|
||||
{{#if (and (not-eq method.methodType "token") method.canDisable)}}
|
||||
<ConfirmAction
|
||||
@isInDropdown={{true}}
|
||||
@confirmTitle="Disable method?"
|
||||
@confirmMessage="This may affect access to Vault data."
|
||||
@buttonText="Disable"
|
||||
@onConfirmAction={{perform this.disableMethod method}}
|
||||
/>
|
||||
{{/if}}
|
||||
</ul>
|
||||
</nav>
|
||||
</PopupMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -45,15 +45,17 @@
|
||||
<Toolbar>
|
||||
<ToolbarActions>
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
@disabled={{not (is-empty this.model.enforcements)}}
|
||||
data-test-delete-mfa-config
|
||||
class="toolbar-button"
|
||||
@disabledMessage={{unless
|
||||
(is-empty this.model.enforcements)
|
||||
"This method cannot be deleted until its enforcements are deleted. This can be done from the 'Enforcements' tab."
|
||||
}}
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{this.deleteMethod}}
|
||||
@confirmTitle="Are you sure?"
|
||||
@confirmMessage="Deleting this MFA configuration is permanent, and it will no longer be available."
|
||||
@confirmButtonText="Delete"
|
||||
>
|
||||
Delete
|
||||
</ConfirmAction>
|
||||
@buttonText="Delete"
|
||||
/>
|
||||
<ToolbarLink
|
||||
@route="vault.cluster.access.mfa.methods.method.edit"
|
||||
@model={{this.model.method.id}}
|
||||
|
||||
@ -36,7 +36,7 @@
|
||||
<Item.content>
|
||||
{{list.item.id}}
|
||||
</Item.content>
|
||||
<Item.menu as |m|>
|
||||
<Item.menu>
|
||||
{{#let (concat this.currentNamespace (if this.currentNamespace "/") list.item.id) as |targetNamespace|}}
|
||||
{{#if (includes targetNamespace this.accessibleNamespaces)}}
|
||||
<li class="action">
|
||||
@ -46,23 +46,22 @@
|
||||
</li>
|
||||
{{/if}}
|
||||
{{/let}}
|
||||
<li class="action">
|
||||
<m.Message
|
||||
@id={{list.item.id}}
|
||||
@confirmButtonText="Remove"
|
||||
@message="Any engines or mounts in this namespace will also be removed."
|
||||
@onConfirm={{action
|
||||
(perform
|
||||
Item.callMethod
|
||||
"destroyRecord"
|
||||
list.item
|
||||
(concat "Successfully deleted namespace: " list.item.id)
|
||||
"There was an error deleting this namespace: "
|
||||
(action "refreshNamespaceList")
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</li>
|
||||
<ConfirmAction
|
||||
@isInDropdown={{true}}
|
||||
@buttonText="Delete"
|
||||
@confirmTitle="Delete this namespace?"
|
||||
@confirmMessage="Any engines or mounts in this namespace will also be removed."
|
||||
@onConfirmAction={{action
|
||||
(perform
|
||||
Item.callMethod
|
||||
"destroyRecord"
|
||||
list.item
|
||||
(concat "Successfully deleted namespace: " list.item.id)
|
||||
"There was an error deleting this namespace: "
|
||||
(action "refreshNamespaceList")
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</Item.menu>
|
||||
</ListItem>
|
||||
{{/if}}
|
||||
|
||||
@ -41,15 +41,14 @@
|
||||
<ToolbarActions>
|
||||
{{#if @model.canDelete}}
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
@buttonText="Delete assignment"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{this.delete}}
|
||||
@confirmTitle="Delete assignment?"
|
||||
@confirmMessage="This assignment will be permanently deleted. You will not be able to recover it."
|
||||
@confirmButtonText="Delete"
|
||||
data-test-oidc-assignment-delete
|
||||
>
|
||||
Delete assignment
|
||||
</ConfirmAction>
|
||||
/>
|
||||
<div class="toolbar-separator"></div>
|
||||
{{/if}}
|
||||
{{#if @model.canEdit}}
|
||||
|
||||
@ -8,14 +8,13 @@
|
||||
{{#if this.model.canDelete}}
|
||||
<ConfirmAction
|
||||
data-test-oidc-client-delete
|
||||
@buttonClasses="toolbar-link"
|
||||
@buttonText="Delete application"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{this.delete}}
|
||||
@confirmTitle="Delete application?"
|
||||
@confirmMessage="This application will be permanently deleted. You will need to re-create it to use it again."
|
||||
@confirmButtonText="Delete"
|
||||
>
|
||||
Delete application
|
||||
</ConfirmAction>
|
||||
/>
|
||||
<div class="toolbar-separator"></div>
|
||||
{{/if}}
|
||||
{{#if this.model.canEdit}}
|
||||
|
||||
@ -5,43 +5,30 @@
|
||||
|
||||
<Toolbar>
|
||||
<ToolbarActions>
|
||||
{{#if this.model.canDelete}}
|
||||
<ToolTip @verticalPosition="above" as |T|>
|
||||
<T.Trigger tabindex="-1">
|
||||
<ConfirmAction
|
||||
data-test-oidc-key-delete
|
||||
@disabled={{eq this.model.name "default"}}
|
||||
@buttonClasses="toolbar-link"
|
||||
@onConfirmAction={{this.delete}}
|
||||
@confirmTitle="Delete key?"
|
||||
@confirmMessage="This key will be permanently deleted. You will not be able to recover it."
|
||||
@confirmButtonText="Delete"
|
||||
>
|
||||
Delete key
|
||||
</ConfirmAction>
|
||||
</T.Trigger>
|
||||
{{#if (eq this.model.name "default")}}
|
||||
<T.Content @defaultClass="tool-tip smaller-font">
|
||||
<div class="box">
|
||||
This is a built-in key that cannot be deleted.
|
||||
</div>
|
||||
</T.Content>
|
||||
{{/if}}
|
||||
</ToolTip>
|
||||
{{#if (and (not-eq this.model.name "default") this.model.canDelete)}}
|
||||
<ConfirmAction
|
||||
@buttonText="Delete key"
|
||||
data-test-oidc-key-delete
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{this.delete}}
|
||||
@confirmTitle="Delete key?"
|
||||
@confirmMessage="This key will be permanently deleted. You will not be able to recover it."
|
||||
/>
|
||||
<div class="toolbar-separator"></div>
|
||||
{{/if}}
|
||||
{{#if this.model.canRotate}}
|
||||
<ConfirmAction
|
||||
@buttonText="Rotate key"
|
||||
data-test-oidc-key-rotate
|
||||
@buttonClasses="toolbar-link"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{perform this.rotateKey}}
|
||||
@confirmTitle="Rotate this key?"
|
||||
@confirmMessage="After rotation, a new public/private key pair will be generated."
|
||||
@confirmButtonText="Rotate"
|
||||
@modalColor="warning"
|
||||
@isRunning={{this.rotateKey.isRunning}}
|
||||
>
|
||||
Rotate key
|
||||
</ConfirmAction>
|
||||
/>
|
||||
{{/if}}
|
||||
{{#if this.model.canEdit}}
|
||||
<ToolbarLink @route="vault.cluster.access.oidc.keys.key.edit" @model={{this.model.name}} data-test-oidc-key-edit>
|
||||
|
||||
@ -5,29 +5,16 @@
|
||||
|
||||
<Toolbar>
|
||||
<ToolbarActions>
|
||||
{{#if this.model.canDelete}}
|
||||
<ToolTip @verticalPosition="above" as |T|>
|
||||
<T.Trigger tabindex="-1">
|
||||
<ConfirmAction
|
||||
data-test-oidc-provider-delete
|
||||
@disabled={{eq this.model.name "default"}}
|
||||
@buttonClasses="toolbar-link"
|
||||
@onConfirmAction={{this.delete}}
|
||||
@confirmTitle="Delete provider?"
|
||||
@confirmMessage="This provider will be permanently deleted. You will need to re-create it to use it again."
|
||||
@confirmButtonText="Delete"
|
||||
>
|
||||
Delete provider
|
||||
</ConfirmAction>
|
||||
</T.Trigger>
|
||||
{{#if (eq this.model.name "default")}}
|
||||
<T.Content @defaultClass="tool-tip smaller-font">
|
||||
<div class="box">
|
||||
This is a built-in provider that cannot be deleted.
|
||||
</div>
|
||||
</T.Content>
|
||||
{{/if}}
|
||||
</ToolTip>
|
||||
{{#if (and (not-eq this.model.name "default") this.model.canDelete)}}
|
||||
<ConfirmAction
|
||||
data-test-oidc-provider-delete
|
||||
@buttonText="Delete provider"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{this.delete}}
|
||||
@confirmTitle="Delete provider?"
|
||||
@confirmMessage="This provider will be permanently deleted. You will need to re-create it to use it again."
|
||||
/>
|
||||
<div class="toolbar-separator"></div>
|
||||
{{/if}}
|
||||
{{#if this.model.canEdit}}
|
||||
|
||||
@ -38,14 +38,13 @@
|
||||
{{#if this.model.canDelete}}
|
||||
<ConfirmAction
|
||||
data-test-oidc-scope-delete
|
||||
@buttonClasses="toolbar-link"
|
||||
@buttonText="Delete scope"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{this.delete}}
|
||||
@confirmTitle="Delete scope?"
|
||||
@confirmMessage="This scope will be permanently deleted. You will not be able to recover it."
|
||||
@confirmButtonText="Delete"
|
||||
>
|
||||
Delete scope
|
||||
</ConfirmAction>
|
||||
/>
|
||||
<div class="toolbar-separator"></div>
|
||||
{{/if}}
|
||||
{{#if this.model.canEdit}}
|
||||
|
||||
@ -92,53 +92,50 @@
|
||||
</div>
|
||||
<div class="column has-text-right">
|
||||
<PopupMenu name="policy-nav">
|
||||
<Confirm as |c|>
|
||||
<nav class="menu">
|
||||
<ul class="menu-list">
|
||||
{{#if item.updatePath.isPending}}
|
||||
<nav class="menu">
|
||||
<ul class="menu-list">
|
||||
{{#if item.updatePath.isPending}}
|
||||
<li class="action">
|
||||
<LoadingDropdownOption />
|
||||
</li>
|
||||
<li class="action">
|
||||
<LoadingDropdownOption />
|
||||
</li>
|
||||
{{else}}
|
||||
{{#if item.canRead}}
|
||||
<li class="action">
|
||||
<LoadingDropdownOption />
|
||||
<LinkTo
|
||||
@route="vault.cluster.policy.show"
|
||||
@models={{array this.policyType item.id}}
|
||||
data-test-policy-link="show"
|
||||
>
|
||||
Details
|
||||
</LinkTo>
|
||||
</li>
|
||||
<li class="action">
|
||||
<LoadingDropdownOption />
|
||||
</li>
|
||||
{{else}}
|
||||
{{#if item.canRead}}
|
||||
<li class="action">
|
||||
<LinkTo
|
||||
@route="vault.cluster.policy.show"
|
||||
@models={{array this.policyType item.id}}
|
||||
data-test-policy-link="show"
|
||||
>
|
||||
Details
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if item.canEdit}}
|
||||
<li class="action">
|
||||
<LinkTo
|
||||
@route="vault.cluster.policy.edit"
|
||||
@models={{array this.policyType item.id}}
|
||||
data-test-policy-link="edit"
|
||||
>
|
||||
Edit
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if item.canDelete}}
|
||||
<li class="action">
|
||||
<c.Message
|
||||
@id={{item.id}}
|
||||
@confirmMessage="This will permanently delete this policy and may affect access to some data"
|
||||
@onConfirm={{action "deletePolicy" item}}
|
||||
data-test-policy-delete={{item.id}}
|
||||
/>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</ul>
|
||||
</nav>
|
||||
</Confirm>
|
||||
{{#if item.canEdit}}
|
||||
<li class="action">
|
||||
<LinkTo
|
||||
@route="vault.cluster.policy.edit"
|
||||
@models={{array this.policyType item.id}}
|
||||
data-test-policy-link="edit"
|
||||
>
|
||||
Edit
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if item.canDelete}}
|
||||
<ConfirmAction
|
||||
@isInDropdown={{true}}
|
||||
@buttonText="Delete"
|
||||
@confirmTitle="Delete this policy?"
|
||||
@confirmMessage="This will permanently delete this policy and may affect access to some data"
|
||||
@onConfirmAction={{action "deletePolicy" item}}
|
||||
/>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</ul>
|
||||
</nav>
|
||||
</PopupMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -31,13 +31,12 @@
|
||||
<ToolbarActions>
|
||||
{{#if (and (not-eq this.model.id "default") this.capabilities.canDelete)}}
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
@confirmMessage="This may affect access to Vault data."
|
||||
@buttonText="Delete policy"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@confirmMessage="Deleting this policy may affect access to Vault data."
|
||||
@onConfirmAction={{this.deletePolicy}}
|
||||
data-test-policy-delete="true"
|
||||
>
|
||||
Delete
|
||||
</ConfirmAction>
|
||||
/>
|
||||
<div class="toolbar-separator"></div>
|
||||
{{/if}}
|
||||
<ToolbarLink @route="vault.cluster.policy.show" @model={{this.model.id}} data-test-policy-edit-toggle>
|
||||
|
||||
@ -96,30 +96,24 @@
|
||||
{{! meatball sandwich menu }}
|
||||
<div class="linked-block-popup-menu">
|
||||
<PopupMenu @name="engine-menu">
|
||||
<Confirm as |c|>
|
||||
<nav class="menu" aria-label="{{if backend.isSupportedBackend 'supported' 'unsupported'}} secrets engine menu">
|
||||
<ul class="menu-list">
|
||||
<li class="action">
|
||||
<LinkTo @route="vault.cluster.secrets.backend.configuration" @model={{backend.id}} data-test-engine-config>
|
||||
View configuration
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{#if (not-eq backend.type "cubbyhole")}}
|
||||
<li class="action">
|
||||
<c.Message
|
||||
@id={{backend.id}}
|
||||
@triggerText="Disable"
|
||||
@message="Any data in this engine will be permanently deleted."
|
||||
@title="Disable engine?"
|
||||
@confirmButtonText="Disable"
|
||||
@onConfirm={{perform this.disableEngine backend}}
|
||||
data-test-engine-disable="true"
|
||||
/>
|
||||
</li>
|
||||
{{/if}}
|
||||
</ul>
|
||||
</nav>
|
||||
</Confirm>
|
||||
<nav class="menu" aria-label="{{if backend.isSupportedBackend 'supported' 'unsupported'}} secrets engine menu">
|
||||
<ul class="menu-list">
|
||||
<li class="action">
|
||||
<LinkTo @route="vault.cluster.secrets.backend.configuration" @model={{backend.id}} data-test-engine-config>
|
||||
View configuration
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{#if (not-eq backend.type "cubbyhole")}}
|
||||
<ConfirmAction
|
||||
@isInDropdown={{true}}
|
||||
@confirmMessage="Any data in this engine will be permanently deleted."
|
||||
@confirmTitle="Disable engine?"
|
||||
@buttonText="Disable"
|
||||
@onConfirmAction={{perform this.disableEngine backend}}
|
||||
/>
|
||||
{{/if}}
|
||||
</ul>
|
||||
</nav>
|
||||
</PopupMenu>
|
||||
</div>
|
||||
</LinkedBlock>
|
||||
|
||||
@ -3,57 +3,65 @@
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
~}}
|
||||
|
||||
<div class="confirm-action" ...attributes>
|
||||
<BasicDropdown
|
||||
@horizontalPosition={{this.horizontalPosition}}
|
||||
@verticalPosition={{this.verticalPosition}}
|
||||
@onOpen={{this.toggleConfirm}}
|
||||
@onClose={{this.toggleConfirm}}
|
||||
as |d|
|
||||
{{#if @isInDropdown}}
|
||||
{{! Hds component renders <li> and <button> elements }}
|
||||
<Hds::Dropdown::ListItem::Interactive
|
||||
data-test-confirm-action-trigger
|
||||
@text={{@buttonText}}
|
||||
@color="critical"
|
||||
{{on "click" (fn (mut this.showConfirmModal) true)}}
|
||||
...attributes
|
||||
{{! remove class when dropdown/popup menus are replaced with Hds::Dropdown }}
|
||||
class="hds-confirm-action-critical"
|
||||
/>
|
||||
{{else}}
|
||||
<Hds::Button
|
||||
data-test-confirm-action-trigger
|
||||
@text={{@buttonText}}
|
||||
@color={{@buttonColor}}
|
||||
{{on "click" (fn (mut this.showConfirmModal) true)}}
|
||||
...attributes
|
||||
/>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.showConfirmModal}}
|
||||
<Hds::Modal
|
||||
id="confirm-action-modal"
|
||||
@color={{this.modalColor}}
|
||||
@size="small"
|
||||
@onClose={{fn (mut this.showConfirmModal) false}}
|
||||
as |M|
|
||||
>
|
||||
<d.Trigger
|
||||
@htmlTag="button"
|
||||
class={{concat @buttonClasses " popup-menu-trigger" (if d.isOpen " is-active")}}
|
||||
type="button"
|
||||
disabled={{this.disabled}}
|
||||
data-test-confirm-action-trigger="true"
|
||||
>
|
||||
{{yield}}
|
||||
{{#if (eq @buttonClasses "toolbar-link")}}
|
||||
<Chevron @direction={{if this.showConfirm "up" "down"}} data-test-confirm-action-chevron />
|
||||
{{/if}}
|
||||
</d.Trigger>
|
||||
<d.Content @defaultClass="popup-menu-content">
|
||||
<div class="box confirm-action-message">
|
||||
<div class="message is-highlight">
|
||||
<div class="message-title" data-test-confirm-action-title>
|
||||
<Icon @name="alert-triangle-fill" />
|
||||
{{this.confirmTitle}}
|
||||
</div>
|
||||
<p>
|
||||
{{this.confirmMessage}}
|
||||
</p>
|
||||
</div>
|
||||
<div class="confirm-action-options">
|
||||
{{! TODO Hds::Button replacement - skipping because modal will replace this confirm inline-popup menu }}
|
||||
<button
|
||||
type="button"
|
||||
disabled={{or this.disabled this.isRunning}}
|
||||
class="link is-destroy"
|
||||
data-test-confirm-button="true"
|
||||
{{on "click" (fn this.onConfirm d.actions)}}
|
||||
>
|
||||
{{#if this.isRunning}}
|
||||
<span class="loader is-inline-block"></span>
|
||||
{{else}}
|
||||
{{this.confirmButtonText}}
|
||||
{{/if}}
|
||||
</button>
|
||||
<button type="button" class="link" data-test-confirm-cancel-button="true" {{on "click" d.actions.close}}>
|
||||
{{this.cancelButtonText}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</d.Content>
|
||||
</BasicDropdown>
|
||||
</div>
|
||||
{{#if @disabledMessage}}
|
||||
<M.Header data-test-confirm-action-title @icon="x-circle">
|
||||
Not allowed
|
||||
</M.Header>
|
||||
<M.Body data-test-confirm-action-message>
|
||||
{{@disabledMessage}}
|
||||
</M.Body>
|
||||
<M.Footer as |F|>
|
||||
<Hds::Button data-test-confirm-cancel-button @text="Close" {{on "click" F.close}} />
|
||||
</M.Footer>
|
||||
{{else}}
|
||||
<M.Header data-test-confirm-action-title @icon="alert-circle">
|
||||
{{or @confirmTitle "Are you sure?"}}
|
||||
</M.Header>
|
||||
<M.Body data-test-confirm-action-message>
|
||||
{{this.confirmMessage}}
|
||||
</M.Body>
|
||||
<M.Footer as |F|>
|
||||
<Hds::ButtonSet>
|
||||
<Hds::Button
|
||||
data-test-confirm-button
|
||||
disabled={{@isRunning}}
|
||||
@icon={{if @isRunning "loading"}}
|
||||
@color={{if (eq this.modalColor "critical") "critical" "primary"}}
|
||||
@text="Confirm"
|
||||
{{on "click" this.onConfirm}}
|
||||
/>
|
||||
<Hds::Button data-test-confirm-cancel-button @color="secondary" @text="Cancel" {{on "click" F.close}} />
|
||||
</Hds::ButtonSet>
|
||||
</M.Footer>
|
||||
{{/if}}
|
||||
</Hds::Modal>
|
||||
{{/if}}
|
||||
@ -10,81 +10,69 @@ import { tracked } from '@glimmer/tracking';
|
||||
|
||||
/**
|
||||
* @module ConfirmAction
|
||||
* `ConfirmAction` is a button followed by a pop up confirmation message and button used to prevent users from performing actions they do not intend to.
|
||||
* ConfirmAction is a button that opens a modal containing a confirmation message with confirm or cancel action.
|
||||
* Splattributes are spread to the button element to apply styling directly without adding extra args.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* <ConfirmAction
|
||||
* @onConfirmAction={{ () => { console.log('Action!') } }}
|
||||
* @confirmMessage="Are you sure you want to delete this config?">
|
||||
* Delete
|
||||
* </ConfirmAction>
|
||||
// in dropdown
|
||||
<ConfirmAction
|
||||
@isInDropdown={{true}}
|
||||
@buttonText="Delete"
|
||||
@confirmMessage="This action cannot be undone."
|
||||
@onConfirmAction={{log "my action!"}}
|
||||
/>
|
||||
|
||||
// in toolbar
|
||||
<ConfirmAction
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@buttonText="Delete item"
|
||||
@confirmTitle="Delete item?"
|
||||
@onConfirmAction={{log "my action!"}}
|
||||
@confirmMessage="Are you sure you want to delete this config?"
|
||||
@isRunning={{this.rotateKey.isRunning}}
|
||||
@disabledMessage={{if true "A secondary ID is required perform revocation."}}
|
||||
/>
|
||||
* ```
|
||||
*
|
||||
* @param {Func} [onConfirmAction=null] - The action to take upon confirming.
|
||||
* @param {String} [confirmTitle=Delete this?] - The title to display when confirming.
|
||||
* @param {Function} onConfirmAction - The action to take upon confirming.
|
||||
* @param {String} [confirmTitle=Are you sure?] - The title to display in the confirmation modal.
|
||||
* @param {String} [confirmMessage=You will not be able to recover it later.] - The message to display when confirming.
|
||||
* @param {String} [confirmButtonText=Delete] - The confirm button text.
|
||||
* @param {String} [cancelButtonText=Cancel] - The cancel button text.
|
||||
* @param {String} [buttonClasses] - A string to indicate the button class.
|
||||
* @param {String} [horizontalPosition=auto-right] - For the position of the dropdown.
|
||||
* @param {String} [verticalPosition=below] - For the position of the dropdown.
|
||||
* @param {Boolean} [isRunning=false] - If action is still running disable the confirm.
|
||||
* @param {Boolean} [disable=false] - To disable the confirm action.
|
||||
* @param {Boolean} isInDropdown - If true styles for dropdowns, button color is 'critical', and renders inside `<li>` elements via `<Hds::Dropdown::ListItem::Interactive`
|
||||
* @param {String} buttonText - Text for the button that toggles modal to open.
|
||||
* @param {String} [buttonColor=primary] - Color of button that toggles modal, only applies when @isInDropdown=false. Options are primary, secondary (use for toolbars), tertiary, or critical
|
||||
* @param {String} [modalColor=critical] - Styles modal color, if 'critical' confirm button is also 'critical'. Possible values: critical, warning or neutral ('neutral' used for @disabledMessage modal)
|
||||
* @param {Boolean} [isRunning] - Disables the modal confirm button - usually a concurrency task that informs the modal if a process is still running
|
||||
* @param {String} [disabledMessage] - A message explaining why the confirm action is not allowed, usually combined with a conditional that returns a string if true
|
||||
*
|
||||
*/
|
||||
|
||||
export default class ConfirmActionComponent extends Component {
|
||||
@tracked showConfirm = false;
|
||||
@tracked showConfirmModal = false;
|
||||
|
||||
get horizontalPosition() {
|
||||
return this.args.horizontalPosition || 'auto-right';
|
||||
}
|
||||
|
||||
get verticalPosition() {
|
||||
return this.args.verticalPosition || 'below';
|
||||
}
|
||||
|
||||
get isRunning() {
|
||||
return this.args.isRunning || false;
|
||||
}
|
||||
|
||||
get disabled() {
|
||||
return this.args.disabled || false;
|
||||
}
|
||||
|
||||
get confirmTitle() {
|
||||
return this.args.confirmTitle || 'Delete this?';
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
assert(
|
||||
'<ConfirmAction> component expects @onConfirmAction arg to be a function',
|
||||
typeof this.args.onConfirmAction === 'function'
|
||||
);
|
||||
assert(`@buttonText is required for ConfirmAction components`, this.args.buttonText);
|
||||
}
|
||||
|
||||
get confirmMessage() {
|
||||
return this.args.confirmMessage || 'You will not be able to recover it later.';
|
||||
}
|
||||
|
||||
get confirmButtonText() {
|
||||
return this.args.confirmButtonText || 'Delete';
|
||||
}
|
||||
|
||||
get cancelButtonText() {
|
||||
return this.args.cancelButtonText || 'Cancel';
|
||||
get modalColor() {
|
||||
if (this.args.disabledMessage) return 'neutral';
|
||||
return this.args.modalColor || 'critical';
|
||||
}
|
||||
|
||||
@action
|
||||
toggleConfirm() {
|
||||
// toggle
|
||||
this.showConfirm = !this.showConfirm;
|
||||
}
|
||||
|
||||
@action
|
||||
onConfirm(actions) {
|
||||
const confirmAction = this.args.onConfirmAction;
|
||||
|
||||
if (typeof confirmAction !== 'function') {
|
||||
assert('confirm-action components expects `onConfirmAction` attr to be a function');
|
||||
} else {
|
||||
confirmAction();
|
||||
// close the dropdown content
|
||||
actions.close();
|
||||
}
|
||||
async onConfirm() {
|
||||
await this.args.onConfirmAction();
|
||||
// close modal after destructive operation
|
||||
this.showConfirmModal = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,72 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import Component from '@ember/component';
|
||||
import { computed } from '@ember/object';
|
||||
import layout from '../templates/components/confirm';
|
||||
import { next } from '@ember/runloop';
|
||||
|
||||
/**
|
||||
* @module Confirm
|
||||
* `Confirm` components prevent users from performing actions they do not intend to by showing a confirmation message as an overlay. This is a contextual component that should always be rendered with a `Message` which triggers the message.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* <div class="box">
|
||||
* <Confirm as |c|>
|
||||
* <c.Message
|
||||
* @id={{item.id}}
|
||||
* @triggerText="Delete"
|
||||
* @message="This will permanently delete this secret and all its versions."
|
||||
* @onConfirm={{action "delete" item "secret"}}
|
||||
* />
|
||||
* </Confirm>
|
||||
* </div>
|
||||
* ```
|
||||
*/
|
||||
|
||||
export default Component.extend({
|
||||
layout,
|
||||
openTrigger: null,
|
||||
height: 0,
|
||||
focusTrigger: null,
|
||||
wormholeReference: null,
|
||||
wormholeId: computed('elementId', function () {
|
||||
return `confirm-${this.elementId}`;
|
||||
}),
|
||||
didInsertElement() {
|
||||
this._super(...arguments);
|
||||
this.set('wormholeReference', this.element.querySelector(`#${this.wormholeId}`));
|
||||
},
|
||||
didRender() {
|
||||
this._super(...arguments);
|
||||
this.updateHeight();
|
||||
},
|
||||
updateHeight: function () {
|
||||
const height = this.openTrigger
|
||||
? this.element.querySelector('.confirm-overlay').clientHeight
|
||||
: this.element.querySelector('.confirm').clientHeight;
|
||||
this.element.querySelector('.confirm-wrapper').style = `height: ${height}px;`;
|
||||
},
|
||||
actions: {
|
||||
onTrigger: function (itemId, e) {
|
||||
this.set('openTrigger', itemId);
|
||||
|
||||
// store a reference to the trigger so we can focus the element
|
||||
// after clicking cancel
|
||||
this.set('focusTrigger', e.target);
|
||||
this.updateHeight();
|
||||
},
|
||||
onCancel: function () {
|
||||
this.set('openTrigger', '');
|
||||
this.updateHeight();
|
||||
|
||||
next(() => {
|
||||
this.focusTrigger.focus();
|
||||
this.set('focusTrigger', null);
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -1,59 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import Component from '@ember/component';
|
||||
import { computed } from '@ember/object';
|
||||
import layout from '../../templates/components/confirm/message';
|
||||
|
||||
/**
|
||||
* @module Message
|
||||
* `Message` components trigger and display a confirmation message. They should only be used within a `Confirm` component.
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* <div class="box">
|
||||
* <Confirm as |c|>
|
||||
* <c.Message
|
||||
* @id={{item.id}}
|
||||
* @triggerText="Delete"
|
||||
* @message="This will permanently delete this secret and all its versions."
|
||||
* @onConfirm={{action "delete" item "secret"}}
|
||||
* />
|
||||
* </Confirm>
|
||||
* </div>
|
||||
* ```
|
||||
*
|
||||
* @property id=null {ID} - A unique identifier used to bind a trigger to a confirmation message.
|
||||
* @property onConfirm=null {Func} - The action to take when the user clicks the confirm button.
|
||||
* @property [triggerText='Delete'] {String} - The text on the trigger button.
|
||||
* @property [title='Delete this?'] {String} - The header text to display in the confirmation message.
|
||||
* @property [message='You will not be able to recover it later.'] {String} - The message to display above the confirm and cancel buttons.
|
||||
* @property [confirmButtonText='Delete'] {String} - The text to display on the confirm button.
|
||||
* @property [cancelButtonText='Cancel'] {String} - The text to display on the cancel button.
|
||||
*/
|
||||
|
||||
export default Component.extend({
|
||||
layout,
|
||||
tagName: '',
|
||||
renderedTrigger: null,
|
||||
id: null,
|
||||
onCancel() {},
|
||||
onConfirm() {},
|
||||
resetTrigger() {},
|
||||
title: 'Delete this?',
|
||||
message: 'You will not be able to recover it later.',
|
||||
triggerText: 'Delete',
|
||||
confirmButtonText: 'Delete',
|
||||
cancelButtonText: 'Cancel',
|
||||
showConfirm: computed('id', 'renderedTrigger', function () {
|
||||
return this.renderedTrigger === this.id;
|
||||
}),
|
||||
actions: {
|
||||
onConfirm() {
|
||||
this.onConfirm();
|
||||
this.resetTrigger();
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -1,12 +0,0 @@
|
||||
{{!
|
||||
Copyright (c) HashiCorp, Inc.
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
~}}
|
||||
|
||||
<li class="action">
|
||||
{{#if @loadingParam}}
|
||||
<LoadingDropdownOption />
|
||||
{{else}}
|
||||
{{yield}}
|
||||
{{/if}}
|
||||
</li>
|
||||
@ -1,23 +0,0 @@
|
||||
{{!
|
||||
Copyright (c) HashiCorp, Inc.
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
~}}
|
||||
|
||||
<div class="confirm-wrapper">
|
||||
<div class="confirm {{if this.openTrigger 'show-confirm'}}" ...attributes>
|
||||
{{yield
|
||||
(hash
|
||||
Message=(component
|
||||
"confirm/message"
|
||||
renderedTrigger=(readonly this.openTrigger)
|
||||
wormholeReference=this.wormholeReference
|
||||
onCancel=(action "onCancel")
|
||||
onTrigger=(action "onTrigger")
|
||||
resetTrigger=(action (mut this.openTrigger) "")
|
||||
)
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
<div id={{this.wormholeId}} class="confirm-overlay {{if this.openTrigger 'show-confirm'}}">
|
||||
</div>
|
||||
</div>
|
||||
@ -1,40 +0,0 @@
|
||||
{{!
|
||||
Copyright (c) HashiCorp, Inc.
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
~}}
|
||||
|
||||
{{#if this.showConfirm}}
|
||||
{{#maybe-in-element this.wormholeReference false}}
|
||||
<div class="confirm-action-message">
|
||||
<div class="message is-highlight">
|
||||
<div class="message-title">
|
||||
<Icon @name="alert-triangle-fill" />
|
||||
{{this.title}}
|
||||
</div>
|
||||
<p>
|
||||
{{this.message}}
|
||||
</p>
|
||||
</div>
|
||||
<div class="confirm-action-options">
|
||||
{{! TODO Hds::Button replacement - skipping because modal will replace this confirm inline-popup menu }}
|
||||
<button type="button" class="link is-destroy" data-test-confirm-button="true" onclick={{action "onConfirm"}}>
|
||||
{{this.confirmButtonText}}
|
||||
</button>
|
||||
<button type="button" class="link" data-test-confirm-cancel-button="true" {{action this.onCancel}}>
|
||||
{{this.cancelButtonText}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{{/maybe-in-element}}
|
||||
{{/if}}
|
||||
{{! TODO Hds::Button replacement - skipping because modal will replace this confirm inline-popup menu }}
|
||||
<button
|
||||
type="button"
|
||||
class="link is-destroy"
|
||||
disabled={{this.showConfirm}}
|
||||
onclick={{action this.onTrigger this.id}}
|
||||
data-test-confirm-action-trigger={{this.id}}
|
||||
...attributes
|
||||
>
|
||||
{{this.triggerText}}
|
||||
</button>
|
||||
@ -5,13 +5,11 @@
|
||||
|
||||
{{#if this.hasMenu}}
|
||||
<PopupMenu>
|
||||
<Confirm as |c|>
|
||||
<nav class="menu">
|
||||
<ul class="menu-list">
|
||||
{{yield (hash Message=c.Message)}}
|
||||
</ul>
|
||||
</nav>
|
||||
</Confirm>
|
||||
<nav class="menu">
|
||||
<ul class="menu-list">
|
||||
{{yield}}
|
||||
</ul>
|
||||
</nav>
|
||||
</PopupMenu>
|
||||
{{else}}
|
||||
{{yield this.item}}
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
export { default } from 'core/components/confirm';
|
||||
@ -1,6 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
export { default } from 'core/components/confirm/message';
|
||||
@ -1,6 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
export { default } from 'core/components/menu-loader';
|
||||
@ -64,32 +64,33 @@
|
||||
<Item.content>
|
||||
<Icon @name="file-text" class="has-text-grey-light" />{{list.item.id}}
|
||||
</Item.content>
|
||||
<Item.menu as |m|>
|
||||
<Item.menu>
|
||||
<li class="action">
|
||||
<LinkTo @route="credentials.show" @models={{array this.scope this.role list.item.id}} class="is-block">
|
||||
View credentials
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{#if list.item.deletePath.canDelete}}
|
||||
<MenuLoader @loadingParam={{list.item.deletePath.isPending}}>
|
||||
<m.Message
|
||||
@id={{list.item.id}}
|
||||
@triggerText="Revoke credentials"
|
||||
@title="Revoke this?"
|
||||
@message="Any client using these credentials will no longer be able to."
|
||||
@confirmButtonText="Revoke"
|
||||
@onConfirm={{action
|
||||
(perform
|
||||
Item.callMethod
|
||||
"destroyRecord"
|
||||
list.item
|
||||
"Successfully revoked credentials"
|
||||
"There was an error revoking the credentials"
|
||||
(action "refresh")
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</MenuLoader>
|
||||
{{#if list.item.deletePath.isPending}}
|
||||
<li class="action">
|
||||
<LoadingDropdownOption />
|
||||
</li>
|
||||
{{else if list.item.deletePath.canDelete}}
|
||||
<ConfirmAction
|
||||
@isInDropdown={{true}}
|
||||
@buttonText="Revoke credentials"
|
||||
@confirmTitle="Revoke this?"
|
||||
@confirmMessage="Any client using these credentials will no longer be able to."
|
||||
@onConfirmAction={{action
|
||||
(perform
|
||||
Item.callMethod
|
||||
"destroyRecord"
|
||||
list.item
|
||||
"Successfully revoked credentials"
|
||||
"There was an error revoking the credentials"
|
||||
(action "refresh")
|
||||
)
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
</Item.menu>
|
||||
</ListItem>
|
||||
|
||||
@ -17,15 +17,13 @@
|
||||
<ToolbarActions>
|
||||
{{#if this.model.deletePath.canDelete}}
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
@buttonText="Revoke credentials"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{this.revokeCredentials}}
|
||||
@confirmTitle="Revoke this?"
|
||||
@confirmMessage="Any client using these credentials will no longer be able to."
|
||||
@cancelButtonText="Cancel"
|
||||
@confirmButtonText="Revoke"
|
||||
>
|
||||
Revoke credentials
|
||||
</ConfirmAction>
|
||||
/>
|
||||
<div class="toolbar-separator"></div>
|
||||
{{/if}}
|
||||
<ToolbarLink @route="credentials.index" @models={{array this.scope this.role}} data-test-kmip-link-back-to-role>
|
||||
|
||||
@ -8,13 +8,12 @@
|
||||
<ToolbarActions>
|
||||
{{#if this.model.updatePath.canUpdate}}
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
@buttonText="Delete role"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{this.deleteRole}}
|
||||
@confirmMessage={{concat "Are you sure you want to delete " this.model.id "?"}}
|
||||
@cancelButtonText="Cancel"
|
||||
>
|
||||
Delete role
|
||||
</ConfirmAction>
|
||||
@confirmMessage="Are you sure you want to delete {{this.model.id}}?"
|
||||
/>
|
||||
<div class="toolbar-separator"></div>
|
||||
{{/if}}
|
||||
{{#if this.model.updatePath.canUpdate}}
|
||||
|
||||
@ -70,7 +70,7 @@
|
||||
<Item.content>
|
||||
<Icon @name="user" class="has-text-grey-light" />{{list.item.id}}
|
||||
</Item.content>
|
||||
<Item.menu as |m|>
|
||||
<Item.menu>
|
||||
<li class="action">
|
||||
<LinkTo @route="credentials" @models={{array this.scope list.item.id}} class="is-block">
|
||||
View credentials
|
||||
@ -81,20 +81,22 @@
|
||||
View role
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{#if list.item.updatePath.canUpdate}}
|
||||
<MenuLoader @loadingParam={{list.item.updatePath.isPending}}>
|
||||
{{#if list.item.updatePath.isPending}}
|
||||
<li class="action">
|
||||
<LoadingDropdownOption />
|
||||
</li>
|
||||
{{else}}
|
||||
{{#if list.item.updatePath.canUpdate}}
|
||||
<LinkTo @route="role.edit" @models={{array this.scope list.item.id}} class="is-block">
|
||||
Edit role
|
||||
</LinkTo>
|
||||
</MenuLoader>
|
||||
{{/if}}
|
||||
{{#if list.item.updatePath.canDelete}}
|
||||
<MenuLoader @loadingParam={{list.item.updatePath.isPending}}>
|
||||
<m.Message
|
||||
@id={{list.item.id}}
|
||||
@triggerText="Delete role"
|
||||
@message={{concat "Are you sure you want to delete " list.item.id "?"}}
|
||||
@onConfirm={{action
|
||||
{{/if}}
|
||||
{{#if list.item.updatePath.canDelete}}
|
||||
<ConfirmAction
|
||||
@isInDropdown={{true}}
|
||||
@buttonText="Delete role"
|
||||
@confirmMessage="Are you sure you want to delete {{list.item.id}}?"
|
||||
@onConfirmAction={{action
|
||||
(perform
|
||||
Item.callMethod
|
||||
"destroyRecord"
|
||||
@ -104,9 +106,9 @@
|
||||
(action "refresh")
|
||||
)
|
||||
}}
|
||||
data-test-scope-delete="true"
|
||||
data-test-scope-delete
|
||||
/>
|
||||
</MenuLoader>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</Item.menu>
|
||||
</ListItem>
|
||||
|
||||
@ -59,33 +59,34 @@
|
||||
<Item.content>
|
||||
<Icon @name="folder" class="has-text-grey-light" />{{list.item.id}}
|
||||
</Item.content>
|
||||
<Item.menu as |m|>
|
||||
<Item.menu>
|
||||
<li class="action">
|
||||
<LinkTo @route="scope" @model={{list.item.id}} class="is-block">
|
||||
View scope
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{#if list.item.updatePath.canDelete}}
|
||||
<MenuLoader @loadingParam={{list.item.updatePath.isPending}}>
|
||||
<m.Message
|
||||
@id={{list.item.id}}
|
||||
@triggerText="Delete scope"
|
||||
@title={{concat "Delete scope " list.item.id "?"}}
|
||||
@message="This will permanently delete this scope and all roles and credentials contained within"
|
||||
@cancelButtonText="Cancel"
|
||||
@onConfirm={{action
|
||||
(perform
|
||||
Item.callMethod
|
||||
"destroyRecord"
|
||||
list.item
|
||||
(concat "Successfully deleted scope " list.item.id)
|
||||
(concat "There was an error deleting the scope " list.item.id)
|
||||
(action "refresh")
|
||||
)
|
||||
}}
|
||||
data-test-scope-delete="true"
|
||||
/>
|
||||
</MenuLoader>
|
||||
{{#if list.item.updatePath.isPending}}
|
||||
<li class="action">
|
||||
<LoadingDropdownOption />
|
||||
</li>
|
||||
{{else if list.item.updatePath.canDelete}}
|
||||
<ConfirmAction
|
||||
@isInDropdown={{true}}
|
||||
@buttonText="Delete scope"
|
||||
@confirmTitle="Delete scope {{list.item.id}}?"
|
||||
@confirmMessage="This will permanently delete this scope and all roles and credentials contained within"
|
||||
@onConfirmAction={{action
|
||||
(perform
|
||||
Item.callMethod
|
||||
"destroyRecord"
|
||||
list.item
|
||||
(concat "Successfully deleted scope " list.item.id)
|
||||
(concat "There was an error deleting the scope " list.item.id)
|
||||
(action "refresh")
|
||||
)
|
||||
}}
|
||||
data-test-scope-delete
|
||||
/>
|
||||
{{/if}}
|
||||
</Item.menu>
|
||||
</ListItem>
|
||||
|
||||
@ -17,9 +17,13 @@
|
||||
<Toolbar>
|
||||
<ToolbarActions>
|
||||
{{#if @model.canDelete}}
|
||||
<ConfirmAction @buttonClasses="toolbar-link" @onConfirmAction={{this.delete}} data-test-delete>
|
||||
Delete role
|
||||
</ConfirmAction>
|
||||
<ConfirmAction
|
||||
@buttonText="Delete role"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{this.delete}}
|
||||
data-test-delete
|
||||
/>
|
||||
<div class="toolbar-separator"></div>
|
||||
{{/if}}
|
||||
{{#if @model.canGenerateCreds}}
|
||||
|
||||
@ -40,7 +40,7 @@
|
||||
<Icon @name="user" />
|
||||
<span data-test-role={{role.name}}>{{role.name}}</span>
|
||||
</Item.content>
|
||||
<Item.menu as |Menu|>
|
||||
<Item.menu>
|
||||
{{#if role.rolesPath.isLoading}}
|
||||
<li class="action">
|
||||
<Hds::Button disabled @color="tertiary" @icon="loading" @text="loading" @isIconOnly={{true}} />
|
||||
@ -68,16 +68,13 @@
|
||||
Edit
|
||||
</LinkTo>
|
||||
</li>
|
||||
<li class="action">
|
||||
<Menu.Message
|
||||
data-test-delete
|
||||
@id={{role.id}}
|
||||
@triggerText="Delete"
|
||||
@title="Are you sure?"
|
||||
@message="Deleting this role means that you’ll need to recreate it in order to generate credentials again."
|
||||
@onConfirm={{fn this.onDelete role}}
|
||||
/>
|
||||
</li>
|
||||
<ConfirmAction
|
||||
data-test-delete
|
||||
@isInDropdown={{true}}
|
||||
@buttonText="Delete"
|
||||
@confirmMessage="Deleting this role means that you’ll need to recreate it in order to generate credentials again."
|
||||
@onConfirmAction={{fn this.onDelete role}}
|
||||
/>
|
||||
{{/if}}
|
||||
</Item.menu>
|
||||
</ListItem>
|
||||
|
||||
@ -101,17 +101,12 @@
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if metadata.canDeleteMetadata}}
|
||||
<li>
|
||||
<ConfirmAction
|
||||
@buttonClasses="link is-destroy"
|
||||
@onConfirmAction={{fn this.onDelete metadata}}
|
||||
@confirmMessage="This will permanently delete this secret and all its versions."
|
||||
@cancelButtonText="Cancel"
|
||||
data-test-delete-metadata={{metadata.path}}
|
||||
>
|
||||
Permanently delete
|
||||
</ConfirmAction>
|
||||
</li>
|
||||
<ConfirmAction
|
||||
@buttonText="Permanently delete"
|
||||
@isInDropdown={{true}}
|
||||
@onConfirmAction={{fn this.onDelete metadata}}
|
||||
@confirmMessage="This will permanently delete this secret and all its versions."
|
||||
/>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</ul>
|
||||
|
||||
@ -7,16 +7,16 @@
|
||||
<:toolbarActions>
|
||||
{{#if @configModel}}
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
@buttonText="Rotate root"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{perform this.rotateRoot}}
|
||||
@confirmTitle="Rotate root?"
|
||||
@confirmMessage="After rotation, Vault will generate a new root password in your directory server."
|
||||
@confirmButtonText="Rotate"
|
||||
@disabled={{this.rotateRoot.isRunning}}
|
||||
@modalColor="warning"
|
||||
@isRunning={{this.rotateRoot.isRunning}}
|
||||
data-test-toolbar-rotate-action
|
||||
>
|
||||
Rotate root
|
||||
</ConfirmAction>
|
||||
/>
|
||||
{{/if}}
|
||||
<ToolbarLink @route="configure" data-test-toolbar-config-action>
|
||||
{{if @configModel "Edit configuration" "Configure LDAP"}}
|
||||
|
||||
@ -46,7 +46,7 @@
|
||||
<Icon @name="folder" />
|
||||
<span data-test-library={{library.name}}>{{library.name}}</span>
|
||||
</Item.content>
|
||||
<Item.menu as |Menu|>
|
||||
<Item.menu>
|
||||
{{#if library.libraryPath.isLoading}}
|
||||
<li class="action">
|
||||
<Hds::Button disabled @color="tertiary" @icon="loading" @text="loading" @isIconOnly={{true}} />
|
||||
@ -75,16 +75,14 @@
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{#if library.canDelete}}
|
||||
<li class="action">
|
||||
<Menu.Message
|
||||
data-test-delete
|
||||
@id={{library.id}}
|
||||
@triggerText="Delete"
|
||||
@title="Are you sure?"
|
||||
@message="This library and associated accounts will be permanently deleted. You will not be able to recover it."
|
||||
@onConfirm={{fn this.onDelete library}}
|
||||
/>
|
||||
</li>
|
||||
<ConfirmAction
|
||||
data-test-delete
|
||||
@id={{library.id}}
|
||||
@isInDropdown={{true}}
|
||||
@buttonText="Delete"
|
||||
@confirmMessage="This library and associated accounts will be permanently deleted. You will not be able to recover it."
|
||||
@onConfirmAction={{fn this.onDelete library}}
|
||||
/>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</Item.menu>
|
||||
|
||||
@ -26,9 +26,13 @@
|
||||
<Toolbar>
|
||||
<ToolbarActions>
|
||||
{{#if @model.canDelete}}
|
||||
<ConfirmAction @buttonClasses="toolbar-link" @onConfirmAction={{this.delete}} data-test-delete>
|
||||
Delete library
|
||||
</ConfirmAction>
|
||||
<ConfirmAction
|
||||
@buttonText="Delete library"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{this.delete}}
|
||||
data-test-delete
|
||||
/>
|
||||
{{#if @model.canEdit}}
|
||||
<div class="toolbar-separator"></div>
|
||||
{{/if}}
|
||||
|
||||
@ -17,9 +17,13 @@
|
||||
<Toolbar>
|
||||
<ToolbarActions>
|
||||
{{#if @model.canDelete}}
|
||||
<ConfirmAction @buttonClasses="toolbar-link" @onConfirmAction={{this.delete}} data-test-delete>
|
||||
Delete role
|
||||
</ConfirmAction>
|
||||
<ConfirmAction
|
||||
@buttonText="Delete role"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{this.delete}}
|
||||
data-test-delete
|
||||
/>
|
||||
<div class="toolbar-separator"></div>
|
||||
{{/if}}
|
||||
{{#if @model.canReadCreds}}
|
||||
@ -29,16 +33,16 @@
|
||||
{{/if}}
|
||||
{{#if @model.canRotateStaticCreds}}
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
@buttonText="Rotate credentials"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@confirmTitle="Rotate credentials?"
|
||||
@confirmMessage="When manually rotating credentials, the rotation period will start over."
|
||||
@confirmButtonText="Rotate"
|
||||
@disabled={{this.rotateCredentials.isRunning}}
|
||||
@modalColor="warning"
|
||||
@isRunning={{this.rotateCredentials.isRunning}}
|
||||
@onConfirmAction={{perform this.rotateCredentials}}
|
||||
data-test-rotate-credentials
|
||||
>
|
||||
Rotate credentials
|
||||
</ConfirmAction>
|
||||
/>
|
||||
{{/if}}
|
||||
{{#if @model.canEdit}}
|
||||
<ToolbarLink @route="roles.role.edit" data-test-edit>
|
||||
|
||||
@ -53,7 +53,7 @@
|
||||
<span data-test-role={{role.name}}>{{role.name}}</span>
|
||||
<Hds::Badge @text={{role.type}} data-test-role-type-badge={{role.name}} />
|
||||
</Item.content>
|
||||
<Item.menu as |Menu|>
|
||||
<Item.menu>
|
||||
{{#if role.rolePath.isLoading}}
|
||||
<li class="action">
|
||||
<Hds::Button disabled @color="tertiary" @icon="loading" @text="loading" @isIconOnly={{true}} />
|
||||
@ -82,17 +82,15 @@
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{#if role.canRotateStaticCreds}}
|
||||
<li class="action">
|
||||
<Menu.Message
|
||||
data-test-rotate-creds
|
||||
@id={{concat "rotate-" role.id}}
|
||||
@triggerText="Rotate credentials"
|
||||
@title="Are you sure?"
|
||||
@message="When manually rotating credentials, the rotation period will start over."
|
||||
@confirmButtonText="Rotate"
|
||||
@onConfirm={{fn this.onRotate role}}
|
||||
/>
|
||||
</li>
|
||||
<ConfirmAction
|
||||
data-test-rotate-creds
|
||||
@isInDropdown={{true}}
|
||||
@id={{concat "rotate-" role.id}}
|
||||
@buttonText="Rotate credentials"
|
||||
@confirmMessage="When manually rotating credentials, the rotation period will start over."
|
||||
@modalColor="warning"
|
||||
@onConfirmAction={{fn this.onRotate role}}
|
||||
/>
|
||||
{{/if}}
|
||||
<li class="action">
|
||||
<LinkTo
|
||||
@ -107,16 +105,13 @@
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{#if role.canDelete}}
|
||||
<li class="action">
|
||||
<Menu.Message
|
||||
data-test-delete
|
||||
@id={{concat "delete-" role.id}}
|
||||
@triggerText="Delete"
|
||||
@title="Are you sure?"
|
||||
@message="Deleting this role means that you’ll need to recreate it in order to generate credentials again."
|
||||
@onConfirm={{fn this.onDelete role}}
|
||||
/>
|
||||
</li>
|
||||
<ConfirmAction
|
||||
data-test-delete
|
||||
@isInDropdown={{true}}
|
||||
@buttonText="Delete"
|
||||
@confirmMessage="Deleting this role means that you’ll need to recreate it in order to generate credentials again."
|
||||
@onConfirmAction={{fn this.onDelete role}}
|
||||
/>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</Item.menu>
|
||||
|
||||
@ -15,14 +15,13 @@
|
||||
/>
|
||||
{{#if @model.canRevoke}}
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
@buttonText="Revoke certificate"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{fn (perform this.revoke)}}
|
||||
@confirmTitle="Revoke certificate?"
|
||||
@confirmButtonText="Revoke"
|
||||
data-test-pki-cert-revoke-button
|
||||
>
|
||||
Revoke certificate
|
||||
</ConfirmAction>
|
||||
/>
|
||||
{{/if}}
|
||||
</ToolbarActions>
|
||||
</Toolbar>
|
||||
|
||||
@ -7,14 +7,13 @@
|
||||
<ToolbarActions>
|
||||
{{#if @canDelete}}
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{this.deleteKey}}
|
||||
@confirmTitle="Delete key?"
|
||||
@confirmButtonText="Delete"
|
||||
@buttonText="Delete"
|
||||
data-test-pki-key-delete
|
||||
>
|
||||
Delete
|
||||
</ConfirmAction>
|
||||
/>
|
||||
<div class="toolbar-separator"></div>
|
||||
{{/if}}
|
||||
{{#if @key.privateKey}}
|
||||
|
||||
@ -7,14 +7,13 @@
|
||||
<ToolbarActions>
|
||||
{{#if @role.canDelete}}
|
||||
<ConfirmAction
|
||||
@buttonClasses="toolbar-link"
|
||||
class="toolbar-button"
|
||||
@buttonColor="secondary"
|
||||
@onConfirmAction={{this.deleteRole}}
|
||||
@confirmTitle="Delete role?"
|
||||
@confirmButtonText="Delete"
|
||||
@buttonText="Delete"
|
||||
data-test-pki-role-delete
|
||||
>
|
||||
Delete
|
||||
</ConfirmAction>
|
||||
/>
|
||||
<div class="toolbar-separator"></div>
|
||||
{{/if}}
|
||||
{{#if @role.canGenerateCert}}
|
||||
|
||||
@ -46,15 +46,12 @@
|
||||
{{#if this.model.canRevokeSecondary}}
|
||||
<li class="action">
|
||||
<ConfirmAction
|
||||
@buttonClasses="button link is-destroy"
|
||||
@buttonText="Revoke"
|
||||
@isInDropdown={{true}}
|
||||
@confirmTitle="Revoke token?"
|
||||
@confirmMessage="This will revoke this secondary token."
|
||||
@confirmButtonText="Revoke"
|
||||
@horizontalPosition="auto-left"
|
||||
@onConfirmAction={{action "onSubmit" "revoke-secondary" "primary" (hash id=secondary)}}
|
||||
>
|
||||
Revoke
|
||||
</ConfirmAction>
|
||||
/>
|
||||
</li>
|
||||
{{/if}}
|
||||
</ul>
|
||||
|
||||
@ -23,17 +23,12 @@
|
||||
<div class="field is-grouped box is-fullwidth is-bottomless">
|
||||
<div class="control">
|
||||
<ConfirmAction
|
||||
@buttonClasses="button is-primary"
|
||||
@buttonText="Revoke"
|
||||
@confirmTitle="Revoke token?"
|
||||
@confirmMessage="This will revoke this secondary token."
|
||||
@confirmButtonText="Revoke"
|
||||
@disabled={{not this.id}}
|
||||
@disabledMessage="A secondary ID is required perform revocation."
|
||||
@horizontalPosition="auto-left"
|
||||
@disabledMessage={{unless this.id "A secondary ID is required perform revocation."}}
|
||||
@onConfirmAction={{action "onSubmit" "revoke-secondary" "primary" (hash id=this.id)}}
|
||||
>
|
||||
Revoke
|
||||
</ConfirmAction>
|
||||
/>
|
||||
</div>
|
||||
<div class="control">
|
||||
{{#unless this.isRevoking}}
|
||||
|
||||
@ -107,9 +107,13 @@ module('Acceptance | mfa-method', function (hooks) {
|
||||
await visit('/vault/access/mfa/methods');
|
||||
await click('[data-test-mfa-method-list-item]');
|
||||
assert.dom('[data-test-tab="config"]').hasClass('active', 'Configuration tab is active by default');
|
||||
await click('[data-test-delete-mfa-config]');
|
||||
|
||||
assert
|
||||
.dom('[data-test-confirm-action-trigger]')
|
||||
.isDisabled('Delete toolbar action disabled when method is attached to an enforcement');
|
||||
.dom('[data-test-confirm-action-message]')
|
||||
.hasText(
|
||||
"This method cannot be deleted until its enforcements are deleted. This can be done from the 'Enforcements' tab."
|
||||
);
|
||||
|
||||
const fields = [
|
||||
['Issuer', 'Period', 'Key size', 'QR size', 'Algorithm', 'Digits', 'Skew', 'Max validation attempts'],
|
||||
|
||||
@ -81,7 +81,7 @@ module('Acceptance | oidc-config clients and keys', function (hooks) {
|
||||
// navigate to default key details from pop-up menu
|
||||
await click('[data-test-popup-menu-trigger]');
|
||||
await click('[data-test-oidc-key-menu-link="details"]');
|
||||
assert.dom(SELECTORS.keyDeleteButton).isDisabled('delete button is disabled for default key');
|
||||
assert.dom(SELECTORS.keyDeleteButton).doesNotExist('delete button is hidden for default key');
|
||||
await click(SELECTORS.keyEditButton);
|
||||
assert.strictEqual(
|
||||
currentRouteName(),
|
||||
|
||||
@ -376,7 +376,7 @@ module('Acceptance | oidc-config providers and scopes', function (hooks) {
|
||||
);
|
||||
await click('[data-test-oidc-provider-linked-block="default"] [data-test-popup-menu-trigger]');
|
||||
await click('[data-test-oidc-provider-menu-link="details"]');
|
||||
assert.dom(SELECTORS.providerDeleteButton).isDisabled('delete button is disabled for default provider');
|
||||
assert.dom(SELECTORS.providerDeleteButton).doesNotExist('delete button hidden for default provider');
|
||||
});
|
||||
|
||||
// PROVIDER DELETE + EDIT PERMISSIONS
|
||||
|
||||
@ -126,8 +126,8 @@ module('Acceptance | pki workflow', function (hooks) {
|
||||
|
||||
await visit(`/vault/secrets/${this.mountPath}/pki/roles/some-role/details`);
|
||||
assert.dom(SELECTORS.deleteRoleButton).exists('Delete role button is shown');
|
||||
await click(`${SELECTORS.deleteRoleButton} [data-test-confirm-action-trigger]`);
|
||||
await click(`[data-test-confirm-button]`);
|
||||
await click(SELECTORS.deleteRoleButton);
|
||||
await click('[data-test-confirm-button]');
|
||||
assert.strictEqual(
|
||||
currentURL(),
|
||||
`/vault/secrets/${this.mountPath}/pki/roles`,
|
||||
|
||||
@ -55,7 +55,7 @@ module('Acceptance | policies (old)', function (hooks) {
|
||||
|
||||
await click('[data-test-policy-edit-toggle]');
|
||||
|
||||
await click('[data-test-policy-delete] button');
|
||||
await click('[data-test-confirm-action-trigger]');
|
||||
|
||||
await click('[data-test-confirm-button]');
|
||||
await waitUntil(() => currentURL() === `/vault/policies/acl`);
|
||||
|
||||
@ -105,7 +105,7 @@ module('Acceptance | kubernetes | roles', function (hooks) {
|
||||
this.validateRoute(assert, 'roles.role.edit', 'Transitions to edit route');
|
||||
await click('[data-test-cancel]');
|
||||
await click('[data-test-list-item-link]');
|
||||
await click('[data-test-delete] button');
|
||||
await click('[data-test-delete]');
|
||||
await click('[data-test-confirm-button]');
|
||||
assert
|
||||
.dom('[data-test-list-item-link]')
|
||||
|
||||
@ -25,7 +25,7 @@ module('Acceptance | unseal', function (hooks) {
|
||||
assert.strictEqual(currentURL(), '/vault/settings/seal');
|
||||
|
||||
// seal
|
||||
await click('[data-test-seal] button');
|
||||
await click('[data-test-seal]');
|
||||
|
||||
await click('[data-test-confirm-button]');
|
||||
|
||||
|
||||
@ -12,12 +12,12 @@ export const SELECTORS = {
|
||||
oidcClientCreateButton: '[data-test-oidc-configure]',
|
||||
oidcRouteTabs: '[data-test-oidc-tabs]',
|
||||
oidcLandingImg: '[data-test-oidc-img]',
|
||||
confirmActionButton: '[data-test-confirm-button="true"]',
|
||||
confirmActionButton: '[data-test-confirm-button]',
|
||||
inlineAlert: '[data-test-inline-alert]',
|
||||
// client route
|
||||
clientSaveButton: '[data-test-oidc-client-save]',
|
||||
clientCancelButton: '[data-test-oidc-client-cancel]',
|
||||
clientDeleteButton: '[data-test-oidc-client-delete] button',
|
||||
clientDeleteButton: '[data-test-oidc-client-delete]',
|
||||
clientEditButton: '[data-test-oidc-client-edit]',
|
||||
clientDetailsTab: '[data-test-oidc-client-details]',
|
||||
clientProvidersTab: '[data-test-oidc-client-providers]',
|
||||
@ -26,14 +26,14 @@ export const SELECTORS = {
|
||||
assignmentSaveButton: '[data-test-oidc-assignment-save]',
|
||||
assignmentCreateButton: '[data-test-oidc-assignment-create]',
|
||||
assignmentEditButton: '[data-test-oidc-assignment-edit]',
|
||||
assignmentDeleteButton: '[data-test-oidc-assignment-delete] button',
|
||||
assignmentDeleteButton: '[data-test-oidc-assignment-delete]',
|
||||
assignmentCancelButton: '[data-test-oidc-assignment-cancel]',
|
||||
assignmentDetailsTab: '[data-test-oidc-assignment-details]',
|
||||
|
||||
// scope routes
|
||||
scopeSaveButton: '[data-test-oidc-scope-save]',
|
||||
scopeCancelButton: '[data-test-oidc-scope-cancel]',
|
||||
scopeDeleteButton: '[data-test-oidc-scope-delete] button',
|
||||
scopeDeleteButton: '[data-test-oidc-scope-delete]',
|
||||
scopeEditButton: '[data-test-oidc-scope-edit]',
|
||||
scopeDetailsTab: '[data-test-oidc-scope-details]',
|
||||
scopeEmptyState: '[data-test-oidc-scope-empty-state]',
|
||||
@ -43,16 +43,16 @@ export const SELECTORS = {
|
||||
// key route
|
||||
keySaveButton: '[data-test-oidc-key-save]',
|
||||
keyCancelButton: '[data-test-oidc-key-cancel]',
|
||||
keyDeleteButton: '[data-test-oidc-key-delete] button',
|
||||
keyDeleteButton: '[data-test-oidc-key-delete]',
|
||||
keyEditButton: '[data-test-oidc-key-edit]',
|
||||
keyRotateButton: '[data-test-oidc-key-rotate] button',
|
||||
keyRotateButton: '[data-test-oidc-key-rotate]',
|
||||
keyDetailsTab: '[data-test-oidc-key-details]',
|
||||
keyClientsTab: '[data-test-oidc-key-clients]',
|
||||
|
||||
// provider route
|
||||
providerSaveButton: '[data-test-oidc-provider-save]',
|
||||
providerCancelButton: '[data-test-oidc-provider-cancel]',
|
||||
providerDeleteButton: '[data-test-oidc-provider-delete] button',
|
||||
providerDeleteButton: '[data-test-oidc-provider-delete]',
|
||||
providerEditButton: '[data-test-oidc-provider-edit]',
|
||||
providerDetailsTab: '[data-test-oidc-provider-details]',
|
||||
providerClientsTab: '[data-test-oidc-provider-clients]',
|
||||
|
||||
@ -18,7 +18,7 @@ export const SELECTORS = {
|
||||
keyNameValue: '[data-test-value-div="Key name"]',
|
||||
keyTypeValue: '[data-test-value-div="Key type"]',
|
||||
keyBitsValue: '[data-test-value-div="Key bits"]',
|
||||
keyDeleteButton: '[data-test-pki-key-delete] button',
|
||||
keyDeleteButton: '[data-test-pki-key-delete]',
|
||||
downloadButton: '[data-test-download-button]',
|
||||
keyEditLink: '[data-test-pki-key-edit]',
|
||||
confirmDelete: '[data-test-confirm-button]',
|
||||
|
||||
@ -5,54 +5,155 @@
|
||||
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, click } from '@ember/test-helpers';
|
||||
import { render, click, find } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import sinon from 'sinon';
|
||||
|
||||
const SELECTORS = {
|
||||
modalToggle: '[data-test-confirm-action-trigger]',
|
||||
title: '[data-test-confirm-action-title]',
|
||||
message: '[data-test-confirm-action-message]',
|
||||
confirm: '[data-test-confirm-button]',
|
||||
cancel: '[data-test-confirm-cancel-button]',
|
||||
};
|
||||
module('Integration | Component | confirm-action', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders and on click shows the correct icon', async function (assert) {
|
||||
const confirmAction = sinon.spy();
|
||||
this.set('onConfirm', confirmAction);
|
||||
await render(hbs`
|
||||
<ConfirmAction
|
||||
@onConfirmAction={{this.onConfirm}}
|
||||
@buttonClasses="toolbar-link"
|
||||
>
|
||||
DELETE
|
||||
</ConfirmAction>
|
||||
`);
|
||||
assert.dom('[data-test-icon="chevron-down"]').exists('Icon is pointing down');
|
||||
await click('[data-test-confirm-action-trigger="true"]');
|
||||
assert.dom('[data-test-icon="chevron-up"]').exists('Icon is now pointing up');
|
||||
assert.dom('[data-test-confirm-action-title]').hasText('Delete this?');
|
||||
hooks.beforeEach(function () {
|
||||
this.onConfirm = sinon.spy();
|
||||
});
|
||||
|
||||
test('it closes the confirmation modal on successful delete', async function (assert) {
|
||||
const confirmAction = sinon.spy();
|
||||
this.set('onConfirm', confirmAction);
|
||||
test('it renders defaults and calls onConfirmAction', async function (assert) {
|
||||
await render(hbs`
|
||||
<ConfirmAction
|
||||
@buttonText="DELETE"
|
||||
@onConfirmAction={{this.onConfirm}}
|
||||
@buttonClasses="toolbar-link"
|
||||
>
|
||||
DELETE
|
||||
</ConfirmAction>
|
||||
/>
|
||||
`);
|
||||
await click('[data-test-confirm-action-trigger="true"]');
|
||||
await click('[data-test-confirm-cancel-button="true"]');
|
||||
// assert that after CANCEL the icon button is pointing down.
|
||||
assert.dom('[data-test-icon="chevron-down"]').exists('Icon is pointing down after clicking cancel');
|
||||
// open the modal again to test the DELETE action
|
||||
await click('[data-test-confirm-action-trigger="true"]');
|
||||
await click('[data-test-confirm-button="true"]');
|
||||
|
||||
assert.dom(SELECTORS.modalToggle).hasText('DELETE', 'renders button text');
|
||||
await click(SELECTORS.modalToggle);
|
||||
// hasClass assertion wasn't working so this is the workaround
|
||||
assert.strictEqual(
|
||||
find('#confirm-action-modal').className,
|
||||
'hds-modal hds-modal--size-small hds-modal--color-critical',
|
||||
'renders critical modal color by default'
|
||||
);
|
||||
assert.strictEqual(
|
||||
find(SELECTORS.confirm).className,
|
||||
'hds-button hds-button--size-medium hds-button--color-critical',
|
||||
'renders critical confirm button'
|
||||
);
|
||||
assert.dom(SELECTORS.title).hasText('Are you sure?', 'renders default title');
|
||||
assert
|
||||
.dom('[data-test-icon="chevron-down"]')
|
||||
.exists('Icon is pointing down after executing the Delete action');
|
||||
assert.true(confirmAction.called, 'calls the action when Delete is pressed');
|
||||
.dom(SELECTORS.message)
|
||||
.hasText('You will not be able to recover it later.', 'renders default body text');
|
||||
await click(SELECTORS.cancel);
|
||||
assert.false(this.onConfirm.called, 'does not call the action when Cancel is clicked');
|
||||
await click(SELECTORS.modalToggle);
|
||||
await click(SELECTORS.confirm);
|
||||
assert.true(this.onConfirm.called, 'calls the action when Confirm is clicked');
|
||||
assert.dom(SELECTORS.title).doesNotExist('modal closes after confirm is clicked');
|
||||
});
|
||||
|
||||
test('it renders isInDropdown defaults and calls onConfirmAction', async function (assert) {
|
||||
await render(hbs`
|
||||
<ConfirmAction
|
||||
@buttonText="DELETE"
|
||||
@onConfirmAction={{this.onConfirm}}
|
||||
@isInDropdown={{true}}
|
||||
/>
|
||||
`);
|
||||
|
||||
assert.dom(`li ${SELECTORS.modalToggle}`).exists('element renders inside <li>');
|
||||
assert.dom(SELECTORS.modalToggle).hasClass('hds-confirm-action-critical', 'button has dropdown styling');
|
||||
await click(SELECTORS.modalToggle);
|
||||
assert.dom(SELECTORS.title).hasText('Are you sure?', 'renders default title');
|
||||
assert
|
||||
.dom('[data-test-confirm-action-title]')
|
||||
.doesNotExist('it has closed the confirm content and does not show the title');
|
||||
.dom(SELECTORS.message)
|
||||
.hasText('You will not be able to recover it later.', 'renders default body text');
|
||||
await click('[data-test-confirm-cancel-button]');
|
||||
assert.false(this.onConfirm.called, 'does not call the action when Cancel is clicked');
|
||||
await click(SELECTORS.modalToggle);
|
||||
await click(SELECTORS.confirm);
|
||||
assert.true(this.onConfirm.called, 'calls the action when Confirm is clicked');
|
||||
assert.dom(SELECTORS.title).doesNotExist('modal closes after confirm is clicked');
|
||||
});
|
||||
|
||||
test('it renders loading state', async function (assert) {
|
||||
await render(hbs`
|
||||
<ConfirmAction
|
||||
@buttonText="Open!"
|
||||
@onConfirmAction={{this.onConfirm}}
|
||||
@isRunning={{true}}
|
||||
/>
|
||||
`);
|
||||
|
||||
await click(SELECTORS.modalToggle);
|
||||
|
||||
assert.dom(SELECTORS.confirm).isDisabled('disables confirm button when loading');
|
||||
assert.dom('[data-test-confirm-button] [data-test-icon="loading"]').exists('it renders loading icon');
|
||||
});
|
||||
|
||||
test('it renders disabledMessage modal', async function (assert) {
|
||||
this.condition = true;
|
||||
await render(hbs`
|
||||
<ConfirmAction
|
||||
@buttonText="Open!"
|
||||
@onConfirmAction={{this.onConfirm}}
|
||||
@confirmTitle="Do this?"
|
||||
@confirmMessage="Are you really, really sure?"
|
||||
@disabledMessage={{if this.condition "This is the reason you cannot do the thing"}}
|
||||
/>
|
||||
`);
|
||||
|
||||
await click(SELECTORS.modalToggle);
|
||||
assert.strictEqual(
|
||||
find('#confirm-action-modal').className,
|
||||
'hds-modal hds-modal--size-small hds-modal--color-neutral',
|
||||
'renders critical modal color by default'
|
||||
);
|
||||
assert.dom(SELECTORS.title).hasText('Not allowed', 'renders disabled title');
|
||||
assert
|
||||
.dom(SELECTORS.message)
|
||||
.hasText('This is the reason you cannot do the thing', 'renders disabled message as body text');
|
||||
assert.dom(SELECTORS.confirm).doesNotExist('does not render confirm action button');
|
||||
assert.dom(SELECTORS.cancel).hasText('Close');
|
||||
});
|
||||
|
||||
test('it renders passed args', async function (assert) {
|
||||
this.condition = false;
|
||||
await render(hbs`
|
||||
<ConfirmAction
|
||||
@buttonText="Open!"
|
||||
@onConfirmAction={{this.onConfirm}}
|
||||
@modalColor="warning"
|
||||
@buttonColor="secondary"
|
||||
@confirmTitle="Do this?"
|
||||
@confirmMessage="Are you really, really sure?"
|
||||
@disabledMessage={{if this.condition "This is the reason you cannot do the thing"}}
|
||||
/>
|
||||
`);
|
||||
|
||||
// hasClass assertion wasn't working so this is the workaround
|
||||
assert.strictEqual(
|
||||
find(SELECTORS.modalToggle).className,
|
||||
'hds-button hds-button--size-medium hds-button--color-secondary',
|
||||
'renders @buttonColor classes'
|
||||
);
|
||||
await click(SELECTORS.modalToggle);
|
||||
assert.strictEqual(
|
||||
find('#confirm-action-modal').className,
|
||||
'hds-modal hds-modal--size-small hds-modal--color-warning',
|
||||
'renders warning modal'
|
||||
);
|
||||
assert.strictEqual(
|
||||
find(SELECTORS.confirm).className,
|
||||
'hds-button hds-button--size-medium hds-button--color-primary',
|
||||
'renders primary confirm button'
|
||||
);
|
||||
assert.dom(SELECTORS.title).hasText('Do this?', 'renders passed title');
|
||||
assert.dom(SELECTORS.message).hasText('Are you really, really sure?', 'renders passed body text');
|
||||
assert.dom(SELECTORS.confirm).hasText('Confirm');
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,107 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, click } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import sinon from 'sinon';
|
||||
|
||||
module('Integration | Component | Confirm', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
this.set('id', 'foo');
|
||||
this.set('title', 'Are you sure?');
|
||||
this.set('message', 'You will not be able to recover this item later.');
|
||||
this.set('triggerText', 'Click me!');
|
||||
this.set('onConfirm', sinon.spy());
|
||||
});
|
||||
|
||||
test('it renders', async function (assert) {
|
||||
await render(hbs`
|
||||
<Confirm as |c|>
|
||||
<c.Message
|
||||
@id={{this.id}}
|
||||
@title={{this.title}}
|
||||
@triggerText={{this.triggerText}}
|
||||
@message={{this.message}}
|
||||
@onConfirm={{this.onConfirm}}
|
||||
/>
|
||||
</Confirm>
|
||||
`);
|
||||
|
||||
assert.dom('.confirm-wrapper').exists();
|
||||
assert.dom('.confirm').containsText(this.triggerText);
|
||||
});
|
||||
|
||||
test('does not show the confirmation message until it is triggered', async function (assert) {
|
||||
await render(hbs`
|
||||
<Confirm as |c|>
|
||||
<c.Message
|
||||
@id={{this.id}}
|
||||
@title={{this.title}}
|
||||
@triggerText={{this.triggerText}}
|
||||
@message={{this.message}}
|
||||
@onConfirm={{this.onConfirm}}
|
||||
/>
|
||||
</Confirm>
|
||||
`);
|
||||
assert.dom('.confirm-overlay').doesNotContainText(this.message);
|
||||
|
||||
await click('[data-test-confirm-action-trigger]');
|
||||
|
||||
assert.dom('.confirm-overlay').containsText(this.title);
|
||||
assert.dom('.confirm-overlay').containsText(this.message);
|
||||
});
|
||||
|
||||
test('it calls onConfirm when the confirm button is clicked', async function (assert) {
|
||||
await render(hbs`
|
||||
<Confirm as |c|>
|
||||
<c.Message
|
||||
@id={{this.id}}
|
||||
@title={{this.title}}
|
||||
@triggerText={{this.triggerText}}
|
||||
@message={{this.message}}
|
||||
@onConfirm={{this.onConfirm}}
|
||||
/>
|
||||
</Confirm>
|
||||
`);
|
||||
await click('[data-test-confirm-action-trigger]');
|
||||
await click('[data-test-confirm-button=true]');
|
||||
|
||||
assert.ok(this.onConfirm.calledOnce);
|
||||
});
|
||||
|
||||
test('it shows only the active triggers message', async function (assert) {
|
||||
await render(hbs`
|
||||
<Confirm as |c|>
|
||||
<c.Message
|
||||
@id={{this.id}}
|
||||
@title={{this.title}}
|
||||
@triggerText={{this.triggerText}}
|
||||
@message={{this.message}}
|
||||
@onConfirm={{this.onConfirm}}
|
||||
/>
|
||||
<c.Message
|
||||
@id='bar'
|
||||
@title='Wow'
|
||||
@message='Bazinga!'
|
||||
@onConfirm={{this.onConfirm}}
|
||||
/>
|
||||
</Confirm>
|
||||
`);
|
||||
|
||||
await click(`[data-test-confirm-action-trigger=${this.id}]`);
|
||||
assert.dom('.confirm-overlay').containsText(this.title);
|
||||
assert.dom('.confirm-overlay').containsText(this.message);
|
||||
|
||||
await click('[data-test-confirm-cancel-button]');
|
||||
|
||||
await click("[data-test-confirm-action-trigger='bar']");
|
||||
assert.dom('.confirm-overlay').containsText('Wow');
|
||||
assert.dom('.confirm-overlay').containsText('Bazinga!');
|
||||
});
|
||||
});
|
||||
@ -8,7 +8,7 @@ import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import { setupMirage } from 'ember-cli-mirage/test-support';
|
||||
import { click, triggerEvent, settled, fillIn } from '@ember/test-helpers';
|
||||
import { click, settled, fillIn } from '@ember/test-helpers';
|
||||
|
||||
const ts = 'data-test-kms-provider';
|
||||
const root = {
|
||||
@ -48,7 +48,7 @@ module('Integration | Component | keymgmt/provider-edit', function (hooks) {
|
||||
});
|
||||
|
||||
test('it should render show view', async function (assert) {
|
||||
assert.expect(16);
|
||||
assert.expect(10);
|
||||
|
||||
// override capability getters
|
||||
Object.defineProperties(this.model, {
|
||||
@ -64,17 +64,6 @@ module('Integration | Component | keymgmt/provider-edit', function (hooks) {
|
||||
},
|
||||
};
|
||||
});
|
||||
this.server.delete('/keymgmt/kms/foo-bar', () => {
|
||||
assert.ok(true, 'Request made to delete key');
|
||||
return {};
|
||||
});
|
||||
this.owner.lookup('service:router').reopen({
|
||||
transitionTo(path, model, { queryParams: { tab } }) {
|
||||
assert.strictEqual(path, root.path, 'Root path sent in transitionTo on delete');
|
||||
assert.strictEqual(model, root.model, 'Root model sent in transitionTo on delete');
|
||||
assert.deepEqual(tab, 'provider', 'Correct query params sent in transitionTo on delete');
|
||||
},
|
||||
});
|
||||
|
||||
const changeTab = async (tab) => {
|
||||
this.set('tab', tab);
|
||||
@ -104,16 +93,58 @@ module('Integration | Component | keymgmt/provider-edit', function (hooks) {
|
||||
assert.dom('[data-test-secret-link]').exists({ count: 2 }, 'Keys list renders');
|
||||
|
||||
await changeTab('details');
|
||||
assert.dom(`[${ts}-delete] button`).isDisabled('Delete action disabled when keys exist');
|
||||
await triggerEvent(`[data-test-tooltip-trigger]`, 'mouseenter');
|
||||
assert.dom(`[${ts}-delete-tooltip]`).exists('Tooltip is show when delete action is disabled');
|
||||
await click(`[${ts}-delete]`);
|
||||
assert
|
||||
.dom('[data-test-confirm-action-message]')
|
||||
.hasText(
|
||||
'This provider cannot be deleted until all 2 key(s) distributed to it are revoked. This can be done from the Keys tab.',
|
||||
'Renders disabled message'
|
||||
);
|
||||
await click('[data-test-confirm-cancel-button]');
|
||||
});
|
||||
|
||||
test('it should delete a provider', async function (assert) {
|
||||
assert.expect(5);
|
||||
|
||||
// override capability getters
|
||||
Object.defineProperties(this.model, {
|
||||
canDelete: { value: true },
|
||||
canListKeys: { value: true },
|
||||
});
|
||||
|
||||
this.server.post('/sys/capabilities-self', () => ({}));
|
||||
this.server.get('/keymgmt/kms/foo-bar/key', () => {
|
||||
return {
|
||||
data: {
|
||||
keys: [],
|
||||
},
|
||||
};
|
||||
});
|
||||
this.server.delete('/keymgmt/kms/foo-bar', () => {
|
||||
assert.ok(true, 'Request made to delete key');
|
||||
return {};
|
||||
});
|
||||
this.owner.lookup('service:router').reopen({
|
||||
transitionTo(path, model, { queryParams: { tab } }) {
|
||||
assert.strictEqual(path, root.path, 'Root path sent in transitionTo on delete');
|
||||
assert.strictEqual(model, root.model, 'Root model sent in transitionTo on delete');
|
||||
assert.deepEqual(tab, 'provider', 'Correct query params sent in transitionTo on delete');
|
||||
},
|
||||
});
|
||||
|
||||
await render(hbs`
|
||||
<Keymgmt::ProviderEdit
|
||||
@root={{this.root}}
|
||||
@model={{this.model}}
|
||||
@mode="show"
|
||||
@tab={{this.tab}}
|
||||
/>`);
|
||||
|
||||
this.model.keys = [];
|
||||
await settled();
|
||||
assert
|
||||
.dom('[data-test-value-div="Keys"]')
|
||||
.hasText('None', 'None is displayed when no keys exist for provider');
|
||||
await click(`[${ts}-delete] button`);
|
||||
|
||||
await click(`[${ts}-delete]`);
|
||||
await click('[data-test-confirm-button]');
|
||||
});
|
||||
|
||||
|
||||
@ -104,13 +104,13 @@ module('Integration | Component | kubernetes | Page::Role::Details', function (h
|
||||
return;
|
||||
});
|
||||
|
||||
assert.dom('[data-test-delete] button').hasText('Delete role', 'Delete action renders');
|
||||
assert.dom('[data-test-delete]').hasText('Delete role', 'Delete action renders');
|
||||
assert
|
||||
.dom('[data-test-generate-credentials]')
|
||||
.hasText('Generate credentials', 'Generate credentials action renders');
|
||||
assert.dom('[data-test-edit]').hasText('Edit role', 'Edit action renders');
|
||||
|
||||
await click('[data-test-delete] button');
|
||||
await click('[data-test-delete]');
|
||||
await click('[data-test-confirm-button]');
|
||||
assert.ok(
|
||||
transitionStub.calledWith('vault.cluster.secrets.backend.kubernetes.roles'),
|
||||
|
||||
@ -80,8 +80,8 @@ module('Integration | Component | kv | Page::List', function (hooks) {
|
||||
|
||||
const popupSelector = `${PAGE.list.item('my-secret-0')} ${PAGE.popup}`;
|
||||
await click(popupSelector);
|
||||
await click('[data-test-confirm-action-trigger="true"]');
|
||||
await click('[data-test-confirm-button=true]');
|
||||
await click('[data-test-confirm-action-trigger]');
|
||||
await click('[data-test-confirm-button]');
|
||||
assert.dom(PAGE.list.item('my-secret-0')).doesNotExist('deleted the first record from the list');
|
||||
});
|
||||
});
|
||||
|
||||
@ -13,7 +13,7 @@ import { duration } from 'core/helpers/format-duration';
|
||||
import { createSecretsEngine, generateBreadcrumbs } from 'vault/tests/helpers/ldap';
|
||||
|
||||
const selectors = {
|
||||
rotateAction: '[data-test-toolbar-rotate-action] button',
|
||||
rotateAction: '[data-test-toolbar-rotate-action]',
|
||||
confirmRotate: '[data-test-confirm-button]',
|
||||
configAction: '[data-test-toolbar-config-action]',
|
||||
configCta: '[data-test-config-cta]',
|
||||
|
||||
@ -65,11 +65,11 @@ module('Integration | Component | ldap | Page::Library::Details', function (hook
|
||||
assert.dom('[data-test-tab="accounts"]').hasText('Accounts', 'Accounts tab renders');
|
||||
assert.dom('[data-test-tab="config"]').hasText('Configuration', 'Configuration tab renders');
|
||||
|
||||
assert.dom('[data-test-delete] button').hasText('Delete library', 'Delete action renders');
|
||||
assert.dom('[data-test-delete]').hasText('Delete library', 'Delete action renders');
|
||||
assert.dom('[data-test-edit]').hasText('Edit library', 'Edit action renders');
|
||||
|
||||
const transitionStub = sinon.stub(this.owner.lookup('service:router'), 'transitionTo');
|
||||
await click('[data-test-delete] button');
|
||||
await click('[data-test-delete]');
|
||||
await click('[data-test-confirm-button]');
|
||||
assert.ok(
|
||||
transitionStub.calledWith('vault.cluster.secrets.backend.ldap.libraries'),
|
||||
|
||||
@ -61,7 +61,7 @@ module('Integration | Component | ldap | Page::Role::Details', function (hooks)
|
||||
|
||||
await this.renderComponent('static');
|
||||
|
||||
assert.dom('[data-test-delete] button').hasText('Delete role', 'Delete action renders');
|
||||
assert.dom('[data-test-delete]').hasText('Delete role', 'Delete action renders');
|
||||
assert.dom('[data-test-get-credentials]').hasText('Get credentials', 'Get credentials action renders');
|
||||
assert.dom('[data-test-rotate-credentials]').exists('Rotate credentials action renders for static role');
|
||||
assert.dom('[data-test-edit]').hasText('Edit role', 'Edit action renders');
|
||||
@ -78,7 +78,7 @@ module('Integration | Component | ldap | Page::Role::Details', function (hooks)
|
||||
.dom('[data-test-rotate-credentials]')
|
||||
.doesNotExist('Rotate credentials action is hidden for dynamic role');
|
||||
|
||||
await click('[data-test-delete] button');
|
||||
await click('[data-test-delete]');
|
||||
await click('[data-test-confirm-button]');
|
||||
assert.ok(
|
||||
transitionStub.calledWith('vault.cluster.secrets.backend.ldap.roles'),
|
||||
|
||||
@ -24,7 +24,7 @@ module('Integration | Component | seal-action', function (hooks) {
|
||||
await render(hbs`<SealAction @onSeal={{action this.handleSeal}} />`);
|
||||
|
||||
// attempt seal
|
||||
await click('[data-test-seal] button');
|
||||
await click('[data-test-seal]');
|
||||
await click('[data-test-confirm-button]');
|
||||
|
||||
assert.ok(this.sealSuccess.calledOnce, 'called onSeal action');
|
||||
@ -36,7 +36,7 @@ module('Integration | Component | seal-action', function (hooks) {
|
||||
await render(hbs`<SealAction @onSeal={{action this.handleSeal}} />`);
|
||||
|
||||
// attempt seal
|
||||
await click('[data-test-seal] button');
|
||||
await click('[data-test-seal]');
|
||||
await click('[data-test-confirm-button]');
|
||||
|
||||
assert.ok(this.sealError.calledOnce, 'called onSeal action');
|
||||
|
||||
@ -16,10 +16,6 @@ export default create({
|
||||
findPolicyByName(name) {
|
||||
return this.policies.filterBy('name', name)[0];
|
||||
},
|
||||
delete: clickable('[data-test-confirm-action-trigger]', {
|
||||
testContainer: '#ember-testing',
|
||||
}),
|
||||
confirmDelete: clickable('[data-test-confirm-button]', {
|
||||
testContainer: '#ember-testing',
|
||||
}),
|
||||
delete: clickable('[data-test-confirm-action-trigger]'),
|
||||
confirmDelete: clickable('[data-test-confirm-button]'),
|
||||
});
|
||||
|
||||
@ -6,6 +6,6 @@
|
||||
import { clickable, create, isPresent, visitable } from 'ember-cli-page-object';
|
||||
export default create({
|
||||
visit: visitable('/vault/policy/:type/:name/edit'),
|
||||
deleteIsPresent: isPresent('[data-test-policy-delete]'),
|
||||
deleteIsPresent: isPresent('[data-test-confirm-action-trigger]'),
|
||||
toggleEdit: clickable('[data-test-policy-edit-toggle]'),
|
||||
});
|
||||
|
||||
@ -11,7 +11,7 @@ export default create({
|
||||
breadcrumbs: collection('[data-test-secret-breadcrumb]', {
|
||||
text: text(),
|
||||
}),
|
||||
deleteBtnV1: clickable('[data-test-secret-v1-delete="true"] button'),
|
||||
deleteBtnV1: clickable('[data-test-secret-v1-delete]'),
|
||||
confirmBtn: clickable('[data-test-confirm-button]'),
|
||||
rows: collection('data-test-row-label'),
|
||||
edit: clickable('[data-test-secret-edit]'),
|
||||
|
||||
@ -33,12 +33,8 @@ export default create({
|
||||
menuItems: collection('.ember-basic-dropdown-content li', {
|
||||
testContainer: '#ember-testing',
|
||||
}),
|
||||
delete: clickable('[data-test-confirm-action-trigger]', {
|
||||
testContainer: '#ember-testing',
|
||||
}),
|
||||
confirmDelete: clickable('[data-test-confirm-button]', {
|
||||
testContainer: '#ember-testing',
|
||||
}),
|
||||
delete: clickable('[data-test-confirm-action-trigger]'),
|
||||
confirmDelete: clickable('[data-test-confirm-button]'),
|
||||
backendIsEmpty: getter(function () {
|
||||
return this.secrets.length === 0;
|
||||
}),
|
||||
|
||||
@ -16,11 +16,7 @@ export default create({
|
||||
configLink: clickable('[data-test-engine-config]', {
|
||||
testContainer: '#ember-testing',
|
||||
}),
|
||||
disableButton: clickable('[data-test-confirm-action-trigger]', {
|
||||
testContainer: '#ember-testing',
|
||||
}),
|
||||
confirmDisable: clickable('[data-test-confirm-button]', {
|
||||
testContainer: '#ember-testing',
|
||||
}),
|
||||
disableButton: clickable('[data-test-confirm-action-trigger]'),
|
||||
confirmDisable: clickable('[data-test-confirm-button]'),
|
||||
console: uiPanel,
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user