diff --git a/ui/app/adapters/job.js b/ui/app/adapters/job.js index af8b05aaf..2999988fa 100644 --- a/ui/app/adapters/job.js +++ b/ui/app/adapters/job.js @@ -79,6 +79,16 @@ export default Watchable.extend({ }, }); }, + + // Running a job doesn't follow REST create semantics so it's easier to + // treat it as an action. + run(job) { + return this.ajax(this.urlForCreateRecord('job'), 'POST', { + data: { + Job: job.get('_newDefinitionJSON'), + }, + }); + }, }); function associateNamespace(url, namespace) { diff --git a/ui/app/controllers/jobs/run.js b/ui/app/controllers/jobs/run.js index 916a0c8e2..871f7ed4f 100644 --- a/ui/app/controllers/jobs/run.js +++ b/ui/app/controllers/jobs/run.js @@ -1,6 +1,8 @@ import Controller from '@ember/controller'; import { computed } from '@ember/object'; import { task } from 'ember-concurrency'; +import { qpBuilder } from 'nomad-ui/utils/classes/query-params'; +import { next } from '@ember/runloop'; export default Controller.extend({ stage: computed('planOutput', function() { @@ -18,15 +20,25 @@ export default Controller.extend({ try { const planOutput = yield this.get('model').plan(); - console.log('Heyo!', planOutput); this.set('planOutput', planOutput); } catch (err) { this.set('planError', err); - console.log('Uhoh', err); } }).drop(), - submit: task(function*() {}), + submit: task(function*() { + try { + yield this.get('model').run(); + const id = this.get('model.plainId'); + const namespace = this.get('model.namespace.name') || 'default'; + // navigate to the new job page + this.transitionToRoute('jobs.job', id, { + queryParams: { jobNamespace: namespace }, + }); + } catch (err) { + this.set('runError', err); + } + }), cancel() { this.set('planOutput', null); diff --git a/ui/app/models/job.js b/ui/app/models/job.js index 5de6977ae..1ccbf305e 100644 --- a/ui/app/models/job.js +++ b/ui/app/models/job.js @@ -198,6 +198,11 @@ export default Model.extend({ return this.store.adapterFor('job').plan(this); }, + run() { + assert('A job must be parsed before ran', this.get('_newDefinitionJSON')); + return this.store.adapterFor('job').run(this); + }, + parse() { const definition = this.get('_newDefinition'); let promise; @@ -224,8 +229,16 @@ export default Model.extend({ }, setIDByPayload(payload) { - this.set('plainId', payload.Name); - this.set('id', JSON.stringify([payload.Name, payload.Namespace || 'default'])); + const namespace = payload.Namespace || 'default'; + const id = payload.Name; + + this.set('plainId', id); + this.set('id', JSON.stringify([id, namespace])); + + const namespaceRecord = this.store.peekRecord('namespace', namespace); + if (namespaceRecord) { + this.set('namespace', namespaceRecord); + } }, statusClass: computed('status', function() {