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}} +