Merge branch 'master' into fix-safari-3192
This commit is contained in:
@@ -25,10 +25,11 @@ define([
|
||||
], function (
|
||||
utils
|
||||
) {
|
||||
function ObjectServiceProvider(eventEmitter, objectService, instantiate, topic) {
|
||||
function ObjectServiceProvider(eventEmitter, objectService, instantiate, topic, $injector) {
|
||||
this.eventEmitter = eventEmitter;
|
||||
this.objectService = objectService;
|
||||
this.instantiate = instantiate;
|
||||
this.$injector = $injector;
|
||||
|
||||
this.generalTopic = topic('mutation');
|
||||
this.bridgeEventBuses();
|
||||
@@ -68,16 +69,53 @@ define([
|
||||
removeGeneralTopicListener = this.generalTopic.listen(handleLegacyMutation);
|
||||
};
|
||||
|
||||
ObjectServiceProvider.prototype.save = function (object) {
|
||||
var key = object.key;
|
||||
ObjectServiceProvider.prototype.create = async function (object) {
|
||||
let model = utils.toOldFormat(object);
|
||||
|
||||
return object.getCapability('persistence')
|
||||
.persist()
|
||||
.then(function () {
|
||||
return utils.toNewFormat(object, key);
|
||||
});
|
||||
return this.getPersistenceService().createObject(
|
||||
this.getSpace(utils.makeKeyString(object.identifier)),
|
||||
object.identifier.key,
|
||||
model
|
||||
);
|
||||
}
|
||||
ObjectServiceProvider.prototype.update = async function (object) {
|
||||
let model = utils.toOldFormat(object);
|
||||
|
||||
return this.getPersistenceService().updateObject(
|
||||
this.getSpace(utils.makeKeyString(object.identifier)),
|
||||
object.identifier.key,
|
||||
model
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the space in which this domain object is persisted;
|
||||
* this is useful when, for example, decided which space a
|
||||
* newly-created domain object should be persisted to (by
|
||||
* default, this should be the space of its containing
|
||||
* object.)
|
||||
*
|
||||
* @returns {string} the name of the space which should
|
||||
* be used to persist this object
|
||||
*/
|
||||
ObjectServiceProvider.prototype.getSpace = function (keystring) {
|
||||
return this.getIdentifierService().parse(keystring).getSpace();
|
||||
};
|
||||
|
||||
ObjectServiceProvider.prototype.getIdentifierService = function () {
|
||||
if (this.identifierService === undefined) {
|
||||
this.identifierService = this.$injector.get('identifierService');
|
||||
}
|
||||
return this.identifierService;
|
||||
};
|
||||
|
||||
ObjectServiceProvider.prototype.getPersistenceService = function () {
|
||||
if (this.persistenceService === undefined) {
|
||||
this.persistenceService = this.$injector.get('persistenceService');
|
||||
}
|
||||
return this.persistenceService;
|
||||
}
|
||||
|
||||
ObjectServiceProvider.prototype.delete = function (object) {
|
||||
// TODO!
|
||||
};
|
||||
@@ -118,7 +156,8 @@ define([
|
||||
eventEmitter,
|
||||
objectService,
|
||||
instantiate,
|
||||
topic
|
||||
topic,
|
||||
openmct.$injector
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
@@ -101,14 +101,25 @@ define([
|
||||
*/
|
||||
|
||||
/**
|
||||
* Save this domain object in its current state.
|
||||
* Create the given domain object in the corresponding persistence store
|
||||
*
|
||||
* @method save
|
||||
* @method create
|
||||
* @memberof module:openmct.ObjectProvider#
|
||||
* @param {module:openmct.DomainObject} domainObject the domain object to
|
||||
* save
|
||||
* create
|
||||
* @returns {Promise} a promise which will resolve when the domain object
|
||||
* has been saved, or be rejected if it cannot be saved
|
||||
* has been created, or be rejected if it cannot be saved
|
||||
*/
|
||||
|
||||
/**
|
||||
* Update this domain object in its persistence store
|
||||
*
|
||||
* @method update
|
||||
* @memberof module:openmct.ObjectProvider#
|
||||
* @param {module:openmct.DomainObject} domainObject the domain object to
|
||||
* update
|
||||
* @returns {Promise} a promise which will resolve when the domain object
|
||||
* has been updated, or be rejected if it cannot be saved
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -161,8 +172,41 @@ define([
|
||||
throw new Error('Delete not implemented');
|
||||
};
|
||||
|
||||
ObjectAPI.prototype.save = function () {
|
||||
throw new Error('Save not implemented');
|
||||
ObjectAPI.prototype.isPersistable = function (domainObject) {
|
||||
let provider = this.getProvider(domainObject.identifier);
|
||||
return provider !== undefined &&
|
||||
provider.create !== undefined &&
|
||||
provider.update !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save this domain object in its current state. EXPERIMENTAL
|
||||
*
|
||||
* @private
|
||||
* @memberof module:openmct.ObjectAPI#
|
||||
* @param {module:openmct.DomainObject} domainObject the domain object to
|
||||
* save
|
||||
* @returns {Promise} a promise which will resolve when the domain object
|
||||
* has been saved, or be rejected if it cannot be saved
|
||||
*/
|
||||
ObjectAPI.prototype.save = function (domainObject) {
|
||||
let provider = this.getProvider(domainObject.identifier);
|
||||
let result;
|
||||
|
||||
if (!this.isPersistable(domainObject)) {
|
||||
result = Promise.reject('Object provider does not support saving');
|
||||
} else if (hasAlreadyBeenPersisted(domainObject)) {
|
||||
result = Promise.resolve(true);
|
||||
} else {
|
||||
if (domainObject.persisted === undefined) {
|
||||
this.mutate(domainObject, 'persisted', domainObject.modified);
|
||||
result = provider.create(domainObject);
|
||||
} else {
|
||||
this.mutate(domainObject, 'persisted', domainObject.modified);
|
||||
result = provider.update(domainObject);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -276,5 +320,9 @@ define([
|
||||
* @memberof module:openmct
|
||||
*/
|
||||
|
||||
function hasAlreadyBeenPersisted(domainObject) {
|
||||
return domainObject.persisted !== undefined &&
|
||||
domainObject.persisted === domainObject.modified;
|
||||
}
|
||||
return ObjectAPI;
|
||||
});
|
||||
|
||||
60
src/api/objects/ObjectAPISpec.js
Normal file
60
src/api/objects/ObjectAPISpec.js
Normal file
@@ -0,0 +1,60 @@
|
||||
import ObjectAPI from './ObjectAPI.js';
|
||||
|
||||
describe("The Object API", () => {
|
||||
let objectAPI;
|
||||
let mockDomainObject;
|
||||
const TEST_NAMESPACE = "test-namespace";
|
||||
const FIFTEEN_MINUTES = 15 * 60 * 1000;
|
||||
|
||||
beforeEach(() => {
|
||||
objectAPI = new ObjectAPI();
|
||||
mockDomainObject = {
|
||||
identifier: {
|
||||
namespace: TEST_NAMESPACE,
|
||||
key: "test-key"
|
||||
},
|
||||
name: "test object",
|
||||
type: "test-type"
|
||||
};
|
||||
})
|
||||
describe("The save function", () => {
|
||||
it("Rejects if no provider available", () => {
|
||||
let rejected = false;
|
||||
return objectAPI.save(mockDomainObject)
|
||||
.catch(() => rejected = true)
|
||||
.then(() => expect(rejected).toBe(true));
|
||||
});
|
||||
describe("when a provider is available", () => {
|
||||
let mockProvider;
|
||||
beforeEach(() => {
|
||||
mockProvider = jasmine.createSpyObj("mock provider", [
|
||||
"create",
|
||||
"update"
|
||||
]);
|
||||
objectAPI.addProvider(TEST_NAMESPACE, mockProvider);
|
||||
})
|
||||
it("Calls 'create' on provider if object is new", () => {
|
||||
objectAPI.save(mockDomainObject);
|
||||
expect(mockProvider.create).toHaveBeenCalled();
|
||||
expect(mockProvider.update).not.toHaveBeenCalled();
|
||||
});
|
||||
it("Calls 'update' on provider if object is not new", () => {
|
||||
mockDomainObject.persisted = Date.now() - FIFTEEN_MINUTES;
|
||||
mockDomainObject.modified = Date.now();
|
||||
|
||||
objectAPI.save(mockDomainObject);
|
||||
expect(mockProvider.create).not.toHaveBeenCalled();
|
||||
expect(mockProvider.update).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("Does not persist if the object is unchanged", () => {
|
||||
mockDomainObject.persisted =
|
||||
mockDomainObject.modified = Date.now();
|
||||
|
||||
objectAPI.save(mockDomainObject);
|
||||
expect(mockProvider.create).not.toHaveBeenCalled();
|
||||
expect(mockProvider.update).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
@@ -27,13 +27,14 @@
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
&.is-missing {
|
||||
@include isMissing($absPos: true);
|
||||
border: $borderMissing;
|
||||
@include isMissing($absPos: true);
|
||||
|
||||
.is-missing__indicator {
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.is-missing__indicator {
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
&.is-missing {
|
||||
border: $borderMissing;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,21 +22,24 @@
|
||||
<button
|
||||
v-for="(tab,index) in tabsList"
|
||||
:key="index"
|
||||
class="c-tabs-view__tab c-tab c-object-label"
|
||||
class="c-tab c-tabs-view__tab"
|
||||
:class="{
|
||||
'is-current': isCurrent(tab),
|
||||
'is-missing': tab.domainObject.status === 'missing'
|
||||
'is-current': isCurrent(tab)
|
||||
}"
|
||||
@click="showTab(tab, index)"
|
||||
>
|
||||
<div class="c-object-label__type-icon"
|
||||
:class="tab.type.definition.cssClass"
|
||||
<div class="c-object-label"
|
||||
:class="{'is-missing': tab.domainObject.status === 'missing'}"
|
||||
>
|
||||
<span class="is-missing__indicator"
|
||||
title="This item is missing"
|
||||
></span>
|
||||
<div class="c-object-label__type-icon"
|
||||
:class="tab.type.definition.cssClass"
|
||||
>
|
||||
<span class="is-missing__indicator"
|
||||
title="This item is missing"
|
||||
></span>
|
||||
</div>
|
||||
<span class="c-button__label c-object-label__name">{{ tab.domainObject.name }}</span>
|
||||
</div>
|
||||
<span class="c-button__label c-object-label__name">{{ tab.domainObject.name }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
//pointer-events: none; // Don't think we can do this, as disables title hover on icon element
|
||||
|
||||
.is-missing__indicator {
|
||||
display: block;
|
||||
display: none ;
|
||||
text-shadow: $colorBodyBg 0 0 2px;
|
||||
color: $colorAlert;
|
||||
font-family: symbolsfont;
|
||||
@@ -139,6 +139,9 @@
|
||||
z-index: 3;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-missing .is-missing__indicator,
|
||||
.is-missing .is-missing__indicator { display: block !important; }
|
||||
}
|
||||
|
||||
@mixin bgDiagonalStripes($c: yellow, $a: 0.1, $d: 40px) {
|
||||
|
||||
@@ -53,7 +53,9 @@ export default {
|
||||
mounted() {
|
||||
this.currentObject = this.object;
|
||||
this.updateView();
|
||||
this.$el.addEventListener('dragover', this.onDragOver);
|
||||
this.$el.addEventListener('dragover', this.onDragOver, {
|
||||
capture: true
|
||||
});
|
||||
this.$el.addEventListener('drop', this.editIfEditable, {
|
||||
capture: true
|
||||
});
|
||||
@@ -269,6 +271,7 @@ export default {
|
||||
if (provider &&
|
||||
provider.canEdit &&
|
||||
provider.canEdit(this.currentObject) &&
|
||||
this.isEditingAllowed() &&
|
||||
!this.openmct.editor.isEditing()) {
|
||||
this.openmct.editor.edit();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user