Merge pull request #3845 from hashicorp/f-ui-node-meta

UI: Add client meta attributes to the client detail page
This commit is contained in:
Michael Lange 2018-02-26 16:53:06 -08:00 committed by GitHub
commit d5254c1563
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 67 additions and 7 deletions

View file

@ -9,8 +9,13 @@ export default Fragment.extend({
attributes: attr(), attributes: attr(),
attributesStructured: computed('attributes', function() { attributesStructured: computed('attributes', function() {
// `unflatten` doesn't sort keys before unflattening, so manual preprocessing is necessary.
const original = this.get('attributes'); const original = this.get('attributes');
if (!original) {
return;
}
// `unflatten` doesn't sort keys before unflattening, so manual preprocessing is necessary.
const attrs = Object.keys(original) const attrs = Object.keys(original)
.sort() .sort()
.reduce((obj, key) => { .reduce((obj, key) => {

View file

@ -20,6 +20,7 @@ export default Model.extend({
httpAddr: attr('string'), httpAddr: attr('string'),
tlsEnabled: attr('boolean'), tlsEnabled: attr('boolean'),
attributes: fragment('node-attributes'), attributes: fragment('node-attributes'),
meta: fragment('node-attributes'),
resources: fragment('resources'), resources: fragment('resources'),
reserved: fragment('resources'), reserved: fragment('resources'),

View file

@ -84,6 +84,24 @@
attributes=model.attributes.attributesStructured attributes=model.attributes.attributesStructured
class="attributes-table"}} class="attributes-table"}}
</div> </div>
<div class="boxed-section-head">
Meta
</div>
{{#if model.meta.attributesStructured}}
<div class="boxed-section-body is-full-bleed">
{{attributes-table
data-test-meta
attributes=model.meta.attributesStructured
class="attributes-table"}}
</div>
{{else}}
<div class="boxed-section-body">
<div data-test-empty-meta-message class="empty-message">
<h3 class="empty-message-headline">No Meta Attributes</h3>
<p class="empty-message-body">This client is configured with no meta attributes.</p>
</div>
</div>
{{/if}}
</div> </div>
</section> </section>
{{/gutter-menu}} {{/gutter-menu}}

View file

@ -58,6 +58,14 @@ export default Factory.extend({
}; };
}, },
withMeta: trait({
meta: {
just: 'some',
prop: 'erties',
'over.here': 100,
},
}),
afterCreate(node, server) { afterCreate(node, server) {
// Each node has a corresponding client stats resource that's queried via node IP. // Each node has a corresponding client stats resource that's queried via node IP.
// Create that record, even though it's not a relationship. // Create that record, even though it's not a relationship.

View file

@ -197,9 +197,7 @@ test('each allocation should have high-level details for the allocation', functi
}); });
}); });
test('each allocation should show job information even if the job is incomplete and already in the store', function( test('each allocation should show job information even if the job is incomplete and already in the store', function(assert) {
assert
) {
// First, visit clients to load the allocations for each visible node. // First, visit clients to load the allocations for each visible node.
// Don't load the job belongsTo of the allocation! Leave it unfulfilled. // Don't load the job belongsTo of the allocation! Leave it unfulfilled.
@ -288,9 +286,39 @@ test('/clients/:id should list all attributes for the node', function(assert) {
}); });
}); });
test('when the node is not found, an error message is shown, but the URL persists', function( test('/clients/:id lists all meta attributes', function(assert) {
assert node = server.create('node', 'forceIPv4', 'withMeta');
) {
visit(`/clients/${node.id}`);
andThen(() => {
assert.ok(find('[data-test-meta]'), 'Meta attributes table is on the page');
assert.notOk(find('[data-test-empty-meta-message]'), 'Meta attributes is not empty');
const firstMetaKey = Object.keys(node.meta)[0];
assert.equal(
find('[data-test-meta] [data-test-key]').textContent.trim(),
firstMetaKey,
'Meta attributes for the node are bound to the attributes table'
);
assert.equal(
find('[data-test-meta] [data-test-value]').textContent.trim(),
node.meta[firstMetaKey],
'Meta attributes for the node are bound to the attributes table'
);
});
});
test('/clients/:id shows an empty message when there is no meta data', function(assert) {
visit(`/clients/${node.id}`);
andThen(() => {
assert.notOk(find('[data-test-meta]'), 'Meta attributes table is not on the page');
assert.ok(find('[data-test-empty-meta-message]'), 'Meta attributes is empty');
});
});
test('when the node is not found, an error message is shown, but the URL persists', function(assert) {
visit('/clients/not-a-real-node'); visit('/clients/not-a-real-node');
andThen(() => { andThen(() => {