Skip to content

Commit

Permalink
Edit from Version functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
philrenaud committed Oct 10, 2024
1 parent 278a2df commit eaed41d
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 22 deletions.
3 changes: 3 additions & 0 deletions .changelog/24168.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
ui: Add an Edit From Version button as an option when reverting from an older job version
```
4 changes: 2 additions & 2 deletions ui/app/adapters/job.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ export default class JobAdapter extends WatchableNamespaceIDs {
return this.ajax(url, 'GET');
}

fetchRawSpecification(job) {
fetchRawSpecification(job, version) {
const url = addToPath(
this.urlForFindRecord(job.get('id'), 'job', null, 'submission'),
'',
'version=' + job.get('version')
'version=' + (version || job.get('version'))
);
return this.ajax(url, 'GET');
}
Expand Down
27 changes: 27 additions & 0 deletions ui/app/components/job-version.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
* SPDX-License-Identifier: BUSL-1.1
*/

// @ts-check

import Component from '@glimmer/component';
import { action, computed } from '@ember/object';
import { alias } from '@ember/object/computed';
Expand Down Expand Up @@ -80,6 +82,11 @@ export default class JobVersion extends Component {
this.isOpen = !this.isOpen;
}

/**
* @type {'idle' | 'confirming'}
*/
@tracked revertButtonStatus = 'idle';

@task(function* () {
try {
const versionBeforeReversion = this.version.get('job.version');
Expand Down Expand Up @@ -108,6 +115,26 @@ export default class JobVersion extends Component {
})
revertTo;

@action async editFromVersion() {
try {
this.router.transitionTo(
'jobs.job.definition',
this.version.get('job.idWithNamespace'),
{
queryParams: {
isEditing: true,
version: this.version.number,
},
}
);
} catch (e) {
this.args.handleError({
level: 'danger',
title: 'Could Not Edit from Version',
});
}
}

@action
handleKeydown(event) {
if (event.key === 'Escape') {
Expand Down
4 changes: 2 additions & 2 deletions ui/app/models/job.js
Original file line number Diff line number Diff line change
Expand Up @@ -541,8 +541,8 @@ export default class Job extends Model {
return this.store.adapterFor('job').fetchRawDefinition(this);
}

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

forcePeriodic() {
Expand Down
37 changes: 33 additions & 4 deletions ui/app/routes/jobs/job/definition.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,58 @@

// @ts-check
import Route from '@ember/routing/route';

import { inject as service } from '@ember/service';
/**
* Route for fetching and displaying a job's definition and specification.
*/
export default class DefinitionRoute extends Route {
@service notifications;

queryParams = {
version: {
refreshModel: true,
},
};

/**
* Fetch the job's definition, specification, and variables from the API.
*
* @returns {Promise<Object>} A promise that resolves to an object containing the job, definition, format,
* specification, variableFlags, and variableLiteral.
*/
async model() {
async model({ version }) {
version = +version; // query parameter is a string; convert to number
const job = this.modelFor('jobs.job');
if (!job) return;

const definition = await job.fetchRawDefinition();
let definition;

if (version) {
try {
const versionResponse = await job.getVersions();
const versions = versionResponse.Versions;
definition = versions.findBy('Version', version);
if (!definition) {
throw new Error('Version not found');
}
} catch (e) {
console.error('error fetching job version definition', e);
this.notifications.add({
title: 'Error Fetching Job Version Definition',
message: `There was an error fetching the versions for this job: ${e.message}`,
color: 'critical',
});
}
} else {
definition = await job.fetchRawDefinition();
}

let format = 'json'; // default to json in network request errors
let specification;
let variableFlags;
let variableLiteral;
try {
const specificationResponse = await job.fetchRawSpecification();
const specificationResponse = await job.fetchRawSpecification(version);
specification = specificationResponse?.Source ?? null;
variableFlags = specificationResponse?.VariableFlags ?? null;
variableLiteral = specificationResponse?.Variables ?? null;
Expand Down
63 changes: 49 additions & 14 deletions ui/app/templates/components/job-version.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -81,20 +81,55 @@
<div class="version-options">
{{#unless this.isCurrent}}
{{#if (can "run job" namespace=this.version.job.namespace)}}
<TwoStepButton
data-test-revert-to
@classes={{hash
idleButton="is-warning is-outlined"
confirmButton="is-warning"}}
@fadingBackground={{true}}
@idleText="Revert Version"
@cancelText="Cancel"
@confirmText="Yes, Revert Version"
@confirmationMessage="Are you sure you want to revert to this version?"
@inlineText={{true}}
@size="small"
@awaitingConfirmation={{this.revertTo.isRunning}}
@onConfirm={{perform this.revertTo}} />
{{#if (eq this.revertButtonStatus 'idle')}}
<Hds::Button
data-test-revert-to
@text="Revert Version"
@color="critical"
@size="small"
@isInline={{true}}
@disabled={{this.revertTo.isRunning}}
{{on "click" (action (mut this.revertButtonStatus) "confirming")}}
/>
{{else if (eq this.revertButtonStatus 'confirming')}}
<span data-test-confirmation-message class="confirmation-text is-right-aligned has-text-inline">
Are you sure you want to revert to this version?
</span>
<Hds::Button
data-test-revert-to
@text="Cancel"
@color="secondary"
@size="small"
@isInline={{true}}
{{on "click" (action (mut this.revertButtonStatus) "idle")}}
/>
<Hds::Button
data-test-revert-to
@text="Edit from Version"
@color="secondary"
@size="small"
@isInline={{true}}
{{on "click" (action this.editFromVersion)}}
/>
<Hds::Button
data-test-revert-to
@text="Yes, Revert Now"
@color="critical"
@size="small"
@isInline={{true}}
@disabled={{this.revertTo.isRunning}}
{{on "click" (perform this.revertTo)}}
/>
{{else if (eq this.revertButtonStatus 'running')}}
<Hds::Button
data-test-revert-to
@text="Reverting..."
@color="critical"
@size="small"
@isInline={{true}}
@disabled={{true}}
/>
{{/if}}
{{else}}
<Hds::Button
data-test-revert-to
Expand Down
2 changes: 2 additions & 0 deletions ui/tests/unit/adapters/job-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,8 @@ module('Unit | Adapter | Job', function (hooks) {
assert.equal(request.method, 'GET');
});

// TODO: test that version requests work for fetchRawDefinition

test('forcePeriodic requests include the activeRegion', async function (assert) {
const region = 'region-2';
const job = await this.initializeWithJob({ region });
Expand Down

0 comments on commit eaed41d

Please sign in to comment.