From 104e6bac71d16c4e7009555764a34ac342694390 Mon Sep 17 00:00:00 2001 From: John Cowen Date: Mon, 19 Nov 2018 14:49:16 +0000 Subject: [PATCH] UI: Move legacy ACLs to use the new searchables/changeable-sets (#4933) --- ui-v2/app/controllers/dc/acls/index.js | 28 +-- ui-v2/app/initializers/search.js | 2 + ui-v2/app/search/filters/acl.js | 14 ++ ui-v2/app/templates/components/acl-filter.hbs | 2 +- ui-v2/app/templates/dc/acls/index.hbs | 159 +++++++++--------- .../unit/controllers/dc/acls/index-test.js | 2 +- ui-v2/tests/unit/search/filters/acl-test.js | 36 ++++ 7 files changed, 150 insertions(+), 93 deletions(-) create mode 100644 ui-v2/app/search/filters/acl.js create mode 100644 ui-v2/tests/unit/search/filters/acl-test.js diff --git a/ui-v2/app/controllers/dc/acls/index.js b/ui-v2/app/controllers/dc/acls/index.js index 3a28d5a76d..2d49d9fed4 100644 --- a/ui-v2/app/controllers/dc/acls/index.js +++ b/ui-v2/app/controllers/dc/acls/index.js @@ -1,11 +1,12 @@ import Controller from '@ember/controller'; import { computed, get } from '@ember/object'; import WithFiltering from 'consul-ui/mixins/with-filtering'; +import WithSearching from 'consul-ui/mixins/with-searching'; import ucfirst from 'consul-ui/utils/ucfirst'; const countType = function(items, type) { return type === '' ? get(items, 'length') : items.filterBy('Type', type).length; }; -export default Controller.extend(WithFiltering, { +export default Controller.extend(WithSearching, WithFiltering, { queryParams: { type: { as: 'type', @@ -15,6 +16,17 @@ export default Controller.extend(WithFiltering, { replace: true, }, }, + init: function() { + this.searchParams = { + acl: 's', + }; + this._super(...arguments); + }, + searchable: computed('filtered', function() { + return get(this, 'searchables.acl') + .add(get(this, 'filtered')) + .search(get(this, this.searchParams.acl)); + }), typeFilters: computed('items', function() { const items = get(this, 'items'); return ['', 'management', 'client'].map(function(item) { @@ -27,18 +39,8 @@ export default Controller.extend(WithFiltering, { }; }); }), - // TODO: This should be using a searchable - filter: function(item, { s = '', type = '' }) { - const sLower = s.toLowerCase(); - return ( - (get(item, 'Name') - .toLowerCase() - .indexOf(sLower) !== -1 || - get(item, 'ID') - .toLowerCase() - .indexOf(sLower) !== -1) && - (type === '' || get(item, 'Type') === type) - ); + filter: function(item, { type = '' }) { + return type === '' || get(item, 'Type') === type; }, actions: { sendClone: function(item) { diff --git a/ui-v2/app/initializers/search.js b/ui-v2/app/initializers/search.js index 455c9ad17b..69875fdb11 100644 --- a/ui-v2/app/initializers/search.js +++ b/ui-v2/app/initializers/search.js @@ -2,6 +2,7 @@ import intention from 'consul-ui/search/filters/intention'; import token from 'consul-ui/search/filters/token'; import policy from 'consul-ui/search/filters/policy'; import kv from 'consul-ui/search/filters/kv'; +import acl from 'consul-ui/search/filters/acl'; import node from 'consul-ui/search/filters/node'; // service instance import nodeService from 'consul-ui/search/filters/node/service'; @@ -16,6 +17,7 @@ export function initialize(application) { const searchables = { intention: intention(filterable), token: token(filterable), + acl: acl(filterable), policy: policy(filterable), kv: kv(filterable), healthyNode: node(filterable), diff --git a/ui-v2/app/search/filters/acl.js b/ui-v2/app/search/filters/acl.js new file mode 100644 index 0000000000..b68e31ec37 --- /dev/null +++ b/ui-v2/app/search/filters/acl.js @@ -0,0 +1,14 @@ +import { get } from '@ember/object'; +export default function(filterable) { + return filterable(function(item, { s = '' }) { + const sLower = s.toLowerCase(); + return ( + get(item, 'Name') + .toLowerCase() + .indexOf(sLower) !== -1 || + get(item, 'ID') + .toLowerCase() + .indexOf(sLower) !== -1 + ); + }); +} diff --git a/ui-v2/app/templates/components/acl-filter.hbs b/ui-v2/app/templates/components/acl-filter.hbs index e6d24e39a3..44595ea10d 100644 --- a/ui-v2/app/templates/components/acl-filter.hbs +++ b/ui-v2/app/templates/components/acl-filter.hbs @@ -1,4 +1,4 @@ {{!
}} - {{freetext-filter onchange=(action onchange) value=search placeholder="Search by name/token"}} + {{freetext-filter searchable=searchable value=search placeholder="Search by name/token"}} {{radio-group name="type" value=type items=filters onchange=(action onchange)}} {{!
}} diff --git a/ui-v2/app/templates/dc/acls/index.hbs b/ui-v2/app/templates/dc/acls/index.hbs index 52cc48f51a..57f94c8946 100644 --- a/ui-v2/app/templates/dc/acls/index.hbs +++ b/ui-v2/app/templates/dc/acls/index.hbs @@ -13,87 +13,90 @@ {{/block-slot}} {{#block-slot 'toolbar'}} {{#if (gt items.length 0) }} - {{acl-filter filters=typeFilters search=filters.s type=filters.type onchange=(action 'filter')}} + {{acl-filter searchable=searchable filters=typeFilters search=filters.s type=filters.type onchange=(action 'filter')}} {{/if}} {{/block-slot}} {{#block-slot 'content'}} -{{#if (gt filtered.length 0)}} - {{#tabular-collection - items=(sort-by 'Name:asc' filtered) as |item index| - }} - {{#block-slot 'header'}} - Name - Type - {{/block-slot}} - {{#block-slot 'row'}} - - {{item.Name}} - - - {{#if (eq item.Type 'management')}} - {{item.Type}} - {{else}} - {{item.Type}} - {{/if}} - - {{/block-slot}} - {{#block-slot 'actions' as |index change checked|}} - {{#confirmation-dialog confirming=false index=index}} - {{#block-slot 'action' as |confirm|}} - {{#action-group index=index onchange=(action change) checked=(if (eq checked index) 'checked')}} - + {{/action-group}} + {{/block-slot}} + {{#block-slot 'dialog' as |execute cancel message name|}} +

+ {{#if (eq name 'delete')}} + Are you sure you want to delete this ACL token? + {{else if (eq name 'logout')}} + Are you sure you want to stop using this ACL token? This will log you out. + {{ else if (eq name 'use')}} + Are you sure you want to use this ACL token? + {{/if}} +

+ + + {{/block-slot}} + {{/confirmation-dialog}} + {{/block-slot}} + {{/tabular-collection}} + {{/block-slot}} + {{#block-slot 'empty'}} +

+ There are no ACLs. +

+ {{/block-slot}} + {{/changeable-set}} {{/block-slot}} {{/app-view}} \ No newline at end of file diff --git a/ui-v2/tests/unit/controllers/dc/acls/index-test.js b/ui-v2/tests/unit/controllers/dc/acls/index-test.js index 3772df42f2..c5b3982ed9 100644 --- a/ui-v2/tests/unit/controllers/dc/acls/index-test.js +++ b/ui-v2/tests/unit/controllers/dc/acls/index-test.js @@ -2,7 +2,7 @@ import { moduleFor, test } from 'ember-qunit'; moduleFor('controller:dc/acls/index', 'Unit | Controller | dc/acls/index', { // Specify the other units that are required for this test. - // needs: ['controller:foo'] + needs: ['service:search', 'service:dom'], }); // Replace this with your real tests. diff --git a/ui-v2/tests/unit/search/filters/acl-test.js b/ui-v2/tests/unit/search/filters/acl-test.js new file mode 100644 index 0000000000..7531f6e691 --- /dev/null +++ b/ui-v2/tests/unit/search/filters/acl-test.js @@ -0,0 +1,36 @@ +import getFilter from 'consul-ui/search/filters/acl'; +import { module, test } from 'qunit'; + +module('Unit | Search | Filter | acl'); + +const filter = getFilter(cb => cb); +test('items are found by properties', function(assert) { + [ + { + ID: 'HIT-id', + Name: 'name', + }, + { + ID: 'id', + Name: 'name-HIT', + }, + ].forEach(function(item) { + const actual = filter(item, { + s: 'hit', + }); + assert.ok(actual); + }); +}); +test('items are not found', function(assert) { + [ + { + ID: 'id', + Name: 'name', + }, + ].forEach(function(item) { + const actual = filter(item, { + s: 'hit', + }); + assert.notOk(actual); + }); +});