mirror of
https://github.com/kemko/nomad.git
synced 2026-01-06 18:35:44 +03:00
New primary-metric component
It encapsulates all the tracker, polling, and markup for this style of metric.
This commit is contained in:
103
ui/app/components/primary-metric.js
Normal file
103
ui/app/components/primary-metric.js
Normal file
@@ -0,0 +1,103 @@
|
||||
import Ember from 'ember';
|
||||
import Component from '@ember/component';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { computed } from '@ember/object';
|
||||
import NodeStatsTracker from 'nomad-ui/utils/classes/node-stats-tracker';
|
||||
import AllocationStatsTracker from 'nomad-ui/utils/classes/allocation-stats-tracker';
|
||||
import { task, timeout } from 'ember-concurrency';
|
||||
|
||||
export default Component.extend({
|
||||
token: service(),
|
||||
|
||||
// One of Node, Allocation, or TaskState
|
||||
resource: null,
|
||||
|
||||
// cpu or memory
|
||||
metric: null,
|
||||
|
||||
// An instance of a StatsTracker. An alternative interface to resource
|
||||
tracker: computed('trackedResource', 'type', function() {
|
||||
const resource = this.get('trackedResource');
|
||||
|
||||
if (!resource) return;
|
||||
|
||||
const Constructor = this.get('type') === 'node' ? NodeStatsTracker : AllocationStatsTracker;
|
||||
const resourceProp = this.get('type') === 'node' ? 'node' : 'allocation';
|
||||
return Constructor.create({
|
||||
fetch: url => this.get('token').authorizedRequest(url),
|
||||
[resourceProp]: resource,
|
||||
});
|
||||
}),
|
||||
|
||||
type: computed('resource', function() {
|
||||
const resource = this.get('resource');
|
||||
return resource && resource.constructor.modelName;
|
||||
}),
|
||||
|
||||
trackedResource: computed('resource', 'type', function() {
|
||||
// TaskStates use the allocation stats tracker
|
||||
return this.get('type') === 'task-state'
|
||||
? this.get('resource.allocation')
|
||||
: this.get('resource');
|
||||
}),
|
||||
|
||||
metricLabel: computed('metric', function() {
|
||||
const metric = this.get('metric');
|
||||
const mappings = {
|
||||
cpu: 'CPU',
|
||||
memory: 'Memory',
|
||||
};
|
||||
return mappings[metric] || metric;
|
||||
}),
|
||||
|
||||
data: computed('resource', 'metric', 'type', function() {
|
||||
if (!this.get('tracker')) return [];
|
||||
|
||||
const metric = this.get('metric');
|
||||
if (this.get('type') === 'task-state') {
|
||||
// handle getting the right task out of the tracker
|
||||
const task = this.get('tracker.tasks').findBy('task', this.get('resource.name'));
|
||||
return task && task[metric];
|
||||
}
|
||||
|
||||
return this.get(`tracker.${metric}`);
|
||||
}),
|
||||
|
||||
reservedAmount: computed('resource', 'metric', 'type', function() {
|
||||
const metricProperty = this.get('metric') === 'cpu' ? 'reservedCPU' : 'reservedMemory';
|
||||
|
||||
if (this.get('type') === 'task-state') {
|
||||
const task = this.get('tracker.tasks').findBy('task', this.get('resource.name'));
|
||||
return task[metricProperty];
|
||||
}
|
||||
|
||||
return this.get(`tracker.${metricProperty}`);
|
||||
}),
|
||||
|
||||
chartClass: computed('metric', function() {
|
||||
const metric = this.get('metric');
|
||||
const mappings = {
|
||||
cpu: 'is-info',
|
||||
memory: 'is-danger',
|
||||
};
|
||||
|
||||
return mappings[metric] || 'is-primary';
|
||||
}),
|
||||
|
||||
poller: task(function*() {
|
||||
do {
|
||||
yield this.get('tracker').poll();
|
||||
yield timeout(2000);
|
||||
} while (!Ember.testing);
|
||||
}),
|
||||
|
||||
didReceiveAttrs() {
|
||||
if (this.get('tracker')) {
|
||||
this.get('poller').perform();
|
||||
}
|
||||
},
|
||||
|
||||
willDestroy() {
|
||||
this.get('poller').cancelAll();
|
||||
},
|
||||
});
|
||||
26
ui/app/templates/components/primary-metric.hbs
Normal file
26
ui/app/templates/components/primary-metric.hbs
Normal file
@@ -0,0 +1,26 @@
|
||||
{{metricLabel}}
|
||||
<div style="height: 200px">
|
||||
{{stats-time-series data=data chartClass=chartClass}}
|
||||
</div>
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<div class="inline-chart">
|
||||
<progress
|
||||
class="progress {{chartClass}} is-small"
|
||||
value="{{data.lastObject.percent}}"
|
||||
max="1">
|
||||
{{data.lastObject.percent}}
|
||||
</progress>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-minimum">
|
||||
{{format-percentage data.lastObject.percent total=1}}
|
||||
</div>
|
||||
</div>
|
||||
{{#if (eq metric "cpu")}}
|
||||
{{data.lastObject.used}} Mhz / {{reservedAmount}} Mhz reserved
|
||||
{{else if (eq metric "memory")}}
|
||||
{{format-bytes data.lastObject.used}} MiB / {{reservedAmount}} MiB reserved
|
||||
{{else}}
|
||||
{{data.lastObject.used}} / {{reservedAmount}} reserved
|
||||
{{/if}}
|
||||
@@ -19,9 +19,7 @@ export default Mixin.create({
|
||||
assert('Url must be defined', url);
|
||||
|
||||
return this.get('fetch')(url)
|
||||
.then(res => {
|
||||
return res.json();
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(frame => this.append(frame));
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user