Compare commits
17 Commits
misc-fixes
...
alpha-enum
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9fef060501 | ||
|
|
c38d810658 | ||
|
|
f5c48b7bf6 | ||
|
|
d0e08f1d9a | ||
|
|
72ea7b80fd | ||
|
|
35d0c02bc5 | ||
|
|
abd7506b45 | ||
|
|
526b4aa07e | ||
|
|
b5e23963d4 | ||
|
|
2c11eb90d4 | ||
|
|
90e9c79e19 | ||
|
|
1b83631e43 | ||
|
|
547d4e82db | ||
|
|
3377ad5e0d | ||
|
|
1c0df60f05 | ||
|
|
138067dca9 | ||
|
|
844280eaa5 |
@@ -86,6 +86,7 @@
|
|||||||
openmct.install(openmct.plugins.LADTable());
|
openmct.install(openmct.plugins.LADTable());
|
||||||
openmct.install(openmct.plugins.Filters(['table', 'telemetry.plot.overlay']));
|
openmct.install(openmct.plugins.Filters(['table', 'telemetry.plot.overlay']));
|
||||||
openmct.install(openmct.plugins.ObjectMigration());
|
openmct.install(openmct.plugins.ObjectMigration());
|
||||||
|
openmct.install(openmct.plugins.GoToOriginalAction());
|
||||||
openmct.start();
|
openmct.start();
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
"node-bourbon": "^4.2.3",
|
"node-bourbon": "^4.2.3",
|
||||||
"node-sass": "^4.9.2",
|
"node-sass": "^4.9.2",
|
||||||
"painterro": "^0.2.65",
|
"painterro": "^0.2.65",
|
||||||
"printj": "^1.1.0",
|
"printj": "^1.2.1",
|
||||||
"raw-loader": "^0.5.1",
|
"raw-loader": "^0.5.1",
|
||||||
"request": "^2.69.0",
|
"request": "^2.69.0",
|
||||||
"split": "^1.0.0",
|
"split": "^1.0.0",
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
ng-model="ngModel"
|
ng-model="ngModel"
|
||||||
ng-show="ngModel.progressPerc !== undefined"></mct-include>
|
ng-show="ngModel.progressPerc !== undefined"></mct-include>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div class="c-overlay__button-bar">
|
<div class="c-overlay__button-bar">
|
||||||
<button ng-repeat="dialogOption in ngModel.options"
|
<button ng-repeat="dialogOption in ngModel.options"
|
||||||
class="c-button"
|
class="c-button"
|
||||||
@@ -21,5 +22,4 @@
|
|||||||
{{ngModel.primaryOption.label}}
|
{{ngModel.primaryOption.label}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ define(
|
|||||||
* @returns boolean
|
* @returns boolean
|
||||||
*/
|
*/
|
||||||
EditorCapability.prototype.inEditContext = function () {
|
EditorCapability.prototype.inEditContext = function () {
|
||||||
console.warn('DEPRECATION WARNING: isEditing checks must be done via openmct.editor.');
|
|
||||||
return this.openmct.editor.isEditing();
|
return this.openmct.editor.isEditing();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -74,7 +73,6 @@ define(
|
|||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
EditorCapability.prototype.isEditContextRoot = function () {
|
EditorCapability.prototype.isEditContextRoot = function () {
|
||||||
console.warn('DEPRECATION WARNING: isEditing checks must be done via openmct.editor.');
|
|
||||||
return this.openmct.editor.isEditing();
|
return this.openmct.editor.isEditing();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ define([
|
|||||||
"./src/actions/MoveAction",
|
"./src/actions/MoveAction",
|
||||||
"./src/actions/CopyAction",
|
"./src/actions/CopyAction",
|
||||||
"./src/actions/LinkAction",
|
"./src/actions/LinkAction",
|
||||||
"./src/actions/GoToOriginalAction",
|
|
||||||
"./src/actions/SetPrimaryLocationAction",
|
"./src/actions/SetPrimaryLocationAction",
|
||||||
"./src/services/LocatingCreationDecorator",
|
"./src/services/LocatingCreationDecorator",
|
||||||
"./src/services/LocatingObjectDecorator",
|
"./src/services/LocatingObjectDecorator",
|
||||||
@@ -41,7 +40,6 @@ define([
|
|||||||
MoveAction,
|
MoveAction,
|
||||||
CopyAction,
|
CopyAction,
|
||||||
LinkAction,
|
LinkAction,
|
||||||
GoToOriginalAction,
|
|
||||||
SetPrimaryLocationAction,
|
SetPrimaryLocationAction,
|
||||||
LocatingCreationDecorator,
|
LocatingCreationDecorator,
|
||||||
LocatingObjectDecorator,
|
LocatingObjectDecorator,
|
||||||
@@ -104,14 +102,6 @@ define([
|
|||||||
"linkService"
|
"linkService"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"key": "follow",
|
|
||||||
"name": "Go To Original",
|
|
||||||
"description": "Go to the original, un-linked instance of this object.",
|
|
||||||
"cssClass": "",
|
|
||||||
"category": "contextual",
|
|
||||||
"implementation": GoToOriginalAction
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"key": "locate",
|
"key": "locate",
|
||||||
"name": "Set Primary Location",
|
"name": "Set Primary Location",
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
function () {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements the "Go To Original" action, which follows a link back
|
|
||||||
* to an original instance of an object.
|
|
||||||
*
|
|
||||||
* @implements {Action}
|
|
||||||
* @constructor
|
|
||||||
* @private
|
|
||||||
* @memberof platform/entanglement
|
|
||||||
* @param {ActionContext} context the context in which the action
|
|
||||||
* will be performed
|
|
||||||
*/
|
|
||||||
function GoToOriginalAction(context) {
|
|
||||||
this.domainObject = context.domainObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
GoToOriginalAction.prototype.perform = function () {
|
|
||||||
return this.domainObject.getCapability("location").getOriginal()
|
|
||||||
.then(function (originalObject) {
|
|
||||||
var actionCapability =
|
|
||||||
originalObject.getCapability("action");
|
|
||||||
return actionCapability &&
|
|
||||||
actionCapability.perform("navigate");
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
GoToOriginalAction.appliesTo = function (context) {
|
|
||||||
var domainObject = context.domainObject;
|
|
||||||
return domainObject && domainObject.hasCapability("location") &&
|
|
||||||
domainObject.getCapability("location").isLink();
|
|
||||||
};
|
|
||||||
|
|
||||||
return GoToOriginalAction;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
define(
|
|
||||||
[
|
|
||||||
'../../src/actions/GoToOriginalAction',
|
|
||||||
'../DomainObjectFactory',
|
|
||||||
'../ControlledPromise'
|
|
||||||
],
|
|
||||||
function (GoToOriginalAction, domainObjectFactory, ControlledPromise) {
|
|
||||||
|
|
||||||
describe("The 'go to original' action", function () {
|
|
||||||
var testContext,
|
|
||||||
originalDomainObject,
|
|
||||||
mockLocationCapability,
|
|
||||||
mockOriginalActionCapability,
|
|
||||||
originalPromise,
|
|
||||||
action;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
mockLocationCapability = jasmine.createSpyObj(
|
|
||||||
'location',
|
|
||||||
['isLink', 'isOriginal', 'getOriginal']
|
|
||||||
);
|
|
||||||
mockOriginalActionCapability = jasmine.createSpyObj(
|
|
||||||
'action',
|
|
||||||
['perform', 'getActions']
|
|
||||||
);
|
|
||||||
originalPromise = new ControlledPromise();
|
|
||||||
mockLocationCapability.getOriginal.and.returnValue(originalPromise);
|
|
||||||
mockLocationCapability.isLink.and.returnValue(true);
|
|
||||||
mockLocationCapability.isOriginal.and.callFake(function () {
|
|
||||||
return !mockLocationCapability.isLink();
|
|
||||||
});
|
|
||||||
testContext = {
|
|
||||||
domainObject: domainObjectFactory({
|
|
||||||
capabilities: {
|
|
||||||
location: mockLocationCapability
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
originalDomainObject = domainObjectFactory({
|
|
||||||
capabilities: {
|
|
||||||
action: mockOriginalActionCapability
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
action = new GoToOriginalAction(testContext);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("is applicable to links", function () {
|
|
||||||
expect(GoToOriginalAction.appliesTo(testContext))
|
|
||||||
.toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("is not applicable to originals", function () {
|
|
||||||
mockLocationCapability.isLink.and.returnValue(false);
|
|
||||||
expect(GoToOriginalAction.appliesTo(testContext))
|
|
||||||
.toBeFalsy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("navigates to original objects when performed", function () {
|
|
||||||
expect(mockOriginalActionCapability.perform)
|
|
||||||
.not.toHaveBeenCalled();
|
|
||||||
action.perform();
|
|
||||||
originalPromise.resolve(originalDomainObject);
|
|
||||||
expect(mockOriginalActionCapability.perform)
|
|
||||||
.toHaveBeenCalledWith('navigate');
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
@@ -80,15 +80,17 @@ define(['zepto'], function ($) {
|
|||||||
var newObj;
|
var newObj;
|
||||||
|
|
||||||
seen.push(parent.getId());
|
seen.push(parent.getId());
|
||||||
parentModel.composition.forEach(function (childId, index) {
|
|
||||||
if (!tree[childId] || seen.includes(childId)) {
|
parentModel.composition.forEach(function (childId) {
|
||||||
|
let keystring = this.openmct.objects.makeKeyString(childId);
|
||||||
|
|
||||||
|
if (!tree[keystring] || seen.includes(keystring)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
newObj = this.instantiate(tree[childId], childId);
|
newObj = this.instantiate(tree[keystring], keystring);
|
||||||
parent.getCapability("composition").add(newObj);
|
|
||||||
newObj.getCapability("location")
|
newObj.getCapability("location")
|
||||||
.setPrimaryLocation(tree[childId].location);
|
.setPrimaryLocation(tree[keystring].location);
|
||||||
this.deepInstantiate(newObj, tree, seen);
|
this.deepInstantiate(newObj, tree, seen);
|
||||||
}, this);
|
}, this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ define([
|
|||||||
'./runs/RegisterLegacyTypes',
|
'./runs/RegisterLegacyTypes',
|
||||||
'./services/LegacyObjectAPIInterceptor',
|
'./services/LegacyObjectAPIInterceptor',
|
||||||
'./views/installLegacyViews',
|
'./views/installLegacyViews',
|
||||||
'./policies/legacyCompositionPolicyAdapter',
|
'./policies/LegacyCompositionPolicyAdapter',
|
||||||
'./actions/LegacyActionAdapter'
|
'./actions/LegacyActionAdapter'
|
||||||
], function (
|
], function (
|
||||||
legacyRegistry,
|
legacyRegistry,
|
||||||
|
|||||||
@@ -45,22 +45,27 @@ define([
|
|||||||
view: function (domainObject) {
|
view: function (domainObject) {
|
||||||
let $rootScope = openmct.$injector.get('$rootScope');
|
let $rootScope = openmct.$injector.get('$rootScope');
|
||||||
let templateLinker = openmct.$injector.get('templateLinker');
|
let templateLinker = openmct.$injector.get('templateLinker');
|
||||||
let scope = $rootScope.$new();
|
let scope = $rootScope.$new(true);
|
||||||
let legacyObject = convertToLegacyObject(domainObject);
|
let legacyObject = convertToLegacyObject(domainObject);
|
||||||
let isDestroyed = false;
|
let isDestroyed = false;
|
||||||
let unlistenToStatus;
|
let unlistenToStatus;
|
||||||
|
let element;
|
||||||
scope.domainObject = legacyObject;
|
scope.domainObject = legacyObject;
|
||||||
scope.model = legacyObject.getModel();
|
scope.model = legacyObject.getModel();
|
||||||
|
let child;
|
||||||
|
let parent;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
show: function (container) {
|
show: function (container) {
|
||||||
|
parent = container;
|
||||||
|
child = document.createElement('div');
|
||||||
|
parent.appendChild(child);
|
||||||
let statusCapability = legacyObject.getCapability('status');
|
let statusCapability = legacyObject.getCapability('status');
|
||||||
unlistenToStatus = statusCapability.listen((newStatus) => {
|
unlistenToStatus = statusCapability.listen((newStatus) => {
|
||||||
container.classList.remove('s-status-timeconductor-unsynced');
|
child.classList.remove('s-status-timeconductor-unsynced');
|
||||||
|
|
||||||
if (newStatus.includes('timeconductor-unsynced')) {
|
if (newStatus.includes('timeconductor-unsynced')) {
|
||||||
container.classList.add('s-status-timeconductor-unsynced');
|
child.classList.add('s-status-timeconductor-unsynced');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -84,12 +89,13 @@ define([
|
|||||||
uses.forEach(function (key, i) {
|
uses.forEach(function (key, i) {
|
||||||
scope[key] = results[i];
|
scope[key] = results[i];
|
||||||
});
|
});
|
||||||
|
element = openmct.$angular.element(child);
|
||||||
templateLinker.link(
|
templateLinker.link(
|
||||||
scope,
|
scope,
|
||||||
openmct.$angular.element(container),
|
element,
|
||||||
legacyView
|
legacyView
|
||||||
);
|
);
|
||||||
container.classList.add('u-contents');
|
child.classList.add('u-contents');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (promises.length) {
|
if (promises.length) {
|
||||||
@@ -103,7 +109,11 @@ define([
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
destroy: function () {
|
destroy: function () {
|
||||||
|
element.off();
|
||||||
|
element.remove();
|
||||||
scope.$destroy();
|
scope.$destroy();
|
||||||
|
element = null;
|
||||||
|
scope = null;
|
||||||
unlistenToStatus();
|
unlistenToStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,15 +41,18 @@ define([
|
|||||||
let domainObject = selection[0][0].context.item;
|
let domainObject = selection[0][0].context.item;
|
||||||
let $rootScope = openmct.$injector.get('$rootScope');
|
let $rootScope = openmct.$injector.get('$rootScope');
|
||||||
let templateLinker = openmct.$injector.get('templateLinker');
|
let templateLinker = openmct.$injector.get('templateLinker');
|
||||||
let scope = $rootScope.$new();
|
let scope = $rootScope.$new(true);
|
||||||
let legacyObject = convertToLegacyObject(domainObject);
|
let legacyObject = convertToLegacyObject(domainObject);
|
||||||
let isDestroyed = false;
|
let isDestroyed = false;
|
||||||
|
let element;
|
||||||
scope.domainObject = legacyObject;
|
scope.domainObject = legacyObject;
|
||||||
scope.model = legacyObject.getModel();
|
scope.model = legacyObject.getModel();
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
show: function (container) {
|
show: function (container) {
|
||||||
|
let child = document.createElement('div');
|
||||||
|
container.appendChild(child);
|
||||||
// TODO: implement "gestures" support ?
|
// TODO: implement "gestures" support ?
|
||||||
let uses = representation.uses || [];
|
let uses = representation.uses || [];
|
||||||
let promises = [];
|
let promises = [];
|
||||||
@@ -70,9 +73,10 @@ define([
|
|||||||
uses.forEach(function (key, i) {
|
uses.forEach(function (key, i) {
|
||||||
scope[key] = results[i];
|
scope[key] = results[i];
|
||||||
});
|
});
|
||||||
|
element = openmct.$angular.element(child)
|
||||||
templateLinker.link(
|
templateLinker.link(
|
||||||
scope,
|
scope,
|
||||||
openmct.$angular.element(container),
|
element,
|
||||||
representation
|
representation
|
||||||
);
|
);
|
||||||
container.style.height = '100%';
|
container.style.height = '100%';
|
||||||
@@ -89,7 +93,11 @@ define([
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
destroy: function () {
|
destroy: function () {
|
||||||
|
element.off();
|
||||||
|
element.remove();
|
||||||
scope.$destroy();
|
scope.$destroy();
|
||||||
|
element = null;
|
||||||
|
scope = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,20 @@ define([
|
|||||||
publicAPI = {};
|
publicAPI = {};
|
||||||
publicAPI.objects = jasmine.createSpyObj('ObjectAPI', [
|
publicAPI.objects = jasmine.createSpyObj('ObjectAPI', [
|
||||||
'get',
|
'get',
|
||||||
'mutate'
|
'mutate',
|
||||||
|
'observe',
|
||||||
|
'areIdsEqual'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
publicAPI.objects.areIdsEqual.and.callFake(function (id1, id2) {
|
||||||
|
return id1.namespace === id2.namespace && id1.key === id2.key;
|
||||||
|
});
|
||||||
|
|
||||||
|
publicAPI.composition = jasmine.createSpyObj('CompositionAPI', [
|
||||||
|
'checkPolicy'
|
||||||
|
]);
|
||||||
|
publicAPI.composition.checkPolicy.and.returnValue(true);
|
||||||
|
|
||||||
publicAPI.objects.eventEmitter = jasmine.createSpyObj('eventemitter', [
|
publicAPI.objects.eventEmitter = jasmine.createSpyObj('eventemitter', [
|
||||||
'on'
|
'on'
|
||||||
]);
|
]);
|
||||||
@@ -119,49 +131,16 @@ define([
|
|||||||
expect(newComposition[2].key).toEqual('a');
|
expect(newComposition[2].key).toEqual('a');
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
it('supports adding an object to composition', function () {
|
||||||
// TODO: Implement add/removal in new default provider.
|
let addListener = jasmine.createSpy('addListener');
|
||||||
xit('synchronizes changes between instances', function () {
|
let mockChildObject = {
|
||||||
var otherComposition = compositionAPI.get(domainObject);
|
identifier: {key: 'mock-key', namespace: ''}
|
||||||
var addListener = jasmine.createSpy('addListener');
|
};
|
||||||
var removeListener = jasmine.createSpy('removeListener');
|
|
||||||
var otherAddListener = jasmine.createSpy('otherAddListener');
|
|
||||||
var otherRemoveListener = jasmine.createSpy('otherRemoveListener');
|
|
||||||
composition.on('add', addListener);
|
composition.on('add', addListener);
|
||||||
composition.on('remove', removeListener);
|
composition.add(mockChildObject);
|
||||||
otherComposition.on('add', otherAddListener);
|
|
||||||
otherComposition.on('remove', otherRemoveListener);
|
|
||||||
|
|
||||||
return Promise.all([composition.load(), otherComposition.load()])
|
expect(domainObject.composition.length).toBe(4);
|
||||||
.then(function () {
|
expect(domainObject.composition[3]).toEqual(mockChildObject.identifier);
|
||||||
expect(addListener).toHaveBeenCalled();
|
|
||||||
expect(otherAddListener).toHaveBeenCalled();
|
|
||||||
expect(removeListener).not.toHaveBeenCalled();
|
|
||||||
expect(otherRemoveListener).not.toHaveBeenCalled();
|
|
||||||
|
|
||||||
var object = addListener.calls.mostRecent().args[0];
|
|
||||||
composition.remove(object);
|
|
||||||
expect(removeListener).toHaveBeenCalled();
|
|
||||||
expect(otherRemoveListener).toHaveBeenCalled();
|
|
||||||
|
|
||||||
addListener.reset();
|
|
||||||
otherAddListener.reset();
|
|
||||||
composition.add(object);
|
|
||||||
expect(addListener).toHaveBeenCalled();
|
|
||||||
expect(otherAddListener).toHaveBeenCalled();
|
|
||||||
|
|
||||||
removeListener.reset();
|
|
||||||
otherRemoveListener.reset();
|
|
||||||
otherComposition.remove(object);
|
|
||||||
expect(removeListener).toHaveBeenCalled();
|
|
||||||
expect(otherRemoveListener).toHaveBeenCalled();
|
|
||||||
|
|
||||||
addListener.reset();
|
|
||||||
otherAddListener.reset();
|
|
||||||
otherComposition.add(object);
|
|
||||||
expect(addListener).toHaveBeenCalled();
|
|
||||||
expect(otherAddListener).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -184,7 +163,9 @@ define([
|
|||||||
key: 'thing'
|
key: 'thing'
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
}
|
},
|
||||||
|
add: jasmine.createSpy('add'),
|
||||||
|
remove: jasmine.createSpy('remove')
|
||||||
};
|
};
|
||||||
domainObject = {
|
domainObject = {
|
||||||
identifier: {
|
identifier: {
|
||||||
@@ -214,6 +195,25 @@ define([
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe('Calling add or remove', function () {
|
||||||
|
let mockChildObject;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
mockChildObject = {
|
||||||
|
identifier: {key: 'mock-key', namespace: ''}
|
||||||
|
};
|
||||||
|
composition.add(mockChildObject);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calls add on the provider', function () {
|
||||||
|
expect(customProvider.add).toHaveBeenCalledWith(domainObject, mockChildObject.identifier);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calls remove on the provider', function () {
|
||||||
|
composition.remove(mockChildObject);
|
||||||
|
expect(customProvider.remove).toHaveBeenCalledWith(domainObject, mockChildObject.identifier);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('dynamic custom composition', function () {
|
describe('dynamic custom composition', function () {
|
||||||
|
|||||||
@@ -75,9 +75,7 @@ define([
|
|||||||
throw new Error('Event not supported by composition: ' + event);
|
throw new Error('Event not supported by composition: ' + event);
|
||||||
}
|
}
|
||||||
if (!this.mutationListener) {
|
if (!this.mutationListener) {
|
||||||
this.mutationListener = this.publicAPI.objects.observe(this.domainObject, '*', (newDomainObject) => {
|
this._synchronize();
|
||||||
this.domainObject = newDomainObject;
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
if (this.provider.on && this.provider.off) {
|
if (this.provider.on && this.provider.off) {
|
||||||
if (event === 'add') {
|
if (event === 'add') {
|
||||||
@@ -134,10 +132,8 @@ define([
|
|||||||
|
|
||||||
this.listeners[event].splice(index, 1);
|
this.listeners[event].splice(index, 1);
|
||||||
if (this.listeners[event].length === 0) {
|
if (this.listeners[event].length === 0) {
|
||||||
if (this.mutationListener) {
|
this._destroy();
|
||||||
this.mutationListener();
|
|
||||||
delete this.mutationListener;
|
|
||||||
}
|
|
||||||
// Remove provider listener if this is the last callback to
|
// Remove provider listener if this is the last callback to
|
||||||
// be removed.
|
// be removed.
|
||||||
if (this.provider.off && this.provider.on) {
|
if (this.provider.off && this.provider.on) {
|
||||||
@@ -181,6 +177,9 @@ define([
|
|||||||
*/
|
*/
|
||||||
CompositionCollection.prototype.add = function (child, skipMutate) {
|
CompositionCollection.prototype.add = function (child, skipMutate) {
|
||||||
if (!skipMutate) {
|
if (!skipMutate) {
|
||||||
|
if (!this.publicAPI.composition.checkPolicy(this.domainObject, child)) {
|
||||||
|
throw `Object of type ${child.type} cannot be added to object of type ${this.domainObject.type}`;
|
||||||
|
}
|
||||||
this.provider.add(this.domainObject, child.identifier);
|
this.provider.add(this.domainObject, child.identifier);
|
||||||
} else {
|
} else {
|
||||||
this.emit('add', child);
|
this.emit('add', child);
|
||||||
@@ -272,6 +271,19 @@ define([
|
|||||||
this.remove(child, true);
|
this.remove(child, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
CompositionCollection.prototype._synchronize = function () {
|
||||||
|
this.mutationListener = this.publicAPI.objects.observe(this.domainObject, '*', (newDomainObject) => {
|
||||||
|
this.domainObject = JSON.parse(JSON.stringify(newDomainObject));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
CompositionCollection.prototype._destroy = function () {
|
||||||
|
if (this.mutationListener) {
|
||||||
|
this.mutationListener();
|
||||||
|
delete this.mutationListener;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emit events.
|
* Emit events.
|
||||||
* @private
|
* @private
|
||||||
|
|||||||
@@ -48,24 +48,11 @@ define([
|
|||||||
this.listeningTo = {};
|
this.listeningTo = {};
|
||||||
this.onMutation = this.onMutation.bind(this);
|
this.onMutation = this.onMutation.bind(this);
|
||||||
|
|
||||||
this.cannotContainDuplicates = this.cannotContainDuplicates.bind(this);
|
|
||||||
this.cannotContainItself = this.cannotContainItself.bind(this);
|
this.cannotContainItself = this.cannotContainItself.bind(this);
|
||||||
|
|
||||||
compositionAPI.addPolicy(this.cannotContainDuplicates);
|
|
||||||
compositionAPI.addPolicy(this.cannotContainItself);
|
compositionAPI.addPolicy(this.cannotContainItself);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
DefaultCompositionProvider.prototype.cannotContainDuplicates = function (parent, child) {
|
|
||||||
return this.appliesTo(parent) &&
|
|
||||||
parent.composition.findIndex((composeeId) => {
|
|
||||||
return composeeId.namespace === child.identifier.namespace &&
|
|
||||||
composeeId.key === child.identifier.key;
|
|
||||||
}) === -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
@@ -199,9 +186,18 @@ define([
|
|||||||
* @memberof module:openmct.CompositionProvider#
|
* @memberof module:openmct.CompositionProvider#
|
||||||
* @method add
|
* @method add
|
||||||
*/
|
*/
|
||||||
DefaultCompositionProvider.prototype.add = function (domainObject, child) {
|
DefaultCompositionProvider.prototype.add = function (parent, childId) {
|
||||||
throw new Error('Default Provider does not implement adding.');
|
if (!this.includes(parent, childId)) {
|
||||||
// TODO: this needs to be synchronized via mutation
|
parent.composition.push(childId);
|
||||||
|
this.publicAPI.objects.mutate(parent, 'composition', parent.composition);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
DefaultCompositionProvider.prototype.includes = function (parent, childId) {
|
||||||
|
return parent.composition.findIndex(composee =>
|
||||||
|
this.publicAPI.objects.areIdsEqual(composee, childId)) !== -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
DefaultCompositionProvider.prototype.reorder = function (domainObject, oldIndex, newIndex) {
|
DefaultCompositionProvider.prototype.reorder = function (domainObject, oldIndex, newIndex) {
|
||||||
|
|||||||
@@ -92,6 +92,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
|
height: 0; // Chrome 73 overflow bug fix
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
padding-right: $interiorMargin; // fend off scroll bar
|
padding-right: $interiorMargin; // fend off scroll bar
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
define([
|
define([
|
||||||
'./components/LadTable.vue',
|
'./components/LADTable.vue',
|
||||||
'vue'
|
'vue'
|
||||||
], function (
|
], function (
|
||||||
LadTableComponent,
|
LadTableComponent,
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import lodash from 'lodash';
|
import lodash from 'lodash';
|
||||||
import LadRow from './LadRow.vue';
|
import LadRow from './LADRow.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
inject: ['openmct', 'domainObject'],
|
inject: ['openmct', 'domainObject'],
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import lodash from 'lodash';
|
import lodash from 'lodash';
|
||||||
import LadRow from './LadRow.vue';
|
import LadRow from './LADRow.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
inject: ['openmct', 'domainObject'],
|
inject: ['openmct', 'domainObject'],
|
||||||
|
|||||||
77
src/plugins/displayLayout/AlphanumericFormatViewProvider.js
Normal file
77
src/plugins/displayLayout/AlphanumericFormatViewProvider.js
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
define([
|
||||||
|
'./components/AlphanumericFormatView.vue',
|
||||||
|
'vue'
|
||||||
|
], function (AlphanumericFormatView, Vue) {
|
||||||
|
|
||||||
|
function AlphanumericFormatViewProvider(openmct, options) {
|
||||||
|
function isTelemetryObject(selectionPath) {
|
||||||
|
let selectedObject = selectionPath[0].context.item;
|
||||||
|
let parentObject = selectionPath[1].context.item;
|
||||||
|
return parentObject &&
|
||||||
|
parentObject.type === 'layout' &&
|
||||||
|
selectedObject &&
|
||||||
|
openmct.telemetry.isTelemetryObject(selectedObject) &&
|
||||||
|
!options.showAsView.includes(selectedObject.type)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
key: 'alphanumeric-format',
|
||||||
|
name: 'Alphanumeric Format',
|
||||||
|
canView: function (selection) {
|
||||||
|
if (selection.length === 0 || selection[0].length === 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return selection.every(isTelemetryObject);
|
||||||
|
},
|
||||||
|
view: function (selection) {
|
||||||
|
let component;
|
||||||
|
return {
|
||||||
|
show: function (element) {
|
||||||
|
component = new Vue({
|
||||||
|
provide: {
|
||||||
|
openmct
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
AlphanumericFormatView: AlphanumericFormatView.default
|
||||||
|
},
|
||||||
|
template: '<alphanumeric-format-view></alphanumeric-format-view>',
|
||||||
|
el: element
|
||||||
|
});
|
||||||
|
},
|
||||||
|
destroy: function () {
|
||||||
|
component.$destroy();
|
||||||
|
component = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
priority: function () {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return AlphanumericFormatViewProvider;
|
||||||
|
});
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="c-properties" v-if="isEditing">
|
||||||
|
<div class="c-properties__header">Alphanumeric Format</div>
|
||||||
|
<ul class="c-properties__section" v-if="!multiSelect">
|
||||||
|
<li class="c-properties__row">
|
||||||
|
<div class="c-properties__label" title="Printf formatting for the selected telemetry">
|
||||||
|
<label for="telemetryPrintfFormat">Format</label>
|
||||||
|
</div>
|
||||||
|
<div class="c-properties__value">
|
||||||
|
<input id="telemetryPrintfFormat" type="text" @change="formatTelemetry" :value="telemetryFormat">
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="c-properties__row--span-all" v-if="multiSelect">No format to display for multiple items</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
inject: ['openmct'],
|
||||||
|
data() {
|
||||||
|
let selectionPath = this.openmct.selection.get()[0];
|
||||||
|
return {
|
||||||
|
isEditing: this.openmct.editor.isEditing(),
|
||||||
|
telemetryFormat: selectionPath[0].context.layoutItem.format,
|
||||||
|
multiSelect: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggleEdit(isEditing) {
|
||||||
|
this.isEditing = isEditing;
|
||||||
|
},
|
||||||
|
formatTelemetry(event) {
|
||||||
|
let selectionPath = this.openmct.selection.get()[0];
|
||||||
|
let newFormat = event.currentTarget.value;
|
||||||
|
selectionPath[0].context.updateTelemetryFormat(newFormat);
|
||||||
|
this.telemetryFormat = newFormat;
|
||||||
|
},
|
||||||
|
handleSelection(selection) {
|
||||||
|
if (selection.length === 0 || selection[0].length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.multiSelect = selection.length > 1 ? true : false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.openmct.editor.on('isEditing', this.toggleEdit);
|
||||||
|
this.openmct.selection.on('change', this.handleSelection);
|
||||||
|
this.handleSelection(this.openmct.selection.get());
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
this.openmct.editor.off('isEditing', this.toggleEdit);
|
||||||
|
this.openmct.selection.off('change', this.handleSelection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
@@ -48,7 +48,8 @@
|
|||||||
:multiSelect="selectedLayoutItems.length > 1"
|
:multiSelect="selectedLayoutItems.length > 1"
|
||||||
@move="move"
|
@move="move"
|
||||||
@endMove="endMove"
|
@endMove="endMove"
|
||||||
@endLineResize='endLineResize'>
|
@endLineResize='endLineResize'
|
||||||
|
@formatChanged='updateTelemetryFormat'>
|
||||||
</component>
|
</component>
|
||||||
<edit-marquee v-if='showMarquee'
|
<edit-marquee v-if='showMarquee'
|
||||||
:gridSize="gridSize"
|
:gridSize="gridSize"
|
||||||
@@ -269,33 +270,63 @@
|
|||||||
_.cloneDeep(this.selectedLayoutItems).forEach(selectedItem => {
|
_.cloneDeep(this.selectedLayoutItems).forEach(selectedItem => {
|
||||||
if (selectedItem.type === 'line-view') {
|
if (selectedItem.type === 'line-view') {
|
||||||
this.initialPositions[selectedItem.id] = [selectedItem.x, selectedItem.y, selectedItem.x2, selectedItem.y2];
|
this.initialPositions[selectedItem.id] = [selectedItem.x, selectedItem.y, selectedItem.x2, selectedItem.y2];
|
||||||
|
this.startingMinX2 = this.startingMinX2 !== undefined ? Math.min(this.startingMinX2, selectedItem.x2) : selectedItem.x2;
|
||||||
|
this.startingMinY2 = this.startingMinY2 !== undefined ? Math.min(this.startingMinY2, selectedItem.y2) : selectedItem.y2;
|
||||||
} else {
|
} else {
|
||||||
this.initialPositions[selectedItem.id] = [selectedItem.x, selectedItem.y];
|
this.initialPositions[selectedItem.id] = [selectedItem.x, selectedItem.y];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.startingMinX = this.startingMinX !== undefined ? Math.min(this.startingMinX, selectedItem.x) : selectedItem.x;
|
||||||
|
this.startingMinY = this.startingMinY !== undefined ? Math.min(this.startingMinY, selectedItem.y) : selectedItem.y;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let layoutItems = this.layoutItems.map(item => {
|
let layoutItems = this.layoutItems.map(item => {
|
||||||
if (this.initialPositions[item.id]) {
|
if (this.initialPositions[item.id]) {
|
||||||
let startingPosition = this.initialPositions[item.id];
|
this.updateItemPosition(item, gridDelta);
|
||||||
let [startingX, startingY, startingX2, startingY2] = startingPosition;
|
|
||||||
item.x = startingX + gridDelta[0];
|
|
||||||
item.y = startingY + gridDelta[1];
|
|
||||||
|
|
||||||
if (item.x2) {
|
|
||||||
item.x2 = startingX2 + gridDelta[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.y2) {
|
|
||||||
item.y2 = startingY2 + gridDelta[1];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
updateItemPosition(item, gridDelta) {
|
||||||
|
let startingPosition = this.initialPositions[item.id];
|
||||||
|
let [startingX, startingY, startingX2, startingY2] = startingPosition;
|
||||||
|
|
||||||
|
if (this.startingMinX + gridDelta[0] >= 0) {
|
||||||
|
if (item.x2 !== undefined) {
|
||||||
|
if (this.startingMinX2 + gridDelta[0] >= 0) {
|
||||||
|
item.x = startingX + gridDelta[0];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
item.x = startingX + gridDelta[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.startingMinY + gridDelta[1] >= 0) {
|
||||||
|
if (item.y2 !== undefined) {
|
||||||
|
if (this.startingMinY2 + gridDelta[1] >= 0) {
|
||||||
|
item.y = startingY + gridDelta[1];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
item.y = startingY + gridDelta[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.x2 !== undefined && this.startingMinX2 + gridDelta[0] >= 0 && this.startingMinX + gridDelta[0] >= 0) {
|
||||||
|
item.x2 = startingX2 + gridDelta[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.y2 !== undefined && this.startingMinY2 + gridDelta[1] >= 0 && this.startingMinY + gridDelta[1] >= 0) {
|
||||||
|
item.y2 = startingY2 + gridDelta[1];
|
||||||
|
}
|
||||||
|
},
|
||||||
endMove() {
|
endMove() {
|
||||||
this.mutate('configuration.items', this.layoutItems);
|
this.mutate('configuration.items', this.layoutItems);
|
||||||
this.initialPositions = undefined;
|
this.initialPositions = undefined;
|
||||||
|
this.startingMinX = undefined;
|
||||||
|
this.startingMinY = undefined;
|
||||||
|
this.startingMinX2 = undefined;
|
||||||
|
this.startingMinY2 = undefined;
|
||||||
},
|
},
|
||||||
mutate(path, value) {
|
mutate(path, value) {
|
||||||
this.openmct.objects.mutate(this.internalDomainObject, path, value);
|
this.openmct.objects.mutate(this.internalDomainObject, path, value);
|
||||||
@@ -527,6 +558,11 @@
|
|||||||
this.layoutItems.splice(itemIndex, 1);
|
this.layoutItems.splice(itemIndex, 1);
|
||||||
this.layoutItems.splice(newIndex, 0, items[itemIndex]);
|
this.layoutItems.splice(newIndex, 0, items[itemIndex]);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
updateTelemetryFormat(item, format) {
|
||||||
|
let index = this.layoutItems.indexOf(item);
|
||||||
|
item.format = format;
|
||||||
|
this.mutate(`configuration.items[${index}]`, item);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|||||||
@@ -116,7 +116,7 @@
|
|||||||
let height = Number.NEGATIVE_INFINITY;
|
let height = Number.NEGATIVE_INFINITY;
|
||||||
|
|
||||||
this.selectedLayoutItems.forEach(item => {
|
this.selectedLayoutItems.forEach(item => {
|
||||||
if (item.x2) {
|
if (item.x2 !== undefined) {
|
||||||
let lineWidth = Math.abs(item.x - item.x2);
|
let lineWidth = Math.abs(item.x - item.x2);
|
||||||
let lineMinX = Math.min(item.x, item.x2);
|
let lineMinX = Math.min(item.x, item.x2);
|
||||||
x = Math.min(lineMinX, x);
|
x = Math.min(lineMinX, x);
|
||||||
@@ -126,7 +126,7 @@
|
|||||||
width = Math.max(item.width + item.x, width);
|
width = Math.max(item.width + item.x, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.y2) {
|
if (item.y2 !== undefined) {
|
||||||
let lineHeight = Math.abs(item.y - item.y2);
|
let lineHeight = Math.abs(item.y - item.y2);
|
||||||
let lineMinY = Math.min(item.y, item.y2);
|
let lineMinY = Math.min(item.y, item.y2);
|
||||||
y = Math.min(lineMinY, y);
|
y = Math.min(lineMinY, y);
|
||||||
|
|||||||
@@ -79,6 +79,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import LayoutFrame from './LayoutFrame.vue'
|
import LayoutFrame from './LayoutFrame.vue'
|
||||||
|
import printj from 'printj'
|
||||||
|
|
||||||
const DEFAULT_TELEMETRY_DIMENSIONS = [10, 5],
|
const DEFAULT_TELEMETRY_DIMENSIONS = [10, 5],
|
||||||
DEFAULT_POSITION = [1, 1];
|
DEFAULT_POSITION = [1, 1];
|
||||||
@@ -143,6 +144,10 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.item.format) {
|
||||||
|
return printj.sprintf(this.item.format, this.datum[this.valueMetadata.key]);
|
||||||
|
}
|
||||||
|
|
||||||
return this.valueFormatter && this.valueFormatter.format(this.datum);
|
return this.valueFormatter && this.valueFormatter.format(this.datum);
|
||||||
},
|
},
|
||||||
telemetryClass() {
|
telemetryClass() {
|
||||||
@@ -168,6 +173,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.context.index = newIndex;
|
this.context.index = newIndex;
|
||||||
|
},
|
||||||
|
item(newItem) {
|
||||||
|
this.context.layoutItem = newItem;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -194,6 +202,7 @@
|
|||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
updateView(datum) {
|
updateView(datum) {
|
||||||
|
// TODO: normalize datum
|
||||||
this.datum = datum;
|
this.datum = datum;
|
||||||
},
|
},
|
||||||
removeSubscription() {
|
removeSubscription() {
|
||||||
@@ -219,10 +228,14 @@
|
|||||||
this.context = {
|
this.context = {
|
||||||
item: domainObject,
|
item: domainObject,
|
||||||
layoutItem: this.item,
|
layoutItem: this.item,
|
||||||
index: this.index
|
index: this.index,
|
||||||
|
updateTelemetryFormat: this.updateTelemetryFormat
|
||||||
};
|
};
|
||||||
this.removeSelectable = this.openmct.selection.selectable(
|
this.removeSelectable = this.openmct.selection.selectable(
|
||||||
this.$el, this.context, this.initSelect);
|
this.$el, this.context, this.initSelect);
|
||||||
|
},
|
||||||
|
updateTelemetryFormat(format) {
|
||||||
|
this.$emit('formatChanged', this.item, format);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ import Vue from 'vue'
|
|||||||
import objectUtils from '../../api/objects/object-utils.js'
|
import objectUtils from '../../api/objects/object-utils.js'
|
||||||
import DisplayLayoutType from './DisplayLayoutType.js'
|
import DisplayLayoutType from './DisplayLayoutType.js'
|
||||||
import DisplayLayoutToolbar from './DisplayLayoutToolbar.js'
|
import DisplayLayoutToolbar from './DisplayLayoutToolbar.js'
|
||||||
|
import AlphaNumericFormatViewProvider from './AlphaNumericFormatViewProvider.js'
|
||||||
|
|
||||||
export default function DisplayLayoutPlugin(options) {
|
export default function DisplayLayoutPlugin(options) {
|
||||||
return function (openmct) {
|
return function (openmct) {
|
||||||
openmct.objectViews.addProvider({
|
openmct.objectViews.addProvider({
|
||||||
@@ -76,7 +78,8 @@ export default function DisplayLayoutPlugin(options) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
openmct.types.addType('layout', DisplayLayoutType());
|
openmct.types.addType('layout', DisplayLayoutType());
|
||||||
openmct.toolbars.addProvider(new DisplayLayoutToolbar(openmct));
|
openmct.toolbars.addProvider(new DisplayLayoutToolbar(openmct, options));
|
||||||
|
openmct.inspectorViews.addProvider(new AlphaNumericFormatViewProvider(openmct, options));
|
||||||
openmct.composition.addPolicy((parent, child) => {
|
openmct.composition.addPolicy((parent, child) => {
|
||||||
if (parent.type === 'layout' && child.type === 'folder') {
|
if (parent.type === 'layout' && child.type === 'folder') {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
53
src/plugins/goToOriginalAction/goToOriginalAction.js
Normal file
53
src/plugins/goToOriginalAction/goToOriginalAction.js
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
export default class GoToOriginalAction {
|
||||||
|
constructor(openmct) {
|
||||||
|
this.name = 'Go To Original';
|
||||||
|
this.description = 'Go to the original unlinked instance of this object';
|
||||||
|
|
||||||
|
this._openmct = openmct;
|
||||||
|
}
|
||||||
|
invoke(objectPath) {
|
||||||
|
this._openmct.objects.getOriginalPath(objectPath[0].identifier)
|
||||||
|
.then((originalPath) => {
|
||||||
|
let url = '#/browse/' + originalPath
|
||||||
|
.map(function (o) {
|
||||||
|
return o && this._openmct.objects.makeKeyString(o.identifier);
|
||||||
|
}.bind(this))
|
||||||
|
.reverse()
|
||||||
|
.slice(1)
|
||||||
|
.join('/');
|
||||||
|
|
||||||
|
window.location.href = url;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
appliesTo(objectPath) {
|
||||||
|
let parentKeystring = objectPath[1] && this._openmct.objects.makeKeyString(objectPath[1].identifier);
|
||||||
|
|
||||||
|
if (!parentKeystring) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (parentKeystring !== objectPath[0].location);
|
||||||
|
}
|
||||||
|
}
|
||||||
28
src/plugins/goToOriginalAction/plugin.js
Normal file
28
src/plugins/goToOriginalAction/plugin.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
import GoToOriginalAction from './goToOriginalAction';
|
||||||
|
|
||||||
|
export default function () {
|
||||||
|
return function (openmct) {
|
||||||
|
openmct.contextMenu.registerAction(new GoToOriginalAction(openmct));
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -64,35 +64,45 @@ define([
|
|||||||
Object.keys(panels).forEach(key => {
|
Object.keys(panels).forEach(key => {
|
||||||
let panel = panels[key];
|
let panel = panels[key];
|
||||||
let domainObject = childObjects[key];
|
let domainObject = childObjects[key];
|
||||||
|
let identifier = undefined;
|
||||||
|
|
||||||
if (isTelemetry(domainObject)) {
|
if (isTelemetry(domainObject)) {
|
||||||
items.push({
|
// If object is a telemetry point, convert it to a plot and
|
||||||
width: panel.dimensions[0],
|
// replace the object in migratedObject composition with the plot.
|
||||||
height: panel.dimensions[1],
|
identifier = {
|
||||||
x: panel.position[0],
|
key: uuid(),
|
||||||
y: panel.position[1],
|
namespace: migratedObject.identifier.namespace
|
||||||
identifier: domainObject.identifier,
|
};
|
||||||
id: uuid(),
|
let plotObject = {
|
||||||
type: 'telemetry-view',
|
identifier: identifier,
|
||||||
displayMode: 'all',
|
location: domainObject.location,
|
||||||
value: openmct.telemetry.getMetadata(domainObject).getDefaultDisplayValue(),
|
name: domainObject.name,
|
||||||
stroke: "transparent",
|
type: "telemetry.plot.overlay"
|
||||||
fill: "",
|
};
|
||||||
color: "",
|
let plotType = openmct.types.get('telemetry.plot.overlay');
|
||||||
size: "13px"
|
plotType.definition.initialize(plotObject);
|
||||||
|
plotObject.composition.push(domainObject.identifier);
|
||||||
|
openmct.objects.mutate(plotObject, 'persisted', Date.now());
|
||||||
|
|
||||||
|
let keyString = openmct.objects.makeKeyString(domainObject.identifier);
|
||||||
|
let clonedComposition = Object.assign([], migratedObject.composition);
|
||||||
|
clonedComposition.forEach((identifier, index) => {
|
||||||
|
if (openmct.objects.makeKeyString(identifier) === keyString) {
|
||||||
|
migratedObject.composition[index] = plotObject.identifier;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
}
|
||||||
|
|
||||||
items.push({
|
items.push({
|
||||||
width: panel.dimensions[0],
|
width: panel.dimensions[0],
|
||||||
height: panel.dimensions[1],
|
height: panel.dimensions[1],
|
||||||
x: panel.position[0],
|
x: panel.position[0],
|
||||||
y: panel.position[1],
|
y: panel.position[1],
|
||||||
identifier: domainObject.identifier,
|
identifier: identifier || domainObject.identifier,
|
||||||
id: uuid(),
|
id: uuid(),
|
||||||
type: 'subobject-view',
|
type: 'subobject-view',
|
||||||
hasFrame: panel.hasFrame
|
hasFrame: panel.hasFrame
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
migratedObject.configuration.items = items;
|
migratedObject.configuration.items = items;
|
||||||
@@ -167,7 +177,9 @@ define([
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
check(domainObject) {
|
check(domainObject) {
|
||||||
return domainObject.type === 'layout' && domainObject.configuration.layout;
|
return domainObject.type === 'layout' &&
|
||||||
|
domainObject.configuration &&
|
||||||
|
domainObject.configuration.layout;
|
||||||
},
|
},
|
||||||
migrate(domainObject) {
|
migrate(domainObject) {
|
||||||
let childObjects = {};
|
let childObjects = {};
|
||||||
@@ -186,7 +198,9 @@ define([
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
check(domainObject) {
|
check(domainObject) {
|
||||||
return domainObject.type === 'telemetry.fixed' && domainObject.configuration['fixed-display'];
|
return domainObject.type === 'telemetry.fixed' &&
|
||||||
|
domainObject.configuration &&
|
||||||
|
domainObject.configuration['fixed-display'];
|
||||||
},
|
},
|
||||||
migrate(domainObject) {
|
migrate(domainObject) {
|
||||||
const DEFAULT_GRID_SIZE = [64, 16];
|
const DEFAULT_GRID_SIZE = [64, 16];
|
||||||
@@ -224,6 +238,7 @@ define([
|
|||||||
{
|
{
|
||||||
check(domainObject) {
|
check(domainObject) {
|
||||||
return domainObject.type === 'table' &&
|
return domainObject.type === 'table' &&
|
||||||
|
domainObject.configuration &&
|
||||||
domainObject.configuration.table;
|
domainObject.configuration.table;
|
||||||
},
|
},
|
||||||
migrate(domainObject) {
|
migrate(domainObject) {
|
||||||
|
|||||||
@@ -115,11 +115,13 @@ define([
|
|||||||
|
|
||||||
Collection.prototype.remove = function (model) {
|
Collection.prototype.remove = function (model) {
|
||||||
var index = this.indexOf(model);
|
var index = this.indexOf(model);
|
||||||
|
|
||||||
if (index === -1) {
|
if (index === -1) {
|
||||||
throw new Error('model not found in collection.');
|
throw new Error('model not found in collection.');
|
||||||
}
|
}
|
||||||
this.models.splice(index, 1);
|
|
||||||
this.emit('remove', model, index);
|
this.emit('remove', model, index);
|
||||||
|
this.models.splice(index, 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
Collection.prototype.destroy = function (model) {
|
Collection.prototype.destroy = function (model) {
|
||||||
|
|||||||
@@ -100,20 +100,34 @@ define([
|
|||||||
removeTelemetryObject: function (identifier) {
|
removeTelemetryObject: function (identifier) {
|
||||||
var plotObject = this.plot.get('domainObject');
|
var plotObject = this.plot.get('domainObject');
|
||||||
if (plotObject.type === 'telemetry.plot.overlay') {
|
if (plotObject.type === 'telemetry.plot.overlay') {
|
||||||
var index = _.findIndex(plotObject.configuration.series, function (s) {
|
|
||||||
|
var persistedIndex = _.findIndex(plotObject.configuration.series, function (s) {
|
||||||
return _.isEqual(identifier, s.identifier);
|
return _.isEqual(identifier, s.identifier);
|
||||||
});
|
});
|
||||||
this.remove(this.at(index));
|
|
||||||
|
var configIndex = _.findIndex(this.models, function (m) {
|
||||||
|
return _.isEqual(m.domainObject.identifier, identifier);
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
when cancelling out of edit mode, the config store and domain object are out of sync
|
||||||
|
thus it is necesarry to check both and remove the models that are no longer in composition
|
||||||
|
*/
|
||||||
|
if (persistedIndex === -1) {
|
||||||
|
this.remove(this.at(configIndex));
|
||||||
|
} else {
|
||||||
|
this.remove(this.at(persistedIndex));
|
||||||
// Because this is triggered by a composition change, we have
|
// Because this is triggered by a composition change, we have
|
||||||
// to defer mutation of our plot object, otherwise we might
|
// to defer mutation of our plot object, otherwise we might
|
||||||
// mutate an outdated version of the plotObject.
|
// mutate an outdated version of the plotObject.
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
var newPlotObject = this.plot.get('domainObject');
|
var newPlotObject = this.plot.get('domainObject');
|
||||||
var cSeries = newPlotObject.configuration.series.slice();
|
var cSeries = newPlotObject.configuration.series.slice();
|
||||||
cSeries.splice(index, 1);
|
cSeries.splice(persistedIndex, 1);
|
||||||
this.openmct.objects.mutate(newPlotObject, 'configuration.series', cSeries);
|
this.openmct.objects.mutate(newPlotObject, 'configuration.series', cSeries);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onSeriesAdd: function (series) {
|
onSeriesAdd: function (series) {
|
||||||
var seriesColor = series.get('color');
|
var seriesColor = series.get('color');
|
||||||
|
|||||||
@@ -25,23 +25,11 @@ define([
|
|||||||
|
|
||||||
function ConfigStore() {
|
function ConfigStore() {
|
||||||
this.store = {};
|
this.store = {};
|
||||||
this.tracking = {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigStore.prototype.track = function (id) {
|
ConfigStore.prototype.deleteStore = function (id) {
|
||||||
if (!this.tracking[id]) {
|
|
||||||
this.tracking[id] = 0;
|
|
||||||
}
|
|
||||||
this.tracking[id] += 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
ConfigStore.prototype.untrack = function (id) {
|
|
||||||
this.tracking[id] -= 1;
|
|
||||||
if (this.tracking[id] <= 0) {
|
|
||||||
delete this.tracking[id];
|
|
||||||
this.store[id].destroy();
|
this.store[id].destroy();
|
||||||
delete this.store[id];
|
delete this.store[id];
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ConfigStore.prototype.add = function (id, config) {
|
ConfigStore.prototype.add = function (id, config) {
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
PlotOptionsController.prototype.destroy = function () {
|
PlotOptionsController.prototype.destroy = function () {
|
||||||
configStore.untrack(this.configId);
|
|
||||||
this.stopListening();
|
this.stopListening();
|
||||||
this.unlisten();
|
this.unlisten();
|
||||||
};
|
};
|
||||||
@@ -60,7 +59,7 @@ define([
|
|||||||
this.$timeout(this.setUpScope.bind(this));
|
this.$timeout(this.setUpScope.bind(this));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
configStore.track(this.configId);
|
|
||||||
this.config = this.$scope.config = config;
|
this.config = this.$scope.config = config;
|
||||||
this.$scope.plotSeries = [];
|
this.$scope.plotSeries = [];
|
||||||
|
|
||||||
|
|||||||
@@ -282,11 +282,19 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
MCTPlotController.prototype.zoom = function (zoomDirection, zoomFactor) {
|
MCTPlotController.prototype.zoom = function (zoomDirection, zoomFactor) {
|
||||||
|
var currentXaxis = this.$scope.xAxis.get('displayRange'),
|
||||||
|
currentYaxis = this.$scope.yAxis.get('displayRange');
|
||||||
|
|
||||||
|
// when there is no plot data, the ranges can be undefined
|
||||||
|
// in which case we should not perform zoom
|
||||||
|
if (!currentXaxis || !currentYaxis) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.freeze();
|
this.freeze();
|
||||||
this.trackHistory();
|
this.trackHistory();
|
||||||
var currentXaxis = this.$scope.xAxis.get('displayRange'),
|
|
||||||
currentYaxis = this.$scope.yAxis.get('displayRange'),
|
var xAxisDist= (currentXaxis.max - currentXaxis.min) * zoomFactor,
|
||||||
xAxisDist= (currentXaxis.max - currentXaxis.min) * zoomFactor,
|
|
||||||
yAxisDist = (currentYaxis.max - currentYaxis.min) * zoomFactor;
|
yAxisDist = (currentYaxis.max - currentYaxis.min) * zoomFactor;
|
||||||
|
|
||||||
if (zoomDirection === 'in') {
|
if (zoomDirection === 'in') {
|
||||||
@@ -322,12 +330,19 @@ define([
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let xDisplayRange = this.$scope.xAxis.get('displayRange'),
|
||||||
|
yDisplayRange = this.$scope.yAxis.get('displayRange');
|
||||||
|
|
||||||
|
// when there is no plot data, the ranges can be undefined
|
||||||
|
// in which case we should not perform zoom
|
||||||
|
if (!xDisplayRange || !yDisplayRange) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.freeze();
|
this.freeze();
|
||||||
window.clearTimeout(this.stillZooming);
|
window.clearTimeout(this.stillZooming);
|
||||||
|
|
||||||
let xDisplayRange = this.$scope.xAxis.get('displayRange'),
|
let xAxisDist = (xDisplayRange.max - xDisplayRange.min),
|
||||||
yDisplayRange = this.$scope.yAxis.get('displayRange'),
|
|
||||||
xAxisDist = (xDisplayRange.max - xDisplayRange.min),
|
|
||||||
yAxisDist = (yDisplayRange.max - yDisplayRange.min),
|
yAxisDist = (yDisplayRange.max - yDisplayRange.min),
|
||||||
xDistMouseToMax = xDisplayRange.max - this.positionOverPlot.x,
|
xDistMouseToMax = xDisplayRange.max - this.positionOverPlot.x,
|
||||||
xDistMouseToMin = this.positionOverPlot.x - xDisplayRange.min,
|
xDistMouseToMin = this.positionOverPlot.x - xDisplayRange.min,
|
||||||
|
|||||||
@@ -148,7 +148,6 @@ define([
|
|||||||
});
|
});
|
||||||
configStore.add(configId, config);
|
configStore.add(configId, config);
|
||||||
}
|
}
|
||||||
configStore.track(configId);
|
|
||||||
return config;
|
return config;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -157,7 +156,8 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
PlotController.prototype.destroy = function () {
|
PlotController.prototype.destroy = function () {
|
||||||
configStore.untrack(this.config.id);
|
configStore.deleteStore(this.config.id);
|
||||||
|
|
||||||
this.stopListening();
|
this.stopListening();
|
||||||
if (this.checkForSize) {
|
if (this.checkForSize) {
|
||||||
clearInterval(this.checkForSize);
|
clearInterval(this.checkForSize);
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
define([
|
define([
|
||||||
'lodash',
|
'lodash',
|
||||||
'./utcTimeSystem/plugin',
|
'./utcTimeSystem/plugin',
|
||||||
|
'./localTimeSystem/plugin',
|
||||||
'../../example/generator/plugin',
|
'../../example/generator/plugin',
|
||||||
'./autoflow/AutoflowTabularPlugin',
|
'./autoflow/AutoflowTabularPlugin',
|
||||||
'./timeConductor/plugin',
|
'./timeConductor/plugin',
|
||||||
@@ -41,10 +42,12 @@ define([
|
|||||||
'./tabs/plugin',
|
'./tabs/plugin',
|
||||||
'./LADTable/plugin',
|
'./LADTable/plugin',
|
||||||
'./filters/plugin',
|
'./filters/plugin',
|
||||||
'./objectMigration/plugin'
|
'./objectMigration/plugin',
|
||||||
|
'./goToOriginalAction/plugin'
|
||||||
], function (
|
], function (
|
||||||
_,
|
_,
|
||||||
UTCTimeSystem,
|
UTCTimeSystem,
|
||||||
|
LocalTimeSystem,
|
||||||
GeneratorPlugin,
|
GeneratorPlugin,
|
||||||
AutoflowPlugin,
|
AutoflowPlugin,
|
||||||
TimeConductorPlugin,
|
TimeConductorPlugin,
|
||||||
@@ -63,7 +66,8 @@ define([
|
|||||||
Tabs,
|
Tabs,
|
||||||
LADTable,
|
LADTable,
|
||||||
Filters,
|
Filters,
|
||||||
ObjectMigration
|
ObjectMigration,
|
||||||
|
GoToOriginalAction
|
||||||
) {
|
) {
|
||||||
var bundleMap = {
|
var bundleMap = {
|
||||||
LocalStorage: 'platform/persistence/local',
|
LocalStorage: 'platform/persistence/local',
|
||||||
@@ -79,6 +83,7 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
plugins.UTCTimeSystem = UTCTimeSystem;
|
plugins.UTCTimeSystem = UTCTimeSystem;
|
||||||
|
plugins.LocalTimeSystem = LocalTimeSystem;
|
||||||
|
|
||||||
plugins.ImportExport = ImportExport;
|
plugins.ImportExport = ImportExport;
|
||||||
|
|
||||||
@@ -160,6 +165,7 @@ define([
|
|||||||
plugins.LADTable = LADTable;
|
plugins.LADTable = LADTable;
|
||||||
plugins.Filters = Filters;
|
plugins.Filters = Filters;
|
||||||
plugins.ObjectMigration = ObjectMigration.default;
|
plugins.ObjectMigration = ObjectMigration.default;
|
||||||
|
plugins.GoToOriginalAction = GoToOriginalAction.default;
|
||||||
|
|
||||||
return plugins;
|
return plugins;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -70,17 +70,15 @@ define([
|
|||||||
*/
|
*/
|
||||||
function onValueInput(event) {
|
function onValueInput(event) {
|
||||||
var elem = event.target,
|
var elem = event.target,
|
||||||
value = (isNaN(elem.valueAsNumber) ? elem.value : elem.valueAsNumber),
|
value = isNaN(Number(elem.value)) ? elem.value : Number(elem.value),
|
||||||
inputIndex = self.valueInputs.indexOf(elem);
|
inputIndex = self.valueInputs.indexOf(elem);
|
||||||
|
|
||||||
if (elem.tagName.toUpperCase() === 'INPUT') {
|
|
||||||
self.eventEmitter.emit('change', {
|
self.eventEmitter.emit('change', {
|
||||||
value: value,
|
value: value,
|
||||||
property: 'values[' + inputIndex + ']',
|
property: 'values[' + inputIndex + ']',
|
||||||
index: self.index
|
index: self.index
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
this.listenTo(this.deleteButton, 'click', this.remove, this);
|
this.listenTo(this.deleteButton, 'click', this.remove, this);
|
||||||
this.listenTo(this.duplicateButton, 'click', this.duplicate, this);
|
this.listenTo(this.duplicateButton, 'click', this.duplicate, this);
|
||||||
@@ -108,8 +106,7 @@ define([
|
|||||||
Object.values(this.selects).forEach(function (select) {
|
Object.values(this.selects).forEach(function (select) {
|
||||||
$('.t-configuration', self.domElement).append(select.getDOM());
|
$('.t-configuration', self.domElement).append(select.getDOM());
|
||||||
});
|
});
|
||||||
|
this.listenTo($('.t-value-inputs', this.domElement), 'input', onValueInput);
|
||||||
this.listenTo($(this.domElement), 'input', onValueInput);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Condition.prototype.getDOM = function (container) {
|
Condition.prototype.getDOM = function (container) {
|
||||||
@@ -167,7 +164,9 @@ define([
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* When an operation is selected, create the appropriate value inputs
|
* When an operation is selected, create the appropriate value inputs
|
||||||
* and add them to the view
|
* and add them to the view. If an operation is of type enum, create
|
||||||
|
* a drop-down menu instead.
|
||||||
|
*
|
||||||
* @param {string} operation The key of currently selected operation
|
* @param {string} operation The key of currently selected operation
|
||||||
*/
|
*/
|
||||||
Condition.prototype.generateValueInputs = function (operation) {
|
Condition.prototype.generateValueInputs = function (operation) {
|
||||||
@@ -176,24 +175,48 @@ define([
|
|||||||
inputCount,
|
inputCount,
|
||||||
inputType,
|
inputType,
|
||||||
newInput,
|
newInput,
|
||||||
index = 0;
|
index = 0,
|
||||||
|
emitChange = false;
|
||||||
|
|
||||||
inputArea.html('');
|
inputArea.html('');
|
||||||
this.valueInputs = [];
|
this.valueInputs = [];
|
||||||
|
this.config.values = [];
|
||||||
|
|
||||||
if (evaluator.getInputCount(operation)) {
|
if (evaluator.getInputCount(operation)) {
|
||||||
inputCount = evaluator.getInputCount(operation);
|
inputCount = evaluator.getInputCount(operation);
|
||||||
inputType = evaluator.getInputType(operation);
|
inputType = evaluator.getInputType(operation);
|
||||||
|
|
||||||
while (index < inputCount) {
|
while (index < inputCount) {
|
||||||
if (!this.config.values[index]) {
|
if (inputType === 'select') {
|
||||||
this.config.values[index] = (inputType === 'number' ? 0 : '');
|
newInput = $('<select>' + this.generateSelectOptions() + '</select>');
|
||||||
}
|
emitChange = true;
|
||||||
|
} else {
|
||||||
|
this.config.values[index] = inputType === 'number' ? 0 : '';
|
||||||
newInput = $('<input type = "' + inputType + '" value = "' + this.config.values[index] + '"> </input>');
|
newInput = $('<input type = "' + inputType + '" value = "' + this.config.values[index] + '"> </input>');
|
||||||
|
}
|
||||||
|
|
||||||
this.valueInputs.push(newInput.get(0));
|
this.valueInputs.push(newInput.get(0));
|
||||||
inputArea.append(newInput);
|
inputArea.append(newInput);
|
||||||
index += 1;
|
index += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (emitChange) {
|
||||||
|
this.eventEmitter.emit('change', {
|
||||||
|
value: Number(newInput[0].options[0].value),
|
||||||
|
property: 'values[0]',
|
||||||
|
index: this.index
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Condition.prototype.generateSelectOptions = function () {
|
||||||
|
let telemetryMetadata = this.conditionManager.getTelemetryMetadata(this.config.object);
|
||||||
|
let options = '';
|
||||||
|
telemetryMetadata[this.config.key].enumerations.forEach(enumeration => {
|
||||||
|
options += '<option value="' + enumeration.value + '">'+ enumeration.string + '</option>';
|
||||||
|
});
|
||||||
|
return options;
|
||||||
};
|
};
|
||||||
|
|
||||||
return Condition;
|
return Condition;
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ define([], function () {
|
|||||||
*/
|
*/
|
||||||
this.inputTypes = {
|
this.inputTypes = {
|
||||||
number: 'number',
|
number: 'number',
|
||||||
string: 'text'
|
string: 'text',
|
||||||
|
enum: 'select'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -34,7 +35,8 @@ define([], function () {
|
|||||||
*/
|
*/
|
||||||
this.inputValidators = {
|
this.inputValidators = {
|
||||||
number: this.validateNumberInput,
|
number: this.validateNumberInput,
|
||||||
string: this.validateStringInput
|
string: this.validateStringInput,
|
||||||
|
enum: this.validateNumberInput
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -201,7 +203,7 @@ define([], function () {
|
|||||||
return typeof input[0] === 'undefined';
|
return typeof input[0] === 'undefined';
|
||||||
},
|
},
|
||||||
text: 'is undefined',
|
text: 'is undefined',
|
||||||
appliesTo: ['string', 'number'],
|
appliesTo: ['string', 'number', 'enum'],
|
||||||
inputCount: 0,
|
inputCount: 0,
|
||||||
getDescription: function () {
|
getDescription: function () {
|
||||||
return ' is undefined';
|
return ' is undefined';
|
||||||
@@ -212,11 +214,33 @@ define([], function () {
|
|||||||
return typeof input[0] !== 'undefined';
|
return typeof input[0] !== 'undefined';
|
||||||
},
|
},
|
||||||
text: 'is defined',
|
text: 'is defined',
|
||||||
appliesTo: ['string', 'number'],
|
appliesTo: ['string', 'number', 'enum'],
|
||||||
inputCount: 0,
|
inputCount: 0,
|
||||||
getDescription: function () {
|
getDescription: function () {
|
||||||
return ' is defined';
|
return ' is defined';
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
enumValueIs: {
|
||||||
|
operation: function (input) {
|
||||||
|
return input[0] === input[1];
|
||||||
|
},
|
||||||
|
text: 'is',
|
||||||
|
appliesTo: ['enum'],
|
||||||
|
inputCount: 1,
|
||||||
|
getDescription: function (values) {
|
||||||
|
return ' == ' + values[0];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enumValueIsNot: {
|
||||||
|
operation: function (input) {
|
||||||
|
return input[0] !== input[1];
|
||||||
|
},
|
||||||
|
text: 'is not',
|
||||||
|
appliesTo: ['enum'],
|
||||||
|
inputCount: 1,
|
||||||
|
getDescription: function (values) {
|
||||||
|
return ' != ' + values[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -310,13 +334,16 @@ define([], function () {
|
|||||||
validator;
|
validator;
|
||||||
|
|
||||||
if (cache[object] && typeof cache[object][key] !== 'undefined') {
|
if (cache[object] && typeof cache[object][key] !== 'undefined') {
|
||||||
telemetryValue = [cache[object][key]];
|
let value = cache[object][key];
|
||||||
|
telemetryValue = [isNaN(Number(value)) ? value : Number(value)];
|
||||||
}
|
}
|
||||||
|
|
||||||
op = this.operations[operation] && this.operations[operation].operation;
|
op = this.operations[operation] && this.operations[operation].operation;
|
||||||
input = telemetryValue && telemetryValue.concat(values);
|
input = telemetryValue && telemetryValue.concat(values);
|
||||||
validator = op && this.inputValidators[this.operations[operation].appliesTo[0]];
|
validator = op && this.inputValidators[this.operations[operation].appliesTo[0]];
|
||||||
|
|
||||||
if (op && input && validator) {
|
if (op && input && validator) {
|
||||||
if (this.operations[operation].appliesTo.length === 2) {
|
if (this.operations[operation].appliesTo.length > 1) {
|
||||||
return (this.validateNumberInput(input) || this.validateStringInput(input)) && op(input);
|
return (this.validateNumberInput(input) || this.validateStringInput(input)) && op(input);
|
||||||
} else {
|
} else {
|
||||||
return validator(input) && op(input);
|
return validator(input) && op(input);
|
||||||
@@ -372,7 +399,7 @@ define([], function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true only of the given operation applies to a given type
|
* Returns true only if the given operation applies to a given type
|
||||||
* @param {string} key The key of the operation
|
* @param {string} key The key of the operation
|
||||||
* @param {string} type The value type to query
|
* @param {string} type The value type to query
|
||||||
* @returns {boolean} True if the condition applies, false otherwise
|
* @returns {boolean} True if the condition applies, false otherwise
|
||||||
|
|||||||
@@ -130,7 +130,9 @@ define ([
|
|||||||
this.telemetryTypesById[objectId] = {};
|
this.telemetryTypesById[objectId] = {};
|
||||||
Object.values(this.telemetryMetadataById[objectId]).forEach(function (valueMetadata) {
|
Object.values(this.telemetryMetadataById[objectId]).forEach(function (valueMetadata) {
|
||||||
var type;
|
var type;
|
||||||
if (valueMetadata.hints.hasOwnProperty('range')) {
|
if (valueMetadata.enumerations !== undefined) {
|
||||||
|
type = 'enum';
|
||||||
|
} else if (valueMetadata.hints.hasOwnProperty('range')) {
|
||||||
type = 'number';
|
type = 'number';
|
||||||
} else if (valueMetadata.hints.hasOwnProperty('domain')) {
|
} else if (valueMetadata.hints.hasOwnProperty('domain')) {
|
||||||
type = 'number';
|
type = 'number';
|
||||||
@@ -163,11 +165,18 @@ define ([
|
|||||||
* @param {datum} datum The new data from the telemetry source
|
* @param {datum} datum The new data from the telemetry source
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ConditionManager.prototype.handleSubscriptionCallback = function (objId, datum) {
|
ConditionManager.prototype.handleSubscriptionCallback = function (objId, telemetryDatum) {
|
||||||
this.subscriptionCache[objId] = datum;
|
this.subscriptionCache[objId] = this.createNormalizedDatum(objId, telemetryDatum);
|
||||||
this.eventEmitter.emit('receiveTelemetry');
|
this.eventEmitter.emit('receiveTelemetry');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ConditionManager.prototype.createNormalizedDatum = function (objId, telemetryDatum) {
|
||||||
|
return Object.values(this.telemetryMetadataById[objId]).reduce((normalizedDatum, metadatum) => {
|
||||||
|
normalizedDatum[metadatum.key] = telemetryDatum[metadatum.source];
|
||||||
|
return normalizedDatum;
|
||||||
|
}, {});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event handler for an add event in this Summary Widget's composition.
|
* Event handler for an add event in this Summary Widget's composition.
|
||||||
* Sets up subscription handlers and parses its property types.
|
* Sets up subscription handlers and parses its property types.
|
||||||
@@ -236,6 +245,7 @@ define ([
|
|||||||
id.namespace === identifier.namespace;
|
id.namespace === identifier.namespace;
|
||||||
});
|
});
|
||||||
delete this.compositionObjs[objectId];
|
delete this.compositionObjs[objectId];
|
||||||
|
delete this.subscriptionCache[objectId];
|
||||||
this.subscriptions[objectId](); //unsubscribe from telemetry source
|
this.subscriptions[objectId](); //unsubscribe from telemetry source
|
||||||
delete this.subscriptions[objectId];
|
delete this.subscriptions[objectId];
|
||||||
this.eventEmitter.emit('remove', identifier);
|
this.eventEmitter.emit('remove', identifier);
|
||||||
|
|||||||
@@ -110,9 +110,11 @@ define([
|
|||||||
|
|
||||||
type = self.manager.getTelemetryPropertyType(self.config.object, key);
|
type = self.manager.getTelemetryPropertyType(self.config.object, key);
|
||||||
|
|
||||||
|
if (type !== undefined) {
|
||||||
self.operationKeys = operations.filter(function (operation) {
|
self.operationKeys = operations.filter(function (operation) {
|
||||||
return self.evaluator.operationAppliesTo(operation, type);
|
return self.evaluator.operationAppliesTo(operation, type);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
OperationSelect.prototype.destroy = function () {
|
OperationSelect.prototype.destroy = function () {
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ define([
|
|||||||
return this.openmct.time.getAllTimeSystems().map(function (ts, i) {
|
return this.openmct.time.getAllTimeSystems().map(function (ts, i) {
|
||||||
return {
|
return {
|
||||||
key: ts.key,
|
key: ts.key,
|
||||||
name: 'UTC',
|
name: ts.name,
|
||||||
format: ts.timeFormat,
|
format: ts.timeFormat,
|
||||||
hints: {
|
hints: {
|
||||||
domain: i
|
domain: i
|
||||||
@@ -64,7 +64,7 @@ define([
|
|||||||
// Generally safe assumption is that we have one domain per timeSystem.
|
// Generally safe assumption is that we have one domain per timeSystem.
|
||||||
values: this.getDomains().concat([
|
values: this.getDomains().concat([
|
||||||
{
|
{
|
||||||
name: 'state',
|
name: 'State',
|
||||||
key: 'state',
|
key: 'state',
|
||||||
source: 'ruleIndex',
|
source: 'ruleIndex',
|
||||||
format: 'enum',
|
format: 'enum',
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ define([
|
|||||||
return typeof input[0] === 'undefined';
|
return typeof input[0] === 'undefined';
|
||||||
},
|
},
|
||||||
text: 'is undefined',
|
text: 'is undefined',
|
||||||
appliesTo: ['string', 'number'],
|
appliesTo: ['string', 'number', 'enum'],
|
||||||
inputCount: 0,
|
inputCount: 0,
|
||||||
getDescription: function () {
|
getDescription: function () {
|
||||||
return ' is undefined';
|
return ' is undefined';
|
||||||
@@ -185,11 +185,33 @@ define([
|
|||||||
return typeof input[0] !== 'undefined';
|
return typeof input[0] !== 'undefined';
|
||||||
},
|
},
|
||||||
text: 'is defined',
|
text: 'is defined',
|
||||||
appliesTo: ['string', 'number'],
|
appliesTo: ['string', 'number', 'enum'],
|
||||||
inputCount: 0,
|
inputCount: 0,
|
||||||
getDescription: function () {
|
getDescription: function () {
|
||||||
return ' is defined';
|
return ' is defined';
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
enumValueIs: {
|
||||||
|
operation: function (input) {
|
||||||
|
return input[0] === input[1];
|
||||||
|
},
|
||||||
|
text: 'is',
|
||||||
|
appliesTo: ['enum'],
|
||||||
|
inputCount: 1,
|
||||||
|
getDescription: function (values) {
|
||||||
|
return ' == ' + values[0];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enumValueIsNot: {
|
||||||
|
operation: function (input) {
|
||||||
|
return input[0] !== input[1];
|
||||||
|
},
|
||||||
|
text: 'is not',
|
||||||
|
appliesTo: ['enum'],
|
||||||
|
inputCount: 1,
|
||||||
|
getDescription: function (values) {
|
||||||
|
return ' != ' + values[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ define([
|
|||||||
this.filteredRows.destroy();
|
this.filteredRows.destroy();
|
||||||
Object.keys(this.subscriptions).forEach(this.unsubscribe, this);
|
Object.keys(this.subscriptions).forEach(this.unsubscribe, this);
|
||||||
this.openmct.time.off('bounds', this.refreshData);
|
this.openmct.time.off('bounds', this.refreshData);
|
||||||
this.openmct.time.on('timeSystem', this.refreshData);
|
this.openmct.time.off('timeSystem', this.refreshData);
|
||||||
if (this.filterObserver) {
|
if (this.filterObserver) {
|
||||||
this.filterObserver();
|
this.filterObserver();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ define(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
class BoundedTableRowCollection extends SortedTableRowCollection {
|
class BoundedTableRowCollection extends SortedTableRowCollection {
|
||||||
constructor (openmct) {
|
constructor(openmct) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.futureBuffer = new SortedTableRowCollection();
|
this.futureBuffer = new SortedTableRowCollection();
|
||||||
@@ -46,12 +46,13 @@ define(
|
|||||||
openmct.time.on('bounds', this.bounds);
|
openmct.time.on('bounds', this.bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
addOne (item) {
|
addOne(item) {
|
||||||
|
let parsedValue = this.getValueForSortColumn(item);
|
||||||
// Insert into either in-bounds array, or the future buffer.
|
// Insert into either in-bounds array, or the future buffer.
|
||||||
// Data in the future buffer will be re-evaluated for possible
|
// Data in the future buffer will be re-evaluated for possible
|
||||||
// insertion on next bounds change
|
// insertion on next bounds change
|
||||||
let beforeStartOfBounds = this.parseTime(item.datum[this.sortOptions.key]) < this.lastBounds.start;
|
let beforeStartOfBounds = parsedValue < this.lastBounds.start;
|
||||||
let afterEndOfBounds = this.parseTime(item.datum[this.sortOptions.key]) > this.lastBounds.end;
|
let afterEndOfBounds = parsedValue > this.lastBounds.end;
|
||||||
|
|
||||||
if (!afterEndOfBounds && !beforeStartOfBounds) {
|
if (!afterEndOfBounds && !beforeStartOfBounds) {
|
||||||
return super.addOne(item);
|
return super.addOne(item);
|
||||||
@@ -86,7 +87,7 @@ define(
|
|||||||
* @fires TelemetryCollection#discarded
|
* @fires TelemetryCollection#discarded
|
||||||
* @param bounds
|
* @param bounds
|
||||||
*/
|
*/
|
||||||
bounds (bounds) {
|
bounds(bounds) {
|
||||||
let startChanged = this.lastBounds.start !== bounds.start;
|
let startChanged = this.lastBounds.start !== bounds.start;
|
||||||
let endChanged = this.lastBounds.end !== bounds.end;
|
let endChanged = this.lastBounds.end !== bounds.end;
|
||||||
|
|
||||||
@@ -135,9 +136,13 @@ define(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getValueForSortColumn(row) {
|
||||||
|
return this.parseTime(row.datum[this.sortOptions.key]);
|
||||||
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
this.openmct.time.off('bounds', this.bounds);
|
this.openmct.time.off('bounds', this.bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return BoundedTableRowCollection;
|
return BoundedTableRowCollection;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -116,10 +116,9 @@ define(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sortOptionsKey = this.sortOptions.key;
|
const testRowValue = this.getValueForSortColumn(testRow);
|
||||||
const testRowValue = testRow.datum[sortOptionsKey];
|
const firstValue = this.getValueForSortColumn(this.rows[0]);
|
||||||
const firstValue = this.rows[0].datum[sortOptionsKey];
|
const lastValue = this.getValueForSortColumn(this.rows[this.rows.length - 1]);
|
||||||
const lastValue = this.rows[this.rows.length - 1].datum[sortOptionsKey];
|
|
||||||
|
|
||||||
lodashFunction = lodashFunction || _.sortedIndex;
|
lodashFunction = lodashFunction || _.sortedIndex;
|
||||||
|
|
||||||
@@ -133,7 +132,7 @@ define(
|
|||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return lodashFunction(rows, testRow, (thisRow) => {
|
return lodashFunction(rows, testRow, (thisRow) => {
|
||||||
return thisRow.datum[sortOptionsKey];
|
return this.getValueForSortColumn(thisRow);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -147,7 +146,7 @@ define(
|
|||||||
} else {
|
} else {
|
||||||
// Use a custom comparison function to support descending sort.
|
// Use a custom comparison function to support descending sort.
|
||||||
return lodashFunction(rows, testRow, (thisRow) => {
|
return lodashFunction(rows, testRow, (thisRow) => {
|
||||||
const thisRowValue = thisRow.datum[sortOptionsKey];
|
const thisRowValue = this.getValueForSortColumn(thisRow);
|
||||||
if (testRowValue === thisRowValue) {
|
if (testRowValue === thisRowValue) {
|
||||||
return EQUAL;
|
return EQUAL;
|
||||||
} else if (testRowValue < thisRowValue) {
|
} else if (testRowValue < thisRowValue) {
|
||||||
@@ -218,25 +217,32 @@ define(
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.emit('remove', removed);
|
this.emit('remove', removed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getValueForSortColumn(row) {
|
||||||
|
return row.datum[this.sortOptions.key];
|
||||||
|
}
|
||||||
|
|
||||||
remove(removedRows) {
|
remove(removedRows) {
|
||||||
this.rows = this.rows.filter(row => {
|
this.rows = this.rows.filter(row => {
|
||||||
return removedRows.indexOf(row) === -1;
|
return removedRows.indexOf(row) === -1;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.emit('remove', removedRows);
|
this.emit('remove', removedRows);
|
||||||
}
|
}
|
||||||
|
|
||||||
getRows () {
|
getRows() {
|
||||||
return this.rows;
|
return this.rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
let removedRows = this.rows;
|
let removedRows = this.rows;
|
||||||
this.rows = [];
|
this.rows = [];
|
||||||
|
|
||||||
this.emit('remove', removedRows);
|
this.emit('remove', removedRows);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return SortedTableRowCollection;
|
return SortedTableRowCollection;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -78,7 +78,7 @@
|
|||||||
<!-- Content table -->
|
<!-- Content table -->
|
||||||
<div class="c-table__body-w c-telemetry-table__body-w js-telemetry-table__body-w" @scroll="scroll" :style="{ 'max-width': widthWithScroll}">
|
<div class="c-table__body-w c-telemetry-table__body-w js-telemetry-table__body-w" @scroll="scroll" :style="{ 'max-width': widthWithScroll}">
|
||||||
<div class="c-telemetry-table__scroll-forcer" :style="{ width: totalWidth + 'px' }"></div>
|
<div class="c-telemetry-table__scroll-forcer" :style="{ width: totalWidth + 'px' }"></div>
|
||||||
<table class="c-table__body c-telemetry-table__body"
|
<table class="c-table__body c-telemetry-table__body js-telemetry-table__content"
|
||||||
:style="{ height: totalHeight + 'px'}">
|
:style="{ height: totalHeight + 'px'}">
|
||||||
<tbody>
|
<tbody>
|
||||||
<telemetry-table-row v-for="(row, rowIndex) in visibleRows"
|
<telemetry-table-row v-for="(row, rowIndex) in visibleRows"
|
||||||
@@ -284,7 +284,7 @@ import _ from 'lodash';
|
|||||||
const VISIBLE_ROW_COUNT = 100;
|
const VISIBLE_ROW_COUNT = 100;
|
||||||
const ROW_HEIGHT = 17;
|
const ROW_HEIGHT = 17;
|
||||||
const RESIZE_POLL_INTERVAL = 200;
|
const RESIZE_POLL_INTERVAL = 200;
|
||||||
const AUTO_SCROLL_TRIGGER_HEIGHT = 20;
|
const AUTO_SCROLL_TRIGGER_HEIGHT = 100;
|
||||||
const RESIZE_HOT_ZONE = 10;
|
const RESIZE_HOT_ZONE = 10;
|
||||||
const MOVE_TRIGGER_WAIT = 500;
|
const MOVE_TRIGGER_WAIT = 500;
|
||||||
const VERTICAL_SCROLL_WIDTH = 30;
|
const VERTICAL_SCROLL_WIDTH = 30;
|
||||||
@@ -364,14 +364,15 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
updateVisibleRows() {
|
updateVisibleRows() {
|
||||||
|
if (!this.updatingView) {
|
||||||
|
this.updatingView = true;
|
||||||
|
requestAnimationFrame(()=> {
|
||||||
|
|
||||||
let start = 0;
|
let start = 0;
|
||||||
let end = VISIBLE_ROW_COUNT;
|
let end = VISIBLE_ROW_COUNT;
|
||||||
let filteredRows = this.table.filteredRows.getRows();
|
let filteredRows = this.table.filteredRows.getRows();
|
||||||
let filteredRowsLength = filteredRows.length;
|
let filteredRowsLength = filteredRows.length;
|
||||||
|
|
||||||
this.totalHeight = this.rowHeight * filteredRowsLength - 1;
|
|
||||||
|
|
||||||
if (filteredRowsLength < VISIBLE_ROW_COUNT) {
|
if (filteredRowsLength < VISIBLE_ROW_COUNT) {
|
||||||
end = filteredRowsLength;
|
end = filteredRowsLength;
|
||||||
} else {
|
} else {
|
||||||
@@ -393,13 +394,18 @@ export default {
|
|||||||
}
|
}
|
||||||
this.rowOffset = start;
|
this.rowOffset = start;
|
||||||
this.visibleRows = filteredRows.slice(start, end);
|
this.visibleRows = filteredRows.slice(start, end);
|
||||||
|
|
||||||
|
this.updatingView = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
calculateFirstVisibleRow() {
|
calculateFirstVisibleRow() {
|
||||||
return Math.floor(this.scrollable.scrollTop / this.rowHeight);
|
let scrollTop = this.scrollable.scrollTop;
|
||||||
|
return Math.floor(scrollTop / this.rowHeight);
|
||||||
},
|
},
|
||||||
calculateLastVisibleRow() {
|
calculateLastVisibleRow() {
|
||||||
let bottomScroll = this.scrollable.scrollTop + this.scrollable.offsetHeight;
|
let scrollBottom = this.scrollable.scrollTop + this.scrollable.offsetHeight;
|
||||||
return Math.floor(bottomScroll / this.rowHeight);
|
return Math.ceil(scrollBottom / this.rowHeight);
|
||||||
},
|
},
|
||||||
updateHeaders() {
|
updateHeaders() {
|
||||||
this.headers = this.table.configuration.getVisibleHeaders();
|
this.headers = this.table.configuration.getVisibleHeaders();
|
||||||
@@ -443,10 +449,7 @@ export default {
|
|||||||
}
|
}
|
||||||
this.table.sortBy(this.sortOptions);
|
this.table.sortBy(this.sortOptions);
|
||||||
},
|
},
|
||||||
scroll() {
|
scroll () {
|
||||||
if (!this.processingScroll) {
|
|
||||||
this.processingScroll = true;
|
|
||||||
requestAnimationFrame(()=> {
|
|
||||||
this.updateVisibleRows();
|
this.updateVisibleRows();
|
||||||
this.synchronizeScrollX();
|
this.synchronizeScrollX();
|
||||||
|
|
||||||
@@ -457,57 +460,59 @@ export default {
|
|||||||
// Auto-scroll will be re-enabled if user scrolls to bottom again.
|
// Auto-scroll will be re-enabled if user scrolls to bottom again.
|
||||||
this.autoScroll = false;
|
this.autoScroll = false;
|
||||||
}
|
}
|
||||||
this.processingScroll = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
shouldSnapToBottom() {
|
shouldSnapToBottom() {
|
||||||
return this.scrollable.scrollTop >= (this.scrollable.scrollHeight - this.scrollable.offsetHeight - AUTO_SCROLL_TRIGGER_HEIGHT);
|
return this.scrollable.scrollTop >= (this.scrollable.scrollHeight - this.scrollable.offsetHeight - AUTO_SCROLL_TRIGGER_HEIGHT);
|
||||||
},
|
},
|
||||||
scrollToBottom() {
|
scrollToBottom() {
|
||||||
this.scrollable.scrollTop = this.scrollable.scrollHeight;
|
this.scrollable.scrollTop = Number.MAX_SAFE_INTEGER;
|
||||||
},
|
},
|
||||||
synchronizeScrollX() {
|
synchronizeScrollX() {
|
||||||
this.headersHolderEl.scrollLeft = this.scrollable.scrollLeft;
|
this.headersHolderEl.scrollLeft = this.scrollable.scrollLeft;
|
||||||
},
|
},
|
||||||
filterChanged(columnKey) {
|
filterChanged(columnKey) {
|
||||||
this.table.filteredRows.setColumnFilter(columnKey, this.filters[columnKey]);
|
this.table.filteredRows.setColumnFilter(columnKey, this.filters[columnKey]);
|
||||||
|
this.setHeight();
|
||||||
},
|
},
|
||||||
clearFilter(columnKey) {
|
clearFilter(columnKey) {
|
||||||
this.filters[columnKey] = '';
|
this.filters[columnKey] = '';
|
||||||
this.table.filteredRows.setColumnFilter(columnKey, '');
|
this.table.filteredRows.setColumnFilter(columnKey, '');
|
||||||
|
this.setHeight();
|
||||||
},
|
},
|
||||||
rowsAdded(rows) {
|
rowsAdded (rows) {
|
||||||
|
this.setHeight();
|
||||||
|
|
||||||
let sizingRow;
|
let sizingRow;
|
||||||
if (Array.isArray(rows)) {
|
if (Array.isArray(rows)) {
|
||||||
sizingRow = rows[0];
|
sizingRow = rows[0];
|
||||||
} else {
|
} else {
|
||||||
sizingRow = rows;
|
sizingRow = rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.sizingRows[sizingRow.objectKeyString]) {
|
if (!this.sizingRows[sizingRow.objectKeyString]) {
|
||||||
this.sizingRows[sizingRow.objectKeyString] = sizingRow;
|
this.sizingRows[sizingRow.objectKeyString] = sizingRow;
|
||||||
this.$nextTick().then(this.calculateColumnWidths);
|
this.$nextTick().then(this.calculateColumnWidths);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.updatingView) {
|
|
||||||
this.updatingView = true;
|
|
||||||
requestAnimationFrame(()=> {
|
|
||||||
this.updateVisibleRows();
|
|
||||||
if (this.autoScroll) {
|
if (this.autoScroll) {
|
||||||
this.$nextTick().then(this.scrollToBottom);
|
this.scrollToBottom();
|
||||||
}
|
}
|
||||||
this.updatingView = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
rowsRemoved(rows) {
|
|
||||||
if (!this.updatingView) {
|
|
||||||
this.updatingView = true;
|
|
||||||
requestAnimationFrame(()=> {
|
|
||||||
this.updateVisibleRows();
|
this.updateVisibleRows();
|
||||||
this.updatingView = false;
|
},
|
||||||
});
|
rowsRemoved (rows) {
|
||||||
}
|
this.setHeight();
|
||||||
|
this.updateVisibleRows();
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Calculates height based on total number of rows, and sets table height.
|
||||||
|
*/
|
||||||
|
setHeight() {
|
||||||
|
let filteredRowsLength = this.table.filteredRows.getRows().length;
|
||||||
|
this.totalHeight = this.rowHeight * filteredRowsLength - 1;
|
||||||
|
// Set element height directly to avoid having to wait for Vue to update DOM
|
||||||
|
// which causes subsequent scroll to use an out of date height.
|
||||||
|
this.contentTable.style.height = this.totalHeight + 'px';
|
||||||
},
|
},
|
||||||
exportAsCSV() {
|
exportAsCSV() {
|
||||||
const headerKeys = Object.keys(this.headers);
|
const headerKeys = Object.keys(this.headers);
|
||||||
@@ -595,7 +600,11 @@ export default {
|
|||||||
this.calculateTableSize();
|
this.calculateTableSize();
|
||||||
// On some resize events scrollTop is reset to 0. Possibly due to a transition we're using?
|
// On some resize events scrollTop is reset to 0. Possibly due to a transition we're using?
|
||||||
// Need to preserve scroll position in this case.
|
// Need to preserve scroll position in this case.
|
||||||
|
if (this.autoScroll) {
|
||||||
|
this.scrollToBottom();
|
||||||
|
} else {
|
||||||
this.scrollable.scrollTop = scrollTop;
|
this.scrollable.scrollTop = scrollTop;
|
||||||
|
}
|
||||||
width = el.clientWidth;
|
width = el.clientWidth;
|
||||||
height = el.clientHeight;
|
height = el.clientHeight;
|
||||||
}
|
}
|
||||||
@@ -608,6 +617,9 @@ export default {
|
|||||||
this.filterChanged = _.debounce(this.filterChanged, 500);
|
this.filterChanged = _.debounce(this.filterChanged, 500);
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
this.rowsAdded = _.throttle(this.rowsAdded, 200);
|
||||||
|
this.rowsRemoved = _.throttle(this.rowsRemoved, 200);
|
||||||
|
this.scroll = _.throttle(this.scroll, 100);
|
||||||
|
|
||||||
this.table.on('object-added', this.addObject);
|
this.table.on('object-added', this.addObject);
|
||||||
this.table.on('object-removed', this.removeObject);
|
this.table.on('object-removed', this.removeObject);
|
||||||
@@ -621,6 +633,7 @@ export default {
|
|||||||
//Default sort
|
//Default sort
|
||||||
this.sortOptions = this.table.filteredRows.sortBy();
|
this.sortOptions = this.table.filteredRows.sortBy();
|
||||||
this.scrollable = this.$el.querySelector('.js-telemetry-table__body-w');
|
this.scrollable = this.$el.querySelector('.js-telemetry-table__body-w');
|
||||||
|
this.contentTable = this.$el.querySelector('.js-telemetry-table__content');
|
||||||
this.sizingTable = this.$el.querySelector('.js-telemetry-table__sizing');
|
this.sizingTable = this.$el.querySelector('.js-telemetry-table__sizing');
|
||||||
this.headersHolderEl = this.$el.querySelector('.js-table__headers-w');
|
this.headersHolderEl = this.$el.querySelector('.js-table__headers-w');
|
||||||
|
|
||||||
|
|||||||
@@ -54,10 +54,11 @@
|
|||||||
|
|
||||||
&:after {
|
&:after {
|
||||||
// App logo
|
// App logo
|
||||||
top: 0;
|
$d: 25%;
|
||||||
right: 15%;
|
top: $d;
|
||||||
bottom: 0;
|
right: $d;
|
||||||
left: 15%;
|
bottom: $d;
|
||||||
|
left: $d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,12 +76,20 @@
|
|||||||
|
|
||||||
&__image,
|
&__image,
|
||||||
&__text {
|
&__text {
|
||||||
height: 50%;
|
flex: 1 1 auto;
|
||||||
flex: 1 1 0;
|
}
|
||||||
|
|
||||||
|
&__image {
|
||||||
|
height: 35%;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__text {
|
&__text {
|
||||||
|
height: 65%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
> * + * {
|
||||||
|
border-top: 1px solid $colorInteriorBorder;
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&--licenses {
|
&--licenses {
|
||||||
@@ -107,7 +116,7 @@
|
|||||||
|
|
||||||
h1, h2, h3 {
|
h1, h2, h3 {
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
margin-bottom: 1em;
|
margin-bottom: .25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
|
|||||||
@@ -393,6 +393,11 @@ select {
|
|||||||
color: $colorMenuIc;
|
color: $colorMenuIc;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
margin-right: $interiorMargin;
|
margin-right: $interiorMargin;
|
||||||
|
min-width: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not([class]):before {
|
||||||
|
content: ''; // Add this element so that menu items without an icon still indent properly
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,3 +33,4 @@
|
|||||||
@import "table";
|
@import "table";
|
||||||
@import "legacy";
|
@import "legacy";
|
||||||
@import "legacy-plots";
|
@import "legacy-plots";
|
||||||
|
@import "legacy-messages";
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ export default {
|
|||||||
this.currentObject = this.object;
|
this.currentObject = this.object;
|
||||||
this.updateView();
|
this.updateView();
|
||||||
this.$el.addEventListener('dragover', this.onDragOver);
|
this.$el.addEventListener('dragover', this.onDragOver);
|
||||||
this.$el.addEventListener('drop', this.addObjectToParent);
|
|
||||||
this.$el.addEventListener('drop', this.editIfEditable, {
|
this.$el.addEventListener('drop', this.editIfEditable, {
|
||||||
capture: true
|
capture: true
|
||||||
});
|
});
|
||||||
|
this.$el.addEventListener('drop', this.addObjectToParent);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
clear() {
|
clear() {
|
||||||
@@ -57,6 +57,10 @@ export default {
|
|||||||
this.removeSelectable();
|
this.removeSelectable();
|
||||||
delete this.removeSelectable;
|
delete this.removeSelectable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.composition) {
|
||||||
|
this.composition._destroy();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
invokeEditModeHandler(editMode) {
|
invokeEditModeHandler(editMode) {
|
||||||
this.currentView.onEditModeChange(editMode);
|
this.currentView.onEditModeChange(editMode);
|
||||||
@@ -70,6 +74,13 @@ export default {
|
|||||||
if (!this.currentObject) {
|
if (!this.currentObject) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.composition = this.openmct.composition.get(this.currentObject);
|
||||||
|
if (this.composition) {
|
||||||
|
this.composition._synchronize();
|
||||||
|
this.loadComposition();
|
||||||
|
}
|
||||||
|
|
||||||
this.viewContainer = document.createElement('div');
|
this.viewContainer = document.createElement('div');
|
||||||
this.viewContainer.classList.add('c-object-view','u-contents');
|
this.viewContainer.classList.add('c-object-view','u-contents');
|
||||||
this.$el.append(this.viewContainer);
|
this.$el.append(this.viewContainer);
|
||||||
@@ -112,6 +123,10 @@ export default {
|
|||||||
delete this.removeSelectable;
|
delete this.removeSelectable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.composition) {
|
||||||
|
this.composition._destroy();
|
||||||
|
}
|
||||||
|
|
||||||
this.currentObject = object;
|
this.currentObject = object;
|
||||||
this.unlisten = this.openmct.objects.observe(this.currentObject, '*', (mutatedObject) => {
|
this.unlisten = this.openmct.objects.observe(this.currentObject, '*', (mutatedObject) => {
|
||||||
this.currentObject = mutatedObject;
|
this.currentObject = mutatedObject;
|
||||||
@@ -120,6 +135,9 @@ export default {
|
|||||||
this.viewKey = viewKey;
|
this.viewKey = viewKey;
|
||||||
this.updateView(immediatelySelect);
|
this.updateView(immediatelySelect);
|
||||||
},
|
},
|
||||||
|
loadComposition() {
|
||||||
|
return this.composition.load();
|
||||||
|
},
|
||||||
getSelectionContext() {
|
getSelectionContext() {
|
||||||
if (this.currentView.getSelectionContext) {
|
if (this.currentView.getSelectionContext) {
|
||||||
return this.currentView.getSelectionContext();
|
return this.currentView.getSelectionContext();
|
||||||
@@ -133,10 +151,12 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
addObjectToParent(event) {
|
addObjectToParent(event) {
|
||||||
if (this.hasComposableDomainObject(event)) {
|
if (this.hasComposableDomainObject(event) && this.composition) {
|
||||||
let composableDomainObject = this.getComposableDomainObject(event);
|
let composableDomainObject = this.getComposableDomainObject(event);
|
||||||
this.currentObject.composition.push(composableDomainObject.identifier);
|
this.loadComposition().then(() => {
|
||||||
this.openmct.objects.mutate(this.currentObject, 'composition', this.currentObject.composition);
|
this.composition.add(composableDomainObject);
|
||||||
|
});
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
}
|
}
|
||||||
@@ -155,6 +175,7 @@ export default {
|
|||||||
editIfEditable(event) {
|
editIfEditable(event) {
|
||||||
let provider = this.getViewProvider();
|
let provider = this.getViewProvider();
|
||||||
if (provider &&
|
if (provider &&
|
||||||
|
provider.canEdit &&
|
||||||
provider.canEdit(this.currentObject) &&
|
provider.canEdit(this.currentObject) &&
|
||||||
!this.openmct.editor.isEditing()) {
|
!this.openmct.editor.isEditing()) {
|
||||||
this.openmct.editor.edit();
|
this.openmct.editor.edit();
|
||||||
|
|||||||
@@ -25,10 +25,6 @@ import _ from 'lodash';
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
updateSelection(selection) {
|
updateSelection(selection) {
|
||||||
if (_.isEqual(this.selection, selection)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.selection = selection;
|
this.selection = selection;
|
||||||
|
|
||||||
if (this.selectedViews) {
|
if (this.selectedViews) {
|
||||||
@@ -38,10 +34,6 @@ import _ from 'lodash';
|
|||||||
this.$el.innerHTML = '';
|
this.$el.innerHTML = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selection.length > 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.selectedViews = this.openmct.inspectorViews.get(selection);
|
this.selectedViews = this.openmct.inspectorViews.get(selection);
|
||||||
this.selectedViews.forEach(selectedView => {
|
this.selectedViews.forEach(selectedView => {
|
||||||
let viewContainer = document.createElement('div');
|
let viewContainer = document.createElement('div');
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="c-about c-about--splash">
|
<div class="c-about c-about--splash">
|
||||||
<div v-if="!branding.aboutHtml" class="c-about__image c-splash-image"></div>
|
<div class="c-about__image c-splash-image"></div>
|
||||||
|
|
||||||
<div class="c-about__text s-text">
|
<div class="c-about__text s-text">
|
||||||
<div v-if="branding.aboutHtml" class="s-text l-content" v-html="branding.aboutHtml"></div>
|
<div class="c-about__text__element" v-if="branding.aboutHtml" v-html="branding.aboutHtml"></div>
|
||||||
|
<div class="c-about__text__element">
|
||||||
<h1 class="l-title s-title">Open MCT</h1>
|
<h1 class="l-title s-title">Open MCT</h1>
|
||||||
<div class="l-description s-description">
|
<div class="l-description s-description">
|
||||||
<p>Open MCT, Copyright © 2014-2019, United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All rights reserved.</p>
|
<p>Open MCT, Copyright © 2014-2019, United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All rights reserved.</p>
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
<li>Branch: {{buildInfo.branch || 'Unknown'}}</li>
|
<li>Branch: {{buildInfo.branch || 'Unknown'}}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@@ -70,17 +70,18 @@
|
|||||||
this.domainObject = newObject;
|
this.domainObject = newObject;
|
||||||
});
|
});
|
||||||
this.$once('hook:destroyed', removeListener);
|
this.$once('hook:destroyed', removeListener);
|
||||||
|
|
||||||
if (this.openmct.composition.get(this.node.object)) {
|
if (this.openmct.composition.get(this.node.object)) {
|
||||||
this.hasChildren = true;
|
this.hasChildren = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.openmct.router.on('change:path', this.highlightIfNavigated);
|
this.openmct.router.on('change:path', this.highlightIfNavigated);
|
||||||
},
|
},
|
||||||
destroy() {
|
destroyed() {
|
||||||
|
this.openmct.router.off('change:path', this.highlightIfNavigated);
|
||||||
if (this.composition) {
|
if (this.composition) {
|
||||||
this.composition.off('add', this.addChild);
|
this.composition.off('add', this.addChild);
|
||||||
this.composition.off('remove', this.removeChild);
|
this.composition.off('remove', this.removeChild);
|
||||||
this.openmct.router.off('change:path', this.highlightIfNavigated);
|
|
||||||
delete this.composition;
|
delete this.composition;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export default {
|
|||||||
|
|
||||||
this.objectPath.forEach(object => {
|
this.objectPath.forEach(object => {
|
||||||
if (object) {
|
if (object) {
|
||||||
this.$once('hook:destroy',
|
this.$once('hook:destroyed',
|
||||||
this.openmct.objects.observe(object, '*', updateObject.bind(this, object)))
|
this.openmct.objects.observe(object, '*', updateObject.bind(this, object)))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -116,7 +116,7 @@
|
|||||||
this.notebookEnabled = true;
|
this.notebookEnabled = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
destroy() {
|
destroyed() {
|
||||||
this.view.destroy();
|
this.view.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ const webpackConfig = {
|
|||||||
"bourbon": "bourbon.scss",
|
"bourbon": "bourbon.scss",
|
||||||
"vue": path.join(__dirname, "node_modules/vue/dist/vue.js"),
|
"vue": path.join(__dirname, "node_modules/vue/dist/vue.js"),
|
||||||
"d3-scale": path.join(__dirname, "node_modules/d3-scale/build/d3-scale.min.js"),
|
"d3-scale": path.join(__dirname, "node_modules/d3-scale/build/d3-scale.min.js"),
|
||||||
|
"printj": path.join(__dirname, "node_modules/printj/dist/printj.min.js"),
|
||||||
"styles": path.join(__dirname, "src/styles-new")
|
"styles": path.join(__dirname, "src/styles-new")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user