open-consul/ui-v2/app/components/policy-selector.js
John Cowen 81f209d71e UI: ACL Roles (#5635)
Adds support for ACL Roles and Service Identities CRUD, along with necessary changes to Tokens, and the CSS improvements required.

Also includes refinements/improvements for easier testing of deeply nested components.

1. ember-data adapter/serializer/model triplet for Roles
2. repository, form/validations and searching filter for Roles
3. Moves potentially, repeated, or soon to to repeated functionality
into a mixin (mainly for 'many policy' relationships)
4. A few styling tweaks for little edge cases around roles
5. Router additions, Route, Controller and templates for Roles

Also see: 

* UI: ACL Roles cont. plus Service Identities (#5661 and #5720)
2019-05-01 18:22:37 +00:00

83 lines
2.6 KiB
JavaScript

import ChildSelectorComponent from './child-selector';
import { get, set } from '@ember/object';
import { inject as service } from '@ember/service';
import updateArrayObject from 'consul-ui/utils/update-array-object';
const ERROR_PARSE_RULES = 'Failed to parse ACL rules';
const ERROR_NAME_EXISTS = 'Invalid Policy: A Policy with Name';
export default ChildSelectorComponent.extend({
repo: service('repository/policy/component'),
datacenterRepo: service('repository/dc/component'),
name: 'policy',
type: 'policy',
classNames: ['policy-selector'],
init: function() {
this._super(...arguments);
const source = get(this, 'source');
if (source) {
const event = 'save';
this.listen(source, event, e => {
this.actions[event].bind(this)(...e.data);
});
}
},
reset: function(e) {
this._super(...arguments);
set(this, 'isScoped', false);
set(this, 'datacenters', get(this, 'datacenterRepo').findAll());
},
refreshCodeEditor: function(e, target) {
const selector = '.code-editor';
get(this, 'dom')
.component(selector, target)
.didAppear();
},
error: function(e) {
const item = get(this, 'item');
const err = e.error;
if (typeof err.errors !== 'undefined') {
const error = err.errors[0];
let prop;
let message = error.detail;
switch (true) {
case message.indexOf(ERROR_PARSE_RULES) === 0:
prop = 'Rules';
message = error.detail;
break;
case message.indexOf(ERROR_NAME_EXISTS) === 0:
prop = 'Name';
message = message.substr(ERROR_NAME_EXISTS.indexOf(':') + 1);
break;
}
if (prop) {
item.addError(prop, message);
}
} else {
// TODO: Conponents can't throw, use onerror
throw err;
}
},
actions: {
loadItem: function(e, item, items) {
const target = e.target;
// the Details expander toggle, only load on opening
if (target.checked) {
const value = item;
this.refreshCodeEditor(e, target.parentNode);
if (get(item, 'template') === 'service-identity') {
return;
}
// potentially the item could change between load, so we don't check
// anything to see if its already loaded here
const repo = get(this, 'repo');
// TODO: Temporarily add dc here, will soon be serialized onto the policy itself
const dc = get(this, 'dc');
const slugKey = repo.getSlugKey();
const slug = get(value, slugKey);
updateArrayObject(items, repo.findBySlug(slug, dc), slugKey, slug);
}
},
},
});