ui: Move healthcheck ordering to use new comparators (#8096)
This commit is contained in:
parent
2162f8a4fa
commit
d2515ed409
|
@ -1,11 +1,11 @@
|
|||
<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">
|
||||
<div>
|
||||
<ul>
|
||||
{{#each items as |item| }}
|
||||
<li class={{concat 'healthcheck-output ' item.Status}}>
|
||||
<div>
|
||||
<header>
|
||||
<h3>{{item.Name}}</h3>
|
||||
</BlockSlot>
|
||||
<BlockSlot @name="content">
|
||||
</header>
|
||||
<dl>
|
||||
{{#if (eq item.ServiceName "")}}
|
||||
<dt>NodeName</dt>
|
||||
|
@ -23,9 +23,9 @@
|
|||
<dt>Type</dt>
|
||||
<dd>
|
||||
{{item.Type}}
|
||||
{{#if (and exposed (contains item.Type (array 'http' 'grpc')))}}
|
||||
{{#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}}
|
||||
{{/if}}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
|
@ -33,15 +33,16 @@
|
|||
<dd>{{or item.Notes '-'}}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
{{#if (not-eq item.Type 'ttl')}}
|
||||
{{#if (not-eq item.Type 'ttl')}}
|
||||
<dt>Output</dt>
|
||||
<dd>
|
||||
<pre><code>{{item.Output}}</code></pre>
|
||||
<CopyButton @value={{item.Output}} @name="output" />
|
||||
</dd>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</dl>
|
||||
</BlockSlot>
|
||||
</HealthcheckOutput>
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -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: '',
|
||||
});
|
||||
|
|
|
@ -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>
|
|
@ -1,6 +0,0 @@
|
|||
import Component from '@ember/component';
|
||||
import Slotted from 'block-slots';
|
||||
|
||||
export default Component.extend(Slotted, {
|
||||
classNames: ['healthcheck-output'],
|
||||
});
|
|
@ -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;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -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) {
|
||||
|
|
42
ui-v2/app/sort/comparators/check.js
Normal file
42
ui-v2/app/sort/comparators/check.js
Normal 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;
|
||||
};
|
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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(), '');
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue