diff --git a/ui/app/adapters/variable.js b/ui/app/adapters/variable.js
index b6db2ea37..f6b417555 100644
--- a/ui/app/adapters/variable.js
+++ b/ui/app/adapters/variable.js
@@ -1,6 +1,7 @@
import ApplicationAdapter from './application';
import { pluralize } from 'ember-inflector';
import classic from 'ember-classic-decorator';
+import { ConflictError } from '@ember-data/adapter/error';
@classic
export default class VariableAdapter extends ApplicationAdapter {
@@ -11,7 +12,8 @@ export default class VariableAdapter extends ApplicationAdapter {
createRecord(_store, type, snapshot) {
let data = this.serialize(snapshot);
let baseUrl = this.buildURL(type.modelName, data.ID);
- return this.ajax(baseUrl, 'PUT', { data });
+ const checkAndSetValue = snapshot?.attr('modifyIndex') || 0;
+ return this.ajax(`${baseUrl}&cas=${checkAndSetValue}`, 'PUT', { data });
}
urlForFindAll(modelName) {
@@ -33,7 +35,12 @@ export default class VariableAdapter extends ApplicationAdapter {
urlForUpdateRecord(identifier, modelName, snapshot) {
const { id } = _extractIDAndNamespace(identifier, snapshot);
let baseUrl = this.buildURL(modelName, id);
- return `${baseUrl}`;
+ if (snapshot?.adapterOptions?.overwrite) {
+ return `${baseUrl}`;
+ } else {
+ const checkAndSetValue = snapshot?.attr('modifyIndex') || 0;
+ return `${baseUrl}?cas=${checkAndSetValue}`;
+ }
}
urlForDeleteRecord(identifier, modelName, snapshot) {
@@ -41,6 +48,15 @@ export default class VariableAdapter extends ApplicationAdapter {
const baseUrl = this.buildURL(modelName, id);
return `${baseUrl}?namespace=${namespace}`;
}
+
+ handleResponse(status, _, payload) {
+ if (status === 409) {
+ return new ConflictError([
+ { detail: _normalizeConflictErrorObject(payload), status: 409 },
+ ]);
+ }
+ return super.handleResponse(...arguments);
+ }
}
function _extractIDAndNamespace(identifier, snapshot) {
@@ -51,3 +67,10 @@ function _extractIDAndNamespace(identifier, snapshot) {
id,
};
}
+
+function _normalizeConflictErrorObject(conflictingVariable) {
+ return {
+ modifyTime: Math.floor(conflictingVariable.ModifyTime / 1000000),
+ items: conflictingVariable.Items,
+ };
+}
diff --git a/ui/app/components/secure-variable-form.hbs b/ui/app/components/secure-variable-form.hbs
index 8c4449957..e50e9fe73 100644
--- a/ui/app/components/secure-variable-form.hbs
+++ b/ui/app/components/secure-variable-form.hbs
@@ -9,6 +9,27 @@
{{/if}}
+ {{#if this.hasConflict}}
+
+
Heads up! Your Secure Variable has a conflict.
+
This might be because someone else tried saving in the time since you've had it open.
+ {{#if this.conflictingVariable.modifyTime}}
+
+ {{moment-from-now this.conflictingVariable.modifyTime}}
+
+ {{/if}}
+ {{#if this.conflictingVariable.items}}
+
{{stringify-object this.conflictingVariable.items whitespace=2}}
+ {{else}}
+
Your ACL token limits your ability to see further details about the conflicting variable.
+ {{/if}}
+
+
+
+
+
+ {{/if}}
+