Skip to content

Commit

Permalink
UI - kv v2 versions page (#5563)
Browse files Browse the repository at this point in the history
* add versions routes

* move commands and permissions check to stand-alone menu component

* add versions template

* make list-item component more flexible and use hasMenu to optionally render the menu

* move current check next to the version

* fix linting

* remove is-wide from secret list popup
  • Loading branch information
meirish authored Oct 19, 2018
1 parent 7e0b47d commit a58745b
Show file tree
Hide file tree
Showing 16 changed files with 345 additions and 201 deletions.
2 changes: 1 addition & 1 deletion ui/app/components/list-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default Component.extend({
tagName: '',
linkParams: null,
componentName: null,
hasMenu: false,
hasMenu: true,

callMethod: task(function*(method, model, successMessage, failureMessage, successCallback = () => {}) {
let flash = this.get('flashMessages');
Expand Down
2 changes: 2 additions & 0 deletions ui/app/components/list-item/popup-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ import Component from '@ember/component';

export default Component.extend({
tagName: '',
item: null,
hasMenu: null,
});
51 changes: 1 addition & 50 deletions ui/app/components/secret-edit.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { or } from '@ember/object/computed';
import { isBlank, isNone } from '@ember/utils';
import { inject as service } from '@ember/service';
import Component from '@ember/component';
import { computed, set } from '@ember/object';
import { alias } from '@ember/object/computed';
import { alias, or } from '@ember/object/computed';
import { task, waitForEvent } from 'ember-concurrency';
import FocusOnInsertMixin from 'vault/mixins/focus-on-insert';
import keys from 'vault/lib/keycodes';
Expand Down Expand Up @@ -127,49 +126,6 @@ export default Component.extend(FocusOnInsertMixin, {
),
canEditV2Secret: alias('v2UpdatePath.canUpdate'),

deleteVersionPath: maybeQueryRecord(
'capabilities',
context => {
let backend = context.get('model.engine.id');
let id = context.model.id;
return {
id: `${backend}/delete/${id}`,
};
},
'model.id'
),
canDeleteVersion: alias('deleteVersionPath.canUpdate'),
destroyVersionPath: maybeQueryRecord(
'capabilities',
context => {
let backend = context.get('model.engine.id');
let id = context.model.id;
return {
id: `${backend}/destroy/${id}`,
};
},
'model.id'
),
canDestroyVersion: alias('destroyVersionPath.canUpdate'),
undeleteVersionPath: maybeQueryRecord(
'capabilities',
context => {
let backend = context.get('model.engine.id');
let id = context.model.id;
return {
id: `${backend}/undelete/${id}`,
};
},
'model.id'
),
canUndeleteVersion: alias('undeleteVersionPath.canUpdate'),

isFetchingVersionCapabilities: or(
'deleteVersionPath.isPending',
'destroyVersionPath.isPending',
'undeleteVersionPath.isPending'
),

requestInFlight: or('model.isLoading', 'model.isReloading', 'model.isSaving'),

buttonDisabled: or(
Expand Down Expand Up @@ -299,11 +255,6 @@ export default Component.extend(FocusOnInsertMixin, {
});
},

deleteVersion(deleteType = 'destroy') {
let id = this.modelForData.id;
return this.store.adapterFor('secret-v2-version').v2DeleteOperation(this.store, id, deleteType);
},

refresh() {
this.onRefresh();
},
Expand Down
58 changes: 58 additions & 0 deletions ui/app/components/secret-version-menu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { maybeQueryRecord } from 'vault/macros/maybe-query-record';
import Component from '@ember/component';
import { inject as service } from '@ember/service';
import { alias, or } from '@ember/object/computed';

export default Component.extend({
tagName: '',
store: service(),
version: null,
useDefaultTrigger: false,

deleteVersionPath: maybeQueryRecord(
'capabilities',
context => {
let [backend, id] = JSON.parse(context.version.id);
return {
id: `${backend}/delete/${id}`,
};
},
'version.id'
),
canDeleteVersion: alias('deleteVersionPath.canUpdate'),
destroyVersionPath: maybeQueryRecord(
'capabilities',
context => {
let [backend, id] = JSON.parse(context.version.id);
return {
id: `${backend}/destroy/${id}`,
};
},
'version.id'
),
canDestroyVersion: alias('destroyVersionPath.canUpdate'),
undeleteVersionPath: maybeQueryRecord(
'capabilities',
context => {
let [backend, id] = JSON.parse(context.version.id);
return {
id: `${backend}/undelete/${id}`,
};
},
'version.id'
),
canUndeleteVersion: alias('undeleteVersionPath.canUpdate'),

isFetchingVersionCapabilities: or(
'deleteVersionPath.isPending',
'destroyVersionPath.isPending',
'undeleteVersionPath.isPending'
),
actions: {
deleteVersion(deleteType = 'destroy') {
return this.store
.adapterFor('secret-v2-version')
.v2DeleteOperation(this.store, this.version.id, deleteType);
},
},
});
4 changes: 4 additions & 0 deletions ui/app/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ Router.map(function() {
this.route('credentials-root', { path: '/credentials/' });
this.route('credentials', { path: '/credentials/*secret' });

// kv v2 versions
this.route('versions-root', { path: '/versions/' });
this.route('versions', { path: '/versions/*secret' });

// ssh sign
this.route('sign-root', { path: '/sign/' });
this.route('sign', { path: '/sign/*secret' });
Expand Down
6 changes: 3 additions & 3 deletions ui/app/routes/vault/cluster/secrets/backend/secret-edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,16 +140,16 @@ export default Route.extend(UnloadModelRoute, {
},

willTransition(transition) {
let model = this.controller.model;
let { mode, model } = this.controller;
let version = model.get('selectedVersion');
let changed = model.changedAttributes();
let changedKeys = Object.keys(changed);
// until we have time to move `backend` on a v1 model to a relationship,
// it's going to dirty the model state, so we need to look for it
// and explicity ignore it here
if (
(changedKeys.length && changedKeys[0] !== 'backend') ||
(version && Object.keys(version.changedAttributes()).length)
(mode !== 'show' && (changedKeys.length && changedKeys[0] !== 'backend')) ||
(mode !== 'show' && version && Object.keys(version.changedAttributes()).length)
) {
if (
window.confirm(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './version';
27 changes: 27 additions & 0 deletions ui/app/routes/vault/cluster/secrets/backend/versions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Route from '@ember/routing/route';
import utils from 'vault/lib/key-utils';
import UnloadModelRoute from 'vault/mixins/unload-model-route';

export default Route.extend(UnloadModelRoute, {
templateName: 'vault/cluster/secrets/backend/versions',

beforeModel() {
let backendModel = this.modelFor('vault.cluster.secrets.backend');
const { secret } = this.paramsFor(this.routeName);
const parentKey = utils.parentKeyForKey(secret);
if (backendModel.get('isV2KV')) {
return;
}
if (parentKey) {
return this.transitionTo('vault.cluster.secrets.backend.list', parentKey);
} else {
return this.transitionTo('vault.cluster.secrets.backend.list-root');
}
},

model(params) {
let { secret } = params;
const { backend } = this.paramsFor('vault.cluster.secrets.backend');
return this.store.queryRecord('secret-v2', { id: secret, backend });
},
});
1 change: 1 addition & 0 deletions ui/app/serializers/secret-v2.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export default ApplicationSerializer.extend(DS.EmbeddedRecordsMixin, {
return body;
});
}
payload.data.engine_id = payload.backend;
payload.data.id = payload.id;
return requestType === 'queryRecord' ? payload.data : [payload.data];
},
Expand Down
6 changes: 6 additions & 0 deletions ui/app/styles/core/helpers.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@
.is-underline {
text-decoration: underline;
}
.is-no-underline {
text-decoration: none;
}
.is-sideless {
box-shadow: 0 2px 0 -1px $grey-light, 0 -2px 0 -1px $grey-light;
}
.is-bottomless {
box-shadow: 0 -1px 0 0 $grey-light;
}
.has-bottom-shadow {
box-shadow: $box-shadow !important;
}
.is-borderless {
border: none !important;
}
Expand Down
24 changes: 9 additions & 15 deletions ui/app/templates/components/list-item.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,27 @@
{{else if linkParams}}
<LinkedBlock @params={{linkParams}} @class="list-item-row">
<div class="level is-mobile">
<div class="level-left">
<div>
{{#link-to params=linkParams class="has-text-weight-semibold"}}
{{yield (hash content=(component "list-item/content"))}}
{{/link-to}}
</div>
</div>
<div class="level-left is-flex-1">
{{#link-to params=linkParams class="has-text-weight-semibold has-text-black is-display-flex is-flex-1 is-no-underline"}}
{{yield (hash content=(component "list-item/content"))}}
{{/link-to}}
</div>
<div class="level-right">
<div class="level-item">
{{#if hasBlock}}
{{yield (hash callMethod=callMethod menu=(component "list-item/popup-menu"))}}
{{/if}}
{{yield (hash callMethod=callMethod menu=(component "list-item/popup-menu" item=item hasMenu=hasMenu))}}
</div>
</div>
</div>
</LinkedBlock>
{{else}}
<div class="list-item-row">
<div class="level is-mobile">
<div class="level-left">
<div class="has-text-grey has-text-weight-semibold">
{{yield (hash content=(component "list-item/content"))}}
</div>
<div class="level-left is-flex-1 has-text-weight-semibold">
{{yield (hash content=(component "list-item/content"))}}
</div>
<div class="level-right">
<div class="level-item">
{{yield (hash callMethod=callMethod menu=(component "list-item/popup-menu"))}}
{{yield (hash callMethod=callMethod menu=(component "list-item/popup-menu" item=item hasMenu=hasMenu))}}
</div>
</div>
</div>
Expand Down
18 changes: 11 additions & 7 deletions ui/app/templates/components/list-item/popup-menu.hbs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
<PopupMenu>
<nav class="menu">
<ul class="menu-list">
{{yield item}}
</ul>
</nav>
</PopupMenu>
{{#if hasMenu}}
<PopupMenu>
<nav class="menu">
<ul class="menu-list">
{{yield item}}
</ul>
</nav>
</PopupMenu>
{{else}}
{{yield item}}
{{/if}}
Loading

0 comments on commit a58745b

Please sign in to comment.