open-nomad/ui/app/components/job-version.js
Buck Doyle 90ecbdf522
Add job version revert buttons (#10336)
This adds a Revert two-step button to the JobVersions component for
not-current versions, which redirects to the overview on success. It
checks the job version before and after reversion to mitigate the edge
case where reverting to an otherwise-identical version has no effect, as
discussed in #10337.

It uses existing facilities for handling other errors and disabling the
button when permissions are lacking.
2021-04-20 08:33:16 -05:00

98 lines
2.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Component from '@ember/component';
import { action, computed } from '@ember/object';
import { classNames } from '@ember-decorators/component';
import { inject as service } from '@ember/service';
import { task } from 'ember-concurrency';
import messageForError from 'nomad-ui/utils/message-from-adapter-error';
import classic from 'ember-classic-decorator';
const changeTypes = ['Added', 'Deleted', 'Edited'];
@classic
@classNames('job-version', 'boxed-section')
export default class JobVersion extends Component {
version = null;
isOpen = false;
// Passes through to the job-diff component
verbose = true;
@service router;
@computed('version.diff')
get changeCount() {
const diff = this.get('version.diff');
const taskGroups = diff.TaskGroups || [];
if (!diff) {
return 0;
}
return (
fieldChanges(diff) +
taskGroups.reduce(arrayOfFieldChanges, 0) +
(taskGroups.mapBy('Tasks') || []).reduce(flatten, []).reduce(arrayOfFieldChanges, 0)
);
}
@computed('version.{number,job.version}')
get isCurrent() {
return this.get('version.number') === this.get('version.job.version');
}
@action
toggleDiff() {
this.toggleProperty('isOpen');
}
@task(function*() {
try {
const versionBeforeReversion = this.get('version.job.version');
yield this.version.revertTo();
yield this.version.job.reload();
const versionAfterReversion = this.get('version.job.version');
if (versionBeforeReversion === versionAfterReversion) {
this.handleError({
level: 'warn',
title: 'Reversion Had No Effect',
description: 'Reverting to an identical older version doesnt produce a new version',
});
} else {
const job = this.get('version.job');
this.router.transitionTo('jobs.job', job.get('plainId'), {
queryParams: { namespace: job.get('namespace.name') },
});
}
} catch (e) {
this.handleError({
level: 'danger',
title: 'Could Not Revert',
description: messageForError(e, 'revert'),
});
}
})
revertTo;
}
const flatten = (accumulator, array) => accumulator.concat(array);
const countChanges = (total, field) => (changeTypes.includes(field.Type) ? total + 1 : total);
function fieldChanges(diff) {
return (
(diff.Fields || []).reduce(countChanges, 0) +
(diff.Objects || []).reduce(arrayOfFieldChanges, 0)
);
}
function arrayOfFieldChanges(count, diff) {
if (!diff) {
return count;
}
return count + fieldChanges(diff);
}