Compare commits
53 Commits
view-large
...
new-tutori
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9553e0c64f | ||
|
|
da40f4c96e | ||
|
|
6fa5a31217 | ||
|
|
5bc7a701dc | ||
|
|
5cd0516048 | ||
|
|
48a603ece8 | ||
|
|
abfa56464a | ||
|
|
c1d6e21c3c | ||
|
|
3bd556a406 | ||
|
|
347fb6d882 | ||
|
|
b3cf7a5d93 | ||
|
|
c7cffdeb3b | ||
|
|
d45ae7908d | ||
|
|
b10fb4533e | ||
|
|
c74fdb816f | ||
|
|
40985a56c8 | ||
|
|
5c01f0be24 | ||
|
|
f7ff5af60b | ||
|
|
2088fc52f3 | ||
|
|
db33ab143e | ||
|
|
8c77d4006a | ||
|
|
2fa567b98b | ||
|
|
e61f04663a | ||
|
|
4b905fa7d2 | ||
|
|
5e6e7f018a | ||
|
|
53f56b430a | ||
|
|
50c934820c | ||
|
|
2a10a2cae2 | ||
|
|
65325b90fd | ||
|
|
cfecc36ae6 | ||
|
|
d9f8622459 | ||
|
|
8e13819e1e | ||
|
|
aaedf5d576 | ||
|
|
af9ffaf02d | ||
|
|
970acbd56e | ||
|
|
46c7399867 | ||
|
|
9a6745635d | ||
|
|
fa962b42bc | ||
|
|
34dc457aff | ||
|
|
a3311e4c57 | ||
|
|
ef8efbd53d | ||
|
|
6cd99efbb9 | ||
|
|
ae2b73a4f5 | ||
|
|
0c3ff82cfe | ||
|
|
50f303bbdc | ||
|
|
2a4944d6ee | ||
|
|
3544caf4be | ||
|
|
976333d7f7 | ||
|
|
6d5530ba9c | ||
|
|
77d0134e2e | ||
|
|
d3b4ad41c2 | ||
|
|
3d3baddd23 | ||
|
|
9f9d28deef |
@@ -1,6 +1,6 @@
|
||||
# Open MCT [](http://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
||||
Open MCT is a next-generation mission control framework for visualization of data on desktop and mobile devices. It is developed at NASA's Ames Research Center, and is being used by NASA for data analysis of spacecraft missions, as well as planning and operation of experimental rover systems. As a generalizable and open source framework, Open MCT could be used as the basis for building applications for planning, operation, and analysis of any systems producing telemetry data.
|
||||
Open MCT (Open Mission Control Technologies) is a next-generation mission control framework for visualization of data on desktop and mobile devices. It is developed at NASA's Ames Research Center, and is being used by NASA for data analysis of spacecraft missions, as well as planning and operation of experimental rover systems. As a generalizable and open source framework, Open MCT could be used as the basis for building applications for planning, operation, and analysis of any systems producing telemetry data.
|
||||
|
||||
Please visit our [Official Site](https://nasa.github.io/openmct/) and [Getting Started Guide](https://nasa.github.io/openmct/getting-started/)
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ Keeping that in mind, there are a few useful patterns supported by the
|
||||
framework that are useful to keep in mind.
|
||||
|
||||
The specific service infrastructure provided by the platform is described
|
||||
in the [Platform Architecture](Platform.md).
|
||||
in the [Platform Architecture](platform.md).
|
||||
|
||||
## Extension Categories
|
||||
|
||||
|
||||
@@ -2261,10 +2261,7 @@ The platform understands the following policy categories (specifiable as the
|
||||
|
||||
* `action`: Determines whether or not a given action is allowable. The candidate
|
||||
argument here is an Action; the context is its action context object.
|
||||
* `composition`: Determines whether or not domain objects of a given type are
|
||||
allowed to contain domain objects of another type. The candidate argument here
|
||||
is the container's `Type`; the context argument is the `Type` of the object to be
|
||||
contained.
|
||||
* `composition`: Determines whether or not domain objects of a given type (first argument, `parentType`) can contain a given object (second argument, `child`).
|
||||
* `view`: Determines whether or not a view is applicable for a domain object.
|
||||
The candidate argument is the view's extension definition; the context argument
|
||||
is the `DomainObject` to be viewed.
|
||||
|
||||
@@ -320,7 +320,7 @@ define([
|
||||
+ {
|
||||
+ "key": "example.todo",
|
||||
+ "name": "To-Do List",
|
||||
+ "cssclass": "icon-check",
|
||||
+ "cssClass": "icon-check",
|
||||
+ "description": "A list of things that need to be done.",
|
||||
+ "features": ["creation"]
|
||||
+ }
|
||||
@@ -340,7 +340,7 @@ Going through the properties we've defined:
|
||||
domain objects of this type.
|
||||
* The `name` of "To-Do List" is the human-readable name for this type, and will
|
||||
be shown to users.
|
||||
* The `cssclass` maps to an icon that will be shown for each To-Do List. The icons
|
||||
* The `cssClass` maps to an icon that will be shown for each To-Do List. The icons
|
||||
are defined in our [custom open MCT icon set](https://github.com/nasa/openmct/blob/master/platform/commonUI/general/res/sass/_glyphs.scss).
|
||||
A complete list of available icons will be provided in the future.
|
||||
* The `description` is also human-readable, and will be used whenever a longer
|
||||
@@ -416,7 +416,7 @@ define([
|
||||
{
|
||||
"key": "example.todo",
|
||||
"name": "To-Do List",
|
||||
"cssclass": "icon-check",
|
||||
"cssClass": "icon-check",
|
||||
"description": "A list of things that need to be done.",
|
||||
"features": ["creation"]
|
||||
}
|
||||
@@ -425,7 +425,7 @@ define([
|
||||
+ {
|
||||
+ "key": "example.todo",
|
||||
+ "type": "example.todo",
|
||||
+ "cssclass": "icon-check",
|
||||
+ "cssClass": "icon-check",
|
||||
+ "name": "List",
|
||||
+ "templateUrl": "templates/todo.html",
|
||||
+ "editable": true
|
||||
@@ -447,7 +447,7 @@ the domain object type, but could have chosen any unique name.
|
||||
domain objects of that type. This means that we'll see this view for To-do Lists
|
||||
that we create, but not for other domain objects (such as Folders.)
|
||||
|
||||
* The `cssclass` and `name` properties describe the icon and human-readable name
|
||||
* The `cssClass` and `name` properties describe the icon and human-readable name
|
||||
for this view to display in the UI where needed (if multiple views are available
|
||||
for To-do Lists, the user will be able to choose one.)
|
||||
|
||||
@@ -473,7 +473,7 @@ define([
|
||||
{
|
||||
"key": "example.todo",
|
||||
"name": "To-Do List",
|
||||
"cssclass": "icon-check",
|
||||
"cssClass": "icon-check",
|
||||
"description": "A list of things that need to be done.",
|
||||
"features": ["creation"],
|
||||
+ "model": {
|
||||
@@ -488,7 +488,7 @@ define([
|
||||
{
|
||||
"key": "example.todo",
|
||||
"type": "example.todo",
|
||||
"cssclass": "icon-check",
|
||||
"cssClass": "icon-check",
|
||||
"name": "List",
|
||||
"templateUrl": "templates/todo.html",
|
||||
"editable": true
|
||||
@@ -647,7 +647,7 @@ define([
|
||||
{
|
||||
"key": "example.todo",
|
||||
"name": "To-Do List",
|
||||
"cssclass": "icon-check",
|
||||
"cssClass": "icon-check",
|
||||
"description": "A list of things that need to be done.",
|
||||
"features": ["creation"],
|
||||
"model": {
|
||||
@@ -662,7 +662,7 @@ define([
|
||||
{
|
||||
"key": "example.todo",
|
||||
"type": "example.todo",
|
||||
"cssclass": "icon-check",
|
||||
"cssClass": "icon-check",
|
||||
"name": "List",
|
||||
"templateUrl": "templates/todo.html",
|
||||
"editable": true
|
||||
@@ -741,7 +741,7 @@ define([
|
||||
{
|
||||
"key": "example.todo",
|
||||
"name": "To-Do List",
|
||||
"cssclass": "icon-check",
|
||||
"cssClass": "icon-check",
|
||||
"description": "A list of things that need to be done.",
|
||||
"features": ["creation"],
|
||||
"model": {
|
||||
@@ -756,7 +756,7 @@ define([
|
||||
{
|
||||
"key": "example.todo",
|
||||
"type": "example.todo",
|
||||
"cssclass": "icon-check",
|
||||
"cssClass": "icon-check",
|
||||
"name": "List",
|
||||
"templateUrl": "templates/todo.html",
|
||||
"editable": true,
|
||||
@@ -766,7 +766,7 @@ define([
|
||||
+ "items": [
|
||||
+ {
|
||||
+ "text": "Add Task",
|
||||
+ "cssclass": "icon-plus",
|
||||
+ "cssClass": "icon-plus",
|
||||
+ "method": "addTask",
|
||||
+ "control": "button"
|
||||
+ }
|
||||
@@ -775,7 +775,7 @@ define([
|
||||
+ {
|
||||
+ "items": [
|
||||
+ {
|
||||
+ "cssclass": "icon-trash",
|
||||
+ "cssClass": "icon-trash",
|
||||
+ "method": "removeTask",
|
||||
+ "control": "button"
|
||||
+ }
|
||||
@@ -971,7 +971,7 @@ define([
|
||||
{
|
||||
"key": "example.todo",
|
||||
"name": "To-Do List",
|
||||
"cssclass": "icon-check",
|
||||
"cssClass": "icon-check",
|
||||
"description": "A list of things that need to be done.",
|
||||
"features": ["creation"],
|
||||
"model": {
|
||||
@@ -986,7 +986,7 @@ define([
|
||||
{
|
||||
"key": "example.todo",
|
||||
"type": "example.todo",
|
||||
"cssclass": "icon-check",
|
||||
"cssClass": "icon-check",
|
||||
"name": "List",
|
||||
"templateUrl": "templates/todo.html",
|
||||
"editable": true,
|
||||
@@ -996,7 +996,7 @@ define([
|
||||
"items": [
|
||||
{
|
||||
"text": "Add Task",
|
||||
"cssclass": "icon-plus",
|
||||
"cssClass": "icon-plus",
|
||||
"method": "addTask",
|
||||
"control": "button"
|
||||
}
|
||||
@@ -1005,7 +1005,7 @@ define([
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"cssclass": "icon-trash",
|
||||
"cssClass": "icon-trash",
|
||||
"method": "removeTask",
|
||||
"control": "button"
|
||||
}
|
||||
@@ -1236,7 +1236,7 @@ define([
|
||||
{
|
||||
"key": "example.todo",
|
||||
"name": "To-Do List",
|
||||
"cssclass": "icon-check",
|
||||
"cssClass": "icon-check",
|
||||
"description": "A list of things that need to be done.",
|
||||
"features": ["creation"],
|
||||
"model": {
|
||||
@@ -1248,7 +1248,7 @@ define([
|
||||
{
|
||||
"key": "example.todo",
|
||||
"type": "example.todo",
|
||||
"cssclass": "icon-check",
|
||||
"cssClass": "icon-check",
|
||||
"name": "List",
|
||||
"templateUrl": "templates/todo.html",
|
||||
"editable": true,
|
||||
@@ -1258,7 +1258,7 @@ define([
|
||||
"items": [
|
||||
{
|
||||
"text": "Add Task",
|
||||
"cssclass": "icon-plus",
|
||||
"cssClass": "icon-plus",
|
||||
"method": "addTask",
|
||||
"control": "button"
|
||||
}
|
||||
@@ -1267,7 +1267,7 @@ define([
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"cssclass": "icon-trash",
|
||||
"cssClass": "icon-trash",
|
||||
"method": "removeTask",
|
||||
"control": "button"
|
||||
}
|
||||
@@ -1374,7 +1374,7 @@ define([
|
||||
{
|
||||
"name": "Bar Graph",
|
||||
"key": "example.bargraph",
|
||||
"cssclass": "icon-autoflow-tabular",
|
||||
"cssClass": "icon-autoflow-tabular",
|
||||
"templateUrl": "templates/bargraph.html",
|
||||
"needs": [ "telemetry" ],
|
||||
"delegation": true
|
||||
@@ -1677,7 +1677,7 @@ define([
|
||||
{
|
||||
"name": "Bar Graph",
|
||||
"key": "example.bargraph",
|
||||
"cssclass": "icon-autoflow-tabular",
|
||||
"cssClass": "icon-autoflow-tabular",
|
||||
"templateUrl": "templates/bargraph.html",
|
||||
"needs": [ "telemetry" ],
|
||||
"delegation": true
|
||||
@@ -1843,7 +1843,7 @@ define([
|
||||
{
|
||||
"name": "Bar Graph",
|
||||
"key": "example.bargraph",
|
||||
"cssclass": "icon-autoflow-tabular",
|
||||
"cssClass": "icon-autoflow-tabular",
|
||||
"templateUrl": "templates/bargraph.html",
|
||||
"needs": [ "telemetry" ],
|
||||
"delegation": true,
|
||||
@@ -2320,7 +2320,7 @@ define([
|
||||
{
|
||||
"name": "Spacecraft",
|
||||
"key": "example.spacecraft",
|
||||
"cssclass": "icon-object"
|
||||
"cssClass": "icon-object"
|
||||
}
|
||||
],
|
||||
"roots": [
|
||||
@@ -2706,18 +2706,18 @@ define([
|
||||
{
|
||||
"name": "Spacecraft",
|
||||
"key": "example.spacecraft",
|
||||
"cssclass": "icon-object"
|
||||
"cssClass": "icon-object"
|
||||
},
|
||||
+ {
|
||||
+ "name": "Subsystem",
|
||||
+ "key": "example.subsystem",
|
||||
+ "cssclass": "icon-object",
|
||||
+ "cssClass": "icon-object",
|
||||
+ "model": { "composition": [] }
|
||||
+ },
|
||||
+ {
|
||||
+ "name": "Measurement",
|
||||
+ "key": "example.measurement",
|
||||
+ "cssclass": "icon-telemetry",
|
||||
+ "cssClass": "icon-telemetry",
|
||||
+ "model": { "telemetry": {} },
|
||||
+ "telemetry": {
|
||||
+ "source": "example.source",
|
||||
@@ -3031,18 +3031,18 @@ define([
|
||||
{
|
||||
"name": "Spacecraft",
|
||||
"key": "example.spacecraft",
|
||||
"cssclass": "icon-object"
|
||||
"cssClass": "icon-object"
|
||||
},
|
||||
{
|
||||
"name": "Subsystem",
|
||||
"key": "example.subsystem",
|
||||
"cssclass": "icon-object",
|
||||
"cssClass": "icon-object",
|
||||
"model": { "composition": [] }
|
||||
},
|
||||
{
|
||||
"name": "Measurement",
|
||||
"key": "example.measurement",
|
||||
"cssclass": "icon-telemetry",
|
||||
"cssClass": "icon-telemetry",
|
||||
"model": { "telemetry": {} },
|
||||
"telemetry": {
|
||||
"source": "example.source",
|
||||
|
||||
@@ -49,7 +49,7 @@ define([
|
||||
{
|
||||
"key": "eventGenerator",
|
||||
"name": "Event Message Generator",
|
||||
"cssclass": "icon-folder-new",
|
||||
"cssClass": "icon-folder-new",
|
||||
"description": "For development use. Creates sample event message data that mimics a live data stream.",
|
||||
"priority": 10,
|
||||
"features": "creation",
|
||||
|
||||
@@ -36,7 +36,7 @@ define([
|
||||
"name": "Export Telemetry as CSV",
|
||||
"implementation": ExportTelemetryAsCSVAction,
|
||||
"category": "contextual",
|
||||
"cssclass": "icon-download",
|
||||
"cssClass": "icon-download",
|
||||
"depends": [ "exportService" ]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -41,6 +41,10 @@ define([
|
||||
return domainObject.type === 'generator';
|
||||
};
|
||||
|
||||
GeneratorProvider.prototype.supportsRequest =
|
||||
GeneratorProvider.prototype.supportsSubscribe =
|
||||
GeneratorProvider.prototype.canProvideTelemetry;
|
||||
|
||||
GeneratorProvider.prototype.makeWorkerRequest = function (domainObject, request) {
|
||||
var props = [
|
||||
'amplitude',
|
||||
@@ -19,7 +19,7 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define,Promise*/
|
||||
/*global define*/
|
||||
|
||||
define({
|
||||
START_TIME: Date.now() - 24 * 60 * 60 * 1000 // Now minus a day.
|
||||
@@ -19,12 +19,11 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define,Promise*/
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
['./SinewaveConstants', 'moment'],
|
||||
function (SinewaveConstants, moment) {
|
||||
"use strict";
|
||||
|
||||
var START_TIME = SinewaveConstants.START_TIME,
|
||||
FORMAT_REGEX = /^-?\d+:\d+:\d+$/,
|
||||
@@ -1,183 +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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
"./src/SinewaveTelemetryProvider",
|
||||
"./src/SinewaveLimitCapability",
|
||||
"./src/SinewaveDeltaFormat",
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
SinewaveTelemetryProvider,
|
||||
SinewaveLimitCapability,
|
||||
SinewaveDeltaFormat,
|
||||
legacyRegistry
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
legacyRegistry.register("example/generator", {
|
||||
"name": "Sine Wave Generator",
|
||||
"description": "For development use. Generates example streaming telemetry data using a simple sine wave algorithm.",
|
||||
"extensions": {
|
||||
"components": [
|
||||
{
|
||||
"implementation": SinewaveTelemetryProvider,
|
||||
"type": "provider",
|
||||
"provides": "telemetryService",
|
||||
"depends": [
|
||||
"$q",
|
||||
"$timeout"
|
||||
]
|
||||
}
|
||||
],
|
||||
"capabilities": [
|
||||
{
|
||||
"key": "limit",
|
||||
"implementation": SinewaveLimitCapability
|
||||
}
|
||||
],
|
||||
"formats": [
|
||||
{
|
||||
"key": "example.delta",
|
||||
"implementation": SinewaveDeltaFormat
|
||||
}
|
||||
],
|
||||
"constants": [
|
||||
{
|
||||
"key": "TIME_CONDUCTOR_DOMAINS",
|
||||
"value": [
|
||||
{
|
||||
"key": "time",
|
||||
"name": "Time"
|
||||
},
|
||||
{
|
||||
"key": "yesterday",
|
||||
"name": "Yesterday"
|
||||
},
|
||||
{
|
||||
"key": "delta",
|
||||
"name": "Delta",
|
||||
"format": "example.delta"
|
||||
}
|
||||
],
|
||||
"priority": -1
|
||||
}
|
||||
],
|
||||
"types": [
|
||||
{
|
||||
"key": "generator",
|
||||
"name": "Sine Wave Generator",
|
||||
"cssclass": "icon-telemetry",
|
||||
"description": "For development use. Generates example streaming telemetry data using a simple sine wave algorithm.",
|
||||
"priority": 10,
|
||||
"features": "creation",
|
||||
"model": {
|
||||
"telemetry": {
|
||||
"period": 10,
|
||||
"amplitude": 1,
|
||||
"offset": 0,
|
||||
"dataRateInHz": 1
|
||||
}
|
||||
},
|
||||
"telemetry": {
|
||||
"source": "generator",
|
||||
"domains": [
|
||||
{
|
||||
"key": "utc",
|
||||
"name": "Time"
|
||||
},
|
||||
{
|
||||
"key": "yesterday",
|
||||
"name": "Yesterday"
|
||||
},
|
||||
{
|
||||
"key": "delta",
|
||||
"name": "Delta",
|
||||
"format": "example.delta"
|
||||
}
|
||||
],
|
||||
"ranges": [
|
||||
{
|
||||
"key": "sin",
|
||||
"name": "Sine"
|
||||
},
|
||||
{
|
||||
"key": "cos",
|
||||
"name": "Cosine"
|
||||
}
|
||||
]
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"name": "Period",
|
||||
"control": "textfield",
|
||||
"cssclass": "l-input-sm l-numeric",
|
||||
"key": "period",
|
||||
"required": true,
|
||||
"property": [
|
||||
"telemetry",
|
||||
"period"
|
||||
],
|
||||
"pattern": "^\\d*(\\.\\d*)?$"
|
||||
},
|
||||
{
|
||||
"name": "Amplitude",
|
||||
"control": "textfield",
|
||||
"cssclass": "l-input-sm l-numeric",
|
||||
"key": "amplitude",
|
||||
"required": true,
|
||||
"property": [
|
||||
"telemetry",
|
||||
"amplitude"
|
||||
],
|
||||
"pattern": "^\\d*(\\.\\d*)?$"
|
||||
},
|
||||
{
|
||||
"name": "Offset",
|
||||
"control": "textfield",
|
||||
"cssclass": "l-input-sm l-numeric",
|
||||
"key": "offset",
|
||||
"required": true,
|
||||
"property": [
|
||||
"telemetry",
|
||||
"offset"
|
||||
],
|
||||
"pattern": "^\\d*(\\.\\d*)?$"
|
||||
},
|
||||
{
|
||||
"name": "Data Rate (hz)",
|
||||
"control": "textfield",
|
||||
"cssclass": "l-input-sm l-numeric",
|
||||
"key": "dataRateInHz",
|
||||
"required": true,
|
||||
"property": [
|
||||
"telemetry",
|
||||
"dataRateInHz"
|
||||
],
|
||||
"pattern": "^\\d*(\\.\\d*)?$"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
(function () {
|
||||
|
||||
var FIFTEEN_MINUTES = 15 * 60 * 1000;
|
||||
|
||||
var handlers = {
|
||||
subscribe: onSubscribe,
|
||||
@@ -51,6 +52,7 @@
|
||||
function onSubscribe(message) {
|
||||
var data = message.data;
|
||||
|
||||
// Keep
|
||||
var start = Date.now();
|
||||
var step = 1000 / data.dataRateInHz;
|
||||
var nextStep = start - (start % step) + step;
|
||||
@@ -82,8 +84,11 @@
|
||||
|
||||
function onRequest(message) {
|
||||
var data = message.data;
|
||||
if (!data.start || !data.end) {
|
||||
throw new Error('missing start and end!');
|
||||
if (data.end == undefined) {
|
||||
data.end = Date.now();
|
||||
}
|
||||
if (data.start == undefined){
|
||||
data.start = data.end - FIFTEEN_MINUTES;
|
||||
}
|
||||
|
||||
var now = Date.now();
|
||||
171
example/generator/plugin.js
Normal file
171
example/generator/plugin.js
Normal file
@@ -0,0 +1,171 @@
|
||||
/*****************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
"./GeneratorProvider",
|
||||
"./SinewaveLimitCapability",
|
||||
"./SinewaveDeltaFormat"
|
||||
], function (
|
||||
GeneratorProvider,
|
||||
SinewaveLimitCapability,
|
||||
SinewaveDeltaFormat
|
||||
) {
|
||||
|
||||
var legacyExtensions = {
|
||||
"capabilities": [
|
||||
{
|
||||
"key": "limit",
|
||||
"implementation": SinewaveLimitCapability
|
||||
}
|
||||
],
|
||||
"formats": [
|
||||
{
|
||||
"key": "example.delta",
|
||||
"implementation": SinewaveDeltaFormat
|
||||
}
|
||||
],
|
||||
"constants": [
|
||||
{
|
||||
"key": "TIME_CONDUCTOR_DOMAINS",
|
||||
"value": [
|
||||
{
|
||||
"key": "time",
|
||||
"name": "Time"
|
||||
},
|
||||
{
|
||||
"key": "yesterday",
|
||||
"name": "Yesterday"
|
||||
},
|
||||
{
|
||||
"key": "delta",
|
||||
"name": "Delta"
|
||||
}
|
||||
],
|
||||
"priority": -1
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
return function(openmct){
|
||||
//Register legacy extensions for things not yet supported by the new API
|
||||
Object.keys(legacyExtensions).forEach(function (type){
|
||||
var extensionsOfType = legacyExtensions[type];
|
||||
extensionsOfType.forEach(function (extension) {
|
||||
openmct.legacyExtension(type, extension)
|
||||
})
|
||||
});
|
||||
openmct.types.addType("generator", {
|
||||
label: "Sine Wave Generator",
|
||||
description: "For development use. Generates example streaming telemetry data using a simple sine wave algorithm.",
|
||||
cssClass: "icon-telemetry",
|
||||
creatable: true,
|
||||
form: [
|
||||
{
|
||||
name: "Period",
|
||||
control: "textfield",
|
||||
cssClass: "l-input-sm l-numeric",
|
||||
key: "period",
|
||||
required: true,
|
||||
property: [
|
||||
"telemetry",
|
||||
"period"
|
||||
],
|
||||
pattern: "^\\d*(\\.\\d*)?$"
|
||||
},
|
||||
{
|
||||
name: "Amplitude",
|
||||
control: "textfield",
|
||||
cssClass: "l-input-sm l-numeric",
|
||||
key: "amplitude",
|
||||
required: true,
|
||||
property: [
|
||||
"telemetry",
|
||||
"amplitude"
|
||||
],
|
||||
pattern: "^\\d*(\\.\\d*)?$"
|
||||
},
|
||||
{
|
||||
name: "Offset",
|
||||
control: "textfield",
|
||||
cssClass: "l-input-sm l-numeric",
|
||||
key: "offset",
|
||||
required: true,
|
||||
property: [
|
||||
"telemetry",
|
||||
"offset"
|
||||
],
|
||||
pattern: "^\\d*(\\.\\d*)?$"
|
||||
},
|
||||
{
|
||||
name: "Data Rate (hz)",
|
||||
control: "textfield",
|
||||
cssClass: "l-input-sm l-numeric",
|
||||
key: "dataRateInHz",
|
||||
required: true,
|
||||
property: [
|
||||
"telemetry",
|
||||
"dataRateInHz"
|
||||
],
|
||||
pattern: "^\\d*(\\.\\d*)?$"
|
||||
}
|
||||
],
|
||||
initialize: function (object) {
|
||||
object.telemetry = {
|
||||
period: 10,
|
||||
amplitude: 1,
|
||||
offset: 0,
|
||||
dataRateInHz: 1,
|
||||
domains: [
|
||||
{
|
||||
key: "utc",
|
||||
name: "Time",
|
||||
format: "utc"
|
||||
},
|
||||
{
|
||||
key: "yesterday",
|
||||
name: "Yesterday",
|
||||
format: "utc"
|
||||
},
|
||||
{
|
||||
key: "delta",
|
||||
name: "Delta",
|
||||
format: "example.delta"
|
||||
}
|
||||
],
|
||||
ranges: [
|
||||
{
|
||||
key: "sin",
|
||||
name: "Sine"
|
||||
},
|
||||
{
|
||||
key: "cos",
|
||||
name: "Cosine"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
openmct.telemetry.addProvider(new GeneratorProvider());
|
||||
};
|
||||
|
||||
});
|
||||
@@ -49,7 +49,7 @@ define([
|
||||
{
|
||||
"key": "imagery",
|
||||
"name": "Example Imagery",
|
||||
"cssclass": "icon-image",
|
||||
"cssClass": "icon-image",
|
||||
"features": "creation",
|
||||
"description": "For development use. Creates example imagery data that mimics a live imagery stream.",
|
||||
"priority": 10,
|
||||
|
||||
@@ -31,7 +31,7 @@ define(['../../../platform/features/conductor/core/src/timeSystems/LocalClock'],
|
||||
this.metadata = {
|
||||
key: 'test-lad',
|
||||
mode: 'lad',
|
||||
cssclass: 'icon-clock',
|
||||
cssClass: 'icon-clock',
|
||||
label: 'Latest Available Data',
|
||||
name: 'Latest available data',
|
||||
description: 'Monitor real-time streaming data as it comes in. The Time Conductor and displays will automatically advance themselves based on a UTC clock.'
|
||||
|
||||
@@ -41,18 +41,18 @@ define([
|
||||
{
|
||||
"name":"Mars Science Laboratory",
|
||||
"key": "msl.curiosity",
|
||||
"cssclass": "icon-object"
|
||||
"cssClass": "icon-object"
|
||||
},
|
||||
{
|
||||
"name": "Instrument",
|
||||
"key": "msl.instrument",
|
||||
"cssclass": "icon-object",
|
||||
"cssClass": "icon-object",
|
||||
"model": {"composition": []}
|
||||
},
|
||||
{
|
||||
"name": "Measurement",
|
||||
"key": "msl.measurement",
|
||||
"cssclass": "icon-telemetry",
|
||||
"cssClass": "icon-telemetry",
|
||||
"model": {"telemetry": {}},
|
||||
"telemetry": {
|
||||
"source": "rems.source",
|
||||
|
||||
@@ -81,7 +81,7 @@ define([
|
||||
{
|
||||
"key": "plot",
|
||||
"name": "Example Telemetry Plot",
|
||||
"cssclass": "icon-telemetry-panel",
|
||||
"cssClass": "icon-telemetry-panel",
|
||||
"description": "For development use. A plot for displaying telemetry.",
|
||||
"priority": 10,
|
||||
"delegates": [
|
||||
@@ -129,7 +129,7 @@ define([
|
||||
{
|
||||
"name": "Period",
|
||||
"control": "textfield",
|
||||
"cssclass": "l-input-sm l-numeric",
|
||||
"cssClass": "l-input-sm l-numeric",
|
||||
"key": "period",
|
||||
"required": true,
|
||||
"property": [
|
||||
|
||||
@@ -63,7 +63,7 @@ define(
|
||||
* Get the CSS class that defines the icon
|
||||
* to display in this indicator. This will appear
|
||||
* as a dataflow icon.
|
||||
* @returns {string} the cssclass of the dataflow icon
|
||||
* @returns {string} the cssClass of the dataflow icon
|
||||
*/
|
||||
getCssClass: function () {
|
||||
return "icon-connectivity";
|
||||
|
||||
@@ -69,6 +69,11 @@ var gulp = require('gulp'),
|
||||
}
|
||||
};
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
options.requirejsOptimize.optimize = 'none';
|
||||
}
|
||||
|
||||
|
||||
gulp.task('scripts', function () {
|
||||
var requirejsOptimize = require('gulp-requirejs-optimize');
|
||||
var replace = require('gulp-replace-task');
|
||||
|
||||
22
index.html
22
index.html
@@ -25,20 +25,32 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<title></title>
|
||||
<script src="openmct-tutorial/lib/http.js">
|
||||
</script>
|
||||
<script src="bower_components/requirejs/require.js">
|
||||
</script>
|
||||
<script src="openmct-tutorial/dictionary-plugin.js">
|
||||
</script>
|
||||
<script src="openmct-tutorial/realtime-telemetry-plugin.js">
|
||||
</script>
|
||||
<script src="openmct-tutorial/historical-telemetry-plugin.js">
|
||||
</script>
|
||||
<script>
|
||||
require(['openmct'], function (openmct) {
|
||||
[
|
||||
'example/imagery',
|
||||
'example/eventGenerator',
|
||||
'example/generator'
|
||||
'example/eventGenerator'
|
||||
].forEach(
|
||||
openmct.legacyRegistry.enable.bind(openmct.legacyRegistry)
|
||||
);
|
||||
openmct.install(openmct.plugins.myItems);
|
||||
openmct.install(openmct.plugins.localStorage);
|
||||
openmct.install(openmct.plugins.espresso);
|
||||
openmct.install(openmct.plugins.MyItems());
|
||||
openmct.install(openmct.plugins.LocalStorage());
|
||||
openmct.install(openmct.plugins.Espresso());
|
||||
openmct.install(openmct.plugins.Generator());
|
||||
openmct.install(openmct.plugins.UTCTimeSystem());
|
||||
openmct.install(DictionaryPlugin());
|
||||
openmct.install(RealtimeTelemetryPlugin());
|
||||
openmct.install(HistoricalTelemetryPlugin());
|
||||
openmct.start();
|
||||
});
|
||||
</script>
|
||||
|
||||
1
openmct-tutorial
Submodule
1
openmct-tutorial
Submodule
Submodule openmct-tutorial added at 7076a15d3a
@@ -84,5 +84,11 @@ define([
|
||||
return new Main().run(defaultRegistry);
|
||||
});
|
||||
|
||||
// For now, install conductor by default
|
||||
openmct.install(openmct.plugins.Conductor({
|
||||
showConductor: false
|
||||
}));
|
||||
|
||||
|
||||
return openmct;
|
||||
});
|
||||
|
||||
@@ -226,7 +226,7 @@ define([
|
||||
"$window"
|
||||
],
|
||||
"group": "windowing",
|
||||
"cssclass": "icon-new-window",
|
||||
"cssClass": "icon-new-window",
|
||||
"priority": "preferred"
|
||||
},
|
||||
{
|
||||
@@ -241,7 +241,7 @@ define([
|
||||
{
|
||||
"key": "items",
|
||||
"name": "Items",
|
||||
"cssclass": "icon-thumbs-strip",
|
||||
"cssClass": "icon-thumbs-strip",
|
||||
"description": "Grid of available items",
|
||||
"template": itemsTemplate,
|
||||
"uses": [
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<div ng-controller="BrowseObjectController" class="abs l-flex-col">
|
||||
<div class="holder flex-elem l-flex-row object-browse-bar">
|
||||
<div class="holder flex-elem l-flex-row object-browse-bar ">
|
||||
<div class="items-select left flex-elem l-flex-row grows">
|
||||
<mct-representation key="'back-arrow'"
|
||||
mct-object="domainObject"
|
||||
@@ -31,18 +31,16 @@
|
||||
</mct-representation>
|
||||
</div>
|
||||
<div class="btn-bar right l-flex-row flex-elem flex-justify-end flex-fixed">
|
||||
<span class="l-object-action-buttons">
|
||||
<mct-representation key="'switcher'"
|
||||
mct-object="domainObject"
|
||||
ng-model="representation">
|
||||
</mct-representation>
|
||||
<!-- Temporarily, on mobile, the action buttons are hidden-->
|
||||
<mct-representation key="'action-group'"
|
||||
mct-object="domainObject"
|
||||
parameters="{ category: 'view-control' }"
|
||||
class="mobile-hide l-object-action-buttons">
|
||||
</mct-representation>
|
||||
</span>
|
||||
<mct-representation key="'switcher'"
|
||||
mct-object="domainObject"
|
||||
ng-model="representation">
|
||||
</mct-representation>
|
||||
<!-- Temporarily, on mobile, the action buttons are hidden-->
|
||||
<mct-representation key="'action-group'"
|
||||
mct-object="domainObject"
|
||||
parameters="{ category: 'view-control' }"
|
||||
class="mobile-hide">
|
||||
</mct-representation>
|
||||
</div>
|
||||
</div>
|
||||
<div class="holder l-flex-col flex-elem grows l-object-wrapper l-controls-visible l-time-controller-visible">
|
||||
|
||||
@@ -28,8 +28,4 @@
|
||||
key="'menu-arrow'"
|
||||
mct-object='domainObject'
|
||||
class="flex-elem context-available-w"></mct-representation>
|
||||
</span>
|
||||
<a class="s-button icon-expand t-btn-view-large"
|
||||
title="View large"
|
||||
mct-trigger-modal>
|
||||
</a>
|
||||
</span>
|
||||
@@ -43,24 +43,24 @@ define([], function () {
|
||||
return context.getParent();
|
||||
}
|
||||
|
||||
function isOrphan(domainObject) {
|
||||
var parent = getParent(domainObject),
|
||||
composition = parent.getModel().composition,
|
||||
id = domainObject.getId();
|
||||
return !composition || (composition.indexOf(id) === -1);
|
||||
}
|
||||
|
||||
function navigateToParent(domainObject) {
|
||||
function preventOrphanNavigation(domainObject) {
|
||||
var parent = getParent(domainObject);
|
||||
return parent.getCapability('action').perform('navigate');
|
||||
parent.useCapability('composition')
|
||||
.then(function (composees) {
|
||||
var isOrphan = composees.every(function (c) {
|
||||
return c.getId() !== domainObject.getId();
|
||||
});
|
||||
if (isOrphan) {
|
||||
parent.getCapability('action').perform('navigate');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function checkNavigation() {
|
||||
var navigatedObject = navigationService.getNavigation();
|
||||
if (navigatedObject.hasCapability('context') &&
|
||||
isOrphan(navigatedObject)) {
|
||||
if (navigatedObject.hasCapability('context')) {
|
||||
if (!navigatedObject.getCapability('editor').isEditContextRoot()) {
|
||||
navigateToParent(navigatedObject);
|
||||
preventOrphanNavigation(navigatedObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,12 +46,12 @@ define(
|
||||
};
|
||||
|
||||
FullscreenAction.prototype.getMetadata = function () {
|
||||
// We override getMetadata, because the icon cssclass and
|
||||
// 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.cssClass = screenfull.isFullscreen ? "icon-fullscreen-expand" : "icon-fullscreen-collapse";
|
||||
metadata.description = screenfull.isFullscreen ?
|
||||
EXIT_FULLSCREEN : ENTER_FULLSCREEN;
|
||||
metadata.group = "windowing";
|
||||
|
||||
@@ -33,7 +33,7 @@ define([
|
||||
mockContext,
|
||||
mockActionCapability,
|
||||
mockEditor,
|
||||
testParentModel,
|
||||
testParentComposition,
|
||||
testId,
|
||||
mockThrottledFns;
|
||||
|
||||
@@ -41,7 +41,6 @@ define([
|
||||
testId = 'some-identifier';
|
||||
|
||||
mockThrottledFns = [];
|
||||
testParentModel = {};
|
||||
|
||||
mockTopic = jasmine.createSpy('topic');
|
||||
mockThrottle = jasmine.createSpy('throttle');
|
||||
@@ -55,14 +54,12 @@ define([
|
||||
mockDomainObject = jasmine.createSpyObj('domainObject', [
|
||||
'getId',
|
||||
'getCapability',
|
||||
'getModel',
|
||||
'hasCapability'
|
||||
]);
|
||||
mockParentObject = jasmine.createSpyObj('domainObject', [
|
||||
'getId',
|
||||
'getCapability',
|
||||
'getModel',
|
||||
'hasCapability'
|
||||
'useCapability'
|
||||
]);
|
||||
mockContext = jasmine.createSpyObj('context', ['getParent']);
|
||||
mockActionCapability = jasmine.createSpyObj('action', ['perform']);
|
||||
@@ -75,9 +72,7 @@ define([
|
||||
mockThrottledFns.push(mockThrottledFn);
|
||||
return mockThrottledFn;
|
||||
});
|
||||
mockTopic.andCallFake(function (k) {
|
||||
return k === 'mutation' && mockMutationTopic;
|
||||
});
|
||||
mockTopic.andReturn(mockMutationTopic);
|
||||
mockDomainObject.getId.andReturn(testId);
|
||||
mockDomainObject.getCapability.andCallFake(function (c) {
|
||||
return {
|
||||
@@ -88,12 +83,13 @@ define([
|
||||
mockDomainObject.hasCapability.andCallFake(function (c) {
|
||||
return !!mockDomainObject.getCapability(c);
|
||||
});
|
||||
mockParentObject.getModel.andReturn(testParentModel);
|
||||
mockParentObject.getCapability.andCallFake(function (c) {
|
||||
return {
|
||||
action: mockActionCapability
|
||||
}[c];
|
||||
});
|
||||
testParentComposition = [];
|
||||
mockParentObject.useCapability.andReturn(Promise.resolve(testParentComposition));
|
||||
mockContext.getParent.andReturn(mockParentObject);
|
||||
mockNavigationService.getNavigation.andReturn(mockDomainObject);
|
||||
mockEditor.isEditContextRoot.andReturn(false);
|
||||
@@ -126,7 +122,9 @@ define([
|
||||
var prefix = isOrphan ? "" : "non-";
|
||||
describe("for " + prefix + "orphan objects", function () {
|
||||
beforeEach(function () {
|
||||
testParentModel.composition = isOrphan ? [] : [testId];
|
||||
if (!isOrphan) {
|
||||
testParentComposition.push(mockDomainObject);
|
||||
}
|
||||
});
|
||||
|
||||
[false, true].forEach(function (isEditRoot) {
|
||||
@@ -136,13 +134,31 @@ define([
|
||||
function itNavigatesAsExpected() {
|
||||
if (isOrphan && !isEditRoot) {
|
||||
it("navigates to the parent", function () {
|
||||
expect(mockActionCapability.perform)
|
||||
.toHaveBeenCalledWith('navigate');
|
||||
var done = false;
|
||||
waitsFor(function () {
|
||||
return done;
|
||||
});
|
||||
setTimeout(function () {
|
||||
done = true;
|
||||
}, 5);
|
||||
runs(function () {
|
||||
expect(mockActionCapability.perform)
|
||||
.toHaveBeenCalledWith('navigate');
|
||||
});
|
||||
});
|
||||
} else {
|
||||
it("does nothing", function () {
|
||||
expect(mockActionCapability.perform)
|
||||
.not.toHaveBeenCalled();
|
||||
var done = false;
|
||||
waitsFor(function () {
|
||||
return done;
|
||||
});
|
||||
setTimeout(function () {
|
||||
done = true;
|
||||
}, 5);
|
||||
runs(function () {
|
||||
expect(mockActionCapability.perform)
|
||||
.not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -157,7 +173,6 @@ define([
|
||||
mockNavigationService.addListener.mostRecentCall
|
||||
.args[0](mockDomainObject);
|
||||
});
|
||||
|
||||
itNavigatesAsExpected();
|
||||
});
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ define(
|
||||
});
|
||||
|
||||
it("provides displayable metadata", function () {
|
||||
expect(action.getMetadata().cssclass).toBeDefined();
|
||||
expect(action.getMetadata().cssClass).toBeDefined();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<div class="abs overlay l-dialog" ng-class="{'delayEntry100ms' : ngModel.delay}">
|
||||
<div class="abs overlay" ng-class="{'delayEntry100ms' : ngModel.delay}">
|
||||
<div class="abs blocker"></div>
|
||||
<div class="abs holder">
|
||||
<a ng-click="ngModel.cancel()"
|
||||
|
||||
@@ -163,7 +163,7 @@ define([
|
||||
],
|
||||
"description": "Edit",
|
||||
"category": "view-control",
|
||||
"cssclass": "major icon-pencil"
|
||||
"cssClass": "major icon-pencil"
|
||||
},
|
||||
{
|
||||
"key": "properties",
|
||||
@@ -172,7 +172,7 @@ define([
|
||||
"view-control"
|
||||
],
|
||||
"implementation": PropertiesAction,
|
||||
"cssclass": "major icon-pencil",
|
||||
"cssClass": "major icon-pencil",
|
||||
"name": "Edit Properties...",
|
||||
"description": "Edit properties of this object.",
|
||||
"depends": [
|
||||
@@ -183,7 +183,7 @@ define([
|
||||
"key": "remove",
|
||||
"category": "contextual",
|
||||
"implementation": RemoveAction,
|
||||
"cssclass": "icon-trash",
|
||||
"cssClass": "icon-trash",
|
||||
"name": "Remove",
|
||||
"description": "Remove this object from its containing object.",
|
||||
"depends": [
|
||||
@@ -195,7 +195,7 @@ define([
|
||||
"category": "save",
|
||||
"implementation": SaveAndStopEditingAction,
|
||||
"name": "Save and Finish Editing",
|
||||
"cssclass": "icon-save labeled",
|
||||
"cssClass": "icon-save labeled",
|
||||
"description": "Save changes made to these objects.",
|
||||
"depends": [
|
||||
"dialogService",
|
||||
@@ -207,7 +207,7 @@ define([
|
||||
"category": "save",
|
||||
"implementation": SaveAction,
|
||||
"name": "Save and Continue Editing",
|
||||
"cssclass": "icon-save labeled",
|
||||
"cssClass": "icon-save labeled",
|
||||
"description": "Save changes made to these objects.",
|
||||
"depends": [
|
||||
"dialogService",
|
||||
@@ -219,7 +219,7 @@ define([
|
||||
"category": "save",
|
||||
"implementation": SaveAsAction,
|
||||
"name": "Save As...",
|
||||
"cssclass": "icon-save labeled",
|
||||
"cssClass": "icon-save labeled",
|
||||
"description": "Save changes made to these objects.",
|
||||
"depends": [
|
||||
"$injector",
|
||||
@@ -237,7 +237,7 @@ define([
|
||||
// Because we use the name as label for edit buttons and mct-control buttons need
|
||||
// the label to be set to undefined in order to not apply the labeled CSS rule.
|
||||
"name": undefined,
|
||||
"cssclass": "icon-x no-label",
|
||||
"cssClass": "icon-x no-label",
|
||||
"description": "Discard changes made to these objects.",
|
||||
"depends": []
|
||||
}
|
||||
|
||||
@@ -25,14 +25,14 @@
|
||||
<li ng-repeat="createAction in createActions" ng-click="createAction.perform()">
|
||||
<a ng-mouseover="representation.activeMetadata = createAction.getMetadata()"
|
||||
ng-mouseleave="representation.activeMetadata = undefined"
|
||||
class="menu-item-a {{ createAction.getMetadata().cssclass }}">
|
||||
class="menu-item-a {{ createAction.getMetadata().cssClass }}">
|
||||
{{createAction.getMetadata().name}}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="pane right menu-item-description">
|
||||
<div class="desc-area icon {{ representation.activeMetadata.cssclass }}"></div>
|
||||
<div class="desc-area icon {{ representation.activeMetadata.cssClass }}"></div>
|
||||
<div class="desc-area title">
|
||||
{{representation.activeMetadata.name}}
|
||||
</div>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
structure="{
|
||||
text: saveActions[0].getMetadata().name,
|
||||
click: actionPerformer(saveActions[0]),
|
||||
cssclass: 'major ' + saveActions[0].getMetadata().cssclass
|
||||
cssClass: 'major ' + saveActions[0].getMetadata().cssClass
|
||||
}">
|
||||
</mct-control>
|
||||
</span>
|
||||
@@ -36,7 +36,7 @@
|
||||
structure="{
|
||||
options: saveActionsAsMenuOptions,
|
||||
click: saveActionMenuClickHandler,
|
||||
cssclass: 'btn-bar right icon-save no-label major'
|
||||
cssClass: 'btn-bar right icon-save no-label major'
|
||||
}">
|
||||
</mct-control>
|
||||
</span>
|
||||
@@ -46,7 +46,7 @@
|
||||
structure="{
|
||||
text: currentAction.getMetadata().name,
|
||||
click: actionPerformer(currentAction),
|
||||
cssclass: currentAction.getMetadata().cssclass
|
||||
cssClass: currentAction.getMetadata().cssClass
|
||||
}">
|
||||
</mct-control>
|
||||
</span>
|
||||
|
||||
@@ -48,9 +48,10 @@ define(
|
||||
* Decorate PersistenceCapability to queue persistence calls when a
|
||||
* transaction is in progress.
|
||||
*/
|
||||
TransactionCapabilityDecorator.prototype.getCapabilities = function (model) {
|
||||
TransactionCapabilityDecorator.prototype.getCapabilities = function () {
|
||||
var self = this,
|
||||
capabilities = this.capabilityService.getCapabilities(model),
|
||||
capabilities = this.capabilityService.getCapabilities
|
||||
.apply(this.capabilityService, arguments),
|
||||
persistenceCapability = capabilities.persistence;
|
||||
|
||||
capabilities.persistence = function (domainObject) {
|
||||
|
||||
@@ -41,7 +41,7 @@ define(
|
||||
return {
|
||||
key: action,
|
||||
name: action.getMetadata().name,
|
||||
cssclass: action.getMetadata().cssclass
|
||||
cssClass: action.getMetadata().cssClass
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ define(
|
||||
function AddAction(type, parent, context, $q, dialogService, policyService) {
|
||||
this.metadata = {
|
||||
key: 'add',
|
||||
cssclass: type.getCssClass(),
|
||||
cssClass: type.getCssClass(),
|
||||
name: type.getName(),
|
||||
type: type.getKey(),
|
||||
description: type.getDescription(),
|
||||
|
||||
@@ -54,8 +54,7 @@ define(
|
||||
AddActionProvider.prototype.getActions = function (actionContext) {
|
||||
var context = actionContext || {},
|
||||
key = context.key,
|
||||
destination = context.domainObject,
|
||||
self = this;
|
||||
destination = context.domainObject;
|
||||
|
||||
// We only provide Add actions, and we need a
|
||||
// domain object to serve as the container for the
|
||||
@@ -66,18 +65,16 @@ define(
|
||||
}
|
||||
|
||||
// Introduce one create action per type
|
||||
return this.typeService.listTypes().filter(function (type) {
|
||||
return self.policyService.allow("creation", type) && self.policyService.allow("composition", destination.getCapability('type'), type);
|
||||
}).map(function (type) {
|
||||
return ['timeline', 'activity'].map(function (type) {
|
||||
return new AddAction(
|
||||
type,
|
||||
this.typeService.getType(type),
|
||||
destination,
|
||||
context,
|
||||
self.$q,
|
||||
self.dialogService,
|
||||
self.policyService
|
||||
this.$q,
|
||||
this.dialogService,
|
||||
this.policyService
|
||||
);
|
||||
});
|
||||
}, this);
|
||||
};
|
||||
|
||||
return AddActionProvider;
|
||||
|
||||
@@ -47,7 +47,7 @@ define(
|
||||
function CreateAction(type, parent, context) {
|
||||
this.metadata = {
|
||||
key: 'create',
|
||||
cssclass: type.getCssClass(),
|
||||
cssClass: type.getCssClass(),
|
||||
name: type.getName(),
|
||||
type: type.getKey(),
|
||||
description: type.getDescription(),
|
||||
|
||||
@@ -56,16 +56,16 @@ define(
|
||||
*/
|
||||
CreateWizard.prototype.getFormStructure = function (includeLocation) {
|
||||
var sections = [],
|
||||
type = this.type,
|
||||
domainObject = this.domainObject,
|
||||
policyService = this.policyService;
|
||||
|
||||
function validateLocation(locatingObject) {
|
||||
var locatingType = locatingObject &&
|
||||
locatingObject.getCapability('type');
|
||||
return locatingType && policyService.allow(
|
||||
function validateLocation(parent) {
|
||||
var parentType = parent &&
|
||||
parent.getCapability('type');
|
||||
return parentType && policyService.allow(
|
||||
"composition",
|
||||
locatingType,
|
||||
type
|
||||
parentType,
|
||||
domainObject
|
||||
);
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ define(
|
||||
if (includeLocation) {
|
||||
sections.push({
|
||||
name: 'Location',
|
||||
cssclass: "grows",
|
||||
cssClass: "grows",
|
||||
rows: [{
|
||||
name: "Save In",
|
||||
control: "locator",
|
||||
|
||||
@@ -28,7 +28,7 @@ define(
|
||||
describe("The Edit Action controller", function () {
|
||||
var mockSaveActionMetadata = {
|
||||
name: "mocked-save-action",
|
||||
cssclass: "mocked-save-action-css"
|
||||
cssClass: "mocked-save-action-css"
|
||||
};
|
||||
|
||||
function fakeGetActions(actionContext) {
|
||||
@@ -86,7 +86,7 @@ define(
|
||||
expect(menuOptions[1].key).toEqual(mockScope.saveActions[1]);
|
||||
menuOptions.forEach(function (option) {
|
||||
expect(option.name).toEqual(mockSaveActionMetadata.name);
|
||||
expect(option.cssclass).toEqual(mockSaveActionMetadata.cssclass);
|
||||
expect(option.cssClass).toEqual(mockSaveActionMetadata.cssClass);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -31,9 +31,7 @@ define(
|
||||
var mockTypeService,
|
||||
mockDialogService,
|
||||
mockPolicyService,
|
||||
mockCreationPolicy,
|
||||
mockCompositionPolicy,
|
||||
mockPolicyMap = {},
|
||||
mockTypeMap,
|
||||
mockTypes,
|
||||
mockDomainObject,
|
||||
mockQ,
|
||||
@@ -55,49 +53,33 @@ define(
|
||||
);
|
||||
mockType.hasFeature.andReturn(true);
|
||||
mockType.getName.andReturn(name);
|
||||
mockType.getKey.andReturn(name);
|
||||
return mockType;
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
mockTypeService = jasmine.createSpyObj(
|
||||
"typeService",
|
||||
["listTypes"]
|
||||
);
|
||||
mockDialogService = jasmine.createSpyObj(
|
||||
"dialogService",
|
||||
["getUserInput"]
|
||||
);
|
||||
mockPolicyService = jasmine.createSpyObj(
|
||||
"policyService",
|
||||
["allow"]
|
||||
["getType"]
|
||||
);
|
||||
mockDialogService = {};
|
||||
mockPolicyService = {};
|
||||
mockDomainObject = {};
|
||||
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
"domainObject",
|
||||
["getCapability"]
|
||||
);
|
||||
|
||||
//Mocking getCapability because AddActionProvider uses the
|
||||
// type capability of the destination object.
|
||||
mockDomainObject.getCapability.andReturn({});
|
||||
|
||||
mockTypes = ["A", "B", "C"].map(createMockType);
|
||||
mockTypes = [
|
||||
"timeline",
|
||||
"activity",
|
||||
"other"
|
||||
].map(createMockType);
|
||||
mockTypeMap = {};
|
||||
|
||||
mockTypes.forEach(function (type) {
|
||||
mockPolicyMap[type.getName()] = true;
|
||||
mockTypeMap[type.getKey()] = type;
|
||||
});
|
||||
|
||||
mockCreationPolicy = function (type) {
|
||||
return mockPolicyMap[type.getName()];
|
||||
};
|
||||
|
||||
mockCompositionPolicy = function () {
|
||||
return true;
|
||||
};
|
||||
|
||||
mockPolicyService.allow.andReturn(true);
|
||||
|
||||
mockTypeService.listTypes.andReturn(mockTypes);
|
||||
mockTypeService.getType.andCallFake(function (key) {
|
||||
return mockTypeMap[key];
|
||||
});
|
||||
|
||||
provider = new AddActionProvider(
|
||||
mockQ,
|
||||
@@ -107,29 +89,16 @@ define(
|
||||
);
|
||||
});
|
||||
|
||||
it("checks for creatability", function () {
|
||||
provider.getActions({
|
||||
it("provides actions for timeline and activity", function () {
|
||||
var actions = provider.getActions({
|
||||
key: "add",
|
||||
domainObject: mockDomainObject
|
||||
});
|
||||
expect(actions.length).toBe(2);
|
||||
expect(actions[0].metadata.type).toBe('timeline');
|
||||
expect(actions[1].metadata.type).toBe('activity');
|
||||
|
||||
// Make sure it was creation which was used to check
|
||||
expect(mockPolicyService.allow)
|
||||
.toHaveBeenCalledWith("creation", mockTypes[0]);
|
||||
});
|
||||
|
||||
it("checks for composability of type", function () {
|
||||
provider.getActions({
|
||||
key: "add",
|
||||
domainObject: mockDomainObject
|
||||
});
|
||||
|
||||
expect(mockPolicyService.allow).toHaveBeenCalledWith(
|
||||
"composition",
|
||||
jasmine.any(Object),
|
||||
jasmine.any(Object)
|
||||
);
|
||||
|
||||
expect(mockDomainObject.getCapability).toHaveBeenCalledWith('type');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ define(
|
||||
|
||||
expect(metadata.name).toEqual("Test");
|
||||
expect(metadata.description).toEqual("a test type");
|
||||
expect(metadata.cssclass).toEqual("icon-telemetry");
|
||||
expect(metadata.cssClass).toEqual("icon-telemetry");
|
||||
});
|
||||
|
||||
describe("the perform function", function () {
|
||||
|
||||
@@ -175,7 +175,7 @@ define(
|
||||
expect(mockPolicyService.allow).toHaveBeenCalledWith(
|
||||
'composition',
|
||||
mockOtherType,
|
||||
mockType
|
||||
mockDomainObject
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"metadata": {
|
||||
"name": "openmct-symbols-16px",
|
||||
"lastOpened": 1487197651675,
|
||||
"created": 1487194069058
|
||||
"lastOpened": 1481575258437,
|
||||
"created": 1481575255265
|
||||
},
|
||||
"iconSets": [
|
||||
{
|
||||
@@ -540,21 +540,13 @@
|
||||
"code": 921654,
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 120,
|
||||
"id": 105,
|
||||
"name": "icon-reset",
|
||||
"prevSize": 24,
|
||||
"code": 921655,
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 121,
|
||||
"id": 103,
|
||||
"name": "icon-x-in-circle",
|
||||
"prevSize": 24,
|
||||
"code": 921656,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 118,
|
||||
@@ -562,7 +554,7 @@
|
||||
"name": "icon-brightness",
|
||||
"prevSize": 24,
|
||||
"code": 921657,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 119,
|
||||
@@ -570,15 +562,15 @@
|
||||
"name": "icon-contrast",
|
||||
"prevSize": 24,
|
||||
"code": 921664,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 122,
|
||||
"id": 106,
|
||||
"name": "icon-expand",
|
||||
"order": 120,
|
||||
"id": 105,
|
||||
"name": "icon-reset",
|
||||
"prevSize": 24,
|
||||
"code": 921665,
|
||||
"tempChar": ""
|
||||
"code": 921655,
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 37,
|
||||
@@ -586,7 +578,7 @@
|
||||
"name": "icon-activity",
|
||||
"id": 32,
|
||||
"code": 921856,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 36,
|
||||
@@ -594,7 +586,7 @@
|
||||
"name": "icon-activity-mode",
|
||||
"id": 31,
|
||||
"code": 921857,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 52,
|
||||
@@ -602,7 +594,7 @@
|
||||
"name": "icon-autoflow-tabular",
|
||||
"id": 47,
|
||||
"code": 921858,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 55,
|
||||
@@ -610,7 +602,7 @@
|
||||
"name": "icon-clock",
|
||||
"id": 50,
|
||||
"code": 921859,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 58,
|
||||
@@ -618,7 +610,7 @@
|
||||
"name": "icon-database",
|
||||
"id": 53,
|
||||
"code": 921860,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 57,
|
||||
@@ -626,7 +618,7 @@
|
||||
"name": "icon-database-query",
|
||||
"id": 52,
|
||||
"code": 921861,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 17,
|
||||
@@ -634,7 +626,7 @@
|
||||
"name": "icon-dataset",
|
||||
"id": 12,
|
||||
"code": 921862,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 22,
|
||||
@@ -642,7 +634,7 @@
|
||||
"name": "icon-datatable",
|
||||
"id": 17,
|
||||
"code": 921863,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 59,
|
||||
@@ -650,7 +642,7 @@
|
||||
"name": "icon-dictionary",
|
||||
"id": 54,
|
||||
"code": 921864,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 62,
|
||||
@@ -658,7 +650,7 @@
|
||||
"name": "icon-folder",
|
||||
"id": 57,
|
||||
"code": 921865,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 66,
|
||||
@@ -666,7 +658,7 @@
|
||||
"name": "icon-image",
|
||||
"id": 61,
|
||||
"code": 921872,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 68,
|
||||
@@ -674,7 +666,7 @@
|
||||
"name": "icon-layout",
|
||||
"id": 63,
|
||||
"code": 921873,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 77,
|
||||
@@ -682,7 +674,7 @@
|
||||
"name": "icon-object",
|
||||
"id": 72,
|
||||
"code": 921874,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 78,
|
||||
@@ -690,7 +682,7 @@
|
||||
"name": "icon-object-unknown",
|
||||
"id": 73,
|
||||
"code": 921875,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 79,
|
||||
@@ -698,7 +690,7 @@
|
||||
"name": "icon-packet",
|
||||
"id": 74,
|
||||
"code": 921876,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 80,
|
||||
@@ -706,7 +698,7 @@
|
||||
"name": "icon-page",
|
||||
"id": 75,
|
||||
"code": 921877,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 114,
|
||||
@@ -714,7 +706,7 @@
|
||||
"name": "icon-plot-overlay",
|
||||
"prevSize": 24,
|
||||
"code": 921878,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 113,
|
||||
@@ -722,7 +714,7 @@
|
||||
"name": "icon-plot-stacked",
|
||||
"prevSize": 24,
|
||||
"code": 921879,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 10,
|
||||
@@ -730,7 +722,7 @@
|
||||
"name": "icon-session",
|
||||
"id": 5,
|
||||
"code": 921880,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 24,
|
||||
@@ -738,7 +730,7 @@
|
||||
"name": "icon-tabular",
|
||||
"id": 19,
|
||||
"code": 921881,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 7,
|
||||
@@ -746,7 +738,7 @@
|
||||
"name": "icon-tabular-lad",
|
||||
"id": 2,
|
||||
"code": 921888,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 6,
|
||||
@@ -754,7 +746,7 @@
|
||||
"name": "icon-tabular-lad-set",
|
||||
"id": 1,
|
||||
"code": 921889,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 8,
|
||||
@@ -762,7 +754,7 @@
|
||||
"name": "icon-tabular-realtime",
|
||||
"id": 3,
|
||||
"code": 921890,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 23,
|
||||
@@ -770,7 +762,7 @@
|
||||
"name": "icon-tabular-scrolling",
|
||||
"id": 18,
|
||||
"code": 921891,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 112,
|
||||
@@ -778,7 +770,7 @@
|
||||
"name": "icon-telemetry",
|
||||
"id": 86,
|
||||
"code": 921892,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 90,
|
||||
@@ -786,7 +778,7 @@
|
||||
"name": "icon-telemetry-panel",
|
||||
"id": 85,
|
||||
"code": 921893,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 93,
|
||||
@@ -794,7 +786,7 @@
|
||||
"name": "icon-timeline",
|
||||
"id": 88,
|
||||
"code": 921894,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 116,
|
||||
@@ -802,7 +794,7 @@
|
||||
"name": "icon-timer-v1.5",
|
||||
"prevSize": 24,
|
||||
"code": 921895,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 11,
|
||||
@@ -810,7 +802,7 @@
|
||||
"name": "icon-topic",
|
||||
"id": 6,
|
||||
"code": 921896,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 115,
|
||||
@@ -818,7 +810,7 @@
|
||||
"name": "icon-box-with-dashed-lines",
|
||||
"id": 29,
|
||||
"code": 921897,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
@@ -2191,30 +2183,6 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 104,
|
||||
"paths": [
|
||||
"M460.8 460.8l-187.8-187.8c57.2-42.8 128-68.2 204.8-68.2 188.2 0 341.6 153.2 341.6 341.4s-153.2 341.2-341.4 341.2c-165 0-302.8-117.6-334.6-273h-138.4c14.2 101.8 61 195.6 135 269.6 90.2 90.2 210.4 140 338 140s247.6-49.8 338-140 140-210.4 140-338-49.8-247.6-140-338-210.4-140-338-140c-111.4 0-217 38-302 107.6l-176-175.6v460.8h460.8z"
|
||||
],
|
||||
"attrs": [
|
||||
{
|
||||
"fill": "rgb(0, 161, 75)"
|
||||
}
|
||||
],
|
||||
"isMulticolor": false,
|
||||
"isMulticolor2": false,
|
||||
"grid": 16,
|
||||
"tags": [
|
||||
"icon-reset"
|
||||
],
|
||||
"colorPermutations": {
|
||||
"1161751207457516161751": [
|
||||
{
|
||||
"f": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"paths": [
|
||||
"M512 0c-282.8 0-512 229.2-512 512s229.2 512 512 512 512-229.2 512-512-229.2-512-512-512zM832 704l-128 128-192-192-192 192-128-128 192-192-192-192 128-128 192 192 192-192 128 128-192 192 192 192z"
|
||||
@@ -2335,31 +2303,26 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 106,
|
||||
"id": 104,
|
||||
"paths": [
|
||||
"M960 0c0 0 0 0 0 0h-320v128h165.4l-210.6 210.8c-25 25-25 65.6 0 90.6 12.4 12.4 28.8 18.8 45.2 18.8s32.8-6.2 45.2-18.8l210.8-210.8v165.4h128v-384h-64z",
|
||||
"M896 805.4l-210.8-210.6c-25-25-65.6-25-90.6 0s-25 65.6 0 90.6l210.8 210.6h-165.4v128h384v-384h-128v165.4z",
|
||||
"M218.6 128h165.4v-128h-320c0 0 0 0 0 0h-64v384h128v-165.4l210.8 210.8c12.4 12.4 28.8 18.8 45.2 18.8s32.8-6.2 45.2-18.8c25-25 25-65.6 0-90.6l-210.6-210.8z",
|
||||
"M338.8 594.8l-210.8 210.6v-165.4h-128v384h384v-128h-165.4l210.8-210.8c25-25 25-65.6 0-90.6-25.2-24.8-65.6-24.8-90.6 0.2z"
|
||||
"M460.8 460.8l-187.8-187.8c57.2-42.8 128-68.2 204.8-68.2 188.2 0 341.6 153.2 341.6 341.4s-153.2 341.2-341.4 341.2c-165 0-302.8-117.6-334.6-273h-138.4c14.2 101.8 61 195.6 135 269.6 90.2 90.2 210.4 140 338 140s247.6-49.8 338-140 140-210.4 140-338-49.8-247.6-140-338-210.4-140-338-140c-111.4 0-217 38-302 107.6l-176-175.6v460.8h460.8z"
|
||||
],
|
||||
"attrs": [
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
],
|
||||
"grid": 16,
|
||||
"tags": [
|
||||
"icon-expand"
|
||||
{
|
||||
"fill": "rgb(0, 161, 75)"
|
||||
}
|
||||
],
|
||||
"isMulticolor": false,
|
||||
"isMulticolor2": false,
|
||||
"grid": 16,
|
||||
"tags": [
|
||||
"icon-reset"
|
||||
],
|
||||
"colorPermutations": {
|
||||
"1161751207457516161751": [
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
{
|
||||
"f": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
Binary file not shown.
@@ -77,7 +77,6 @@
|
||||
<glyph unicode="󡀸" glyph-name="icon-x-in-circle" d="M512 960c-282.8 0-512-229.2-512-512s229.2-512 512-512 512 229.2 512 512-229.2 512-512 512zM832 256l-128-128-192 192-192-192-128 128 192 192-192 192 128 128 192-192 192 192 128-128-192-192 192-192z" />
|
||||
<glyph unicode="󡀹" glyph-name="icon-brightness" d="M253.414 641.939l-155.172 116.384c-50.233-66.209-85.127-146.713-97.91-234.39l191.586-30.216c8.145 56.552 29.998 106.879 62.068 149.006zM191.98 402.283l-191.919-27.434c13.115-90.459 48.009-170.963 99.174-238.453l154.18 117.665c-31.476 41.347-53.309 91.675-61.231 146.504zM466.283 768.020l-27.434 191.919c-90.459-13.115-170.963-48.009-238.453-99.174l117.665-154.18c41.347 31.476 91.675 53.309 146.504 61.231zM822.323 861.758c-66.209 50.233-146.713 85.127-234.39 97.91l-30.216-191.586c56.552-8.145 106.879-29.998 149.006-62.068zM832.020 493.717l191.919 27.434c-13.115 90.459-48.009 170.963-99.174 238.453l-154.18-117.665c31.476-41.347 53.309-91.675 61.231-146.504zM201.677 34.242c66.209-50.233 146.713-85.127 234.39-97.91l30.216 191.586c-56.552 8.145-106.879 29.998-149.006 62.068zM770.586 254.061l155.131-116.343c50.233 66.209 85.127 146.713 97.91 234.39l-191.586 30.216c-8.125-56.564-29.966-106.906-62.028-149.049zM557.717 127.98l27.434-191.919c90.459 13.115 170.963 48.009 238.453 99.174l-117.665 154.18c-41.347-31.476-91.675-53.309-146.504-61.231zM770.586 448c0-142.813-115.773-258.586-258.586-258.586s-258.586 115.773-258.586 258.586c0 142.813 115.773 258.586 258.586 258.586s258.586-115.773 258.586-258.586z" />
|
||||
<glyph unicode="󡁀" glyph-name="icon-contrast" d="M512 960c-282.78 0-512-229.24-512-512s229.22-512 512-512 512 229.24 512 512-229.22 512-512 512zM783.52 176.48c-69.111-69.481-164.785-112.481-270.502-112.481-0.358 0-0.716 0-1.074 0.001l0.055 768c212.070-0.010 383.982-171.929 383.982-384 0-106.034-42.977-202.031-112.462-271.52z" />
|
||||
<glyph unicode="󡁁" glyph-name="icon-expand" d="M960 960c0 0 0 0 0 0h-320v-128h165.4l-210.6-210.8c-25-25-25-65.6 0-90.6 12.4-12.4 28.8-18.8 45.2-18.8s32.8 6.2 45.2 18.8l210.8 210.8v-165.4h128v384h-64zM896 154.6l-210.8 210.6c-25 25-65.6 25-90.6 0s-25-65.6 0-90.6l210.8-210.6h-165.4v-128h384v384h-128v-165.4zM218.6 832h165.4v128h-320c0 0 0 0 0 0h-64v-384h128v165.4l210.8-210.8c12.4-12.4 28.8-18.8 45.2-18.8s32.8 6.2 45.2 18.8c25 25 25 65.6 0 90.6l-210.6 210.8zM338.8 365.2l-210.8-210.6v165.4h-128v-384h384v128h-165.4l210.8 210.8c25 25 25 65.6 0 90.6-25.2 24.8-65.6 24.8-90.6-0.2z" />
|
||||
<glyph unicode="󡄀" glyph-name="icon-activity" d="M576 896h-256l320-320h-290.256c-44.264 76.516-126.99 128-221.744 128h-128v-512h128c94.754 0 177.48 51.484 221.744 128h290.256l-320-320h256l448 448-448 448z" />
|
||||
<glyph unicode="󡄁" glyph-name="icon-activity-mode" d="M512 960c-214.866 0-398.786-132.372-474.744-320h90.744c56.86 0 107.938-24.724 143.094-64h240.906l-192 192h256l320-320-320-320h-256l192 192h-240.906c-35.156-39.276-86.234-64-143.094-64h-90.744c75.958-187.628 259.878-320 474.744-320 282.77 0 512 229.23 512 512s-229.23 512-512 512z" />
|
||||
<glyph unicode="󡄂" glyph-name="icon-autoflow-tabular" d="M192 960c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h64v1024h-64zM384 960h256v-1024h-256v1024zM832 960h-64v-704h256v512c0 105.6-86.4 192-192 192z" />
|
||||
|
||||
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 39 KiB |
Binary file not shown.
Binary file not shown.
@@ -66,7 +66,7 @@ body, html {
|
||||
color: $colorBodyFg;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-size: 100%;
|
||||
font-weight: normal;
|
||||
font-weight: 200;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -73,11 +73,10 @@ $glyph-icon-thumbs-strip: '\e1033';
|
||||
$glyph-icon-two-parts-both: '\e1034';
|
||||
$glyph-icon-two-parts-one-only: '\e1035';
|
||||
$glyph-icon-resync: '\e1036';
|
||||
$glyph-icon-reset: '\e1037';
|
||||
$glyph-icon-x-in-circle: '\e1038';
|
||||
$glyph-icon-brightness: '\e1039';
|
||||
$glyph-icon-contrast: '\e1040';
|
||||
$glyph-icon-expand: '\e1041';
|
||||
$glyph-icon-reset: '\e1037';
|
||||
$glyph-icon-activity: '\e1100';
|
||||
$glyph-icon-activity-mode: '\e1101';
|
||||
$glyph-icon-autoflow-tabular: '\e1102';
|
||||
@@ -176,12 +175,11 @@ $glyph-icon-box-with-dashed-lines: '\e1129';
|
||||
.icon-thumbs-strip { @include glyph($glyph-icon-thumbs-strip); }
|
||||
.icon-two-parts-both { @include glyph($glyph-icon-two-parts-both); }
|
||||
.icon-two-parts-one-only { @include glyph($glyph-icon-two-parts-one-only); }
|
||||
.icon-resync { @include glyph($glyph-icon-resync); }
|
||||
.icon-reset { @include glyph($glyph-icon-reset); }
|
||||
.icon-x-in-circle { @include glyph($glyph-icon-x-in-circle); }
|
||||
.icon-brightness { @include glyph($glyph-icon-brightness); }
|
||||
.icon-contrast { @include glyph($glyph-icon-contrast); }
|
||||
.icon-expand { @include glyph($glyph-icon-expand); }
|
||||
.icon-reset { @include glyph($glyph-icon-reset); }
|
||||
.icon-resync { @include glyph($glyph-icon-resync); }
|
||||
.icon-activity { @include glyph($glyph-icon-activity); }
|
||||
.icon-activity-mode { @include glyph($glyph-icon-activity-mode); }
|
||||
.icon-autoflow-tabular { @include glyph($glyph-icon-autoflow-tabular); }
|
||||
|
||||
@@ -631,8 +631,7 @@ textarea {
|
||||
}
|
||||
}
|
||||
|
||||
.view-switcher,
|
||||
.t-btn-view-large {
|
||||
.view-switcher {
|
||||
@include trans-prop-nice-fade($controlFadeMs);
|
||||
}
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@
|
||||
.context-menu-holder,
|
||||
.menu-holder {
|
||||
position: absolute;
|
||||
z-index: 120;
|
||||
z-index: 70;
|
||||
.context-menu-wrapper {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
@@ -273,7 +273,7 @@
|
||||
|
||||
.btn-bar.right .menu,
|
||||
.menus-to-left .menu {
|
||||
z-index: 79;
|
||||
z-index: 79;
|
||||
left: auto;
|
||||
right: 0;
|
||||
width: auto;
|
||||
|
||||
@@ -21,16 +21,11 @@
|
||||
*****************************************************************************/
|
||||
|
||||
.overlay {
|
||||
font-size: 90%;
|
||||
&.delayEntry100ms {
|
||||
@include keyframes(fadeInFromNone) {
|
||||
0% {
|
||||
display: none;
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
}
|
||||
0% { display: none; opacity: 0; }
|
||||
100% { display: block; opacity: 1; }
|
||||
}
|
||||
@include animation-delay($delayEntryMs);
|
||||
@include animation(fadeInFromNone $durEntryMs ease-in);
|
||||
@@ -48,13 +43,17 @@
|
||||
left: auto;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
> .holder {
|
||||
@include containerSubtle($colorOvrBg, $colorOvrFg);
|
||||
border-radius: $basicCr * 3;
|
||||
color: $colorOvrFg;
|
||||
top: 50%;
|
||||
right: auto;
|
||||
bottom: auto;
|
||||
left: 50%;
|
||||
@include transform(translateX(-50%) translateY(-50%));
|
||||
height: 70%;
|
||||
width: 50%;
|
||||
min-height: 300px;
|
||||
min-width: 600px;
|
||||
z-index: 101;
|
||||
@@ -66,106 +65,72 @@
|
||||
left: $m;
|
||||
}
|
||||
}
|
||||
}
|
||||
.title {
|
||||
@include ellipsize();
|
||||
font-size: 1.2em;
|
||||
line-height: 120%;
|
||||
margin-bottom: $interiorMargin;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
&.l-dialog {
|
||||
.s-button {
|
||||
&:not(.major) {
|
||||
@include btnSubtle($bg: $colorOvrBtnBg, $bgHov: pullForward($colorOvrBtnBg, 10%), $fg: $colorOvrBtnFg, $fgHov: $colorOvrBtnFg, $ic: $colorOvrBtnFg, $icHov: $colorOvrBtnFg);
|
||||
.hint, .field-hints { color: $colorFieldHintOverlay !important; }
|
||||
|
||||
.abs.top-bar {
|
||||
height: $ovrTopBarH;
|
||||
}
|
||||
|
||||
.abs.editor,
|
||||
.abs.message-body {
|
||||
top: $ovrTopBarH + $interiorMarginLg;
|
||||
bottom: $ovrFooterH + $interiorMarginLg;
|
||||
left: 0;
|
||||
right: 0;
|
||||
overflow: auto;
|
||||
.field.l-input-med {
|
||||
input[type='text'] {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
> .holder {
|
||||
@include containerSubtle($colorOvrBg, $colorOvrFg);
|
||||
border-radius: $basicCr * 2;
|
||||
//color: $colorOvrFg;
|
||||
height: 70%;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.title {
|
||||
@include ellipsize();
|
||||
font-size: 1.2em;
|
||||
line-height: 120%;
|
||||
margin-bottom: $interiorMargin;
|
||||
}
|
||||
|
||||
.hint, .field-hints {
|
||||
color: $colorFieldHintOverlay !important;
|
||||
}
|
||||
|
||||
.abs.top-bar {
|
||||
height: $ovrTopBarH;
|
||||
}
|
||||
|
||||
.abs.bottom-bar {
|
||||
top: auto;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow: visible;
|
||||
height: $ovrFooterH;
|
||||
}
|
||||
|
||||
.abs.editor,
|
||||
.abs.message-body {
|
||||
top: $ovrTopBarH + $interiorMarginLg;
|
||||
bottom: $ovrFooterH + $interiorMarginLg;
|
||||
left: 0;
|
||||
right: 0;
|
||||
overflow: auto;
|
||||
.field.l-input-med {
|
||||
input[type='text'] {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-bar {
|
||||
text-align: right;
|
||||
.s-button {
|
||||
font-size: 95%;
|
||||
height: $ovrFooterH;
|
||||
line-height: $ovrFooterH;
|
||||
margin-left: $interiorMargin;
|
||||
padding: 0 $interiorMargin * 3;
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.l-progress-bar {
|
||||
$h: $progressBarHOverlay;
|
||||
display: block;
|
||||
height: $h;
|
||||
line-height: $h;
|
||||
margin: .5em 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.select {
|
||||
box-shadow: $shdwBtnsOverlay;
|
||||
}
|
||||
}
|
||||
|
||||
&.l-large-view {
|
||||
> .holder {
|
||||
@include keyframes(overlayIn) {
|
||||
from { opacity: 0; width: 1%; height: 1%; }
|
||||
to { opacity: 1; width: 90%; height: 90%; }
|
||||
.bottom-bar {
|
||||
text-align: right;
|
||||
.s-button {
|
||||
$bg: $colorOvrBtnBg;
|
||||
&:not(.major) {
|
||||
@include btnSubtle($bg, pullForward($bg, 10%), $colorOvrBtnFg, $colorOvrBtnFg);
|
||||
}
|
||||
@include animToParams(overlayIn, $dur: 1s, $delay: 0);
|
||||
background: $colorBodyBg;
|
||||
border-radius: $basicCr * 2;
|
||||
//height: 90%;
|
||||
//width: 90%;
|
||||
|
||||
.t-btn-view-large {
|
||||
display: none;
|
||||
font-size: 95%;
|
||||
height: $ovrFooterH;
|
||||
line-height: $ovrFooterH;
|
||||
margin-left: $interiorMargin;
|
||||
padding: 0 $interiorMargin * 3;
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.abs.bottom-bar {
|
||||
top: auto;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow: visible;
|
||||
height: $ovrFooterH;
|
||||
}
|
||||
|
||||
.l-progress-bar {
|
||||
$h: $progressBarHOverlay;
|
||||
display: block;
|
||||
height: $h;
|
||||
line-height: $h;
|
||||
margin: .5em 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.select {
|
||||
box-shadow: $shdwBtnsOverlay;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
$output-bourbon-deprecation-warnings: false;
|
||||
@import "bourbon";
|
||||
@import "logo-and-bg";
|
||||
|
||||
|
||||
@@ -20,77 +20,69 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
.frame {
|
||||
$ohH: $btnFrameH;
|
||||
$bc: $colorInteriorBorder;
|
||||
&.child-frame.panel {
|
||||
background: $colorBodyBg;
|
||||
border: 1px solid $bc;
|
||||
$ohH: $btnFrameH;
|
||||
$bc: $colorInteriorBorder;
|
||||
&.child-frame.panel {
|
||||
background: $colorBodyBg;
|
||||
border: 1px solid $bc;
|
||||
z-index: 0; // Needed to prevent child-frame controls from showing through when another child-frame is above
|
||||
&:hover {
|
||||
border-color: lighten($bc, 10%);
|
||||
&:hover {
|
||||
border-color: lighten($bc, 10%);
|
||||
}
|
||||
}
|
||||
.object-top-bar {
|
||||
font-size: 0.75em;
|
||||
height: $ohH;
|
||||
line-height: $ohH;
|
||||
.left {
|
||||
padding-right: $interiorMarginLg;
|
||||
}
|
||||
}
|
||||
.object-browse-bar {
|
||||
font-size: 0.75em;
|
||||
height: $ohH;
|
||||
line-height: $ohH;
|
||||
}
|
||||
|
||||
> .object-holder.abs {
|
||||
top: $ohH + $interiorMargin;
|
||||
}
|
||||
.contents {
|
||||
$myM: $interiorMargin;
|
||||
top: $myM;
|
||||
right: $myM;
|
||||
bottom: $myM;
|
||||
left: $myM;
|
||||
}
|
||||
&.frame-template {
|
||||
.s-button,
|
||||
.s-menu-button {
|
||||
height: $ohH;
|
||||
line-height: $ohH;
|
||||
padding: 0 $interiorMargin;
|
||||
> span,
|
||||
}
|
||||
>.object-holder.abs {
|
||||
top: $ohH + $interiorMargin;
|
||||
}
|
||||
.contents {
|
||||
$myM: $interiorMargin;
|
||||
top: $myM;
|
||||
right: $myM;
|
||||
bottom: $myM;
|
||||
left: $myM;
|
||||
}
|
||||
&.frame-template {
|
||||
.s-button,
|
||||
.s-menu-button {
|
||||
height: $ohH;
|
||||
line-height: $ohH;
|
||||
padding: 0 $interiorMargin;
|
||||
> span,
|
||||
&:before {
|
||||
font-size: 0.65rem;
|
||||
}
|
||||
}
|
||||
font-size: 0.65rem;
|
||||
}
|
||||
}
|
||||
|
||||
.s-menu-button:after {
|
||||
font-size: 8px;
|
||||
}
|
||||
.s-menu-button:after {
|
||||
font-size: 8px;
|
||||
}
|
||||
|
||||
.view-switcher {
|
||||
z-index: 10;
|
||||
}
|
||||
}
|
||||
.view-switcher {
|
||||
margin-left: $interiorMargin; // Kick other top bar elements away when I'm present.
|
||||
// Hide the name when the view switcher is in a frame context
|
||||
.title-label {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.view-switcher {
|
||||
z-index: 10;
|
||||
}
|
||||
}
|
||||
.view-switcher {
|
||||
// Hide the name when the view switcher is in a frame context
|
||||
.title-label {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
body.desktop .frame {
|
||||
// Hide local controls initially and show it them on hover when they're in an element that's in a frame context
|
||||
// Frame template is used because we need to target the lowest nested frame
|
||||
.view-switcher,
|
||||
.t-btn-view-large {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
// Target the first descendant so that we only show the elements in the outermost container.
|
||||
// Handles the case where we have layouts in layouts.
|
||||
&:hover > .object-browse-bar {
|
||||
.view-switcher,
|
||||
.t-btn-view-large {
|
||||
opacity: 1;
|
||||
pointer-events: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
body.desktop .frame.frame-template {
|
||||
// Hide the view switcher by default when it's in an element that's in a frame context
|
||||
// Frame template is used because we need to target the lowest nested frame
|
||||
.view-switcher {
|
||||
opacity: 0;
|
||||
}
|
||||
&:hover .view-switcher {
|
||||
// Show the view switcher on frame hover
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@@ -136,6 +136,14 @@
|
||||
.mini-tab-icon.toggle-pane {
|
||||
z-index: 5;
|
||||
}
|
||||
&.items {
|
||||
.object-browse-bar {
|
||||
.left.abs,
|
||||
.right.abs {
|
||||
top: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
body.desktop .pane .mini-tab-icon.toggle-pane {
|
||||
@@ -242,9 +250,10 @@ body.desktop .pane .mini-tab-icon.toggle-pane {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.object-browse-bar {
|
||||
.l-object-action-buttons {
|
||||
margin-left: $interiorMarginLg; // Kick the view switcher and other elements away
|
||||
.object-browse-bar,
|
||||
.top-bar {
|
||||
.view-switcher {
|
||||
margin-right: $interiorMarginLg * 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,6 +265,7 @@ body.desktop .pane .mini-tab-icon.toggle-pane {
|
||||
white-space: nowrap;
|
||||
|
||||
.left {
|
||||
padding-right: $interiorMarginLg;
|
||||
.l-back {
|
||||
margin-right: $interiorMarginLg;
|
||||
&.s-status-editing { display: none; }
|
||||
@@ -338,7 +348,7 @@ body.desktop {
|
||||
.pane:not(.resizing) {
|
||||
@include trans-prop-nice-resize-w(250ms);
|
||||
}
|
||||
.pane.primary-pane > .object-browse-bar {
|
||||
.pane.primary-pane .object-browse-bar {
|
||||
min-width: 200px; // Needed for nice display when primary pane is constrained severely via splitters
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<a class="s-button key-{{parameters.action.getMetadata().key}} {{parameters.action.getMetadata().cssclass}}"
|
||||
<a class="s-button key-{{parameters.action.getMetadata().key}} {{parameters.action.getMetadata().cssClass}}"
|
||||
ng-class="{ labeled: parameters.labeled }"
|
||||
title="{{parameters.action.getMetadata().description}}"
|
||||
ng-click="parameters.action.perform()">
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<span ng-controller="ViewSwitcherController">
|
||||
<div class="view-switcher menu-element s-menu-button {{ngModel.selected.cssclass}}"
|
||||
<div class="view-switcher menu-element s-menu-button {{ngModel.selected.cssClass}}"
|
||||
ng-if="view.length > 1"
|
||||
ng-controller="ClickAwayController as toggle">
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<ul>
|
||||
<li ng-repeat="option in view"
|
||||
ng-click="ngModel.selected = option; toggle.setState(false)"
|
||||
class="{{option.cssclass}}">
|
||||
class="{{option.cssClass}}">
|
||||
{{option.name}}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<li ng-repeat="menuAction in menuActions"
|
||||
ng-click="menuAction.perform()"
|
||||
title="{{menuAction.getMetadata().description}}"
|
||||
class="{{menuAction.getMetadata().cssclass}}">
|
||||
class="{{menuAction.getMetadata().cssClass}}">
|
||||
{{menuAction.getMetadata().name}}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
$output-bourbon-deprecation-warnings: false;
|
||||
@import "bourbon";
|
||||
|
||||
@import "../../../../general/res/sass/_mixins";
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
$output-bourbon-deprecation-warnings: false;
|
||||
@import "bourbon";
|
||||
|
||||
@import "../../../../general/res/sass/_mixins";
|
||||
|
||||
@@ -40,9 +40,6 @@ define([
|
||||
{
|
||||
"category": "composition",
|
||||
"implementation": CompositionPolicy,
|
||||
"depends": [
|
||||
"$injector"
|
||||
],
|
||||
"message": "Objects of this type cannot contain objects of that type."
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,77 +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(
|
||||
[],
|
||||
function () {
|
||||
|
||||
/**
|
||||
* Build a table indicating which types are expected to expose
|
||||
* which capabilities. This supports composition policy (rules
|
||||
* for which objects can contain which other objects) which
|
||||
* sometimes is determined based on the presence of capabilities.
|
||||
* @constructor
|
||||
* @memberof platform/containment
|
||||
*/
|
||||
function CapabilityTable(typeService, capabilityService) {
|
||||
var self = this;
|
||||
|
||||
// Build an initial model for a type
|
||||
function buildModel(type) {
|
||||
var model = Object.create(type.getInitialModel() || {});
|
||||
model.type = type.getKey();
|
||||
return model;
|
||||
}
|
||||
|
||||
// Get capabilities expected for this type
|
||||
function getCapabilities(type) {
|
||||
return capabilityService.getCapabilities(buildModel(type));
|
||||
}
|
||||
|
||||
// Populate the lookup table for this type's capabilities
|
||||
function addToTable(type) {
|
||||
var typeKey = type.getKey();
|
||||
Object.keys(getCapabilities(type)).forEach(function (key) {
|
||||
self.table[key] = self.table[key] || {};
|
||||
self.table[key][typeKey] = true;
|
||||
});
|
||||
}
|
||||
|
||||
// Build the table
|
||||
this.table = {};
|
||||
(typeService.listTypes() || []).forEach(addToTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a type is expected to expose a specific capability.
|
||||
* @param {string} typeKey the type identifier
|
||||
* @param {string} capabilityKey the capability identifier
|
||||
* @returns {boolean} true if expected to be exposed
|
||||
*/
|
||||
CapabilityTable.prototype.hasCapability = function (typeKey, capabilityKey) {
|
||||
return (this.table[capabilityKey] || {})[typeKey];
|
||||
};
|
||||
|
||||
return CapabilityTable;
|
||||
}
|
||||
);
|
||||
@@ -45,9 +45,7 @@ define(
|
||||
ComposeActionPolicy.prototype.allowComposition = function (containerObject, selectedObject) {
|
||||
// Get the object types involved in the compose action
|
||||
var containerType = containerObject &&
|
||||
containerObject.getCapability('type'),
|
||||
selectedType = selectedObject &&
|
||||
selectedObject.getCapability('type');
|
||||
containerObject.getCapability('type');
|
||||
|
||||
// Get a reference to the policy service if needed...
|
||||
this.policyService = this.policyService || this.getPolicyService();
|
||||
@@ -57,7 +55,7 @@ define(
|
||||
this.policyService.allow(
|
||||
'composition',
|
||||
containerType,
|
||||
selectedType
|
||||
selectedObject
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
* @namespace platform/containment
|
||||
*/
|
||||
define(
|
||||
['./ContainmentTable'],
|
||||
function (ContainmentTable) {
|
||||
[],
|
||||
function () {
|
||||
|
||||
/**
|
||||
* Defines composition policy as driven by type metadata.
|
||||
@@ -35,21 +35,33 @@ define(
|
||||
* @memberof platform/containment
|
||||
* @implements {Policy.<Type, Type>}
|
||||
*/
|
||||
function CompositionPolicy($injector) {
|
||||
// We're really just wrapping the containment table and rephrasing
|
||||
// it as a policy decision.
|
||||
var table;
|
||||
|
||||
this.getTable = function () {
|
||||
return (table = table || new ContainmentTable(
|
||||
$injector.get('typeService'),
|
||||
$injector.get('capabilityService')
|
||||
));
|
||||
};
|
||||
function CompositionPolicy() {
|
||||
}
|
||||
|
||||
CompositionPolicy.prototype.allow = function (candidate, context) {
|
||||
return this.getTable().canContain(candidate, context);
|
||||
CompositionPolicy.prototype.allow = function (parentType, child) {
|
||||
var parentDef = parentType.getDefinition();
|
||||
|
||||
// A parent without containment rules can contain anything.
|
||||
if (!parentDef.contains) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If any containment rule matches context type, the candidate
|
||||
// can contain this type.
|
||||
return parentDef.contains.some(function (c) {
|
||||
// Simple containment rules are supported typeKeys.
|
||||
if (typeof c === 'string') {
|
||||
return c === child.getCapability('type').getKey();
|
||||
}
|
||||
// More complicated rules require context to have all specified
|
||||
// capabilities.
|
||||
if (!Array.isArray(c.has)) {
|
||||
c.has = [c.has];
|
||||
}
|
||||
return c.has.every(function (capability) {
|
||||
return child.hasCapability(capability);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return CompositionPolicy;
|
||||
|
||||
@@ -1,116 +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(
|
||||
['./CapabilityTable'],
|
||||
function (CapabilityTable) {
|
||||
|
||||
// Symbolic value for the type table for cases when any type
|
||||
// is allowed to be contained.
|
||||
var ANY = true;
|
||||
|
||||
/**
|
||||
* Supports composition policy by maintaining a table of
|
||||
* domain object types, to determine if they can contain
|
||||
* other domain object types. This is determined at application
|
||||
* start time (plug-in support means this cannot be determined
|
||||
* prior to that, but we don't want to redo these calculations
|
||||
* every time policy is checked.)
|
||||
* @constructor
|
||||
* @memberof platform/containment
|
||||
*/
|
||||
function ContainmentTable(typeService, capabilityService) {
|
||||
var self = this,
|
||||
types = typeService.listTypes(),
|
||||
capabilityTable = new CapabilityTable(typeService, capabilityService);
|
||||
|
||||
// Add types which have all these capabilities to the set
|
||||
// of allowed types
|
||||
function addToSetByCapability(set, has) {
|
||||
has = Array.isArray(has) ? has : [has];
|
||||
types.forEach(function (type) {
|
||||
var typeKey = type.getKey();
|
||||
set[typeKey] = has.map(function (capabilityKey) {
|
||||
return capabilityTable.hasCapability(typeKey, capabilityKey);
|
||||
}).reduce(function (a, b) {
|
||||
return a && b;
|
||||
}, true);
|
||||
});
|
||||
}
|
||||
|
||||
// Add this type (or type description) to the set of allowed types
|
||||
function addToSet(set, type) {
|
||||
// Is this a simple case of an explicit type identifier?
|
||||
if (typeof type === 'string') {
|
||||
// If so, add it to the set of allowed types
|
||||
set[type] = true;
|
||||
} else {
|
||||
// Otherwise, populate that set based on capabilities
|
||||
addToSetByCapability(set, (type || {}).has || []);
|
||||
}
|
||||
}
|
||||
|
||||
// Add to the lookup table for this type
|
||||
function addToTable(type) {
|
||||
var key = type.getKey(),
|
||||
definition = type.getDefinition() || {},
|
||||
contains = definition.contains;
|
||||
|
||||
// Check for defined containment restrictions
|
||||
if (contains === undefined) {
|
||||
// If not, accept anything
|
||||
self.table[key] = ANY;
|
||||
} else {
|
||||
// Start with an empty set...
|
||||
self.table[key] = {};
|
||||
// ...cast accepted types to array if necessary...
|
||||
contains = Array.isArray(contains) ? contains : [contains];
|
||||
// ...and add all containment rules to that set
|
||||
contains.forEach(function (c) {
|
||||
addToSet(self.table[key], c);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Build the table
|
||||
this.table = {};
|
||||
types.forEach(addToTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if domain objects of one type can contain domain
|
||||
* objects of another type.
|
||||
* @param {Type} containerType type of the containing domain object
|
||||
* @param {Type} containedType type of the domain object
|
||||
* to be contained
|
||||
* @returns {boolean} true if allowable
|
||||
*/
|
||||
ContainmentTable.prototype.canContain = function (containerType, containedType) {
|
||||
var set = this.table[containerType.getKey()] || {};
|
||||
// Recognize either the symbolic value for "can contain
|
||||
// anything", or lookup the specific type from the set.
|
||||
return (set === ANY) || set[containedType.getKey()];
|
||||
};
|
||||
|
||||
return ContainmentTable;
|
||||
}
|
||||
);
|
||||
@@ -1,85 +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/CapabilityTable"],
|
||||
function (CapabilityTable) {
|
||||
describe("Composition policy's capability table", function () {
|
||||
var mockTypeService,
|
||||
mockCapabilityService,
|
||||
mockTypes,
|
||||
table;
|
||||
|
||||
beforeEach(function () {
|
||||
mockTypeService = jasmine.createSpyObj(
|
||||
'typeService',
|
||||
['listTypes']
|
||||
);
|
||||
mockCapabilityService = jasmine.createSpyObj(
|
||||
'capabilityService',
|
||||
['getCapabilities']
|
||||
);
|
||||
// Both types can only contain b, let's say
|
||||
mockTypes = ['a', 'b'].map(function (type) {
|
||||
var mockType = jasmine.createSpyObj(
|
||||
'type-' + type,
|
||||
['getKey', 'getDefinition', 'getInitialModel']
|
||||
);
|
||||
mockType.getKey.andReturn(type);
|
||||
// Return a model to drive apparent capabilities
|
||||
mockType.getInitialModel.andReturn({ id: type });
|
||||
return mockType;
|
||||
});
|
||||
|
||||
mockTypeService.listTypes.andReturn(mockTypes);
|
||||
mockCapabilityService.getCapabilities.andCallFake(function (model) {
|
||||
var capabilities = {};
|
||||
capabilities[model.id + '-capability'] = true;
|
||||
return capabilities;
|
||||
});
|
||||
|
||||
table = new CapabilityTable(
|
||||
mockTypeService,
|
||||
mockCapabilityService
|
||||
);
|
||||
});
|
||||
|
||||
it("provides for lookup of capabilities by type", function () {
|
||||
// Based on initial model, should report the presence
|
||||
// of particular capabilities - suffixed above with -capability
|
||||
expect(table.hasCapability('a', 'a-capability'))
|
||||
.toBeTruthy();
|
||||
expect(table.hasCapability('a', 'b-capability'))
|
||||
.toBeFalsy();
|
||||
expect(table.hasCapability('a', 'c-capability'))
|
||||
.toBeFalsy();
|
||||
expect(table.hasCapability('b', 'a-capability'))
|
||||
.toBeFalsy();
|
||||
expect(table.hasCapability('b', 'b-capability'))
|
||||
.toBeTruthy();
|
||||
expect(table.hasCapability('b', 'c-capability'))
|
||||
.toBeFalsy();
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -79,7 +79,7 @@ define(
|
||||
expect(mockPolicyService.allow).toHaveBeenCalledWith(
|
||||
'composition',
|
||||
mockTypes[0],
|
||||
mockTypes[1]
|
||||
mockDomainObjects[1]
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -24,60 +24,94 @@ define(
|
||||
["../src/CompositionPolicy"],
|
||||
function (CompositionPolicy) {
|
||||
describe("Composition policy", function () {
|
||||
var mockInjector,
|
||||
mockTypeService,
|
||||
mockCapabilityService,
|
||||
mockTypes,
|
||||
var typeA,
|
||||
typeB,
|
||||
typeC,
|
||||
mockChildObject,
|
||||
policy;
|
||||
|
||||
beforeEach(function () {
|
||||
mockInjector = jasmine.createSpyObj('$injector', ['get']);
|
||||
mockTypeService = jasmine.createSpyObj(
|
||||
'typeService',
|
||||
['listTypes']
|
||||
typeA = jasmine.createSpyObj(
|
||||
'type A-- the particular kind',
|
||||
['getKey', 'getDefinition']
|
||||
);
|
||||
mockCapabilityService = jasmine.createSpyObj(
|
||||
'capabilityService',
|
||||
['getCapabilities']
|
||||
);
|
||||
// Both types can only contain b, let's say
|
||||
mockTypes = ['a', 'b'].map(function (type) {
|
||||
var mockType = jasmine.createSpyObj(
|
||||
'type-' + type,
|
||||
['getKey', 'getDefinition', 'getInitialModel']
|
||||
);
|
||||
mockType.getKey.andReturn(type);
|
||||
mockType.getDefinition.andReturn({
|
||||
contains: ['b']
|
||||
});
|
||||
mockType.getInitialModel.andReturn({});
|
||||
return mockType;
|
||||
typeA.getKey.andReturn('a');
|
||||
typeA.getDefinition.andReturn({
|
||||
contains: ['a']
|
||||
});
|
||||
|
||||
mockInjector.get.andCallFake(function (name) {
|
||||
return {
|
||||
typeService: mockTypeService,
|
||||
capabilityService: mockCapabilityService
|
||||
}[name];
|
||||
|
||||
typeB = jasmine.createSpyObj(
|
||||
'type B-- anything goes',
|
||||
['getKey', 'getDefinition']
|
||||
);
|
||||
typeB.getKey.andReturn('b');
|
||||
typeB.getDefinition.andReturn({
|
||||
contains: ['a', 'b']
|
||||
});
|
||||
|
||||
mockTypeService.listTypes.andReturn(mockTypes);
|
||||
mockCapabilityService.getCapabilities.andReturn({});
|
||||
typeC = jasmine.createSpyObj(
|
||||
'type C-- distinguishing and interested in telemetry',
|
||||
['getKey', 'getDefinition']
|
||||
);
|
||||
typeC.getKey.andReturn('c');
|
||||
typeC.getDefinition.andReturn({
|
||||
contains: [{has: 'telemetry'}]
|
||||
});
|
||||
|
||||
policy = new CompositionPolicy(mockInjector);
|
||||
mockChildObject = jasmine.createSpyObj(
|
||||
'childObject',
|
||||
['getCapability', 'hasCapability']
|
||||
);
|
||||
|
||||
policy = new CompositionPolicy();
|
||||
});
|
||||
|
||||
// Test basic composition policy here; test more closely at
|
||||
// the unit level in ContainmentTable for 'has' support, et al
|
||||
it("enforces containment rules defined by types", function () {
|
||||
expect(policy.allow(mockTypes[0], mockTypes[1]))
|
||||
.toBeTruthy();
|
||||
expect(policy.allow(mockTypes[1], mockTypes[1]))
|
||||
.toBeTruthy();
|
||||
expect(policy.allow(mockTypes[1], mockTypes[0]))
|
||||
.toBeFalsy();
|
||||
expect(policy.allow(mockTypes[0], mockTypes[0]))
|
||||
.toBeFalsy();
|
||||
describe('enforces simple containment rules', function () {
|
||||
|
||||
it('allows when type matches', function () {
|
||||
mockChildObject.getCapability.andReturn(typeA);
|
||||
expect(policy.allow(typeA, mockChildObject))
|
||||
.toBeTruthy();
|
||||
|
||||
expect(policy.allow(typeB, mockChildObject))
|
||||
.toBeTruthy();
|
||||
|
||||
mockChildObject.getCapability.andReturn(typeB);
|
||||
expect(policy.allow(typeB, mockChildObject))
|
||||
.toBeTruthy();
|
||||
});
|
||||
|
||||
|
||||
it('disallows when type doesn\'t match', function () {
|
||||
|
||||
mockChildObject.getCapability.andReturn(typeB);
|
||||
expect(policy.allow(typeA, mockChildObject))
|
||||
.toBeFalsy();
|
||||
|
||||
mockChildObject.getCapability.andReturn(typeC);
|
||||
expect(policy.allow(typeA, mockChildObject))
|
||||
.toBeFalsy();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('enforces capability-based containment rules', function () {
|
||||
it('allows when object has capability', function () {
|
||||
mockChildObject.hasCapability.andReturn(true);
|
||||
expect(policy.allow(typeC, mockChildObject))
|
||||
.toBeTruthy();
|
||||
expect(mockChildObject.hasCapability)
|
||||
.toHaveBeenCalledWith('telemetry');
|
||||
});
|
||||
|
||||
it('skips when object doesn\'t have capability', function () {
|
||||
mockChildObject.hasCapability.andReturn(false);
|
||||
expect(policy.allow(typeC, mockChildObject))
|
||||
.toBeFalsy();
|
||||
expect(mockChildObject.hasCapability)
|
||||
.toHaveBeenCalledWith('telemetry');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,96 +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/ContainmentTable"],
|
||||
function (ContainmentTable) {
|
||||
describe("Composition policy's containment table", function () {
|
||||
var mockTypeService,
|
||||
mockCapabilityService,
|
||||
mockTypes,
|
||||
table;
|
||||
|
||||
beforeEach(function () {
|
||||
mockTypeService = jasmine.createSpyObj(
|
||||
'typeService',
|
||||
['listTypes']
|
||||
);
|
||||
mockCapabilityService = jasmine.createSpyObj(
|
||||
'capabilityService',
|
||||
['getCapabilities']
|
||||
);
|
||||
// Both types can only contain b, let's say
|
||||
mockTypes = ['a', 'b', 'c'].map(function (type, index) {
|
||||
var mockType = jasmine.createSpyObj(
|
||||
'type-' + type,
|
||||
['getKey', 'getDefinition', 'getInitialModel']
|
||||
);
|
||||
mockType.getKey.andReturn(type);
|
||||
mockType.getDefinition.andReturn({
|
||||
// First two contain objects with capability 'b';
|
||||
// third one defines no containership rules
|
||||
contains: (index < 2) ? [{ has: 'b' }] : undefined
|
||||
});
|
||||
// Return a model to drive apparent capabilities
|
||||
mockType.getInitialModel.andReturn({ id: type });
|
||||
return mockType;
|
||||
});
|
||||
|
||||
mockTypeService.listTypes.andReturn(mockTypes);
|
||||
mockCapabilityService.getCapabilities.andCallFake(function (model) {
|
||||
var capabilities = {};
|
||||
capabilities[model.id] = true;
|
||||
return capabilities;
|
||||
});
|
||||
|
||||
table = new ContainmentTable(
|
||||
mockTypeService,
|
||||
mockCapabilityService
|
||||
);
|
||||
});
|
||||
|
||||
// The plain type case is tested in CompositionPolicySpec,
|
||||
// so just test for special syntax ('has', or no contains rules) here
|
||||
it("enforces 'has' containment rules related to capabilities", function () {
|
||||
expect(table.canContain(mockTypes[0], mockTypes[1]))
|
||||
.toBeTruthy();
|
||||
expect(table.canContain(mockTypes[1], mockTypes[1]))
|
||||
.toBeTruthy();
|
||||
expect(table.canContain(mockTypes[1], mockTypes[0]))
|
||||
.toBeFalsy();
|
||||
expect(table.canContain(mockTypes[0], mockTypes[0]))
|
||||
.toBeFalsy();
|
||||
});
|
||||
|
||||
it("allows anything when no containership rules are defined", function () {
|
||||
expect(table.canContain(mockTypes[2], mockTypes[0]))
|
||||
.toBeTruthy();
|
||||
expect(table.canContain(mockTypes[2], mockTypes[1]))
|
||||
.toBeTruthy();
|
||||
expect(table.canContain(mockTypes[2], mockTypes[2]))
|
||||
.toBeTruthy();
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -241,7 +241,7 @@ define([
|
||||
"property": "name",
|
||||
"pattern": "\\S+",
|
||||
"required": true,
|
||||
"cssclass": "l-input-lg"
|
||||
"cssClass": "l-input-lg"
|
||||
},
|
||||
{
|
||||
"name": "Notes",
|
||||
@@ -249,19 +249,19 @@ define([
|
||||
"property": "notes",
|
||||
"control": "textarea",
|
||||
"required": false,
|
||||
"cssclass": "l-textarea-sm"
|
||||
"cssClass": "l-textarea-sm"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "root",
|
||||
"name": "Root",
|
||||
"cssclass": "icon-folder"
|
||||
"cssClass": "icon-folder"
|
||||
},
|
||||
{
|
||||
"key": "folder",
|
||||
"name": "Folder",
|
||||
"cssclass": "icon-folder",
|
||||
"cssClass": "icon-folder",
|
||||
"features": "creation",
|
||||
"description": "Create folders to organize other objects or links to objects.",
|
||||
"priority": 1000,
|
||||
@@ -272,11 +272,11 @@ define([
|
||||
{
|
||||
"key": "unknown",
|
||||
"name": "Unknown Type",
|
||||
"cssclass": "icon-object-unknown"
|
||||
"cssClass": "icon-object-unknown"
|
||||
},
|
||||
{
|
||||
"name": "Unknown Type",
|
||||
"cssclass": "icon-object-unknown"
|
||||
"cssClass": "icon-object-unknown"
|
||||
}
|
||||
],
|
||||
"capabilities": [
|
||||
|
||||
@@ -58,7 +58,7 @@ define(
|
||||
* @property {string} key machine-readable identifier for this action
|
||||
* @property {string} name human-readable name for this action
|
||||
* @property {string} description human-readable description
|
||||
* @property {string} cssclass CSS class for icon
|
||||
* @property {string} cssClass CSS class for icon
|
||||
* @property {ActionContext} context the context in which the action
|
||||
* will be performed.
|
||||
*/
|
||||
|
||||
@@ -53,10 +53,10 @@ define(
|
||||
*/
|
||||
function CoreCapabilityProvider(capabilities, $log) {
|
||||
// Filter by invoking the capability's appliesTo method
|
||||
function filterCapabilities(model) {
|
||||
function filterCapabilities(model, id) {
|
||||
return capabilities.filter(function (capability) {
|
||||
return capability.appliesTo ?
|
||||
capability.appliesTo(model) :
|
||||
capability.appliesTo(model, id) :
|
||||
true;
|
||||
});
|
||||
}
|
||||
@@ -75,8 +75,8 @@ define(
|
||||
return result;
|
||||
}
|
||||
|
||||
function getCapabilities(model) {
|
||||
return packageCapabilities(filterCapabilities(model));
|
||||
function getCapabilities(model, id) {
|
||||
return packageCapabilities(filterCapabilities(model, id));
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -56,12 +56,12 @@ define(
|
||||
* @method Type#getDescription
|
||||
*/
|
||||
/**
|
||||
* Get the cssclass associated with this type. cssclass is a
|
||||
* Get the cssClass associated with this type. cssClass is a
|
||||
* string which will appear as an icon (when
|
||||
* displayed in an appropriate font) which visually
|
||||
* distinguish types from one another.
|
||||
*
|
||||
* @returns {string} the cssclass for this type
|
||||
* @returns {string} the cssClass for this type
|
||||
* @method Type#getCssClass
|
||||
*/
|
||||
/**
|
||||
@@ -145,7 +145,7 @@ define(
|
||||
};
|
||||
|
||||
TypeImpl.prototype.getCssClass = function () {
|
||||
return this.typeDef.cssclass;
|
||||
return this.typeDef.cssClass;
|
||||
};
|
||||
|
||||
TypeImpl.prototype.getProperties = function () {
|
||||
|
||||
@@ -33,7 +33,7 @@ define(
|
||||
key: 'test-type',
|
||||
name: 'Test Type',
|
||||
description: 'A type, for testing',
|
||||
cssclass: 'icon-telemetry-panel',
|
||||
cssClass: 'icon-telemetry-panel',
|
||||
inherits: ['test-parent-1', 'test-parent-2'],
|
||||
features: ['test-feature-1'],
|
||||
properties: [{}],
|
||||
|
||||
@@ -30,18 +30,18 @@ define(
|
||||
testTypeDefinitions = [
|
||||
{
|
||||
key: 'basic',
|
||||
cssclass: "icon-magnify-in",
|
||||
cssClass: "icon-magnify-in",
|
||||
name: "Basic Type"
|
||||
},
|
||||
{
|
||||
key: 'multi1',
|
||||
cssclass: "icon-trash",
|
||||
cssClass: "icon-trash",
|
||||
description: "Multi1 Description",
|
||||
capabilities: ['a1', 'b1']
|
||||
},
|
||||
{
|
||||
key: 'multi2',
|
||||
cssclass: "icon-magnify-out",
|
||||
cssClass: "icon-magnify-out",
|
||||
capabilities: ['a2', 'b2', 'c2']
|
||||
},
|
||||
{
|
||||
|
||||
@@ -66,7 +66,7 @@ define([
|
||||
"key": "move",
|
||||
"name": "Move",
|
||||
"description": "Move object to another location.",
|
||||
"cssclass": "icon-move",
|
||||
"cssClass": "icon-move",
|
||||
"category": "contextual",
|
||||
"implementation": MoveAction,
|
||||
"depends": [
|
||||
@@ -79,7 +79,7 @@ define([
|
||||
"key": "copy",
|
||||
"name": "Duplicate",
|
||||
"description": "Duplicate object to another location.",
|
||||
"cssclass": "icon-duplicate",
|
||||
"cssClass": "icon-duplicate",
|
||||
"category": "contextual",
|
||||
"implementation": CopyAction,
|
||||
"depends": [
|
||||
@@ -95,7 +95,7 @@ define([
|
||||
"key": "link",
|
||||
"name": "Create Link",
|
||||
"description": "Create Link to object in another location.",
|
||||
"cssclass": "icon-link",
|
||||
"cssClass": "icon-link",
|
||||
"category": "contextual",
|
||||
"implementation": LinkAction,
|
||||
"depends": [
|
||||
@@ -108,7 +108,7 @@ define([
|
||||
"key": "follow",
|
||||
"name": "Go To Original",
|
||||
"description": "Go to the original, un-linked instance of this object.",
|
||||
"cssclass": "",
|
||||
"cssClass": "",
|
||||
"category": "contextual",
|
||||
"implementation": GoToOriginalAction
|
||||
},
|
||||
@@ -116,7 +116,7 @@ define([
|
||||
"key": "locate",
|
||||
"name": "Set Primary Location",
|
||||
"description": "Set a domain object's primary location.",
|
||||
"cssclass": "",
|
||||
"cssClass": "",
|
||||
"category": "contextual",
|
||||
"implementation": SetPrimaryLocationAction
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ define(
|
||||
return this.policyService.allow(
|
||||
"composition",
|
||||
parentCandidate.getCapability('type'),
|
||||
object.getCapability('type')
|
||||
object
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ define(
|
||||
return this.policyService.allow(
|
||||
"composition",
|
||||
parentCandidate.getCapability('type'),
|
||||
object.getCapability('type')
|
||||
object
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ define(
|
||||
sections: [
|
||||
{
|
||||
name: 'Location',
|
||||
cssclass: "grows",
|
||||
cssClass: "grows",
|
||||
rows: [
|
||||
{
|
||||
name: label,
|
||||
|
||||
@@ -56,7 +56,7 @@ define(
|
||||
return this.policyService.allow(
|
||||
"composition",
|
||||
parentCandidate.getCapability('type'),
|
||||
object.getCapability('type')
|
||||
object
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ define(
|
||||
expect(policyService.allow).toHaveBeenCalledWith(
|
||||
"composition",
|
||||
parentCandidate.capabilities.type,
|
||||
object.capabilities.type
|
||||
object
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ define(
|
||||
expect(mockPolicyService.allow).toHaveBeenCalledWith(
|
||||
"composition",
|
||||
parentCandidate.capabilities.type,
|
||||
object.capabilities.type
|
||||
object
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ define(
|
||||
expect(policyService.allow).toHaveBeenCalledWith(
|
||||
"composition",
|
||||
parentCandidate.capabilities.type,
|
||||
object.capabilities.type
|
||||
object
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ define([
|
||||
],
|
||||
"category": "contextual",
|
||||
"name": "Start",
|
||||
"cssclass": "icon-play",
|
||||
"cssClass": "icon-play",
|
||||
"priority": "preferred"
|
||||
},
|
||||
{
|
||||
@@ -147,7 +147,7 @@ define([
|
||||
],
|
||||
"category": "contextual",
|
||||
"name": "Restart at 0",
|
||||
"cssclass": "icon-refresh",
|
||||
"cssClass": "icon-refresh",
|
||||
"priority": "preferred"
|
||||
}
|
||||
],
|
||||
@@ -155,7 +155,7 @@ define([
|
||||
{
|
||||
"key": "clock",
|
||||
"name": "Clock",
|
||||
"cssclass": "icon-clock",
|
||||
"cssClass": "icon-clock",
|
||||
"description": "A UTC-based clock that supports a variety of display formats. Clocks can be added to Display Layouts.",
|
||||
"priority": 101,
|
||||
"features": [
|
||||
@@ -183,7 +183,7 @@ define([
|
||||
"name": "hh:mm:ss"
|
||||
}
|
||||
],
|
||||
"cssclass": "l-inline"
|
||||
"cssClass": "l-inline"
|
||||
},
|
||||
{
|
||||
"control": "select",
|
||||
@@ -197,7 +197,7 @@ define([
|
||||
"name": "24hr"
|
||||
}
|
||||
],
|
||||
"cssclass": "l-inline"
|
||||
"cssClass": "l-inline"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -212,7 +212,7 @@ define([
|
||||
{
|
||||
"key": "timer",
|
||||
"name": "Timer",
|
||||
"cssclass": "icon-timer",
|
||||
"cssClass": "icon-timer",
|
||||
"description": "A timer that counts up or down to a datetime. Timers can be started, stopped and reset whenever needed, and support a variety of display formats. Each Timer displays the same value to all users. Timers can be added to Display Layouts.",
|
||||
"priority": 100,
|
||||
"features": [
|
||||
|
||||
@@ -131,11 +131,11 @@ define(
|
||||
/**
|
||||
* Get the CSS class to display the right icon
|
||||
* for the start/restart button.
|
||||
* @returns {string} cssclass to display
|
||||
* @returns {string} cssClass to display
|
||||
*/
|
||||
TimerController.prototype.buttonCssClass = function () {
|
||||
return this.relevantAction ?
|
||||
this.relevantAction.getMetadata().cssclass : "";
|
||||
this.relevantAction.getMetadata().cssClass : "";
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -85,8 +85,8 @@ define(
|
||||
'timer.restart': mockRestart
|
||||
}[k]];
|
||||
});
|
||||
mockStart.getMetadata.andReturn({ cssclass: "icon-play", name: "Start" });
|
||||
mockRestart.getMetadata.andReturn({ cssclass: "icon-refresh", name: "Restart" });
|
||||
mockStart.getMetadata.andReturn({ cssClass: "icon-play", name: "Start" });
|
||||
mockRestart.getMetadata.andReturn({ cssClass: "icon-refresh", name: "Restart" });
|
||||
mockScope.domainObject = mockDomainObject;
|
||||
|
||||
testModel = {};
|
||||
@@ -144,7 +144,7 @@ define(
|
||||
expect(controller.text()).toEqual("0D 00:00:00");
|
||||
});
|
||||
|
||||
it("shows cssclass & name for the applicable start/restart action", function () {
|
||||
it("shows cssClass & name for the applicable start/restart action", function () {
|
||||
invokeWatch('domainObject', mockDomainObject);
|
||||
expect(controller.buttonCssClass()).toEqual("icon-play");
|
||||
expect(controller.buttonText()).toEqual("Start");
|
||||
|
||||
@@ -21,11 +21,9 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
"./src/ConductorTelemetryDecorator",
|
||||
"./src/ConductorRepresenter",
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
ConductorTelemetryDecorator,
|
||||
ConductorRepresenter,
|
||||
legacyRegistry
|
||||
) {
|
||||
@@ -39,16 +37,6 @@ define([
|
||||
"openmct"
|
||||
]
|
||||
}
|
||||
],
|
||||
"components": [
|
||||
{
|
||||
"type": "decorator",
|
||||
"provides": "telemetryService",
|
||||
"implementation": ConductorTelemetryDecorator,
|
||||
"depends": [
|
||||
"openmct"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web 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 Web 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 () {
|
||||
|
||||
/**
|
||||
* Decorates the `telemetryService` such that requests are
|
||||
* mediated by the time conductor. This is a modified version of the
|
||||
* decorator used in the old TimeConductor that integrates with the
|
||||
* new TimeConductor API.
|
||||
*
|
||||
* @constructor
|
||||
* @memberof platform/features/conductor
|
||||
* @implements {TelemetryService}
|
||||
* @param {platform/features/conductor.TimeConductor} conductor
|
||||
* the service which exposes the global time conductor
|
||||
* @param {TelemetryService} telemetryService the decorated service
|
||||
*/
|
||||
function ConductorTelemetryDecorator(openmct, telemetryService) {
|
||||
this.conductor = openmct.conductor;
|
||||
this.telemetryService = telemetryService;
|
||||
|
||||
this.amendRequests = ConductorTelemetryDecorator.prototype.amendRequests.bind(this);
|
||||
}
|
||||
|
||||
function amendRequest(request, bounds, timeSystem) {
|
||||
request = request || {};
|
||||
request.start = bounds.start;
|
||||
request.end = bounds.end;
|
||||
request.domain = timeSystem.metadata.key;
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
ConductorTelemetryDecorator.prototype.amendRequests = function (requests) {
|
||||
var bounds = this.conductor.bounds(),
|
||||
timeSystem = this.conductor.timeSystem();
|
||||
|
||||
return (requests || []).map(function (request) {
|
||||
return amendRequest(request, bounds, timeSystem);
|
||||
});
|
||||
};
|
||||
|
||||
ConductorTelemetryDecorator.prototype.requestTelemetry = function (requests) {
|
||||
return this.telemetryService
|
||||
.requestTelemetry(this.amendRequests(requests));
|
||||
};
|
||||
|
||||
ConductorTelemetryDecorator.prototype.subscribe = function (callback, requests) {
|
||||
var unsubscribeFunc = this.telemetryService.subscribe(callback, this.amendRequests(requests)),
|
||||
conductor = this.conductor,
|
||||
self = this;
|
||||
|
||||
function amendRequests() {
|
||||
return self.amendRequests(requests);
|
||||
}
|
||||
|
||||
conductor.on('bounds', amendRequests);
|
||||
return function () {
|
||||
unsubscribeFunc();
|
||||
conductor.off('bounds', amendRequests);
|
||||
};
|
||||
};
|
||||
|
||||
return ConductorTelemetryDecorator;
|
||||
}
|
||||
);
|
||||
@@ -70,8 +70,9 @@ define([
|
||||
"$location",
|
||||
"openmct",
|
||||
"timeConductorViewService",
|
||||
"timeSystems[]",
|
||||
"formatService"
|
||||
"formatService",
|
||||
"DEFAULT_TIMECONDUCTOR_MODE",
|
||||
"SHOW_TIMECONDUCTOR"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -150,6 +151,13 @@ define([
|
||||
"link": "https://github.com/d3/d3/blob/master/LICENSE"
|
||||
}
|
||||
],
|
||||
"constants": [
|
||||
{
|
||||
"key": "DEFAULT_TIMECONDUCTOR_MODE",
|
||||
"value": "realtime",
|
||||
"priority": "fallback"
|
||||
}
|
||||
],
|
||||
"formats": [
|
||||
{
|
||||
"key": "number",
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
$output-bourbon-deprecation-warnings: false;
|
||||
@import "bourbon";
|
||||
@import "../../../../../commonUI/general/res/sass/constants";
|
||||
@import "../../../../../commonUI/general/res/sass/mixins";
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
$output-bourbon-deprecation-warnings: false;
|
||||
@import "bourbon";
|
||||
@import "../../../../../commonUI/general/res/sass/constants";
|
||||
@import "../../../../../commonUI/general/res/sass/mixins";
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
ng-click="ngModel.selectedKey=key">
|
||||
<a ng-mouseover="ngModel.activeMetadata = metadata"
|
||||
ng-mouseleave="ngModel.activeMetadata = undefined"
|
||||
class="menu-item-a {{metadata.cssclass}}">
|
||||
class="menu-item-a {{metadata.cssClass}}">
|
||||
{{metadata.name}}
|
||||
</a>
|
||||
</li>
|
||||
@@ -34,7 +34,7 @@
|
||||
</div>
|
||||
<div class="pane right menu-item-description">
|
||||
<div
|
||||
class="desc-area ui-symbol icon type-icon {{ngModel.activeMetadata.cssclass}}"></div>
|
||||
class="desc-area ui-symbol icon type-icon {{ngModel.activeMetadata.cssClass}}"></div>
|
||||
<div class="desc-area title">
|
||||
{{ngModel.activeMetadata.name}}
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<!-- Parent holder for time conductor. follow-mode | fixed-mode -->
|
||||
<div ng-controller="TimeConductorController as tcController"
|
||||
class="holder grows flex-elem l-flex-row l-time-conductor {{modeModel.selectedKey}}-mode {{timeSystemModel.selected.metadata.key}}-time-system"
|
||||
ng-class="{'status-panning': tcController.panning}">
|
||||
|
||||
ng-class="{'status-panning': tcController.panning}" ng-show="showTimeConductor">
|
||||
<div class="flex-elem holder time-conductor-icon">
|
||||
<div class="hand-little"></div>
|
||||
<div class="hand-big"></div>
|
||||
|
||||
@@ -31,7 +31,7 @@ define(['./TickSource'], function (TickSource) {
|
||||
this.metadata = {
|
||||
key: 'local',
|
||||
mode: 'realtime',
|
||||
cssclass: 'icon-clock',
|
||||
cssClass: 'icon-clock',
|
||||
label: 'Real-time',
|
||||
name: 'Real-time Mode',
|
||||
description: 'Monitor real-time streaming data as it comes in. The Time Conductor and displays will automatically advance themselves based on a UTC clock.'
|
||||
|
||||
@@ -40,7 +40,16 @@ define(
|
||||
* @memberof platform.features.conductor
|
||||
* @constructor
|
||||
*/
|
||||
function TimeConductorController($scope, $window, $location, openmct, conductorViewService, timeSystems, formatService) {
|
||||
function TimeConductorController(
|
||||
$scope,
|
||||
$window,
|
||||
$location,
|
||||
openmct,
|
||||
conductorViewService,
|
||||
formatService,
|
||||
DEFAULT_MODE,
|
||||
SHOW_TIMECONDUCTOR
|
||||
) {
|
||||
|
||||
var self = this;
|
||||
|
||||
@@ -60,10 +69,14 @@ define(
|
||||
this.validation = new TimeConductorValidation(this.conductor);
|
||||
this.formatService = formatService;
|
||||
|
||||
//Check if the default mode defined is actually available
|
||||
if (this.modes[DEFAULT_MODE] === undefined) {
|
||||
DEFAULT_MODE = 'fixed';
|
||||
}
|
||||
this.DEFAULT_MODE = DEFAULT_MODE;
|
||||
|
||||
// Construct the provided time system definitions
|
||||
this.timeSystems = timeSystems.map(function (timeSystemConstructor) {
|
||||
return timeSystemConstructor();
|
||||
});
|
||||
this.timeSystems = conductorViewService.systems;
|
||||
|
||||
this.initializeScope();
|
||||
var searchParams = JSON.parse(JSON.stringify(this.$location.search()));
|
||||
@@ -94,6 +107,8 @@ define(
|
||||
//Respond to any subsequent conductor changes
|
||||
this.conductor.on('bounds', this.changeBounds);
|
||||
this.conductor.on('timeSystem', this.changeTimeSystem);
|
||||
|
||||
this.$scope.showTimeConductor = SHOW_TIMECONDUCTOR;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,7 +154,7 @@ define(
|
||||
//Set mode from url if changed
|
||||
if (searchParams[SEARCH.MODE] === undefined ||
|
||||
searchParams[SEARCH.MODE] !== this.$scope.modeModel.selectedKey) {
|
||||
this.setMode(searchParams[SEARCH.MODE] || "fixed");
|
||||
this.setMode(searchParams[SEARCH.MODE] || this.DEFAULT_MODE);
|
||||
}
|
||||
|
||||
if (searchParams[SEARCH.TIME_SYSTEM] &&
|
||||
|
||||
@@ -130,8 +130,10 @@ define(['./TimeConductorController'], function (TimeConductorController) {
|
||||
mockLocation,
|
||||
{conductor: mockTimeConductor},
|
||||
mockConductorViewService,
|
||||
mockTimeSystems,
|
||||
mockFormatService
|
||||
mockFormatService,
|
||||
'fixed',
|
||||
true
|
||||
|
||||
);
|
||||
|
||||
tsListener = getListener(mockTimeConductor.on, "timeSystem");
|
||||
@@ -244,7 +246,6 @@ define(['./TimeConductorController'], function (TimeConductorController) {
|
||||
var ts1Metadata;
|
||||
var ts2Metadata;
|
||||
var ts3Metadata;
|
||||
var mockTimeSystemConstructors;
|
||||
|
||||
beforeEach(function () {
|
||||
mode = "realtime";
|
||||
@@ -276,11 +277,7 @@ define(['./TimeConductorController'], function (TimeConductorController) {
|
||||
];
|
||||
|
||||
//Wrap in mock constructors
|
||||
mockTimeSystemConstructors = mockTimeSystems.map(function (mockTimeSystem) {
|
||||
return function () {
|
||||
return mockTimeSystem;
|
||||
};
|
||||
});
|
||||
mockConductorViewService.systems = mockTimeSystems;
|
||||
|
||||
controller = new TimeConductorController(
|
||||
mockScope,
|
||||
@@ -288,8 +285,9 @@ define(['./TimeConductorController'], function (TimeConductorController) {
|
||||
mockLocation,
|
||||
{conductor: mockTimeConductor},
|
||||
mockConductorViewService,
|
||||
mockTimeSystemConstructors,
|
||||
mockFormatService
|
||||
mockFormatService,
|
||||
"fixed",
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
@@ -434,12 +432,7 @@ define(['./TimeConductorController'], function (TimeConductorController) {
|
||||
}
|
||||
};
|
||||
|
||||
mockTimeSystems.push(function () {
|
||||
return timeSystem;
|
||||
});
|
||||
mockTimeSystems.push(function () {
|
||||
return otherTimeSystem;
|
||||
});
|
||||
mockConductorViewService.systems = [timeSystem, otherTimeSystem];
|
||||
|
||||
urlBounds = {
|
||||
start: 100,
|
||||
@@ -467,8 +460,9 @@ define(['./TimeConductorController'], function (TimeConductorController) {
|
||||
mockLocation,
|
||||
{conductor: mockTimeConductor},
|
||||
mockConductorViewService,
|
||||
mockTimeSystems,
|
||||
mockFormatService
|
||||
mockFormatService,
|
||||
"fixed",
|
||||
true
|
||||
);
|
||||
|
||||
spyOn(controller, "setMode");
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user