Merge pull request #3406 from hashicorp/b-ui-sort-allocs-by-modify-index

Sort allocs by ModifyIndex + bonus content
This commit is contained in:
Michael Lange 2017-10-18 11:59:01 -07:00 committed by GitHub
commit 721905b628
11 changed files with 114 additions and 72 deletions

View file

@ -1,7 +1,7 @@
import Ember from 'ember';
import { lazyClick } from '../helpers/lazy-click';
const { Component, inject } = Ember;
const { Component, inject, run } = Ember;
export default Component.extend({
store: inject.service(),
@ -45,11 +45,19 @@ export default Component.extend({
// being resolved through the store (store.findAll('job')). The
// workaround is to persist the jobID as a string on the allocation
// and manually re-link the two records here.
run.scheduleOnce('afterRender', this, qualifyJob);
},
});
const allocation = this.get('allocation');
function qualifyJob() {
const allocation = this.get('allocation');
if (allocation.get('originalJobId')) {
const job = this.get('store').peekRecord('job', allocation.get('originalJobId'));
if (job) {
allocation.set('job', job);
allocation.setProperties({
job,
originalJobId: null,
});
} else {
this.get('store')
.findRecord('job', allocation.get('originalJobId'))
@ -57,5 +65,5 @@ export default Component.extend({
allocation.set('job', job);
});
}
},
});
}
}

View file

