Compare commits
1 Commits
view-api-s
...
bug-1730
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
423c4cf0c1 |
@@ -4,6 +4,12 @@ deployment:
|
||||
commands:
|
||||
- npm install canvas nomnoml
|
||||
- ./build-docs.sh
|
||||
- git fetch --unshallow
|
||||
- git push git@heroku.com:openmctweb-demo.git $CIRCLE_SHA1:refs/heads/master
|
||||
openmct-demo:
|
||||
branch: live_demo
|
||||
heroku:
|
||||
appname: openmct-demo
|
||||
openmctweb-staging-deux:
|
||||
branch: mobile
|
||||
heroku:
|
||||
|
||||
@@ -127,8 +127,7 @@
|
||||
{ 'meaning': 'Timer object', 'cssClass': 'icon-timer', 'cssContent': 'e1127', 'htmlEntity': '&#xe1127' },
|
||||
{ 'meaning': 'Data Topic', 'cssClass': 'icon-topic', 'cssContent': 'e1128', 'htmlEntity': '&#xe1128' },
|
||||
{ 'meaning': 'Fixed Position object', 'cssClass': 'icon-box-with-dashed-lines', 'cssContent': 'e1129', 'htmlEntity': '&#xe1129' },
|
||||
{ 'meaning': 'Summary Widget', 'cssClass': 'icon-summary-widget', 'cssContent': 'e1130', 'htmlEntity': '&#xe1130' },
|
||||
{ 'meaning': 'Notebook object', 'cssClass': 'icon-notebook', 'cssContent': 'e1131', 'htmlEntity': '&#xe1131' }
|
||||
{ 'meaning': 'Summary Widget', 'cssClass': 'icon-summary-widget', 'cssContent': 'e1130', 'htmlEntity': '&#xe1130' }
|
||||
];
|
||||
"></div>
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<span class='type-icon flex-elem {{type.getCssClass()}}'></span>
|
||||
<span class="l-elem-wrapper l-flex-row flex-elem grows" ng-controller="ObjectHeaderController as controller">
|
||||
<span ng-if="parameters.mode" class='action flex-elem'>{{parameters.mode}}</span>
|
||||
<span ng-attr-contenteditable="{{ controller.editable ? true : undefined }}"
|
||||
<span contenteditable="true"
|
||||
class='title-label flex-elem holder flex-can-shrink s-input-inline'
|
||||
ng-click="controller.edit()"
|
||||
ng-blur="controller.updateName($event)"
|
||||
|
||||
@@ -32,8 +32,7 @@ define(
|
||||
*/
|
||||
function ObjectHeaderController($scope) {
|
||||
this.$scope = $scope;
|
||||
this.domainObject = $scope.domainObject;
|
||||
this.editable = this.allowEdit();
|
||||
$scope.editing = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,49 +41,33 @@ define(
|
||||
* @param event the mouse event
|
||||
*/
|
||||
ObjectHeaderController.prototype.updateName = function (event) {
|
||||
if (!event || !event.currentTarget) {
|
||||
return;
|
||||
}
|
||||
if (event && (event.type === 'blur' || event.which === 13)) {
|
||||
var name = event.currentTarget.innerHTML;
|
||||
|
||||
if (event.type === 'blur') {
|
||||
this.updateModel(event);
|
||||
} else if (event.which === 13) {
|
||||
this.updateModel(event);
|
||||
event.currentTarget.blur();
|
||||
window.getSelection().removeAllRanges();
|
||||
if (name.length === 0) {
|
||||
name = "Unnamed " + this.$scope.domainObject.getCapability("type").typeDef.name;
|
||||
event.currentTarget.innerHTML = name;
|
||||
}
|
||||
|
||||
if (name !== this.$scope.domainObject.model.name) {
|
||||
this.$scope.domainObject.getCapability('mutation').mutate(function (model) {
|
||||
model.name = name;
|
||||
});
|
||||
}
|
||||
|
||||
this.$scope.editing = false;
|
||||
|
||||
if (event.which === 13) {
|
||||
event.currentTarget.blur();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the model.
|
||||
*
|
||||
* @param event the mouse event
|
||||
* @param private
|
||||
* Marks the status of the field as editing.
|
||||
*/
|
||||
ObjectHeaderController.prototype.updateModel = function (event) {
|
||||
var name = event.currentTarget.textContent.replace(/\n/g, ' ');
|
||||
|
||||
if (name.length === 0) {
|
||||
name = "Unnamed " + this.domainObject.getCapability("type").typeDef.name;
|
||||
event.currentTarget.textContent = name;
|
||||
}
|
||||
|
||||
if (name !== this.domainObject.getModel().name) {
|
||||
this.domainObject.getCapability('mutation').mutate(function (model) {
|
||||
model.name = name;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the domain object is editable.
|
||||
*
|
||||
* @private
|
||||
* @return true if object is editable
|
||||
*/
|
||||
ObjectHeaderController.prototype.allowEdit = function () {
|
||||
var type = this.domainObject && this.domainObject.getCapability('type');
|
||||
return !!(type && type.hasFeature('creation'));
|
||||
ObjectHeaderController.prototype.edit = function () {
|
||||
this.$scope.editing = true;
|
||||
};
|
||||
|
||||
return ObjectHeaderController;
|
||||
|
||||
@@ -32,27 +32,22 @@ define(
|
||||
mockTypeCapability,
|
||||
mockEvent,
|
||||
mockCurrentTarget,
|
||||
model,
|
||||
controller;
|
||||
|
||||
beforeEach(function () {
|
||||
mockMutationCapability = jasmine.createSpyObj("mutation", ["mutate"]);
|
||||
mockTypeCapability = jasmine.createSpyObj("type", ["typeDef", "hasFeature"]);
|
||||
mockTypeCapability.typeDef = { name: ""};
|
||||
mockTypeCapability.hasFeature.andCallFake(function (feature) {
|
||||
return feature === 'creation';
|
||||
});
|
||||
|
||||
mockTypeCapability = {
|
||||
typeDef: {
|
||||
name: ""
|
||||
}
|
||||
};
|
||||
mockCapabilities = {
|
||||
mutation: mockMutationCapability,
|
||||
type: mockTypeCapability
|
||||
};
|
||||
|
||||
model = {
|
||||
name: "Test name"
|
||||
};
|
||||
mockDomainObject = jasmine.createSpyObj("domainObject", ["getCapability", "getModel"]);
|
||||
mockDomainObject.getModel.andReturn(model);
|
||||
mockDomainObject = jasmine.createSpyObj("domainObject", ["getCapability", "model"]);
|
||||
mockDomainObject.model = {name: "Test name"};
|
||||
mockDomainObject.getCapability.andCallFake(function (key) {
|
||||
return mockCapabilities[key];
|
||||
});
|
||||
@@ -61,7 +56,7 @@ define(
|
||||
domainObject: mockDomainObject
|
||||
};
|
||||
|
||||
mockCurrentTarget = jasmine.createSpyObj("currentTarget", ["blur", "textContent"]);
|
||||
mockCurrentTarget = jasmine.createSpyObj("currentTarget", ["blur", "innerHTML"]);
|
||||
mockCurrentTarget.blur.andReturn(mockCurrentTarget);
|
||||
|
||||
mockEvent = {
|
||||
@@ -75,7 +70,7 @@ define(
|
||||
|
||||
it("updates the model with new name on blur", function () {
|
||||
mockEvent.type = "blur";
|
||||
mockCurrentTarget.textContent = "New name";
|
||||
mockCurrentTarget.innerHTML = "New name";
|
||||
controller.updateName(mockEvent);
|
||||
|
||||
expect(mockMutationCapability.mutate).toHaveBeenCalled();
|
||||
@@ -83,23 +78,23 @@ define(
|
||||
|
||||
it("updates the model with a default for blank names", function () {
|
||||
mockEvent.type = "blur";
|
||||
mockCurrentTarget.textContent = "";
|
||||
mockCurrentTarget.innerHTML = "";
|
||||
controller.updateName(mockEvent);
|
||||
|
||||
expect(mockCurrentTarget.textContent.length).not.toEqual(0);
|
||||
expect(mockCurrentTarget.innerHTML.length).not.toEqual(0);
|
||||
expect(mockMutationCapability.mutate).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not update the model if the same name", function () {
|
||||
mockEvent.type = "blur";
|
||||
mockCurrentTarget.textContent = mockDomainObject.getModel().name;
|
||||
mockCurrentTarget.innerHTML = mockDomainObject.model.name;
|
||||
controller.updateName(mockEvent);
|
||||
|
||||
expect(mockMutationCapability.mutate).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("updates the model on enter keypress event only", function () {
|
||||
mockCurrentTarget.textContent = "New name";
|
||||
mockCurrentTarget.innerHTML = "New name";
|
||||
controller.updateName(mockEvent);
|
||||
|
||||
expect(mockMutationCapability.mutate).not.toHaveBeenCalled();
|
||||
@@ -109,29 +104,17 @@ define(
|
||||
|
||||
expect(mockMutationCapability.mutate).toHaveBeenCalledWith(jasmine.any(Function));
|
||||
|
||||
mockMutationCapability.mutate.mostRecentCall.args[0](model);
|
||||
mockMutationCapability.mutate.mostRecentCall.args[0](mockDomainObject.model);
|
||||
|
||||
expect(mockDomainObject.getModel().name).toBe("New name");
|
||||
expect(mockDomainObject.model.name).toBe("New name");
|
||||
});
|
||||
|
||||
it("blurs the field on enter key press", function () {
|
||||
mockCurrentTarget.textContent = "New name";
|
||||
mockEvent.which = 13;
|
||||
controller.updateName(mockEvent);
|
||||
|
||||
expect(mockEvent.currentTarget.blur).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("allows editting name when object is creatable", function () {
|
||||
expect(controller.allowEdit()).toBe(true);
|
||||
});
|
||||
|
||||
it("disallows editting name when object is non-creatable", function () {
|
||||
mockTypeCapability.hasFeature.andReturn(false);
|
||||
|
||||
expect(controller.allowEdit()).toBe(false);
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<div class="s-menu-button major create-button" ng-click="createController.toggle()">
|
||||
<span class="title-label">Create</span>
|
||||
</div>
|
||||
<div class="menu super-menu l-create-menu" ng-show="createController.isActive()">
|
||||
<div class="menu super-menu" ng-show="createController.isActive()">
|
||||
<mct-representation mct-object="domainObject" key="'create-menu'">
|
||||
</mct-representation>
|
||||
</div>
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<div class="w-menu" ng-controller="CreateMenuController">
|
||||
<div class="col menu-items">
|
||||
<div class="contents" ng-controller="CreateMenuController">
|
||||
<div class="pane left menu-items">
|
||||
<ul>
|
||||
<li ng-repeat="createAction in createActions" ng-click="createAction.perform()">
|
||||
<a ng-mouseover="representation.activeMetadata = createAction.getMetadata()"
|
||||
@@ -31,15 +31,13 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col menu-item-description">
|
||||
<div class="pane right menu-item-description">
|
||||
<div class="desc-area icon {{ representation.activeMetadata.cssClass }}"></div>
|
||||
<div class="w-title-desc">
|
||||
<div class="desc-area title">
|
||||
{{representation.activeMetadata.name}}
|
||||
</div>
|
||||
<div class="desc-area description">
|
||||
{{representation.activeMetadata.description}}
|
||||
</div>
|
||||
<div class="desc-area title">
|
||||
{{representation.activeMetadata.name}}
|
||||
</div>
|
||||
<div class="desc-area description">
|
||||
{{representation.activeMetadata.description}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"metadata": {
|
||||
"name": "openmct-symbols-16px",
|
||||
"lastOpened": 0,
|
||||
"created": 1506973656040
|
||||
"created": 1505151140023
|
||||
},
|
||||
"iconSets": [
|
||||
{
|
||||
@@ -899,14 +899,6 @@
|
||||
"prevSize": 24,
|
||||
"code": 921904,
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 139,
|
||||
"id": 117,
|
||||
"name": "icon-notebook",
|
||||
"prevSize": 24,
|
||||
"code": 921905,
|
||||
"tempChar": ""
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
@@ -3532,29 +3524,6 @@
|
||||
{}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 117,
|
||||
"paths": [
|
||||
"M896 110.8c0-79.8-55.4-127.4-123-105.4l-773 250.6h896v-145.2z",
|
||||
"M896 320h-896v576c0 70.4 57.6 128 128 128h768c70.4 0 128-57.6 128-128v-448c0-70.4-57.6-128-128-128zM832 832h-384v-320h384v320z"
|
||||
],
|
||||
"attrs": [
|
||||
{},
|
||||
{}
|
||||
],
|
||||
"isMulticolor": false,
|
||||
"isMulticolor2": false,
|
||||
"grid": 16,
|
||||
"tags": [
|
||||
"icon-notebook"
|
||||
],
|
||||
"colorPermutations": {
|
||||
"1161751207457516161751": [
|
||||
{},
|
||||
{}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"colorThemes": [
|
||||
|
||||
Binary file not shown.
@@ -118,5 +118,4 @@
|
||||
<glyph unicode="󡄨" glyph-name="icon-topic" d="M454.36 483.36l86.3 86.3c9.088 8.965 21.577 14.502 35.36 14.502s26.272-5.537 35.366-14.507l86.294-86.294c19.328-19.358 42.832-34.541 69.047-44.082l1.313 171.722-57.64 57.64c-34.407 34.33-81.9 55.558-134.35 55.558s-99.943-21.228-134.354-55.562l-86.296-86.297c-9.088-8.965-21.577-14.502-35.36-14.502s-26.272 5.537-35.366 14.507l-28.674 28.654v-172.14c19.045-7.022 41.040-11.084 63.984-11.084 52.463 0 99.966 21.239 134.379 55.587zM505.64 412.64l-86.3-86.3c-9.088-8.965-21.577-14.502-35.36-14.502s-26.272 5.537-35.366 14.507l-86.294 86.294c-2 2-4.2 4-6.36 6v-197.36c33.664-30.72 78.65-49.537 128.031-49.537 52.44 0 99.923 21.22 134.333 55.541l86.296 86.296c9.088 8.965 21.577 14.502 35.36 14.502s26.272-5.537 35.366-14.507l86.294-86.294c2-2 4.2-4 6.36-6v197.36c-33.664 30.72-78.65 49.537-128.031 49.537-52.44 0-99.923-21.22-134.333-55.541zM832 960h-128v-192h127.66l0.34-0.34v-639.32l-0.34-0.34h-127.66v-192h128c105.6 0 192 86.4 192 192v640c0 105.6-86.4 192-192 192zM320 128h-127.66l-0.34 0.34v639.32l0.34 0.34h127.66v192h-128c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h128v192z" />
|
||||
<glyph unicode="󡄩" glyph-name="icon-box-with-dashed-lines" d="M0 576h128v-256h-128v256zM128 831.78l0.22 0.22h191.78v128h-192c-70.606-0.215-127.785-57.394-128-127.979v-192.021h128v191.78zM128 64.22v191.78h-128v-192c0.215-70.606 57.394-127.785 127.979-128h192.021v128h-191.78zM384 960h256v-128h-256v128zM896 64.22l-0.22-0.22h-191.78v-128h192c70.606 0.215 127.785 57.394 128 127.979v192.021h-128v-191.78zM896 960h-192v-128h191.78l0.22-0.22v-191.78h128v192c-0.215 70.606-57.394 127.785-127.979 128zM896 576h128v-256h-128v256zM384 64h256v-128h-256v128zM256 704h512v-512h-512v512z" />
|
||||
<glyph unicode="󡄰" glyph-name="icon-summary-widget" d="M896 960h-768c-70.4 0-128-57.6-128-128v-768c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v768c0 70.4-57.6 128-128 128zM847.8 349.6l-82.6-143.2-189.6 131.6 19.2-230h-165.4l19.2 230-189.6-131.6-82.6 143.2 208.6 98.4-208.8 98.4 82.6 143.2 189.6-131.6-19.2 230h165.4l-19.2-230 189.6 131.6 82.6-143.2-208.6-98.4 208.8-98.4z" />
|
||||
<glyph unicode="󡄱" glyph-name="icon-notebook" d="M896 849.2c0 79.8-55.4 127.4-123 105.4l-773-250.6h896v145.2zM896 640h-896v-576c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v448c0 70.4-57.6 128-128 128zM832 128h-384v320h384v-320z" />
|
||||
</font></defs></svg>
|
||||
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
Binary file not shown.
Binary file not shown.
@@ -146,7 +146,6 @@ $glyph-icon-timer: '\e1127';
|
||||
$glyph-icon-topic: '\e1128';
|
||||
$glyph-icon-box-with-dashed-lines: '\e1129';
|
||||
$glyph-icon-summary-widget: '\e1130';
|
||||
$glyph-icon-notebook: '\e1131';
|
||||
|
||||
/************************** 16 PX CLASSES */
|
||||
|
||||
@@ -261,7 +260,6 @@ $glyph-icon-notebook: '\e1131';
|
||||
.icon-topic { @include glyphBefore($glyph-icon-topic); }
|
||||
.icon-box-with-dashed-lines { @include glyphBefore($glyph-icon-box-with-dashed-lines); }
|
||||
.icon-summary-widget { @include glyphBefore($glyph-icon-summary-widget); }
|
||||
.icon-notebook { @include glyphBefore($glyph-icon-notebook); }
|
||||
|
||||
/************************** 12 PX CLASSES */
|
||||
.icon-crosshair-12px { @include glyphBefore($glyph-icon-crosshair,'symbolsfont-12px'); }
|
||||
|
||||
@@ -26,6 +26,5 @@
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -753,15 +753,11 @@ body.desktop {
|
||||
}
|
||||
|
||||
.overlay ::-webkit-scrollbar-thumb {
|
||||
$lr: 15%;
|
||||
background: $scrollbarThumbColorOverlay;
|
||||
&:hover { background: $scrollbarThumbColorOverlayHov; }
|
||||
}
|
||||
|
||||
.menu ::-webkit-scrollbar-thumb {
|
||||
background: $scrollbarThumbColorMenu;
|
||||
&:hover { background: $scrollbarThumbColorMenuHov; }
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-corner {
|
||||
background: $scrollbarTrackColorBg;
|
||||
}
|
||||
|
||||
@@ -21,87 +21,92 @@
|
||||
*****************************************************************************/
|
||||
/******************************************************** MENU BUTTONS */
|
||||
.s-menu-button {
|
||||
// Formerly .btn-menu
|
||||
@extend .s-button;
|
||||
span.l-click-area {
|
||||
// In markup, this element should not enclose anything.
|
||||
@extend .abs;
|
||||
}
|
||||
// Formerly .btn-menu
|
||||
@extend .s-button;
|
||||
span.l-click-area {
|
||||
// In markup, this element should not enclose anything.
|
||||
@extend .abs;
|
||||
}
|
||||
|
||||
.icon {
|
||||
font-size: 16px; //120%;
|
||||
}
|
||||
.icon {
|
||||
font-size: 16px; //120%;
|
||||
}
|
||||
|
||||
.title-label {
|
||||
margin-left: $interiorMarginSm;
|
||||
}
|
||||
.title-label {
|
||||
margin-left: $interiorMarginSm;
|
||||
}
|
||||
|
||||
.color-swatch {
|
||||
// Used in color menu buttons in toolbar
|
||||
$d: 10px;
|
||||
display: inline-block;
|
||||
border: 1px solid rgba($colorBtnFg, 0.2);
|
||||
height: $d;
|
||||
width: $d;
|
||||
height: $d; width: $d;
|
||||
vertical-align: middle;
|
||||
margin-left: $interiorMarginSm;
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
&:after {
|
||||
// Adds the downward facing 'context available / invoke menu' arrow element
|
||||
@include contextArrow();
|
||||
color: rgba($colorInvokeMenu, percentToDecimal($contrastInvokeMenuPercent));
|
||||
}
|
||||
&:after {
|
||||
// Adds the downward facing 'context available / invoke menu' arrow element
|
||||
@include contextArrow();
|
||||
color: rgba($colorInvokeMenu, percentToDecimal($contrastInvokeMenuPercent));
|
||||
}
|
||||
|
||||
&.create-button {
|
||||
&.create-button {
|
||||
@extend .icon-plus;
|
||||
.title-label {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
.title-label {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.menu {
|
||||
left: 0;
|
||||
text-align: left;
|
||||
}
|
||||
.menu {
|
||||
left: 0;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************** MENUS THEMSELVES */
|
||||
.menu-element {
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.s-menu {
|
||||
border-radius: $basicCr;
|
||||
@include containerSubtle($colorMenuBg, $colorMenuFg);
|
||||
@include boxShdw($shdwMenu);
|
||||
@include txtShdw($shdwMenuText);
|
||||
padding: $interiorMarginSm 0;
|
||||
}
|
||||
|
||||
.menu {
|
||||
border-radius: $basicCr;
|
||||
@include containerSubtle($colorMenuBg, $colorMenuFg);
|
||||
@include boxShdw($shdwMenu);
|
||||
@include txtShdw($shdwMenuText);
|
||||
padding: $interiorMarginSm 0;
|
||||
display: block;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
ul {
|
||||
@include menuUlReset();
|
||||
li {
|
||||
box-sizing: border-box;
|
||||
border-top: 1px solid pullForward($colorMenuBg, 10%);
|
||||
// TODO: reduce size of icons
|
||||
@extend .s-menu;
|
||||
display: block;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
ul {
|
||||
@include menuUlReset();
|
||||
li {
|
||||
box-sizing: border-box;
|
||||
border-top: 1px solid pullForward($colorMenuBg, 10%);
|
||||
color: $colorMenuFg;
|
||||
line-height: $menuLineH;
|
||||
padding: $interiorMarginSm $interiorMargin * 2 $interiorMarginSm ($interiorMargin * 2) + $treeTypeIconW;
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
&:first-child {
|
||||
border: none;
|
||||
}
|
||||
&:hover {
|
||||
background: $colorMenuHovBg;
|
||||
color: $colorMenuHovFg;
|
||||
//color: pullForward($colorMenuBg, 60%);
|
||||
line-height: $menuLineH;
|
||||
padding: $interiorMarginSm $interiorMargin * 2 $interiorMarginSm ($interiorMargin * 2) + $treeTypeIconW;
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
&:first-child {
|
||||
border: none;
|
||||
}
|
||||
&:hover {
|
||||
background: $colorMenuHovBg;
|
||||
color: $colorMenuHovFg;
|
||||
&:before {
|
||||
color: $colorMenuHovIc;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:before {
|
||||
@extend .ui-symbol;
|
||||
@extend .type-icon;
|
||||
@@ -109,8 +114,8 @@
|
||||
display: inline-block;
|
||||
left: $interiorMargin * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.menu,
|
||||
@@ -118,97 +123,94 @@
|
||||
.context-menu,
|
||||
.super-menu,
|
||||
.s-menu-button .menu {
|
||||
pointer-events: auto;
|
||||
ul li {
|
||||
a.menu-item-a {
|
||||
pointer-events: auto;
|
||||
ul li {
|
||||
a.menu-item-a {
|
||||
color: $colorMenuFg;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
&:before,
|
||||
a.menu-item-a:before {
|
||||
color: $colorMenuIc;
|
||||
left: $interiorMargin;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.checkbox-menu {
|
||||
// Used in search dropdown in tree
|
||||
@extend .context-menu;
|
||||
ul li {
|
||||
padding-left: 50px;
|
||||
.checkbox {
|
||||
$d: 0.7rem;
|
||||
position: absolute;
|
||||
left: $interiorMargin;
|
||||
top: ($menuLineH - $d) / 1.5;
|
||||
em {
|
||||
height: $d;
|
||||
width: $d;
|
||||
&:before {
|
||||
font-size: 7px !important;
|
||||
height: $d;
|
||||
width: $d;
|
||||
line-height: $d;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:before {
|
||||
// Used in search dropdown in tree
|
||||
@extend .context-menu;
|
||||
ul li {
|
||||
padding-left: 50px;
|
||||
.checkbox {
|
||||
$d: 0.7rem;
|
||||
position: absolute;
|
||||
left: $interiorMargin;
|
||||
top: ($menuLineH - $d) / 1.5;
|
||||
em {
|
||||
height: $d;
|
||||
width: $d;
|
||||
&:before {
|
||||
font-size: 7px !important;
|
||||
height: $d;
|
||||
width: $d;
|
||||
line-height: $d;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:before {
|
||||
// Type icon
|
||||
left: 25px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.super-menu,
|
||||
.super-menu > mct-representation,
|
||||
.super-menu > .contents {
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
position: relative;
|
||||
left: 25px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.super-menu {
|
||||
$plw: 50%;
|
||||
$prw: 100% - $plw;
|
||||
position: absolute;
|
||||
.w-menu {
|
||||
align-items: stretch;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin: $interiorMarginLg;
|
||||
}
|
||||
.col {
|
||||
box-sizing: border-box;
|
||||
flex: 1 1 auto;
|
||||
overflow-x: hidden;
|
||||
&.menu-items {
|
||||
border-right: 1px solid pullForward($colorMenuBg, 10%);
|
||||
overflow-y: auto;
|
||||
padding-right: $interiorMargin;
|
||||
width: $plw;
|
||||
ul {
|
||||
li {
|
||||
border-radius: $controlCr;
|
||||
padding-left: 30px;
|
||||
border-top: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.menu-item-description {
|
||||
$p: $interiorMargin * 3;
|
||||
overflow-y: hidden;
|
||||
padding: $p $p 0 $p;
|
||||
width: $prw;
|
||||
|
||||
$w: 500px;
|
||||
$h: $w - 20;
|
||||
$plw: 50%;
|
||||
$prw: 50%;
|
||||
display: block;
|
||||
width: $w;
|
||||
height: $h;
|
||||
.contents {
|
||||
@include absPosDefault($interiorMargin);
|
||||
}
|
||||
.pane {
|
||||
box-sizing: border-box;
|
||||
&.menu-items {
|
||||
border-right: 1px solid pullForward($colorMenuBg, 10%);
|
||||
left: 0;
|
||||
padding-right: $interiorMargin;
|
||||
right: auto;
|
||||
width: $plw;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
ul {
|
||||
li {
|
||||
border-radius: $controlCr;
|
||||
padding-left: 30px;
|
||||
border-top: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.menu-item-description {
|
||||
left: auto;
|
||||
right: 0;
|
||||
padding: $interiorMargin * 5;
|
||||
width: $prw;
|
||||
.desc-area {
|
||||
&.icon {
|
||||
color: $colorCreateMenuLgIcon;
|
||||
font-size: 8em;
|
||||
margin-bottom: $interiorMargin * 3;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
}
|
||||
&.title {
|
||||
color: $colorCreateMenuText;
|
||||
font-size: 1.2em;
|
||||
margin-bottom: $interiorMargin * 2;
|
||||
}
|
||||
&.description {
|
||||
color: pushBack($colorCreateMenuText, 20%);
|
||||
@@ -216,104 +218,67 @@
|
||||
line-height: 1.5em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.w-title-desc {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden; // Height set in specific menu instances
|
||||
}
|
||||
|
||||
// Specific menu instances
|
||||
&.l-create-menu {
|
||||
width: 500px;
|
||||
.col {
|
||||
max-height: 70vh;
|
||||
}
|
||||
.w-title-desc {
|
||||
height: 190px;
|
||||
}
|
||||
.desc-area {
|
||||
&.icon {
|
||||
font-size: 8em;
|
||||
height: 135px;
|
||||
margin-bottom: $interiorMargin * 3;
|
||||
}
|
||||
&.title {
|
||||
font-size: 1.2em;
|
||||
margin-bottom: $interiorMargin * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.mini {
|
||||
width: 400px;
|
||||
.col {
|
||||
max-height: 50vh;
|
||||
height: 300px;
|
||||
.pane {
|
||||
&.menu-items {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
&.menu-item-description {
|
||||
$p: $interiorMargin * 2;
|
||||
padding: $p $p 0 $p;
|
||||
}
|
||||
}
|
||||
.w-title-desc {
|
||||
height: 180px;
|
||||
}
|
||||
.desc-area {
|
||||
&.icon {
|
||||
font-size: 4em;
|
||||
height: 70px;
|
||||
margin-bottom: $interiorMargin * 3;
|
||||
}
|
||||
&.title {
|
||||
font-size: 1em;
|
||||
margin-bottom: $interiorMargin * 2;
|
||||
padding: $interiorMargin * 3;
|
||||
.desc-area {
|
||||
&.icon {
|
||||
font-size: 4em;
|
||||
}
|
||||
&.title {
|
||||
font-size: 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.context-menu {
|
||||
font-size: 0.80rem;
|
||||
font-size: 0.80rem;
|
||||
}
|
||||
|
||||
.context-menu-holder,
|
||||
.menu-holder {
|
||||
position: absolute;
|
||||
z-index: 120;
|
||||
.context-menu-wrapper {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
&.go-left .context-menu,
|
||||
&.go-left .menu {
|
||||
right: 0;
|
||||
}
|
||||
&.go-up .context-menu,
|
||||
&.go-up .menu {
|
||||
bottom: 0;
|
||||
}
|
||||
position: absolute;
|
||||
z-index: 120;
|
||||
.context-menu-wrapper {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
&.go-left .context-menu,
|
||||
&.go-left .menu {
|
||||
right: 0;
|
||||
}
|
||||
&.go-up .context-menu,
|
||||
&.go-up .menu {
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.context-menu-holder {
|
||||
pointer-events: none;
|
||||
height: 200px;
|
||||
width: 170px;
|
||||
pointer-events: none;
|
||||
height: 200px;
|
||||
width: 170px;
|
||||
}
|
||||
|
||||
.btn-bar.right .menu,
|
||||
.menus-to-left .menu {
|
||||
z-index: 79;
|
||||
left: auto;
|
||||
right: 0;
|
||||
width: auto;
|
||||
left: auto;
|
||||
right: 0;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.menus-up .menu {
|
||||
bottom: $btnStdH;
|
||||
top: auto;
|
||||
bottom: $btnStdH; top: auto;
|
||||
}
|
||||
|
||||
@@ -156,8 +156,6 @@
|
||||
left: 0;
|
||||
right: 0;
|
||||
overflow: auto;
|
||||
padding-right: $interiorMargin;
|
||||
padding-bottom: $interiorMargin;
|
||||
.field.l-input-med {
|
||||
input[type='text'] {
|
||||
width: 100%;
|
||||
|
||||
@@ -108,11 +108,8 @@ define(
|
||||
|
||||
getMetadata();
|
||||
});
|
||||
|
||||
var mutation = $scope.ngModel.selectedObject.getCapability('mutation');
|
||||
var unlisten = mutation.listen(getMetadata);
|
||||
$scope.$on('$destroy', unlisten);
|
||||
}
|
||||
|
||||
return ObjectInspectorController;
|
||||
}
|
||||
);
|
||||
|
||||
@@ -39,18 +39,10 @@ define(
|
||||
beforeEach(function () {
|
||||
mockScope = jasmine.createSpyObj(
|
||||
"$scope",
|
||||
["$watch", "$on"]
|
||||
["$watch"]
|
||||
);
|
||||
mockScope.ngModel = {};
|
||||
mockScope.ngModel.selectedObject = {
|
||||
getCapability: function () {
|
||||
return {
|
||||
listen: function () {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
mockScope.ngModel.selectedObject = 'mock selected object';
|
||||
|
||||
mockObjectService = jasmine.createSpyObj(
|
||||
"objectService",
|
||||
|
||||
@@ -201,15 +201,13 @@ $shdwItemTreeIcon: 0.6;
|
||||
$colorThumbHoverBg: $colorItemTreeHoverBg;
|
||||
|
||||
// Scrollbar
|
||||
$scrollbarTrackSize: 7px;
|
||||
$scrollbarTrackShdw: rgba(#000, 0.5) 0 1px 5px;
|
||||
$scrollbarTrackColorBg: transparent; //rgba(#000, 0.4);
|
||||
$scrollbarTrackSize: 10px;
|
||||
$scrollbarTrackShdw: rgba(#000, 0.7) 0 1px 5px;
|
||||
$scrollbarTrackColorBg: rgba(#000, 0.4);
|
||||
$scrollbarThumbColor: pullForward($colorBodyBg, 10%);
|
||||
$scrollbarThumbColorHov: pullForward($scrollbarThumbColor, 2%);
|
||||
$scrollbarThumbColorOverlay: pullForward($colorOvrBg, 10%);
|
||||
$scrollbarThumbColorOverlayHov: pullForward($scrollbarThumbColorOverlay, 2%);
|
||||
$scrollbarThumbColorMenu: pullForward($colorMenuBg, 20%);
|
||||
$scrollbarThumbColorMenuHov: pullForward($scrollbarThumbColorMenu, 2%);
|
||||
|
||||
// Splitter
|
||||
// All splitterD* values MUST both be either odd or even numbers
|
||||
|
||||
@@ -201,15 +201,13 @@ $shdwItemTreeIcon: none;
|
||||
$colorThumbHoverBg: $colorItemTreeHoverBg;
|
||||
|
||||
// Scrollbar
|
||||
$scrollbarTrackSize: 7px;
|
||||
$scrollbarTrackSize: 10px;
|
||||
$scrollbarTrackShdw: rgba(#000, 0.2) 0 1px 2px;
|
||||
$scrollbarTrackColorBg: rgba(#000, 0.2);
|
||||
$scrollbarThumbColor: darken($colorBodyBg, 50%);
|
||||
$scrollbarThumbColorHov: $colorKey;
|
||||
$scrollbarThumbColorOverlay: darken($colorOvrBg, 50%);
|
||||
$scrollbarThumbColorOverlayHov: $scrollbarThumbColorHov;
|
||||
$scrollbarThumbColorMenu: pullForward($colorMenuBg, 10%);
|
||||
$scrollbarThumbColorMenuHov: pullForward($scrollbarThumbColorMenu, 2%);
|
||||
|
||||
// Splitter
|
||||
// All splitterD* values MUST both be either odd or even numbers
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<div class="w-menu">
|
||||
<div class="col menu-items">
|
||||
<div class="contents">
|
||||
<div class="pane left menu-items">
|
||||
<ul>
|
||||
<li ng-repeat="metadata in ngModel.options"
|
||||
ng-click="ngModel.select(metadata)">
|
||||
@@ -32,15 +32,13 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col menu-item-description">
|
||||
<div class="pane right menu-item-description">
|
||||
<div class="desc-area ui-symbol icon type-icon {{ngModel.activeMetadata.cssClass}}"></div>
|
||||
<div class="w-title-desc">
|
||||
<div class="desc-area title">
|
||||
{{ngModel.activeMetadata.name}}
|
||||
</div>
|
||||
<div class="desc-area description">
|
||||
{{ngModel.activeMetadata.description}}
|
||||
</div>
|
||||
<div class="desc-area title">
|
||||
{{ngModel.activeMetadata.name}}
|
||||
</div>
|
||||
<div class="desc-area description">
|
||||
{{ngModel.activeMetadata.description}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
ng-click="modeController.toggle()">
|
||||
<span class="title-label">{{ngModel.selected.name}}</span>
|
||||
</div>
|
||||
<div class="menu super-menu mini l-mode-selector-menu"
|
||||
<div class="menu super-menu mini mode-selector-menu"
|
||||
ng-show="modeController.isActive()">
|
||||
<mct-include key="'mode-menu'"
|
||||
ng-model="ngModel">
|
||||
|
||||
@@ -201,7 +201,7 @@ define(
|
||||
var options = [{
|
||||
key: 'fixed',
|
||||
name: 'Fixed Timespan Mode',
|
||||
description: 'Query and explore data that falls between two fixed datetimes.',
|
||||
description: 'Query and explore data that falls between two fixed datetimes',
|
||||
cssClass: 'icon-calendar'
|
||||
}];
|
||||
var clocks = {};
|
||||
|
||||
@@ -26,12 +26,8 @@
|
||||
* @namespace platform/features/layout
|
||||
*/
|
||||
define(
|
||||
[
|
||||
'./LayoutDrag'
|
||||
],
|
||||
function (
|
||||
LayoutDrag
|
||||
) {
|
||||
['./LayoutDrag'],
|
||||
function (LayoutDrag) {
|
||||
|
||||
var DEFAULT_DIMENSIONS = [12, 8],
|
||||
DEFAULT_GRID_SIZE = [32, 32],
|
||||
@@ -128,10 +124,6 @@ define(
|
||||
self.select(null, self.droppedIdToSelectAfterRefresh);
|
||||
delete self.droppedIdToSelectAfterRefresh;
|
||||
}
|
||||
|
||||
if (composition.indexOf(self.selectedId) === -1) {
|
||||
self.clearSelection();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -424,17 +424,6 @@ define(
|
||||
expect(selectedObj.showFrame).toEqual(jasmine.any(Function));
|
||||
});
|
||||
|
||||
it("deselects the object that is no longer in the composition", function () {
|
||||
mockScope.$watchCollection.mostRecentCall.args[1]();
|
||||
var childObj = mockCompositionObjects[0];
|
||||
controller.select(mockEvent, childObj.getId());
|
||||
|
||||
var composition = ["b", "c"];
|
||||
mockScope.$watchCollection.mostRecentCall.args[1](composition);
|
||||
|
||||
expect(controller.selected(childObj)).toBe(false);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
@@ -80,8 +80,8 @@
|
||||
</div>
|
||||
</td>
|
||||
<td>{{child.type}}</td>
|
||||
<td>{{child.persisted}}</td>
|
||||
<td>{{child.modified}}</td>
|
||||
<td>{{child.persisted.toUTCString()}}</td>
|
||||
<td>{{child.modified.toUTCString()}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -52,10 +52,10 @@ define(function () {
|
||||
type: child.getCapability('type').getName(),
|
||||
persisted: new Date(
|
||||
child.getModel().persisted
|
||||
).toUTCString(),
|
||||
),
|
||||
modified: new Date(
|
||||
child.getModel().modified
|
||||
).toUTCString(),
|
||||
),
|
||||
asDomainObject: child,
|
||||
location: child.getCapability('location'),
|
||||
action: child.getCapability('action')
|
||||
|
||||
@@ -36,13 +36,6 @@ define(
|
||||
|
||||
PlotViewPolicy.prototype.hasNumericTelemetry = function (domainObject) {
|
||||
var adaptedObject = domainObject.useCapability('adapter');
|
||||
|
||||
if (!adaptedObject.telemetry) {
|
||||
return domainObject.hasCapability('delegation') &&
|
||||
domainObject.getCapability('delegation')
|
||||
.doesDelegateCapability('telemetry');
|
||||
}
|
||||
|
||||
var metadata = this.openmct.telemetry.getMetadata(adaptedObject);
|
||||
var rangeValues = metadata.valuesForHints(['range']);
|
||||
if (rangeValues.length === 0) {
|
||||
|
||||
@@ -27,19 +27,17 @@ define(
|
||||
describe("Plot view policy", function () {
|
||||
var testView,
|
||||
mockDomainObject,
|
||||
testAdaptedObject,
|
||||
openmct,
|
||||
telemetryMetadata,
|
||||
policy;
|
||||
|
||||
beforeEach(function () {
|
||||
testView = { key: "plot" };
|
||||
testAdaptedObject = { telemetry: {} };
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
'domainObject',
|
||||
['useCapability', 'hasCapability', 'getCapability']
|
||||
['useCapability']
|
||||
);
|
||||
mockDomainObject.useCapability.andReturn(testAdaptedObject);
|
||||
mockDomainObject.useCapability.andReturn('adaptedObject');
|
||||
openmct = {
|
||||
telemetry: jasmine.createSpyObj('telemetryAPI', [
|
||||
'getMetadata'
|
||||
@@ -58,7 +56,7 @@ define(
|
||||
expect(mockDomainObject.useCapability)
|
||||
.toHaveBeenCalledWith('adapter');
|
||||
expect(openmct.telemetry.getMetadata)
|
||||
.toHaveBeenCalledWith(testAdaptedObject);
|
||||
.toHaveBeenCalledWith('adaptedObject');
|
||||
expect(telemetryMetadata.valuesForHints)
|
||||
.toHaveBeenCalledWith(['range']);
|
||||
});
|
||||
@@ -89,30 +87,6 @@ define(
|
||||
expect(policy.allow(testView, mockDomainObject)).toBe(true);
|
||||
});
|
||||
|
||||
it('returns true for telemetry delegators', function () {
|
||||
delete testAdaptedObject.telemetry;
|
||||
mockDomainObject.hasCapability.andCallFake(function (c) {
|
||||
return c === 'delegation';
|
||||
});
|
||||
mockDomainObject.getCapability.andReturn(
|
||||
jasmine.createSpyObj('delegation', [
|
||||
'doesDelegateCapability'
|
||||
])
|
||||
);
|
||||
mockDomainObject.getCapability('delegation')
|
||||
.doesDelegateCapability.andCallFake(function (c) {
|
||||
return c === 'telemetry';
|
||||
});
|
||||
expect(policy.allow(testView, mockDomainObject)).toBe(true);
|
||||
expect(openmct.telemetry.getMetadata).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('returns true for non-telemetry non-delegators', function () {
|
||||
delete testAdaptedObject.telemetry;
|
||||
mockDomainObject.hasCapability.andReturn(false);
|
||||
expect(policy.allow(testView, mockDomainObject)).toBe(false);
|
||||
});
|
||||
|
||||
it("allows other views", function () {
|
||||
testView.key = "somethingElse";
|
||||
expect(policy.allow(testView, mockDomainObject)).toBe(true);
|
||||
|
||||
@@ -47,7 +47,7 @@ define([
|
||||
"name": "Export as JSON",
|
||||
"implementation": ExportAsJSONAction,
|
||||
"category": "contextual",
|
||||
"cssClass": "icon-export",
|
||||
"cssClass": "icon-save",
|
||||
"depends": [
|
||||
"exportService",
|
||||
"policyService",
|
||||
@@ -59,7 +59,7 @@ define([
|
||||
"name": "Import from JSON",
|
||||
"implementation": ImportAsJSONAction,
|
||||
"category": "contextual",
|
||||
"cssClass": "icon-import",
|
||||
"cssClass": "icon-download",
|
||||
"depends": [
|
||||
"exportService",
|
||||
"identifierService",
|
||||
|
||||
16
src/MCT.js
16
src/MCT.js
@@ -106,9 +106,9 @@ define([
|
||||
*
|
||||
* @type {module:openmct.ViewRegistry}
|
||||
* @memberof module:openmct.MCT#
|
||||
* @name objectViews
|
||||
* @name mainViews
|
||||
*/
|
||||
this.objectViews = new ViewRegistry();
|
||||
this.mainViews = new ViewRegistry();
|
||||
|
||||
/**
|
||||
* Registry for views which should appear in the Inspector area.
|
||||
@@ -255,18 +255,6 @@ define([
|
||||
this.legacyExtension('types', legacyDefinition);
|
||||
}.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.enable('adapter');
|
||||
/**
|
||||
|
||||
@@ -24,6 +24,7 @@ define([
|
||||
'legacyRegistry',
|
||||
'./actions/ActionDialogDecorator',
|
||||
'./capabilities/AdapterCapability',
|
||||
'./controllers/AdaptedViewController',
|
||||
'./directives/MCTView',
|
||||
'./services/Instantiate',
|
||||
'./services/MissingModelCompatibilityDecorator',
|
||||
@@ -31,11 +32,13 @@ define([
|
||||
'./policies/AdapterCompositionPolicy',
|
||||
'./policies/AdaptedViewPolicy',
|
||||
'./runs/AlternateCompositionInitializer',
|
||||
'./runs/TimeSettingsURLHandler'
|
||||
'./runs/TimeSettingsURLHandler',
|
||||
'text!./templates/adapted-view-template.html'
|
||||
], function (
|
||||
legacyRegistry,
|
||||
ActionDialogDecorator,
|
||||
AdapterCapability,
|
||||
AdaptedViewController,
|
||||
MCTView,
|
||||
Instantiate,
|
||||
MissingModelCompatibilityDecorator,
|
||||
@@ -43,15 +46,15 @@ define([
|
||||
AdapterCompositionPolicy,
|
||||
AdaptedViewPolicy,
|
||||
AlternateCompositionInitializer,
|
||||
TimeSettingsURLHandler
|
||||
TimeSettingsURLHandler,
|
||||
adaptedViewTemplate
|
||||
) {
|
||||
legacyRegistry.register('src/adapter', {
|
||||
"extensions": {
|
||||
"directives": [
|
||||
{
|
||||
key: "mctView",
|
||||
implementation: MCTView,
|
||||
depends: ["openmct"]
|
||||
implementation: MCTView
|
||||
}
|
||||
],
|
||||
capabilities: [
|
||||
@@ -60,6 +63,16 @@ define([
|
||||
implementation: AdapterCapability
|
||||
}
|
||||
],
|
||||
controllers: [
|
||||
{
|
||||
key: "AdaptedViewController",
|
||||
implementation: AdaptedViewController,
|
||||
depends: [
|
||||
'$scope',
|
||||
'openmct'
|
||||
]
|
||||
}
|
||||
],
|
||||
services: [
|
||||
{
|
||||
key: "instantiate",
|
||||
@@ -122,6 +135,12 @@ define([
|
||||
depends: ["openmct", "$location", "$rootScope"]
|
||||
}
|
||||
],
|
||||
views: [
|
||||
{
|
||||
key: "adapted-view",
|
||||
template: adaptedViewTemplate
|
||||
}
|
||||
],
|
||||
licenses: [
|
||||
{
|
||||
"name": "almond",
|
||||
|
||||
@@ -22,12 +22,10 @@
|
||||
|
||||
define([
|
||||
'./synchronizeMutationCapability',
|
||||
'./AlternateCompositionCapability',
|
||||
'./patchViewCapability'
|
||||
'./AlternateCompositionCapability'
|
||||
], function (
|
||||
synchronizeMutationCapability,
|
||||
AlternateCompositionCapability,
|
||||
patchViewCapability
|
||||
AlternateCompositionCapability
|
||||
) {
|
||||
|
||||
/**
|
||||
@@ -48,9 +46,6 @@ define([
|
||||
capabilities.mutation =
|
||||
synchronizeMutationCapability(capabilities.mutation);
|
||||
}
|
||||
if (capabilities.view) {
|
||||
capabilities.view = patchViewCapability(capabilities.view);
|
||||
}
|
||||
if (AlternateCompositionCapability.appliesTo(model, id)) {
|
||||
capabilities.composition = function (domainObject) {
|
||||
return new AlternateCompositionCapability(this.$injector, domainObject);
|
||||
|
||||
@@ -20,41 +20,21 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
'lodash'
|
||||
], function (
|
||||
_
|
||||
) {
|
||||
define([], function () {
|
||||
function AdaptedViewController($scope, openmct) {
|
||||
function refresh(legacyObject) {
|
||||
if (!legacyObject) {
|
||||
$scope.view = undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
function patchViewCapability(viewConstructor) {
|
||||
return function makeCapability(domainObject) {
|
||||
var capability = viewConstructor(domainObject);
|
||||
var oldInvoke = capability.invoke.bind(capability);
|
||||
var domainObject = legacyObject.useCapability('adapter');
|
||||
var providers = openmct.mainViews.get(domainObject);
|
||||
$scope.view = providers[0] && providers[0].view(domainObject);
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
$scope.$watch('domainObject', refresh);
|
||||
}
|
||||
|
||||
return patchViewCapability;
|
||||
return AdaptedViewController;
|
||||
});
|
||||
@@ -21,23 +21,18 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
'angular',
|
||||
'./Region'
|
||||
], function (
|
||||
angular,
|
||||
Region
|
||||
) {
|
||||
function MCTView(openmct) {
|
||||
function MCTView() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
restrict: 'A',
|
||||
link: function (scope, element, attrs) {
|
||||
var provider = openmct.objectViews.getByProviderKey(attrs.mctProviderKey);
|
||||
var view = new provider.view(scope.domainObject.useCapability('adapter'));
|
||||
var domElement = element[0];
|
||||
|
||||
view.show(domElement);
|
||||
|
||||
if (view.destroy) {
|
||||
scope.$on('$destroy', function () {
|
||||
view.destroy(domElement);
|
||||
});
|
||||
}
|
||||
var region = new Region(element[0]);
|
||||
scope.$watch(attrs.mctView, region.show.bind(region));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
45
src/adapter/directives/Region.js
Normal file
45
src/adapter/directives/Region.js
Normal file
@@ -0,0 +1,45 @@
|
||||
/*****************************************************************************
|
||||
* 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,
|
||||
legacyObject
|
||||
) {
|
||||
if (view.hasOwnProperty('provider')) {
|
||||
if (view.key === 'adapted-view') {
|
||||
var domainObject = legacyObject.useCapability('adapter');
|
||||
return view.provider.canView(domainObject);
|
||||
return this.openmct.mainViews.get(domainObject).length > 0;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -37,7 +37,8 @@ define(['EventEmitter'], function (EventEmitter) {
|
||||
this.key = 'local';
|
||||
this.cssClass = 'icon-clock';
|
||||
this.name = 'Local Clock';
|
||||
this.description = "Provides UTC timestamps every second from the local system clock.";
|
||||
this.description = "Updates every second, providing UTC timestamps from " +
|
||||
"user's local computer.";
|
||||
|
||||
this.period = period;
|
||||
this.timeoutHandle = undefined;
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global console */
|
||||
|
||||
define([], function () {
|
||||
/**
|
||||
@@ -29,7 +28,7 @@ define([], function () {
|
||||
* @memberof module:openmct
|
||||
*/
|
||||
function ViewRegistry() {
|
||||
this.providers = {};
|
||||
this.providers = [];
|
||||
}
|
||||
|
||||
|
||||
@@ -40,17 +39,9 @@ define([], function () {
|
||||
* which can provide views of this object
|
||||
*/
|
||||
ViewRegistry.prototype.get = function (item) {
|
||||
return this.getAllProviders()
|
||||
.filter(function (provider) {
|
||||
return provider.canView(item);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
ViewRegistry.prototype.getAllProviders = function () {
|
||||
return Object.values(this.providers);
|
||||
return this.providers.filter(function (provider) {
|
||||
return provider.canView(item);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -61,22 +52,7 @@ define([], function () {
|
||||
* @memberof module:openmct.ViewRegistry#
|
||||
*/
|
||||
ViewRegistry.prototype.addProvider = function (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];
|
||||
this.providers.push(provider);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -115,12 +91,6 @@ define([], function () {
|
||||
* Exposes types of views in Open MCT.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
|
||||
@@ -130,28 +100,15 @@ define([], function () {
|
||||
* When called by Open MCT, this may include additional arguments
|
||||
* which are on the path to the object to be viewed; for instance,
|
||||
* 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
|
||||
* @memberof module:openmct.ViewProvider#
|
||||
* @param {module:openmct.DomainObject} domainObject the domain object
|
||||
* to be viewed
|
||||
* @returns {boolean} 'true' if the view applies to the provided object,
|
||||
* 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.
|
||||
* @returns {boolean} true if this domain object can be viewed using
|
||||
* this provider
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -169,6 +126,27 @@ define([], function () {
|
||||
* @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;
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user