Skip to content

Commit

Permalink
Merge pull request #3829 from hashicorp/f-ui-specialized-job-pages
Browse files Browse the repository at this point in the history
UI: Specialized Job Detail Pages
  • Loading branch information
DingoEatingFuzz committed Feb 7, 2018
2 parents 229760a + 9e606f3 commit ea9ff98
Show file tree
Hide file tree
Showing 58 changed files with 2,059 additions and 582 deletions.
13 changes: 13 additions & 0 deletions ui/app/adapters/job.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,17 @@ export default ApplicationAdapter.extend({
const url = this.buildURL('job', name, job, 'findRecord');
return this.ajax(url, 'GET', { data: assign(this.buildQuery() || {}, namespaceQuery) });
},

forcePeriodic(job) {
if (job.get('periodic')) {
const [name, namespace] = JSON.parse(job.get('id'));
let url = `${this.buildURL('job', name, job, 'findRecord')}/periodic/force`;

if (namespace) {
url += `?namespace=${namespace}`;
}

return this.ajax(url, 'POST');
}
},
});
2 changes: 2 additions & 0 deletions ui/app/components/allocation-status-bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export default DistributionBar.extend({

allocationContainer: null,

'data-test-allocation-status-bar': true,

data: computed(
'allocationContainer.{queuedAllocs,completeAllocs,failedAllocs,runningAllocs,startingAllocs}',
function() {
Expand Down
27 changes: 27 additions & 0 deletions ui/app/components/children-status-bar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { computed } from '@ember/object';
import DistributionBar from './distribution-bar';

export default DistributionBar.extend({
layoutName: 'components/distribution-bar',

job: null,

'data-test-children-status-bar': true,

data: computed('job.{pendingChildren,runningChildren,deadChildren}', function() {
if (!this.get('job')) {
return [];
}

const children = this.get('job').getProperties(
'pendingChildren',
'runningChildren',
'deadChildren'
);
return [
{ label: 'Pending', value: children.pendingChildren, className: 'queued' },
{ label: 'Running', value: children.runningChildren, className: 'running' },
{ label: 'Dead', value: children.deadChildren, className: 'complete' },
];
}),
});
29 changes: 29 additions & 0 deletions ui/app/components/job-page/abstract.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Component from '@ember/component';
import { computed } from '@ember/object';
import { inject as service } from '@ember/service';

export default Component.extend({
system: service(),

job: null,

// Provide a value that is bound to a query param
sortProperty: null,
sortDescending: null,

// Provide actions that require routing
onNamespaceChange() {},
gotoTaskGroup() {},
gotoJob() {},

breadcrumbs: computed('job.{name,id}', function() {
const job = this.get('job');
return [
{ label: 'Jobs', args: ['jobs'] },
{
label: job.get('name'),
args: ['jobs.job', job],
},
];
}),
});
3 changes: 3 additions & 0 deletions ui/app/components/job-page/batch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import AbstractJobPage from './abstract';

export default AbstractJobPage.extend();
16 changes: 16 additions & 0 deletions ui/app/components/job-page/parameterized-child.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { computed } from '@ember/object';
import { alias } from '@ember/object/computed';
import PeriodicChildJobPage from './periodic-child';

export default PeriodicChildJobPage.extend({
payload: alias('job.decodedPayload'),
payloadJSON: computed('payload', function() {
let json;
try {
json = JSON.parse(this.get('payload'));
} catch (e) {
// Swallow error and fall back to plain text rendering
}
return json;
}),
});
3 changes: 3 additions & 0 deletions ui/app/components/job-page/parameterized.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import AbstractJobPage from './abstract';

export default AbstractJobPage.extend();
31 changes: 31 additions & 0 deletions ui/app/components/job-page/parts/children.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Component from '@ember/component';
import { computed } from '@ember/object';
import { alias } from '@ember/object/computed';
import Sortable from 'nomad-ui/mixins/sortable';

export default Component.extend(Sortable, {
job: null,

classNames: ['boxed-section'],

// Provide a value that is bound to a query param
sortProperty: null,
sortDescending: null,
currentPage: null,

// Provide an action with access to the router
gotoJob() {},

pageSize: 10,

taskGroups: computed('job.taskGroups.[]', function() {
return this.get('job.taskGroups') || [];
}),

children: computed('job.children.[]', function() {
return this.get('job.children') || [];
}),

listToSort: alias('children'),
sortedChildren: alias('listSorted'),
});
12 changes: 12 additions & 0 deletions ui/app/components/job-page/parts/evaluations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import Component from '@ember/component';
import { computed } from '@ember/object';

export default Component.extend({
job: null,

classNames: ['boxed-section'],

sortedEvaluations: computed('job.evaluations.@each.modifyIndex', function() {
return (this.get('job.evaluations') || []).sortBy('modifyIndex').reverse();
}),
});
6 changes: 6 additions & 0 deletions ui/app/components/job-page/parts/placement-failures.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Component from '@ember/component';

export default Component.extend({
job: null,
tagName: '',
});
6 changes: 6 additions & 0 deletions ui/app/components/job-page/parts/running-deployment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Component from '@ember/component';

export default Component.extend({
job: null,
tagName: '',
});
7 changes: 7 additions & 0 deletions ui/app/components/job-page/parts/summary.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Component from '@ember/component';

export default Component.extend({
job: null,

classNames: ['boxed-section'],
});
24 changes: 24 additions & 0 deletions ui/app/components/job-page/parts/task-groups.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import Component from '@ember/component';
import { computed } from '@ember/object';
import { alias } from '@ember/object/computed';
import Sortable from 'nomad-ui/mixins/sortable';

export default Component.extend(Sortable, {
job: null,

classNames: ['boxed-section'],

// Provide a value that is bound to a query param
sortProperty: null,
sortDescending: null,

// Provide an action with access to the router
gotoTaskGroup() {},

taskGroups: computed('job.taskGroups.[]', function() {
return this.get('job.taskGroups') || [];
}),

listToSort: alias('taskGroups'),
sortedTaskGroups: alias('listSorted'),
});
21 changes: 21 additions & 0 deletions ui/app/components/job-page/periodic-child.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import AbstractJobPage from './abstract';
import { computed } from '@ember/object';

export default AbstractJobPage.extend({
breadcrumbs: computed('job.{name,id}', 'job.parent.{name,id}', function() {
const job = this.get('job');
const parent = this.get('job.parent');

return [
{ label: 'Jobs', args: ['jobs'] },
{
label: parent.get('name'),
args: ['jobs.job', parent],
},
{
label: job.get('trimmedName'),
args: ['jobs.job', job],
},
];
}),
});
15 changes: 15 additions & 0 deletions ui/app/components/job-page/periodic.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import AbstractJobPage from './abstract';
import { inject as service } from '@ember/service';

export default AbstractJobPage.extend({
store: service(),
actions: {
forceLaunch() {
this.get('job')
.forcePeriodic()
.then(() => {
this.get('store').findAll('job');
});
},
},
});
3 changes: 3 additions & 0 deletions ui/app/components/job-page/service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import AbstractJobPage from './abstract';

export default AbstractJobPage.extend();
22 changes: 12 additions & 10 deletions ui/app/controllers/jobs/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { inject as service } from '@ember/service';
import { alias, filterBy } from '@ember/object/computed';
import { alias } from '@ember/object/computed';
import Controller, { inject as controller } from '@ember/controller';
import { computed } from '@ember/object';
import Sortable from 'nomad-ui/mixins/sortable';
Expand All @@ -11,10 +11,6 @@ export default Controller.extend(Sortable, Searchable, {

isForbidden: alias('jobsController.isForbidden'),

pendingJobs: filterBy('model', 'status', 'pending'),
runningJobs: filterBy('model', 'status', 'running'),
deadJobs: filterBy('model', 'status', 'dead'),

queryParams: {
currentPage: 'page',
searchTerm: 'search',
Expand All @@ -30,16 +26,22 @@ export default Controller.extend(Sortable, Searchable, {

searchProps: computed(() => ['id', 'name']),

/**
Filtered jobs are those that match the selected namespace and aren't children
of periodic or parameterized jobs.
*/
filteredJobs: computed(
'model.[]',
'model.@each.parent',
'system.activeNamespace',
'system.namespaces.length',
function() {
if (this.get('system.namespaces.length')) {
return this.get('model').filterBy('namespace.id', this.get('system.activeNamespace.id'));
} else {
return this.get('model');
}
const hasNamespaces = this.get('system.namespaces.length');
const activeNamespace = this.get('system.activeNamespace.id');

return this.get('model')
.filter(job => !hasNamespaces || job.get('namespace.id') === activeNamespace)
.filter(job => !job.get('parent.content'));
}
),

Expand Down
22 changes: 7 additions & 15 deletions ui/app/controllers/jobs/job/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { inject as service } from '@ember/service';
import { alias } from '@ember/object/computed';
import Controller, { inject as controller } from '@ember/controller';
import { computed } from '@ember/object';
import Sortable from 'nomad-ui/mixins/sortable';
import WithNamespaceResetting from 'nomad-ui/mixins/with-namespace-resetting';

export default Controller.extend(Sortable, WithNamespaceResetting, {
export default Controller.extend(WithNamespaceResetting, {
system: service(),
jobController: controller('jobs.job'),

Expand All @@ -16,28 +14,22 @@ export default Controller.extend(Sortable, WithNamespaceResetting, {
},

currentPage: 1,
pageSize: 10,

sortProperty: 'name',
sortDescending: false,

breadcrumbs: alias('jobController.breadcrumbs'),
job: alias('model'),

taskGroups: computed('model.taskGroups.[]', function() {
return this.get('model.taskGroups') || [];
}),

listToSort: alias('taskGroups'),
sortedTaskGroups: alias('listSorted'),

sortedEvaluations: computed('model.evaluations.@each.modifyIndex', function() {
return (this.get('model.evaluations') || []).sortBy('modifyIndex').reverse();
}),

actions: {
gotoTaskGroup(taskGroup) {
this.transitionToRoute('jobs.job.task-group', taskGroup.get('job'), taskGroup);
},

gotoJob(job) {
this.transitionToRoute('jobs.job', job, {
queryParams: { jobNamespace: job.get('namespace.name') },
});
},
},
});
Loading

0 comments on commit ea9ff98

Please sign in to comment.