Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI: Stop job button #4189

Merged
merged 11 commits into from
Apr 21, 2018
24 changes: 17 additions & 7 deletions ui/app/adapters/job.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,24 @@ export default Watchable.extend({

forcePeriodic(job) {
if (job.get('periodic')) {
const [path, params] = this.buildURL('job', job.get('id'), job, 'findRecord').split('?');
let url = `${path}/periodic/force`;

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

const url = addToPath(this.urlForFindRecord(job.get('id'), 'job'), '/periodic/force');
return this.ajax(url, 'POST');
}
},

stop(job) {
const url = this.urlForFindRecord(job.get('id'), 'job');
return this.ajax(url, 'DELETE');
},
});

function addToPath(url, extension = '') {
const [path, params] = url.split('?');
let newUrl = `${path}${extension}`;

if (params) {
newUrl += `?${params}`;
}

return newUrl;
}
12 changes: 12 additions & 0 deletions ui/app/components/job-page/abstract.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ export default Component.extend({
gotoTaskGroup() {},
gotoJob() {},

// Set to a { title, description } to surface an error
errorMessage: null,

breadcrumbs: computed('job.{name,id}', function() {
const job = this.get('job');
return [
Expand All @@ -33,4 +36,13 @@ export default Component.extend({
},
];
}),

actions: {
clearErrorMessage() {
this.set('errorMessage', null);
},
handleError(errorObject) {
this.set('errorMessage', errorObject);
},
},
});
8 changes: 8 additions & 0 deletions ui/app/components/job-page/parts/error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Component from '@ember/component';

export default Component.extend({
tagName: '',

errorMessage: null,
onDismiss() {},
});
23 changes: 23 additions & 0 deletions ui/app/components/job-page/parts/title.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Component from '@ember/component';

export default Component.extend({
tagName: '',

job: null,
title: null,

handleError() {},

actions: {
stopJob() {
this.get('job')
.stop()
.catch(() => {
this.get('handleError')({
title: 'Could Not Stop Job',
description: 'Your ACL token does not grant permission to stop jobs.',
});
});
},
},
});
11 changes: 7 additions & 4 deletions ui/app/components/job-page/periodic.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,21 @@ import { inject as service } from '@ember/service';
export default AbstractJobPage.extend({
store: service(),

errorMessage: '',
errorMessage: null,

actions: {
forceLaunch() {
this.get('job')
.forcePeriodic()
.catch(error => {
this.set('errorMessage', `Could not force launch: ${error}`);
.catch(() => {
this.set('errorMessage', {
title: 'Could Not Force Launch',
description: 'Your ACL token does not grant permission to submit jobs.',
});
});
},
clearErrorMessage() {
this.set('errorMessage', '');
this.set('errorMessage', null);
},
},
});
26 changes: 26 additions & 0 deletions ui/app/components/two-step-button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import Component from '@ember/component';
import { equal } from '@ember/object/computed';

export default Component.extend({
classNames: ['two-step-button'],

idleText: '',
cancelText: '',
confirmText: '',
confirmationMessage: '',
onConfirm() {},
onCancel() {},

state: 'idle',
isIdle: equal('state', 'idle'),
isPendingConfirmation: equal('state', 'prompt'),

actions: {
setToIdle() {
this.set('state', 'idle');
},
promptForConfirmation() {
this.set('state', 'prompt');
},
},
});
4 changes: 4 additions & 0 deletions ui/app/models/job.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ export default Model.extend({
return this.store.adapterFor('job').forcePeriodic(this);
},

stop() {
return this.store.adapterFor('job').stop(this);
},

statusClass: computed('status', function() {
const classMap = {
pending: 'is-pending',
Expand Down
37 changes: 19 additions & 18 deletions ui/app/styles/components.scss
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
@import "./components/badge";
@import "./components/boxed-section";
@import "./components/cli-window";
@import "./components/ember-power-select";
@import "./components/empty-message";
@import "./components/error-container";
@import "./components/gutter";
@import "./components/inline-definitions";
@import "./components/job-diff";
@import "./components/json-viewer";
@import "./components/loading-spinner";
@import "./components/metrics";
@import "./components/node-status-light";
@import "./components/page-layout";
@import "./components/simple-list";
@import "./components/status-text";
@import "./components/timeline";
@import "./components/tooltip";
@import './components/badge';
@import './components/boxed-section';
@import './components/cli-window';
@import './components/ember-power-select';
@import './components/empty-message';
@import './components/error-container';
@import './components/gutter';
@import './components/inline-definitions';
@import './components/job-diff';
@import './components/json-viewer';
@import './components/loading-spinner';
@import './components/metrics';
@import './components/node-status-light';
@import './components/page-layout';
@import './components/simple-list';
@import './components/status-text';
@import './components/timeline';
@import './components/tooltip';
@import './components/two-step-button';
14 changes: 14 additions & 0 deletions ui/app/styles/components/two-step-button.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.two-step-button {
display: inline;
position: relative;

.confirmation-text {
position: absolute;
left: 0;
top: -1.2em;
font-size: $body-size;
font-weight: $weight-normal;
color: darken($grey-blue, 20%);
white-space: nowrap;
}
}
7 changes: 3 additions & 4 deletions ui/app/templates/components/job-page/batch.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
{{/each}}
{{/global-header}}
{{#job-page/parts/body job=job onNamespaceChange=onNamespaceChange}}
<h1 class="title">
{{job.name}}
<span class="bumper-left tag {{job.statusClass}}" data-test-job-status>{{job.status}}</span>
</h1>
{{job-page/parts/error errorMessage=errorMessage onDismiss=(action "clearErrorMessage")}}

{{job-page/parts/title job=job handleError=(action "handleError")}}

<div class="boxed-section job-stats">
<div class="boxed-section-body">
Expand Down
7 changes: 3 additions & 4 deletions ui/app/templates/components/job-page/parameterized-child.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
{{/each}}
{{/global-header}}
{{#job-page/parts/body job=job onNamespaceChange=onNamespaceChange}}
<h1 class="title">
{{job.trimmedName}}
<span class="bumper-left tag {{job.statusClass}}" data-test-job-status>{{job.status}}</span>
</h1>
{{job-page/parts/error errorMessage=errorMessage onDismiss=(action "clearErrorMessage")}}

{{job-page/parts/title job=job title=job.trimmedName handleError=(action "handleError")}}

<div class="boxed-section job-stats">
<div class="boxed-section-body">
Expand Down
8 changes: 4 additions & 4 deletions ui/app/templates/components/job-page/parameterized.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
{{/each}}
{{/global-header}}
{{#job-page/parts/body job=job onNamespaceChange=onNamespaceChange}}
<h1 class="title">
{{job.name}}
<span class="bumper-left tag {{job.statusClass}}" data-test-job-status>{{job.status}}</span>
{{job-page/parts/error errorMessage=errorMessage onDismiss=(action "clearErrorMessage")}}

{{#job-page/parts/title job=job handleError=(action "handleError")}}
<span class="tag is-hollow">Parameterized</span>
</h1>
{{/job-page/parts/title}}

<div class="boxed-section job-stats">
<div class="boxed-section-body">
Expand Down
13 changes: 13 additions & 0 deletions ui/app/templates/components/job-page/parts/error.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{{#if errorMessage}}
<div class="notification is-danger">
<div class="columns">
<div class="column">
<h3 data-test-job-error-title class="title is-4">{{errorMessage.title}}</h3>
<p data-test-job-error-body>{{errorMessage.description}}</p>
</div>
<div class="column is-centered is-minimum">
<button data-test-job-error-close class="button is-danger" onclick={{action onDismiss}}>Okay</button>
</div>
</div>
</div>
{{/if}}
14 changes: 14 additions & 0 deletions ui/app/templates/components/job-page/parts/title.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<h1 class="title">
{{or title job.name}}
<span class="bumper-left tag {{job.statusClass}}" data-test-job-status>{{job.status}}</span>
{{yield}}
{{#if (not (eq job.status "dead"))}}
{{two-step-button
data-test-stop
idleText="Stop"
cancelText="Cancel"
confirmText="Yes, Stop"
confirmationMessage="Are you sure you want to stop this job?"
onConfirm=(action "stopJob")}}
{{/if}}
</h1>
7 changes: 3 additions & 4 deletions ui/app/templates/components/job-page/periodic-child.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
{{/each}}
{{/global-header}}
{{#job-page/parts/body job=job onNamespaceChange=onNamespaceChange}}
<h1 class="title">
{{job.trimmedName}}
<span class="bumper-left tag {{job.statusClass}}" data-test-job-status>{{job.status}}</span>
</h1>
{{job-page/parts/error errorMessage=errorMessage onDismiss=(action "clearErrorMessage")}}

{{job-page/parts/title job=job title=job.trimmedName handleError=(action "handleError")}}

<div class="boxed-section job-stats">
<div class="boxed-section-body">
Expand Down
21 changes: 4 additions & 17 deletions ui/app/templates/components/job-page/periodic.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,12 @@
{{/each}}
{{/global-header}}
{{#job-page/parts/body job=job onNamespaceChange=onNamespaceChange}}
{{#if errorMessage}}
<div class="notification is-danger">
<div class="columns">
<div class="column">
<h3 data-test-force-error-title class="title is-4">Could Not Force Launch</h3>
<p data-test-force-error-body>Your ACL token does not grant permission to submit jobs.</p>
</div>
<div class="column is-centered is-minimum">
<button data-test-force-error-close class="button is-danger" {{action "clearErrorMessage"}}>Okay</button>
</div>
</div>
</div>
{{/if}}
<h1 class="title">
{{job.name}}
<span class="bumper-left tag {{job.statusClass}}" data-test-job-status>{{job.status}}</span>
{{job-page/parts/error errorMessage=errorMessage onDismiss=(action "clearErrorMessage")}}

{{#job-page/parts/title job=job title=job.trimmedName handleError=(action "handleError")}}
<span class="tag is-hollow">periodic</span>
<button data-test-force-launch class="button is-warning is-small is-inline" onclick={{action "forceLaunch"}}>Force Launch</button>
</h1>
{{/job-page/parts/title}}

<div class="boxed-section job-stats">
<div class="boxed-section-body">
Expand Down
7 changes: 3 additions & 4 deletions ui/app/templates/components/job-page/service.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
{{/each}}
{{/global-header}}
{{#job-page/parts/body job=job onNamespaceChange=onNamespaceChange}}
<h1 class="title">
{{job.name}}
<span class="bumper-left tag {{job.statusClass}}" data-test-job-status>{{job.status}}</span>
</h1>
{{job-page/parts/error errorMessage=errorMessage onDismiss=(action "clearErrorMessage")}}

{{job-page/parts/title job=job handleError=(action "handleError")}}

<div class="boxed-section job-stats">
<div class="boxed-section-body">
Expand Down
7 changes: 3 additions & 4 deletions ui/app/templates/components/job-page/system.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
{{/each}}
{{/global-header}}
{{#job-page/parts/body job=job onNamespaceChange=onNamespaceChange}}
<h1 class="title">
{{job.name}}
<span class="bumper-left tag {{job.statusClass}}" data-test-job-status>{{job.status}}</span>
</h1>
{{job-page/parts/error errorMessage=errorMessage onDismiss=(action "clearErrorMessage")}}

{{job-page/parts/title job=job handleError=(action "handleError")}}

<div class="boxed-section job-stats">
<div class="boxed-section-body">
Expand Down
19 changes: 19 additions & 0 deletions ui/app/templates/components/two-step-button.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{{#if isIdle}}
<button data-test-idle-button type="button" class="button is-warning is-small is-inline" onclick={{action "promptForConfirmation"}}>
{{idleText}}
</button>
{{else if isPendingConfirmation}}
<span data-test-confirmation-message class="confirmation-text">{{confirmationMessage}}</span>
<button data-test-cancel-button type="button" class="button is-dark is-outlined is-small is-inline" onclick={{action (queue
(action "setToIdle")
(action onCancel)
)}}>
{{cancelText}}
</button>
<button data-test-confirm-button class="button is-danger is-small is-inline" onclick={{action (queue
(action "setToIdle")
(action onConfirm)
)}}>
{{confirmText}}
</button>
{{/if}}
6 changes: 6 additions & 0 deletions ui/mirage/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ export default function() {
return new Response(200, {}, '{}');
});

this.delete('/job/:id', function(schema, { params }) {
const job = schema.jobs.find(params.id);
job.update({ status: 'dead' });
return new Response(204, {}, '');
});

this.get('/deployment/:id');

this.get('/job/:id/evaluations', function({ evaluations }, { params }) {
Expand Down
Loading