mirror of
https://github.com/nasa/openmct.git
synced 2025-06-26 11:09:22 +00:00
Compare commits
50 Commits
layout-imp
...
table-perf
Author | SHA1 | Date | |
---|---|---|---|
d026a67ac0 | |||
78018628ce | |||
0e30fba72d | |||
1c77ef142c | |||
853764d863 | |||
d0ab59f9da | |||
21e08709cb | |||
a1aa99837b | |||
037264b0bf | |||
1a06702dbe | |||
666bb41697 | |||
e254fafb5c | |||
1dc1cc6c24 | |||
baa5d10009 | |||
ac2b9acccb | |||
075d4deecb | |||
ac11f898d4 | |||
dd31de6935 | |||
9e811e722f | |||
8ef53d85c4 | |||
abcc5cb023 | |||
931871ff95 | |||
6b1e8862ef | |||
00ce246fc5 | |||
c0c7d96429 | |||
92b2582d0d | |||
4084a1ac86 | |||
cb1a1c2616 | |||
ce6c1f173e | |||
30a4888363 | |||
b0917a9866 | |||
464e5de947 | |||
47a07da17d | |||
ec4c443299 | |||
3122168b0e | |||
da3af4b3db | |||
850fa28bf6 | |||
270684c5fd | |||
afa1589cb5 | |||
18a94d938f | |||
d026bc2134 | |||
c0b7276787 | |||
bb8342f62b | |||
0d8dad1559 | |||
c1ef701eb2 | |||
c6a181a2e7 | |||
981392ea07 | |||
5928a102a6 | |||
c748569433 | |||
a87fc51fbb |
@ -37,25 +37,25 @@ define([
|
|||||||
},
|
},
|
||||||
LIMITS = {
|
LIMITS = {
|
||||||
rh: {
|
rh: {
|
||||||
cssClass: "s-limit-upr s-limit-red",
|
cssClass: "is-limit--upr is-limit--red",
|
||||||
low: RED,
|
low: RED,
|
||||||
high: Number.POSITIVE_INFINITY,
|
high: Number.POSITIVE_INFINITY,
|
||||||
name: "Red High"
|
name: "Red High"
|
||||||
},
|
},
|
||||||
rl: {
|
rl: {
|
||||||
cssClass: "s-limit-lwr s-limit-red",
|
cssClass: "is-limit--lwr is-limit--red",
|
||||||
high: -RED,
|
high: -RED,
|
||||||
low: Number.NEGATIVE_INFINITY,
|
low: Number.NEGATIVE_INFINITY,
|
||||||
name: "Red Low"
|
name: "Red Low"
|
||||||
},
|
},
|
||||||
yh: {
|
yh: {
|
||||||
cssClass: "s-limit-upr s-limit-yellow",
|
cssClass: "is-limit--upr is-limit--yellow",
|
||||||
low: YELLOW,
|
low: YELLOW,
|
||||||
high: RED,
|
high: RED,
|
||||||
name: "Yellow High"
|
name: "Yellow High"
|
||||||
},
|
},
|
||||||
yl: {
|
yl: {
|
||||||
cssClass: "s-limit-lwr s-limit-yellow",
|
cssClass: "is-limit--lwr is-limit--yellow",
|
||||||
low: -RED,
|
low: -RED,
|
||||||
high: -YELLOW,
|
high: -YELLOW,
|
||||||
name: "Yellow Low"
|
name: "Yellow Low"
|
||||||
|
@ -43,15 +43,14 @@ define([
|
|||||||
form: [
|
form: [
|
||||||
{
|
{
|
||||||
name: "State Duration (seconds)",
|
name: "State Duration (seconds)",
|
||||||
control: "textfield",
|
control: "numberfield",
|
||||||
cssClass: "l-input-sm l-numeric",
|
cssClass: "l-input-sm l-numeric",
|
||||||
key: "duration",
|
key: "duration",
|
||||||
required: true,
|
required: true,
|
||||||
property: [
|
property: [
|
||||||
"telemetry",
|
"telemetry",
|
||||||
"duration"
|
"duration"
|
||||||
],
|
]
|
||||||
pattern: "^\\d*(\\.\\d*)?$"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
initialize: function (object) {
|
initialize: function (object) {
|
||||||
|
210
index.html
210
index.html
@ -36,7 +36,9 @@
|
|||||||
<body>
|
<body>
|
||||||
</body>
|
</body>
|
||||||
<script>
|
<script>
|
||||||
var THIRTY_MINUTES = 30 * 60 * 1000;
|
const FIVE_MINUTES = 5 * 60 * 1000;
|
||||||
|
const THIRTY_MINUTES = 30 * 60 * 1000;
|
||||||
|
|
||||||
[
|
[
|
||||||
'example/eventGenerator',
|
'example/eventGenerator',
|
||||||
'example/styleguide'
|
'example/styleguide'
|
||||||
@ -49,7 +51,6 @@
|
|||||||
openmct.install(openmct.plugins.ExampleImagery());
|
openmct.install(openmct.plugins.ExampleImagery());
|
||||||
openmct.install(openmct.plugins.UTCTimeSystem());
|
openmct.install(openmct.plugins.UTCTimeSystem());
|
||||||
openmct.install(openmct.plugins.ImportExport());
|
openmct.install(openmct.plugins.ImportExport());
|
||||||
openmct.install(openmct.plugins.FixedView());
|
|
||||||
openmct.install(openmct.plugins.AutoflowView({
|
openmct.install(openmct.plugins.AutoflowView({
|
||||||
type: "telemetry.panel"
|
type: "telemetry.panel"
|
||||||
}));
|
}));
|
||||||
@ -68,8 +69,8 @@
|
|||||||
timeSystem: 'utc',
|
timeSystem: 'utc',
|
||||||
clock: 'local',
|
clock: 'local',
|
||||||
clockOffsets: {
|
clockOffsets: {
|
||||||
start: -25 * 60 * 1000,
|
start: - THIRTY_MINUTES,
|
||||||
end: 5 * 60 * 1000
|
end: FIVE_MINUTES
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -79,206 +80,7 @@
|
|||||||
openmct.install(openmct.plugins.FolderView());
|
openmct.install(openmct.plugins.FolderView());
|
||||||
openmct.install(openmct.plugins.Tabs());
|
openmct.install(openmct.plugins.Tabs());
|
||||||
openmct.install(openmct.plugins.FlexibleLayout());
|
openmct.install(openmct.plugins.FlexibleLayout());
|
||||||
openmct.time.clock('local', {start: -THIRTY_MINUTES, end: 0});
|
openmct.install(openmct.plugins.LADTable());
|
||||||
openmct.time.timeSystem('utc');
|
|
||||||
openmct.start();
|
openmct.start();
|
||||||
|
|
||||||
// openmct.toolbars.addProvider({
|
|
||||||
// name: "Testing Toolbar",
|
|
||||||
// key: "testing",
|
|
||||||
// description: "a mock toolbar that exercises all controls",
|
|
||||||
// forSelection: function (selection) {
|
|
||||||
// return true; // always applies.
|
|
||||||
// },
|
|
||||||
// toolbar: function (selection) {
|
|
||||||
// return [
|
|
||||||
// {
|
|
||||||
// control: 'menu',
|
|
||||||
// icon: 'icon-plus',
|
|
||||||
// label: 'Add',
|
|
||||||
// options: [
|
|
||||||
// { name: 'Box', class: 'icon-box', title: 'Add Box' },
|
|
||||||
// { name: 'Line', class: 'icon-line-horz', title: 'Add Line' },
|
|
||||||
// { name: 'Text', class: 'icon-font', title: 'Add Text' },
|
|
||||||
// { name: 'Image', class: 'icon-image', title: 'Add Image' }
|
|
||||||
// ]
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// control: 'separator'
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// control: 'color-picker',
|
|
||||||
// icon: 'icon-paint-bucket',
|
|
||||||
// value: '#33ff00',
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// control: 'color-picker',
|
|
||||||
// icon: 'icon-pencil',
|
|
||||||
// value: '#ffffff',
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// control: 'color-picker',
|
|
||||||
// icon: 'icon-font',
|
|
||||||
// value: '#333333',
|
|
||||||
// },
|
|
||||||
//
|
|
||||||
// {
|
|
||||||
// control: 'separator'
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// control: 'select-menu',
|
|
||||||
// value: 11,
|
|
||||||
// options: [
|
|
||||||
// { value: 9, name: '9 px' },
|
|
||||||
// { value: 10, name: '10 px' },
|
|
||||||
// { value: 11, name: '11 px' },
|
|
||||||
// { value: 12, name: '12 px' },
|
|
||||||
// { value: 13, name: '13 px' },
|
|
||||||
// { value: 14, name: '14 px' },
|
|
||||||
// { value: 16, name: '16 px' },
|
|
||||||
// { value: 18, name: '18 px' },
|
|
||||||
// { value: 20, name: '20 px' },
|
|
||||||
// { value: 24, name: '24 px' },
|
|
||||||
// { value: 28, name: '28 px' },
|
|
||||||
// { value: 32, name: '32 px' },
|
|
||||||
// { value: 40, name: '40 px' },
|
|
||||||
// { value: 48, name: '48 px' },
|
|
||||||
// { value: 56, name: '56 px' },
|
|
||||||
// { value: 64, name: '64 px' },
|
|
||||||
// { value: 72, name: '72 px' },
|
|
||||||
// { value: 80, name: '80 px' },
|
|
||||||
// { value: 88, name: '88 px' },
|
|
||||||
// { value: 96, name: '96 px' },
|
|
||||||
// { value: 128, name: '128 px' },
|
|
||||||
// { value: 160, name: '160 px' }
|
|
||||||
// ]
|
|
||||||
// },
|
|
||||||
//
|
|
||||||
// {
|
|
||||||
// control: 'separator'
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// control: 'menu',
|
|
||||||
// icon: 'icon-layers',
|
|
||||||
// options: [
|
|
||||||
// { name: 'Move to top', class: 'icon-arrow-double-up', title: 'Move to top' },
|
|
||||||
// { name: 'Move up', class: 'icon-arrow-up', title: 'Move up' },
|
|
||||||
// { name: 'Move down', class: 'icon-arrow-down', title: 'Move down' },
|
|
||||||
// { name: 'Move to bottom', class: 'icon-arrow-double-down', title: 'Move to bottom' }
|
|
||||||
// ]
|
|
||||||
// },
|
|
||||||
//
|
|
||||||
// {
|
|
||||||
// control: 'separator'
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// control: 'button',
|
|
||||||
// icon: 'icon-gear'
|
|
||||||
// },
|
|
||||||
//
|
|
||||||
// {
|
|
||||||
// control: 'separator'
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// control: 'input',
|
|
||||||
// type: 'number',
|
|
||||||
// label: 'X',
|
|
||||||
// value: 1,
|
|
||||||
// title: 'X position'
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// control: 'input',
|
|
||||||
// type: 'number',
|
|
||||||
// label: 'Y',
|
|
||||||
// value: 2,
|
|
||||||
// title: 'Y position'
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// control: 'input',
|
|
||||||
// type: 'number',
|
|
||||||
// label: 'W',
|
|
||||||
// value: 3,
|
|
||||||
// title: 'Width'
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// control: 'input',
|
|
||||||
// type: 'number',
|
|
||||||
// label: 'H',
|
|
||||||
// value: 4,
|
|
||||||
// title: 'Height'
|
|
||||||
// },
|
|
||||||
//
|
|
||||||
// {
|
|
||||||
// control: 'separator'
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// control: 'button',
|
|
||||||
// icon: 'icon-trash',
|
|
||||||
// label: 'delete',
|
|
||||||
// modifier: 'caution'
|
|
||||||
// },
|
|
||||||
//
|
|
||||||
// {
|
|
||||||
// control: 'separator'
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// control: 'checkbox',
|
|
||||||
// name: 'this is a checkbox',
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// control: 'separator'
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// control: 'toggle-button',
|
|
||||||
// title: 'Toggle Frame',
|
|
||||||
// property: 'hideFrame',
|
|
||||||
// value: false,
|
|
||||||
// options: [
|
|
||||||
// {
|
|
||||||
// value: true,
|
|
||||||
// icon: 'icon-frame-hide'
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// value: false,
|
|
||||||
// icon: 'icon-frame-show'
|
|
||||||
// }
|
|
||||||
// ]
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// control: 'toggle-button',
|
|
||||||
// title: 'Snap to grid',
|
|
||||||
// property: 'snapToGrid',
|
|
||||||
// value: true,
|
|
||||||
// options: [
|
|
||||||
// {
|
|
||||||
// value: true,
|
|
||||||
// icon: 'icon-grid-snap-to'
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// value: false,
|
|
||||||
// icon: 'icon-grid-snap-no'
|
|
||||||
// }
|
|
||||||
// ]
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// control: 'toggle-button',
|
|
||||||
// title: 'Toggle label',
|
|
||||||
// property: 'showLabel',
|
|
||||||
// value: true,
|
|
||||||
// options: [
|
|
||||||
// {
|
|
||||||
// value: true,
|
|
||||||
// icon: 'icon-two-parts-both'
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// value: false,
|
|
||||||
// icon: 'icon-two-parts-one-only'
|
|
||||||
// }
|
|
||||||
// ]
|
|
||||||
// }
|
|
||||||
// ];
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
@ -58,7 +58,6 @@
|
|||||||
"printj": "^1.1.0",
|
"printj": "^1.1.0",
|
||||||
"raw-loader": "^0.5.1",
|
"raw-loader": "^0.5.1",
|
||||||
"request": "^2.69.0",
|
"request": "^2.69.0",
|
||||||
"screenfull": "^3.3.2",
|
|
||||||
"split": "^1.0.0",
|
"split": "^1.0.0",
|
||||||
"style-loader": "^0.21.0",
|
"style-loader": "^0.21.0",
|
||||||
"v8-compile-cache": "^1.1.0",
|
"v8-compile-cache": "^1.1.0",
|
||||||
|
@ -31,7 +31,6 @@ define([
|
|||||||
"./src/navigation/NavigateAction",
|
"./src/navigation/NavigateAction",
|
||||||
"./src/navigation/OrphanNavigationHandler",
|
"./src/navigation/OrphanNavigationHandler",
|
||||||
"./src/windowing/NewTabAction",
|
"./src/windowing/NewTabAction",
|
||||||
"./src/windowing/FullscreenAction",
|
|
||||||
"./src/windowing/WindowTitler",
|
"./src/windowing/WindowTitler",
|
||||||
"./res/templates/browse.html",
|
"./res/templates/browse.html",
|
||||||
"./res/templates/browse-object.html",
|
"./res/templates/browse-object.html",
|
||||||
@ -53,7 +52,6 @@ define([
|
|||||||
NavigateAction,
|
NavigateAction,
|
||||||
OrphanNavigationHandler,
|
OrphanNavigationHandler,
|
||||||
NewTabAction,
|
NewTabAction,
|
||||||
FullscreenAction,
|
|
||||||
WindowTitler,
|
WindowTitler,
|
||||||
browseTemplate,
|
browseTemplate,
|
||||||
browseObjectTemplate,
|
browseObjectTemplate,
|
||||||
@ -225,13 +223,6 @@ define([
|
|||||||
"group": "windowing",
|
"group": "windowing",
|
||||||
"cssClass": "icon-new-window",
|
"cssClass": "icon-new-window",
|
||||||
"priority": "preferred"
|
"priority": "preferred"
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "fullscreen",
|
|
||||||
"implementation": FullscreenAction,
|
|
||||||
"category": "view-control",
|
|
||||||
"group": "windowing",
|
|
||||||
"priority": "default"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"runs": [
|
"runs": [
|
||||||
@ -265,18 +256,6 @@ define([
|
|||||||
key: "inspectorRegion",
|
key: "inspectorRegion",
|
||||||
template: inspectorRegionTemplate
|
template: inspectorRegionTemplate
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"licenses": [
|
|
||||||
{
|
|
||||||
"name": "screenfull.js",
|
|
||||||
"version": "1.2.0",
|
|
||||||
"description": "Wrapper for cross-browser usage of fullscreen API",
|
|
||||||
"author": "Sindre Sorhus",
|
|
||||||
"website": "https://github.com/sindresorhus/screenfull.js/",
|
|
||||||
"copyright": "Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)",
|
|
||||||
"license": "license-mit",
|
|
||||||
"link": "https://github.com/sindresorhus/screenfull.js/blob/gh-pages/license"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,64 +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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Module defining FullscreenAction. Created by vwoeltje on 11/18/14.
|
|
||||||
*/
|
|
||||||
define(
|
|
||||||
["screenfull"],
|
|
||||||
function (screenfull) {
|
|
||||||
|
|
||||||
var ENTER_FULLSCREEN = "Enter full screen mode",
|
|
||||||
EXIT_FULLSCREEN = "Exit full screen mode";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The fullscreen action toggles between fullscreen display
|
|
||||||
* and regular in-window display.
|
|
||||||
* @memberof platform/commonUI/browse
|
|
||||||
* @constructor
|
|
||||||
* @implements {Action}
|
|
||||||
*/
|
|
||||||
function FullscreenAction(context) {
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
FullscreenAction.prototype.perform = function () {
|
|
||||||
screenfull.toggle();
|
|
||||||
};
|
|
||||||
|
|
||||||
FullscreenAction.prototype.getMetadata = function () {
|
|
||||||
// We override getMetadata, because the icon cssClass and
|
|
||||||
// description need to be determined at run-time
|
|
||||||
// based on whether or not we are currently
|
|
||||||
// full screen.
|
|
||||||
var metadata = Object.create(FullscreenAction);
|
|
||||||
metadata.cssClass = screenfull.isFullscreen ? "icon-fullscreen-expand" : "icon-fullscreen-collapse";
|
|
||||||
metadata.description = screenfull.isFullscreen ?
|
|
||||||
EXIT_FULLSCREEN : ENTER_FULLSCREEN;
|
|
||||||
metadata.group = "windowing";
|
|
||||||
metadata.context = this.context;
|
|
||||||
return metadata;
|
|
||||||
};
|
|
||||||
|
|
||||||
return FullscreenAction;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,59 +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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MCTRepresentationSpec. Created by vwoeltje on 11/6/14.
|
|
||||||
*/
|
|
||||||
define(
|
|
||||||
["../../src/windowing/FullscreenAction", "screenfull"],
|
|
||||||
function (FullscreenAction, screenfull) {
|
|
||||||
|
|
||||||
describe("The fullscreen action", function () {
|
|
||||||
var action,
|
|
||||||
oldToggle;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
// Screenfull is not shimmed or injected, so
|
|
||||||
// we need to spy on it in the global scope.
|
|
||||||
oldToggle = screenfull.toggle;
|
|
||||||
|
|
||||||
screenfull.toggle = jasmine.createSpy("toggle");
|
|
||||||
|
|
||||||
action = new FullscreenAction({});
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(function () {
|
|
||||||
screenfull.toggle = oldToggle;
|
|
||||||
});
|
|
||||||
|
|
||||||
it("toggles fullscreen mode when performed", function () {
|
|
||||||
action.perform();
|
|
||||||
expect(screenfull.toggle).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("provides displayable metadata", function () {
|
|
||||||
expect(action.getMetadata().cssClass).toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -10,6 +10,16 @@
|
|||||||
ng-show="ngModel.progressPerc !== undefined"></mct-include>
|
ng-show="ngModel.progressPerc !== undefined"></mct-include>
|
||||||
</div>
|
</div>
|
||||||
<div class="bottom-bar">
|
<div class="bottom-bar">
|
||||||
|
<a ng-repeat="dialogOption in ngModel.options"
|
||||||
|
class="s-button"
|
||||||
|
ng-click="dialogOption.callback()">
|
||||||
|
{{dialogOption.label}}
|
||||||
|
</a>
|
||||||
|
<a class="s-button major"
|
||||||
|
ng-if="ngModel.primaryOption"
|
||||||
|
ng-click="ngModel.primaryOption.callback()">
|
||||||
|
{{ngModel.primaryOption.label}}
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -95,7 +95,10 @@ define(
|
|||||||
|
|
||||||
// Create the overlay element and add it to the document's body
|
// Create the overlay element and add it to the document's body
|
||||||
element = this.$compile(TEMPLATE)(scope);
|
element = this.$compile(TEMPLATE)(scope);
|
||||||
this.findBody().prepend(element);
|
|
||||||
|
// Append so that most recent dialog is last in DOM. This means the most recent dialog will be on top when
|
||||||
|
// multiple overlays with the same z-index are active.
|
||||||
|
this.findBody().append(element);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
dismiss: dismiss
|
dismiss: dismiss
|
||||||
|
@ -32,11 +32,7 @@ define([
|
|||||||
"./src/actions/SaveAndStopEditingAction",
|
"./src/actions/SaveAndStopEditingAction",
|
||||||
"./src/actions/SaveAsAction",
|
"./src/actions/SaveAsAction",
|
||||||
"./src/actions/CancelAction",
|
"./src/actions/CancelAction",
|
||||||
"./src/policies/EditActionPolicy",
|
|
||||||
"./src/policies/EditPersistableObjectsPolicy",
|
"./src/policies/EditPersistableObjectsPolicy",
|
||||||
"./src/policies/EditableLinkPolicy",
|
|
||||||
"./src/policies/EditableMovePolicy",
|
|
||||||
"./src/policies/EditContextualActionPolicy",
|
|
||||||
"./src/representers/EditRepresenter",
|
"./src/representers/EditRepresenter",
|
||||||
"./src/capabilities/EditorCapability",
|
"./src/capabilities/EditorCapability",
|
||||||
"./src/capabilities/TransactionCapabilityDecorator",
|
"./src/capabilities/TransactionCapabilityDecorator",
|
||||||
@ -67,11 +63,7 @@ define([
|
|||||||
SaveAndStopEditingAction,
|
SaveAndStopEditingAction,
|
||||||
SaveAsAction,
|
SaveAsAction,
|
||||||
CancelAction,
|
CancelAction,
|
||||||
EditActionPolicy,
|
|
||||||
EditPersistableObjectsPolicy,
|
EditPersistableObjectsPolicy,
|
||||||
EditableLinkPolicy,
|
|
||||||
EditableMovePolicy,
|
|
||||||
EditContextualActionPolicy,
|
|
||||||
EditRepresenter,
|
EditRepresenter,
|
||||||
EditorCapability,
|
EditorCapability,
|
||||||
TransactionCapabilityDecorator,
|
TransactionCapabilityDecorator,
|
||||||
@ -174,7 +166,7 @@ define([
|
|||||||
"name": "Remove",
|
"name": "Remove",
|
||||||
"description": "Remove this object from its containing object.",
|
"description": "Remove this object from its containing object.",
|
||||||
"depends": [
|
"depends": [
|
||||||
"dialogService",
|
"openmct",
|
||||||
"navigationService"
|
"navigationService"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -231,28 +223,11 @@ define([
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"policies": [
|
"policies": [
|
||||||
{
|
|
||||||
"category": "action",
|
|
||||||
"implementation": EditActionPolicy
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"category": "action",
|
"category": "action",
|
||||||
"implementation": EditPersistableObjectsPolicy,
|
"implementation": EditPersistableObjectsPolicy,
|
||||||
"depends": ["openmct"]
|
"depends": ["openmct"]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"category": "action",
|
|
||||||
"implementation": EditContextualActionPolicy,
|
|
||||||
"depends": ["navigationService", "editModeBlacklist", "nonEditContextBlacklist"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"category": "action",
|
|
||||||
"implementation": EditableMovePolicy
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"category": "action",
|
|
||||||
"implementation": EditableLinkPolicy
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"implementation": CreationPolicy,
|
"implementation": CreationPolicy,
|
||||||
"category": "creation"
|
"category": "creation"
|
||||||
@ -349,16 +324,6 @@ define([
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"constants": [
|
|
||||||
{
|
|
||||||
"key": "editModeBlacklist",
|
|
||||||
"value": ["copy", "follow", "link", "locate"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "nonEditContextBlacklist",
|
|
||||||
"value": ["copy", "follow", "properties", "move", "link", "remove", "locate"]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"capabilities": [
|
"capabilities": [
|
||||||
{
|
{
|
||||||
"key": "editor",
|
"key": "editor",
|
||||||
|
@ -42,9 +42,9 @@ define([
|
|||||||
* @constructor
|
* @constructor
|
||||||
* @implements {Action}
|
* @implements {Action}
|
||||||
*/
|
*/
|
||||||
function RemoveAction(dialogService, navigationService, context) {
|
function RemoveAction(openmct, navigationService, context) {
|
||||||
this.domainObject = (context || {}).domainObject;
|
this.domainObject = (context || {}).domainObject;
|
||||||
this.dialogService = dialogService;
|
this.openmct = openmct;
|
||||||
this.navigationService = navigationService;
|
this.navigationService = navigationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +53,6 @@ define([
|
|||||||
*/
|
*/
|
||||||
RemoveAction.prototype.perform = function () {
|
RemoveAction.prototype.perform = function () {
|
||||||
var dialog,
|
var dialog,
|
||||||
dialogService = this.dialogService,
|
|
||||||
domainObject = this.domainObject,
|
domainObject = this.domainObject,
|
||||||
navigationService = this.navigationService;
|
navigationService = this.navigationService;
|
||||||
/*
|
/*
|
||||||
@ -104,13 +103,13 @@ define([
|
|||||||
* capability. Based on object's location and selected object's location
|
* capability. Based on object's location and selected object's location
|
||||||
* user may be navigated to existing parent object
|
* user may be navigated to existing parent object
|
||||||
*/
|
*/
|
||||||
function removeFromContext(object) {
|
function removeFromContext() {
|
||||||
var contextCapability = object.getCapability('context'),
|
var contextCapability = domainObject.getCapability('context'),
|
||||||
parent = contextCapability.getParent();
|
parent = contextCapability.getParent();
|
||||||
|
|
||||||
// If currently within path of removed object(s),
|
// If currently within path of removed object(s),
|
||||||
// navigates to existing object up tree
|
// navigates to existing object up tree
|
||||||
checkObjectNavigation(object, parent);
|
checkObjectNavigation(domainObject, parent);
|
||||||
|
|
||||||
return parent.useCapability('mutation', doMutate);
|
return parent.useCapability('mutation', doMutate);
|
||||||
}
|
}
|
||||||
@ -119,7 +118,7 @@ define([
|
|||||||
* Pass in the function to remove the domain object so it can be
|
* Pass in the function to remove the domain object so it can be
|
||||||
* associated with an 'OK' button press
|
* associated with an 'OK' button press
|
||||||
*/
|
*/
|
||||||
dialog = new RemoveDialog(dialogService, domainObject, removeFromContext);
|
dialog = new RemoveDialog(this.openmct, domainObject, removeFromContext);
|
||||||
dialog.show();
|
dialog.show();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,8 +36,8 @@ define([], function () {
|
|||||||
* @memberof platform/commonUI/edit
|
* @memberof platform/commonUI/edit
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function RemoveDialog(dialogService, domainObject, removeCallback) {
|
function RemoveDialog(openmct, domainObject, removeCallback) {
|
||||||
this.dialogService = dialogService;
|
this.openmct = openmct;
|
||||||
this.domainObject = domainObject;
|
this.domainObject = domainObject;
|
||||||
this.removeCallback = removeCallback;
|
this.removeCallback = removeCallback;
|
||||||
}
|
}
|
||||||
@ -46,31 +46,26 @@ define([], function () {
|
|||||||
* Display a dialog to confirm the removal of a domain object.
|
* Display a dialog to confirm the removal of a domain object.
|
||||||
*/
|
*/
|
||||||
RemoveDialog.prototype.show = function () {
|
RemoveDialog.prototype.show = function () {
|
||||||
var dialog,
|
let dialog = this.openmct.overlays.dialog({
|
||||||
domainObject = this.domainObject,
|
title: 'Remove ' + this.domainObject.getModel().name,
|
||||||
removeCallback = this.removeCallback,
|
iconClass: 'alert',
|
||||||
model = {
|
message: 'Warning! This action will permanently remove this object. Are you sure you want to continue?',
|
||||||
title: 'Remove ' + domainObject.getModel().name,
|
buttons: [
|
||||||
actionText: 'Warning! This action will permanently remove this object. Are you sure you want to continue?',
|
{
|
||||||
severity: 'alert',
|
|
||||||
primaryOption: {
|
|
||||||
label: 'OK',
|
label: 'OK',
|
||||||
callback: function () {
|
callback: () => {
|
||||||
removeCallback(domainObject);
|
this.removeCallback();
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
options: [
|
{
|
||||||
{
|
label: 'Cancel',
|
||||||
label: 'Cancel',
|
callback: () => {
|
||||||
callback: function () {
|
dialog.dismiss();
|
||||||
dialog.dismiss();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
};
|
]
|
||||||
setTimeout(() => this.removeCallback(domainObject));
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return RemoveDialog;
|
return RemoveDialog;
|
||||||
|
@ -169,15 +169,17 @@ function (
|
|||||||
}
|
}
|
||||||
|
|
||||||
function saveAfterClone(clonedObject) {
|
function saveAfterClone(clonedObject) {
|
||||||
return domainObject.getCapability("editor").save()
|
return this.openmct.editor.save().then(() => {
|
||||||
.then(resolveWith(clonedObject));
|
// Force mutation for search indexing
|
||||||
|
clonedObject.useCapability('mutation', (model) => {
|
||||||
|
return model;
|
||||||
|
});
|
||||||
|
return clonedObject;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function finishEditing(clonedObject) {
|
function finishEditing(clonedObject) {
|
||||||
return domainObject.getCapability("editor").finish()
|
return fetchObject(clonedObject.getId())
|
||||||
.then(function () {
|
|
||||||
return fetchObject(clonedObject.getId());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSuccess(object) {
|
function onSuccess(object) {
|
||||||
|
@ -65,11 +65,10 @@ define(
|
|||||||
CreateAction.prototype.perform = function () {
|
CreateAction.prototype.perform = function () {
|
||||||
var newModel = this.type.getInitialModel(),
|
var newModel = this.type.getInitialModel(),
|
||||||
openmct = this.openmct,
|
openmct = this.openmct,
|
||||||
newObject,
|
newObject;
|
||||||
editAction;
|
|
||||||
|
|
||||||
function onSave() {
|
function onSave() {
|
||||||
openmct.editor.save();
|
// openmct.editor.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
function onCancel() {
|
function onCancel() {
|
||||||
@ -81,7 +80,6 @@ define(
|
|||||||
newObject = this.parent.useCapability('instantiation', newModel);
|
newObject = this.parent.useCapability('instantiation', newModel);
|
||||||
|
|
||||||
openmct.editor.edit();
|
openmct.editor.edit();
|
||||||
editAction = newObject.getCapability("action").getActions("edit")[0];
|
|
||||||
newObject.getCapability("action").perform("save-as").then(onSave, onCancel);
|
newObject.getCapability("action").perform("save-as").then(onSave, onCancel);
|
||||||
// TODO: support editing object without saving object first.
|
// TODO: support editing object without saving object first.
|
||||||
// Which means we have to toggle createwizard afterwards. For now,
|
// Which means we have to toggle createwizard afterwards. For now,
|
||||||
|
@ -1,111 +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 () {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Policy controlling when the `edit` and/or `properties` actions
|
|
||||||
* can appear as applicable actions of the `view-control` category
|
|
||||||
* (shown as buttons in the top-right of browse mode.)
|
|
||||||
* @memberof platform/commonUI/edit
|
|
||||||
* @constructor
|
|
||||||
* @implements {Policy.<Action, ActionContext>}
|
|
||||||
*/
|
|
||||||
function EditActionPolicy(policyService) {
|
|
||||||
this.policyService = policyService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a count of views which are not flagged as non-editable.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
EditActionPolicy.prototype.countEditableViews = function (context) {
|
|
||||||
var domainObject = context.domainObject,
|
|
||||||
count = 0,
|
|
||||||
type, views;
|
|
||||||
|
|
||||||
if (!domainObject) {
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
type = domainObject.getCapability('type');
|
|
||||||
views = domainObject.useCapability('view');
|
|
||||||
|
|
||||||
|
|
||||||
// A view is editable unless explicitly flagged as not
|
|
||||||
(views || []).forEach(function (view) {
|
|
||||||
if (isEditable(view) ||
|
|
||||||
(view.key === 'plot' && type.getKey() === 'telemetry.panel') ||
|
|
||||||
(view.key === 'table' && type.getKey() === 'table') ||
|
|
||||||
(view.key === 'rt-table' && type.getKey() === 'rttable')
|
|
||||||
) {
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function isEditable(view) {
|
|
||||||
if (typeof view.editable === Function) {
|
|
||||||
return view.editable(domainObject.useCapability('adapter'));
|
|
||||||
} else {
|
|
||||||
return view.editable === true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the domain object is currently being edited. If
|
|
||||||
* so, the edit action is not applicable.
|
|
||||||
* @param context
|
|
||||||
* @returns {*|boolean}
|
|
||||||
*/
|
|
||||||
function isEditing(context) {
|
|
||||||
var domainObject = (context || {}).domainObject;
|
|
||||||
return domainObject &&
|
|
||||||
domainObject.hasCapability('editor') &&
|
|
||||||
domainObject.getCapability('editor').isEditContextRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
EditActionPolicy.prototype.allow = function (action, context) {
|
|
||||||
var key = action.getMetadata().key,
|
|
||||||
category = (context || {}).category;
|
|
||||||
|
|
||||||
// Restrict 'edit' to cases where there are editable
|
|
||||||
// views (similarly, restrict 'properties' to when
|
|
||||||
// the converse is true), and where the domain object is not
|
|
||||||
// already being edited.
|
|
||||||
if (key === 'edit') {
|
|
||||||
return this.countEditableViews(context) > 0 && !isEditing(context);
|
|
||||||
} else if (key === 'properties' && category === 'view-control') {
|
|
||||||
return this.countEditableViews(context) < 1 && !isEditing(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Like all policies, allow by default.
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
return EditActionPolicy;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,75 +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 () {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Policy controlling whether the context menu is visible when
|
|
||||||
* objects are being edited
|
|
||||||
* @param navigationService
|
|
||||||
* @param editModeBlacklist A blacklist of actions disallowed from
|
|
||||||
* context menu when navigated object is being edited
|
|
||||||
* @param nonEditContextBlacklist A blacklist of actions disallowed
|
|
||||||
* from context menu of non-editable objects, when navigated object
|
|
||||||
* is being edited
|
|
||||||
* @constructor
|
|
||||||
* @param editModeBlacklist A blacklist of actions disallowed from
|
|
||||||
* context menu when navigated object is being edited
|
|
||||||
* @param nonEditContextBlacklist A blacklist of actions disallowed
|
|
||||||
* from context menu of non-editable objects, when navigated object
|
|
||||||
* @implements {Policy.<Action, ActionContext>}
|
|
||||||
*/
|
|
||||||
function EditContextualActionPolicy(navigationService, editModeBlacklist, nonEditContextBlacklist) {
|
|
||||||
this.navigationService = navigationService;
|
|
||||||
|
|
||||||
//The list of objects disallowed on target object when in edit mode
|
|
||||||
this.editModeBlacklist = editModeBlacklist;
|
|
||||||
//The list of objects disallowed on target object that is not in
|
|
||||||
// edit mode (ie. the context menu in the tree on the LHS).
|
|
||||||
this.nonEditContextBlacklist = nonEditContextBlacklist;
|
|
||||||
}
|
|
||||||
|
|
||||||
EditContextualActionPolicy.prototype.allow = function (action, context) {
|
|
||||||
var selectedObject = context.domainObject,
|
|
||||||
navigatedObject = this.navigationService.getNavigation(),
|
|
||||||
actionMetadata = action.getMetadata ? action.getMetadata() : {};
|
|
||||||
|
|
||||||
// FIXME: need to restore support for changing contextual actions
|
|
||||||
// based on edit mode.
|
|
||||||
// if (navigatedObject.hasCapability("editor") && navigatedObject.getCapability("editor").isEditContextRoot()) {
|
|
||||||
// if (selectedObject.hasCapability("editor") && selectedObject.getCapability("editor").inEditContext()) {
|
|
||||||
// return this.editModeBlacklist.indexOf(actionMetadata.key) === -1;
|
|
||||||
// } else {
|
|
||||||
// //Target is in the context menu
|
|
||||||
// return this.nonEditContextBlacklist.indexOf(actionMetadata.key) === -1;
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
return EditContextualActionPolicy;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,51 +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 () {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Policy suppressing links when the linked-to domain object is in
|
|
||||||
* edit mode. Domain objects being edited may not have been persisted,
|
|
||||||
* so creating links to these can result in inconsistent state.
|
|
||||||
*
|
|
||||||
* @memberof platform/commonUI/edit
|
|
||||||
* @constructor
|
|
||||||
* @implements {Policy.<View, DomainObject>}
|
|
||||||
*/
|
|
||||||
function EditableLinkPolicy() {
|
|
||||||
}
|
|
||||||
|
|
||||||
EditableLinkPolicy.prototype.allow = function (action, context) {
|
|
||||||
var key = action.getMetadata().key,
|
|
||||||
object;
|
|
||||||
|
|
||||||
if (key === 'link') {
|
|
||||||
object = context.selectedObject || context.domainObject;
|
|
||||||
return !(object.hasCapability("editor") && object.getCapability("editor").inEditContext());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Like all policies, allow by default.
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
return EditableLinkPolicy;
|
|
||||||
});
|
|
@ -1,52 +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 () {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Policy suppressing move actions among editable and non-editable
|
|
||||||
* domain objects.
|
|
||||||
* @memberof platform/commonUI/edit
|
|
||||||
* @constructor
|
|
||||||
* @implements {Policy.<View, DomainObject>}
|
|
||||||
*/
|
|
||||||
function EditableMovePolicy() {
|
|
||||||
}
|
|
||||||
|
|
||||||
EditableMovePolicy.prototype.allow = function (action, context) {
|
|
||||||
var domainObject = context.domainObject,
|
|
||||||
selectedObject = context.selectedObject,
|
|
||||||
key = action.getMetadata().key,
|
|
||||||
isDomainObjectEditing = domainObject.hasCapability('editor') &&
|
|
||||||
domainObject.getCapability('editor').inEditContext();
|
|
||||||
|
|
||||||
if (key === 'move' && isDomainObjectEditing) {
|
|
||||||
return !!selectedObject && selectedObject.hasCapability('editor') &&
|
|
||||||
selectedObject.getCapability('editor').inEditContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Like all policies, allow by default.
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
return EditableMovePolicy;
|
|
||||||
});
|
|
@ -1,49 +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 () {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Policy controlling which views should be visible in Edit mode.
|
|
||||||
* @memberof platform/commonUI/edit
|
|
||||||
* @constructor
|
|
||||||
* @implements {Policy.<View, DomainObject>}
|
|
||||||
*/
|
|
||||||
function EditableViewPolicy() {
|
|
||||||
}
|
|
||||||
|
|
||||||
EditableViewPolicy.prototype.allow = function (view, domainObject) {
|
|
||||||
// If a view is flagged as non-editable, only allow it
|
|
||||||
// while we're not in Edit mode.
|
|
||||||
if ((view || {}).editable === false) {
|
|
||||||
return !(domainObject.hasCapability('editor') && domainObject.getCapability('editor').inEditContext());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Like all policies, allow by default.
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
return EditableViewPolicy;
|
|
||||||
}
|
|
||||||
);
|
|
@ -29,7 +29,7 @@ define(
|
|||||||
actionContext,
|
actionContext,
|
||||||
capabilities,
|
capabilities,
|
||||||
mockContext,
|
mockContext,
|
||||||
mockDialogService,
|
mockOverlayAPI,
|
||||||
mockDomainObject,
|
mockDomainObject,
|
||||||
mockMutation,
|
mockMutation,
|
||||||
mockNavigationService,
|
mockNavigationService,
|
||||||
@ -68,9 +68,9 @@ define(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
mockDialogService = jasmine.createSpyObj(
|
mockOverlayAPI = jasmine.createSpyObj(
|
||||||
"dialogService",
|
"overlayAPI",
|
||||||
["showBlockingMessage"]
|
["dialog"]
|
||||||
);
|
);
|
||||||
|
|
||||||
mockNavigationService = jasmine.createSpyObj(
|
mockNavigationService = jasmine.createSpyObj(
|
||||||
@ -96,7 +96,7 @@ define(
|
|||||||
|
|
||||||
actionContext = { domainObject: mockDomainObject };
|
actionContext = { domainObject: mockDomainObject };
|
||||||
|
|
||||||
action = new RemoveAction(mockDialogService, mockNavigationService, actionContext);
|
action = new RemoveAction({overlays: mockOverlayAPI}, mockNavigationService, actionContext);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("only applies to objects with parents", function () {
|
it("only applies to objects with parents", function () {
|
||||||
@ -118,7 +118,7 @@ define(
|
|||||||
|
|
||||||
action.perform();
|
action.perform();
|
||||||
|
|
||||||
expect(mockDialogService.showBlockingMessage).toHaveBeenCalled();
|
expect(mockOverlayAPI.dialog).toHaveBeenCalled();
|
||||||
|
|
||||||
// Also check that no mutation happens at this point
|
// Also check that no mutation happens at this point
|
||||||
expect(mockParent.useCapability).not.toHaveBeenCalledWith("mutation", jasmine.any(Function));
|
expect(mockParent.useCapability).not.toHaveBeenCalledWith("mutation", jasmine.any(Function));
|
||||||
@ -158,13 +158,13 @@ define(
|
|||||||
mockGrandchildContext = jasmine.createSpyObj("context", ["getParent"]);
|
mockGrandchildContext = jasmine.createSpyObj("context", ["getParent"]);
|
||||||
mockRootContext = jasmine.createSpyObj("context", ["getParent"]);
|
mockRootContext = jasmine.createSpyObj("context", ["getParent"]);
|
||||||
|
|
||||||
mockDialogService.showBlockingMessage.and.returnValue(mockDialogHandle);
|
mockOverlayAPI.dialog.and.returnValue(mockDialogHandle);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("mutates the parent when performed", function () {
|
it("mutates the parent when performed", function () {
|
||||||
action.perform();
|
action.perform();
|
||||||
mockDialogService.showBlockingMessage.calls.mostRecent().args[0]
|
mockOverlayAPI.dialog.calls.mostRecent().args[0]
|
||||||
.primaryOption.callback();
|
.buttons[0].callback();
|
||||||
|
|
||||||
expect(mockMutation.invoke)
|
expect(mockMutation.invoke)
|
||||||
.toHaveBeenCalledWith(jasmine.any(Function));
|
.toHaveBeenCalledWith(jasmine.any(Function));
|
||||||
@ -174,8 +174,8 @@ define(
|
|||||||
var mutator, result;
|
var mutator, result;
|
||||||
|
|
||||||
action.perform();
|
action.perform();
|
||||||
mockDialogService.showBlockingMessage.calls.mostRecent().args[0]
|
mockOverlayAPI.dialog.calls.mostRecent().args[0]
|
||||||
.primaryOption.callback();
|
.buttons[0].callback();
|
||||||
|
|
||||||
mutator = mockMutation.invoke.calls.mostRecent().args[0];
|
mutator = mockMutation.invoke.calls.mostRecent().args[0];
|
||||||
result = mutator(model);
|
result = mutator(model);
|
||||||
@ -212,8 +212,8 @@ define(
|
|||||||
mockType.hasFeature.and.returnValue(true);
|
mockType.hasFeature.and.returnValue(true);
|
||||||
|
|
||||||
action.perform();
|
action.perform();
|
||||||
mockDialogService.showBlockingMessage.calls.mostRecent().args[0]
|
mockOverlayAPI.dialog.calls.mostRecent().args[0]
|
||||||
.primaryOption.callback();
|
.buttons[0].callback();
|
||||||
|
|
||||||
// Expects navigation to parent of domainObject (removed object)
|
// Expects navigation to parent of domainObject (removed object)
|
||||||
expect(mockNavigationService.setNavigation).toHaveBeenCalledWith(mockParent);
|
expect(mockNavigationService.setNavigation).toHaveBeenCalledWith(mockParent);
|
||||||
@ -242,8 +242,8 @@ define(
|
|||||||
mockType.hasFeature.and.returnValue(true);
|
mockType.hasFeature.and.returnValue(true);
|
||||||
|
|
||||||
action.perform();
|
action.perform();
|
||||||
mockDialogService.showBlockingMessage.calls.mostRecent().args[0]
|
mockOverlayAPI.dialog.calls.mostRecent().args[0]
|
||||||
.primaryOption.callback();
|
.buttons[0].callback();
|
||||||
|
|
||||||
// Expects no navigation to occur
|
// Expects no navigation to occur
|
||||||
expect(mockNavigationService.setNavigation).not.toHaveBeenCalled();
|
expect(mockNavigationService.setNavigation).not.toHaveBeenCalled();
|
||||||
|
@ -1,138 +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/policies/EditActionPolicy"],
|
|
||||||
function (EditActionPolicy) {
|
|
||||||
|
|
||||||
describe("The Edit action policy", function () {
|
|
||||||
var editableView,
|
|
||||||
nonEditableView,
|
|
||||||
testViews,
|
|
||||||
testContext,
|
|
||||||
mockDomainObject,
|
|
||||||
mockEditAction,
|
|
||||||
mockPropertiesAction,
|
|
||||||
mockTypeCapability,
|
|
||||||
mockEditorCapability,
|
|
||||||
capabilities,
|
|
||||||
plotView,
|
|
||||||
policy;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
mockDomainObject = jasmine.createSpyObj(
|
|
||||||
'domainObject',
|
|
||||||
[
|
|
||||||
'useCapability',
|
|
||||||
'hasCapability',
|
|
||||||
'getCapability'
|
|
||||||
]
|
|
||||||
);
|
|
||||||
mockEditorCapability = jasmine.createSpyObj('editorCapability', ['isEditContextRoot']);
|
|
||||||
mockTypeCapability = jasmine.createSpyObj('type', ['getKey']);
|
|
||||||
capabilities = {
|
|
||||||
'editor': mockEditorCapability,
|
|
||||||
'type': mockTypeCapability
|
|
||||||
};
|
|
||||||
|
|
||||||
mockEditAction = jasmine.createSpyObj('edit', ['getMetadata']);
|
|
||||||
mockPropertiesAction = jasmine.createSpyObj('edit', ['getMetadata']);
|
|
||||||
|
|
||||||
mockDomainObject.getCapability.and.callFake(function (capability) {
|
|
||||||
return capabilities[capability];
|
|
||||||
});
|
|
||||||
mockDomainObject.hasCapability.and.callFake(function (capability) {
|
|
||||||
return !!capabilities[capability];
|
|
||||||
});
|
|
||||||
|
|
||||||
editableView = { editable: true };
|
|
||||||
nonEditableView = { editable: false };
|
|
||||||
plotView = { key: "plot", editable: false };
|
|
||||||
testViews = [];
|
|
||||||
|
|
||||||
mockDomainObject.useCapability.and.callFake(function (c) {
|
|
||||||
// Provide test views, only for the view capability
|
|
||||||
return c === 'view' && testViews;
|
|
||||||
});
|
|
||||||
|
|
||||||
mockEditAction.getMetadata.and.returnValue({ key: 'edit' });
|
|
||||||
mockPropertiesAction.getMetadata.and.returnValue({ key: 'properties' });
|
|
||||||
|
|
||||||
testContext = {
|
|
||||||
domainObject: mockDomainObject,
|
|
||||||
category: 'view-control'
|
|
||||||
};
|
|
||||||
|
|
||||||
policy = new EditActionPolicy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows the edit action when there are editable views", function () {
|
|
||||||
testViews = [editableView];
|
|
||||||
expect(policy.allow(mockEditAction, testContext)).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows the edit properties action when there are no editable views", function () {
|
|
||||||
testViews = [nonEditableView, nonEditableView];
|
|
||||||
expect(policy.allow(mockPropertiesAction, testContext)).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("disallows the edit action when there are no editable views", function () {
|
|
||||||
testViews = [nonEditableView, nonEditableView];
|
|
||||||
expect(policy.allow(mockEditAction, testContext)).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("disallows the edit properties action when there are" +
|
|
||||||
" editable views", function () {
|
|
||||||
testViews = [editableView];
|
|
||||||
expect(policy.allow(mockPropertiesAction, testContext)).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("disallows the edit action when object is already being" +
|
|
||||||
" edited", function () {
|
|
||||||
testViews = [editableView];
|
|
||||||
mockEditorCapability.isEditContextRoot.and.returnValue(true);
|
|
||||||
expect(policy.allow(mockEditAction, testContext)).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows editing of panels in plot view", function () {
|
|
||||||
testViews = [plotView];
|
|
||||||
mockTypeCapability.getKey.and.returnValue('telemetry.panel');
|
|
||||||
|
|
||||||
expect(policy.allow(mockEditAction, testContext)).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("disallows editing of plot view when object not a panel type", function () {
|
|
||||||
testViews = [plotView];
|
|
||||||
mockTypeCapability.getKey.and.returnValue('something.else');
|
|
||||||
|
|
||||||
expect(policy.allow(mockEditAction, testContext)).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
it("allows the edit properties outside of the 'view-control' category", function () {
|
|
||||||
testViews = [nonEditableView];
|
|
||||||
testContext.category = "something-else";
|
|
||||||
expect(policy.allow(mockPropertiesAction, testContext)).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,120 +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.
|
|
||||||
*****************************************************************************/
|
|
||||||
/*global describe,it,expect,beforeEach,jasmine*/
|
|
||||||
|
|
||||||
define(
|
|
||||||
["../../src/policies/EditContextualActionPolicy"],
|
|
||||||
function (EditContextualActionPolicy) {
|
|
||||||
|
|
||||||
describe("The Edit contextual action policy", function () {
|
|
||||||
var policy,
|
|
||||||
navigationService,
|
|
||||||
mockAction,
|
|
||||||
context,
|
|
||||||
navigatedObject,
|
|
||||||
mockDomainObject,
|
|
||||||
mockEditorCapability,
|
|
||||||
metadata,
|
|
||||||
editModeBlacklist = ["copy", "follow", "window", "link", "locate"],
|
|
||||||
nonEditContextBlacklist = ["copy", "follow", "properties", "move", "link", "remove", "locate"];
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
mockEditorCapability = jasmine.createSpyObj("editorCapability", ["isEditContextRoot", "inEditContext"]);
|
|
||||||
|
|
||||||
navigatedObject = jasmine.createSpyObj("navigatedObject", ["hasCapability", "getCapability"]);
|
|
||||||
navigatedObject.getCapability.and.returnValue(mockEditorCapability);
|
|
||||||
navigatedObject.hasCapability.and.returnValue(false);
|
|
||||||
|
|
||||||
|
|
||||||
mockDomainObject = jasmine.createSpyObj("domainObject", ["hasCapability", "getCapability"]);
|
|
||||||
mockDomainObject.hasCapability.and.returnValue(false);
|
|
||||||
mockDomainObject.getCapability.and.returnValue(mockEditorCapability);
|
|
||||||
|
|
||||||
navigationService = jasmine.createSpyObj("navigationService", ["getNavigation"]);
|
|
||||||
navigationService.getNavigation.and.returnValue(navigatedObject);
|
|
||||||
|
|
||||||
metadata = {key: "move"};
|
|
||||||
mockAction = jasmine.createSpyObj("action", ["getMetadata"]);
|
|
||||||
mockAction.getMetadata.and.returnValue(metadata);
|
|
||||||
|
|
||||||
context = {domainObject: mockDomainObject};
|
|
||||||
|
|
||||||
policy = new EditContextualActionPolicy(navigationService, editModeBlacklist, nonEditContextBlacklist);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Allows all actions when navigated object not in edit mode', function () {
|
|
||||||
expect(policy.allow(mockAction, context)).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Allows "window" action when navigated object in edit mode,' +
|
|
||||||
' but selected object not in edit mode ', function () {
|
|
||||||
navigatedObject.hasCapability.and.returnValue(true);
|
|
||||||
mockEditorCapability.isEditContextRoot.and.returnValue(true);
|
|
||||||
metadata.key = "window";
|
|
||||||
expect(policy.allow(mockAction, context)).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Allows "remove" action when navigated object in edit mode,' +
|
|
||||||
' and selected object not editable, but its parent is.',
|
|
||||||
function () {
|
|
||||||
var mockParent = jasmine.createSpyObj("parentObject", ["hasCapability"]),
|
|
||||||
mockContextCapability = jasmine.createSpyObj("contextCapability", ["getParent"]);
|
|
||||||
|
|
||||||
mockParent.hasCapability.and.returnValue(true);
|
|
||||||
mockContextCapability.getParent.and.returnValue(mockParent);
|
|
||||||
navigatedObject.hasCapability.and.returnValue(true);
|
|
||||||
|
|
||||||
mockDomainObject.getCapability.and.returnValue(mockContextCapability);
|
|
||||||
mockDomainObject.hasCapability.and.callFake(function (capability) {
|
|
||||||
switch (capability) {
|
|
||||||
case "editor": return false;
|
|
||||||
case "context": return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
metadata.key = "remove";
|
|
||||||
|
|
||||||
expect(policy.allow(mockAction, context)).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Disallows "move" action when navigated object in edit mode,' +
|
|
||||||
' but selected object not in edit mode ', function () {
|
|
||||||
navigatedObject.hasCapability.and.returnValue(true);
|
|
||||||
mockEditorCapability.isEditContextRoot.and.returnValue(true);
|
|
||||||
mockEditorCapability.inEditContext.and.returnValue(false);
|
|
||||||
metadata.key = "move";
|
|
||||||
expect(policy.allow(mockAction, context)).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Disallows copy action when navigated object and' +
|
|
||||||
' selected object in edit mode', function () {
|
|
||||||
navigatedObject.hasCapability.and.returnValue(true);
|
|
||||||
mockDomainObject.hasCapability.and.returnValue(true);
|
|
||||||
mockEditorCapability.isEditContextRoot.and.returnValue(true);
|
|
||||||
mockEditorCapability.inEditContext.and.returnValue(true);
|
|
||||||
|
|
||||||
metadata.key = "copy";
|
|
||||||
expect(policy.allow(mockAction, context)).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,79 +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/policies/EditableViewPolicy"],
|
|
||||||
function (EditableViewPolicy) {
|
|
||||||
|
|
||||||
describe("The editable view policy", function () {
|
|
||||||
var mockDomainObject,
|
|
||||||
testMode,
|
|
||||||
policy;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
testMode = true; // Act as if we're in Edit mode by default
|
|
||||||
mockDomainObject = jasmine.createSpyObj(
|
|
||||||
'domainObject',
|
|
||||||
['hasCapability', 'getCapability']
|
|
||||||
);
|
|
||||||
mockDomainObject.getCapability.and.returnValue({
|
|
||||||
inEditContext: function () {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mockDomainObject.hasCapability.and.callFake(function (c) {
|
|
||||||
return (c === 'editor') && testMode;
|
|
||||||
});
|
|
||||||
|
|
||||||
policy = new EditableViewPolicy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("disallows views in edit mode that are flagged as non-editable", function () {
|
|
||||||
expect(policy.allow({ editable: false }, mockDomainObject))
|
|
||||||
.toBeFalsy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows views in edit mode that are flagged as editable", function () {
|
|
||||||
expect(policy.allow({ editable: true }, mockDomainObject))
|
|
||||||
.toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows any view outside of edit mode", function () {
|
|
||||||
var testViews = [
|
|
||||||
{ editable: false },
|
|
||||||
{ editable: true },
|
|
||||||
{ someKey: "some value" }
|
|
||||||
];
|
|
||||||
testMode = false; // Act as if we're not in Edit mode
|
|
||||||
|
|
||||||
testViews.forEach(function (testView) {
|
|
||||||
expect(policy.allow(testView, mockDomainObject)).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("treats views with no defined 'editable' property as editable", function () {
|
|
||||||
expect(policy.allow({ someKey: "some value" }, mockDomainObject))
|
|
||||||
.toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -31,7 +31,6 @@ define([
|
|||||||
"./src/controllers/TreeNodeController",
|
"./src/controllers/TreeNodeController",
|
||||||
"./src/controllers/ActionGroupController",
|
"./src/controllers/ActionGroupController",
|
||||||
"./src/controllers/ToggleController",
|
"./src/controllers/ToggleController",
|
||||||
"./src/controllers/ContextMenuController",
|
|
||||||
"./src/controllers/ClickAwayController",
|
"./src/controllers/ClickAwayController",
|
||||||
"./src/controllers/ViewSwitcherController",
|
"./src/controllers/ViewSwitcherController",
|
||||||
"./src/controllers/GetterSetterController",
|
"./src/controllers/GetterSetterController",
|
||||||
@ -49,8 +48,6 @@ define([
|
|||||||
"./src/directives/MCTSplitter",
|
"./src/directives/MCTSplitter",
|
||||||
"./src/directives/MCTTree",
|
"./src/directives/MCTTree",
|
||||||
"./src/directives/MCTIndicators",
|
"./src/directives/MCTIndicators",
|
||||||
"./src/directives/MCTPreview",
|
|
||||||
"./src/actions/MCTPreviewAction",
|
|
||||||
"./src/filters/ReverseFilter",
|
"./src/filters/ReverseFilter",
|
||||||
"./res/templates/bottombar.html",
|
"./res/templates/bottombar.html",
|
||||||
"./res/templates/controls/action-button.html",
|
"./res/templates/controls/action-button.html",
|
||||||
@ -65,13 +62,11 @@ define([
|
|||||||
"./res/templates/tree-node.html",
|
"./res/templates/tree-node.html",
|
||||||
"./res/templates/label.html",
|
"./res/templates/label.html",
|
||||||
"./res/templates/controls/action-group.html",
|
"./res/templates/controls/action-group.html",
|
||||||
"./res/templates/menu/context-menu.html",
|
|
||||||
"./res/templates/controls/switcher.html",
|
"./res/templates/controls/switcher.html",
|
||||||
"./res/templates/object-inspector.html",
|
"./res/templates/object-inspector.html",
|
||||||
"./res/templates/controls/selector.html",
|
"./res/templates/controls/selector.html",
|
||||||
"./res/templates/controls/datetime-picker.html",
|
"./res/templates/controls/datetime-picker.html",
|
||||||
"./res/templates/controls/datetime-field.html",
|
"./res/templates/controls/datetime-field.html",
|
||||||
"./res/templates/preview.html",
|
|
||||||
'legacyRegistry'
|
'legacyRegistry'
|
||||||
], function (
|
], function (
|
||||||
UrlService,
|
UrlService,
|
||||||
@ -84,7 +79,6 @@ define([
|
|||||||
TreeNodeController,
|
TreeNodeController,
|
||||||
ActionGroupController,
|
ActionGroupController,
|
||||||
ToggleController,
|
ToggleController,
|
||||||
ContextMenuController,
|
|
||||||
ClickAwayController,
|
ClickAwayController,
|
||||||
ViewSwitcherController,
|
ViewSwitcherController,
|
||||||
GetterSetterController,
|
GetterSetterController,
|
||||||
@ -102,8 +96,6 @@ define([
|
|||||||
MCTSplitter,
|
MCTSplitter,
|
||||||
MCTTree,
|
MCTTree,
|
||||||
MCTIndicators,
|
MCTIndicators,
|
||||||
MCTPreview,
|
|
||||||
MCTPreviewAction,
|
|
||||||
ReverseFilter,
|
ReverseFilter,
|
||||||
bottombarTemplate,
|
bottombarTemplate,
|
||||||
actionButtonTemplate,
|
actionButtonTemplate,
|
||||||
@ -118,13 +110,11 @@ define([
|
|||||||
treeNodeTemplate,
|
treeNodeTemplate,
|
||||||
labelTemplate,
|
labelTemplate,
|
||||||
actionGroupTemplate,
|
actionGroupTemplate,
|
||||||
contextMenuTemplate,
|
|
||||||
switcherTemplate,
|
switcherTemplate,
|
||||||
objectInspectorTemplate,
|
objectInspectorTemplate,
|
||||||
selectorTemplate,
|
selectorTemplate,
|
||||||
datetimePickerTemplate,
|
datetimePickerTemplate,
|
||||||
datetimeFieldTemplate,
|
datetimeFieldTemplate,
|
||||||
previewTemplate,
|
|
||||||
legacyRegistry
|
legacyRegistry
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@ -252,13 +242,6 @@ define([
|
|||||||
"key": "ToggleController",
|
"key": "ToggleController",
|
||||||
"implementation": ToggleController
|
"implementation": ToggleController
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"key": "ContextMenuController",
|
|
||||||
"implementation": ContextMenuController,
|
|
||||||
"depends": [
|
|
||||||
"$scope"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"key": "ClickAwayController",
|
"key": "ClickAwayController",
|
||||||
"implementation": ClickAwayController,
|
"implementation": ClickAwayController,
|
||||||
@ -394,31 +377,6 @@ define([
|
|||||||
"key": "mctIndicators",
|
"key": "mctIndicators",
|
||||||
"implementation": MCTIndicators,
|
"implementation": MCTIndicators,
|
||||||
"depends": ['openmct']
|
"depends": ['openmct']
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "mctPreview",
|
|
||||||
"implementation": MCTPreview,
|
|
||||||
"depends": [
|
|
||||||
"$document"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"actions": [
|
|
||||||
{
|
|
||||||
"key": "mct-preview-action",
|
|
||||||
"implementation": MCTPreviewAction,
|
|
||||||
"name": "Preview",
|
|
||||||
"cssClass": "hide-in-t-main-view icon-eye-open",
|
|
||||||
"description": "Preview in large dialog",
|
|
||||||
"category": [
|
|
||||||
"contextual",
|
|
||||||
"view-control"
|
|
||||||
],
|
|
||||||
"depends": [
|
|
||||||
"$compile",
|
|
||||||
"$rootScope"
|
|
||||||
],
|
|
||||||
"priority": "preferred"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"constants": [
|
"constants": [
|
||||||
@ -517,13 +475,6 @@ define([
|
|||||||
"action"
|
"action"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"key": "context-menu",
|
|
||||||
"template": contextMenuTemplate,
|
|
||||||
"uses": [
|
|
||||||
"action"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"key": "switcher",
|
"key": "switcher",
|
||||||
"template": switcherTemplate,
|
"template": switcherTemplate,
|
||||||
@ -534,10 +485,6 @@ define([
|
|||||||
{
|
{
|
||||||
"key": "object-inspector",
|
"key": "object-inspector",
|
||||||
"template": objectInspectorTemplate
|
"template": objectInspectorTemplate
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "mct-preview",
|
|
||||||
"template": previewTemplate
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"controls": [
|
"controls": [
|
||||||
|
@ -1,33 +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.
|
|
||||||
-->
|
|
||||||
<div class="menu-element context-menu-wrapper mobile-disable-select" ng-controller="ContextMenuController">
|
|
||||||
<div class="menu context-menu">
|
|
||||||
<ul>
|
|
||||||
<li ng-repeat="menuAction in menuActions"
|
|
||||||
ng-click="menuAction.perform()"
|
|
||||||
title="{{menuAction.getMetadata().description}}"
|
|
||||||
class="{{menuAction.getMetadata().cssClass}}">
|
|
||||||
{{menuAction.getMetadata().name}}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -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.
|
|
||||||
-->
|
|
||||||
<div class="t-frame-inner abs t-object-type-{{ domainObject.getModel().type }}" mct-preview>
|
|
||||||
<div class="abs object-browse-bar l-flex-row">
|
|
||||||
<div class="left flex-elem l-flex-row grows">
|
|
||||||
<mct-representation
|
|
||||||
key="'object-header-frame'"
|
|
||||||
mct-object="domainObject"
|
|
||||||
class="l-flex-row flex-elem object-header grows">
|
|
||||||
</mct-representation>
|
|
||||||
</div>
|
|
||||||
<div class="btn-bar right l-flex-row flex-elem flex-justify-end flex-fixed">
|
|
||||||
<mct-representation
|
|
||||||
key="'switcher'"
|
|
||||||
ng-model="representation"
|
|
||||||
mct-object="domainObject">
|
|
||||||
</mct-representation>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="abs object-holder">
|
|
||||||
<mct-representation
|
|
||||||
key="representation.selected.key"
|
|
||||||
mct-object="representation.selected.key && domainObject">
|
|
||||||
</mct-representation>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,55 +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 () {
|
|
||||||
|
|
||||||
var PREVIEW_TEMPLATE = '<mct-representation key="\'mct-preview\'"' +
|
|
||||||
'class="t-rep-frame holder"' +
|
|
||||||
'mct-object="domainObject">' +
|
|
||||||
'</mct-representation>';
|
|
||||||
|
|
||||||
function MCTPreviewAction($compile, $rootScope, context) {
|
|
||||||
context = context || {};
|
|
||||||
this.domainObject = context.selectedObject || context.domainObject;
|
|
||||||
this.$rootScope = $rootScope;
|
|
||||||
this.$compile = $compile;
|
|
||||||
}
|
|
||||||
|
|
||||||
MCTPreviewAction.prototype.perform = function () {
|
|
||||||
var newScope = this.$rootScope.$new();
|
|
||||||
newScope.domainObject = this.domainObject;
|
|
||||||
|
|
||||||
this.$compile(PREVIEW_TEMPLATE)(newScope);
|
|
||||||
};
|
|
||||||
|
|
||||||
MCTPreviewAction.appliesTo = function (context) {
|
|
||||||
var domainObject = (context || {}).domainObject,
|
|
||||||
status = domainObject.getCapability('status');
|
|
||||||
|
|
||||||
return !(status && status.get('editing'));
|
|
||||||
};
|
|
||||||
|
|
||||||
return MCTPreviewAction;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,51 +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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Module defining ContextMenuController. Created by vwoeltje on 11/17/14.
|
|
||||||
*/
|
|
||||||
define(
|
|
||||||
[],
|
|
||||||
function () {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Controller for the context menu. Maintains an up-to-date
|
|
||||||
* list of applicable actions (those from category "contextual")
|
|
||||||
*
|
|
||||||
* @memberof platform/commonUI/general
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function ContextMenuController($scope) {
|
|
||||||
// Refresh variable "menuActions" in the scope
|
|
||||||
function updateActions() {
|
|
||||||
$scope.menuActions = $scope.action ?
|
|
||||||
$scope.action.getActions({ category: 'contextual' }) :
|
|
||||||
[];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update using the action capability
|
|
||||||
$scope.$watch("action", updateActions);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ContextMenuController;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,64 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2016, 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(['zepto', '../services/Overlay'], function ($, Overlay) {
|
|
||||||
function MCTPreview($document) {
|
|
||||||
|
|
||||||
function link($scope, $element) {
|
|
||||||
var actions = $scope.domainObject.getCapability('action'),
|
|
||||||
notebookAction = actions.getActions({key: 'notebook-new-entry'})[0];
|
|
||||||
|
|
||||||
var notebookButton = notebookAction ?
|
|
||||||
[
|
|
||||||
{
|
|
||||||
class: 'icon-notebook new-notebook-entry',
|
|
||||||
title: 'New Notebook Entry',
|
|
||||||
clickHandler: function (event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
notebookAction.perform();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
] : [];
|
|
||||||
|
|
||||||
var overlayService = new Overlay({
|
|
||||||
$document: $document,
|
|
||||||
$element: $element[0],
|
|
||||||
$scope: $scope,
|
|
||||||
browseBarButtons: notebookButton
|
|
||||||
});
|
|
||||||
|
|
||||||
overlayService.toggleOverlay();
|
|
||||||
|
|
||||||
$scope.$on('$destroy', function () {
|
|
||||||
$element.remove();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
restrict: 'A',
|
|
||||||
link: link
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return MCTPreview;
|
|
||||||
|
|
||||||
});
|
|
@ -82,7 +82,7 @@ define(
|
|||||||
}
|
}
|
||||||
var searchPath = "?" + arr.join('&'),
|
var searchPath = "?" + arr.join('&'),
|
||||||
newTabPath =
|
newTabPath =
|
||||||
"index.html#" + this.urlForLocation(mode, domainObject) +
|
"#" + this.urlForLocation(mode, domainObject) +
|
||||||
searchPath;
|
searchPath;
|
||||||
return newTabPath;
|
return newTabPath;
|
||||||
};
|
};
|
||||||
|
@ -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(
|
|
||||||
["../../src/controllers/ContextMenuController"],
|
|
||||||
function (ContextMenuController) {
|
|
||||||
|
|
||||||
describe("The context menu controller", function () {
|
|
||||||
var mockScope,
|
|
||||||
mockActions,
|
|
||||||
controller;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
mockActions = jasmine.createSpyObj("action", ["getActions"]);
|
|
||||||
mockScope = jasmine.createSpyObj("$scope", ["$watch"]);
|
|
||||||
controller = new ContextMenuController(mockScope);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("watches scope that may change applicable actions", function () {
|
|
||||||
// The action capability
|
|
||||||
expect(mockScope.$watch).toHaveBeenCalledWith(
|
|
||||||
"action",
|
|
||||||
jasmine.any(Function)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("populates the scope with grouped and ungrouped actions", function () {
|
|
||||||
mockScope.action = mockActions;
|
|
||||||
mockScope.parameters = { category: "test" };
|
|
||||||
|
|
||||||
mockActions.getActions.and.returnValue(["a", "b", "c"]);
|
|
||||||
|
|
||||||
// Call the watch
|
|
||||||
mockScope.$watch.calls.mostRecent().args[1]();
|
|
||||||
|
|
||||||
// Should have grouped and ungrouped actions in scope now
|
|
||||||
expect(mockScope.menuActions.length).toEqual(3);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -43,12 +43,25 @@ define(
|
|||||||
* Launch a dialog showing a list of current notifications.
|
* Launch a dialog showing a list of current notifications.
|
||||||
*/
|
*/
|
||||||
$scope.showNotificationsList = function () {
|
$scope.showNotificationsList = function () {
|
||||||
|
let notificationsList = openmct.notifications.notifications.map(notification => {
|
||||||
|
if (notification.model.severity === 'alert' || notification.model.severity === 'info') {
|
||||||
|
notification.model.primaryOption = {
|
||||||
|
label: 'Dismiss',
|
||||||
|
callback: () => {
|
||||||
|
let currentIndex = notificationsList.indexOf(notification);
|
||||||
|
notification.dismiss();
|
||||||
|
notificationsList.splice(currentIndex, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return notification;
|
||||||
|
})
|
||||||
dialogService.getDialogResponse('overlay-message-list', {
|
dialogService.getDialogResponse('overlay-message-list', {
|
||||||
dialog: {
|
dialog: {
|
||||||
title: "Messages",
|
title: "Messages",
|
||||||
//Launch the message list dialog with the models
|
//Launch the message list dialog with the models
|
||||||
// from the notifications
|
// from the notifications
|
||||||
messages: openmct.notifications.notifications
|
messages: notificationsList
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -19,16 +19,14 @@
|
|||||||
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.
|
||||||
-->
|
-->
|
||||||
<div class="l-time-display l-digital l-clock s-clock" ng-controller="ClockController as clock">
|
<div class="c-clock l-time-display" ng-controller="ClockController as clock">
|
||||||
<div class="l-elem-wrapper">
|
<div class="c-clock__timezone">
|
||||||
<span class="l-elem timezone">
|
{{clock.zone()}}
|
||||||
{{clock.zone()}}
|
</div>
|
||||||
</span>
|
<div class="c-clock__value">
|
||||||
<span class="l-elem value active">
|
{{clock.text()}}
|
||||||
{{clock.text()}}
|
</div>
|
||||||
</span>
|
<div class="c-clock__ampm">
|
||||||
<span class="l-elem ampm">
|
{{clock.ampm()}}
|
||||||
{{clock.ampm()}}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -19,21 +19,19 @@
|
|||||||
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.
|
||||||
-->
|
-->
|
||||||
<div class="l-time-display l-digital l-timer s-timer s-state-{{timer.timerState}}" ng-controller="TimerController as timer">
|
<div class="c-timer is-{{timer.timerState}}" ng-controller="TimerController as timer">
|
||||||
<div class="l-elem-wrapper l-flex-row">
|
<div class="c-timer__controls">
|
||||||
<div class="l-elem-wrapper l-flex-row controls">
|
<button ng-click="timer.clickStopButton()"
|
||||||
<a ng-click="timer.clickStopButton()"
|
ng-hide="timer.timerState == 'stopped'"
|
||||||
title="Stop"
|
title="Reset"
|
||||||
class="flex-elem s-icon-button t-btn-stop icon-box"></a>
|
class="c-timer__ctrl-reset c-click-icon c-click-icon--major icon-reset"></button>
|
||||||
<a ng-click="timer.clickButton()"
|
<button ng-click="timer.clickButton()"
|
||||||
title="{{timer.buttonText()}}"
|
title="{{timer.buttonText()}}"
|
||||||
class="flex-elem s-icon-button t-btn-pauseplay {{timer.buttonCssClass()}}"></a>
|
class="c-timer__ctrl-pause-play c-click-icon c-click-icon--major {{timer.buttonCssClass()}}"></button>
|
||||||
</div>
|
</div>
|
||||||
<span class="flex-elem l-value {{timer.signClass()}}">
|
<div class="c-timer__direction {{timer.signClass()}}"
|
||||||
<span class="value"
|
ng-hide="!timer.signClass()"></div>
|
||||||
ng-class="{ active:timer.text() }">{{timer.text() || "--:--:--"}}
|
<div class="c-timer__value">{{timer.text() || "--:--:--"}}
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
<span ng-controller="RefreshingController"></span>
|
|
||||||
</div>
|
</div>
|
||||||
|
<span class="c-timer__ng-controller u-contents" ng-controller="RefreshingController"></span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,475 +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/FixedController",
|
|
||||||
"./templates/fixed.html",
|
|
||||||
"./templates/frame.html",
|
|
||||||
"./templates/elements/telemetry.html",
|
|
||||||
"./templates/elements/box.html",
|
|
||||||
"./templates/elements/line.html",
|
|
||||||
"./templates/elements/text.html",
|
|
||||||
"./templates/elements/image.html",
|
|
||||||
"legacyRegistry"
|
|
||||||
], function (
|
|
||||||
FixedController,
|
|
||||||
fixedTemplate,
|
|
||||||
frameTemplate,
|
|
||||||
telemetryTemplate,
|
|
||||||
boxTemplate,
|
|
||||||
lineTemplate,
|
|
||||||
textTemplate,
|
|
||||||
imageTemplate,
|
|
||||||
legacyRegistry
|
|
||||||
) {
|
|
||||||
return function() {
|
|
||||||
return function (openmct) {
|
|
||||||
openmct.legacyRegistry.register("platform/features/fixed", {
|
|
||||||
"name": "Fixed position components.",
|
|
||||||
"description": "Plug in adding Fixed Position object type.",
|
|
||||||
"extensions": {
|
|
||||||
"views": [
|
|
||||||
{
|
|
||||||
"key": "fixed-display",
|
|
||||||
"name": "Fixed Position Display",
|
|
||||||
"cssClass": "icon-box-with-dashed-lines",
|
|
||||||
"type": "telemetry.fixed",
|
|
||||||
"template": fixedTemplate,
|
|
||||||
"uses": ["composition"],
|
|
||||||
"editable": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"templates": [
|
|
||||||
{
|
|
||||||
"key": "fixed.telemetry",
|
|
||||||
"template": telemetryTemplate
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "fixed.box",
|
|
||||||
"template": boxTemplate
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "fixed.line",
|
|
||||||
"template": lineTemplate
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "fixed.text",
|
|
||||||
"template": textTemplate
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "fixed.image",
|
|
||||||
"template": imageTemplate
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"controllers": [
|
|
||||||
{
|
|
||||||
"key": "FixedController",
|
|
||||||
"implementation": FixedController,
|
|
||||||
"depends": [
|
|
||||||
"$scope",
|
|
||||||
"$q",
|
|
||||||
"dialogService",
|
|
||||||
"openmct",
|
|
||||||
"$element"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"toolbars": [
|
|
||||||
{
|
|
||||||
name: "Fixed Position Toolbar",
|
|
||||||
key: "fixed.position",
|
|
||||||
description: "Toolbar for the selected element inside a fixed position display.",
|
|
||||||
forSelection: function (selection) {
|
|
||||||
if (!selection) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (openmct.editor.isEditing() &&
|
|
||||||
selection[0] && selection[0].context.elementProxy &&
|
|
||||||
((selection[1] && selection[1].context.item.type === 'telemetry.fixed') ||
|
|
||||||
(selection[0] && selection[0].context.item && selection[0].context.item.type === 'telemetry.fixed')));
|
|
||||||
},
|
|
||||||
toolbar: function (selection) {
|
|
||||||
var imageProperties = ["add", "remove", "order", "stroke", "useGrid", "x", "y", "height", "width", "url"];
|
|
||||||
var boxProperties = ["add", "remove", "order", "stroke", "useGrid", "x", "y", "height", "width", "fill"];
|
|
||||||
var textProperties = ["add", "remove", "order", "stroke", "useGrid", "x", "y", "height", "width", "fill", "color", "size", "text"];
|
|
||||||
var lineProperties = ["add", "remove", "order", "stroke", "useGrid", "x", "y", "x2", "y2"];
|
|
||||||
var telemetryProperties = ["add", "remove", "order", "stroke", "useGrid", "x", "y", "height", "width", "fill", "color", "size", "titled"];
|
|
||||||
var fixedPageProperties = ["add"];
|
|
||||||
|
|
||||||
var properties = [],
|
|
||||||
fixedItem = selection[0] && selection[0].context.item,
|
|
||||||
elementProxy = selection[0] && selection[0].context.elementProxy,
|
|
||||||
domainObject = selection[1] && selection[1].context.item,
|
|
||||||
path;
|
|
||||||
|
|
||||||
if (elementProxy) {
|
|
||||||
var type = elementProxy.element.type;
|
|
||||||
path = "configuration['fixed-display'].elements[" + elementProxy.index + "]";
|
|
||||||
properties =
|
|
||||||
type === 'fixed.image' ? imageProperties :
|
|
||||||
type === 'fixed.text' ? textProperties :
|
|
||||||
type === 'fixed.box' ? boxProperties :
|
|
||||||
type === 'fixed.line' ? lineProperties :
|
|
||||||
type === 'fixed.telemetry' ? telemetryProperties : [];
|
|
||||||
} else if (fixedItem) {
|
|
||||||
properties = domainObject && domainObject.type === 'layout' ? [] : fixedPageProperties;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
control: "menu",
|
|
||||||
domainObject: domainObject || selection[0].context.item,
|
|
||||||
method: function (option) {
|
|
||||||
selection[0].context.fixedController.add(option.key);
|
|
||||||
},
|
|
||||||
key: "add",
|
|
||||||
icon: "icon-plus",
|
|
||||||
label: "Add",
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
"name": "Box",
|
|
||||||
"class": "icon-box",
|
|
||||||
"key": "fixed.box"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Line",
|
|
||||||
"class": "icon-line-horz",
|
|
||||||
"key": "fixed.line"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Text",
|
|
||||||
"class": "icon-T",
|
|
||||||
"key": "fixed.text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Image",
|
|
||||||
"class": "icon-image",
|
|
||||||
"key": "fixed.image"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "menu",
|
|
||||||
domainObject: domainObject,
|
|
||||||
method: function (option) {
|
|
||||||
console.log('option', option)
|
|
||||||
selection[0].context.fixedController.order(
|
|
||||||
selection[0].context.elementProxy,
|
|
||||||
option.key
|
|
||||||
);
|
|
||||||
},
|
|
||||||
key: "order",
|
|
||||||
icon: "icon-layers",
|
|
||||||
title: "Move the selected object above or below other objects",
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
"name": "Move to Top",
|
|
||||||
"class": "icon-arrow-double-up",
|
|
||||||
"key": "top"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Move Up",
|
|
||||||
"class": "icon-arrow-up",
|
|
||||||
"key": "up"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Move Down",
|
|
||||||
"class": "icon-arrow-down",
|
|
||||||
"key": "down"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Move to Bottom",
|
|
||||||
"class": "icon-arrow-double-down",
|
|
||||||
"key": "bottom"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "color-picker",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".fill",
|
|
||||||
icon: "icon-paint-bucket",
|
|
||||||
title: "Set fill color",
|
|
||||||
key: 'fill'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "color-picker",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".stroke",
|
|
||||||
icon: "icon-line-horz",
|
|
||||||
title: "Set border color",
|
|
||||||
key: 'stroke'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "button",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".url",
|
|
||||||
icon: "icon-image",
|
|
||||||
title: "Edit image properties",
|
|
||||||
key: 'url',
|
|
||||||
dialog: {
|
|
||||||
control: "input",
|
|
||||||
type: "text",
|
|
||||||
name: "Image URL",
|
|
||||||
class: "l-input-lg",
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "color-picker",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".color",
|
|
||||||
icon: "icon-T",
|
|
||||||
mandatory: true,
|
|
||||||
title: "Set text color",
|
|
||||||
key: 'color'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "select-menu",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".size",
|
|
||||||
title: "Set text size",
|
|
||||||
key: 'size',
|
|
||||||
options: [9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 30, 36, 48, 72, 96].map(function (size) {
|
|
||||||
return { "value": size + "px"};
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "input",
|
|
||||||
type: "number",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".x",
|
|
||||||
label: "X",
|
|
||||||
title: "X position",
|
|
||||||
key: "x",
|
|
||||||
class: "l-input-sm",
|
|
||||||
min: "0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "input",
|
|
||||||
type: "number",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".y",
|
|
||||||
label: "Y",
|
|
||||||
title: "Y position",
|
|
||||||
key: "y",
|
|
||||||
class: "l-input-sm",
|
|
||||||
min: "0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "input",
|
|
||||||
type: "number",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".x",
|
|
||||||
label: "X1",
|
|
||||||
title: "X1 position",
|
|
||||||
key: "x1",
|
|
||||||
class: "l-input-sm",
|
|
||||||
min: "0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "input",
|
|
||||||
type: "number",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".y",
|
|
||||||
label: "Y1",
|
|
||||||
title: "Y1 position",
|
|
||||||
key: "y1",
|
|
||||||
class: "l-input-sm",
|
|
||||||
min: "0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "input",
|
|
||||||
type: "number",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".x2",
|
|
||||||
label: "X2",
|
|
||||||
title: "X2 position",
|
|
||||||
key: "x2",
|
|
||||||
class: "l-input-sm",
|
|
||||||
min: "0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "input",
|
|
||||||
type: "number",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".y2",
|
|
||||||
label: "Y2",
|
|
||||||
title: "Y2 position",
|
|
||||||
key: "y2",
|
|
||||||
class: "l-input-sm",
|
|
||||||
min: "0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "input",
|
|
||||||
type: "number",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".height",
|
|
||||||
label: "H",
|
|
||||||
title: "Resize object height",
|
|
||||||
key: "height",
|
|
||||||
class: "l-input-sm",
|
|
||||||
min: "1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "input",
|
|
||||||
type: "number",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".width",
|
|
||||||
label: "W",
|
|
||||||
title: "Resize object width",
|
|
||||||
key: "width",
|
|
||||||
class: "l-input-sm",
|
|
||||||
min: "1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "toggle-button",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".useGrid",
|
|
||||||
key: "useGrid",
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
value: true,
|
|
||||||
icon: 'icon-grid-snap-to',
|
|
||||||
title: 'Snap to grid'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: false,
|
|
||||||
icon: 'icon-grid-snap-no',
|
|
||||||
title: "Do not snap to grid"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "button",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".text",
|
|
||||||
icon: "icon-gear",
|
|
||||||
title: "Edit text properties",
|
|
||||||
key: "text",
|
|
||||||
dialog: {
|
|
||||||
control: "input",
|
|
||||||
type: "text",
|
|
||||||
name: "Text",
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "toggle-button",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".titled",
|
|
||||||
key: "titled",
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
value: true,
|
|
||||||
icon: 'icon-two-parts-both',
|
|
||||||
title: 'Show label'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: false,
|
|
||||||
icon: 'icon-two-parts-one-only',
|
|
||||||
title: "Hide label"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "button",
|
|
||||||
domainObject: domainObject,
|
|
||||||
method: function () {
|
|
||||||
selection[0].context.fixedController.remove(
|
|
||||||
selection[0].context.elementProxy
|
|
||||||
);
|
|
||||||
},
|
|
||||||
key: "remove",
|
|
||||||
icon: "icon-trash"
|
|
||||||
}
|
|
||||||
].filter(function (item) {
|
|
||||||
var filtered;
|
|
||||||
|
|
||||||
properties.forEach(function (property) {
|
|
||||||
if (item.property && item.key === property ||
|
|
||||||
item.method && item.key === property) {
|
|
||||||
filtered = item;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return filtered;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"key": "telemetry.fixed",
|
|
||||||
"name": "Fixed Position Display",
|
|
||||||
"cssClass": "icon-box-with-dashed-lines",
|
|
||||||
"description": "Collect and display telemetry elements in " +
|
|
||||||
"alphanumeric format in a simple canvas workspace. " +
|
|
||||||
"Elements can be positioned and sized. " +
|
|
||||||
"Lines, boxes and images can be added as well.",
|
|
||||||
"priority": 899,
|
|
||||||
"delegates": [
|
|
||||||
"telemetry"
|
|
||||||
],
|
|
||||||
"features": "creation",
|
|
||||||
"contains": [
|
|
||||||
{
|
|
||||||
"has": "telemetry"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"model": {
|
|
||||||
"layoutGrid": [64, 16],
|
|
||||||
"composition": []
|
|
||||||
},
|
|
||||||
"properties": [
|
|
||||||
{
|
|
||||||
"name": "Layout Grid",
|
|
||||||
"control": "composite",
|
|
||||||
"items": [
|
|
||||||
{
|
|
||||||
"name": "Horizontal grid (px)",
|
|
||||||
"control": "textfield",
|
|
||||||
"cssClass": "l-input-sm l-numeric"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Vertical grid (px)",
|
|
||||||
"control": "textfield",
|
|
||||||
"cssClass": "l-input-sm l-numeric"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"pattern": "^(\\d*[1-9]\\d*)?$",
|
|
||||||
"property": "layoutGrid",
|
|
||||||
"conversion": "number[]"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"views": [
|
|
||||||
"fixed-display"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
openmct.legacyRegistry.enable("platform/features/fixed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
@ -1,720 +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(
|
|
||||||
[
|
|
||||||
'lodash',
|
|
||||||
'./FixedProxy',
|
|
||||||
'./elements/ElementProxies',
|
|
||||||
'./FixedDragHandle',
|
|
||||||
'../../../../src/api/objects/object-utils'
|
|
||||||
],
|
|
||||||
function (
|
|
||||||
_,
|
|
||||||
FixedProxy,
|
|
||||||
ElementProxies,
|
|
||||||
FixedDragHandle,
|
|
||||||
objectUtils
|
|
||||||
) {
|
|
||||||
|
|
||||||
var DEFAULT_DIMENSIONS = [2, 1];
|
|
||||||
|
|
||||||
// Convert from element x/y/width/height to an
|
|
||||||
// appropriate ng-style argument, to position elements.
|
|
||||||
function convertPosition(elementProxy) {
|
|
||||||
if (elementProxy.getStyle) {
|
|
||||||
return elementProxy.getStyle();
|
|
||||||
}
|
|
||||||
|
|
||||||
var gridSize = elementProxy.getGridSize();
|
|
||||||
|
|
||||||
// Multiply position/dimensions by grid size
|
|
||||||
return {
|
|
||||||
left: (gridSize[0] * elementProxy.element.x) + 'px',
|
|
||||||
top: (gridSize[1] * elementProxy.element.y) + 'px',
|
|
||||||
width: (gridSize[0] * elementProxy.element.width) + 'px',
|
|
||||||
height: (gridSize[1] * elementProxy.element.height) + 'px'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The FixedController is responsible for supporting the
|
|
||||||
* Fixed Position view. It arranges frames according to saved
|
|
||||||
* configuration and provides methods for updating these based on
|
|
||||||
* mouse movement.
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
* @param {Scope} $scope the controller's Angular scope
|
|
||||||
*/
|
|
||||||
function FixedController($scope, $q, dialogService, openmct, $element) {
|
|
||||||
this.names = {}; // Cache names by ID
|
|
||||||
this.values = {}; // Cache values by ID
|
|
||||||
this.elementProxiesById = {};
|
|
||||||
this.telemetryObjects = {};
|
|
||||||
this.subscriptions = {};
|
|
||||||
this.openmct = openmct;
|
|
||||||
this.$element = $element;
|
|
||||||
this.$scope = $scope;
|
|
||||||
this.dialogService = dialogService;
|
|
||||||
this.$q = $q;
|
|
||||||
this.newDomainObject = $scope.domainObject.useCapability('adapter');
|
|
||||||
this.fixedViewSelectable = false;
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
[
|
|
||||||
'digest',
|
|
||||||
'fetchHistoricalData',
|
|
||||||
'getTelemetry',
|
|
||||||
'setDisplayedValue',
|
|
||||||
'subscribeToObject',
|
|
||||||
'unsubscribe',
|
|
||||||
'updateView'
|
|
||||||
].forEach(function (name) {
|
|
||||||
self[name] = self[name].bind(self);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Decorate an element for display
|
|
||||||
function makeProxyElement(element, index, elements) {
|
|
||||||
var ElementProxy = ElementProxies[element.type],
|
|
||||||
e = ElementProxy && new ElementProxy(element, index, elements, self.gridSize);
|
|
||||||
|
|
||||||
if (e) {
|
|
||||||
// Provide a displayable position (convert from grid to px)
|
|
||||||
e.style = convertPosition(e);
|
|
||||||
// Template names are same as type names, presently
|
|
||||||
e.template = element.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decorate elements in the current configuration
|
|
||||||
function refreshElements() {
|
|
||||||
var elements = (((self.newDomainObject.configuration || {})['fixed-display'] || {}).elements || []);
|
|
||||||
|
|
||||||
// Create the new proxies...
|
|
||||||
self.elementProxies = elements.map(makeProxyElement);
|
|
||||||
|
|
||||||
if (self.selectedElementProxy) {
|
|
||||||
// If selection is not in array, select parent.
|
|
||||||
// Otherwise, set the element to select after refresh.
|
|
||||||
var index = elements.indexOf(self.selectedElementProxy.element);
|
|
||||||
if (index === -1) {
|
|
||||||
self.$element[0].click();
|
|
||||||
} else if (!self.elementToSelectAfterRefresh) {
|
|
||||||
self.elementToSelectAfterRefresh = self.elementProxies[index].element;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, rebuild lists of elements by id to
|
|
||||||
// facilitate faster update when new telemetry comes in.
|
|
||||||
self.elementProxiesById = {};
|
|
||||||
self.elementProxies.forEach(function (elementProxy) {
|
|
||||||
var id = elementProxy.id;
|
|
||||||
if (elementProxy.element.type === 'fixed.telemetry') {
|
|
||||||
// Provide it a cached name/value to avoid flashing
|
|
||||||
elementProxy.name = self.names[id];
|
|
||||||
elementProxy.value = self.values[id];
|
|
||||||
self.elementProxiesById[id] = self.elementProxiesById[id] || [];
|
|
||||||
self.elementProxiesById[id].push(elementProxy);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trigger a new query for telemetry data
|
|
||||||
function updateDisplayBounds(bounds, isTick) {
|
|
||||||
if (!isTick) {
|
|
||||||
//Reset values
|
|
||||||
self.values = {};
|
|
||||||
refreshElements();
|
|
||||||
|
|
||||||
//Fetch new data
|
|
||||||
Object.values(self.telemetryObjects).forEach(function (object) {
|
|
||||||
self.fetchHistoricalData(object);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add an element to this view
|
|
||||||
function addElement(element) {
|
|
||||||
var index;
|
|
||||||
var elements = (((self.newDomainObject.configuration || {})['fixed-display'] || {}).elements || []);
|
|
||||||
elements.push(element);
|
|
||||||
|
|
||||||
if (self.selectedElementProxy) {
|
|
||||||
index = elements.indexOf(self.selectedElementProxy.element);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.mutate("configuration['fixed-display'].elements", elements);
|
|
||||||
elements = (self.newDomainObject.configuration)['fixed-display'].elements || [];
|
|
||||||
self.elementToSelectAfterRefresh = elements[elements.length - 1];
|
|
||||||
|
|
||||||
if (self.selectedElementProxy) {
|
|
||||||
// Update the selected element with the new
|
|
||||||
// value since newDomainOject is mutated.
|
|
||||||
self.selectedElementProxy.element = elements[index];
|
|
||||||
}
|
|
||||||
refreshElements();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Position a panel after a drop event
|
|
||||||
function handleDrop(e, id, position) {
|
|
||||||
// Don't handle this event if it has already been handled
|
|
||||||
if (e.defaultPrevented) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
// Store the position of this element.
|
|
||||||
// color is set to "" to let the CSS theme determine the default color
|
|
||||||
addElement({
|
|
||||||
type: "fixed.telemetry",
|
|
||||||
x: Math.floor(position.x / self.gridSize[0]),
|
|
||||||
y: Math.floor(position.y / self.gridSize[1]),
|
|
||||||
id: id,
|
|
||||||
stroke: "transparent",
|
|
||||||
color: "",
|
|
||||||
titled: true,
|
|
||||||
width: DEFAULT_DIMENSIONS[0],
|
|
||||||
height: DEFAULT_DIMENSIONS[1],
|
|
||||||
useGrid: true
|
|
||||||
});
|
|
||||||
|
|
||||||
// Subscribe to the new object to get telemetry
|
|
||||||
self.openmct.objects.get(id).then(function (object) {
|
|
||||||
self.getTelemetry(object);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.elementProxies = [];
|
|
||||||
this.addElement = addElement;
|
|
||||||
this.refreshElements = refreshElements;
|
|
||||||
this.fixedProxy = new FixedProxy(this.addElement, this.$q, this.dialogService);
|
|
||||||
|
|
||||||
this.composition = this.openmct.composition.get(this.newDomainObject);
|
|
||||||
this.composition.on('add', this.onCompositionAdd, this);
|
|
||||||
this.composition.on('remove', this.onCompositionRemove, this);
|
|
||||||
this.composition.load();
|
|
||||||
|
|
||||||
// Position panes where they are dropped
|
|
||||||
$scope.$on("mctDrop", handleDrop);
|
|
||||||
|
|
||||||
$scope.$on("$destroy", this.destroy.bind(this));
|
|
||||||
|
|
||||||
// Respond to external bounds changes
|
|
||||||
this.openmct.time.on("bounds", updateDisplayBounds);
|
|
||||||
|
|
||||||
this.openmct.selection.on('change', this.setSelection.bind(this));
|
|
||||||
this.openmct.editor.on('isEditing', this.handleEditing.bind(this));
|
|
||||||
|
|
||||||
this.$element.on('click', this.bypassSelection.bind(this));
|
|
||||||
this.unlisten = this.openmct.objects.observe(this.newDomainObject, '*', function (obj) {
|
|
||||||
this.newDomainObject = JSON.parse(JSON.stringify(obj));
|
|
||||||
this.updateElementPositions(this.newDomainObject.layoutGrid);
|
|
||||||
}.bind(this));
|
|
||||||
|
|
||||||
this.updateElementPositions(this.newDomainObject.layoutGrid);
|
|
||||||
refreshElements();
|
|
||||||
}
|
|
||||||
|
|
||||||
FixedController.prototype.updateElementPositions = function (layoutGrid) {
|
|
||||||
this.gridSize = layoutGrid;
|
|
||||||
|
|
||||||
this.elementProxies.forEach(function (elementProxy) {
|
|
||||||
elementProxy.setGridSize(this.gridSize);
|
|
||||||
elementProxy.style = convertPosition(elementProxy);
|
|
||||||
}.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
FixedController.prototype.onCompositionAdd = function (object) {
|
|
||||||
this.getTelemetry(object);
|
|
||||||
};
|
|
||||||
|
|
||||||
FixedController.prototype.onCompositionRemove = function (identifier) {
|
|
||||||
// Defer mutation of newDomainObject to prevent mutating an
|
|
||||||
// outdated version since this is triggered by a composition change.
|
|
||||||
setTimeout(function () {
|
|
||||||
var id = objectUtils.makeKeyString(identifier);
|
|
||||||
var elements = this.newDomainObject.configuration['fixed-display'].elements || [];
|
|
||||||
var newElements = elements.filter(function (proxy) {
|
|
||||||
return proxy.id !== id;
|
|
||||||
});
|
|
||||||
this.mutate("configuration['fixed-display'].elements", newElements);
|
|
||||||
|
|
||||||
if (this.subscriptions[id]) {
|
|
||||||
this.subscriptions[id]();
|
|
||||||
delete this.subscriptions[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
delete this.telemetryObjects[id];
|
|
||||||
this.refreshElements();
|
|
||||||
}.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes an element from the view.
|
|
||||||
*
|
|
||||||
* @param {Object} elementProxy the element proxy to remove.
|
|
||||||
*/
|
|
||||||
FixedController.prototype.remove = function (elementProxy) {
|
|
||||||
var element = elementProxy.element;
|
|
||||||
var elements = this.newDomainObject.configuration['fixed-display'].elements || [];
|
|
||||||
elements.splice(elements.indexOf(element), 1);
|
|
||||||
|
|
||||||
if (element.type === 'fixed.telemetry') {
|
|
||||||
this.newDomainObject.composition = this.newDomainObject.composition.filter(function (identifier) {
|
|
||||||
return objectUtils.makeKeyString(identifier) !== element.id;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.mutate("configuration['fixed-display'].elements", elements);
|
|
||||||
this.refreshElements();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a new element to the view.
|
|
||||||
*
|
|
||||||
* @param {string} type the type of element to add. Supported types are:
|
|
||||||
* `fixed.image`
|
|
||||||
* `fixed.box`
|
|
||||||
* `fixed.text`
|
|
||||||
* `fixed.line`
|
|
||||||
*/
|
|
||||||
FixedController.prototype.add = function (type) {
|
|
||||||
this.fixedProxy.add(type);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Change the display order of the element proxy.
|
|
||||||
*/
|
|
||||||
FixedController.prototype.order = function (elementProxy, position) {
|
|
||||||
var elements = elementProxy.order(position);
|
|
||||||
|
|
||||||
// Find the selected element index in the updated array.
|
|
||||||
var selectedElemenetIndex = elements.indexOf(this.selectedElementProxy.element);
|
|
||||||
|
|
||||||
this.mutate("configuration['fixed-display'].elements", elements);
|
|
||||||
elements = (this.newDomainObject.configuration)['fixed-display'].elements || [];
|
|
||||||
|
|
||||||
// Update the selected element with the new
|
|
||||||
// value since newDomainOject is mutated.
|
|
||||||
this.selectedElementProxy.element = elements[selectedElemenetIndex];
|
|
||||||
this.refreshElements();
|
|
||||||
};
|
|
||||||
|
|
||||||
FixedController.prototype.generateDragHandle = function (elementProxy, elementHandle) {
|
|
||||||
var index = this.elementProxies.indexOf(elementProxy);
|
|
||||||
|
|
||||||
if (elementHandle) {
|
|
||||||
elementHandle.element = elementProxy.element;
|
|
||||||
elementProxy = elementHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new FixedDragHandle(
|
|
||||||
elementProxy,
|
|
||||||
"configuration['fixed-display'].elements[" + index + "]",
|
|
||||||
this
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
FixedController.prototype.generateDragHandles = function (elementProxy) {
|
|
||||||
return elementProxy.handles().map(function (handle) {
|
|
||||||
return this.generateDragHandle(elementProxy, handle);
|
|
||||||
}, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
FixedController.prototype.updateSelectionStyle = function () {
|
|
||||||
this.selectedElementProxy.style = convertPosition(this.selectedElementProxy);
|
|
||||||
};
|
|
||||||
|
|
||||||
FixedController.prototype.setSelection = function (selectable) {
|
|
||||||
var selection = selectable[0];
|
|
||||||
|
|
||||||
if (this.selectionListeners) {
|
|
||||||
this.selectionListeners.forEach(function (l) {
|
|
||||||
l();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.selectionListeners = [];
|
|
||||||
|
|
||||||
if (!selection) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selection.context.elementProxy) {
|
|
||||||
this.selectedElementProxy = selection.context.elementProxy;
|
|
||||||
this.attachSelectionListeners();
|
|
||||||
this.mvHandle = this.generateDragHandle(this.selectedElementProxy);
|
|
||||||
this.resizeHandles = this.generateDragHandles(this.selectedElementProxy);
|
|
||||||
} else {
|
|
||||||
// Make fixed view selectable if it's not already.
|
|
||||||
if (!this.fixedViewSelectable && selectable.length === 1) {
|
|
||||||
this.fixedViewSelectable = true;
|
|
||||||
selection.context.fixedController = this;
|
|
||||||
this.openmct.selection.select(selection);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.resizeHandles = [];
|
|
||||||
this.mvHandle = undefined;
|
|
||||||
this.selectedElementProxy = undefined;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
FixedController.prototype.attachSelectionListeners = function () {
|
|
||||||
var index = this.elementProxies.indexOf(this.selectedElementProxy);
|
|
||||||
var path = "configuration['fixed-display'].elements[" + index + "]";
|
|
||||||
|
|
||||||
this.selectionListeners.push(this.openmct.objects.observe(this.newDomainObject, path + ".useGrid", function (newValue) {
|
|
||||||
if (this.selectedElementProxy.useGrid() !== newValue) {
|
|
||||||
this.selectedElementProxy.useGrid(newValue);
|
|
||||||
this.updateSelectionStyle();
|
|
||||||
this.openmct.objects.mutate(this.newDomainObject, path, this.selectedElementProxy.element);
|
|
||||||
}
|
|
||||||
}.bind(this)));
|
|
||||||
[
|
|
||||||
"width",
|
|
||||||
"height",
|
|
||||||
"stroke",
|
|
||||||
"fill",
|
|
||||||
"x",
|
|
||||||
"y",
|
|
||||||
"x1",
|
|
||||||
"y1",
|
|
||||||
"x2",
|
|
||||||
"y2",
|
|
||||||
"color",
|
|
||||||
"size",
|
|
||||||
"text",
|
|
||||||
"titled"
|
|
||||||
].forEach(function (property) {
|
|
||||||
this.selectionListeners.push(this.openmct.objects.observe(this.newDomainObject, path + "." + property, function (newValue) {
|
|
||||||
this.selectedElementProxy.element[property] = newValue;
|
|
||||||
this.updateSelectionStyle();
|
|
||||||
}.bind(this)));
|
|
||||||
}.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
FixedController.prototype.destroy = function () {
|
|
||||||
this.unsubscribe();
|
|
||||||
this.unlisten();
|
|
||||||
this.openmct.time.off("bounds", this.updateDisplayBounds);
|
|
||||||
this.openmct.selection.off("change", this.setSelection);
|
|
||||||
this.composition.off('add', this.onCompositionAdd, this);
|
|
||||||
this.composition.off('remove', this.onCompositionRemove, this);
|
|
||||||
this.openmct.editor.off('isEditing', this.handleEditing, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A rate-limited digest function. Caps digests at 60Hz
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
FixedController.prototype.digest = function () {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
if (!this.digesting) {
|
|
||||||
this.digesting = true;
|
|
||||||
requestAnimationFrame(function () {
|
|
||||||
self.$scope.$digest();
|
|
||||||
self.digesting = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unsubscribe all listeners
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
FixedController.prototype.unsubscribe = function () {
|
|
||||||
Object.values(this.subscriptions).forEach(function (unsubscribeFunc) {
|
|
||||||
unsubscribeFunc();
|
|
||||||
});
|
|
||||||
this.subscriptions = {};
|
|
||||||
this.telemetryObjects = {};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subscribe to the given domain object
|
|
||||||
* @private
|
|
||||||
* @param {object} object Domain object to subscribe to
|
|
||||||
* @returns {object} The provided object, for chaining.
|
|
||||||
*/
|
|
||||||
FixedController.prototype.subscribeToObject = function (object) {
|
|
||||||
var self = this;
|
|
||||||
var timeAPI = this.openmct.time;
|
|
||||||
var id = objectUtils.makeKeyString(object.identifier);
|
|
||||||
this.subscriptions[id] = self.openmct.telemetry.subscribe(object, function (datum) {
|
|
||||||
if (timeAPI.clock() !== undefined) {
|
|
||||||
self.updateView(object, datum);
|
|
||||||
}
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
return object;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print the values from the given datum against the provided object in the view.
|
|
||||||
* @private
|
|
||||||
* @param {object} telemetryObject The domain object associated with the given telemetry data
|
|
||||||
* @param {object} datum The telemetry datum containing the values to print
|
|
||||||
*/
|
|
||||||
FixedController.prototype.updateView = function (telemetryObject, datum) {
|
|
||||||
var metadata = this.openmct.telemetry.getMetadata(telemetryObject);
|
|
||||||
var valueMetadata = this.chooseValueMetadataToDisplay(metadata);
|
|
||||||
var formattedTelemetryValue = this.getFormattedTelemetryValueForKey(valueMetadata, datum);
|
|
||||||
var limitEvaluator = this.openmct.telemetry.limitEvaluator(telemetryObject);
|
|
||||||
var alarm = limitEvaluator && limitEvaluator.evaluate(datum, valueMetadata);
|
|
||||||
|
|
||||||
this.setDisplayedValue(
|
|
||||||
telemetryObject,
|
|
||||||
formattedTelemetryValue,
|
|
||||||
alarm && alarm.cssClass
|
|
||||||
);
|
|
||||||
this.digest();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
FixedController.prototype.getFormattedTelemetryValueForKey = function (valueMetadata, datum) {
|
|
||||||
var formatter = this.openmct.telemetry.getValueFormatter(valueMetadata);
|
|
||||||
|
|
||||||
return formatter.format(datum);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
FixedController.prototype.chooseValueMetadataToDisplay = function (metadata) {
|
|
||||||
// If there is a range value, show that preferentially
|
|
||||||
var valueMetadata = metadata.valuesForHints(['range'])[0];
|
|
||||||
|
|
||||||
// If no range is defined, default to the highest priority non time-domain data.
|
|
||||||
if (valueMetadata === undefined) {
|
|
||||||
var valuesOrderedByPriority = metadata.values();
|
|
||||||
valueMetadata = valuesOrderedByPriority.filter(function (values) {
|
|
||||||
return !(values.hints.domain);
|
|
||||||
})[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return valueMetadata;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request the last historical data point for the given domain object
|
|
||||||
* @param {object} object
|
|
||||||
* @returns {object} the provided object for chaining.
|
|
||||||
*/
|
|
||||||
FixedController.prototype.fetchHistoricalData = function (object) {
|
|
||||||
var bounds = this.openmct.time.bounds();
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
self.openmct.telemetry.request(object, {start: bounds.start, end: bounds.end, size: 1})
|
|
||||||
.then(function (data) {
|
|
||||||
if (data.length > 0) {
|
|
||||||
self.updateView(object, data[data.length - 1]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return object;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print a value to the onscreen element associated with a given telemetry object.
|
|
||||||
* @private
|
|
||||||
* @param {object} telemetryObject The telemetry object associated with the value
|
|
||||||
* @param {string | number} value The value to print to screen
|
|
||||||
* @param {string} [cssClass] an optional CSS class to apply to the onscreen element.
|
|
||||||
*/
|
|
||||||
FixedController.prototype.setDisplayedValue = function (telemetryObject, value, cssClass) {
|
|
||||||
var id = objectUtils.makeKeyString(telemetryObject.identifier);
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
(self.elementProxiesById[id] || []).forEach(function (element) {
|
|
||||||
self.names[id] = telemetryObject.name;
|
|
||||||
self.values[id] = value;
|
|
||||||
element.name = self.names[id];
|
|
||||||
element.value = self.values[id];
|
|
||||||
element.cssClass = cssClass;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
FixedController.prototype.getTelemetry = function (domainObject) {
|
|
||||||
var id = objectUtils.makeKeyString(domainObject.identifier);
|
|
||||||
|
|
||||||
if (this.subscriptions[id]) {
|
|
||||||
this.subscriptions[id]();
|
|
||||||
delete this.subscriptions[id];
|
|
||||||
}
|
|
||||||
delete this.telemetryObjects[id];
|
|
||||||
|
|
||||||
if (!this.openmct.telemetry.isTelemetryObject(domainObject)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize display
|
|
||||||
this.telemetryObjects[id] = domainObject;
|
|
||||||
this.setDisplayedValue(domainObject, "");
|
|
||||||
|
|
||||||
return Promise.resolve(domainObject)
|
|
||||||
.then(this.fetchHistoricalData)
|
|
||||||
.then(this.subscribeToObject);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the size of the grid, in pixels. The returned array
|
|
||||||
* is in the form `[x, y]`.
|
|
||||||
* @returns {number[]} the grid size
|
|
||||||
* @memberof platform/features/layout.FixedController#
|
|
||||||
*/
|
|
||||||
FixedController.prototype.getGridSize = function () {
|
|
||||||
return this.gridSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an array of elements in this panel; these are
|
|
||||||
* decorated proxies for both selection and display.
|
|
||||||
* @returns {Array} elements in this panel
|
|
||||||
*/
|
|
||||||
FixedController.prototype.getElements = function () {
|
|
||||||
return this.elementProxies;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the element should be selected or not.
|
|
||||||
*
|
|
||||||
* @param elementProxy the element to check
|
|
||||||
* @returns {boolean} true if the element should be selected.
|
|
||||||
*/
|
|
||||||
FixedController.prototype.shouldSelect = function (elementProxy) {
|
|
||||||
if (elementProxy.element === this.elementToSelectAfterRefresh) {
|
|
||||||
delete this.elementToSelectAfterRefresh;
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if an element is currently selected.
|
|
||||||
*
|
|
||||||
* @returns {boolean} true if an element is selected.
|
|
||||||
*/
|
|
||||||
FixedController.prototype.isElementSelected = function () {
|
|
||||||
return (this.selectedElementProxy) ? true : false;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the style for the selected element.
|
|
||||||
*
|
|
||||||
* @returns {string} element style
|
|
||||||
*/
|
|
||||||
FixedController.prototype.getSelectedElementStyle = function () {
|
|
||||||
return (this.selectedElementProxy) ? this.selectedElementProxy.style : undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the selected element.
|
|
||||||
*
|
|
||||||
* @returns the selected element
|
|
||||||
*/
|
|
||||||
FixedController.prototype.getSelectedElement = function () {
|
|
||||||
return this.selectedElementProxy;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prevents the event from bubbling up if drag is in progress.
|
|
||||||
*/
|
|
||||||
FixedController.prototype.bypassSelection = function ($event) {
|
|
||||||
if (this.dragInProgress) {
|
|
||||||
if ($event) {
|
|
||||||
$event.stopPropagation();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get drag handles.
|
|
||||||
* @returns {platform/features/layout.FixedDragHandle[]}
|
|
||||||
* drag handles for the current selection
|
|
||||||
*/
|
|
||||||
FixedController.prototype.handles = function () {
|
|
||||||
return this.resizeHandles;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the handle to handle dragging to reposition an element.
|
|
||||||
* @returns {platform/features/layout.FixedDragHandle} the drag handle
|
|
||||||
*/
|
|
||||||
FixedController.prototype.moveHandle = function () {
|
|
||||||
return this.mvHandle;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the selection context.
|
|
||||||
*
|
|
||||||
* @param elementProxy the element proxy
|
|
||||||
* @returns {object} the context object which includes elementProxy
|
|
||||||
*/
|
|
||||||
FixedController.prototype.getContext = function (elementProxy) {
|
|
||||||
return {
|
|
||||||
elementProxy: elementProxy,
|
|
||||||
fixedController: this
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* End drag.
|
|
||||||
*
|
|
||||||
* @param handle the resize handle
|
|
||||||
*/
|
|
||||||
FixedController.prototype.endDrag = function (handle) {
|
|
||||||
this.dragInProgress = true;
|
|
||||||
|
|
||||||
setTimeout(function () {
|
|
||||||
this.dragInProgress = false;
|
|
||||||
}.bind(this), 0);
|
|
||||||
|
|
||||||
if (handle) {
|
|
||||||
handle.endDrag();
|
|
||||||
} else {
|
|
||||||
this.moveHandle().endDrag();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
FixedController.prototype.mutate = function (path, value) {
|
|
||||||
this.openmct.objects.mutate(this.newDomainObject, path, value);
|
|
||||||
};
|
|
||||||
|
|
||||||
FixedController.prototype.handleEditing = function (isEditing) {
|
|
||||||
// Listen for edit mode changes and update selection if necessary.
|
|
||||||
// Mainly to ensure fixedController is on the selection context when editing.
|
|
||||||
this.setSelection(this.openmct.selection.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
return FixedController;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,110 +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 () {
|
|
||||||
|
|
||||||
// Drag handle dimensions
|
|
||||||
var DRAG_HANDLE_SIZE = [6, 6];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Template-displayable drag handle for an element in fixed
|
|
||||||
* position mode.
|
|
||||||
*
|
|
||||||
* @param elementHandle the element handle
|
|
||||||
* @param configPath the configuration path of an element
|
|
||||||
* @param {Object} fixedControl the fixed controller
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function FixedDragHandle(elementHandle, configPath, fixedControl) {
|
|
||||||
this.elementHandle = elementHandle;
|
|
||||||
this.configPath = configPath;
|
|
||||||
this.fixedControl = fixedControl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a CSS style to position this drag handle.
|
|
||||||
*
|
|
||||||
* @returns CSS style object (for `ng-style`)
|
|
||||||
* @memberof platform/features/layout.FixedDragHandle#
|
|
||||||
*/
|
|
||||||
FixedDragHandle.prototype.style = function () {
|
|
||||||
var gridSize = this.elementHandle.getGridSize();
|
|
||||||
|
|
||||||
// Adjust from grid to pixel coordinates
|
|
||||||
var x = this.elementHandle.x() * gridSize[0],
|
|
||||||
y = this.elementHandle.y() * gridSize[1];
|
|
||||||
|
|
||||||
// Convert to a CSS style centered on that point
|
|
||||||
return {
|
|
||||||
left: (x - DRAG_HANDLE_SIZE[0] / 2) + 'px',
|
|
||||||
top: (y - DRAG_HANDLE_SIZE[1] / 2) + 'px',
|
|
||||||
width: DRAG_HANDLE_SIZE[0] + 'px',
|
|
||||||
height: DRAG_HANDLE_SIZE[1] + 'px'
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start a drag gesture. This should be called when a drag
|
|
||||||
* begins to track initial state.
|
|
||||||
*/
|
|
||||||
FixedDragHandle.prototype.startDrag = function () {
|
|
||||||
// Cache initial x/y positions
|
|
||||||
this.dragging = {
|
|
||||||
x: this.elementHandle.x(),
|
|
||||||
y: this.elementHandle.y()
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Continue a drag gesture; update x/y positions.
|
|
||||||
*
|
|
||||||
* @param {number[]} delta x/y pixel difference since drag started
|
|
||||||
*/
|
|
||||||
FixedDragHandle.prototype.continueDrag = function (delta) {
|
|
||||||
var gridSize = this.elementHandle.getGridSize();
|
|
||||||
|
|
||||||
if (this.dragging) {
|
|
||||||
// Update x/y positions (snapping to grid)
|
|
||||||
var newX = this.dragging.x + Math.round(delta[0] / gridSize[0]);
|
|
||||||
var newY = this.dragging.y + Math.round(delta[1] / gridSize[1]);
|
|
||||||
|
|
||||||
this.elementHandle.x(Math.max(0, newX));
|
|
||||||
this.elementHandle.y(Math.max(0, newY));
|
|
||||||
this.fixedControl.updateSelectionStyle();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* End a drag gesture. This should be called when a drag
|
|
||||||
* concludes to trigger commit of changes.
|
|
||||||
*/
|
|
||||||
FixedDragHandle.prototype.endDrag = function () {
|
|
||||||
this.dragging = undefined;
|
|
||||||
this.fixedControl.mutate(this.configPath, this.elementHandle.element);
|
|
||||||
};
|
|
||||||
|
|
||||||
return FixedDragHandle;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,76 +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(
|
|
||||||
['./elements/ElementFactory'],
|
|
||||||
function (ElementFactory) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Proxy for configuring a fixed position view via the toolbar.
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
* @param {Function} addElementCallback callback to invoke when
|
|
||||||
* elements are created
|
|
||||||
* @param $q Angular's $q, for promise-handling
|
|
||||||
* @param {DialogService} dialogService dialog service to use
|
|
||||||
* when adding a new element will require user input
|
|
||||||
*/
|
|
||||||
function FixedProxy(addElementCallback, $q, dialogService) {
|
|
||||||
this.factory = new ElementFactory(dialogService);
|
|
||||||
this.$q = $q;
|
|
||||||
this.addElementCallback = addElementCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a new visual element to this view. Supported types are:
|
|
||||||
*
|
|
||||||
* * `fixed.image`
|
|
||||||
* * `fixed.box`
|
|
||||||
* * `fixed.text`
|
|
||||||
* * `fixed.line`
|
|
||||||
*
|
|
||||||
* @param {string} type the type of element to add
|
|
||||||
*/
|
|
||||||
FixedProxy.prototype.add = function (type) {
|
|
||||||
var addElementCallback = this.addElementCallback;
|
|
||||||
|
|
||||||
// Place a configured element into the view configuration
|
|
||||||
function addElement(element) {
|
|
||||||
// Configure common properties of the element
|
|
||||||
element.x = element.x || 0;
|
|
||||||
element.y = element.y || 0;
|
|
||||||
element.width = element.width || 1;
|
|
||||||
element.height = element.height || 1;
|
|
||||||
element.type = type;
|
|
||||||
element.useGrid = true;
|
|
||||||
|
|
||||||
// Finally, add it to the view's configuration
|
|
||||||
addElementCallback(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Defer creation to the factory
|
|
||||||
this.$q.when(this.factory.createElement(type)).then(addElement);
|
|
||||||
};
|
|
||||||
|
|
||||||
return FixedProxy;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,115 +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 () {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles drag interactions on frames in layouts. This will
|
|
||||||
* provides new positions/dimensions for frames based on
|
|
||||||
* relative pixel positions provided; these will take into account
|
|
||||||
* the grid size (in a snap-to sense) and will enforce some minimums
|
|
||||||
* on both position and dimensions.
|
|
||||||
*
|
|
||||||
* The provided position and dimensions factors will determine
|
|
||||||
* whether this is a move or a resize, and what type of resize it
|
|
||||||
* will be. For instance, a position factor of [1, 1]
|
|
||||||
* will move a frame along with the mouse as the drag
|
|
||||||
* proceeds, while a dimension factor of [0, 0] will leave
|
|
||||||
* dimensions unchanged. Combining these in different
|
|
||||||
* ways results in different handles; a position factor of
|
|
||||||
* [1, 0] and a dimensions factor of [-1, 0] will implement
|
|
||||||
* a left-edge resize, as the horizontal position will move
|
|
||||||
* with the mouse while the horizontal dimensions shrink in
|
|
||||||
* kind (and vertical properties remain unmodified.)
|
|
||||||
*
|
|
||||||
* @param {object} rawPosition the initial position/dimensions
|
|
||||||
* of the frame being interacted with
|
|
||||||
* @param {number[]} posFactor the position factor
|
|
||||||
* @param {number[]} dimFactor the dimensions factor
|
|
||||||
* @param {number[]} the size of each grid element, in pixels
|
|
||||||
* @constructor
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
*/
|
|
||||||
function LayoutDrag(rawPosition, posFactor, dimFactor, gridSize) {
|
|
||||||
this.rawPosition = rawPosition;
|
|
||||||
this.posFactor = posFactor;
|
|
||||||
this.dimFactor = dimFactor;
|
|
||||||
this.gridSize = gridSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert a delta from pixel coordinates to grid coordinates,
|
|
||||||
// rounding to whole-number grid coordinates.
|
|
||||||
function toGridDelta(gridSize, pixelDelta) {
|
|
||||||
return pixelDelta.map(function (v, i) {
|
|
||||||
return Math.round(v / gridSize[i]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Utility function to perform element-by-element multiplication
|
|
||||||
function multiply(array, factors) {
|
|
||||||
return array.map(function (v, i) {
|
|
||||||
return v * factors[i];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Utility function to perform element-by-element addition
|
|
||||||
function add(array, other) {
|
|
||||||
return array.map(function (v, i) {
|
|
||||||
return v + other[i];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Utility function to perform element-by-element max-choosing
|
|
||||||
function max(array, other) {
|
|
||||||
return array.map(function (v, i) {
|
|
||||||
return Math.max(v, other[i]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a new position object in grid coordinates, with
|
|
||||||
* position and dimensions both offset appropriately
|
|
||||||
* according to the factors supplied in the constructor.
|
|
||||||
* @param {number[]} pixelDelta the offset from the
|
|
||||||
* original position, in pixels
|
|
||||||
*/
|
|
||||||
LayoutDrag.prototype.getAdjustedPosition = function (pixelDelta) {
|
|
||||||
var gridDelta = toGridDelta(this.gridSize, pixelDelta);
|
|
||||||
return {
|
|
||||||
position: max(add(
|
|
||||||
this.rawPosition.position,
|
|
||||||
multiply(gridDelta, this.posFactor)
|
|
||||||
), [0, 0]),
|
|
||||||
dimensions: max(add(
|
|
||||||
this.rawPosition.dimensions,
|
|
||||||
multiply(gridDelta, this.dimFactor)
|
|
||||||
), [1, 1])
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
return LayoutDrag;
|
|
||||||
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,105 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2016, 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([
|
|
||||||
'zepto',
|
|
||||||
'../../../commonUI/general/src/services/Overlay'
|
|
||||||
], function (
|
|
||||||
$,
|
|
||||||
Overlay
|
|
||||||
) {
|
|
||||||
/**
|
|
||||||
* MCT Trigger Modal is intended for use in only one location: inside the
|
|
||||||
* object-header to allow views in a layout to be popped out in a modal.
|
|
||||||
* Users can close the modal and go back to normal, and everything generally
|
|
||||||
* just works fine.
|
|
||||||
*
|
|
||||||
* This code is sensitive to how our html is constructed-- particularly with
|
|
||||||
* how it locates the the container of an element in a layout. However, it
|
|
||||||
* should be able to handle slight relocations so long as it is always a
|
|
||||||
* descendent of a `.frame` element.
|
|
||||||
*/
|
|
||||||
function MCTTriggerModal($document) {
|
|
||||||
|
|
||||||
function link($scope, $element) {
|
|
||||||
var actions = $scope.domainObject.getCapability('action'),
|
|
||||||
notebookAction = actions.getActions({key: 'notebook-new-entry'})[0];
|
|
||||||
|
|
||||||
var frame = $element.parent();
|
|
||||||
|
|
||||||
for (var i = 0; i < 10; i++) {
|
|
||||||
if (frame.hasClass('frame')) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
frame = frame.parent();
|
|
||||||
}
|
|
||||||
if (!frame.hasClass('frame')) {
|
|
||||||
$element.remove();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
frame = frame[0];
|
|
||||||
|
|
||||||
var layoutContainer = frame.parentElement;
|
|
||||||
|
|
||||||
var notebookButton = notebookAction ?
|
|
||||||
[
|
|
||||||
{
|
|
||||||
class: 'icon-notebook new-notebook-entry',
|
|
||||||
title: 'New Notebook Entry',
|
|
||||||
clickHandler: function (event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
notebookAction.perform();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
] : [];
|
|
||||||
|
|
||||||
var overlayService = new Overlay ({
|
|
||||||
$document: $document,
|
|
||||||
$scope: $scope,
|
|
||||||
$element: frame,
|
|
||||||
overlayWillMount: function () {
|
|
||||||
$(frame).removeClass('frame frame-template');
|
|
||||||
layoutContainer.removeChild(frame);
|
|
||||||
},
|
|
||||||
overlayDidUnmount: function () {
|
|
||||||
$(frame).addClass('frame frame-template');
|
|
||||||
layoutContainer.appendChild(frame);
|
|
||||||
},
|
|
||||||
browseBarButtons: notebookButton
|
|
||||||
});
|
|
||||||
|
|
||||||
$element.on('click', overlayService.toggleOverlay);
|
|
||||||
$scope.$on('$destroy', function () {
|
|
||||||
$element.off('click', overlayService.toggleOverlay);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
restrict: 'A',
|
|
||||||
link: link
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return MCTTriggerModal;
|
|
||||||
|
|
||||||
});
|
|
@ -1,58 +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 () {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility function for creating getter-setter functions,
|
|
||||||
* since these are frequently useful for element proxies.
|
|
||||||
*
|
|
||||||
* An optional third argument may be supplied in order to
|
|
||||||
* constrain or modify arguments when using as a setter;
|
|
||||||
* this argument is a function which takes two arguments
|
|
||||||
* (the current value for the property, and the requested
|
|
||||||
* new value.) This is useful when values need to be kept
|
|
||||||
* in certain ranges; specifically, to keep x/y positions
|
|
||||||
* non-negative in a fixed position view.
|
|
||||||
*
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
* @param {Object} object the object to get/set values upon
|
|
||||||
* @param {string} key the property to get/set
|
|
||||||
* @param {function} [updater] function used to process updates
|
|
||||||
*/
|
|
||||||
function AccessorMutator(object, key, updater) {
|
|
||||||
return function (value) {
|
|
||||||
if (arguments.length > 0) {
|
|
||||||
object[key] = updater ?
|
|
||||||
updater(value, object[key]) :
|
|
||||||
value;
|
|
||||||
}
|
|
||||||
return object[key];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return AccessorMutator;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,61 +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(
|
|
||||||
['./ElementProxy', './AccessorMutator'],
|
|
||||||
function (ElementProxy, AccessorMutator) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Selection proxy for Box elements in a fixed position view.
|
|
||||||
* Also serves as a superclass for Text elements, since those
|
|
||||||
* elements have a superset of Box properties.
|
|
||||||
*
|
|
||||||
* Note that arguments here are meant to match those expected
|
|
||||||
* by `Array.prototype.map`
|
|
||||||
*
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
* @param element the fixed position element, as stored in its
|
|
||||||
* configuration
|
|
||||||
* @param index the element's index within its array
|
|
||||||
* @param {number[]} gridSize the current layout grid size in [x,y] from
|
|
||||||
* @param {Array} elements the full array of elements
|
|
||||||
*/
|
|
||||||
function BoxProxy(element, index, elements, gridSize) {
|
|
||||||
var proxy = new ElementProxy(element, index, elements, gridSize);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get/set this element's fill color. (Omitting the
|
|
||||||
* argument makes this act as a getter.)
|
|
||||||
* @method
|
|
||||||
* @param {string} fill the new fill color
|
|
||||||
* @returns {string} the fill color
|
|
||||||
* @memberof platform/features/layout.BoxProxy#
|
|
||||||
*/
|
|
||||||
proxy.fill = new AccessorMutator(element, 'fill');
|
|
||||||
|
|
||||||
return proxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
return BoxProxy;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,115 +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 () {
|
|
||||||
|
|
||||||
var INITIAL_STATES = {
|
|
||||||
"fixed.image": {
|
|
||||||
stroke: "transparent"
|
|
||||||
},
|
|
||||||
"fixed.box": {
|
|
||||||
fill: "#717171",
|
|
||||||
border: "transparent",
|
|
||||||
stroke: "transparent"
|
|
||||||
},
|
|
||||||
"fixed.line": {
|
|
||||||
x: 5,
|
|
||||||
y: 9,
|
|
||||||
x2: 6,
|
|
||||||
y2: 6,
|
|
||||||
stroke: "#717171"
|
|
||||||
},
|
|
||||||
"fixed.text": {
|
|
||||||
fill: "transparent",
|
|
||||||
stroke: "transparent",
|
|
||||||
size: "13px"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
DIALOGS = {
|
|
||||||
"fixed.image": {
|
|
||||||
name: "Image Properties",
|
|
||||||
sections: [
|
|
||||||
{
|
|
||||||
rows: [
|
|
||||||
{
|
|
||||||
key: "url",
|
|
||||||
control: "textfield",
|
|
||||||
name: "Image URL",
|
|
||||||
"cssClass": "l-input-lg",
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"fixed.text": {
|
|
||||||
name: "Text Element Properties",
|
|
||||||
sections: [
|
|
||||||
{
|
|
||||||
rows: [
|
|
||||||
{
|
|
||||||
key: "text",
|
|
||||||
control: "textfield",
|
|
||||||
name: "Text",
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The ElementFactory creates new instances of elements for the
|
|
||||||
* fixed position view, prompting for user input where necessary.
|
|
||||||
* @param {DialogService} dialogService service to request user input
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function ElementFactory(dialogService) {
|
|
||||||
this.dialogService = dialogService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new element for the fixed position view.
|
|
||||||
* @param {string} type the type of element to create
|
|
||||||
* @returns {Promise|object} the created element, or a promise
|
|
||||||
* for that element
|
|
||||||
*/
|
|
||||||
ElementFactory.prototype.createElement = function (type) {
|
|
||||||
var initialState = INITIAL_STATES[type] || {};
|
|
||||||
|
|
||||||
// Clone that state
|
|
||||||
initialState = JSON.parse(JSON.stringify(initialState));
|
|
||||||
|
|
||||||
// Show a dialog to configure initial state, if appropriate
|
|
||||||
return DIALOGS[type] ? this.dialogService.getUserInput(
|
|
||||||
DIALOGS[type],
|
|
||||||
initialState
|
|
||||||
) : initialState;
|
|
||||||
};
|
|
||||||
|
|
||||||
return ElementFactory;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,209 +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(
|
|
||||||
['./AccessorMutator', './ResizeHandle', './UnitAccessorMutator'],
|
|
||||||
function (AccessorMutator, ResizeHandle, UnitAccessorMutator) {
|
|
||||||
|
|
||||||
// Index deltas for changes in order
|
|
||||||
var ORDERS = {
|
|
||||||
top: Number.POSITIVE_INFINITY,
|
|
||||||
up: 1,
|
|
||||||
down: -1,
|
|
||||||
bottom: Number.NEGATIVE_INFINITY
|
|
||||||
};
|
|
||||||
|
|
||||||
// Mininmum pixel height and width for objects
|
|
||||||
var MIN_WIDTH = 10;
|
|
||||||
var MIN_HEIGHT = 10;
|
|
||||||
|
|
||||||
// Ensure a value is non-negative (for x/y setters)
|
|
||||||
function clamp(value) {
|
|
||||||
return Math.max(value, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract superclass for other classes which provide useful
|
|
||||||
* interfaces upon an elements in a fixed position view.
|
|
||||||
* This handles the generic operations (e.g. remove) so that
|
|
||||||
* subclasses only need to implement element-specific behaviors.
|
|
||||||
*
|
|
||||||
* Note that arguments here are meant to match those expected
|
|
||||||
* by `Array.prototype.map`
|
|
||||||
*
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
* @param element the fixed position element, as stored in its
|
|
||||||
* configuration
|
|
||||||
* @param index the element's index within its array
|
|
||||||
* @param {Array} elements the full array of elements
|
|
||||||
* @param {number[]} gridSize the current layout grid size in [x,y] from
|
|
||||||
*/
|
|
||||||
function ElementProxy(element, index, elements, gridSize) {
|
|
||||||
/**
|
|
||||||
* The element as stored in the view configuration.
|
|
||||||
* @memberof platform/features/layout.ElementProxy#
|
|
||||||
*/
|
|
||||||
this.element = element;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The current grid size of the layout.
|
|
||||||
* @memberof platform/features/layout.ElementProxy#
|
|
||||||
*/
|
|
||||||
this.gridSize = gridSize || [1,1]; //Ensure a reasonable default
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get and/or set the x position of this element.
|
|
||||||
* Units are in fixed position grid space.
|
|
||||||
* @param {number} [x] the new x position (if setting)
|
|
||||||
* @returns {number} the x position
|
|
||||||
* @memberof platform/features/layout.ElementProxy#
|
|
||||||
*/
|
|
||||||
this.x = new AccessorMutator(element, 'x', clamp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get and/or set the y position of this element.
|
|
||||||
* Units are in fixed position grid space.
|
|
||||||
* @param {number} [y] the new y position (if setting)
|
|
||||||
* @returns {number} the y position
|
|
||||||
* @memberof platform/features/layout.ElementProxy#
|
|
||||||
*/
|
|
||||||
this.y = new AccessorMutator(element, 'y', clamp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get and/or set the stroke color of this element.
|
|
||||||
* @param {string} [stroke] the new stroke color (if setting)
|
|
||||||
* @returns {string} the stroke color
|
|
||||||
* @memberof platform/features/layout.ElementProxy#
|
|
||||||
*/
|
|
||||||
this.stroke = new AccessorMutator(element, 'stroke');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get and/or set the width of this element.
|
|
||||||
* Units are in fixed position grid space.
|
|
||||||
* @param {number} [w] the new width (if setting)
|
|
||||||
* @returns {number} the width
|
|
||||||
* @memberof platform/features/layout.ElementProxy#
|
|
||||||
*/
|
|
||||||
this.width = new AccessorMutator(element, 'width');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get and/or set the height of this element.
|
|
||||||
* Units are in fixed position grid space.
|
|
||||||
* @param {number} [h] the new height (if setting)
|
|
||||||
* @returns {number} the height
|
|
||||||
* @memberof platform/features/layout.ElementProxy#
|
|
||||||
*/
|
|
||||||
this.height = new AccessorMutator(element, 'height');
|
|
||||||
|
|
||||||
this.useGrid = new UnitAccessorMutator(this);
|
|
||||||
this.index = index;
|
|
||||||
this.elements = elements;
|
|
||||||
this.resizeHandles = [new ResizeHandle(this, this.element)];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Change the display order of this element.
|
|
||||||
* @param {string} o where to move this element;
|
|
||||||
* one of "top", "up", "down", or "bottom"
|
|
||||||
* @return {Array} the full array of elements
|
|
||||||
*/
|
|
||||||
ElementProxy.prototype.order = function (o) {
|
|
||||||
var index = this.index,
|
|
||||||
elements = this.elements,
|
|
||||||
element = this.element,
|
|
||||||
delta = ORDERS[o] || 0,
|
|
||||||
desired = Math.max(
|
|
||||||
Math.min(index + delta, elements.length - 1),
|
|
||||||
0
|
|
||||||
);
|
|
||||||
// Move to the desired index, if this is a change
|
|
||||||
if ((desired !== index) && (elements[index] === element)) {
|
|
||||||
// Splice out the current element
|
|
||||||
elements.splice(index, 1);
|
|
||||||
// Splice it back in at the correct index
|
|
||||||
elements.splice(desired, 0, element);
|
|
||||||
// Track change in index (proxy should be recreated
|
|
||||||
// anyway, but be consistent)
|
|
||||||
this.index = desired;
|
|
||||||
}
|
|
||||||
|
|
||||||
return elements;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get handles to control specific features of this element,
|
|
||||||
* e.g. corner size.
|
|
||||||
* @return {platform/features/layout.ElementHandle[]} handles
|
|
||||||
* for moving/resizing this element
|
|
||||||
*/
|
|
||||||
ElementProxy.prototype.handles = function () {
|
|
||||||
return this.resizeHandles;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns which grid size the element is currently using.
|
|
||||||
* @return {number[]} The current grid size in [x,y] form if the element
|
|
||||||
* is currently using the grid, [1,1] if it is using
|
|
||||||
* pixels.
|
|
||||||
*/
|
|
||||||
ElementProxy.prototype.getGridSize = function () {
|
|
||||||
var gridSize;
|
|
||||||
// Default to using the grid if useGrid was not defined
|
|
||||||
if (typeof this.element.useGrid === 'undefined') {
|
|
||||||
this.element.useGrid = true;
|
|
||||||
}
|
|
||||||
if (this.element.useGrid) {
|
|
||||||
gridSize = this.gridSize;
|
|
||||||
} else {
|
|
||||||
gridSize = [1,1];
|
|
||||||
}
|
|
||||||
return gridSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the current grid size stored by this element proxy
|
|
||||||
* @param {number[]} gridSize The current layout grid size in [x,y] form
|
|
||||||
*/
|
|
||||||
ElementProxy.prototype.setGridSize = function (gridSize) {
|
|
||||||
this.gridSize = gridSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the current minimum element width in grid units
|
|
||||||
* @return {number} The current minimum element width
|
|
||||||
*/
|
|
||||||
ElementProxy.prototype.getMinWidth = function () {
|
|
||||||
return Math.ceil(MIN_WIDTH / this.getGridSize()[0]);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the current minimum element height in grid units
|
|
||||||
* @return {number} The current minimum element height
|
|
||||||
*/
|
|
||||||
ElementProxy.prototype.getMinHeight = function () {
|
|
||||||
return Math.ceil(MIN_HEIGHT / this.getGridSize()[1]);
|
|
||||||
};
|
|
||||||
|
|
||||||
return ElementProxy;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,58 +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(
|
|
||||||
['./ElementProxy', './AccessorMutator'],
|
|
||||||
function (ElementProxy, AccessorMutator) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Selection proxy for Image elements in a fixed position view.
|
|
||||||
*
|
|
||||||
* Note that arguments here are meant to match those expected
|
|
||||||
* by `Array.prototype.map`
|
|
||||||
*
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
* @param element the fixed position element, as stored in its
|
|
||||||
* configuration
|
|
||||||
* @param index the element's index within its array
|
|
||||||
* @param {Array} elements the full array of elements
|
|
||||||
* @param {number[]} gridSize the current layout grid size in [x,y] from
|
|
||||||
* @augments {platform/features/layout.ElementProxy}
|
|
||||||
*/
|
|
||||||
function ImageProxy(element, index, elements, gridSize) {
|
|
||||||
var proxy = new ElementProxy(element, index, elements, gridSize);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get and/or set the displayed text of this element.
|
|
||||||
* @param {string} [text] the new text (if setting)
|
|
||||||
* @returns {string} the text
|
|
||||||
* @memberof platform/features/layout.ImageProxy#
|
|
||||||
*/
|
|
||||||
proxy.url = new AccessorMutator(element, 'url');
|
|
||||||
|
|
||||||
return proxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ImageProxy;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,94 +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 () {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle for changing x/y position of a line's end point.
|
|
||||||
* This is used to support drag handles for line elements
|
|
||||||
* in a fixed position view. Field names for opposite ends
|
|
||||||
* are provided to avoid zero-length lines.
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
* @param element the line element
|
|
||||||
* @param {string} xProperty field which stores x position
|
|
||||||
* @param {string} yProperty field which stores y position
|
|
||||||
* @param {string} xOther field which stores x of other end
|
|
||||||
* @param {string} yOther field which stores y of other end
|
|
||||||
* @implements {platform/features/layout.ElementHandle}
|
|
||||||
*/
|
|
||||||
function LineHandle(element, elementProxy, xProperty, yProperty, xOther, yOther) {
|
|
||||||
this.elementProxy = elementProxy;
|
|
||||||
this.element = element;
|
|
||||||
this.xProperty = xProperty;
|
|
||||||
this.yProperty = yProperty;
|
|
||||||
this.xOther = xOther;
|
|
||||||
this.yOther = yOther;
|
|
||||||
}
|
|
||||||
|
|
||||||
LineHandle.prototype.x = function (value) {
|
|
||||||
var element = this.element,
|
|
||||||
xProperty = this.xProperty,
|
|
||||||
yProperty = this.yProperty,
|
|
||||||
xOther = this.xOther,
|
|
||||||
yOther = this.yOther;
|
|
||||||
|
|
||||||
if (arguments.length > 0) {
|
|
||||||
// Ensure we stay in view
|
|
||||||
value = Math.max(value, 0);
|
|
||||||
// Make sure end points will still be different
|
|
||||||
if (element[yOther] !== element[yProperty] ||
|
|
||||||
element[xOther] !== value) {
|
|
||||||
element[xProperty] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return element[xProperty];
|
|
||||||
};
|
|
||||||
|
|
||||||
LineHandle.prototype.y = function (value) {
|
|
||||||
var element = this.element,
|
|
||||||
xProperty = this.xProperty,
|
|
||||||
yProperty = this.yProperty,
|
|
||||||
xOther = this.xOther,
|
|
||||||
yOther = this.yOther;
|
|
||||||
|
|
||||||
if (arguments.length > 0) {
|
|
||||||
// Ensure we stay in view
|
|
||||||
value = Math.max(value, 0);
|
|
||||||
// Make sure end points will still be different
|
|
||||||
if (element[xOther] !== element[xProperty] ||
|
|
||||||
element[yOther] !== value) {
|
|
||||||
element[yProperty] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return element[yProperty];
|
|
||||||
};
|
|
||||||
|
|
||||||
LineHandle.prototype.getGridSize = function () {
|
|
||||||
return this.elementProxy.getGridSize();
|
|
||||||
};
|
|
||||||
|
|
||||||
return LineHandle;
|
|
||||||
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,171 +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(
|
|
||||||
['./ElementProxy', './LineHandle', './AccessorMutator'],
|
|
||||||
function (ElementProxy, LineHandle, AccessorMutator) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Selection/diplay proxy for line elements of a fixed position
|
|
||||||
* view.
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
* @param element the fixed position element, as stored in its
|
|
||||||
* configuration
|
|
||||||
* @param index the element's index within its array
|
|
||||||
* @param {Array} elements the full array of elements
|
|
||||||
* @param {number[]} gridSize the current layout grid size in [x,y] from
|
|
||||||
* @augments {platform/features/layout.ElementProxy}
|
|
||||||
*/
|
|
||||||
function LineProxy(element, index, elements, gridSize) {
|
|
||||||
var proxy = new ElementProxy(element, index, elements, gridSize),
|
|
||||||
handles = [
|
|
||||||
new LineHandle(element, proxy, 'x', 'y', 'x2', 'y2'),
|
|
||||||
new LineHandle(element, proxy, 'x2', 'y2', 'x', 'y')
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets style specific to line proxy.
|
|
||||||
*/
|
|
||||||
proxy.getStyle = function () {
|
|
||||||
var layoutGridSize = proxy.getGridSize();
|
|
||||||
|
|
||||||
return {
|
|
||||||
left: (layoutGridSize[0] * proxy.x()) + 'px',
|
|
||||||
top: (layoutGridSize[1] * proxy.y()) + 'px',
|
|
||||||
width: (layoutGridSize[0] * proxy.width()) + 'px',
|
|
||||||
height: (layoutGridSize[1] * proxy.height()) + 'px'
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the top-left x coordinate, in grid space, of
|
|
||||||
* this line's bounding box.
|
|
||||||
* @returns {number} the x coordinate
|
|
||||||
* @memberof platform/features/layout.LineProxy#
|
|
||||||
*/
|
|
||||||
proxy.x = function (v) {
|
|
||||||
var x = Math.min(element.x, element.x2),
|
|
||||||
delta = Math.max(v, 0) - x;
|
|
||||||
if (arguments.length > 0 && delta) {
|
|
||||||
element.x += delta;
|
|
||||||
element.x2 += delta;
|
|
||||||
}
|
|
||||||
return x;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the top-left y coordinate, in grid space, of
|
|
||||||
* this line's bounding box.
|
|
||||||
* @returns {number} the y coordinate
|
|
||||||
* @memberof platform/features/layout.LineProxy#
|
|
||||||
*/
|
|
||||||
proxy.y = function (v) {
|
|
||||||
var y = Math.min(element.y, element.y2),
|
|
||||||
delta = Math.max(v, 0) - y;
|
|
||||||
if (arguments.length > 0 && delta) {
|
|
||||||
element.y += delta;
|
|
||||||
element.y2 += delta;
|
|
||||||
}
|
|
||||||
return y;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the width, in grid space, of
|
|
||||||
* this line's bounding box.
|
|
||||||
* @returns {number} the width
|
|
||||||
* @memberof platform/features/layout.LineProxy#
|
|
||||||
*/
|
|
||||||
proxy.width = function () {
|
|
||||||
return Math.max(Math.abs(element.x - element.x2), 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the height, in grid space, of
|
|
||||||
* this line's bounding box.
|
|
||||||
* @returns {number} the height
|
|
||||||
* @memberof platform/features/layout.LineProxy#
|
|
||||||
*/
|
|
||||||
proxy.height = function () {
|
|
||||||
return Math.max(Math.abs(element.y - element.y2), 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the x position, in grid units relative to
|
|
||||||
* the top-left corner, of the first point in this line
|
|
||||||
* segment.
|
|
||||||
* @returns {number} the x position of the first point
|
|
||||||
* @memberof platform/features/layout.LineProxy#
|
|
||||||
*/
|
|
||||||
proxy.x1 = function () {
|
|
||||||
return element.x - proxy.x();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the y position, in grid units relative to
|
|
||||||
* the top-left corner, of the first point in this line
|
|
||||||
* segment.
|
|
||||||
* @returns {number} the y position of the first point
|
|
||||||
* @memberof platform/features/layout.LineProxy#
|
|
||||||
*/
|
|
||||||
proxy.y1 = function () {
|
|
||||||
return element.y - proxy.y();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the x position, in grid units relative to
|
|
||||||
* the top-left corner, of the second point in this line
|
|
||||||
* segment.
|
|
||||||
* @returns {number} the x position of the second point
|
|
||||||
* @memberof platform/features/layout.LineProxy#
|
|
||||||
*/
|
|
||||||
proxy.x2 = function () {
|
|
||||||
return element.x2 - proxy.x();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the y position, in grid units relative to
|
|
||||||
* the top-left corner, of the second point in this line
|
|
||||||
* segment.
|
|
||||||
* @returns {number} the y position of the second point
|
|
||||||
* @memberof platform/features/layout.LineProxy#
|
|
||||||
*/
|
|
||||||
proxy.y2 = function () {
|
|
||||||
return element.y2 - proxy.y();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get element handles for changing the position of end
|
|
||||||
* points of this line.
|
|
||||||
* @returns {LineHandle[]} line handles for both end points
|
|
||||||
* @memberof platform/features/layout.LineProxy#
|
|
||||||
*/
|
|
||||||
proxy.handles = function () {
|
|
||||||
return handles;
|
|
||||||
};
|
|
||||||
|
|
||||||
return proxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
return LineProxy;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,72 +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 () {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @interface platform/features/layout.ElementHandle
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle for changing width/height properties of an element.
|
|
||||||
* This is used to support drag handles for different
|
|
||||||
* element types in a fixed position view.
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function ResizeHandle(elementProxy, element) {
|
|
||||||
this.elementProxy = elementProxy;
|
|
||||||
this.element = element;
|
|
||||||
}
|
|
||||||
|
|
||||||
ResizeHandle.prototype.x = function (value) {
|
|
||||||
var element = this.element;
|
|
||||||
if (arguments.length > 0) {
|
|
||||||
element.width = Math.max(
|
|
||||||
this.elementProxy.getMinWidth(),
|
|
||||||
value - element.x
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return element.x + element.width;
|
|
||||||
};
|
|
||||||
|
|
||||||
ResizeHandle.prototype.y = function (value) {
|
|
||||||
var element = this.element;
|
|
||||||
if (arguments.length > 0) {
|
|
||||||
element.height = Math.max(
|
|
||||||
this.elementProxy.getMinHeight(),
|
|
||||||
value - element.y
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return element.y + element.height;
|
|
||||||
};
|
|
||||||
|
|
||||||
ResizeHandle.prototype.getGridSize = function () {
|
|
||||||
return this.elementProxy.getGridSize();
|
|
||||||
};
|
|
||||||
|
|
||||||
return ResizeHandle;
|
|
||||||
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,56 +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(
|
|
||||||
['./TextProxy'],
|
|
||||||
function (TextProxy) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Selection proxy for telemetry elements in a fixed position view.
|
|
||||||
*
|
|
||||||
* Note that arguments here are meant to match those expected
|
|
||||||
* by `Array.prototype.map`
|
|
||||||
*
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
* @param element the fixed position element, as stored in its
|
|
||||||
* configuration
|
|
||||||
* @param index the element's index within its array
|
|
||||||
* @param {Array} elements the full array of elements
|
|
||||||
* @param {number[]} gridSize the current layout grid size in [x,y] form
|
|
||||||
* @augments {platform/features/layout.ElementProxy}
|
|
||||||
*/
|
|
||||||
function TelemetryProxy(element, index, elements, gridSize) {
|
|
||||||
var proxy = new TextProxy(element, index, elements, gridSize);
|
|
||||||
|
|
||||||
// Expose the domain object identifier
|
|
||||||
proxy.id = element.id;
|
|
||||||
|
|
||||||
// Don't expose text configuration
|
|
||||||
delete proxy.text;
|
|
||||||
|
|
||||||
return proxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TelemetryProxy;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,75 +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(
|
|
||||||
['./BoxProxy', './AccessorMutator'],
|
|
||||||
function (BoxProxy, AccessorMutator) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Selection proxy for Text elements in a fixed position view.
|
|
||||||
*
|
|
||||||
* Note that arguments here are meant to match those expected
|
|
||||||
* by `Array.prototype.map`
|
|
||||||
*
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
* @param element the fixed position element, as stored in its
|
|
||||||
* configuration
|
|
||||||
* @param index the element's index within its array
|
|
||||||
* @param {Array} elements the full array of elements
|
|
||||||
* @param {number[]} gridSize the current layout grid size in [x,y] from
|
|
||||||
* @augments {platform/features/layout.ElementProxy}
|
|
||||||
*/
|
|
||||||
function TextProxy(element, index, elements, gridSize) {
|
|
||||||
var proxy = new BoxProxy(element, index, elements, gridSize);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get and/or set the text color of this element.
|
|
||||||
* @param {string} [color] the new text color (if setting)
|
|
||||||
* @returns {string} the text color
|
|
||||||
* @memberof platform/features/layout.TextProxy#
|
|
||||||
*/
|
|
||||||
proxy.color = new AccessorMutator(element, 'color');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get and/or set the displayed text of this element.
|
|
||||||
* @param {string} [text] the new text (if setting)
|
|
||||||
* @returns {string} the text
|
|
||||||
* @memberof platform/features/layout.TextProxy#
|
|
||||||
*/
|
|
||||||
proxy.text = new AccessorMutator(element, 'text');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get and/or set the text size of this element.
|
|
||||||
*
|
|
||||||
* @param {string} [size] the new text size (if setting)
|
|
||||||
* @returns {string} the text size
|
|
||||||
* @memberof platform/features/layout.TextProxy#
|
|
||||||
*/
|
|
||||||
proxy.size = new AccessorMutator(element, 'size');
|
|
||||||
|
|
||||||
return proxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TextProxy;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,92 +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 () {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Variant of AccessorMutator to handle the specific case of updating
|
|
||||||
* useGrid, in order update the positions appropriately from within
|
|
||||||
* the scope of UnitAccessorMutator
|
|
||||||
*
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
* @param {ElementProxy} proxy ElementProxy object to perform the update
|
|
||||||
* upon
|
|
||||||
*/
|
|
||||||
function UnitAccessorMutator(elementProxy) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
this.elementProxy = elementProxy;
|
|
||||||
return function (useGrid) {
|
|
||||||
var current = elementProxy.element.useGrid;
|
|
||||||
if (arguments.length > 0) {
|
|
||||||
elementProxy.element.useGrid = useGrid;
|
|
||||||
if (useGrid && !current) {
|
|
||||||
self.convertCoordsTo('grid');
|
|
||||||
} else if (!useGrid && current) {
|
|
||||||
self.convertCoordsTo('px');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return elementProxy.element.useGrid;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For the elementProxy object called upon, convert its element's
|
|
||||||
* coordinates and size from pixels to grid units, or vice-versa.
|
|
||||||
* @param {string} unit When called with 'px', converts grid units to
|
|
||||||
* pixels; when called with 'grid', snaps element
|
|
||||||
* to grid units
|
|
||||||
*/
|
|
||||||
UnitAccessorMutator.prototype.convertCoordsTo = function (unit) {
|
|
||||||
var proxy = this.elementProxy,
|
|
||||||
gridSize = proxy.gridSize,
|
|
||||||
element = proxy.element,
|
|
||||||
minWidth = proxy.getMinWidth(),
|
|
||||||
minHeight = proxy.getMinHeight();
|
|
||||||
if (unit === 'px') {
|
|
||||||
element.x = element.x * gridSize[0];
|
|
||||||
element.y = element.y * gridSize[1];
|
|
||||||
element.width = element.width * gridSize[0];
|
|
||||||
element.height = element.height * gridSize[1];
|
|
||||||
if (element.x2 && element.y2) {
|
|
||||||
element.x2 = element.x2 * gridSize[0];
|
|
||||||
element.y2 = element.y2 * gridSize[1];
|
|
||||||
}
|
|
||||||
} else if (unit === 'grid') {
|
|
||||||
element.x = Math.round(element.x / gridSize[0]);
|
|
||||||
element.y = Math.round(element.y / gridSize[1]);
|
|
||||||
element.width = Math.max(Math.round(element.width / gridSize[0]), minWidth);
|
|
||||||
element.height = Math.max(Math.round(element.height / gridSize[1]), minHeight);
|
|
||||||
if (element.x2 && element.y2) {
|
|
||||||
element.x2 = Math.round(element.x2 / gridSize[0]);
|
|
||||||
element.y2 = Math.round(element.y2 / gridSize[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return UnitAccessorMutator;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,26 +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.
|
|
||||||
-->
|
|
||||||
<div
|
|
||||||
class="l-fixed-position-box"
|
|
||||||
ng-style="{ background: ngModel.fill(), border: '1px ' + ngModel.stroke() + ' solid' }"
|
|
||||||
>
|
|
||||||
</div>
|
|
@ -1,26 +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.
|
|
||||||
-->
|
|
||||||
<div
|
|
||||||
ng-style="{ 'background-image': 'url(' + ngModel.element.url + ')', border: '1px solid ' + ngModel.stroke() }"
|
|
||||||
class="l-fixed-position-image"
|
|
||||||
>
|
|
||||||
</div>
|
|
@ -1,31 +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.
|
|
||||||
-->
|
|
||||||
<svg ng-attr-width="{{ngModel.getGridSize()[0] * ngModel.width()}}"
|
|
||||||
ng-attr-height="{{ngModel.getGridSize()[1] * ngModel.height()}}">
|
|
||||||
<line ng-attr-x1="{{ngModel.getGridSize()[0] * ngModel.x1() + 1}}"
|
|
||||||
ng-attr-y1="{{ngModel.getGridSize()[1] * ngModel.y1() + 1}}"
|
|
||||||
ng-attr-x2="{{ngModel.getGridSize()[0] * ngModel.x2() + 1}}"
|
|
||||||
ng-attr-y2="{{ngModel.getGridSize()[1] * ngModel.y2() + 1}}"
|
|
||||||
ng-attr-stroke="{{ngModel.stroke()}}"
|
|
||||||
stroke-width="2">
|
|
||||||
</line>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.5 KiB |
@ -1,27 +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.
|
|
||||||
-->
|
|
||||||
<div
|
|
||||||
class="l-fixed-position-text l-static-text"
|
|
||||||
ng-style="{ background: ngModel.fill(), 'border-color': ngModel.stroke(), color: ngModel.color(), 'font-size': ngModel.size() }"
|
|
||||||
>
|
|
||||||
{{ngModel.element.text}}
|
|
||||||
</div>
|
|
@ -1,62 +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.
|
|
||||||
-->
|
|
||||||
<div class="t-fixed-position l-fixed-position"
|
|
||||||
ng-controller="FixedController as controller">
|
|
||||||
|
|
||||||
<!-- Background grid -->
|
|
||||||
<div class="l-fixed-position__grid-holder l-grid-holder c-grid" ng-click="controller.bypassSelection($event)">
|
|
||||||
<div class="c-grid__x l-grid l-grid-x"
|
|
||||||
ng-if="!controller.getGridSize()[0] < 3"
|
|
||||||
ng-style="{ 'background-size': controller.getGridSize() [0] + 'px 100%' }"></div>
|
|
||||||
<div class="c-grid__y l-grid l-grid-y"
|
|
||||||
ng-if="!controller.getGridSize()[1] < 3"
|
|
||||||
ng-style="{ 'background-size': '100% ' + controller.getGridSize() [1] + 'px' }"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Fixed position elements -->
|
|
||||||
<div ng-repeat="element in controller.getElements()"
|
|
||||||
class="l-fixed-position-item s-selectable s-moveable is-selectable is-moveable"
|
|
||||||
ng-style="element.style"
|
|
||||||
mct-selectable="controller.getContext(element)"
|
|
||||||
mct-init-select="controller.shouldSelect(element)">
|
|
||||||
<mct-include key="element.template"
|
|
||||||
parameters="{ gridSize: controller.getGridSize() }"
|
|
||||||
ng-model="element">
|
|
||||||
</mct-include>
|
|
||||||
</div>
|
|
||||||
<!-- Selection highlight, handles -->
|
|
||||||
<span class="c-frame-edit" ng-if="controller.isElementSelected()">
|
|
||||||
<div class="c-frame-edit__move"
|
|
||||||
mct-drag-down="controller.moveHandle().startDrag()"
|
|
||||||
mct-drag="controller.moveHandle().continueDrag(delta)"
|
|
||||||
mct-drag-up="controller.endDrag()"
|
|
||||||
ng-style="controller.getSelectedElementStyle()">
|
|
||||||
</div>
|
|
||||||
<div ng-repeat="handle in controller.handles()"
|
|
||||||
class="c-frame-edit__handle c-frame-edit__handle--nwse"
|
|
||||||
ng-style="handle.style()"
|
|
||||||
mct-drag-down="handle.startDrag()"
|
|
||||||
mct-drag="handle.continueDrag(delta)"
|
|
||||||
mct-drag-up="controller.endDrag(handle)">
|
|
||||||
</div>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
@ -1,49 +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.
|
|
||||||
-->
|
|
||||||
<div class="frame frame-template t-frame-inner abs has-local-controls t-object-type-{{ domainObject.getModel().type }}">
|
|
||||||
<div class="abs object-browse-bar l-flex-row">
|
|
||||||
<div class="left flex-elem l-flex-row grows">
|
|
||||||
<mct-representation
|
|
||||||
key="'object-header-frame'"
|
|
||||||
mct-object="domainObject"
|
|
||||||
class="l-flex-row flex-elem object-header grows">
|
|
||||||
</mct-representation>
|
|
||||||
</div>
|
|
||||||
<div class="btn-bar right l-flex-row flex-elem flex-justify-end flex-fixed h-local-controls local-controls-hidden">
|
|
||||||
<mct-representation
|
|
||||||
key="'switcher'"
|
|
||||||
ng-model="representation"
|
|
||||||
mct-object="domainObject">
|
|
||||||
</mct-representation>
|
|
||||||
<a class="s-button icon-expand t-btn-view-large"
|
|
||||||
title="View large"
|
|
||||||
mct-trigger-modal>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="abs object-holder">
|
|
||||||
<mct-representation
|
|
||||||
key="representation.selected.key"
|
|
||||||
mct-object="representation.selected.key && domainObject">
|
|
||||||
</mct-representation>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,641 +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/FixedController",
|
|
||||||
"zepto"
|
|
||||||
],
|
|
||||||
function (
|
|
||||||
FixedController,
|
|
||||||
$
|
|
||||||
) {
|
|
||||||
|
|
||||||
describe("The Fixed Position controller", function () {
|
|
||||||
var mockScope,
|
|
||||||
mockQ,
|
|
||||||
mockDialogService,
|
|
||||||
mockFormatter,
|
|
||||||
mockDomainObject,
|
|
||||||
mockEvent,
|
|
||||||
testGrid,
|
|
||||||
testModel,
|
|
||||||
testConfiguration,
|
|
||||||
mockOpenMCT,
|
|
||||||
mockTelemetryAPI,
|
|
||||||
mockCompositionAPI,
|
|
||||||
mockCompositionCollection,
|
|
||||||
mockChildren,
|
|
||||||
mockConductor,
|
|
||||||
mockMetadata,
|
|
||||||
mockTimeSystem,
|
|
||||||
mockLimitEvaluator,
|
|
||||||
mockSelection,
|
|
||||||
mockObjects,
|
|
||||||
mockNewDomainObject,
|
|
||||||
unlistenFunc,
|
|
||||||
$element = [],
|
|
||||||
selectable = [],
|
|
||||||
controller;
|
|
||||||
|
|
||||||
// Utility function; find a $on calls for a given expression.
|
|
||||||
function findOn(expr) {
|
|
||||||
var on;
|
|
||||||
mockScope.$on.calls.all().forEach(function (call) {
|
|
||||||
if (call.args[0] === expr) {
|
|
||||||
on = call.args[1];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return on;
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeMockDomainObject(id) {
|
|
||||||
return {
|
|
||||||
identifier: {
|
|
||||||
key: "domainObject-" + id,
|
|
||||||
namespace: ""
|
|
||||||
},
|
|
||||||
name: "Point " + id
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
mockScope = jasmine.createSpyObj(
|
|
||||||
'$scope',
|
|
||||||
["$on", "$watch", "$digest", "commit"]
|
|
||||||
);
|
|
||||||
mockQ = jasmine.createSpyObj('$q', ['when']);
|
|
||||||
mockDialogService = jasmine.createSpyObj(
|
|
||||||
'dialogService',
|
|
||||||
['getUserInput']
|
|
||||||
);
|
|
||||||
mockFormatter = jasmine.createSpyObj(
|
|
||||||
'telemetryFormatter',
|
|
||||||
['format']
|
|
||||||
);
|
|
||||||
mockFormatter.format.and.callFake(function (valueMetadata) {
|
|
||||||
return "Formatted " + valueMetadata.value;
|
|
||||||
});
|
|
||||||
|
|
||||||
mockConductor = jasmine.createSpyObj('conductor', [
|
|
||||||
'on',
|
|
||||||
'off',
|
|
||||||
'bounds',
|
|
||||||
'timeSystem',
|
|
||||||
'clock'
|
|
||||||
]);
|
|
||||||
mockConductor.bounds.and.returnValue({});
|
|
||||||
mockTimeSystem = {
|
|
||||||
metadata: {
|
|
||||||
key: 'key'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
mockConductor.timeSystem.and.returnValue(mockTimeSystem);
|
|
||||||
|
|
||||||
mockEvent = jasmine.createSpyObj(
|
|
||||||
'event',
|
|
||||||
['preventDefault']
|
|
||||||
);
|
|
||||||
|
|
||||||
mockTelemetryAPI = jasmine.createSpyObj('telemetry',
|
|
||||||
[
|
|
||||||
'subscribe',
|
|
||||||
'request',
|
|
||||||
'isTelemetryObject',
|
|
||||||
'getMetadata',
|
|
||||||
'limitEvaluator',
|
|
||||||
'getValueFormatter'
|
|
||||||
]
|
|
||||||
);
|
|
||||||
mockTelemetryAPI.isTelemetryObject.and.returnValue(true);
|
|
||||||
mockTelemetryAPI.request.and.returnValue(Promise.resolve([]));
|
|
||||||
|
|
||||||
testGrid = [123, 456];
|
|
||||||
testModel = {
|
|
||||||
composition: ['a', 'b', 'c'],
|
|
||||||
layoutGrid: testGrid
|
|
||||||
};
|
|
||||||
testConfiguration = { elements: [
|
|
||||||
{ type: "fixed.telemetry", id: 'a', x: 1, y: 1, useGrid: true},
|
|
||||||
{ type: "fixed.telemetry", id: 'b', x: 1, y: 1, useGrid: true},
|
|
||||||
{ type: "fixed.telemetry", id: 'c', x: 1, y: 1, useGrid: true}
|
|
||||||
]};
|
|
||||||
|
|
||||||
mockChildren = testModel.composition.map(makeMockDomainObject);
|
|
||||||
mockCompositionCollection = jasmine.createSpyObj('compositionCollection', [
|
|
||||||
'load',
|
|
||||||
'on',
|
|
||||||
'off'
|
|
||||||
]);
|
|
||||||
mockCompositionAPI = jasmine.createSpyObj('composition', [
|
|
||||||
'get'
|
|
||||||
]);
|
|
||||||
mockCompositionAPI.get.and.returnValue(mockCompositionCollection);
|
|
||||||
mockCompositionCollection.load.and.returnValue(
|
|
||||||
Promise.resolve(mockChildren)
|
|
||||||
);
|
|
||||||
|
|
||||||
mockScope.model = testModel;
|
|
||||||
mockScope.configuration = testConfiguration;
|
|
||||||
|
|
||||||
mockNewDomainObject = jasmine.createSpyObj("newDomainObject", [
|
|
||||||
'layoutGrid',
|
|
||||||
'configuration',
|
|
||||||
'composition'
|
|
||||||
]);
|
|
||||||
mockNewDomainObject.layoutGrid = testGrid;
|
|
||||||
mockNewDomainObject.configuration = {
|
|
||||||
'fixed-display': testConfiguration
|
|
||||||
};
|
|
||||||
mockNewDomainObject.composition = ['a', 'b', 'c'];
|
|
||||||
|
|
||||||
mockDomainObject = jasmine.createSpyObj(
|
|
||||||
'domainObject',
|
|
||||||
['getId', 'getModel', 'getCapability', 'useCapability']
|
|
||||||
);
|
|
||||||
mockDomainObject.useCapability.and.returnValue(mockNewDomainObject);
|
|
||||||
mockScope.domainObject = mockDomainObject;
|
|
||||||
|
|
||||||
selectable[0] = {
|
|
||||||
context: {
|
|
||||||
oldItem: mockDomainObject
|
|
||||||
}
|
|
||||||
};
|
|
||||||
mockSelection = jasmine.createSpyObj("selection", [
|
|
||||||
'select',
|
|
||||||
'on',
|
|
||||||
'off',
|
|
||||||
'get'
|
|
||||||
]);
|
|
||||||
mockSelection.get.and.returnValue([]);
|
|
||||||
|
|
||||||
unlistenFunc = jasmine.createSpy("unlisten");
|
|
||||||
mockObjects = jasmine.createSpyObj('objects', [
|
|
||||||
'observe',
|
|
||||||
'get'
|
|
||||||
]);
|
|
||||||
mockObjects.observe.and.returnValue(unlistenFunc);
|
|
||||||
|
|
||||||
mockOpenMCT = {
|
|
||||||
time: mockConductor,
|
|
||||||
telemetry: mockTelemetryAPI,
|
|
||||||
composition: mockCompositionAPI,
|
|
||||||
selection: mockSelection,
|
|
||||||
objects: mockObjects
|
|
||||||
};
|
|
||||||
|
|
||||||
$element = $('<div></div>');
|
|
||||||
spyOn($element[0], 'click');
|
|
||||||
|
|
||||||
mockMetadata = jasmine.createSpyObj('mockMetadata', [
|
|
||||||
'valuesForHints',
|
|
||||||
'value',
|
|
||||||
'values'
|
|
||||||
]);
|
|
||||||
mockMetadata.value.and.returnValue({
|
|
||||||
key: 'value'
|
|
||||||
});
|
|
||||||
|
|
||||||
mockMetadata.valuesForHints.and.callFake(function (hints) {
|
|
||||||
if (hints === ['domain']) {
|
|
||||||
return [{
|
|
||||||
key: 'time'
|
|
||||||
}];
|
|
||||||
} else {
|
|
||||||
return [{
|
|
||||||
key: 'value'
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mockLimitEvaluator = jasmine.createSpyObj('limitEvaluator', [
|
|
||||||
'evaluate'
|
|
||||||
]);
|
|
||||||
|
|
||||||
mockLimitEvaluator.evaluate.and.returnValue({});
|
|
||||||
|
|
||||||
mockTelemetryAPI.getMetadata.and.returnValue(mockMetadata);
|
|
||||||
mockTelemetryAPI.limitEvaluator.and.returnValue(mockLimitEvaluator);
|
|
||||||
mockTelemetryAPI.getValueFormatter.and.returnValue(mockFormatter);
|
|
||||||
|
|
||||||
controller = new FixedController(
|
|
||||||
mockScope,
|
|
||||||
mockQ,
|
|
||||||
mockDialogService,
|
|
||||||
mockOpenMCT,
|
|
||||||
$element
|
|
||||||
);
|
|
||||||
spyOn(controller, "mutate");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("subscribes a domain object", function () {
|
|
||||||
var object = makeMockDomainObject("mock");
|
|
||||||
|
|
||||||
return controller.getTelemetry(object).then(function () {
|
|
||||||
expect(mockTelemetryAPI.subscribe).toHaveBeenCalledWith(
|
|
||||||
object,
|
|
||||||
jasmine.any(Function),
|
|
||||||
jasmine.any(Object)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("releases subscription when a domain objects is removed", function () {
|
|
||||||
var unsubscribe = jasmine.createSpy('unsubscribe');
|
|
||||||
var unsubscribePromise = new Promise(function (resolve) {
|
|
||||||
unsubscribe.and.callFake(resolve);
|
|
||||||
});
|
|
||||||
var object = makeMockDomainObject("mock");
|
|
||||||
|
|
||||||
mockTelemetryAPI.subscribe.and.returnValue(unsubscribe);
|
|
||||||
return controller.getTelemetry(object).then(function () {
|
|
||||||
controller.onCompositionRemove(object.identifier);
|
|
||||||
return unsubscribePromise;
|
|
||||||
}).then(function () {
|
|
||||||
expect(unsubscribe).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("exposes visible elements based on configuration", function () {
|
|
||||||
var elements = controller.getElements();
|
|
||||||
|
|
||||||
expect(elements.length).toEqual(3);
|
|
||||||
expect(elements[0].id).toEqual('a');
|
|
||||||
expect(elements[1].id).toEqual('b');
|
|
||||||
expect(elements[2].id).toEqual('c');
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows elements to be selected", function () {
|
|
||||||
selectable[0].context.elementProxy = controller.getElements()[1];
|
|
||||||
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable);
|
|
||||||
|
|
||||||
expect(controller.isElementSelected()).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows selection retrieval", function () {
|
|
||||||
var elements = controller.getElements();
|
|
||||||
selectable[0].context.elementProxy = elements[1];
|
|
||||||
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable);
|
|
||||||
|
|
||||||
expect(controller.getSelectedElement()).toEqual(elements[1]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("selects the parent view when selected element is removed", function () {
|
|
||||||
var elements = controller.getElements();
|
|
||||||
selectable[0].context.elementProxy = elements[1];
|
|
||||||
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable);
|
|
||||||
controller.remove(elements[1]);
|
|
||||||
|
|
||||||
expect($element[0].click).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("retains selections during refresh", function () {
|
|
||||||
// Get elements; remove one of them; trigger refresh.
|
|
||||||
// Same element (at least by index) should still be selected.
|
|
||||||
var elements = controller.getElements();
|
|
||||||
selectable[0].context.elementProxy = elements[1];
|
|
||||||
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable);
|
|
||||||
|
|
||||||
expect(controller.getSelectedElement()).toEqual(elements[1]);
|
|
||||||
|
|
||||||
controller.remove(elements[2]);
|
|
||||||
elements = controller.getElements();
|
|
||||||
|
|
||||||
// Verify removal, as test assumes this
|
|
||||||
expect(elements.length).toEqual(2);
|
|
||||||
|
|
||||||
expect(controller.shouldSelect(elements[1])).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Displays received values for telemetry elements", function () {
|
|
||||||
var elements;
|
|
||||||
var mockTelemetry = {
|
|
||||||
time: 100,
|
|
||||||
value: 200
|
|
||||||
};
|
|
||||||
var testElement = {};
|
|
||||||
var telemetryObject = {
|
|
||||||
identifier: {
|
|
||||||
key: '12345'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
mockConductor.clock.and.returnValue({});
|
|
||||||
controller.elementProxiesById = {};
|
|
||||||
controller.elementProxiesById['12345'] = [testElement];
|
|
||||||
controller.elementProxies = [testElement];
|
|
||||||
|
|
||||||
controller.subscribeToObject(telemetryObject);
|
|
||||||
mockTelemetryAPI.subscribe.calls.mostRecent().args[1](mockTelemetry);
|
|
||||||
|
|
||||||
return new Promise(function (resolve) {
|
|
||||||
mockScope.$digest.and.callFake(resolve);
|
|
||||||
}).then(function () {
|
|
||||||
// Get elements that controller is now exposing
|
|
||||||
elements = controller.getElements();
|
|
||||||
|
|
||||||
// Formatted values should be available
|
|
||||||
expect(elements[0].value).toEqual("Formatted 200");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("updates elements styles when grid size changes", function () {
|
|
||||||
// Grid size is initially set to testGrid which is [123, 456]
|
|
||||||
var originalLeft = controller.getElements()[0].style.left;
|
|
||||||
|
|
||||||
// Change the grid size
|
|
||||||
controller.updateElementPositions([20, 20]);
|
|
||||||
|
|
||||||
expect(controller.getElements()[0].style.left).not.toEqual(originalLeft);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("listens for drop events", function () {
|
|
||||||
mockScope.domainObject = mockDomainObject;
|
|
||||||
mockScope.model = testModel;
|
|
||||||
|
|
||||||
// Layout should position panels according to
|
|
||||||
// where the user dropped them, so it needs to
|
|
||||||
// listen for drop events.
|
|
||||||
expect(mockScope.$on).toHaveBeenCalledWith(
|
|
||||||
'mctDrop',
|
|
||||||
jasmine.any(Function)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Verify precondition
|
|
||||||
expect(testConfiguration.elements.length).toEqual(3);
|
|
||||||
|
|
||||||
// Notify that a drop occurred
|
|
||||||
testModel.composition.push('d');
|
|
||||||
|
|
||||||
mockObjects.get.and.returnValue(Promise.resolve([]));
|
|
||||||
|
|
||||||
findOn('mctDrop')(
|
|
||||||
mockEvent,
|
|
||||||
'd',
|
|
||||||
{ x: 300, y: 100 }
|
|
||||||
);
|
|
||||||
|
|
||||||
// Should have added an element
|
|
||||||
expect(testConfiguration.elements.length).toEqual(4);
|
|
||||||
|
|
||||||
// ...and prevented default...
|
|
||||||
expect(mockEvent.preventDefault).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("ignores drops when default has been prevented", function () {
|
|
||||||
// Avoids redundant drop-handling, WTD-1233
|
|
||||||
mockEvent.defaultPrevented = true;
|
|
||||||
|
|
||||||
// Notify that a drop occurred
|
|
||||||
testModel.composition.push('d');
|
|
||||||
findOn('mctDrop')(
|
|
||||||
mockEvent,
|
|
||||||
'd',
|
|
||||||
{ x: 300, y: 100 }
|
|
||||||
);
|
|
||||||
|
|
||||||
// Should NOT have added an element
|
|
||||||
expect(testConfiguration.elements.length).toEqual(3);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("unsubscribes when destroyed", function () {
|
|
||||||
var unsubscribe = jasmine.createSpy('unsubscribe');
|
|
||||||
var object = makeMockDomainObject("mock");
|
|
||||||
|
|
||||||
mockTelemetryAPI.subscribe.and.returnValue(unsubscribe);
|
|
||||||
|
|
||||||
return controller.getTelemetry(object).then(function () {
|
|
||||||
expect(unsubscribe).not.toHaveBeenCalled();
|
|
||||||
// Destroy the scope
|
|
||||||
findOn('$destroy')();
|
|
||||||
|
|
||||||
expect(unsubscribe).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("exposes its grid size", function () {
|
|
||||||
expect(controller.getGridSize()).toEqual(testGrid);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("exposes drag handles", function () {
|
|
||||||
var handles;
|
|
||||||
selectable[0].context.elementProxy = controller.getElements()[1];
|
|
||||||
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable);
|
|
||||||
|
|
||||||
// Should have a non-empty array of handles
|
|
||||||
handles = controller.handles();
|
|
||||||
|
|
||||||
expect(handles).toEqual(jasmine.any(Array));
|
|
||||||
expect(handles.length).not.toEqual(0);
|
|
||||||
|
|
||||||
// And they should have start/continue/end drag methods
|
|
||||||
handles.forEach(function (handle) {
|
|
||||||
expect(handle.startDrag).toEqual(jasmine.any(Function));
|
|
||||||
expect(handle.continueDrag).toEqual(jasmine.any(Function));
|
|
||||||
expect(handle.endDrag).toEqual(jasmine.any(Function));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("exposes a move handle", function () {
|
|
||||||
selectable[0].context.elementProxy = controller.getElements()[1];
|
|
||||||
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable);
|
|
||||||
|
|
||||||
// Should have a move handle
|
|
||||||
var handle = controller.moveHandle();
|
|
||||||
|
|
||||||
// And it should have start/continue/end drag methods
|
|
||||||
expect(handle.startDrag).toEqual(jasmine.any(Function));
|
|
||||||
expect(handle.continueDrag).toEqual(jasmine.any(Function));
|
|
||||||
expect(handle.endDrag).toEqual(jasmine.any(Function));
|
|
||||||
});
|
|
||||||
|
|
||||||
it("updates selection style during drag", function () {
|
|
||||||
var oldStyle;
|
|
||||||
selectable[0].context.elementProxy = controller.getElements()[1];
|
|
||||||
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable);
|
|
||||||
|
|
||||||
// Get style
|
|
||||||
oldStyle = controller.getSelectedElementStyle();
|
|
||||||
|
|
||||||
// Start a drag gesture
|
|
||||||
controller.moveHandle().startDrag();
|
|
||||||
|
|
||||||
// Haven't moved yet; style shouldn't have updated yet
|
|
||||||
expect(controller.getSelectedElementStyle()).toEqual(oldStyle);
|
|
||||||
|
|
||||||
// Drag a little
|
|
||||||
controller.moveHandle().continueDrag([1000, 100]);
|
|
||||||
|
|
||||||
// Style should have been updated
|
|
||||||
expect(controller.getSelectedElementStyle()).not.toEqual(oldStyle);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("cleans up selection on scope destroy", function () {
|
|
||||||
expect(mockScope.$on).toHaveBeenCalledWith(
|
|
||||||
'$destroy',
|
|
||||||
jasmine.any(Function)
|
|
||||||
);
|
|
||||||
|
|
||||||
mockScope.$on.calls.mostRecent().args[1]();
|
|
||||||
|
|
||||||
expect(mockOpenMCT.selection.off).toHaveBeenCalledWith(
|
|
||||||
'change',
|
|
||||||
jasmine.any(Function)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("on display bounds changes", function () {
|
|
||||||
var testBounds;
|
|
||||||
var boundsChangeCallback;
|
|
||||||
var objectOne;
|
|
||||||
var objectTwo;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
testBounds = { start: 123, end: 321 };
|
|
||||||
boundsChangeCallback = mockConductor.on.calls.mostRecent().args[1];
|
|
||||||
objectOne = {};
|
|
||||||
objectTwo = {};
|
|
||||||
controller.telemetryObjects = [
|
|
||||||
objectOne,
|
|
||||||
objectTwo
|
|
||||||
];
|
|
||||||
spyOn(controller, "fetchHistoricalData");
|
|
||||||
controller.fetchHistoricalData.and.callThrough();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("registers a bounds change listener", function () {
|
|
||||||
expect(mockConductor.on).toHaveBeenCalledWith("bounds", jasmine.any(Function));
|
|
||||||
});
|
|
||||||
|
|
||||||
it("requests only a single point", function () {
|
|
||||||
mockConductor.clock.and.returnValue(undefined);
|
|
||||||
boundsChangeCallback(testBounds);
|
|
||||||
expect(mockTelemetryAPI.request.calls.count()).toBe(2);
|
|
||||||
|
|
||||||
mockTelemetryAPI.request.calls.all().forEach(function (call) {
|
|
||||||
expect(call.args[1].size).toBe(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Does not fetch historical data on tick", function () {
|
|
||||||
boundsChangeCallback(testBounds, true);
|
|
||||||
expect(mockTelemetryAPI.request.calls.count()).toBe(0);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("on receipt of telemetry", function () {
|
|
||||||
var mockTelemetryObject;
|
|
||||||
var testValue;
|
|
||||||
var testElement;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
mockTelemetryObject = {
|
|
||||||
identifier: {
|
|
||||||
key: '12345'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
testValue = 30;
|
|
||||||
testElement = {};
|
|
||||||
|
|
||||||
controller.elementProxiesById = {};
|
|
||||||
controller.elementProxiesById['12345'] = [testElement];
|
|
||||||
controller.elementProxies = [testElement];
|
|
||||||
});
|
|
||||||
|
|
||||||
it("updates displayed values from historical telemetry", function () {
|
|
||||||
spyOn(controller, "updateView");
|
|
||||||
controller.updateView.and.callThrough();
|
|
||||||
|
|
||||||
mockTelemetryAPI.request.and.returnValue(Promise.resolve([{
|
|
||||||
time: 100,
|
|
||||||
value: testValue
|
|
||||||
}]));
|
|
||||||
|
|
||||||
controller.fetchHistoricalData(mockTelemetryObject);
|
|
||||||
|
|
||||||
return new Promise(function (resolve) {
|
|
||||||
mockScope.$digest.and.callFake(resolve);
|
|
||||||
}).then(function () {
|
|
||||||
expect(controller.updateView).toHaveBeenCalled();
|
|
||||||
expect(controller.getElements()[0].value)
|
|
||||||
.toEqual("Formatted " + testValue);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("selects an range value to display, if available", function () {
|
|
||||||
mockMetadata.valuesForHints.and.returnValue([
|
|
||||||
{
|
|
||||||
key: 'range',
|
|
||||||
source: 'range'
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
var key = controller.chooseValueMetadataToDisplay(mockMetadata).source;
|
|
||||||
expect(key).toEqual('range');
|
|
||||||
});
|
|
||||||
|
|
||||||
it("selects the first non-domain value to display, if no range available", function () {
|
|
||||||
mockMetadata.valuesForHints.and.returnValue([]);
|
|
||||||
mockMetadata.values.and.returnValue([
|
|
||||||
{
|
|
||||||
key: 'domain',
|
|
||||||
source: 'domain',
|
|
||||||
hints: {
|
|
||||||
domain: 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'image',
|
|
||||||
source: 'image',
|
|
||||||
hints: {
|
|
||||||
image: 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
var key = controller.chooseValueMetadataToDisplay(mockMetadata).source;
|
|
||||||
expect(key).toEqual('image');
|
|
||||||
});
|
|
||||||
|
|
||||||
it("reflects limit status", function () {
|
|
||||||
mockLimitEvaluator.evaluate.and.returnValue({cssClass: "alarm-a"});
|
|
||||||
controller.updateView(mockTelemetryObject, [{
|
|
||||||
time: 100,
|
|
||||||
value: testValue
|
|
||||||
}]);
|
|
||||||
|
|
||||||
return new Promise(function (resolve) {
|
|
||||||
mockScope.$digest.and.callFake(resolve);
|
|
||||||
}).then(function () {
|
|
||||||
// Limit-based CSS classes should be available
|
|
||||||
expect(controller.getElements()[0].cssClass).toEqual("alarm-a");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("listens for selection change events", function () {
|
|
||||||
expect(mockOpenMCT.selection.on).toHaveBeenCalledWith(
|
|
||||||
'change',
|
|
||||||
jasmine.any(Function)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,92 +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/FixedDragHandle'],
|
|
||||||
function (FixedDragHandle) {
|
|
||||||
|
|
||||||
var TEST_GRID_SIZE = [13, 33];
|
|
||||||
|
|
||||||
describe("A fixed position drag handle", function () {
|
|
||||||
var mockElementHandle,
|
|
||||||
mockConfigPath,
|
|
||||||
mockFixedControl,
|
|
||||||
handle;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
mockElementHandle = jasmine.createSpyObj(
|
|
||||||
'elementHandle',
|
|
||||||
['x', 'y','getGridSize']
|
|
||||||
);
|
|
||||||
mockElementHandle.x.and.returnValue(6);
|
|
||||||
mockElementHandle.y.and.returnValue(8);
|
|
||||||
mockElementHandle.getGridSize.and.returnValue(TEST_GRID_SIZE);
|
|
||||||
|
|
||||||
mockFixedControl = jasmine.createSpyObj(
|
|
||||||
'fixedControl',
|
|
||||||
['updateSelectionStyle', 'mutate']
|
|
||||||
);
|
|
||||||
mockFixedControl.updateSelectionStyle.and.returnValue();
|
|
||||||
mockFixedControl.mutate.and.returnValue();
|
|
||||||
|
|
||||||
mockConfigPath = jasmine.createSpy('configPath');
|
|
||||||
|
|
||||||
handle = new FixedDragHandle(
|
|
||||||
mockElementHandle,
|
|
||||||
mockConfigPath,
|
|
||||||
mockFixedControl
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("provides a style for positioning", function () {
|
|
||||||
var style = handle.style();
|
|
||||||
// 6 grid coords * 13 pixels - 3 pixels for centering
|
|
||||||
expect(style.left).toEqual('75px');
|
|
||||||
// 8 grid coords * 33 pixels - 3 pixels for centering
|
|
||||||
expect(style.top).toEqual('261px');
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows handles to be dragged", function () {
|
|
||||||
handle.startDrag();
|
|
||||||
handle.continueDrag([16, 8]);
|
|
||||||
|
|
||||||
// Should update x/y, snapped to grid
|
|
||||||
expect(mockElementHandle.x).toHaveBeenCalledWith(7);
|
|
||||||
expect(mockElementHandle.y).toHaveBeenCalledWith(8);
|
|
||||||
|
|
||||||
handle.continueDrag([-16, -35]);
|
|
||||||
|
|
||||||
// Should have interpreted relative to initial state
|
|
||||||
expect(mockElementHandle.x).toHaveBeenCalledWith(5);
|
|
||||||
expect(mockElementHandle.y).toHaveBeenCalledWith(7);
|
|
||||||
|
|
||||||
// Should have called updateSelectionStyle once per continueDrag
|
|
||||||
expect(mockFixedControl.updateSelectionStyle.calls.count()).toEqual(2);
|
|
||||||
|
|
||||||
// Finally, ending drag should mutate
|
|
||||||
handle.endDrag();
|
|
||||||
expect(mockFixedControl.mutate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,71 +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/FixedProxy'],
|
|
||||||
function (FixedProxy) {
|
|
||||||
|
|
||||||
describe("Fixed Position view's selection proxy", function () {
|
|
||||||
var mockCallback,
|
|
||||||
mockQ,
|
|
||||||
mockDialogService,
|
|
||||||
mockPromise,
|
|
||||||
proxy;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
mockCallback = jasmine.createSpy('callback');
|
|
||||||
mockQ = jasmine.createSpyObj('$q', ['when']);
|
|
||||||
mockDialogService = jasmine.createSpyObj('dialogService', ['getUserInput']);
|
|
||||||
mockPromise = jasmine.createSpyObj('promise', ['then']);
|
|
||||||
|
|
||||||
mockQ.when.and.returnValue(mockPromise);
|
|
||||||
|
|
||||||
proxy = new FixedProxy(mockCallback, mockQ, mockDialogService);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("handles promised element creation", function () {
|
|
||||||
// The element factory may return promises (e.g. if
|
|
||||||
// user input is required) so make sure proxy is wrapping these
|
|
||||||
proxy.add("fixed.box");
|
|
||||||
expect(mockQ.when).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("notifies its callback when an element is created", function () {
|
|
||||||
proxy.add("fixed.box");
|
|
||||||
// Callback should not have been invoked yet
|
|
||||||
expect(mockCallback).not.toHaveBeenCalled();
|
|
||||||
// Resolve the promise
|
|
||||||
mockPromise.then.calls.mostRecent().args[0]({});
|
|
||||||
// Should have fired the callback
|
|
||||||
expect(mockCallback).toHaveBeenCalledWith({
|
|
||||||
type: "fixed.box",
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
width: 1,
|
|
||||||
height: 1,
|
|
||||||
useGrid: true
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,81 +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/LayoutDrag"],
|
|
||||||
function (LayoutDrag) {
|
|
||||||
|
|
||||||
describe("A Layout drag handler", function () {
|
|
||||||
var testPosition = {
|
|
||||||
position: [8, 11],
|
|
||||||
dimensions: [3, 2]
|
|
||||||
};
|
|
||||||
|
|
||||||
it("changes position by a supplied factor, rounding by grid size", function () {
|
|
||||||
var handler = new LayoutDrag(
|
|
||||||
testPosition,
|
|
||||||
[1, 1],
|
|
||||||
[0, 0],
|
|
||||||
[10, 20]
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(handler.getAdjustedPosition([37, 84])).toEqual({
|
|
||||||
position: [12, 15],
|
|
||||||
dimensions: [3, 2]
|
|
||||||
});
|
|
||||||
expect(handler.getAdjustedPosition([-37, 84])).toEqual({
|
|
||||||
position: [4, 15],
|
|
||||||
dimensions: [3, 2]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("changes dimensions by a supplied factor, rounding by grid size", function () {
|
|
||||||
var handler = new LayoutDrag(
|
|
||||||
testPosition,
|
|
||||||
[0, 0],
|
|
||||||
[1, 1],
|
|
||||||
[10, 20]
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(handler.getAdjustedPosition([37, 84])).toEqual({
|
|
||||||
position: [8, 11],
|
|
||||||
dimensions: [7, 6]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows mixing dimension and position factors", function () {
|
|
||||||
var handler = new LayoutDrag(
|
|
||||||
testPosition,
|
|
||||||
[0, 1],
|
|
||||||
[-1, 0],
|
|
||||||
[10, 20]
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(handler.getAdjustedPosition([11, 84])).toEqual({
|
|
||||||
position: [8, 15],
|
|
||||||
dimensions: [2, 2]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,128 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2016, 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/MCTTriggerModal'
|
|
||||||
], function (
|
|
||||||
MCTTriggerModal
|
|
||||||
) {
|
|
||||||
describe('MCTTriggerModal', function () {
|
|
||||||
var $scope,
|
|
||||||
$element,
|
|
||||||
frame,
|
|
||||||
layoutContainer,
|
|
||||||
$document,
|
|
||||||
mctTriggerModal;
|
|
||||||
|
|
||||||
function makeElement(classes, parentEl) {
|
|
||||||
var elem = jasmine.createSpyObj('element.' + classes.join('.'), [
|
|
||||||
'hasClass',
|
|
||||||
'parent'
|
|
||||||
]);
|
|
||||||
elem.hasClass.and.callFake(function (className) {
|
|
||||||
return classes.indexOf(className) !== -1;
|
|
||||||
});
|
|
||||||
elem.parent.and.returnValue(parentEl);
|
|
||||||
var div = document.createElement('div');
|
|
||||||
div.className = classes.join(' ');
|
|
||||||
parentEl[0].appendChild(div);
|
|
||||||
elem[0] = div;
|
|
||||||
return elem;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
$scope = jasmine.createSpyObj('$scope', ['$on']);
|
|
||||||
$scope.domainObject = { getCapability: function () {
|
|
||||||
return { getActions: function () {
|
|
||||||
return [];
|
|
||||||
}};
|
|
||||||
}};
|
|
||||||
|
|
||||||
$element = jasmine.createSpyObj('$element', [
|
|
||||||
'parent',
|
|
||||||
'remove',
|
|
||||||
'on',
|
|
||||||
'off'
|
|
||||||
]);
|
|
||||||
layoutContainer = document.createElement('div');
|
|
||||||
frame = makeElement(['frame'], [layoutContainer]);
|
|
||||||
var child = makeElement([], frame);
|
|
||||||
for (var i = 0; i < 5; i++) {
|
|
||||||
child = makeElement([], child);
|
|
||||||
}
|
|
||||||
$element.parent.and.returnValue(child);
|
|
||||||
$document = [jasmine.createSpyObj('document', ['createElement'])];
|
|
||||||
$document[0].body = document.createElement('div');
|
|
||||||
$document[0].createElement.and.callFake(function (tag) {
|
|
||||||
return document.createElement(tag);
|
|
||||||
});
|
|
||||||
|
|
||||||
mctTriggerModal = new MCTTriggerModal($document);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('is a directive definition', function () {
|
|
||||||
expect(mctTriggerModal.restrict).toBe('A');
|
|
||||||
expect(mctTriggerModal.link).toEqual(jasmine.any(Function));
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('link', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
mctTriggerModal.link($scope, $element);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('attaches handlers to $element', function () {
|
|
||||||
expect($element.on).toHaveBeenCalledWith(
|
|
||||||
'click',
|
|
||||||
jasmine.any(Function)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('cleans up on $scope $destroy', function () {
|
|
||||||
expect($scope.$on).toHaveBeenCalledWith(
|
|
||||||
'$destroy',
|
|
||||||
jasmine.any(Function)
|
|
||||||
);
|
|
||||||
$scope.$on.calls.mostRecent().args[1]();
|
|
||||||
expect($element.off).toHaveBeenCalledWith(
|
|
||||||
'click',
|
|
||||||
jasmine.any(Function)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('opens and closes overlays', function () {
|
|
||||||
[
|
|
||||||
'a.close', 'a.t-done', '.abs.blocker'
|
|
||||||
].forEach(function (selector) {
|
|
||||||
$element.on.calls.mostRecent().args[1]();
|
|
||||||
var container = $document[0].body.querySelector('.t-contents');
|
|
||||||
expect(container.children[0]).toBe(frame[0]);
|
|
||||||
expect(layoutContainer.children[0]).not.toBe(frame[0]);
|
|
||||||
$document[0].body.querySelector(selector)
|
|
||||||
.dispatchEvent(new Event('click'));
|
|
||||||
expect(container.children[0]).not.toBe(frame[0]);
|
|
||||||
expect(layoutContainer.children[0]).toBe(frame[0]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,50 +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/elements/AccessorMutator'],
|
|
||||||
function (AccessorMutator) {
|
|
||||||
|
|
||||||
describe("An accessor-mutator", function () {
|
|
||||||
var testObject,
|
|
||||||
am;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
testObject = { t: 42, other: 100 };
|
|
||||||
am = new AccessorMutator(testObject, 't');
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows access to a property", function () {
|
|
||||||
expect(am()).toEqual(42);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows mutation of a property", function () {
|
|
||||||
expect(am("some other value")).toEqual("some other value");
|
|
||||||
expect(testObject).toEqual({
|
|
||||||
t: "some other value",
|
|
||||||
other: 100
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,55 +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/elements/BoxProxy'],
|
|
||||||
function (BoxProxy) {
|
|
||||||
|
|
||||||
describe("A fixed position box proxy", function () {
|
|
||||||
var testElement,
|
|
||||||
testElements,
|
|
||||||
proxy;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
testElement = {
|
|
||||||
x: 1,
|
|
||||||
y: 2,
|
|
||||||
width: 42,
|
|
||||||
height: 24,
|
|
||||||
fill: "transparent"
|
|
||||||
};
|
|
||||||
testElements = [{}, {}, testElement, {}];
|
|
||||||
proxy = new BoxProxy(
|
|
||||||
testElement,
|
|
||||||
testElements.indexOf(testElement),
|
|
||||||
testElements
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("provides getter/setter for fill color", function () {
|
|
||||||
expect(proxy.fill()).toEqual('transparent');
|
|
||||||
expect(proxy.fill('#FFF')).toEqual('#FFF');
|
|
||||||
expect(proxy.fill()).toEqual('#FFF');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,69 +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/elements/ElementFactory'],
|
|
||||||
function (ElementFactory) {
|
|
||||||
|
|
||||||
var DIALOG_ELEMENTS = ['image', 'text'],
|
|
||||||
NON_DIALOG_ELEMENTS = ['box', 'line'];
|
|
||||||
|
|
||||||
describe("The fixed position element factory", function () {
|
|
||||||
var mockDialogService,
|
|
||||||
mockPromise,
|
|
||||||
factory;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
mockDialogService = jasmine.createSpyObj(
|
|
||||||
'dialogService',
|
|
||||||
['getUserInput']
|
|
||||||
);
|
|
||||||
mockPromise = jasmine.createSpyObj(
|
|
||||||
'promise',
|
|
||||||
['then']
|
|
||||||
);
|
|
||||||
|
|
||||||
mockDialogService.getUserInput.and.returnValue(mockPromise);
|
|
||||||
mockPromise.then.and.returnValue(mockPromise);
|
|
||||||
|
|
||||||
factory = new ElementFactory(mockDialogService);
|
|
||||||
});
|
|
||||||
|
|
||||||
DIALOG_ELEMENTS.forEach(function (type) {
|
|
||||||
it("shows a dialog for " + type + " elements", function () {
|
|
||||||
expect(factory.createElement('fixed.' + type))
|
|
||||||
.toEqual(mockPromise);
|
|
||||||
expect(mockDialogService.getUserInput).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
NON_DIALOG_ELEMENTS.forEach(function (type) {
|
|
||||||
it("immediately provides " + type + " elements", function () {
|
|
||||||
var result = factory.createElement('fixed.' + type);
|
|
||||||
expect(result).toBeDefined();
|
|
||||||
expect(result).not.toEqual(mockPromise);
|
|
||||||
expect(mockDialogService.getUserInput).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,51 +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/elements/ElementProxies'],
|
|
||||||
function (ElementProxies) {
|
|
||||||
|
|
||||||
// Expect these element types to have proxies
|
|
||||||
var ELEMENT_TYPES = [
|
|
||||||
"fixed.telemetry",
|
|
||||||
"fixed.line",
|
|
||||||
"fixed.box",
|
|
||||||
"fixed.text",
|
|
||||||
"fixed.image"
|
|
||||||
];
|
|
||||||
|
|
||||||
// Verify that the set of proxies exposed matches the specific
|
|
||||||
// list above.
|
|
||||||
describe("The set of element proxies", function () {
|
|
||||||
ELEMENT_TYPES.forEach(function (t) {
|
|
||||||
it("exposes a proxy wrapper for " + t + " elements", function () {
|
|
||||||
expect(typeof ElementProxies[t]).toEqual('function');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("exposes no additional wrappers", function () {
|
|
||||||
expect(Object.keys(ElementProxies).length)
|
|
||||||
.toEqual(ELEMENT_TYPES.length);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,98 +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/elements/ElementProxy'],
|
|
||||||
function (ElementProxy) {
|
|
||||||
|
|
||||||
describe("A fixed position element proxy", function () {
|
|
||||||
var testElement,
|
|
||||||
testElements,
|
|
||||||
proxy;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
testElement = {
|
|
||||||
x: 1,
|
|
||||||
y: 2,
|
|
||||||
stroke: '#717171',
|
|
||||||
width: 42,
|
|
||||||
height: 24,
|
|
||||||
useGrid: true
|
|
||||||
};
|
|
||||||
testElements = [{}, {}, testElement, {}];
|
|
||||||
proxy = new ElementProxy(
|
|
||||||
testElement,
|
|
||||||
testElements.indexOf(testElement),
|
|
||||||
testElements,
|
|
||||||
[13,21]
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("exposes element properties", function () {
|
|
||||||
Object.keys(testElement).forEach(function (k) {
|
|
||||||
expect(proxy[k]()).toEqual(testElement[k]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows order to be changed", function () {
|
|
||||||
proxy.order("down");
|
|
||||||
expect(testElements).toEqual([{}, testElement, {}, {}]);
|
|
||||||
proxy.order("up");
|
|
||||||
expect(testElements).toEqual([{}, {}, testElement, {}]);
|
|
||||||
proxy.order("bottom");
|
|
||||||
expect(testElements).toEqual([testElement, {}, {}, {}]);
|
|
||||||
proxy.order("top");
|
|
||||||
expect(testElements).toEqual([{}, {}, {}, testElement]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("ensures x/y values are non-negative", function () {
|
|
||||||
proxy.x(-1);
|
|
||||||
proxy.y(-400);
|
|
||||||
expect(proxy.x()).toEqual(0);
|
|
||||||
expect(proxy.y()).toEqual(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows modifying the current grid size", function () {
|
|
||||||
proxy.setGridSize([112,420]);
|
|
||||||
expect(proxy.gridSize).toEqual([112,420]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("returns the current grid size only if the element snaps to grid", function () {
|
|
||||||
expect(proxy.getGridSize()).toEqual([13,21]);
|
|
||||||
proxy.useGrid(false);
|
|
||||||
expect(proxy.getGridSize()).toEqual([1,1]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("returns the mininum height and width of an element currently used units", function () {
|
|
||||||
// Assumes mininum height and width are 10, in pixels
|
|
||||||
expect(proxy.getMinWidth()).toEqual(1);
|
|
||||||
expect(proxy.getMinHeight()).toEqual(1);
|
|
||||||
proxy.setGridSize([7,4]);
|
|
||||||
expect(proxy.getMinWidth()).toEqual(2);
|
|
||||||
expect(proxy.getMinHeight()).toEqual(3);
|
|
||||||
proxy.useGrid(false);
|
|
||||||
expect(proxy.getMinWidth()).toEqual(10);
|
|
||||||
expect(proxy.getMinHeight()).toEqual(10);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,56 +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/elements/ImageProxy'],
|
|
||||||
function (ImageProxy) {
|
|
||||||
|
|
||||||
describe("A fixed position image proxy", function () {
|
|
||||||
var testElement,
|
|
||||||
testElements,
|
|
||||||
proxy;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
testElement = {
|
|
||||||
x: 1,
|
|
||||||
y: 2,
|
|
||||||
width: 42,
|
|
||||||
height: 24,
|
|
||||||
url: "http://www.nasa.gov"
|
|
||||||
};
|
|
||||||
testElements = [{}, {}, testElement, {}];
|
|
||||||
proxy = new ImageProxy(
|
|
||||||
testElement,
|
|
||||||
testElements.indexOf(testElement),
|
|
||||||
testElements
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("provides getter/setter for image URL", function () {
|
|
||||||
expect(proxy.url()).toEqual("http://www.nasa.gov");
|
|
||||||
expect(proxy.url("http://www.nasa.gov/some.jpg"))
|
|
||||||
.toEqual("http://www.nasa.gov/some.jpg");
|
|
||||||
expect(proxy.url()).toEqual("http://www.nasa.gov/some.jpg");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,81 +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/elements/LineHandle'],
|
|
||||||
function (LineHandle) {
|
|
||||||
|
|
||||||
describe("A fixed position drag handle", function () {
|
|
||||||
var testElement,
|
|
||||||
mockElementProxy,
|
|
||||||
handle,
|
|
||||||
TEST_GRID_SIZE = [45, 21];
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
testElement = {
|
|
||||||
x: 3,
|
|
||||||
y: 42,
|
|
||||||
x2: 8,
|
|
||||||
y2: 11,
|
|
||||||
useGrid: true
|
|
||||||
};
|
|
||||||
mockElementProxy = jasmine.createSpyObj('elementProxy', ['getGridSize']);
|
|
||||||
mockElementProxy.getGridSize.and.returnValue(TEST_GRID_SIZE);
|
|
||||||
|
|
||||||
handle = new LineHandle(testElement, mockElementProxy, 'x', 'y', 'x2', 'y2');
|
|
||||||
});
|
|
||||||
|
|
||||||
it("provides x/y grid coordinates for its corner", function () {
|
|
||||||
expect(handle.x()).toEqual(3);
|
|
||||||
expect(handle.y()).toEqual(42);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("changes x and y positions", function () {
|
|
||||||
handle.x(30);
|
|
||||||
expect(testElement.x).toEqual(30);
|
|
||||||
handle.y(40);
|
|
||||||
expect(testElement.y).toEqual(40);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("disallows values less than zero", function () {
|
|
||||||
handle.x(-1);
|
|
||||||
handle.y(-400);
|
|
||||||
expect(testElement.x).toEqual(0);
|
|
||||||
expect(testElement.y).toEqual(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("ensures that end points remain different", function () {
|
|
||||||
handle.x(testElement.x2);
|
|
||||||
handle.y(testElement.y2);
|
|
||||||
// First change should have been fine, because y was different
|
|
||||||
expect(testElement.x).toEqual(testElement.x2);
|
|
||||||
// Second change should have been rejected
|
|
||||||
expect(testElement.y).not.toEqual(testElement.y2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("returns the correct grid size", function () {
|
|
||||||
expect(handle.getGridSize()).toEqual(TEST_GRID_SIZE);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,95 +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/elements/LineProxy'],
|
|
||||||
function (LineProxy) {
|
|
||||||
|
|
||||||
describe("A fixed position line proxy", function () {
|
|
||||||
var vertical, horizontal, diagonal, reversed;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
vertical = { x: 1, y: 4, x2: 1, y2: 8};
|
|
||||||
horizontal = { x: 3, y: 3, x2: 12, y2: 3};
|
|
||||||
diagonal = { x: 3, y: 8, x2: 5, y2: 11};
|
|
||||||
reversed = { x2: 3, y2: 8, x: 5, y: 11};
|
|
||||||
});
|
|
||||||
|
|
||||||
it("ensures visible width for vertical lines", function () {
|
|
||||||
expect(new LineProxy(vertical).width()).toEqual(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("ensures visible height for horizontal lines", function () {
|
|
||||||
expect(new LineProxy(horizontal).height()).toEqual(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("provides a bounding box for lines", function () {
|
|
||||||
var proxy = new LineProxy(diagonal);
|
|
||||||
expect(proxy.x()).toEqual(3);
|
|
||||||
expect(proxy.y()).toEqual(8);
|
|
||||||
expect(proxy.width()).toEqual(2);
|
|
||||||
expect(proxy.height()).toEqual(3);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("bounds lines identically regardless of point order", function () {
|
|
||||||
// That is, x(), width(), y(), and height() should always give
|
|
||||||
// the same results for the same line segments, regardless of
|
|
||||||
// which point is x,y and which is x2,y2
|
|
||||||
['x', 'y', 'width', 'height'].forEach(function (method) {
|
|
||||||
expect(new LineProxy(diagonal)[method]())
|
|
||||||
.toEqual(new LineProxy(reversed)[method]());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("adjusts both ends when mutating x", function () {
|
|
||||||
var proxy = new LineProxy(diagonal);
|
|
||||||
proxy.x(6);
|
|
||||||
expect(diagonal).toEqual({ x: 6, y: 8, x2: 8, y2: 11});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("adjusts both ends when mutating y", function () {
|
|
||||||
var proxy = new LineProxy(diagonal);
|
|
||||||
proxy.y(6);
|
|
||||||
expect(diagonal).toEqual({ x: 3, y: 6, x2: 5, y2: 9});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("provides internal positions for SVG lines", function () {
|
|
||||||
var proxy;
|
|
||||||
proxy = new LineProxy(diagonal);
|
|
||||||
expect(proxy.x1()).toEqual(0);
|
|
||||||
expect(proxy.y1()).toEqual(0);
|
|
||||||
expect(proxy.x2()).toEqual(2);
|
|
||||||
expect(proxy.y2()).toEqual(3);
|
|
||||||
proxy = new LineProxy(reversed);
|
|
||||||
expect(proxy.x1()).toEqual(2);
|
|
||||||
expect(proxy.y1()).toEqual(3);
|
|
||||||
expect(proxy.x2()).toEqual(0);
|
|
||||||
expect(proxy.y2()).toEqual(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("provides handles for both ends", function () {
|
|
||||||
expect(new LineProxy(diagonal).handles().length).toEqual(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -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/elements/ResizeHandle'],
|
|
||||||
function (ResizeHandle) {
|
|
||||||
|
|
||||||
var TEST_MIN_WIDTH = 4,
|
|
||||||
TEST_MIN_HEIGHT = 2,
|
|
||||||
TEST_GRID_SIZE = [34, 81];
|
|
||||||
|
|
||||||
describe("A fixed position drag handle", function () {
|
|
||||||
var testElement,
|
|
||||||
mockElementProxy,
|
|
||||||
handle;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
testElement = {
|
|
||||||
x: 3,
|
|
||||||
y: 42,
|
|
||||||
width: 30,
|
|
||||||
height: 36,
|
|
||||||
useGrid: true
|
|
||||||
};
|
|
||||||
mockElementProxy = jasmine.createSpyObj('elementProxy', [
|
|
||||||
'getGridSize',
|
|
||||||
'getMinWidth',
|
|
||||||
'getMinHeight'
|
|
||||||
]);
|
|
||||||
mockElementProxy.getGridSize.and.returnValue(TEST_GRID_SIZE);
|
|
||||||
mockElementProxy.getMinWidth.and.returnValue(TEST_MIN_WIDTH);
|
|
||||||
mockElementProxy.getMinHeight.and.returnValue(TEST_MIN_HEIGHT);
|
|
||||||
|
|
||||||
handle = new ResizeHandle(
|
|
||||||
mockElementProxy,
|
|
||||||
testElement
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("provides x/y grid coordinates for lower-right corner", function () {
|
|
||||||
expect(handle.x()).toEqual(33);
|
|
||||||
expect(handle.y()).toEqual(78);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("changes width of an element", function () {
|
|
||||||
handle.x(30);
|
|
||||||
// Should change width, not x
|
|
||||||
expect(testElement.x).toEqual(3);
|
|
||||||
expect(testElement.width).toEqual(27);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("changes height of an element", function () {
|
|
||||||
handle.y(60);
|
|
||||||
// Should change height, not y
|
|
||||||
expect(testElement.y).toEqual(42);
|
|
||||||
expect(testElement.height).toEqual(18);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("enforces minimum width/height", function () {
|
|
||||||
handle.x(testElement.x);
|
|
||||||
handle.y(testElement.y);
|
|
||||||
expect(testElement.x).toEqual(3);
|
|
||||||
expect(testElement.y).toEqual(42);
|
|
||||||
expect(testElement.width).toEqual(TEST_MIN_WIDTH);
|
|
||||||
expect(testElement.height).toEqual(TEST_MIN_HEIGHT);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("returns the correct grid size", function () {
|
|
||||||
expect(handle.getGridSize()).toEqual(TEST_GRID_SIZE);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,54 +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/elements/TelemetryProxy'],
|
|
||||||
function (TelemetryProxy) {
|
|
||||||
|
|
||||||
describe("A fixed position telemetry proxy", function () {
|
|
||||||
var testElement,
|
|
||||||
testElements,
|
|
||||||
proxy;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
testElement = {
|
|
||||||
x: 1,
|
|
||||||
y: 2,
|
|
||||||
z: 3,
|
|
||||||
width: 42,
|
|
||||||
height: 24,
|
|
||||||
id: "test-id"
|
|
||||||
};
|
|
||||||
testElements = [{}, {}, testElement, {}];
|
|
||||||
proxy = new TelemetryProxy(
|
|
||||||
testElement,
|
|
||||||
testElements.indexOf(testElement),
|
|
||||||
testElements
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("exposes the element's id", function () {
|
|
||||||
expect(proxy.id).toEqual('test-id');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,70 +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/elements/TextProxy'],
|
|
||||||
function (TextProxy) {
|
|
||||||
|
|
||||||
describe("A fixed position text proxy", function () {
|
|
||||||
var testElement,
|
|
||||||
testElements,
|
|
||||||
proxy;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
testElement = {
|
|
||||||
x: 1,
|
|
||||||
y: 2,
|
|
||||||
width: 42,
|
|
||||||
height: 24,
|
|
||||||
fill: "transparent",
|
|
||||||
size: "20px"
|
|
||||||
};
|
|
||||||
testElements = [{}, {}, testElement, {}];
|
|
||||||
proxy = new TextProxy(
|
|
||||||
testElement,
|
|
||||||
testElements.indexOf(testElement),
|
|
||||||
testElements
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("provides getter/setter for fill color", function () {
|
|
||||||
expect(proxy.fill()).toEqual('transparent');
|
|
||||||
expect(proxy.fill('#FFF')).toEqual('#FFF');
|
|
||||||
expect(proxy.fill()).toEqual('#FFF');
|
|
||||||
});
|
|
||||||
|
|
||||||
it("provides getter/setter for text size", function () {
|
|
||||||
expect(proxy.size()).toEqual('20px');
|
|
||||||
expect(proxy.size('12px')).toEqual('12px');
|
|
||||||
expect(proxy.size()).toEqual('12px');
|
|
||||||
});
|
|
||||||
|
|
||||||
it("defaults to 13px for unspecified text size", function () {
|
|
||||||
testElement = {x: 1, y: 2};
|
|
||||||
proxy = new TextProxy(testElement, 0, [testElement]);
|
|
||||||
|
|
||||||
expect(proxy.size()).toEqual('13px');
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,157 +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/elements/UnitAccessorMutator'],
|
|
||||||
function (UnitAccessorMutator) {
|
|
||||||
|
|
||||||
var GRID_SIZE = [13,17];
|
|
||||||
|
|
||||||
describe("An elementProxy.gridSize accessor-mutator", function () {
|
|
||||||
var mockElementProxy,
|
|
||||||
testElement,
|
|
||||||
mockLineProxy,
|
|
||||||
testLine,
|
|
||||||
uAM,
|
|
||||||
uAMLine;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
testElement = {
|
|
||||||
x: 2,
|
|
||||||
y: 3,
|
|
||||||
width: 4,
|
|
||||||
height: 5,
|
|
||||||
useGrid: true
|
|
||||||
};
|
|
||||||
|
|
||||||
mockElementProxy = {
|
|
||||||
element: testElement,
|
|
||||||
gridSize: GRID_SIZE,
|
|
||||||
getMinHeight: jasmine.createSpy('minHeight'),
|
|
||||||
getMinWidth: jasmine.createSpy('minWidth')
|
|
||||||
};
|
|
||||||
|
|
||||||
testLine = {
|
|
||||||
x: 7,
|
|
||||||
y: 8,
|
|
||||||
x2: 9,
|
|
||||||
y2: 10,
|
|
||||||
width: 11,
|
|
||||||
height: 12,
|
|
||||||
useGrid: true
|
|
||||||
};
|
|
||||||
|
|
||||||
mockLineProxy = {
|
|
||||||
element: testLine,
|
|
||||||
gridSize: GRID_SIZE,
|
|
||||||
getMinHeight: jasmine.createSpy('minHeight'),
|
|
||||||
getMinWidth: jasmine.createSpy('minWidth')
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uAM = new UnitAccessorMutator(mockElementProxy);
|
|
||||||
uAMLine = new UnitAccessorMutator(mockLineProxy);
|
|
||||||
|
|
||||||
mockElementProxy.getMinWidth.and.returnValue(1);
|
|
||||||
mockElementProxy.getMinHeight.and.returnValue(1);
|
|
||||||
|
|
||||||
mockLineProxy.getMinWidth.and.returnValue(1);
|
|
||||||
mockLineProxy.getMinHeight.and.returnValue(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows access to useGrid", function () {
|
|
||||||
expect(uAM()).toEqual(mockElementProxy.element.useGrid);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows mutation of useGrid", function () {
|
|
||||||
uAM(false);
|
|
||||||
expect(mockElementProxy.element.useGrid).toEqual(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("converts coordinates appropriately for a box", function () {
|
|
||||||
uAM(false);
|
|
||||||
expect(mockElementProxy.element.x).toEqual(26);
|
|
||||||
expect(mockElementProxy.element.y).toEqual(51);
|
|
||||||
expect(mockElementProxy.element.width).toEqual(52);
|
|
||||||
expect(mockElementProxy.element.height).toEqual(85);
|
|
||||||
uAM(true);
|
|
||||||
expect(mockElementProxy.element.x).toEqual(2);
|
|
||||||
expect(mockElementProxy.element.y).toEqual(3);
|
|
||||||
expect(mockElementProxy.element.width).toEqual(4);
|
|
||||||
expect(mockElementProxy.element.height).toEqual(5);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("converts coordinates appropriately for a line", function () {
|
|
||||||
uAMLine(false);
|
|
||||||
expect(mockLineProxy.element.x).toEqual(91);
|
|
||||||
expect(mockLineProxy.element.y).toEqual(136);
|
|
||||||
expect(mockLineProxy.element.x2).toEqual(117);
|
|
||||||
expect(mockLineProxy.element.y2).toEqual(170);
|
|
||||||
expect(mockLineProxy.element.width).toEqual(143);
|
|
||||||
expect(mockLineProxy.element.height).toEqual(204);
|
|
||||||
uAMLine(true);
|
|
||||||
expect(mockLineProxy.element.x).toEqual(7);
|
|
||||||
expect(mockLineProxy.element.y).toEqual(8);
|
|
||||||
expect(mockLineProxy.element.x2).toEqual(9);
|
|
||||||
expect(mockLineProxy.element.y2).toEqual(10);
|
|
||||||
expect(mockLineProxy.element.width).toEqual(11);
|
|
||||||
expect(mockLineProxy.element.height).toEqual(12);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("doesn't covert coordinates unecessarily", function () {
|
|
||||||
uAM(false);
|
|
||||||
expect(mockElementProxy.element.x).toEqual(26);
|
|
||||||
expect(mockElementProxy.element.y).toEqual(51);
|
|
||||||
expect(mockElementProxy.element.width).toEqual(52);
|
|
||||||
expect(mockElementProxy.element.height).toEqual(85);
|
|
||||||
uAM(false);
|
|
||||||
expect(mockElementProxy.element.x).toEqual(26);
|
|
||||||
expect(mockElementProxy.element.y).toEqual(51);
|
|
||||||
expect(mockElementProxy.element.width).toEqual(52);
|
|
||||||
expect(mockElementProxy.element.height).toEqual(85);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("snaps coordinates onto the grid", function () {
|
|
||||||
uAM(false);
|
|
||||||
mockElementProxy.element.x += 11;
|
|
||||||
mockElementProxy.element.y -= 27;
|
|
||||||
mockElementProxy.element.width -= 14;
|
|
||||||
mockElementProxy.element.height += 4;
|
|
||||||
uAM(true);
|
|
||||||
expect(mockElementProxy.element.x).toEqual(3);
|
|
||||||
expect(mockElementProxy.element.y).toEqual(1);
|
|
||||||
expect(mockElementProxy.element.width).toEqual(3);
|
|
||||||
expect(mockElementProxy.element.height).toEqual(5);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("enforces a minimum height and width", function () {
|
|
||||||
uAM(false);
|
|
||||||
mockElementProxy.element.width = 4;
|
|
||||||
mockElementProxy.element.height = 4;
|
|
||||||
uAM(true);
|
|
||||||
expect(mockElementProxy.element.width).toEqual(1);
|
|
||||||
expect(mockElementProxy.element.height).toEqual(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -30,6 +30,7 @@ define([
|
|||||||
"./src/controllers/CompositeController",
|
"./src/controllers/CompositeController",
|
||||||
"./src/controllers/ColorController",
|
"./src/controllers/ColorController",
|
||||||
"./src/controllers/DialogButtonController",
|
"./src/controllers/DialogButtonController",
|
||||||
|
"./src/controllers/SnapshotPreviewController",
|
||||||
"./res/templates/controls/autocomplete.html",
|
"./res/templates/controls/autocomplete.html",
|
||||||
"./res/templates/controls/checkbox.html",
|
"./res/templates/controls/checkbox.html",
|
||||||
"./res/templates/controls/datetime.html",
|
"./res/templates/controls/datetime.html",
|
||||||
@ -44,6 +45,7 @@ define([
|
|||||||
"./res/templates/controls/dialog.html",
|
"./res/templates/controls/dialog.html",
|
||||||
"./res/templates/controls/radio.html",
|
"./res/templates/controls/radio.html",
|
||||||
"./res/templates/controls/file-input.html",
|
"./res/templates/controls/file-input.html",
|
||||||
|
"./res/templates/controls/snap-view.html",
|
||||||
'legacyRegistry'
|
'legacyRegistry'
|
||||||
], function (
|
], function (
|
||||||
MCTForm,
|
MCTForm,
|
||||||
@ -55,6 +57,7 @@ define([
|
|||||||
CompositeController,
|
CompositeController,
|
||||||
ColorController,
|
ColorController,
|
||||||
DialogButtonController,
|
DialogButtonController,
|
||||||
|
SnapshotPreviewController,
|
||||||
autocompleteTemplate,
|
autocompleteTemplate,
|
||||||
checkboxTemplate,
|
checkboxTemplate,
|
||||||
datetimeTemplate,
|
datetimeTemplate,
|
||||||
@ -69,6 +72,7 @@ define([
|
|||||||
dialogTemplate,
|
dialogTemplate,
|
||||||
radioTemplate,
|
radioTemplate,
|
||||||
fileInputTemplate,
|
fileInputTemplate,
|
||||||
|
snapViewTemplate,
|
||||||
legacyRegistry
|
legacyRegistry
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@ -153,6 +157,10 @@ define([
|
|||||||
{
|
{
|
||||||
"key": "file-input",
|
"key": "file-input",
|
||||||
"template": fileInputTemplate
|
"template": fileInputTemplate
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "snap-view",
|
||||||
|
"template": snapViewTemplate
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"controllers": [
|
"controllers": [
|
||||||
@ -186,6 +194,14 @@ define([
|
|||||||
"$scope",
|
"$scope",
|
||||||
"dialogService"
|
"dialogService"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SnapshotPreviewController",
|
||||||
|
"implementation": SnapshotPreviewController,
|
||||||
|
"depends": [
|
||||||
|
"$scope",
|
||||||
|
"openmct"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"components": [
|
"components": [
|
||||||
|
@ -19,21 +19,18 @@
|
|||||||
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.
|
||||||
-->
|
-->
|
||||||
<div
|
<span ng-controller="SnapshotPreviewController"
|
||||||
class="l-fixed-position-text l-telemetry"
|
class='form-control shell'>
|
||||||
ng-style="{ background: ngModel.fill(), 'border-color': ngModel.stroke(), color: ngModel.color(), 'font-size': ngModel.size() }"
|
<span class='field control {{structure.cssClass}}'>
|
||||||
>
|
<image
|
||||||
<span
|
class="c-ne__embed__snap-thumb"
|
||||||
class="l-elem l-value l-obj-val-format"
|
src="{{imageUrl || structure.src}}"
|
||||||
data-value="{{ngModel.value}}"
|
ng-click="previewImage(imageUrl || structure.src)"
|
||||||
ng-class="ngModel.cssClass"
|
name="mctControl">
|
||||||
>
|
</image>
|
||||||
{{ngModel.value}}
|
<br>
|
||||||
|
<a title="Annotate" class="s-button icon-pencil" ng-click="annotateImage(ngModel, field, imageUrl || structure.src)">
|
||||||
|
<span class="title-label">Annotate</span>
|
||||||
|
</a>
|
||||||
</span>
|
</span>
|
||||||
<span
|
</span>
|
||||||
class="l-elem l-title"
|
|
||||||
ng-show="ngModel.element.titled"
|
|
||||||
>
|
|
||||||
{{ngModel.name}}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
130
platform/forms/src/controllers/SnapshotPreviewController.js
Normal file
130
platform/forms/src/controllers/SnapshotPreviewController.js
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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(
|
||||||
|
[
|
||||||
|
'painterro'
|
||||||
|
],
|
||||||
|
function (Painterro) {
|
||||||
|
|
||||||
|
function SnapshotPreviewController($scope, openmct) {
|
||||||
|
|
||||||
|
$scope.previewImage = function (imageUrl) {
|
||||||
|
let image = document.createElement('img');
|
||||||
|
image.src = imageUrl;
|
||||||
|
|
||||||
|
let previewImageOverlay = openmct.overlays.overlay(
|
||||||
|
{
|
||||||
|
element: image,
|
||||||
|
size: 'large',
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
label: 'Done',
|
||||||
|
callback: function () {
|
||||||
|
previewImageOverlay.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.annotateImage = function (ngModel, field, imageUrl) {
|
||||||
|
$scope.imageUrl = imageUrl;
|
||||||
|
|
||||||
|
let div = document.createElement('div'),
|
||||||
|
painterroInstance = {},
|
||||||
|
save = false;
|
||||||
|
|
||||||
|
div.id = 'snap-annotation';
|
||||||
|
|
||||||
|
let annotateImageOverlay = openmct.overlays.overlay(
|
||||||
|
{
|
||||||
|
element: div,
|
||||||
|
size: 'large',
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
label: 'Cancel',
|
||||||
|
callback: function () {
|
||||||
|
save = false;
|
||||||
|
painterroInstance.save();
|
||||||
|
annotateImageOverlay.dismiss();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Save',
|
||||||
|
callback: function () {
|
||||||
|
save = true;
|
||||||
|
painterroInstance.save();
|
||||||
|
annotateImageOverlay.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
painterroInstance = Painterro({
|
||||||
|
id: 'snap-annotation',
|
||||||
|
activeColor: '#ff0000',
|
||||||
|
activeColorAlpha: 1.0,
|
||||||
|
activeFillColor: '#fff',
|
||||||
|
activeFillColorAlpha: 0.0,
|
||||||
|
backgroundFillColor: '#000',
|
||||||
|
backgroundFillColorAlpha: 0.0,
|
||||||
|
defaultFontSize: 16,
|
||||||
|
defaultLineWidth: 2,
|
||||||
|
defaultTool: 'ellipse',
|
||||||
|
hiddenTools: ['save', 'open', 'close', 'eraser', 'pixelize', 'rotate', 'settings', 'resize'],
|
||||||
|
translation: {
|
||||||
|
name: 'en',
|
||||||
|
strings: {
|
||||||
|
lineColor: 'Line',
|
||||||
|
fillColor: 'Fill',
|
||||||
|
lineWidth: 'Size',
|
||||||
|
textColor: 'Color',
|
||||||
|
fontSize: 'Size',
|
||||||
|
fontStyle: 'Style'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
saveHandler: function (image, done) {
|
||||||
|
if (save) {
|
||||||
|
let url = image.asBlob(),
|
||||||
|
reader = new window.FileReader();
|
||||||
|
|
||||||
|
reader.readAsDataURL(url);
|
||||||
|
reader.onloadend = function () {
|
||||||
|
$scope.imageUrl = reader.result;
|
||||||
|
ngModel[field] = reader.result;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
ngModel.field = imageUrl;
|
||||||
|
console.warn('You cancelled the annotation!!!');
|
||||||
|
}
|
||||||
|
done(true);
|
||||||
|
}
|
||||||
|
}).show(imageUrl);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return SnapshotPreviewController;
|
||||||
|
}
|
||||||
|
);
|
@ -25,12 +25,10 @@ define([
|
|||||||
"./src/MCTRepresentation",
|
"./src/MCTRepresentation",
|
||||||
"./src/gestures/DragGesture",
|
"./src/gestures/DragGesture",
|
||||||
"./src/gestures/DropGesture",
|
"./src/gestures/DropGesture",
|
||||||
"./src/gestures/ContextMenuGesture",
|
|
||||||
"./src/gestures/GestureProvider",
|
"./src/gestures/GestureProvider",
|
||||||
"./src/gestures/GestureRepresenter",
|
"./src/gestures/GestureRepresenter",
|
||||||
"./src/services/DndService",
|
"./src/services/DndService",
|
||||||
"./src/TemplateLinker",
|
"./src/TemplateLinker",
|
||||||
"./src/actions/ContextMenuAction",
|
|
||||||
"./src/TemplatePrefetcher",
|
"./src/TemplatePrefetcher",
|
||||||
'legacyRegistry'
|
'legacyRegistry'
|
||||||
], function (
|
], function (
|
||||||
@ -38,12 +36,10 @@ define([
|
|||||||
MCTRepresentation,
|
MCTRepresentation,
|
||||||
DragGesture,
|
DragGesture,
|
||||||
DropGesture,
|
DropGesture,
|
||||||
ContextMenuGesture,
|
|
||||||
GestureProvider,
|
GestureProvider,
|
||||||
GestureRepresenter,
|
GestureRepresenter,
|
||||||
DndService,
|
DndService,
|
||||||
TemplateLinker,
|
TemplateLinker,
|
||||||
ContextMenuAction,
|
|
||||||
TemplatePrefetcher,
|
TemplatePrefetcher,
|
||||||
legacyRegistry
|
legacyRegistry
|
||||||
) {
|
) {
|
||||||
@ -88,14 +84,6 @@ define([
|
|||||||
"dndService",
|
"dndService",
|
||||||
"$q"
|
"$q"
|
||||||
]
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "menu",
|
|
||||||
"implementation": ContextMenuGesture,
|
|
||||||
"depends": [
|
|
||||||
"$timeout",
|
|
||||||
"agentService"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"components": [
|
"components": [
|
||||||
@ -136,19 +124,6 @@ define([
|
|||||||
"comment": "For internal use by mct-include and mct-representation."
|
"comment": "For internal use by mct-include and mct-representation."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"actions": [
|
|
||||||
{
|
|
||||||
"key": "menu",
|
|
||||||
"implementation": ContextMenuAction,
|
|
||||||
"depends": [
|
|
||||||
"$compile",
|
|
||||||
"$document",
|
|
||||||
"$rootScope",
|
|
||||||
"popupService",
|
|
||||||
"agentService"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"runs": [
|
"runs": [
|
||||||
{
|
{
|
||||||
"priority": "mandatory",
|
"priority": "mandatory",
|
||||||
|
@ -1,138 +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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Module defining ContextMenuAction. Created by shale on 06/30/2015.
|
|
||||||
*/
|
|
||||||
define(
|
|
||||||
["../gestures/GestureConstants"],
|
|
||||||
function (GestureConstants) {
|
|
||||||
|
|
||||||
var MENU_TEMPLATE = "<mct-representation key=\"'context-menu'\" " +
|
|
||||||
"mct-object=\"domainObject\" " +
|
|
||||||
"ng-class=\"menuClass\" " +
|
|
||||||
"ng-style=\"menuStyle\">" +
|
|
||||||
"</mct-representation>",
|
|
||||||
dismissExistingMenu;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Launches a custom context menu for the domain object it contains.
|
|
||||||
*
|
|
||||||
* @memberof platform/representation
|
|
||||||
* @constructor
|
|
||||||
* @param $compile Angular's $compile service
|
|
||||||
* @param $document the current document
|
|
||||||
* @param $rootScope Angular's root scope
|
|
||||||
* @param {platform/commonUI/general.PopupService} popupService
|
|
||||||
* @param actionContext the context in which the action
|
|
||||||
* should be performed
|
|
||||||
* @implements {Action}
|
|
||||||
*/
|
|
||||||
function ContextMenuAction(
|
|
||||||
$compile,
|
|
||||||
$document,
|
|
||||||
$rootScope,
|
|
||||||
popupService,
|
|
||||||
agentService,
|
|
||||||
actionContext
|
|
||||||
) {
|
|
||||||
this.$compile = $compile;
|
|
||||||
this.agentService = agentService;
|
|
||||||
this.actionContext = actionContext;
|
|
||||||
this.popupService = popupService;
|
|
||||||
this.getDocument = function () {
|
|
||||||
return $document;
|
|
||||||
};
|
|
||||||
this.getRootScope = function () {
|
|
||||||
return $rootScope;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
ContextMenuAction.prototype.perform = function () {
|
|
||||||
var $compile = this.$compile,
|
|
||||||
$document = this.getDocument(),
|
|
||||||
$rootScope = this.getRootScope(),
|
|
||||||
actionContext = this.actionContext,
|
|
||||||
eventCoords = [
|
|
||||||
actionContext.event.pageX,
|
|
||||||
actionContext.event.pageY
|
|
||||||
],
|
|
||||||
menuDim = GestureConstants.MCT_MENU_DIMENSIONS,
|
|
||||||
body = $document.find('body'),
|
|
||||||
scope = $rootScope.$new(),
|
|
||||||
initiatingEvent = this.agentService.isMobile() ?
|
|
||||||
'touchstart' : 'mousedown',
|
|
||||||
menu,
|
|
||||||
popup;
|
|
||||||
|
|
||||||
// Remove the context menu
|
|
||||||
function dismiss() {
|
|
||||||
if (popup) {
|
|
||||||
popup.dismiss();
|
|
||||||
popup = undefined;
|
|
||||||
}
|
|
||||||
scope.$destroy();
|
|
||||||
body.off("mousedown", dismiss);
|
|
||||||
dismissExistingMenu = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dismiss any menu which was already showing
|
|
||||||
if (dismissExistingMenu) {
|
|
||||||
dismissExistingMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ...and record the presence of this menu.
|
|
||||||
dismissExistingMenu = dismiss;
|
|
||||||
|
|
||||||
// Set up the scope, including menu positioning
|
|
||||||
scope.domainObject = actionContext.domainObject;
|
|
||||||
scope.menuClass = { "context-menu-holder": true };
|
|
||||||
// Create the context menu
|
|
||||||
menu = $compile(MENU_TEMPLATE)(scope);
|
|
||||||
|
|
||||||
popup = this.popupService.display(menu, eventCoords, {
|
|
||||||
marginX: -menuDim[0],
|
|
||||||
marginY: -menuDim[1]
|
|
||||||
});
|
|
||||||
|
|
||||||
scope.menuClass['go-left'] = popup.goesLeft();
|
|
||||||
scope.menuClass['go-up'] = popup.goesUp();
|
|
||||||
|
|
||||||
// Stop propagation so that clicks or touches on the menu do not close the menu
|
|
||||||
menu.on(initiatingEvent, function (event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Dismiss the menu when body is clicked/touched elsewhere
|
|
||||||
// ('mousedown' because 'click' breaks left-click context menus)
|
|
||||||
// ('touchstart' because 'touch' breaks context menus up)
|
|
||||||
body.on(initiatingEvent, dismiss);
|
|
||||||
// NOTE: Apply to mobile?
|
|
||||||
menu.on('click', dismiss);
|
|
||||||
|
|
||||||
// Don't launch browser's context menu
|
|
||||||
actionContext.event.preventDefault();
|
|
||||||
};
|
|
||||||
|
|
||||||
return ContextMenuAction;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,100 +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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Module defining ContextMenuGesture.
|
|
||||||
* Created by vwoeltje on 11/17/14. Modified by shale on 06/30/2015.
|
|
||||||
*/
|
|
||||||
define(
|
|
||||||
function () {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add listeners to a representation such that it calls the
|
|
||||||
* context menu action for the domain object it contains.
|
|
||||||
*
|
|
||||||
* @memberof platform/representation
|
|
||||||
* @constructor
|
|
||||||
* @param element the jqLite-wrapped element which should exhibit
|
|
||||||
* the context menu
|
|
||||||
* @param {DomainObject} domainObject the object on which actions
|
|
||||||
* in the context menu will be performed
|
|
||||||
* @implements {Gesture}
|
|
||||||
*/
|
|
||||||
function ContextMenuGesture($timeout, agentService, element, domainObject) {
|
|
||||||
var isPressing,
|
|
||||||
isDragging,
|
|
||||||
longTouchTime = 500;
|
|
||||||
|
|
||||||
function showMenu(event) {
|
|
||||||
domainObject.getCapability('action').perform({
|
|
||||||
key: 'menu',
|
|
||||||
domainObject: domainObject,
|
|
||||||
event: event
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// When context menu event occurs, show object actions instead
|
|
||||||
if (!agentService.isMobile()) {
|
|
||||||
|
|
||||||
// When context menu event occurs, show object actions instead
|
|
||||||
element.on('contextmenu', showMenu);
|
|
||||||
} else if (agentService.isMobile()) {
|
|
||||||
|
|
||||||
// If on mobile device, then start timeout for the single touch event
|
|
||||||
// during the timeout 'isPressing' is true.
|
|
||||||
element.on('touchstart', function (event) {
|
|
||||||
if (event.touches.length < 2) {
|
|
||||||
isPressing = true;
|
|
||||||
|
|
||||||
// After the timeout, if 'isPressing' is
|
|
||||||
// true, display context menu for object
|
|
||||||
$timeout(function () {
|
|
||||||
if (isPressing && !isDragging) {
|
|
||||||
showMenu(event);
|
|
||||||
}
|
|
||||||
}, longTouchTime);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// If on Mobile Device, and user scrolls/drags set flag to true
|
|
||||||
element.on('touchmove', function () {
|
|
||||||
isDragging = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Whenever the touch event ends, 'isPressing' & 'isDragging' is false.
|
|
||||||
element.on('touchend', function () {
|
|
||||||
isPressing = false;
|
|
||||||
isDragging = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.showMenuCallback = showMenu;
|
|
||||||
this.element = element;
|
|
||||||
}
|
|
||||||
|
|
||||||
ContextMenuGesture.prototype.destroy = function () {
|
|
||||||
this.element.off('contextmenu', this.showMenu);
|
|
||||||
};
|
|
||||||
|
|
||||||
return ContextMenuGesture;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,202 +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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Module defining ContextMenuActionSpec. Created by shale on 07/02/2015.
|
|
||||||
*/
|
|
||||||
define(
|
|
||||||
["../../src/actions/ContextMenuAction"],
|
|
||||||
function (ContextMenuAction) {
|
|
||||||
|
|
||||||
var JQLITE_FUNCTIONS = ["on", "off", "find", "append", "remove"],
|
|
||||||
DOMAIN_OBJECT_METHODS = ["getId", "getModel", "getCapability", "hasCapability", "useCapability"];
|
|
||||||
|
|
||||||
|
|
||||||
describe("The 'context menu' action", function () {
|
|
||||||
var mockCompile,
|
|
||||||
mockCompiledTemplate,
|
|
||||||
mockMenu,
|
|
||||||
mockDocument,
|
|
||||||
mockBody,
|
|
||||||
mockPopupService,
|
|
||||||
mockRootScope,
|
|
||||||
mockAgentService,
|
|
||||||
mockScope,
|
|
||||||
mockDomainObject,
|
|
||||||
mockEvent,
|
|
||||||
mockPopup,
|
|
||||||
mockActionContext,
|
|
||||||
action;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
mockCompile = jasmine.createSpy("$compile");
|
|
||||||
mockCompiledTemplate = jasmine.createSpy("template");
|
|
||||||
mockMenu = jasmine.createSpyObj("menu", JQLITE_FUNCTIONS);
|
|
||||||
mockDocument = jasmine.createSpyObj("$document", JQLITE_FUNCTIONS);
|
|
||||||
mockBody = jasmine.createSpyObj("body", JQLITE_FUNCTIONS);
|
|
||||||
mockPopupService =
|
|
||||||
jasmine.createSpyObj("popupService", ["display"]);
|
|
||||||
mockPopup = jasmine.createSpyObj("popup", [
|
|
||||||
"dismiss",
|
|
||||||
"goesLeft",
|
|
||||||
"goesUp"
|
|
||||||
]);
|
|
||||||
mockRootScope = jasmine.createSpyObj("$rootScope", ["$new"]);
|
|
||||||
mockAgentService = jasmine.createSpyObj("agentService", ["isMobile"]);
|
|
||||||
mockScope = jasmine.createSpyObj("scope", ["$destroy"]);
|
|
||||||
mockDomainObject = jasmine.createSpyObj("domainObject", DOMAIN_OBJECT_METHODS);
|
|
||||||
mockEvent = jasmine.createSpyObj("event", ["preventDefault", "stopPropagation"]);
|
|
||||||
mockEvent.pageX = 123;
|
|
||||||
mockEvent.pageY = 321;
|
|
||||||
|
|
||||||
mockCompile.and.returnValue(mockCompiledTemplate);
|
|
||||||
mockCompiledTemplate.and.returnValue(mockMenu);
|
|
||||||
mockDocument.find.and.returnValue(mockBody);
|
|
||||||
mockRootScope.$new.and.returnValue(mockScope);
|
|
||||||
mockPopupService.display.and.returnValue(mockPopup);
|
|
||||||
|
|
||||||
mockActionContext = {key: 'menu', domainObject: mockDomainObject, event: mockEvent};
|
|
||||||
|
|
||||||
action = new ContextMenuAction(
|
|
||||||
mockCompile,
|
|
||||||
mockDocument,
|
|
||||||
mockRootScope,
|
|
||||||
mockPopupService,
|
|
||||||
mockAgentService,
|
|
||||||
mockActionContext
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("displays a popup when performed", function () {
|
|
||||||
action.perform();
|
|
||||||
expect(mockPopupService.display).toHaveBeenCalledWith(
|
|
||||||
mockMenu,
|
|
||||||
[mockEvent.pageX, mockEvent.pageY],
|
|
||||||
jasmine.any(Object)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("prevents the default context menu behavior", function () {
|
|
||||||
action.perform();
|
|
||||||
expect(mockEvent.preventDefault).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("adds classes to menus based on position", function () {
|
|
||||||
var booleans = [false, true];
|
|
||||||
|
|
||||||
booleans.forEach(function (goLeft) {
|
|
||||||
booleans.forEach(function (goUp) {
|
|
||||||
mockPopup.goesLeft.and.returnValue(goLeft);
|
|
||||||
mockPopup.goesUp.and.returnValue(goUp);
|
|
||||||
action.perform();
|
|
||||||
expect(!!mockScope.menuClass['go-up'])
|
|
||||||
.toEqual(goUp);
|
|
||||||
expect(!!mockScope.menuClass['go-left'])
|
|
||||||
.toEqual(goLeft);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
it("removes a menu when body is clicked", function () {
|
|
||||||
// Show the menu
|
|
||||||
action.perform();
|
|
||||||
|
|
||||||
// Verify precondition
|
|
||||||
expect(mockBody.remove).not.toHaveBeenCalled();
|
|
||||||
|
|
||||||
// Find and fire body's mousedown listener
|
|
||||||
mockBody.on.calls.all().forEach(function (call) {
|
|
||||||
if (call.args[0] === 'mousedown') {
|
|
||||||
call.args[1]();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Menu should have been removed
|
|
||||||
expect(mockPopup.dismiss).toHaveBeenCalled();
|
|
||||||
|
|
||||||
// Listener should have been detached from body
|
|
||||||
expect(mockBody.off).toHaveBeenCalledWith(
|
|
||||||
'mousedown',
|
|
||||||
jasmine.any(Function)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("removes a menu when it is clicked", function () {
|
|
||||||
// Show the menu
|
|
||||||
action.perform();
|
|
||||||
|
|
||||||
// Verify precondition
|
|
||||||
expect(mockMenu.remove).not.toHaveBeenCalled();
|
|
||||||
|
|
||||||
// Find and fire menu's click listener
|
|
||||||
mockMenu.on.calls.all().forEach(function (call) {
|
|
||||||
if (call.args[0] === 'click') {
|
|
||||||
call.args[1]();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Menu should have been removed
|
|
||||||
expect(mockPopup.dismiss).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("keeps a menu when menu is clicked", function () {
|
|
||||||
// Show the menu
|
|
||||||
action.perform();
|
|
||||||
// Find and fire body's mousedown listener
|
|
||||||
mockMenu.on.calls.all().forEach(function (call) {
|
|
||||||
if (call.args[0] === 'mousedown') {
|
|
||||||
call.args[1](mockEvent);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Menu should have been removed
|
|
||||||
expect(mockPopup.dismiss).not.toHaveBeenCalled();
|
|
||||||
|
|
||||||
// Listener should have been detached from body
|
|
||||||
expect(mockBody.off).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("keeps a menu when menu is clicked on mobile", function () {
|
|
||||||
mockAgentService.isMobile.and.returnValue(true);
|
|
||||||
action = new ContextMenuAction(
|
|
||||||
mockCompile,
|
|
||||||
mockDocument,
|
|
||||||
mockRootScope,
|
|
||||||
mockPopupService,
|
|
||||||
mockAgentService,
|
|
||||||
mockActionContext
|
|
||||||
);
|
|
||||||
action.perform();
|
|
||||||
|
|
||||||
mockMenu.on.calls.all().forEach(function (call) {
|
|
||||||
if (call.args[0] === 'touchstart') {
|
|
||||||
call.args[1](mockEvent);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(mockPopup.dismiss).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,119 +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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Module defining ContextMenuGestureSpec. Created by vwoeltje on 11/22/14.
|
|
||||||
*/
|
|
||||||
define(
|
|
||||||
["../../src/gestures/ContextMenuGesture"],
|
|
||||||
function (ContextMenuGesture) {
|
|
||||||
|
|
||||||
var JQLITE_FUNCTIONS = ["on", "off", "find", "append", "remove"],
|
|
||||||
DOMAIN_OBJECT_METHODS = ["getId", "getModel", "getCapability", "hasCapability", "useCapability"];
|
|
||||||
|
|
||||||
|
|
||||||
describe("The 'context menu' gesture", function () {
|
|
||||||
var mockTimeout,
|
|
||||||
mockElement,
|
|
||||||
mockAgentService,
|
|
||||||
mockDomainObject,
|
|
||||||
mockTouchEvent,
|
|
||||||
mockContextMenuAction,
|
|
||||||
mockTouch,
|
|
||||||
gesture,
|
|
||||||
fireGesture,
|
|
||||||
fireTouchStartGesture,
|
|
||||||
fireTouchEndGesture;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
mockTimeout = jasmine.createSpy("$timeout");
|
|
||||||
mockElement = jasmine.createSpyObj("element", JQLITE_FUNCTIONS);
|
|
||||||
mockAgentService = jasmine.createSpyObj("agentService", ["isMobile"]);
|
|
||||||
mockDomainObject = jasmine.createSpyObj("domainObject", DOMAIN_OBJECT_METHODS);
|
|
||||||
mockContextMenuAction = jasmine.createSpyObj(
|
|
||||||
"action",
|
|
||||||
["perform", "getActions"]
|
|
||||||
);
|
|
||||||
|
|
||||||
mockDomainObject.getCapability.and.returnValue(mockContextMenuAction);
|
|
||||||
mockContextMenuAction.perform.and.returnValue(jasmine.any(Function));
|
|
||||||
mockAgentService.isMobile.and.returnValue(false);
|
|
||||||
|
|
||||||
|
|
||||||
gesture = new ContextMenuGesture(mockTimeout, mockAgentService, mockElement, mockDomainObject);
|
|
||||||
|
|
||||||
// Capture the contextmenu callback
|
|
||||||
fireGesture = mockElement.on.calls.mostRecent().args[1];
|
|
||||||
});
|
|
||||||
|
|
||||||
it("attaches a callback for context menu events", function () {
|
|
||||||
// Fire a click and expect it to happen
|
|
||||||
fireGesture();
|
|
||||||
expect(mockElement.on).toHaveBeenCalledWith(
|
|
||||||
"contextmenu",
|
|
||||||
jasmine.any(Function)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("detaches a callback for context menu events when destroyed", function () {
|
|
||||||
expect(mockElement.off).not.toHaveBeenCalled();
|
|
||||||
|
|
||||||
gesture.destroy();
|
|
||||||
|
|
||||||
expect(mockElement.off).toHaveBeenCalledWith(
|
|
||||||
"contextmenu",
|
|
||||||
//mockElement.on.calls.mostRecent().args[1]
|
|
||||||
mockDomainObject.calls
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("attaches a callback for context menu events on mobile", function () {
|
|
||||||
// Mock touch event and set to mobile device
|
|
||||||
mockTouchEvent = jasmine.createSpyObj("event", ["preventDefault", "touches"]);
|
|
||||||
mockTouch = jasmine.createSpyObj("touch", ["length"]);
|
|
||||||
mockTouch.length = 1;
|
|
||||||
mockTouchEvent.touches.and.returnValue(mockTouch);
|
|
||||||
mockAgentService.isMobile.and.returnValue(true);
|
|
||||||
|
|
||||||
// Then create new (mobile) gesture
|
|
||||||
gesture = new ContextMenuGesture(mockTimeout, mockAgentService, mockElement, mockDomainObject);
|
|
||||||
|
|
||||||
// Set calls for the touchstart and touchend gestures
|
|
||||||
fireTouchStartGesture = mockElement.on.calls.all()[1].args[1];
|
|
||||||
fireTouchEndGesture = mockElement.on.calls.mostRecent().args[1];
|
|
||||||
|
|
||||||
// Fire touchstart and expect touch start to begin
|
|
||||||
fireTouchStartGesture(mockTouchEvent);
|
|
||||||
expect(mockElement.on).toHaveBeenCalledWith(
|
|
||||||
"touchstart",
|
|
||||||
jasmine.any(Function)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Expect timeout to begin and then fireTouchEnd
|
|
||||||
expect(mockTimeout).toHaveBeenCalled();
|
|
||||||
mockTimeout.calls.mostRecent().args[0]();
|
|
||||||
fireTouchEndGesture(mockTouchEvent);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -40,9 +40,10 @@ define([
|
|||||||
'../platform/framework/src/Main',
|
'../platform/framework/src/Main',
|
||||||
'./styles-new/core.scss',
|
'./styles-new/core.scss',
|
||||||
'./styles-new/notebook.scss',
|
'./styles-new/notebook.scss',
|
||||||
'./ui/components/layout/Layout.vue',
|
'./ui/layout/Layout.vue',
|
||||||
'../platform/core/src/objects/DomainObjectImpl',
|
'../platform/core/src/objects/DomainObjectImpl',
|
||||||
'../platform/core/src/capabilities/ContextualDomainObject',
|
'../platform/core/src/capabilities/ContextualDomainObject',
|
||||||
|
'./ui/preview/plugin',
|
||||||
'vue'
|
'vue'
|
||||||
], function (
|
], function (
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
@ -67,6 +68,7 @@ define([
|
|||||||
Layout,
|
Layout,
|
||||||
DomainObjectImpl,
|
DomainObjectImpl,
|
||||||
ContextualDomainObject,
|
ContextualDomainObject,
|
||||||
|
PreviewPlugin,
|
||||||
Vue
|
Vue
|
||||||
) {
|
) {
|
||||||
/**
|
/**
|
||||||
@ -230,6 +232,7 @@ define([
|
|||||||
this.install(this.plugins.Plot());
|
this.install(this.plugins.Plot());
|
||||||
this.install(this.plugins.TelemetryTable());
|
this.install(this.plugins.TelemetryTable());
|
||||||
this.install(this.plugins.DisplayLayout());
|
this.install(this.plugins.DisplayLayout());
|
||||||
|
this.install(PreviewPlugin.default());
|
||||||
|
|
||||||
if (typeof BUILD_CONSTANTS !== 'undefined') {
|
if (typeof BUILD_CONSTANTS !== 'undefined') {
|
||||||
this.install(buildInfoPlugin(BUILD_CONSTANTS));
|
this.install(buildInfoPlugin(BUILD_CONSTANTS));
|
||||||
|
@ -24,7 +24,7 @@ import LegacyContextMenuAction from './LegacyContextMenuAction';
|
|||||||
|
|
||||||
export default function LegacyActionAdapter(openmct, legacyActions) {
|
export default function LegacyActionAdapter(openmct, legacyActions) {
|
||||||
function contextualCategoryOnly(action) {
|
function contextualCategoryOnly(action) {
|
||||||
if (action.category === 'contextual') {
|
if (action.category === 'contextual' || (Array.isArray(action.category) && action.category.includes('contextual'))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
console.warn(`DEPRECATION WARNING: Action ${action.definition.key} in bundle ${action.bundle.path} is non-contextual and should be migrated.`);
|
console.warn(`DEPRECATION WARNING: Action ${action.definition.key} in bundle ${action.bundle.path} is non-contextual and should be migrated.`);
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import { timingSafeEqual } from "crypto";
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
@ -21,6 +19,9 @@ import { timingSafeEqual } from "crypto";
|
|||||||
* 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.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
import _ from 'lodash';
|
||||||
|
const INSIDE_EDIT_PATH_BLACKLIST = ["copy", "follow", "link", "locate", "move", "link"];
|
||||||
|
const OUTSIDE_EDIT_PATH_BLACKLIST = ["copy", "follow", "properties", "move", "link", "remove", "locate"];
|
||||||
|
|
||||||
export default class LegacyContextMenuAction {
|
export default class LegacyContextMenuAction {
|
||||||
constructor(openmct, LegacyAction) {
|
constructor(openmct, LegacyAction) {
|
||||||
@ -31,13 +32,6 @@ export default class LegacyContextMenuAction {
|
|||||||
this.LegacyAction = LegacyAction;
|
this.LegacyAction = LegacyAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
appliesTo(objectPath) {
|
|
||||||
let legacyObject = this.openmct.legacyObject(objectPath);
|
|
||||||
return this.LegacyAction.appliesTo({
|
|
||||||
domainObject: legacyObject
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
invoke(objectPath) {
|
invoke(objectPath) {
|
||||||
let context = {
|
let context = {
|
||||||
category: 'contextual',
|
category: 'contextual',
|
||||||
@ -54,4 +48,36 @@ export default class LegacyContextMenuAction {
|
|||||||
}
|
}
|
||||||
legacyAction.perform();
|
legacyAction.perform();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
appliesTo(objectPath) {
|
||||||
|
let legacyObject = this.openmct.legacyObject(objectPath);
|
||||||
|
|
||||||
|
return (this.LegacyAction.appliesTo === undefined ||
|
||||||
|
this.LegacyAction.appliesTo({domainObject: legacyObject})) &&
|
||||||
|
!this.isBlacklisted(objectPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
isBlacklisted(objectPath) {
|
||||||
|
let navigatedObject = this.openmct.router.path[0];
|
||||||
|
let isEditing = this.openmct.editor.isEditing();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the object being edited, or a child of the object being edited?
|
||||||
|
*/
|
||||||
|
function isInsideEditPath() {
|
||||||
|
return objectPath.some((object) => _.eq(object.identifier, navigatedObject.identifier));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEditing) {
|
||||||
|
if (isInsideEditPath()) {
|
||||||
|
return INSIDE_EDIT_PATH_BLACKLIST.some(actionKey => this.LegacyAction.key === actionKey);
|
||||||
|
} else {
|
||||||
|
return OUTSIDE_EDIT_PATH_BLACKLIST.some(actionKey => this.LegacyAction.key === actionKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -58,11 +58,8 @@ define([
|
|||||||
|
|
||||||
handleLegacyMutation = function (legacyObject) {
|
handleLegacyMutation = function (legacyObject) {
|
||||||
var newStyleObject = utils.toNewFormat(legacyObject.getModel(), legacyObject.getId());
|
var newStyleObject = utils.toNewFormat(legacyObject.getModel(), legacyObject.getId());
|
||||||
|
|
||||||
//Don't trigger self
|
|
||||||
this.eventEmitter.off('mutation', handleMutation);
|
|
||||||
this.eventEmitter.emit(newStyleObject.identifier.key + ":*", newStyleObject);
|
this.eventEmitter.emit(newStyleObject.identifier.key + ":*", newStyleObject);
|
||||||
this.eventEmitter.on('mutation', handleMutation);
|
this.eventEmitter.emit('mutation', newStyleObject);
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
|
|
||||||
this.eventEmitter.on('mutation', handleMutation);
|
this.eventEmitter.on('mutation', handleMutation);
|
||||||
|
@ -21,7 +21,9 @@ define([
|
|||||||
name: legacyView.name,
|
name: legacyView.name,
|
||||||
cssClass: legacyView.cssClass,
|
cssClass: legacyView.cssClass,
|
||||||
description: legacyView.description,
|
description: legacyView.description,
|
||||||
editable: legacyView.editable,
|
canEdit: function () {
|
||||||
|
return legacyView.editable === true;
|
||||||
|
},
|
||||||
canView: function (domainObject) {
|
canView: function (domainObject) {
|
||||||
if (!domainObject || !domainObject.identifier) {
|
if (!domainObject || !domainObject.identifier) {
|
||||||
return false;
|
return false;
|
||||||
@ -77,7 +79,7 @@ define([
|
|||||||
openmct.$angular.element(container),
|
openmct.$angular.element(container),
|
||||||
legacyView
|
legacyView
|
||||||
);
|
);
|
||||||
container.style.height = '100%';
|
container.classList.add('u-contents');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (promises.length) {
|
if (promises.length) {
|
||||||
|
@ -28,12 +28,18 @@ export default class Editor extends EventEmitter {
|
|||||||
super();
|
super();
|
||||||
this.editing = false;
|
this.editing = false;
|
||||||
this.openmct = openmct;
|
this.openmct = openmct;
|
||||||
|
document.addEventListener('drop', (event) => {
|
||||||
|
if (!this.isEditing()) {
|
||||||
|
this.edit();
|
||||||
|
}
|
||||||
|
}, {capture: true});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initiate an editing session. This will start a transaction during
|
* Initiate an editing session. This will start a transaction during
|
||||||
* which any persist operations will be deferred until either save()
|
* which any persist operations will be deferred until either save()
|
||||||
* or finish() are called.
|
* or finish() are called.
|
||||||
|
* @private
|
||||||
*/
|
*/
|
||||||
edit() {
|
edit() {
|
||||||
if (this.editing === true) {
|
if (this.editing === true) {
|
||||||
@ -54,6 +60,8 @@ export default class Editor extends EventEmitter {
|
|||||||
/**
|
/**
|
||||||
* Save any unsaved changes from this editing session. This will
|
* Save any unsaved changes from this editing session. This will
|
||||||
* end the current transaction.
|
* end the current transaction.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
*/
|
*/
|
||||||
save() {
|
save() {
|
||||||
return this.getTransactionService().commit().then((result)=>{
|
return this.getTransactionService().commit().then((result)=>{
|
||||||
@ -67,6 +75,8 @@ export default class Editor extends EventEmitter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* End the currently active transaction and discard unsaved changes.
|
* End the currently active transaction and discard unsaved changes.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
*/
|
*/
|
||||||
cancel() {
|
cancel() {
|
||||||
this.getTransactionService().cancel();
|
this.getTransactionService().cancel();
|
||||||
|
@ -46,6 +46,7 @@ define([
|
|||||||
function DefaultCompositionProvider(publicAPI, compositionAPI) {
|
function DefaultCompositionProvider(publicAPI, compositionAPI) {
|
||||||
this.publicAPI = publicAPI;
|
this.publicAPI = publicAPI;
|
||||||
this.listeningTo = {};
|
this.listeningTo = {};
|
||||||
|
this.onMutation = this.onMutation.bind(this);
|
||||||
|
|
||||||
this.cannotContainDuplicates = this.cannotContainDuplicates.bind(this);
|
this.cannotContainDuplicates = this.cannotContainDuplicates.bind(this);
|
||||||
this.cannotContainItself = this.cannotContainItself.bind(this);
|
this.cannotContainItself = this.cannotContainItself.bind(this);
|
||||||
@ -208,9 +209,10 @@ define([
|
|||||||
if (this.topicListener) {
|
if (this.topicListener) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var topic = this.publicAPI.$injector.get('topic');
|
this.publicAPI.objects.eventEmitter.on('mutation', this.onMutation);
|
||||||
var mutation = topic('mutation');
|
this.topicListener = () => {
|
||||||
this.topicListener = mutation.listen(this.onMutation.bind(this));
|
this.publicAPI.objects.eventEmitter.off('mutation', this.onMutation)
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -220,7 +222,7 @@ define([
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
DefaultCompositionProvider.prototype.onMutation = function (oldDomainObject) {
|
DefaultCompositionProvider.prototype.onMutation = function (oldDomainObject) {
|
||||||
var id = oldDomainObject.getId();
|
var id = objectUtils.makeKeyString(oldDomainObject.identifier);
|
||||||
var listeners = this.listeningTo[id];
|
var listeners = this.listeningTo[id];
|
||||||
|
|
||||||
if (!listeners) {
|
if (!listeners) {
|
||||||
@ -228,7 +230,7 @@ define([
|
|||||||
}
|
}
|
||||||
|
|
||||||
var oldComposition = listeners.composition.map(objectUtils.makeKeyString);
|
var oldComposition = listeners.composition.map(objectUtils.makeKeyString);
|
||||||
var newComposition = oldDomainObject.getModel().composition.map(objectUtils.makeKeyString);
|
var newComposition = oldDomainObject.composition.map(objectUtils.makeKeyString);
|
||||||
|
|
||||||
var added = _.difference(newComposition, oldComposition).map(objectUtils.parseKeyString);
|
var added = _.difference(newComposition, oldComposition).map(objectUtils.parseKeyString);
|
||||||
var removed = _.difference(oldComposition, newComposition).map(objectUtils.parseKeyString);
|
var removed = _.difference(oldComposition, newComposition).map(objectUtils.parseKeyString);
|
||||||
|
@ -73,8 +73,12 @@ class ContextMenuAPI {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_showContextMenuForObjectPath(objectPath, x, y) {
|
_showContextMenuForObjectPath(objectPath, x, y) {
|
||||||
let applicableActions = this._allActions.filter(
|
let applicableActions = this._allActions.filter((action) => {
|
||||||
(action) => action.appliesTo(objectPath));
|
if (action.appliesTo === undefined) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return action.appliesTo(objectPath);
|
||||||
|
});
|
||||||
|
|
||||||
if (this._activeContextMenu) {
|
if (this._activeContextMenu) {
|
||||||
this._hideActiveContextMenu();
|
this._hideActiveContextMenu();
|
||||||
|
@ -83,18 +83,15 @@ define([
|
|||||||
this.object = newObject;
|
this.object = newObject;
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
|
|
||||||
this.eventEmitter.on(qualifiedEventName(this.object, '*'), handleRecursiveMutation);
|
//Emit wildcard event
|
||||||
|
|
||||||
//Emit event specific to property
|
|
||||||
this.eventEmitter.emit(qualifiedEventName(this.object, path), value);
|
|
||||||
|
|
||||||
this.eventEmitter.off(qualifiedEventName(this.object, '*'), handleRecursiveMutation);
|
|
||||||
|
|
||||||
//Emit wildcare event
|
|
||||||
this.eventEmitter.emit(qualifiedEventName(this.object, '*'), this.object);
|
this.eventEmitter.emit(qualifiedEventName(this.object, '*'), this.object);
|
||||||
|
|
||||||
//Emit a general "any object" event
|
//Emit a general "any object" event
|
||||||
this.eventEmitter.emit(ANY_OBJECT_EVENT, this.object);
|
this.eventEmitter.emit(ANY_OBJECT_EVENT, this.object);
|
||||||
|
|
||||||
|
this.eventEmitter.on(qualifiedEventName(this.object, '*'), handleRecursiveMutation);
|
||||||
|
//Emit event specific to property
|
||||||
|
this.eventEmitter.emit(qualifiedEventName(this.object, path), value);
|
||||||
|
this.eventEmitter.off(qualifiedEventName(this.object, '*'), handleRecursiveMutation);
|
||||||
};
|
};
|
||||||
|
|
||||||
return MutableObject;
|
return MutableObject;
|
||||||
|
@ -215,6 +215,19 @@ define([
|
|||||||
return utils.makeKeyString(identifier);
|
return utils.makeKeyString(identifier);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given any number of identifiers, will return true if they are all equal, otherwise false.
|
||||||
|
* @param {module:openmct.ObjectAPI~Identifier[]} identifiers
|
||||||
|
*/
|
||||||
|
ObjectAPI.prototype.areIdsEqual = function (...identifiers) {
|
||||||
|
return identifiers.map(utils.parseKeyString)
|
||||||
|
.every(identifier => {
|
||||||
|
return identifier === identifiers[0] ||
|
||||||
|
(identifier.namespace === identifiers[0].namespace &&
|
||||||
|
identifier.key === identifiers[0].key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uniquely identifies a domain object.
|
* Uniquely identifies a domain object.
|
||||||
*
|
*
|
||||||
|
@ -3,13 +3,15 @@ import Overlay from './Overlay';
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
|
||||||
class Dialog extends Overlay {
|
class Dialog extends Overlay {
|
||||||
constructor({iconClass, message, title, ...options}) {
|
constructor({iconClass, message, title, hint, timestamp, ...options}) {
|
||||||
|
|
||||||
let component = new Vue({
|
let component = new Vue({
|
||||||
provide: {
|
provide: {
|
||||||
iconClass,
|
iconClass,
|
||||||
message,
|
message,
|
||||||
title
|
title,
|
||||||
|
hint,
|
||||||
|
timestamp
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
DialogComponent: DialogComponent
|
DialogComponent: DialogComponent
|
||||||
@ -20,7 +22,7 @@ class Dialog extends Overlay {
|
|||||||
super({
|
super({
|
||||||
element: component.$el,
|
element: component.$el,
|
||||||
size: 'fit',
|
size: 'fit',
|
||||||
notDismissable: true,
|
dismissable: false,
|
||||||
...options
|
...options
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ class Overlay extends EventEmitter {
|
|||||||
constructor(options) {
|
constructor(options) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
this.dismissable = options.dismissable !== false ? true : false;
|
||||||
this.container = document.createElement('div');
|
this.container = document.createElement('div');
|
||||||
this.container.classList.add('l-overlay-wrapper', cssClasses[options.size]);
|
this.container.classList.add('l-overlay-wrapper', cssClasses[options.size]);
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ class Overlay extends EventEmitter {
|
|||||||
dismiss: this.dismiss.bind(this),
|
dismiss: this.dismiss.bind(this),
|
||||||
element: options.element,
|
element: options.element,
|
||||||
buttons: options.buttons,
|
buttons: options.buttons,
|
||||||
notDismissable: options.notDismissable ? true : false
|
dismissable: this.dismissable
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
OverlayComponent: OverlayComponent
|
OverlayComponent: OverlayComponent
|
||||||
@ -35,8 +36,8 @@ class Overlay extends EventEmitter {
|
|||||||
|
|
||||||
dismiss() {
|
dismiss() {
|
||||||
this.emit('destroy');
|
this.emit('destroy');
|
||||||
this.component.$destroy();
|
|
||||||
document.body.removeChild(this.container);
|
document.body.removeChild(this.container);
|
||||||
|
this.component.$destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,6 +14,14 @@ import ProgressDialog from './ProgressDialog';
|
|||||||
class OverlayAPI {
|
class OverlayAPI {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.activeOverlays = [];
|
this.activeOverlays = [];
|
||||||
|
|
||||||
|
this.dismissLastOverlay = this.dismissLastOverlay.bind(this);
|
||||||
|
|
||||||
|
document.addEventListener('keyup', (event) => {
|
||||||
|
if (event.key === 'Escape') {
|
||||||
|
this.dismissLastOverlay();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,14 +46,24 @@ class OverlayAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
] * A description of option properties that can be passed into the overlay
|
* private
|
||||||
* @typedef options
|
*/
|
||||||
|
dismissLastOverlay() {
|
||||||
|
let lastOverlay = this.activeOverlays[this.activeOverlays.length - 1];
|
||||||
|
if (lastOverlay && lastOverlay.dismissable) {
|
||||||
|
lastOverlay.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A description of option properties that can be passed into the overlay
|
||||||
|
* @typedef options
|
||||||
* @property {object} element DOMElement that is to be inserted/shown on the overlay
|
* @property {object} element DOMElement that is to be inserted/shown on the overlay
|
||||||
* @property {string} size prefered size of the overlay (large, small, fit)
|
* @property {string} size prefered size of the overlay (large, small, fit)
|
||||||
* @property {array} buttons optional button objects with label and callback properties
|
* @property {array} buttons optional button objects with label and callback properties
|
||||||
* @property {function} onDestroy callback to be called when overlay is destroyed
|
* @property {function} onDestroy callback to be called when overlay is destroyed
|
||||||
* @property {boolean} notDismissable to prevent user from dismissing the overlay, calling code
|
* @property {boolean} dismissable allow user to dismiss overlay by using esc, and clicking away
|
||||||
* will need to explicitly dismiss the overlay.
|
* from overlay. Unless set to false, all overlays will be dismissable by default.
|
||||||
*/
|
*/
|
||||||
overlay(options) {
|
overlay(options) {
|
||||||
let overlay = new Overlay(options);
|
let overlay = new Overlay(options);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import ProgressComponent from '../../ui/components/layout/ProgressBar.vue';
|
import ProgressComponent from '../../ui/components/ProgressBar.vue';
|
||||||
import Overlay from './Overlay';
|
import Overlay from './Overlay';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ class ProgressDialog extends Overlay {
|
|||||||
super({
|
super({
|
||||||
element: component.$el,
|
element: component.$el,
|
||||||
size: 'fit',
|
size: 'fit',
|
||||||
notDismissable: true,
|
dismissable: false,
|
||||||
...options
|
...options
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -50,7 +50,6 @@
|
|||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
|
|
||||||
> * + * {
|
> * + * {
|
||||||
@include test();
|
|
||||||
margin-top: $interiorMargin;
|
margin-top: $interiorMargin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="c-overlay__outer">
|
<div class="c-overlay__outer">
|
||||||
<button class="c-click-icon c-overlay__close-button icon-x-in-circle"
|
<button class="c-click-icon c-overlay__close-button icon-x-in-circle"
|
||||||
v-if="!notDismissable"
|
v-if="dismissable"
|
||||||
@click="destroy">
|
@click="destroy">
|
||||||
</button>
|
</button>
|
||||||
<div class="c-overlay__contents" ref="element"></div>
|
<div class="c-overlay__contents" ref="element"></div>
|
||||||
@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
.c-overlay {
|
.c-overlay {
|
||||||
@include abs();
|
@include abs();
|
||||||
z-index: 100;
|
z-index: 70;
|
||||||
|
|
||||||
&__blocker {
|
&__blocker {
|
||||||
display: none; // Mobile-first
|
display: none; // Mobile-first
|
||||||
@ -129,19 +129,19 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
inject: ['dismiss', 'element', 'buttons', 'notDismissable'],
|
inject: ['dismiss', 'element', 'buttons', 'dismissable'],
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$refs.element.appendChild(this.element);
|
this.$refs.element.appendChild(this.element);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
destroy: function () {
|
destroy: function () {
|
||||||
if (!this.notDismissable) {
|
if (this.dismissable) {
|
||||||
this.dismiss();
|
this.dismiss();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
buttonClickHandler: function (method) {
|
buttonClickHandler: function (method) {
|
||||||
method();
|
method();
|
||||||
this.destroy();
|
this.$emit('destroy');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,6 +124,22 @@ define([
|
|||||||
return sortedMetadata;
|
return sortedMetadata;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TelemetryMetadataManager.prototype.getDefaultDisplayValue = function () {
|
||||||
|
let valueMetadata = this.valuesForHints(['range'])[0];
|
||||||
|
|
||||||
|
if (valueMetadata === undefined) {
|
||||||
|
valueMetadata = this.values().filter(values => {
|
||||||
|
return !(values.hints.domain);
|
||||||
|
})[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valueMetadata === undefined) {
|
||||||
|
valueMetadata = this.values()[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return valueMetadata.key;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
return TelemetryMetadataManager;
|
return TelemetryMetadataManager;
|
||||||
|
|
||||||
|
@ -20,47 +20,48 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
define([
|
define([
|
||||||
'vue',
|
'./components/LadTableSet.vue',
|
||||||
'../../res/templates/viewSnapshot.html'
|
'vue'
|
||||||
], function (
|
], function (
|
||||||
Vue,
|
LadTableSet,
|
||||||
snapshotOverlayTemplate
|
Vue
|
||||||
) {
|
) {
|
||||||
function SnapshotOverlay (embedObject, formatTime) {
|
function LADTableSetViewProvider(openmct) {
|
||||||
this.embedObject = embedObject;
|
return {
|
||||||
|
key: 'LadTableSet',
|
||||||
|
name: 'LAD Table Set',
|
||||||
|
cssClass: 'icon-tabular-lad-set',
|
||||||
|
canView: function (domainObject) {
|
||||||
|
return domainObject.type === 'LadTableSet';
|
||||||
|
},
|
||||||
|
view: function (domainObject) {
|
||||||
|
let component;
|
||||||
|
|
||||||
this.snapshotOverlayVue = new Vue({
|
|
||||||
template: snapshotOverlayTemplate,
|
|
||||||
data: function () {
|
|
||||||
return {
|
return {
|
||||||
embed: embedObject
|
show: function (element) {
|
||||||
|
component = new Vue({
|
||||||
|
components: {
|
||||||
|
LadTableSet: LadTableSet.default
|
||||||
|
},
|
||||||
|
provide: {
|
||||||
|
openmct,
|
||||||
|
domainObject
|
||||||
|
},
|
||||||
|
el: element,
|
||||||
|
template: '<lad-table-set></lad-table-set>'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
destroy: function (element) {
|
||||||
|
component.$destroy();
|
||||||
|
component = undefined;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
priority: function () {
|
||||||
close: this.close.bind(this),
|
return 1;
|
||||||
formatTime: formatTime
|
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
this.open();
|
|
||||||
}
|
}
|
||||||
|
return LADTableSetViewProvider;
|
||||||
SnapshotOverlay.prototype.open = function () {
|
|
||||||
this.overlay = document.createElement('div');
|
|
||||||
this.overlay.classList.add('abs');
|
|
||||||
|
|
||||||
document.body.appendChild(this.overlay);
|
|
||||||
|
|
||||||
this.overlay.appendChild(this.snapshotOverlayVue.$mount().$el);
|
|
||||||
};
|
|
||||||
|
|
||||||
SnapshotOverlay.prototype.close = function (event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
this.snapshotOverlayVue.$destroy();
|
|
||||||
this.overlay.parentNode.removeChild(this.overlay);
|
|
||||||
};
|
|
||||||
|
|
||||||
return SnapshotOverlay;
|
|
||||||
});
|
});
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user