KV automatic delete state issue in UI (#13166)
* converts secret-v2-version model to native class -- fixes issues with cached values for deleted prop * adds changelog entry * adds disabled state to ToolbarLink component and disables create new version action when users cannot read metadata * updates secret-edit acceptance test
This commit is contained in:
parent
201526e983
commit
516f18f736
|
@ -0,0 +1,3 @@
|
|||
```release-note:bug
|
||||
ui: Fixes issue with placeholder not displaying for automatically deleted secrets when deletion time has passed
|
||||
```
|
|
@ -1,20 +1,21 @@
|
|||
import { belongsTo, attr } from '@ember-data/model';
|
||||
import Secret from './secret';
|
||||
import { computed } from '@ember/object';
|
||||
import SecretModel from './secret';
|
||||
|
||||
export default Secret.extend({
|
||||
failedServerRead: attr('boolean'),
|
||||
pathAttr: 'path',
|
||||
version: attr('number'),
|
||||
secret: belongsTo('secret-v2'),
|
||||
path: attr('string'),
|
||||
deletionTime: attr('string'),
|
||||
createdTime: attr('string'),
|
||||
deleted: computed('deletionTime', function() {
|
||||
export default class SecretV2VersionModel extends SecretModel {
|
||||
@attr('boolean') failedServerRead;
|
||||
@attr('number') version;
|
||||
@attr('string') path;
|
||||
@attr('string') deletionTime;
|
||||
@attr('string') createdTime;
|
||||
@attr('boolean') detroyed;
|
||||
@attr('number') currentVersion;
|
||||
@belongsTo('secret-v2') secret;
|
||||
|
||||
pathAttr = 'path';
|
||||
|
||||
get deleted() {
|
||||
const deletionTime = new Date(this.deletionTime);
|
||||
const now = new Date();
|
||||
return deletionTime <= now;
|
||||
}),
|
||||
destroyed: attr('boolean'),
|
||||
currentVersion: attr('number'),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -155,12 +155,9 @@ export default Route.extend(UnloadModelRoute, {
|
|||
try {
|
||||
if (secretModel.failedServerRead) {
|
||||
// we couldn't read metadata, so we want to directly fetch the version
|
||||
|
||||
versionModel =
|
||||
this.store.peekRecord('secret-v2-version', JSON.stringify(versionId)) ||
|
||||
(await this.store.findRecord('secret-v2-version', JSON.stringify(versionId), {
|
||||
reload: true,
|
||||
}));
|
||||
versionModel = await this.store.findRecord('secret-v2-version', JSON.stringify(versionId), {
|
||||
reload: true,
|
||||
});
|
||||
} else {
|
||||
// we may have previously errored, so roll it back here
|
||||
version.rollbackAttributes();
|
||||
|
|
|
@ -84,7 +84,7 @@
|
|||
color: $black;
|
||||
transition: background-color $speed;
|
||||
|
||||
&:hover {
|
||||
&:hover:not(.disabled) {
|
||||
background-color: $ui-gray-100;
|
||||
border: 0;
|
||||
color: $blue;
|
||||
|
@ -98,6 +98,18 @@
|
|||
height: 2.5rem;
|
||||
padding: $size-10 $size-8;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.5;
|
||||
cursor: default;
|
||||
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
&:hover {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.toolbar-separator {
|
||||
|
|
|
@ -101,6 +101,8 @@
|
|||
@data-test-secret-edit="true"
|
||||
@replace={{true}}
|
||||
@type="add"
|
||||
@disabled={{@model.failedServerRead}}
|
||||
@disabledTooltip="Metadata read access is required to create new version"
|
||||
>
|
||||
Create new version
|
||||
</ToolbarLink>
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"experimentalDecorators": true,
|
||||
"allowJs": true
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
|
@ -7,15 +7,17 @@
|
|||
* ```js
|
||||
* <Toolbar>
|
||||
* <ToolbarActions>
|
||||
* <ToolbarLink @params={{array 'vault.cluster.policies.create'}} @type="add">
|
||||
* <ToolbarLink @params={{array 'vault.cluster.policies.create'}} @type="add" @disabled={{true}} @disabledTooltip="This link is disabled">
|
||||
* Create policy
|
||||
* </ToolbarLink>
|
||||
* </ToolbarActions>
|
||||
* </Toolbar>
|
||||
* ```
|
||||
*
|
||||
* @param params=''{Array} Array to pass to LinkTo
|
||||
* @param type=''{String} Use "add" to change icon
|
||||
* @param {array} params - Array to pass to LinkTo
|
||||
* @param {string} type - Use "add" to change icon
|
||||
* @param {boolean} disabled - pass true to disable link
|
||||
* @param {string} disabledTooltip - tooltip to display on hover when disabled
|
||||
*/
|
||||
|
||||
import Component from '@ember/component';
|
||||
|
@ -27,6 +29,8 @@ export default Component.extend({
|
|||
tagName: '',
|
||||
supportsDataTestProperties: true,
|
||||
type: null,
|
||||
disabled: false,
|
||||
disabledTooltip: null,
|
||||
glyph: computed('type', function() {
|
||||
if (this.type == 'add') {
|
||||
return 'plus-plain';
|
||||
|
|
|
@ -1,20 +1,36 @@
|
|||
<LinkTo
|
||||
{{#let (component "link-to"
|
||||
class="toolbar-link"
|
||||
@params={{params}}
|
||||
data-test-secret-edit={{data-test-secret-edit}}
|
||||
data-test-secondary-add={{data-test-secondary-add}}
|
||||
data-test-configure-link={{data-test-configure-link}}
|
||||
data-test-alias-edit-link={{data-test-alias-edit-link}}
|
||||
data-test-entity-edit-link={{data-test-entity-edit-link}}
|
||||
data-test-replication-link={{data-test-replication-link}}
|
||||
data-test-entity-merge-link={{data-test-entity-merge-link}}
|
||||
data-test-backend-view-link={{data-test-backend-view-link}}
|
||||
data-test-entity-create-link={{data-test-entity-create-link}}
|
||||
data-test-policy-create-link={{data-test-policy-create-link}}
|
||||
data-test-policy-edit-toggle={{data-test-policy-edit-toggle}}
|
||||
data-test-secret-backend-configure={{data-test-secret-backend-configure}}
|
||||
...attributes
|
||||
>
|
||||
{{yield}}
|
||||
<Icon @glyph={{glyph}} />
|
||||
</LinkTo>
|
||||
disabled=disabled
|
||||
params=params
|
||||
data-test-secret-edit=data-test-secret-edit
|
||||
data-test-secondary-add=data-test-secondary-add
|
||||
data-test-configure-link=data-test-configure-link
|
||||
data-test-alias-edit-link=data-test-alias-edit-link
|
||||
data-test-entity-edit-link=data-test-entity-edit-link
|
||||
data-test-replication-link=data-test-replication-link
|
||||
data-test-entity-merge-link=data-test-entity-merge-link
|
||||
data-test-backend-view-link=data-test-backend-view-link
|
||||
data-test-entity-create-link=data-test-entity-create-link
|
||||
data-test-policy-create-link=data-test-policy-create-link
|
||||
data-test-policy-edit-toggle=data-test-policy-edit-toggle
|
||||
data-test-secret-backend-configure=data-test-secret-backend-configure
|
||||
) as |LinkToComponent|}}
|
||||
{{#if (and disabled disabledTooltip)}}
|
||||
<ToolTip @verticalPosition="above" as |T|>
|
||||
<T.trigger tabindex="-1">
|
||||
<LinkToComponent ...attributes>
|
||||
{{yield}} <Icon @glyph={{glyph}} data-test-icon={{glyph}} />
|
||||
</LinkToComponent>
|
||||
</T.trigger>
|
||||
<T.content @class="tool-tip smaller-font">
|
||||
<div class="box" data-test-disabled-tooltip>
|
||||
{{disabledTooltip}}
|
||||
</div>
|
||||
</T.content>
|
||||
</ToolTip>
|
||||
{{else}}
|
||||
<LinkToComponent ...attributes>
|
||||
{{yield}} <Icon @glyph={{glyph}} data-test-icon={{glyph}} />
|
||||
</LinkToComponent>
|
||||
{{/if}}
|
||||
{{/let}}
|
||||
|
|
|
@ -4,18 +4,21 @@
|
|||
`ToolbarLink` components style links and buttons for the Toolbar
|
||||
It should only be used inside of `Toolbar`.
|
||||
|
||||
**Params**
|
||||
|
||||
| Param | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| params | <code>Array</code> | <code>''</code> | Array to pass to LinkTo |
|
||||
| type | <code>String</code> | <code>''</code> | Use "add" to change icon |
|
||||
| Param | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| params | <code>array</code> | Array to pass to LinkTo |
|
||||
| type | <code>string</code> | Use "add" to change icon |
|
||||
| disabled | <code>boolean</code> | pass true to disable link |
|
||||
| disabledTooltip | <code>string</code> | tooltip to display on hover when disabled |
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
<Toolbar>
|
||||
<ToolbarActions>
|
||||
<ToolbarLink @params={{array 'vault.cluster.policies.create'}} @type="add">
|
||||
<ToolbarLink @params={{array 'vault.cluster.policies.create'}} @type="add" @disabled={{true}} @disabledTooltip="This link is disabled">
|
||||
Create policy
|
||||
</ToolbarLink>
|
||||
</ToolbarActions>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import hbs from 'htmlbars-inline-precompile';
|
||||
import { storiesOf } from '@storybook/ember';
|
||||
import { withKnobs, select, text } from '@storybook/addon-knobs';
|
||||
import { withKnobs, select, text, boolean } from '@storybook/addon-knobs';
|
||||
import notes from './toolbar-link.md';
|
||||
|
||||
storiesOf('Toolbar', module)
|
||||
|
@ -17,6 +17,8 @@ storiesOf('Toolbar', module)
|
|||
<ToolbarLink
|
||||
@params={{array '#'}}
|
||||
@type={{type}}
|
||||
@disabled={{disabled}}
|
||||
@disabledTooltip={{disabledTooltip}}
|
||||
>
|
||||
{{label}}
|
||||
</ToolbarLink>
|
||||
|
@ -27,6 +29,8 @@ storiesOf('Toolbar', module)
|
|||
context: {
|
||||
type: select('Type', ['', 'add']),
|
||||
label: text('Button text', 'Edit secret'),
|
||||
disabled: boolean('disabled', false),
|
||||
disabledTooltip: text('Tooltip to display when disabled', ''),
|
||||
},
|
||||
}),
|
||||
{ notes }
|
||||
|
|
|
@ -617,13 +617,8 @@ module('Acceptance | secrets/secret/create', function(hooks) {
|
|||
await assert
|
||||
.dom('[data-test-value-div="secret-key"]')
|
||||
.exists('secret view page and info table row with secret-key value');
|
||||
// check you can create new version
|
||||
await click('[data-test-secret-edit="true"]');
|
||||
await settled();
|
||||
await fillIn('[data-test-secret-key]', 'version2');
|
||||
await editPage.save();
|
||||
await settled();
|
||||
assert.dom('[data-test-row-label="version2"]').exists('the current version displayed is the new version');
|
||||
// create new version should be disabled with no metadata read access
|
||||
assert.dom('[data-test-secret-edit]').hasClass('disabled', 'Create new version action is disabled');
|
||||
assert
|
||||
.dom('[data-test-popup-menu-trigger="version"]')
|
||||
.doesNotExist('the version drop down menu does not show');
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import { render, triggerEvent } from '@ember/test-helpers';
|
||||
import { isPresent } from 'ember-cli-page-object';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
|
@ -14,4 +14,41 @@ module('Integration | Component | toolbar-link', function(hooks) {
|
|||
assert.ok(isPresent('.toolbar-link'));
|
||||
assert.ok(isPresent('.icon'));
|
||||
});
|
||||
|
||||
test('it should render icons', async function(assert) {
|
||||
assert.expect(2);
|
||||
|
||||
await render(hbs`
|
||||
<ToolbarLink
|
||||
@params={{array '/secrets'}}
|
||||
@type={{this.type}}
|
||||
>
|
||||
Test Link
|
||||
</ToolbarLink>
|
||||
`);
|
||||
|
||||
assert.dom('[data-test-icon="chevron-right"]').exists('Default chevron right icon renders');
|
||||
this.set('type', 'add');
|
||||
assert.dom('[data-test-icon="plus-plain"]').exists('Icon can be overriden to show plus sign');
|
||||
});
|
||||
|
||||
test('it should disable and show tooltip if provided', async function(assert) {
|
||||
assert.expect(3);
|
||||
|
||||
await render(hbs`
|
||||
<ToolbarLink
|
||||
@params={{array '/secrets'}}
|
||||
@disabled={{true}}
|
||||
@disabledTooltip={{this.tooltip}}
|
||||
>
|
||||
Test Link
|
||||
</ToolbarLink>
|
||||
`);
|
||||
|
||||
assert.dom('a').hasClass('disabled', 'Link can be disabled');
|
||||
assert.dom('[data-test-popup-menu-trigger]').doesNotExist('Tooltip is hidden when not provided');
|
||||
this.set('tooltip', 'Test tooltip');
|
||||
await triggerEvent('.ember-basic-dropdown-trigger', 'mouseenter');
|
||||
assert.dom('[data-test-disabled-tooltip]').hasText(this.tooltip, 'Tooltip renders');
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue