ui: no partition and peer in bucket-list at the same time (#13812)
* don't show partition / peer at the same time in bucket-list * use bucket-list in intentions table * add bucket-list tests * Simplify bucket list - match old behavior Refactor the bucket-list component to be easier to grok and match how the old template based approach worked. I.e. do not surface partition or namespace when it matches the passed nspace or partition property. * Update docs for bucket-list * fix linting
This commit is contained in:
parent
9176d3ed33
commit
59b044f96d
|
@ -11,6 +11,9 @@ the namespace will be displayed, whereas if the partition is different it will
|
|||
show both the partition and namespace (as a namespace called 'team-1' in
|
||||
`partition-1` is different to a namespace called 'team-1' in `partition-2`)
|
||||
|
||||
When the passed item contains a `PeerName`, this will be displayed in place of
|
||||
the `Partition`.
|
||||
|
||||
Showing the service name is a tiny bit awkward (different boolean type,
|
||||
doesn't care about difference) and could be improved but we only use it for
|
||||
the read only view of intentions.
|
||||
|
@ -89,7 +92,7 @@ At the time of writing, this is not currently used across the entire UI
|
|||
|
||||
| Argument/Attribute | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `item` | `array` | | A Consul object that could have both a `Partition` and a `Namespace` property |
|
||||
| `item` | `object` | | A Consul object that could have a `Partition`, a `Namespace`, a `PeerName` and a `Service` property |
|
||||
| `nspace` | `string` | | The name of the current namespace |
|
||||
| `partition` | `string` | | The name of the current partition |
|
||||
| `service` | `boolean` | | Whether to show the service name on the end or not. Please note you must also pass a item.Service for it to show. We flag this incase an API request has a Service property but you don't want to show it |
|
||||
|
|
|
@ -5,84 +5,105 @@ export default class ConsulBucketList extends Component {
|
|||
@service abilities;
|
||||
|
||||
get itemsToDisplay() {
|
||||
const { item, partition, nspace } = this.args;
|
||||
const { abilities } = this;
|
||||
const { peerOrPartitionPart, namespacePart, servicePart } = this;
|
||||
|
||||
let items = [];
|
||||
return [...peerOrPartitionPart, ...namespacePart, ...servicePart];
|
||||
}
|
||||
|
||||
get peerOrPartitionPart() {
|
||||
const { peerPart, partitionPart } = this;
|
||||
|
||||
if (peerPart.length) {
|
||||
return peerPart;
|
||||
} else {
|
||||
return partitionPart;
|
||||
}
|
||||
}
|
||||
|
||||
get partitionPart() {
|
||||
const { item, partition } = this.args;
|
||||
|
||||
const { abilities } = this;
|
||||
|
||||
if (partition && abilities.can('use partitions')) {
|
||||
if (item.Partition !== partition) {
|
||||
this._addPeer(items);
|
||||
this._addPartition(items);
|
||||
this._addNamespace(items);
|
||||
this._addService(items);
|
||||
} else {
|
||||
this._addPeerInfo(items);
|
||||
return [
|
||||
{
|
||||
type: 'partition',
|
||||
label: 'Admin Partition',
|
||||
item: item.Partition,
|
||||
},
|
||||
];
|
||||
}
|
||||
} else if (nspace && abilities.can('use nspace')) {
|
||||
if (item.Namespace !== nspace) {
|
||||
this._addPeerInfo(items);
|
||||
this._addService(items);
|
||||
} else {
|
||||
this._addPeerInfo(items);
|
||||
}
|
||||
} else {
|
||||
this._addPeerInfo(items);
|
||||
}
|
||||
|
||||
return items;
|
||||
return [];
|
||||
}
|
||||
|
||||
_addPeerInfo(items) {
|
||||
get peerPart() {
|
||||
const { item } = this.args;
|
||||
|
||||
if (item.PeerName) {
|
||||
this._addPeer(items);
|
||||
this._addNamespace(items);
|
||||
return [
|
||||
{
|
||||
type: 'peer',
|
||||
label: 'Peer',
|
||||
item: item.PeerName,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
_addPartition(items) {
|
||||
const { item } = this.args;
|
||||
get namespacePart() {
|
||||
const { item, nspace } = this.args;
|
||||
const { abilities, partitionPart } = this;
|
||||
|
||||
items.push({
|
||||
type: 'partition',
|
||||
label: 'Admin Partition',
|
||||
item: item.Partition,
|
||||
});
|
||||
}
|
||||
|
||||
_addNamespace(items) {
|
||||
const { item } = this.args;
|
||||
|
||||
items.push({
|
||||
const nspaceItem = {
|
||||
type: 'nspace',
|
||||
label: 'Namespace',
|
||||
item: item.Namespace,
|
||||
});
|
||||
};
|
||||
|
||||
// when we surface a partition - show a namespace with it
|
||||
if (partitionPart.length) {
|
||||
return [nspaceItem];
|
||||
}
|
||||
|
||||
if (nspace && abilities.can('use nspaces')) {
|
||||
if (item.Namespace !== nspace) {
|
||||
return [
|
||||
{
|
||||
type: 'nspace',
|
||||
label: 'Namespace',
|
||||
item: item.Namespace,
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
_addService(items) {
|
||||
const { service, item } = this.args;
|
||||
get servicePart() {
|
||||
const { item, service } = this.args;
|
||||
|
||||
if (service && item.Service) {
|
||||
items.push({
|
||||
type: 'service',
|
||||
label: 'Service',
|
||||
item: item.Service,
|
||||
});
|
||||
const { partitionPart, namespacePart } = this;
|
||||
|
||||
// when we show partitionPart or namespacePart -> consider service part
|
||||
if (partitionPart.length || namespacePart.length) {
|
||||
if (item.Service && service) {
|
||||
return [
|
||||
{
|
||||
type: 'service',
|
||||
label: 'Service',
|
||||
item: item.Service,
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_addPeer(items) {
|
||||
const { item } = this.args;
|
||||
|
||||
if (item?.PeerName) {
|
||||
items.push({
|
||||
type: 'peer',
|
||||
label: 'Peer',
|
||||
item: item.PeerName,
|
||||
});
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,43 +24,18 @@ as |item index|>
|
|||
{{else}}
|
||||
{{item.SourceName}}
|
||||
{{/if}}
|
||||
{{#if (or (can 'use nspaces') (can 'use partitions'))}}
|
||||
{{! TODO: slugify }}
|
||||
<em class="consul-intention-list-table__meta-info">
|
||||
{{#if item.SourcePeer}}
|
||||
<span class="consul-intention-list-table__meta-info__peer">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" {{tooltip "Peer" }} class="-mr-1">
|
||||
<path
|
||||
d="M16 8C16 7.80109 15.921 7.61032 15.7803 7.46967L12.2803 3.96967C11.9874 3.67678 11.5126 3.67678 11.2197 3.96967C10.9268 4.26256 10.9268 4.73744 11.2197 5.03033L14.1893 8L11.2197 10.9697C10.9268 11.2626 10.9268 11.7374 11.2197 12.0303C11.5126 12.3232 11.9874 12.3232 12.2803 12.0303L15.7803 8.53033C15.921 8.38968 16 8.19891 16 8Z"
|
||||
fill="#77838A" />
|
||||
<path
|
||||
d="M0.21967 8.53033C-0.0732233 8.23744 -0.0732233 7.76256 0.21967 7.46967L3.71967 3.96967C4.01256 3.67678 4.48744 3.67678 4.78033 3.96967C5.07322 4.26256 5.07322 4.73744 4.78033 5.03033L1.81066 8L4.78033 10.9697C5.07322 11.2626 5.07322 11.7374 4.78033 12.0303C4.48744 12.3232 4.01256 12.3232 3.71967 12.0303L0.21967 8.53033Z"
|
||||
fill="#77838A" />
|
||||
<path
|
||||
d="M5 7C4.44772 7 4 7.44772 4 8C4 8.55229 4.44772 9 5 9H5.01C5.56228 9 6.01 8.55229 6.01 8C6.01 7.44772 5.56228 7 5.01 7H5Z"
|
||||
fill="#77838A" />
|
||||
<path
|
||||
d="M7 8C7 7.44772 7.44772 7 8 7H8.01C8.56228 7 9.01 7.44772 9.01 8C9.01 8.55229 8.56228 9 8.01 9H8C7.44772 9 7 8.55229 7 8Z"
|
||||
fill="#77838A" />
|
||||
<path
|
||||
d="M11 7C10.4477 7 10 7.44772 10 8C10 8.55229 10.4477 9 11 9H11.01C11.5623 9 12.01 8.55229 12.01 8C12.01 7.44772 11.5623 7 11.01 7H11Z"
|
||||
fill="#77838A" />
|
||||
</svg>
|
||||
<span>{{item.SourcePeer}}</span>
|
||||
</span>
|
||||
{{else}}
|
||||
<span
|
||||
class={{concat 'partition-' (or item.SourcePartition 'default')}}
|
||||
>
|
||||
{{or item.SourcePartition 'default'}}
|
||||
</span>
|
||||
{{/if}}
|
||||
/
|
||||
<span
|
||||
class={{concat 'nspace-' (or item.SourceNS 'default')}}
|
||||
>{{or item.SourceNS 'default'}}</span>
|
||||
<Consul::Bucket::List
|
||||
@item={{hash
|
||||
Namespace=item.SourceNS
|
||||
Partition=item.SourcePartition
|
||||
PeerName=item.SourcePeer
|
||||
}}
|
||||
@nspace="-"
|
||||
@partition="-"
|
||||
/>
|
||||
</em>
|
||||
{{/if}}
|
||||
</a>
|
||||
</td>
|
||||
<td class="intent intent-{{slugify item.Action}}" data-test-intention-action={{item.Action}}>
|
||||
|
|
|
@ -0,0 +1,255 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import Service from '@ember/service';
|
||||
|
||||
module('Integration | Component | consul bucket list', function(hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
module('without nspace or partition feature on', function(hooks) {
|
||||
hooks.beforeEach(function() {
|
||||
this.owner.register(
|
||||
'service:abilities',
|
||||
class Stub extends Service {
|
||||
can(permission) {
|
||||
if (permission === 'use partitions') {
|
||||
return false;
|
||||
}
|
||||
if (permission === 'use nspaces') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('it displays a peer when the item passed has a peer name', async function(assert) {
|
||||
const PEER_NAME = 'Tomster';
|
||||
|
||||
this.set('peerName', PEER_NAME);
|
||||
|
||||
await render(hbs`
|
||||
<Consul::Bucket::List
|
||||
@item={{hash
|
||||
PeerName=this.peerName
|
||||
Namespace="default"
|
||||
Partition="default"
|
||||
}}
|
||||
/>
|
||||
`);
|
||||
|
||||
assert.dom('[data-test-bucket-item="peer"]').hasText(PEER_NAME, 'Peer name is displayed');
|
||||
assert.dom('[data-test-bucket-item="nspace"]').doesNotExist('namespace is not shown');
|
||||
assert.dom('[data-test-bucket-item="partition"]').doesNotExist('partition is not shown');
|
||||
});
|
||||
|
||||
test('it does not display a bucket list when item has no peer name', async function(assert) {
|
||||
await render(hbs`
|
||||
<Consul::Bucket::List
|
||||
@item={{hash
|
||||
PeerName=this.peerName
|
||||
}}
|
||||
/>
|
||||
`);
|
||||
|
||||
assert.dom('[data-test-bucket-list]').doesNotExist('no bucket list displayed');
|
||||
});
|
||||
});
|
||||
|
||||
module('with partition feature on', function(hooks) {
|
||||
hooks.beforeEach(function() {
|
||||
this.owner.register(
|
||||
'service:abilities',
|
||||
class Stub extends Service {
|
||||
can(permission) {
|
||||
if (permission === 'use partitions') {
|
||||
return true;
|
||||
}
|
||||
if (permission === 'use nspaces') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test("it displays a peer and nspace and service and no partition when item.Partition and partition don't match", async function(assert) {
|
||||
const PEER_NAME = 'Tomster';
|
||||
const NAMESPACE_NAME = 'Mascot';
|
||||
const SERVICE_NAME = 'Ember.js';
|
||||
|
||||
this.set('peerName', PEER_NAME);
|
||||
this.set('namespace', NAMESPACE_NAME);
|
||||
this.set('service', SERVICE_NAME);
|
||||
|
||||
await render(hbs`
|
||||
<Consul::Bucket::List
|
||||
@item={{hash
|
||||
PeerName=this.peerName
|
||||
Namespace=this.namespace
|
||||
Service=this.service
|
||||
Partition="default"
|
||||
}}
|
||||
@partition="-"
|
||||
@nspace="-"
|
||||
@service="default"
|
||||
/>
|
||||
`);
|
||||
|
||||
assert.dom('[data-test-bucket-item="peer"]').hasText(PEER_NAME, 'Peer is displayed');
|
||||
assert
|
||||
.dom('[data-test-bucket-item="nspace"]')
|
||||
.hasText(NAMESPACE_NAME, 'namespace is displayed');
|
||||
assert.dom('[data-test-bucket-item="service"]').hasText(SERVICE_NAME, 'service is displayed');
|
||||
assert.dom('[data-test-bucket-item="partition"]').doesNotExist('partition is not displayed');
|
||||
});
|
||||
|
||||
test("it displays partition and nspace and service when item.Partition and partition don't match and peer is not set", async function(assert) {
|
||||
const PARTITION_NAME = 'Ember.js';
|
||||
const NAMESPACE_NAME = 'Mascot';
|
||||
const SERVICE_NAME = 'Consul';
|
||||
|
||||
this.set('partition', PARTITION_NAME);
|
||||
this.set('namespace', NAMESPACE_NAME);
|
||||
this.set('service', SERVICE_NAME);
|
||||
|
||||
await render(hbs`
|
||||
<Consul::Bucket::List
|
||||
@item={{hash
|
||||
Namespace=this.namespace
|
||||
Service=this.service
|
||||
Partition=this.partition
|
||||
}}
|
||||
@partition="-"
|
||||
@nspace="-"
|
||||
@service="default"
|
||||
/>
|
||||
`);
|
||||
|
||||
assert.dom('[data-test-bucket-item="peer"]').doesNotExist('peer is not displayed');
|
||||
assert
|
||||
.dom('[data-test-bucket-item="nspace"]')
|
||||
.hasText(NAMESPACE_NAME, 'namespace is displayed');
|
||||
assert.dom('[data-test-bucket-item="service"]').hasText(SERVICE_NAME, 'service is displayed');
|
||||
assert
|
||||
.dom('[data-test-bucket-item="partition"]')
|
||||
.hasText(PARTITION_NAME, 'partition is displayed');
|
||||
});
|
||||
|
||||
test('it displays nspace and peer and service when item.Partition and partition match and peer is set', async function(assert) {
|
||||
const PEER_NAME = 'Tomster';
|
||||
const PARTITION_NAME = 'Ember.js';
|
||||
const NAMESPACE_NAME = 'Mascot';
|
||||
const SERVICE_NAME = 'Ember.js';
|
||||
|
||||
this.set('peerName', PEER_NAME);
|
||||
this.set('partition', PARTITION_NAME);
|
||||
this.set('namespace', NAMESPACE_NAME);
|
||||
this.set('service', SERVICE_NAME);
|
||||
|
||||
await render(hbs`
|
||||
<Consul::Bucket::List
|
||||
@item={{hash
|
||||
PeerName=this.peerName
|
||||
Namespace=this.namespace
|
||||
Service=this.service
|
||||
Partition=this.partition
|
||||
}}
|
||||
@partition={{this.partition}}
|
||||
@nspace="-"
|
||||
@service="default"
|
||||
/>
|
||||
`);
|
||||
|
||||
assert.dom('[data-test-bucket-item="peer"]').hasText(PEER_NAME, 'peer is displayed');
|
||||
assert
|
||||
.dom('[data-test-bucket-item="nspace"]')
|
||||
.hasText(NAMESPACE_NAME, 'namespace is displayed');
|
||||
assert.dom('[data-test-bucket-item="service"]').hasText(SERVICE_NAME, 'service is displayed');
|
||||
assert.dom('[data-test-bucket-item="partition"]').doesNotExist('partition is not displayed');
|
||||
});
|
||||
});
|
||||
|
||||
module('with nspace on but partition feature off', function(hooks) {
|
||||
hooks.beforeEach(function() {
|
||||
this.owner.register(
|
||||
'service:abilities',
|
||||
class Stub extends Service {
|
||||
can(permission) {
|
||||
if (permission === 'use partitions') {
|
||||
return false;
|
||||
}
|
||||
if (permission === 'use nspaces') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test("it displays a peer and nspace and service when item.namespace and nspace don't match", async function(assert) {
|
||||
const PEER_NAME = 'Tomster';
|
||||
const NAMESPACE_NAME = 'Mascot';
|
||||
const SERVICE_NAME = 'Ember.js';
|
||||
|
||||
this.set('peerName', PEER_NAME);
|
||||
this.set('namespace', NAMESPACE_NAME);
|
||||
this.set('service', SERVICE_NAME);
|
||||
|
||||
await render(hbs`
|
||||
<Consul::Bucket::List
|
||||
@item={{hash
|
||||
PeerName=this.peerName
|
||||
Namespace=this.namespace
|
||||
Service=this.service
|
||||
Partition="default"
|
||||
}}
|
||||
@nspace="default"
|
||||
@service="default"
|
||||
/>
|
||||
`);
|
||||
|
||||
assert.dom('[data-test-bucket-item="peer"]').hasText(PEER_NAME, 'Peer is displayed');
|
||||
assert
|
||||
.dom('[data-test-bucket-item="nspace"]')
|
||||
.hasText(NAMESPACE_NAME, 'namespace is displayed');
|
||||
assert.dom('[data-test-bucket-item="service"]').hasText(SERVICE_NAME, 'service is displayed');
|
||||
assert.dom('[data-test-bucket-item="partition"]').doesNotExist('partition is not displayed');
|
||||
});
|
||||
|
||||
test('it displays a peer and no nspace and no service when item.namespace and nspace match', async function(assert) {
|
||||
const PEER_NAME = 'Tomster';
|
||||
const NAMESPACE_NAME = 'Mascot';
|
||||
const SERVICE_NAME = 'Ember.js';
|
||||
|
||||
this.set('peerName', PEER_NAME);
|
||||
this.set('namespace', NAMESPACE_NAME);
|
||||
this.set('service', SERVICE_NAME);
|
||||
|
||||
await render(hbs`
|
||||
<Consul::Bucket::List
|
||||
@item={{hash
|
||||
PeerName=this.peerName
|
||||
Namespace=this.namespace
|
||||
Service=this.service
|
||||
Partition="default"
|
||||
}}
|
||||
@nspace={{this.namespace}}
|
||||
@service="default"
|
||||
/>
|
||||
`);
|
||||
|
||||
assert.dom('[data-test-bucket-item="peer"]').hasText(PEER_NAME, 'Peer is displayed');
|
||||
assert.dom('[data-test-bucket-item="nspace"]').doesNotExist('namespace is not displayed');
|
||||
assert.dom('[data-test-bucket-item="service"]').doesNotExist('service is not displayed');
|
||||
assert.dom('[data-test-bucket-item="partition"]').doesNotExist('partition is not displayed');
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue