mirror of
https://github.com/nasa/openmct.git
synced 2025-06-16 22:28:13 +00:00
Initial functional view API implementation. See #1642
This commit is contained in:
16
src/MCT.js
16
src/MCT.js
@ -106,9 +106,9 @@ define([
|
|||||||
*
|
*
|
||||||
* @type {module:openmct.ViewRegistry}
|
* @type {module:openmct.ViewRegistry}
|
||||||
* @memberof module:openmct.MCT#
|
* @memberof module:openmct.MCT#
|
||||||
* @name mainViews
|
* @name objectViews
|
||||||
*/
|
*/
|
||||||
this.mainViews = new ViewRegistry();
|
this.objectViews = new ViewRegistry();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registry for views which should appear in the Inspector area.
|
* Registry for views which should appear in the Inspector area.
|
||||||
@ -255,6 +255,18 @@ define([
|
|||||||
this.legacyExtension('types', legacyDefinition);
|
this.legacyExtension('types', legacyDefinition);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
|
this.objectViews.getAllProviders().forEach(function (p) {
|
||||||
|
this.legacyExtension('views', {
|
||||||
|
key: p.key,
|
||||||
|
provider: p,
|
||||||
|
name: p.name,
|
||||||
|
cssClass: p.cssClass,
|
||||||
|
description: p.description,
|
||||||
|
editable: p.editable,
|
||||||
|
template: '<mct-view mct-provider-key="' + p.key + '"/>'
|
||||||
|
});
|
||||||
|
}, this);
|
||||||
|
|
||||||
legacyRegistry.register('adapter', this.legacyBundle);
|
legacyRegistry.register('adapter', this.legacyBundle);
|
||||||
legacyRegistry.enable('adapter');
|
legacyRegistry.enable('adapter');
|
||||||
/**
|
/**
|
||||||
|
@ -24,7 +24,6 @@ define([
|
|||||||
'legacyRegistry',
|
'legacyRegistry',
|
||||||
'./actions/ActionDialogDecorator',
|
'./actions/ActionDialogDecorator',
|
||||||
'./capabilities/AdapterCapability',
|
'./capabilities/AdapterCapability',
|
||||||
'./controllers/AdaptedViewController',
|
|
||||||
'./directives/MCTView',
|
'./directives/MCTView',
|
||||||
'./services/Instantiate',
|
'./services/Instantiate',
|
||||||
'./services/MissingModelCompatibilityDecorator',
|
'./services/MissingModelCompatibilityDecorator',
|
||||||
@ -32,13 +31,11 @@ define([
|
|||||||
'./policies/AdapterCompositionPolicy',
|
'./policies/AdapterCompositionPolicy',
|
||||||
'./policies/AdaptedViewPolicy',
|
'./policies/AdaptedViewPolicy',
|
||||||
'./runs/AlternateCompositionInitializer',
|
'./runs/AlternateCompositionInitializer',
|
||||||
'./runs/TimeSettingsURLHandler',
|
'./runs/TimeSettingsURLHandler'
|
||||||
'text!./templates/adapted-view-template.html'
|
|
||||||
], function (
|
], function (
|
||||||
legacyRegistry,
|
legacyRegistry,
|
||||||
ActionDialogDecorator,
|
ActionDialogDecorator,
|
||||||
AdapterCapability,
|
AdapterCapability,
|
||||||
AdaptedViewController,
|
|
||||||
MCTView,
|
MCTView,
|
||||||
Instantiate,
|
Instantiate,
|
||||||
MissingModelCompatibilityDecorator,
|
MissingModelCompatibilityDecorator,
|
||||||
@ -46,15 +43,15 @@ define([
|
|||||||
AdapterCompositionPolicy,
|
AdapterCompositionPolicy,
|
||||||
AdaptedViewPolicy,
|
AdaptedViewPolicy,
|
||||||
AlternateCompositionInitializer,
|
AlternateCompositionInitializer,
|
||||||
TimeSettingsURLHandler,
|
TimeSettingsURLHandler
|
||||||
adaptedViewTemplate
|
|
||||||
) {
|
) {
|
||||||
legacyRegistry.register('src/adapter', {
|
legacyRegistry.register('src/adapter', {
|
||||||
"extensions": {
|
"extensions": {
|
||||||
"directives": [
|
"directives": [
|
||||||
{
|
{
|
||||||
key: "mctView",
|
key: "mctView",
|
||||||
implementation: MCTView
|
implementation: MCTView,
|
||||||
|
depends: ["openmct"]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
capabilities: [
|
capabilities: [
|
||||||
@ -63,16 +60,6 @@ define([
|
|||||||
implementation: AdapterCapability
|
implementation: AdapterCapability
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
controllers: [
|
|
||||||
{
|
|
||||||
key: "AdaptedViewController",
|
|
||||||
implementation: AdaptedViewController,
|
|
||||||
depends: [
|
|
||||||
'$scope',
|
|
||||||
'openmct'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
services: [
|
services: [
|
||||||
{
|
{
|
||||||
key: "instantiate",
|
key: "instantiate",
|
||||||
@ -135,12 +122,6 @@ define([
|
|||||||
depends: ["openmct", "$location", "$rootScope"]
|
depends: ["openmct", "$location", "$rootScope"]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
views: [
|
|
||||||
{
|
|
||||||
key: "adapted-view",
|
|
||||||
template: adaptedViewTemplate
|
|
||||||
}
|
|
||||||
],
|
|
||||||
licenses: [
|
licenses: [
|
||||||
{
|
{
|
||||||
"name": "almond",
|
"name": "almond",
|
||||||
|
@ -22,10 +22,12 @@
|
|||||||
|
|
||||||
define([
|
define([
|
||||||
'./synchronizeMutationCapability',
|
'./synchronizeMutationCapability',
|
||||||
'./AlternateCompositionCapability'
|
'./AlternateCompositionCapability',
|
||||||
|
'./patchViewCapability'
|
||||||
], function (
|
], function (
|
||||||
synchronizeMutationCapability,
|
synchronizeMutationCapability,
|
||||||
AlternateCompositionCapability
|
AlternateCompositionCapability,
|
||||||
|
patchViewCapability
|
||||||
) {
|
) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,6 +48,9 @@ define([
|
|||||||
capabilities.mutation =
|
capabilities.mutation =
|
||||||
synchronizeMutationCapability(capabilities.mutation);
|
synchronizeMutationCapability(capabilities.mutation);
|
||||||
}
|
}
|
||||||
|
if (capabilities.view) {
|
||||||
|
capabilities.view = patchViewCapability(capabilities.view);
|
||||||
|
}
|
||||||
if (AlternateCompositionCapability.appliesTo(model, id)) {
|
if (AlternateCompositionCapability.appliesTo(model, id)) {
|
||||||
capabilities.composition = function (domainObject) {
|
capabilities.composition = function (domainObject) {
|
||||||
return new AlternateCompositionCapability(this.$injector, domainObject);
|
return new AlternateCompositionCapability(this.$injector, domainObject);
|
||||||
|
@ -20,21 +20,41 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
define([], function () {
|
define([
|
||||||
function AdaptedViewController($scope, openmct) {
|
'lodash'
|
||||||
function refresh(legacyObject) {
|
], function (
|
||||||
if (!legacyObject) {
|
_
|
||||||
$scope.view = undefined;
|
) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var domainObject = legacyObject.useCapability('adapter');
|
function patchViewCapability(viewConstructor) {
|
||||||
var providers = openmct.mainViews.get(domainObject);
|
return function makeCapability(domainObject) {
|
||||||
$scope.view = providers[0] && providers[0].view(domainObject);
|
var capability = viewConstructor(domainObject);
|
||||||
}
|
var oldInvoke = capability.invoke.bind(capability);
|
||||||
|
|
||||||
$scope.$watch('domainObject', refresh);
|
capability.invoke = function () {
|
||||||
|
var availableViews = oldInvoke();
|
||||||
|
var newDomainObject = capability
|
||||||
|
.domainObject
|
||||||
|
.useCapability('adapter');
|
||||||
|
|
||||||
|
return _(availableViews).map(function (v, i) {
|
||||||
|
var vd = {
|
||||||
|
view: v,
|
||||||
|
priority: i + 100 // arbitrary to allow new views to
|
||||||
|
// be defaults by returning priority less than 100.
|
||||||
|
};
|
||||||
|
if (v.provider && v.provider.priority) {
|
||||||
|
vd.priority = v.provider.priority(newDomainObject);
|
||||||
|
}
|
||||||
|
return vd;
|
||||||
|
})
|
||||||
|
.sortBy('priority')
|
||||||
|
.map('view')
|
||||||
|
.value();
|
||||||
|
};
|
||||||
|
return capability;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return AdaptedViewController;
|
return patchViewCapability;
|
||||||
});
|
});
|
@ -21,19 +21,23 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
define([
|
define([
|
||||||
'angular',
|
|
||||||
'./Region'
|
|
||||||
], function (
|
], function (
|
||||||
angular,
|
|
||||||
Region
|
|
||||||
) {
|
) {
|
||||||
function MCTView() {
|
function MCTView(openmct) {
|
||||||
return {
|
return {
|
||||||
restrict: 'A',
|
restrict: 'E',
|
||||||
link: function (scope, element, attrs) {
|
link: function (scope, element, attrs) {
|
||||||
var region = new Region(element[0]);
|
var provider = openmct.objectViews.getByProviderKey(attrs.mctProviderKey);
|
||||||
scope.$watch(attrs.mctView, region.show.bind(region));
|
var view = new provider.view(scope.domainObject.useCapability('adapter'));
|
||||||
scope.$on("$destroy", region.clear.bind(region));
|
var domElement = element[0];
|
||||||
|
|
||||||
|
view.show(domElement);
|
||||||
|
|
||||||
|
if (view.destroy) {
|
||||||
|
scope.$on('$destroy', function () {
|
||||||
|
view.destroy(domElement);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2017, 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 () {
|
|
||||||
function Region(element) {
|
|
||||||
this.activeView = undefined;
|
|
||||||
this.element = element;
|
|
||||||
}
|
|
||||||
|
|
||||||
Region.prototype.clear = function () {
|
|
||||||
if (this.activeView) {
|
|
||||||
this.activeView.destroy();
|
|
||||||
this.activeView = undefined;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Region.prototype.show = function (view) {
|
|
||||||
this.clear();
|
|
||||||
this.activeView = view;
|
|
||||||
if (this.activeView) {
|
|
||||||
this.activeView.show(this.element);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return Region;
|
|
||||||
});
|
|
@ -29,9 +29,9 @@ define([], function () {
|
|||||||
view,
|
view,
|
||||||
legacyObject
|
legacyObject
|
||||||
) {
|
) {
|
||||||
if (view.key === 'adapted-view') {
|
if (view.hasOwnProperty('provider')) {
|
||||||
var domainObject = legacyObject.useCapability('adapter');
|
var domainObject = legacyObject.useCapability('adapter');
|
||||||
return this.openmct.mainViews.get(domainObject).length > 0;
|
return view.provider.canView(domainObject);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
* this source code distribution or the Licensing information page available
|
* this source code distribution or the Licensing information page available
|
||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
/*global console */
|
||||||
|
|
||||||
define([], function () {
|
define([], function () {
|
||||||
/**
|
/**
|
||||||
@ -28,7 +29,7 @@ define([], function () {
|
|||||||
* @memberof module:openmct
|
* @memberof module:openmct
|
||||||
*/
|
*/
|
||||||
function ViewRegistry() {
|
function ViewRegistry() {
|
||||||
this.providers = [];
|
this.providers = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -39,9 +40,17 @@ define([], function () {
|
|||||||
* which can provide views of this object
|
* which can provide views of this object
|
||||||
*/
|
*/
|
||||||
ViewRegistry.prototype.get = function (item) {
|
ViewRegistry.prototype.get = function (item) {
|
||||||
return this.providers.filter(function (provider) {
|
return this.getAllProviders()
|
||||||
return provider.canView(item);
|
.filter(function (provider) {
|
||||||
});
|
return provider.canView(item);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ViewRegistry.prototype.getAllProviders = function () {
|
||||||
|
return Object.values(this.providers);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,7 +61,22 @@ define([], function () {
|
|||||||
* @memberof module:openmct.ViewRegistry#
|
* @memberof module:openmct.ViewRegistry#
|
||||||
*/
|
*/
|
||||||
ViewRegistry.prototype.addProvider = function (provider) {
|
ViewRegistry.prototype.addProvider = function (provider) {
|
||||||
this.providers.push(provider);
|
var key = provider.key;
|
||||||
|
if (key === undefined) {
|
||||||
|
throw "View providers must have a unique 'key' property defined";
|
||||||
|
}
|
||||||
|
if (this.providers[key] !== undefined) {
|
||||||
|
console.warn("Provider already defined for key '%s'. Provider keys must be unique.", key);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.providers[key] = provider;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ViewRegistry.prototype.getByProviderKey = function (key) {
|
||||||
|
return this.providers[key];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -91,6 +115,12 @@ define([], function () {
|
|||||||
* Exposes types of views in Open MCT.
|
* Exposes types of views in Open MCT.
|
||||||
*
|
*
|
||||||
* @interface ViewProvider
|
* @interface ViewProvider
|
||||||
|
* @property {string} key a unique identifier for this view
|
||||||
|
* @property {string} name the human-readable name of this view
|
||||||
|
* @property {string} [description] a longer-form description (typically
|
||||||
|
* a single sentence or short paragraph) of this kind of view
|
||||||
|
* @property {string} [cssClass] the CSS class to apply to labels for this
|
||||||
|
* view (to add icons, for instance)
|
||||||
* @memberof module:openmct
|
* @memberof module:openmct
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -100,15 +130,28 @@ define([], function () {
|
|||||||
* When called by Open MCT, this may include additional arguments
|
* When called by Open MCT, this may include additional arguments
|
||||||
* which are on the path to the object to be viewed; for instance,
|
* which are on the path to the object to be viewed; for instance,
|
||||||
* when viewing "A Folder" within "My Items", this method will be
|
* when viewing "A Folder" within "My Items", this method will be
|
||||||
* invoked with "A Folder" (as a domain object) as the first argument,
|
* invoked with "A Folder" (as a domain object) as the first argument
|
||||||
* and "My Items" as the second argument.
|
|
||||||
*
|
*
|
||||||
* @method canView
|
* @method canView
|
||||||
* @memberof module:openmct.ViewProvider#
|
* @memberof module:openmct.ViewProvider#
|
||||||
* @param {module:openmct.DomainObject} domainObject the domain object
|
* @param {module:openmct.DomainObject} domainObject the domain object
|
||||||
* to be viewed
|
* to be viewed
|
||||||
* @returns {boolean} true if this domain object can be viewed using
|
* @returns {boolean} 'true' if the view applies to the provided object,
|
||||||
* this provider
|
* otherwise 'false'.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional method determining the priority of a given view. If this
|
||||||
|
* function is not defined on a view provider, then a default priority
|
||||||
|
* of 100 will be applicable for all objects supported by this view.
|
||||||
|
*
|
||||||
|
* @method priority
|
||||||
|
* @memberof module:openmct.ViewProvider#
|
||||||
|
* @param {module:openmct.DomainObject} domainObject the domain object
|
||||||
|
* to be viewed
|
||||||
|
* @returns {number} The priority of the view. If multiple views could apply
|
||||||
|
* to an object, the view that returns the lowest number will be
|
||||||
|
* the default view.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -126,27 +169,6 @@ define([], function () {
|
|||||||
* @returns {module:openmct.View} a view of this domain object
|
* @returns {module:openmct.View} a view of this domain object
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* Get metadata associated with this view provider. This may be used
|
|
||||||
* to populate the user interface with options associated with this
|
|
||||||
* view provider.
|
|
||||||
*
|
|
||||||
* @method metadata
|
|
||||||
* @memberof module:openmct.ViewProvider#
|
|
||||||
* @returns {module:openmct.ViewProvider~ViewMetadata} view metadata
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef ViewMetadata
|
|
||||||
* @memberof module:openmct.ViewProvider~
|
|
||||||
* @property {string} name the human-readable name of this view
|
|
||||||
* @property {string} key a machine-readable name for this view
|
|
||||||
* @property {string} [description] a longer-form description (typically
|
|
||||||
* a single sentence or short paragraph) of this kind of view
|
|
||||||
* @property {string} cssClass the CSS class to apply to labels for this
|
|
||||||
* view (to add icons, for instance)
|
|
||||||
*/
|
|
||||||
|
|
||||||
return ViewRegistry;
|
return ViewRegistry;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user