@ -125,7 +125,7 @@ export default Component.extend(WindowResizable, {
.attr('y', () => isNarrow ? '50%' : 0)
.attr('clip-path', `url(#${this.get('maskId')})`)
.attr('height', () => isNarrow ? '6px' : '100%')
.attr('transform', () => isNarrow && 'translate(0, -3)')
.attr('transform', () => isNarrow ? 'translate(0, -3)' : '')
.merge(layers)
.attr('class', (d, i) => `bar layer-${i}`)
.transition()

View file

@ -5,6 +5,8 @@ const { Component, computed } = Ember;
export default Component.extend({
tagName: 'th',
attributeBindings: ['title'],
// The prop that the table is currently sorted by
currentProp: '',

View file

@ -17,8 +17,8 @@ export default Controller.extend(Sortable, Searchable, {
currentPage: 1,
pageSize: 10,
sortProperty: 'name',
sortDescending: false,
sortProperty: 'modifyIndex',
sortDescending: true,
searchProps: computed(() => ['id', 'name']),

View file

@ -10,6 +10,14 @@ import shortUUIDProperty from '../utils/properties/short-uuid';
const { computed, RSVP } = Ember;
const STATUS_ORDER = {
pending: 1,
running: 2,
complete: 3,
failed: 4,
lost: 5,
};
export default Model.extend({
shortId: shortUUIDProperty('id'),
job: belongsTo('job'),
@ -24,6 +32,9 @@ export default Model.extend({
clientStatus: attr('string'),
desiredStatus: attr('string'),
statusIndex: computed('clientStatus', function() {
return STATUS_ORDER[this.get('clientStatus')] || 100;
}),
taskGroup: computed('taskGroupName', 'job.taskGroups.[]', function() {
const taskGroups = this.get('job.taskGroups');

View file

@ -3,6 +3,7 @@
{{allocation.shortId}}
</a>
</td>
<td>{{allocation.modifyIndex}}</td>
<td>{{allocation.name}}</td>
<td>
<span class="color-swatch {{allocation.clientStatus}}" /> {{allocation.clientStatus}}

View file

@ -64,11 +64,13 @@
{{#list-table
source=p.list
sortProperty=sortProperty
sortDescending=sortDescending as |t|}}
sortDescending=sortDescending
class="with-foot" as |t|}}
{{#t.head}}
{{#t.sort-by prop="shortId"}}ID{{/t.sort-by}}
{{#t.sort-by prop="modifyIndex" title="Modify Index"}}Modified{{/t.sort-by}}
{{#t.sort-by prop="name"}}Name{{/t.sort-by}}
{{#t.sort-by prop="clientStatus"}}Status{{/t.sort-by}}
{{#t.sort-by prop="statusIndex"}}Status{{/t.sort-by}}
{{#t.sort-by prop="node.shortId"}}Node{{/t.sort-by}}
<th>CPU</th>
<th>Memory</th>
@ -77,19 +79,16 @@
{{allocation-row allocation=row.model context="job" onClick=(action "gotoAllocation" row.model)}}
{{/t.body}}
{{/list-table}}
<nav class="pagination is-centered">
<ul class="pagination-list">
{{#p.first class="pagination-link"}} |&lt; {{/p.first}}
{{#p.prev class="pagination-link"}} &lt; {{/p.prev}}
{{#each p.pageLinks as |link|}}
{{#link-to (query-params currentPage=link.pageNumber) class="pagination-link" activeClass="is-current"}}
{{link.pageNumber}}
{{/link-to}}
{{/each}}
{{#p.next class="pagination-link"}} &gt; {{/p.next}}
{{#p.last class="pagination-link"}} &gt;| {{/p.last}}
</ul>
</nav>
<div class="table-foot">
<nav class="pagination">
<div class="pagination-numbers">
{{p.startsAt}}&ndash;{{p.endsAt}} of {{sortedAllocations.length}}
</div>
{{#p.prev class="pagination-previous"}} &lt; {{/p.prev}}
{{#p.next class="pagination-next"}} &gt; {{/p.next}}
<ul class="pagination-list"></ul>
</nav>
</div>
{{else}}
<div class="boxed-section-body">
<div class="empty-message">

View file

@ -40,8 +40,9 @@
class="allocations with-foot" as |t|}}
{{#t.head}}
{{#t.sort-by prop="shortId"}}ID{{/t.sort-by}}
{{#t.sort-by prop="modifyIndex" title="Modify Index"}}Modified{{/t.sort-by}}
{{#t.sort-by prop="name"}}Name{{/t.sort-by}}
{{#t.sort-by prop="clientStatus"}}Status{{/t.sort-by}}
{{#t.sort-by prop="statusIndex"}}Status{{/t.sort-by}}
{{#t.sort-by prop="job.name"}}Job{{/t.sort-by}}
<th>CPU</th>
<th>Memory</th>

View file

@ -9,6 +9,8 @@ const DESIRED_STATUSES = ['run', 'stop', 'evict'];
export default Factory.extend({
id: i => (i >= 100 ? `${UUIDS[i % 100]}-${i}` : UUIDS[i]),
modifyIndex: () => faker.random.number({ min: 10, max: 2000 }),
clientStatus: faker.list.random(...CLIENT_STATUSES),
desiredStatus: faker.list.random(...DESIRED_STATUSES),

View file

@ -127,12 +127,20 @@ test('each allocation should have high-level details for the allocation', functi
.find('td:eq(1)')
.text()
.trim(),
allocation.modifyIndex,
'Allocation modify index'
);
assert.equal(
allocationRow
.find('td:eq(2)')
.text()
.trim(),
allocation.name,
'Allocation name'
);
assert.equal(
allocationRow
.find('td:eq(2)')
.find('td:eq(3)')
.text()
.trim(),
allocation.clientStatus,
@ -140,41 +148,41 @@ test('each allocation should have high-level details for the allocation', functi
);
assert.ok(
allocationRow
.find('td:eq(3)')
.find('td:eq(4)')
.text()
.includes(server.db.jobs.find(allocation.jobId).name),
'Job name'
);
assert.ok(
allocationRow
.find('td:eq(3) .is-faded')
.find('td:eq(4) .is-faded')
.text()
.includes(allocation.taskGroup),
'Task group name'
);
assert.equal(
allocationRow
.find('td:eq(4)')
.find('td:eq(5)')
.text()
.trim(),
allocStats.resourceUsage.CpuStats.Percent,
'CPU %'
);
assert.equal(
allocationRow.find('td:eq(4) .tooltip').attr('aria-label'),
allocationRow.find('td:eq(5) .tooltip').attr('aria-label'),
`${Math.floor(allocStats.resourceUsage.CpuStats.TotalTicks)} / ${cpuUsed} MHz`,
'Detailed CPU information is in a tooltip'
);
assert.equal(
allocationRow
.find('td:eq(5)')
.find('td:eq(6)')
.text()
.trim(),
allocStats.resourceUsage.MemoryStats.RSS / 1024 / 1024 / memoryUsed,
'Memory used'
);
assert.equal(
allocationRow.find('td:eq(5) .tooltip').attr('aria-label'),
allocationRow.find('td:eq(6) .tooltip').attr('aria-label'),
`${formatBytes([allocStats.resourceUsage.MemoryStats.RSS])} / ${memoryUsed} MiB`,
'Detailed memory information is in a tooltip'
);
@ -209,14 +217,14 @@ test('each allocation should show job information even if the job is incomplete
assert.ok(
allocationRow
.find('td:eq(3)')
.find('td:eq(4)')
.text()
.includes(server.db.jobs.find(allocation.jobId).name),
'Job name'
);
assert.ok(
allocationRow
.find('td:eq(3) .is-faded')
.find('td:eq(4) .is-faded')
.text()
.includes(allocation.taskGroup),
'Task group name'
@ -252,7 +260,7 @@ test('each allocation should link to the job the allocation belongs to', functio
const job = server.db.jobs.find(allocation.jobId);
andThen(() => {
click($('.allocations tbody tr:eq(0) td:eq(3) a').get(0));
click($('.allocations tbody tr:eq(0) td:eq(4) a').get(0));
});
andThen(() => {

View file

@ -140,43 +140,53 @@ test('/jobs/:id/:task-group should list one page of allocations for the task gro
});
test('each allocation should show basic information about the allocation', function(assert) {
const allocation = allocations.sortBy('name')[0];
const allocation = allocations.sortBy('modifyIndex').reverse()[0];
const allocationRow = $(findAll('.allocations tbody tr')[0]);
assert.equal(
allocationRow
.find('td:eq(0)')
.text()
.trim(),
allocation.id.split('-')[0],
'Allocation short id'
);
assert.equal(
allocationRow
.find('td:eq(1)')
.text()
.trim(),
allocation.name,
'Allocation name'
);
assert.equal(
allocationRow
.find('td:eq(2)')
.text()
.trim(),
allocation.clientStatus,
'Client status'
);
assert.equal(
allocationRow
.find('td:eq(3)')
.text()
.trim(),
server.db.nodes.find(allocation.nodeId).id.split('-')[0],
'Node ID'
);
andThen(() => {
assert.equal(
allocationRow
.find('td:eq(0)')
.text()
.trim(),
allocation.id.split('-')[0],
'Allocation short id'
);
assert.equal(
allocationRow
.find('td:eq(1)')
.text()
.trim(),
allocation.modifyIndex,
'Allocation modify index'
);
assert.equal(
allocationRow
.find('td:eq(2)')
.text()
.trim(),
allocation.name,
'Allocation name'
);
assert.equal(
allocationRow
.find('td:eq(3)')
.text()
.trim(),
allocation.clientStatus,
'Client status'
);
assert.equal(
allocationRow
.find('td:eq(4)')
.text()
.trim(),
server.db.nodes.find(allocation.nodeId).id.split('-')[0],
'Node ID'
);
});
click(allocationRow.find('td:eq(3) a').get(0));
click(allocationRow.find('td:eq(4) a').get(0));
andThen(() => {
assert.equal(currentURL(), `/nodes/${allocation.nodeId}`, 'Node links to node page');
@ -196,7 +206,7 @@ test('each allocation should show stats about the allocation, retrieved directly
assert.equal(
allocationRow
.find('td:eq(4)')
.find('td:eq(5)')
.text()
.trim(),
allocStats.resourceUsage.CpuStats.Percent,
@ -204,14 +214,14 @@ test('each allocation should show stats about the allocation, retrieved directly
);
assert.equal(
allocationRow.find('td:eq(4) .tooltip').attr('aria-label'),
allocationRow.find('td:eq(5) .tooltip').attr('aria-label'),
`${Math.floor(allocStats.resourceUsage.CpuStats.TotalTicks)} / ${cpuUsed} MHz`,
'Detailed CPU information is in a tooltip'
);
assert.equal(
allocationRow
.find('td:eq(5)')
.find('td:eq(6)')
.text()
.trim(),
allocStats.resourceUsage.MemoryStats.RSS / 1024 / 1024 / memoryUsed,
@ -219,7 +229,7 @@ test('each allocation should show stats about the allocation, retrieved directly
);
assert.equal(
allocationRow.find('td:eq(5) .tooltip').attr('aria-label'),
allocationRow.find('td:eq(6) .tooltip').attr('aria-label'),
`${formatBytes([allocStats.resourceUsage.MemoryStats.RSS])} / ${memoryUsed} MiB`,
'Detailed memory information is in a tooltip'
);