ui: Move healthcheck ordering to use new comparators (#8096)

This commit is contained in:
John Cowen 2020-06-16 14:13:29 +01:00 committed by GitHub
parent 7dd54185d8
commit 62680891be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 96 additions and 149 deletions

View File

@ -1,47 +1,48 @@
<ul>
{{#each (sort-by (action 'sortChecksByImportance') items) as |item| }}
{{! TODO: this component and its child should be moved to a single component }}
<HealthcheckOutput class={{item.Status}} @tagName="li">
<BlockSlot @name="header">
<h3>{{item.Name}}</h3>
</BlockSlot>
<BlockSlot @name="content">
<dl>
{{#if (eq item.ServiceName "")}}
<dt>NodeName</dt>
<dd>{{item.Node}}</dd>
{{else}}
<dt>ServiceName</dt>
<dd>{{item.ServiceName}}</dd>
{{/if}}
</dl>
<dl>
<dt>CheckID</dt>
<dd>{{or item.CheckID '-'}}</dd>
</dl>
<dl>
<dt>Type</dt>
<dd>
{{item.Type}}
{{#if (and exposed (contains item.Type (array 'http' 'grpc')))}}
<em data-test-exposed="true" data-tooltip="Expose.checks is set to true, so all registered HTTP and gRPC check paths are exposed through Envoy for the Consul agent.">Exposed</em>
{{/if}}
</dd>
</dl>
<dl>
<dt>Notes</dt>
<dd>{{or item.Notes '-'}}</dd>
</dl>
<dl>
{{#if (not-eq item.Type 'ttl')}}
<dt>Output</dt>
<dd>
<pre><code>{{item.Output}}</code></pre>
<CopyButton @value={{item.Output}} @name="output" />
</dd>
{{/if}}
</dl>
</BlockSlot>
</HealthcheckOutput>
<div>
<ul>
{{#each items as |item| }}
<li class={{concat 'healthcheck-output ' item.Status}}>
<div>
<header>
<h3>{{item.Name}}</h3>
</header>
<dl>
{{#if (eq item.ServiceName "")}}
<dt>NodeName</dt>
<dd>{{item.Node}}</dd>
{{else}}
<dt>ServiceName</dt>
<dd>{{item.ServiceName}}</dd>
{{/if}}
</dl>
<dl>
<dt>CheckID</dt>
<dd>{{or item.CheckID '-'}}</dd>
</dl>
<dl>
<dt>Type</dt>
<dd>
{{item.Type}}
{{#if (and exposed (contains item.Type (array 'http' 'grpc')))}}
<em data-test-exposed="true" data-tooltip="Expose.checks is set to true, so all registered HTTP and gRPC check paths are exposed through Envoy for the Consul agent.">Exposed</em>
{{/if}}
</dd>
</dl>
<dl>
<dt>Notes</dt>
<dd>{{or item.Notes '-'}}</dd>
</dl>
<dl>
{{#if (not-eq item.Type 'ttl')}}
<dt>Output</dt>
<dd>
<pre><code>{{item.Output}}</code></pre>
<CopyButton @value={{item.Output}} @name="output" />
</dd>
{{/if}}
</dl>
</div>
</li>
{{/each}}
</ul>
</ul>
</div>

View File

@ -1,36 +1,5 @@
import Component from '@ember/component';
import { get } from '@ember/object';
export default Component.extend({
// TODO: Could potentially do this on attr change
actions: {
sortChecksByImportance: function(a, b) {
const statusA = get(a, 'Status');
const statusB = get(b, 'Status');
switch (statusA) {
case 'passing':
// a = passing
// unless b is also passing then a is less important
return statusB === 'passing' ? 0 : 1;
case 'critical':
// a = critical
// unless b is also critical then a is more important
return statusB === 'critical' ? 0 : -1;
case 'warning':
// a = warning
switch (statusB) {
// b is passing so a is more important
case 'passing':
return -1;
// b is critical so a is less important
case 'critical':
return 1;
// a and b are both warning, therefore equal
default:
return 0;
}
}
return 0;
},
},
tagName: '',
});

View File

@ -1,8 +0,0 @@
{{! TODO: this component and its parent should be moved to a single component }}
{{yield}}
<div>
<header>
<YieldSlot @name="header">{{yield}}</YieldSlot>
</header>
<YieldSlot @name="content">{{yield}}</YieldSlot>
</div>

View File

@ -1,6 +0,0 @@
import Component from '@ember/component';
import Slotted from 'block-slots';
export default Component.extend(Slotted, {
classNames: ['healthcheck-output'],
});

View File

@ -23,34 +23,4 @@ export default Controller.extend(WithEventSource, {
}
}
}),
actions: {
sortChecksByImportance: function(a, b) {
const statusA = get(a, 'Status');
const statusB = get(b, 'Status');
switch (statusA) {
case 'passing':
// a = passing
// unless b is also passing then a is less important
return statusB === 'passing' ? 0 : 1;
case 'critical':
// a = critical
// unless b is also critical then a is more important
return statusB === 'critical' ? 0 : -1;
case 'warning':
// a = warning
switch (statusB) {
// b is passing so a is more important
case 'passing':
return -1;
// b is critical so a is less important
case 'critical':
return 1;
// a and b are both warning, therefore equal
default:
return 0;
}
}
return 0;
},
},
});

View File

@ -1,10 +1,12 @@
import service from 'consul-ui/sort/comparators/service';
import check from 'consul-ui/sort/comparators/check';
export function initialize(container) {
// Service-less injection using private properties at a per-project level
const Sort = container.resolveRegistration('service:sort');
const comparators = {
service: service(),
check: check(),
};
Sort.reopen({
comparator: function(type) {

View File

@ -0,0 +1,42 @@
export default () => key => {
if (key.startsWith('Status:')) {
return function(itemA, itemB) {
const [, dir] = key.split(':');
let a, b;
if (dir === 'asc') {
a = itemA;
b = itemB;
} else {
b = itemA;
a = itemB;
}
const statusA = a.Status;
const statusB = b.Status;
switch (statusA) {
case 'passing':
// a = passing
// unless b is also passing then a is less important
return statusB === 'passing' ? 0 : 1;
case 'critical':
// a = critical
// unless b is also critical then a is more important
return statusB === 'critical' ? 0 : -1;
case 'warning':
// a = warning
switch (statusB) {
// b is passing so a is more important
case 'passing':
return -1;
// b is critical so a is less important
case 'critical':
return 1;
// a and b are both warning, therefore equal
default:
return 0;
}
}
return 0;
};
}
return key;
};

View File

@ -1,7 +1,7 @@
<div id="health-checks" class="tab-section">
<div role="tabpanel">
{{#if (gt item.Checks.length 0) }}
<HealthcheckList @items={{item.Checks}} />
<HealthcheckList @items={{sort-by (comparator 'check' 'Status:asc') item.Checks}} />
{{else}}
<p>
This node has no health checks.

View File

@ -2,7 +2,7 @@
<div role="tabpanel">
{{#if (gt item.ServiceChecks.length 0) }}
<section data-test-service-checks>
<HealthcheckList @items={{item.ServiceChecks}} @exposed={{proxy.ServiceProxy.Expose.Checks}} />
<HealthcheckList @items={{sort-by (comparator 'check' 'Status:asc') item.ServiceChecks}} @exposed={{proxy.ServiceProxy.Expose.Checks}} />
</section>
{{else}}
<p>
@ -11,7 +11,7 @@
{{/if}}
{{#if (gt item.NodeChecks.length 0) }}
<section data-test-node-checks>
<HealthcheckList @items={{item.NodeChecks}} />
<HealthcheckList @items={{sort-by (comparator 'check' 'Status:asc') item.NodeChecks}} />
</section>
{{else}}
<p>

View File

@ -140,7 +140,7 @@
{{#if (or (gt proxy.ServiceChecks.length 0) (gt proxy.NodeChecks.length 0))}}
<section>
<h3>Proxy health</h3>
<HealthcheckList data-test-proxy-checks @items={{append proxy.ServiceChecks proxy.NodeChecks}} />
<HealthcheckList data-test-proxy-checks @items={{sort-by (comparator 'check' 'Status:asc') (append proxy.ServiceChecks proxy.NodeChecks)}} />
</section>
{{/if}}
</div>

View File

@ -1,23 +0,0 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, find } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
module('Integration | Component | healthcheck output', function(hooks) {
setupRenderingTest(hooks);
test('it renders', async function(assert) {
// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.on('myAction', function(val) { ... });
await render(hbs`{{healthcheck-output}}`);
assert.equal(find('*').textContent.trim(), '');
// Template block usage:
await render(hbs`
{{#healthcheck-output}}{{/healthcheck-output}}
`);
assert.equal(find('*').textContent.trim(), '');
});
});