mirror of
https://github.com/nasa/openmct.git
synced 2025-06-26 03:00:13 +00:00
Compare commits
34 Commits
vue-table-
...
create-new
Author | SHA1 | Date | |
---|---|---|---|
a53a669154 | |||
0602613b6e | |||
7620432388 | |||
fc8663c049 | |||
adfe30a891 | |||
5218e350c3 | |||
88615e92d2 | |||
12477a220b | |||
9582fb2b06 | |||
3c075b7ff2 | |||
081edfbd70 | |||
04cc8f7aa2 | |||
a1d206bfc3 | |||
ef9c6d5fed | |||
15a75ac134 | |||
cde3994979 | |||
1a10c966e0 | |||
9288880e47 | |||
d2c5476cdd | |||
8d21d420ae | |||
cc22fd4e9d | |||
4a046b3eea | |||
b0702ceff5 | |||
5af14cd3b9 | |||
d7eb4c17ca | |||
8c9fe2d36b | |||
3246480f82 | |||
8055e050b6 | |||
b0f73fff0d | |||
755cf21d3f | |||
95457a1981 | |||
da0ed95662 | |||
c8919708bb | |||
cc5bfda730 |
40
.circleci/config.yml
Normal file
40
.circleci/config.yml
Normal file
@ -0,0 +1,40 @@
|
||||
version: 2
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
- image: circleci/node:8-browsers
|
||||
environment:
|
||||
CHROME_BIN: "/usr/bin/google-chrome"
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Update npm
|
||||
command: 'sudo npm install -g npm@latest'
|
||||
- restore_cache:
|
||||
key: dependency-cache-{{ checksum "package.json" }}-{{ checksum "bower.json" }}
|
||||
- run:
|
||||
name: Installing dependencies (npm install)
|
||||
command: npm install
|
||||
- save_cache:
|
||||
key: dependency-cache-{{ checksum "package.json" }}-{{ checksum "bower.json" }}
|
||||
paths:
|
||||
- node_modules
|
||||
- bower_components
|
||||
- run:
|
||||
name: npm run test
|
||||
command: npm run test
|
||||
- run:
|
||||
name: npm run lint
|
||||
command: npm run lint
|
||||
- run:
|
||||
name: npm run checkstyle
|
||||
command: npm run checkstyle
|
||||
- store_artifacts:
|
||||
path: dist
|
||||
prefix: dist
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
test:
|
||||
jobs:
|
||||
- build
|
88
API.md
88
API.md
@ -37,7 +37,7 @@
|
||||
- [Time Systems and Bounds](#time-systems-and-bounds)
|
||||
- [Defining and Registering Time Systems](#defining-and-registering-time-systems)
|
||||
- [Getting and Setting the Active Time System](#getting-and-setting-the-active-time-system)
|
||||
- [Time Bounds](#time-bounds)
|
||||
- [Time Bounds](#time-bounds)
|
||||
- [Clocks](#clocks)
|
||||
- [Defining and registering clocks](#defining-and-registering-clocks)
|
||||
- [Getting and setting active clock](#getting-and-setting-active-clock)
|
||||
@ -48,6 +48,10 @@
|
||||
- [The Time Conductor](#the-time-conductor)
|
||||
- [Time Conductor Configuration](#time-conductor-configuration)
|
||||
- [Example conductor configuration](#example-conductor-configuration)
|
||||
- [Indicators](#indicators)
|
||||
- [The URL Status Indicator](#the-url-status-indicator)
|
||||
- [Creating a Simple Indicator](#creating-a-simple-indicator)
|
||||
- [Custom Indicators](#custom-indicators)
|
||||
- [Included Plugins](#included-plugins)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
@ -688,7 +692,7 @@ openmct.time.timeSystem(utcTimeSystem, bounds);
|
||||
Setting the active time system will trigger a [`'timeSystem'`](#time-events)
|
||||
event. If you supplied bounds, a [`'bounds'`](#time-events) event will be triggered afterwards with your newly supplied bounds.
|
||||
|
||||
### Time Bounds
|
||||
#### Time Bounds
|
||||
|
||||
The TimeAPI provides a getter/setter for querying and setting time bounds. Time
|
||||
bounds are simply an object with a `start` and an end `end` attribute.
|
||||
@ -977,6 +981,72 @@ openmct.install(openmct.plugins.Conductor({
|
||||
}));
|
||||
```
|
||||
|
||||
## Indicators
|
||||
|
||||
Indicators are small widgets that reside at the bottom of the screen and are visible from
|
||||
every screen in Open MCT. They can be used to convey system state using an icon and text.
|
||||
Typically an indicator will display an icon (customizable with a CSS class) that will
|
||||
reveal additional information when the mouse cursor is hovered over it.
|
||||
|
||||
### The URL Status Indicator
|
||||
|
||||
A common use case for indicators is to convey the state of some external system such as a
|
||||
persistence backend or HTTP server. So long as this system is accessible via HTTP request,
|
||||
Open MCT provides a general purpose indicator to show whether the server is available and
|
||||
returing a 2xx status code. The URL Status Indicator is made available as a default plugin. See
|
||||
[Included Plugins](#included-plugins) below for details on how to install and configure the
|
||||
URL Status Indicator.
|
||||
|
||||
### Creating a Simple Indicator
|
||||
|
||||
A simple indicator with an icon and some text can be created and added with minimal code. An indicator
|
||||
of this type exposes functions for customizing the text, icon, and style of the indicator.
|
||||
|
||||
eg.
|
||||
``` javascript
|
||||
var myIndicator = openmct.indicators.simpleIndicator();
|
||||
myIndicator.text("Hello World!");
|
||||
openmct.indicators.add(myIndicator);
|
||||
```
|
||||
|
||||
This will create a new indicator and add it to the bottom of the screen in Open MCT.
|
||||
By default, the indicator will appear as an information icon. Hovering over the icon will
|
||||
reveal the text set via the call to `.text()`. The Indicator object returned by the API
|
||||
call exposes a number of functions for customizing the content and appearance of the indicator:
|
||||
|
||||
* `.text([text])`: Gets or sets the text shown when the user hovers over the indicator.
|
||||
Accepts an __optional__ `string` argument that, if provided, will be used to set the text.
|
||||
Hovering over the indicator will expand it to its full size, revealing this text alongside
|
||||
the icon. Returns the currently set text as a `string`.
|
||||
* `.description([description])`: Gets or sets the indicator's description. Accepts an
|
||||
__optional__ `string` argument that, if provided, will be used to set the text. The description
|
||||
allows for more detail to be provided in a tooltip when the user hovers over the indicator.
|
||||
Returns the currently set text as a `string`.
|
||||
* `.iconClass([className])`: Gets or sets the CSS class used to define the icon. Accepts an __optional__
|
||||
`string` parameter to be used to set the class applied to the indicator. Any of
|
||||
[the built-in glyphs](https://nasa.github.io/openmct/style-guide/#/browse/styleguide:home/glyphs?view=styleguide.glyphs)
|
||||
may be used here, or a custom CSS class can be provided. Returns the currently defined CSS
|
||||
class as a `string`.
|
||||
* `.statusClass([className])`: Gets or sets the CSS class used to determine status. Accepts an __optional __
|
||||
`string` parameter to be used to set a status class applied to the indicator. May be used to apply
|
||||
different colors to indicate status.
|
||||
|
||||
### Custom Indicators
|
||||
|
||||
A completely custom indicator can be added by simple providing a DOM element to place alongside other indicators.
|
||||
|
||||
``` javascript
|
||||
var domNode = document.createElement('div');
|
||||
domNode.innerText = new Date().toString();
|
||||
setInterval(function () {
|
||||
domNode.innerText = new Date().toString();
|
||||
}, 1000);
|
||||
|
||||
openmct.indicators.add({
|
||||
element: domNode
|
||||
});
|
||||
```
|
||||
|
||||
## Included Plugins
|
||||
|
||||
Open MCT is packaged along with a few general-purpose plugins:
|
||||
@ -1000,18 +1070,18 @@ openmct.install(openmct.plugins.CouchDB('http://localhost:9200'))
|
||||
* `openmct.plugins.Espresso` and `openmct.plugins.Snow` are two different
|
||||
themes (dark and light) available for Open MCT. Note that at least one
|
||||
of these themes must be installed for Open MCT to appear correctly.
|
||||
* `openmct.plugins.URLIndicatorPlugin` adds an indicator which shows the
|
||||
* `openmct.plugins.URLIndicator` adds an indicator which shows the
|
||||
availability of a URL with the following options:
|
||||
- `url` : URL to indicate the status of
|
||||
- `cssClass`: Icon to show in the status bar, defaults to `icon-database`, [list of all icons](https://nasa.github.io/openmct/style-guide/#/browse/styleguide:home?view=items)
|
||||
- `iconClass`: Icon to show in the status bar, defaults to `icon-database`, [list of all icons](https://nasa.github.io/openmct/style-guide/#/browse/styleguide:home?view=items)
|
||||
- `interval`: Interval between checking the connection, defaults to `10000`
|
||||
- `label` Name showing up as text in the status bar, defaults to url
|
||||
```javascript
|
||||
openmct.install(openmct.plugins.URLIndicatorPlugin({
|
||||
url: 'http://google.com',
|
||||
cssClass: 'check',
|
||||
interval: 10000,
|
||||
label: 'Google'
|
||||
openmct.install(openmct.plugins.URLIndicator({
|
||||
url: 'http://localhost:8080',
|
||||
iconClass: 'check',
|
||||
interval: 10000,
|
||||
label: 'Localhost'
|
||||
})
|
||||
);
|
||||
```
|
||||
|
27
circle.yml
27
circle.yml
@ -1,27 +0,0 @@
|
||||
machine:
|
||||
node:
|
||||
version: 8.11.0
|
||||
|
||||
dependencies:
|
||||
pre:
|
||||
- npm install -g npm@latest
|
||||
|
||||
deployment:
|
||||
production:
|
||||
branch: master
|
||||
commands:
|
||||
- npm install canvas nomnoml
|
||||
- ./build-docs.sh
|
||||
openmctweb-staging-deux:
|
||||
branch: mobile
|
||||
heroku:
|
||||
appname: openmctweb-staging-deux
|
||||
test:
|
||||
post:
|
||||
- gulp lint
|
||||
- gulp checkstyle
|
||||
|
||||
general:
|
||||
branches:
|
||||
ignore:
|
||||
- gh-pages
|
@ -27,14 +27,8 @@ define([
|
||||
|
||||
) {
|
||||
|
||||
var RED = {
|
||||
sin: 0.9,
|
||||
cos: 0.9
|
||||
},
|
||||
YELLOW = {
|
||||
sin: 0.5,
|
||||
cos: 0.5
|
||||
},
|
||||
var RED = 0.9,
|
||||
YELLOW = 0.5,
|
||||
LIMITS = {
|
||||
rh: {
|
||||
cssClass: "s-limit-upr s-limit-red",
|
||||
@ -73,18 +67,17 @@ define([
|
||||
SinewaveLimitProvider.prototype.getLimitEvaluator = function (domainObject) {
|
||||
return {
|
||||
evaluate: function (datum, valueMetadata) {
|
||||
var range = valueMetadata && valueMetadata.key;
|
||||
|
||||
if (datum[range] > RED[range]) {
|
||||
var range = valueMetadata ? valueMetadata.key : 'sin'
|
||||
if (datum[range] > RED) {
|
||||
return LIMITS.rh;
|
||||
}
|
||||
if (datum[range] < -RED[range]) {
|
||||
if (datum[range] < -RED) {
|
||||
return LIMITS.rl;
|
||||
}
|
||||
if (datum[range] > YELLOW[range]) {
|
||||
if (datum[range] > YELLOW) {
|
||||
return LIMITS.yh;
|
||||
}
|
||||
if (datum[range] < -YELLOW[range]) {
|
||||
if (datum[range] < -YELLOW) {
|
||||
return LIMITS.yl;
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,8 @@ define([
|
||||
"provides": "identityService",
|
||||
"type": "provider",
|
||||
"depends": [
|
||||
"dialogService"
|
||||
"dialogService",
|
||||
"$q"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -55,21 +55,37 @@ define(
|
||||
* @implements {IdentityService}
|
||||
* @memberof platform/identity
|
||||
*/
|
||||
function ExampleIdentityProvider(dialogService) {
|
||||
// Handle rejected dialog messages by treating the
|
||||
// current user as undefined.
|
||||
function echo(v) { return v; }
|
||||
function giveUndefined() { return undefined; }
|
||||
function ExampleIdentityProvider(dialogService, $q) {
|
||||
this.dialogService = dialogService;
|
||||
this.$q = $q;
|
||||
|
||||
this.userPromise =
|
||||
dialogService.getUserInput(DIALOG_STRUCTURE, DEFAULT_IDENTITY)
|
||||
.then(echo, giveUndefined);
|
||||
this.returnUser = this.returnUser.bind(this);
|
||||
this.returnUndefined = this.returnUndefined.bind(this);
|
||||
}
|
||||
|
||||
ExampleIdentityProvider.prototype.getUser = function () {
|
||||
return this.userPromise;
|
||||
if (this.user) {
|
||||
return this.$q.when(this.user);
|
||||
} else {
|
||||
return this.dialogService.getUserInput(DIALOG_STRUCTURE, DEFAULT_IDENTITY)
|
||||
.then(this.returnUser, this.returnUndefined);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
ExampleIdentityProvider.prototype.returnUser = function (user) {
|
||||
return this.user = user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
ExampleIdentityProvider.prototype.returnUndefined = function () {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return ExampleIdentityProvider;
|
||||
}
|
||||
);
|
||||
|
@ -1,9 +1,9 @@
|
||||
<span class="status block" ng-controller="DialogLaunchController">
|
||||
<span class="h-indicator" ng-controller="DialogLaunchController">
|
||||
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
|
||||
<span class="status-indicator icon-box-with-arrow"></span><span class="label">
|
||||
<a ng-click="launchProgress(true)">Known</a> |
|
||||
<a ng-click="launchProgress(false)">Unknown</a> |
|
||||
<a ng-click="launchError()">Error</a> |
|
||||
<div class="ls-indicator icon-box-with-arrow s-status-available"><span class="label">
|
||||
<a ng-click="launchProgress(true)">Known</a>
|
||||
<a ng-click="launchProgress(false)">Unknown</a>
|
||||
<a ng-click="launchError()">Error</a>
|
||||
<a ng-click="launchInfo()">Info</a>
|
||||
</span><span class="count"></span>
|
||||
</span></div>
|
||||
</span>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<span class="status block" ng-controller="NotificationLaunchController">
|
||||
<span class="h-indicator" ng-controller="NotificationLaunchController">
|
||||
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
|
||||
<span class="status-indicator icon-bell"></span><span class="label">
|
||||
<a ng-click="newInfo()">Success</a> |
|
||||
<a ng-click="newError()">Error</a> |
|
||||
<a ng-click="newAlert()">Alert</a> |
|
||||
<div class="ls-indicator icon-bell s-status-available"><span class="label">
|
||||
<a ng-click="newInfo()">Success</a>
|
||||
<a ng-click="newError()">Error</a>
|
||||
<a ng-click="newAlert()">Alert</a>
|
||||
<a ng-click="newProgress()">Progress</a>
|
||||
</span><span class="count"></span>
|
||||
</span></div>
|
||||
</span>
|
||||
|
@ -58,7 +58,10 @@
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.w-mct-example > div { margin-bottom: $interiorMarginLg; }
|
||||
.w-mct-example {
|
||||
color: #ccc;
|
||||
> div { margin-bottom: $interiorMarginLg; }
|
||||
}
|
||||
|
||||
code,
|
||||
pre {
|
||||
|
@ -20,12 +20,12 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<style>
|
||||
.w-mct-example div[class*="s-limit"],
|
||||
.w-mct-example div[class*="s-status"],
|
||||
.w-mct-example div[class*="s-unsynced"],
|
||||
.w-mct-example span[class*="s-status"],
|
||||
.w-mct-example div[class*="s-limit"],
|
||||
.w-mct-example span[class*="s-limit"] {
|
||||
border-radius: 4px;
|
||||
padding: 3px 7px;
|
||||
border-radius: 3px;
|
||||
padding: 2px 5px;
|
||||
}
|
||||
.w-mct-example table {
|
||||
width: 100%;
|
||||
@ -36,65 +36,12 @@
|
||||
<h1>Status Indication</h1>
|
||||
|
||||
<div class="l-section">
|
||||
<h2>Overview</h2>
|
||||
<p>Many elements in Open MCT need to articulate a dynamic status; Open MCT provides the following styles and conventions to handle this:</p>
|
||||
<ul>
|
||||
<li><strong>Limits</strong>: when telemetry values exceed minimum or maximum values, they can be violating limits. Limit styles include both color and iconography; color is used to indicate severity while icons are used to indicate direction, upper or lower.</li>
|
||||
<li><strong>Status</strong>: Open MCT also provides a number or built-in Status styles allowing telemetry or other displayed information to be visually classified by type. Common uses for these classes are to visually denote event records.</li>
|
||||
<li><strong>Synchronization</strong>: When the system is displaying real-time data, it is very important that displays clearly indicate when they are not doing so, such as when a plot if frozen while panning or zooming. Open MCT provides a style for this.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="l-section">
|
||||
<h2>Limits</h2>
|
||||
<h2>Status Classes</h2>
|
||||
<div class="cols cols1-1">
|
||||
<div class="col">
|
||||
<p>Limit CSS classes can be applied to any block or inline element. Open MCT limit classes set color and optionally an icon, but don't effect other properties. Yellow and red limit classes can be used as is, or allow the application of any custom icon available in Open MCT's glyphs library. "Level" limit classes - upper and lower - always use an icon in addition to a color; Open MCT doesn't support level limits without color.</p>
|
||||
<ul>
|
||||
<li>Color only</li>
|
||||
<ul>
|
||||
<li><code>s-limit-yellow</code>: A yellow limit.</li>
|
||||
<li><code>s-limit-red</code>: A red limit.</li>
|
||||
</ul>
|
||||
<li>Color and icon</li>
|
||||
<ul>
|
||||
<li><code>s-limit-yellow-icon</code>: A yellow limit with icon.</li>
|
||||
<li><code>s-limit-red-icon</code>: A red limit with icon.</li>
|
||||
</ul>
|
||||
<li>Upper and lower limit indicators. Must be used with a color limit class to be visible.</li>
|
||||
<ul>
|
||||
<li><code>s-limit-upr</code>: Upper limit.
|
||||
</li>
|
||||
<li><code>s-limit-lwr</code>: Lower limit.
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
<mct-example><div class="s-limit-yellow">Yellow limit</div>
|
||||
<div class="s-limit-red">Red limit</div>
|
||||
<div class="s-limit-yellow-icon">Yellow limit with icon</div>
|
||||
<div class="s-limit-red-icon">Red limit with icon</div>
|
||||
<div class="s-limit-yellow s-limit-lwr">Lower yellow limit</div>
|
||||
<div class="s-limit-red s-limit-upr">Upper red limit</div>
|
||||
<div class="s-limit-red icon-bell">Red Limit with a custom icon</div>
|
||||
<div>Some text with an <span class="s-limit-yellow-icon">inline element</span> showing a yellow limit.</div>
|
||||
|
||||
<!-- Limits applied in a table -->
|
||||
<table>
|
||||
<tr class='header'><td>Name</td><td>Value 1</td><td>Value 2</td></tr>
|
||||
<tr><td>ENG_PWR 4991</td><td>7.023</td><td class="s-limit-yellow s-limit-upr">70.23</td></tr>
|
||||
<tr><td>ENG_PWR 4992</td><td>49.784</td><td class="s-limit-red s-limit-lwr">-121.22</td></tr>
|
||||
<tr><td>ENG_PWR 4993</td><td class="s-limit-yellow icon-bell">0.451</td><td>1.007</td></tr>
|
||||
</table>
|
||||
</mct-example>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="l-section">
|
||||
<h2>Status</h2>
|
||||
<div class="cols cols1-1">
|
||||
<div class="col">
|
||||
<p>Classes here can be applied to elements as needed.</p>
|
||||
<p>Status classes allow any block or inline-block element to be decorated in order to articulate a
|
||||
status. Provided classes include color-only and color plus icon; custom icons can easily be
|
||||
employed by using a color-only status class in combination with an <a class="link" href="#/browse/styleguide:home/glyphs?tc.mode=local&tc.timeSystem=utc&tc.startDelta=1800000&tc.endDelta=0&view=styleguide.glyphs">glyph</a>.</p>
|
||||
<ul>
|
||||
<li>Color only</li>
|
||||
<ul>
|
||||
@ -106,37 +53,175 @@
|
||||
</ul>
|
||||
<li>Color and icon</li>
|
||||
<ul>
|
||||
<li><code>s-status-warning-hi-icon</code></li>
|
||||
<li><code>s-status-warning-lo-icon</code></li>
|
||||
<li><code>s-status-diagnostic-icon</code></li>
|
||||
<li><code>s-status-info-icon</code></li>
|
||||
<li><code>s-status-ok-icon</code></li>
|
||||
<li><code>s-status-icon-warning-hi</code></li>
|
||||
<li><code>s-status-icon-warning-lo</code></li>
|
||||
<li><code>s-status-icon-diagnostic</code></li>
|
||||
<li><code>s-status-icon-info</code></li>
|
||||
<li><code>s-status-icon-ok</code></li>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
<mct-example><div class="s-status-warning-hi">WARNING HI</div>
|
||||
<mct-example><!-- Color alone examples -->
|
||||
<div class="s-status-warning-hi">WARNING HI</div>
|
||||
<div class="s-status-warning-lo">WARNING LOW</div>
|
||||
<div class="s-status-diagnostic">DIAGNOSTIC</div>
|
||||
<div class="s-status-info">INFO</div>
|
||||
<div class="s-status-ok">OK</div>
|
||||
<div class="s-status-warning-hi-icon">WARNING HI with icon</div>
|
||||
<div class="s-status-warning-lo-icon">WARNING LOW with icon</div>
|
||||
<div class="s-status-diagnostic-icon">DIAGNOSTIC with icon</div>
|
||||
<div class="s-status-info-icon">INFO with icon</div>
|
||||
<div class="s-status-ok-icon">OK with icon</div>
|
||||
<div class="s-status-warning-hi icon-gear">WARNING HI with custom icon</div>
|
||||
|
||||
<!-- Color and icon examples -->
|
||||
<div class="s-status-icon-warning-hi">WARNING HI with icon</div>
|
||||
<div class="s-status-icon-warning-lo">WARNING LOW with icon</div>
|
||||
<div class="s-status-icon-diagnostic">DIAGNOSTIC with icon</div>
|
||||
<div class="s-status-icon-info">INFO with icon</div>
|
||||
<div class="s-status-icon-ok">OK with icon</div>
|
||||
<div class="s-status-warning-hi icon-alert-triangle">WARNING HI with custom icon</div>
|
||||
<div>Some text with an <span class="s-status-icon-diagnostic">inline element</span> showing a Diagnostic status.</div>
|
||||
</mct-example>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="l-section">
|
||||
<h2>Synchronization</h2>
|
||||
<h2>Limit Classes</h2>
|
||||
<div class="cols cols1-1">
|
||||
<div class="col">
|
||||
<p>When the system is operating in real-time streaming mode, it is important for views that display real-time data to clearly articulate when they are not, such as when a user zooms or pans a plot view, freezing that view. In that case, the CSS class <code>s-unsynced</code> should be applied to that view.</p>
|
||||
<p>Limit classes are a specialized form of status, specifically meant to be applied to telemetry
|
||||
displays to indicate that a limit threshold has been violated. Open MCT provides both severity
|
||||
and direction classes; severity (yellow and red) can be used alone or in combination
|
||||
with direction (upper or lower). Direction classes cannot be used on their own.</p>
|
||||
<p>Like Status classes, Limits can be used as color-only, or color plus icon. Custom icons can
|
||||
be applied in the same fashion as described above.</p>
|
||||
<ul>
|
||||
<li>Severity color alone</li>
|
||||
<ul>
|
||||
<li><code>s-limit-yellow</code>: A yellow limit.</li>
|
||||
<li><code>s-limit-red</code>: A red limit.</li>
|
||||
</ul>
|
||||
<li>Severity color and icon</li>
|
||||
<ul>
|
||||
<li><code>s-limit-icon-yellow</code>: A yellow limit with icon.</li>
|
||||
<li><code>s-limit-icon-red</code>: A red limit with icon.</li>
|
||||
</ul>
|
||||
<li>Direction indicators. MUST be used with a "color alone" limit class. See
|
||||
examples for more.</li>
|
||||
<ul>
|
||||
<li><code>s-limit-upr</code>: Upper limit.</li>
|
||||
<li><code>s-limit-lwr</code>: Lower limit.</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
<mct-example><div class="s-unsynced">This element is unsynced</div>
|
||||
<mct-example><!-- Color alone examples -->
|
||||
<div class="s-limit-yellow">Yellow limit</div>
|
||||
<div class="s-limit-red">Red limit</div>
|
||||
|
||||
<!-- Color and icon examples -->
|
||||
<div class="s-limit-icon-yellow">Yellow limit with icon</div>
|
||||
<div class="s-limit-icon-red">Red limit with icon</div>
|
||||
<div class="s-limit-red icon-alert-rect">Red Limit with a custom icon</div>
|
||||
<div>Some text with an <span class="s-limit-icon-yellow">inline element</span> showing a yellow limit.</div>
|
||||
|
||||
<!-- Severity and direction examples -->
|
||||
<div class="s-limit-yellow s-limit-lwr">Lower yellow limit</div>
|
||||
<div class="s-limit-red s-limit-upr">Upper red limit</div>
|
||||
|
||||
<!-- Limits applied in a table -->
|
||||
<table>
|
||||
<tr class='header'><td>Name</td><td>Value 1</td><td>Value 2</td></tr>
|
||||
<tr><td>ENG_PWR 4991</td><td>7.023</td><td class="s-limit-yellow s-limit-upr">70.23</td></tr>
|
||||
<tr><td>ENG_PWR 4992</td><td>49.784</td><td class="s-limit-red s-limit-lwr">-121.22</td></tr>
|
||||
<tr><td>ENG_PWR 4993</td><td class="s-limit-yellow icon-alert-triangle">0.451</td><td>1.007</td></tr>
|
||||
</table>
|
||||
</mct-example>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="l-section">
|
||||
<h2>Status Bar Indicators</h2>
|
||||
<div class="cols cols1-1">
|
||||
<div class="col">
|
||||
<p>Indicators are small iconic notification elements that appear in the Status Bar area of
|
||||
the application at the window's bottom. Indicators should be used to articulate the state of a
|
||||
system and optionally provide gestures related to that system. They use a combination of icon and
|
||||
color to identify themselves and articulate a state respectively.</p>
|
||||
<h3>Recommendations</h3>
|
||||
<ul>
|
||||
<li><strong>Keep the icon consistent</strong>. The icon is the principal identifier of the system and is a valuable
|
||||
recall aid for the user. Don't change the icon as a system's state changes, use color and
|
||||
text for that purpose.</li>
|
||||
<li><strong>Don't use the same icon more than once</strong>. Select meaningful and distinct icons so the user
|
||||
will be able to quickly identify what they're looking for.</li>
|
||||
</ul>
|
||||
|
||||
<h3>States</h3>
|
||||
<ul>
|
||||
<li><strong>Disabled</strong>: The system is not available to the user.</li>
|
||||
<li><strong>Off / Available</strong>: The system is accessible to the user but is not currently
|
||||
"On" or has not been configured. If the Indicator directly provides gestures
|
||||
related to the system, such as opening a configuration dialog box, then use
|
||||
"Available"; if the user must act elsewhere or the system isn't user-controllable,
|
||||
use "Off".</li>
|
||||
<li><strong>On</strong>: The system is enabled or configured; it is having an effect on the larger application.</li>
|
||||
<li><strong>Alert / Error</strong>: There has been a problem with the system. Generally, "Alert"
|
||||
should be used to call attention to an issue that isn't critical, while "Error"
|
||||
should be used to call attention to a problem that the user should really be aware of or do
|
||||
something about.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Structure</h3>
|
||||
<p>Indicators consist of a <code>.ls-indicator</code>
|
||||
wrapper element with <code>.icon-*</code> classes for the type of thing they represent and
|
||||
<code>.s-status-*</code> classes to articulate the current state. Title attributes should be used
|
||||
to provide more verbose information about the thing and/or its status.</p>
|
||||
<p>The wrapper encloses a <code>.label</code> element that is displayed on hover. This element should
|
||||
include a brief statement of the current status, and can also include clickable elements
|
||||
as <code><a></code> tags. An optional <code>.count</code> element can be included to display
|
||||
information such as a number of messages.</p>
|
||||
<p>Icon classes are as defined on the
|
||||
<a class="link" href="#/browse/styleguide:home/glyphs?tc.mode=local&tc.timeSystem=utc&tc.startDelta=1800000&tc.endDelta=0&view=styleguide.glyphs">
|
||||
Glyphs page</a>. Status classes applicable to Indicators are as follows:</p>
|
||||
<ul>
|
||||
<li><code>s-status-disabled</code></li>
|
||||
<li><code>s-status-off</code></li>
|
||||
<li><code>s-status-available</code></li>
|
||||
<li><code>s-status-on</code></li>
|
||||
<li><code>s-status-alert</code></li>
|
||||
<li><code>s-status-error</code></li>
|
||||
</ul>
|
||||
</div>
|
||||
<mct-example><div class="s-ue-bottom-bar status-holder s-status-bar">
|
||||
<span class="ls-indicator icon-database s-status-disabled" title="The system is currently disabled.">
|
||||
<span class="label">System not enabled.</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="s-ue-bottom-bar status-holder s-status-bar">
|
||||
<span class="ls-indicator icon-database s-status-available" title="Configure data connection.">
|
||||
<span class="label">Data connection available
|
||||
<a class="icon-gear">Configure</a>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="s-ue-bottom-bar status-holder s-status-bar">
|
||||
<span class="ls-indicator icon-database s-status-on" title="Data connected.">
|
||||
<span class="label">Connected to Skynet
|
||||
<a class="icon-gear">Change</a>
|
||||
<a>Disconnect</a>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="s-ue-bottom-bar status-holder s-status-bar">
|
||||
<span class="ls-indicator icon-database s-status-alert" title="System is self-aware.">
|
||||
<span class="label">Skynet at Turing Level 5</span>
|
||||
</span>
|
||||
<span class="ls-indicator icon-bell s-status-error" title="You have alerts.">
|
||||
<span class="label">
|
||||
<a class="icon-alert-triangle">View Alerts</a>
|
||||
</span>
|
||||
<span class="count">495</span>
|
||||
</span>
|
||||
</div>
|
||||
</mct-example>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -54,7 +54,7 @@ define(
|
||||
return "icon-object-unknown";
|
||||
},
|
||||
getText: function () {
|
||||
return latest;
|
||||
return "" + latest;
|
||||
},
|
||||
getDescription: function () {
|
||||
return "";
|
||||
|
@ -30,7 +30,7 @@
|
||||
<script>
|
||||
var THIRTY_MINUTES = 30 * 60 * 1000;
|
||||
|
||||
require(['openmct', './src/plugins/telemetryTable/plugin'], function (openmct, TelemetryTablePlugin) {
|
||||
require(['openmct'], function (openmct) {
|
||||
[
|
||||
'example/eventGenerator',
|
||||
'example/styleguide'
|
||||
@ -70,10 +70,10 @@
|
||||
}));
|
||||
openmct.install(openmct.plugins.SummaryWidget());
|
||||
openmct.install(openmct.plugins.Notebook());
|
||||
openmct.install(TelemetryTablePlugin());
|
||||
openmct.time.clock('local', {start: -THIRTY_MINUTES, end: 0});
|
||||
openmct.time.timeSystem('utc');
|
||||
openmct.start();
|
||||
window.openmct = openmct;
|
||||
});
|
||||
</script>
|
||||
<link rel="stylesheet" href="platform/commonUI/general/res/css/startup-base.css">
|
||||
|
68
notes.md
68
notes.md
@ -1,68 +0,0 @@
|
||||
* Delete old table
|
||||
* Update new table type and test backward compatibility.
|
||||
* re-evaluate TableConfiguration object. Name doesn't make sense right now, and some duplicated code for configuration handling in components.
|
||||
* Rebase over refactor branch
|
||||
* Move css to new table location
|
||||
* Test (see list of issues below)
|
||||
* Push WIP PR
|
||||
|
||||
* [X] Remove column sizing rows on object removal (should be trivial since tracking by object ID already).
|
||||
* [X] Look at optimizing styles in telemetry-table-row
|
||||
- Right now profiling does not highlight this as a bottleneck?
|
||||
* [X] Add title to table cells
|
||||
* [X] Add elipses for overflow on table cells
|
||||
* [X] On entry, filter boxes need to remove magnifying glass.
|
||||
* [X] auto-scroll
|
||||
* [X] Show / hide columns (ie. table configuration)
|
||||
* [X] Why aren't limits being applied until I scroll or do something?
|
||||
* [X] Handle window resizing
|
||||
* [X] Fix memory leaks
|
||||
* [X] Remove isFromObject and hasColumn from TelemetryTableRow
|
||||
* [X] Remove format caching
|
||||
* [X] Add filtering
|
||||
* If the new filter string starts with the old filter string, filter based on the list of previously filtered results, not the base list.
|
||||
* Add the clear filter button
|
||||
* [X] Cache formatted values for "just in time" formatting. I think cache on row. Opportunity to cache on column to benefit from multiple rows with the same value, but memory management becomes a problem then as cache could grow infinitely if the table is left to run.
|
||||
* [X] Do some more testing with multiple objects. Not working properly right now.
|
||||
* [X] Rows not being removed when object removed from composition
|
||||
* [X] Subscribe to realtime data
|
||||
* [X] Column widths should be done on receipt of FIRST DATA, not on receipt of historical data.
|
||||
* [X] Filter subscription data
|
||||
* [X] Export
|
||||
* [X] Add loading spinner
|
||||
* [X] in 'mounted', should not be necessary to bind to 'this'.
|
||||
* [X] Stop Vue from decorating EVERYTHING (but especially the telemetry collection)
|
||||
* [X] Need minimum width on tables. Provided by calcTableWidthPx in MCTTableController
|
||||
* [X] Limits
|
||||
|
||||
* Benchmark - loading 1 million rows
|
||||
- Old tables: ~90s
|
||||
- New tables: ~11s
|
||||
* 1 million rows in 11 secs vs 90s
|
||||
|
||||
To Test
|
||||
* Multiple instances of tables
|
||||
* Make sure time columns are being correctly merged
|
||||
* Test with MSL data sources
|
||||
* Test with tutorial data sources
|
||||
* Behavior at different widths.
|
||||
* Short tables
|
||||
* Test with bounds / clock / time system changes.
|
||||
* Memory leaks
|
||||
|
||||
Post WIP PR
|
||||
* Fix jitter on auto-scroll
|
||||
* Look at scroll-x again. Sounded like there might be some subtlety missing there (something to do with small columns?).
|
||||
* Split TelemetryTableComponent into more components. It's too large now.
|
||||
* Performance
|
||||
* Don't wrap row on load, do it on scroll.
|
||||
* On batch insert, check bounds once, rather than on each insert.
|
||||
* See if sticky headers can be simplified (eg. can we combine headers table with content table?)
|
||||
* Default sort behavior, and sticking to the bottom for realtime numerical
|
||||
* Look at setting top on tbody, instead of each tr
|
||||
* Replace all "mct-table" classes
|
||||
* Consider making the sizing row a separate component. Encapsulate all sizing logic in there.
|
||||
* consider making the header table a separate component.
|
||||
* Test where no time column present (what will it sort by)
|
||||
|
||||
* [X] Optimization - don't both sorting filtered rows initially, just copy over values from bounded row collection which have already been sorted.
|
@ -59,6 +59,8 @@
|
||||
"start": "node app.js",
|
||||
"test": "karma start --single-run",
|
||||
"jshint": "jshint platform example",
|
||||
"lint": "./node_modules/gulp/bin/gulp.js lint",
|
||||
"checkstyle": "./node_modules/gulp/bin/gulp.js checkstyle",
|
||||
"watch": "karma start",
|
||||
"jsdoc": "jsdoc -c jsdoc.json -R API.md -r -d dist/docs/api",
|
||||
"otherdoc": "node docs/gendocs.js --in docs/src --out dist/docs --suppress-toc 'docs/src/index.md|docs/src/process/index.md'",
|
||||
|
@ -33,6 +33,7 @@ define([
|
||||
"./src/actions/SaveAndStopEditingAction",
|
||||
"./src/actions/SaveAsAction",
|
||||
"./src/actions/CancelAction",
|
||||
"./src/actions/CreateNewFolderAction",
|
||||
"./src/policies/EditActionPolicy",
|
||||
"./src/policies/EditPersistableObjectsPolicy",
|
||||
"./src/policies/EditableLinkPolicy",
|
||||
@ -71,6 +72,7 @@ define([
|
||||
SaveAndStopEditingAction,
|
||||
SaveAsAction,
|
||||
CancelAction,
|
||||
CreateNewFolderAction,
|
||||
EditActionPolicy,
|
||||
EditPersistableObjectsPolicy,
|
||||
EditableLinkPolicy,
|
||||
@ -145,7 +147,10 @@ define([
|
||||
"depends": [
|
||||
"$scope",
|
||||
"$timeout",
|
||||
"objectService"
|
||||
"objectService",
|
||||
"typeService",
|
||||
"policyService",
|
||||
"instantiate"
|
||||
]
|
||||
}
|
||||
],
|
||||
@ -188,6 +193,7 @@ define([
|
||||
"name": "Remove",
|
||||
"description": "Remove this object from its containing object.",
|
||||
"depends": [
|
||||
"dialogService",
|
||||
"navigationService"
|
||||
]
|
||||
},
|
||||
@ -241,6 +247,14 @@ define([
|
||||
"cssClass": "icon-x no-label",
|
||||
"description": "Discard changes made to these objects.",
|
||||
"depends": []
|
||||
},
|
||||
{
|
||||
"key": "create-new-folder",
|
||||
"implementation": CreateNewFolderAction,
|
||||
"description": "Creates a new folder.",
|
||||
"depends": [
|
||||
"typeService"
|
||||
]
|
||||
}
|
||||
],
|
||||
"policies": [
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
Open MCT, Copyright (c) 2009-2016, United States Government
|
||||
<!--span
|
||||
Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
as represented by the Administrator of the National Aeronautics and Space
|
||||
Administration. All rights reserved.
|
||||
|
||||
@ -19,19 +19,15 @@
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<div class="l-title s-title">
|
||||
{{parameters.title}}
|
||||
</div>
|
||||
<div class="l-graph-area">
|
||||
<div class="l-labels-holder l-flex-col">
|
||||
<div class="t-resource-graph-tick-label tick-label-y flex-elem">
|
||||
{{parameters.high}}
|
||||
</div>
|
||||
<div class="t-resource-graph-tick-label tick-label-y flex-elem">
|
||||
{{parameters.middle}}
|
||||
</div>
|
||||
<div class="t-resource-graph-tick-label tick-label-y flex-elem">
|
||||
{{parameters.low}}
|
||||
</div>
|
||||
</div>
|
||||
<div name="newFolder" ng-controller="LocatorController">
|
||||
<div ng-if="!createNewFolder">
|
||||
<a class="s-button icon-folder-new" ng-click="createNewFolderClickHandler()" >
|
||||
<span class="title-label">New Folder</span>
|
||||
</a>
|
||||
</div>
|
||||
<div ng-if="createNewFolder">
|
||||
<span><input type="text" ng-model="newFolderName" name="newFolderName"></span>
|
||||
<a class="s-button" ng-click="createClickHandler()">Create</a>
|
||||
<a class="s-button icon-x" ng-click="cancelClickHandler()"></a>
|
||||
</div>
|
||||
</div>
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
Open MCT, Copyright (c) 2014-2017, United States Government
|
||||
as represented by the Administrator of the National Aeronautics and Space
|
||||
Administration. All rights reserved.
|
||||
|
||||
@ -26,4 +26,22 @@
|
||||
ng-model="treeModel">
|
||||
</mct-representation>
|
||||
</div>
|
||||
|
||||
<!-- Create New Folder Action -->
|
||||
<div class="newFolderCreation" style="margin-top:10px; position:absolute; left:0px;">
|
||||
|
||||
<!-- New folder button, triggers create new folder action. -->
|
||||
<div ng-show="!newFolderCreationTriggered">
|
||||
<a class="s-button icon-folder-new" ng-class="{disabled: !validParent()}" ng-click="newFolderButtonClickHandler()">
|
||||
<span class="text-label">New Folder</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Get folder name -->
|
||||
<div ng-show="newFolderCreationTriggered">
|
||||
<input type="text" ng-model="newFolderNameInput">
|
||||
<a class="s-button" ng-class="{ disabled: !validParent() || !validFolderName() }" ng-click="newFolderCreateButtonClickHandler()">Create</a>
|
||||
<a class="s-button icon-x" ng-click="newFolderCancelButtonClickHandler()"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
89
platform/commonUI/edit/src/actions/CreateNewFolderAction.js
Normal file
89
platform/commonUI/edit/src/actions/CreateNewFolderAction.js
Normal file
@ -0,0 +1,89 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
define([
|
||||
|
||||
],
|
||||
function (
|
||||
|
||||
) {
|
||||
|
||||
/**
|
||||
* The CreateNewFolderAction; action is triggered by the new folder button in the locator.
|
||||
*
|
||||
* @constructor
|
||||
* @implements {Action}
|
||||
* @memberof platform/commonUI/edit
|
||||
*/
|
||||
function CreateNewFolderAction(
|
||||
typeService,
|
||||
context
|
||||
) {
|
||||
this.parent = (context || {}).domainObject;
|
||||
this.typeService = typeService;
|
||||
this.type = typeService.getType('folder');
|
||||
}
|
||||
|
||||
CreateNewFolderAction.prototype.perform = function (folderName) {
|
||||
var parent = this.parent,
|
||||
typeService = this.typeService,
|
||||
newModel = this.type.getInitialModel(),
|
||||
folderType = typeService.getType('folder');
|
||||
|
||||
newModel.type = folderType.getKey();
|
||||
newModel.name = folderName;
|
||||
|
||||
function instantiateObject() {
|
||||
var newObject = parent.useCapability('instantiation', newModel);
|
||||
newObject.useCapability('mutation', function () {
|
||||
newModel.location = parent.getId();
|
||||
});
|
||||
return addToParentAndReturn(newObject);
|
||||
}
|
||||
|
||||
function addToParentAndReturn(newObject) {
|
||||
return parent.getCapability('composition').add(newObject)
|
||||
.then(function () {
|
||||
return newObject;
|
||||
});
|
||||
}
|
||||
|
||||
return instantiateObject(newModel, parent);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if this action is applicable in a given context.
|
||||
* This will ensure that a domain object is present in the context,
|
||||
* and that this domain object is in Edit mode.
|
||||
* @returns true if applicable
|
||||
*/
|
||||
CreateNewFolderAction.appliesTo = function (context) {
|
||||
var parent = (context || {}).domainObject;
|
||||
return parent && parent.hasCapability('editor');
|
||||
|
||||
};
|
||||
|
||||
return CreateNewFolderAction;
|
||||
}
|
||||
);
|
||||
|
@ -23,111 +23,119 @@
|
||||
/**
|
||||
* Module defining RemoveAction. Created by vwoeltje on 11/17/14.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
define([
|
||||
'./RemoveDialog'
|
||||
], function (
|
||||
RemoveDialog
|
||||
) {
|
||||
|
||||
/**
|
||||
* Construct an action which will remove the provided object manifestation.
|
||||
* The object will be removed from its parent's composition; the parent
|
||||
* is looked up via the "context" capability (so this will be the
|
||||
* immediate ancestor by which this specific object was reached.)
|
||||
*
|
||||
* @param {DomainObject} object the object to be removed
|
||||
* @param {ActionContext} context the context in which this action is performed
|
||||
* @memberof platform/commonUI/edit
|
||||
* @constructor
|
||||
* @implements {Action}
|
||||
/**
|
||||
* Construct an action which will remove the provided object manifestation.
|
||||
* The object will be removed from its parent's composition; the parent
|
||||
* is looked up via the "context" capability (so this will be the
|
||||
* immediate ancestor by which this specific object was reached.)
|
||||
*
|
||||
* @param {DialogService} dialogService a service which will show the dialog
|
||||
* @param {NavigationService} navigationService a service that maintains the current navigation state
|
||||
* @param {ActionContext} context the context in which this action is performed
|
||||
* @memberof platform/commonUI/edit
|
||||
* @constructor
|
||||
* @implements {Action}
|
||||
*/
|
||||
function RemoveAction(dialogService, navigationService, context) {
|
||||
this.domainObject = (context || {}).domainObject;
|
||||
this.dialogService = dialogService;
|
||||
this.navigationService = navigationService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform this action.
|
||||
*/
|
||||
RemoveAction.prototype.perform = function () {
|
||||
var dialog,
|
||||
dialogService = this.dialogService,
|
||||
domainObject = this.domainObject,
|
||||
navigationService = this.navigationService;
|
||||
/*
|
||||
* Check whether an object ID matches the ID of the object being
|
||||
* removed (used to filter a parent's composition to handle the
|
||||
* removal.)
|
||||
*/
|
||||
function RemoveAction(navigationService, context) {
|
||||
this.domainObject = (context || {}).domainObject;
|
||||
this.navigationService = navigationService;
|
||||
function isNotObject(otherObjectId) {
|
||||
return otherObjectId !== domainObject.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform this action.
|
||||
* @return {Promise} a promise which will be
|
||||
* fulfilled when the action has completed.
|
||||
/*
|
||||
* Mutate a parent object such that it no longer contains the object
|
||||
* which is being removed.
|
||||
*/
|
||||
RemoveAction.prototype.perform = function () {
|
||||
var navigationService = this.navigationService,
|
||||
domainObject = this.domainObject;
|
||||
/*
|
||||
* Check whether an object ID matches the ID of the object being
|
||||
* removed (used to filter a parent's composition to handle the
|
||||
* removal.)
|
||||
*/
|
||||
function isNotObject(otherObjectId) {
|
||||
return otherObjectId !== domainObject.getId();
|
||||
}
|
||||
function doMutate(model) {
|
||||
model.composition = model.composition.filter(isNotObject);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mutate a parent object such that it no longer contains the object
|
||||
* which is being removed.
|
||||
*/
|
||||
function doMutate(model) {
|
||||
model.composition = model.composition.filter(isNotObject);
|
||||
}
|
||||
/*
|
||||
* Checks current object and ascendants of current
|
||||
* object with object being removed, if the current
|
||||
* object or any in the current object's path is being removed,
|
||||
* navigate back to parent of removed object.
|
||||
*/
|
||||
function checkObjectNavigation(object, parentObject) {
|
||||
// Traverse object starts at current location
|
||||
var traverseObject = (navigationService).getNavigation(),
|
||||
context;
|
||||
|
||||
/*
|
||||
* Checks current object and ascendants of current
|
||||
* object with object being removed, if the current
|
||||
* object or any in the current object's path is being removed,
|
||||
* navigate back to parent of removed object.
|
||||
*/
|
||||
function checkObjectNavigation(object, parentObject) {
|
||||
// Traverse object starts at current location
|
||||
var traverseObject = (navigationService).getNavigation(),
|
||||
context;
|
||||
|
||||
// Stop when object is not defined (above ROOT)
|
||||
while (traverseObject) {
|
||||
// If object currently traversed to is object being removed
|
||||
// navigate to parent of current object and then exit loop
|
||||
if (traverseObject.getId() === object.getId()) {
|
||||
navigationService.setNavigation(parentObject);
|
||||
return;
|
||||
}
|
||||
// Traverses to parent of current object, moving
|
||||
// up the ascendant path
|
||||
context = traverseObject.getCapability('context');
|
||||
traverseObject = context && context.getParent();
|
||||
// Stop when object is not defined (above ROOT)
|
||||
while (traverseObject) {
|
||||
// If object currently traversed to is object being removed
|
||||
// navigate to parent of current object and then exit loop
|
||||
if (traverseObject.getId() === object.getId()) {
|
||||
navigationService.setNavigation(parentObject);
|
||||
return;
|
||||
}
|
||||
// Traverses to parent of current object, moving
|
||||
// up the ascendant path
|
||||
context = traverseObject.getCapability('context');
|
||||
traverseObject = context && context.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the object from its parent, as identified by its context
|
||||
* capability. Based on object's location and selected object's location
|
||||
* user may be navigated to existing parent object
|
||||
*/
|
||||
function removeFromContext(object) {
|
||||
var contextCapability = object.getCapability('context'),
|
||||
parent = contextCapability.getParent();
|
||||
/*
|
||||
* Remove the object from its parent, as identified by its context
|
||||
* capability. Based on object's location and selected object's location
|
||||
* user may be navigated to existing parent object
|
||||
*/
|
||||
function removeFromContext(object) {
|
||||
var contextCapability = object.getCapability('context'),
|
||||
parent = contextCapability.getParent();
|
||||
|
||||
// If currently within path of removed object(s),
|
||||
// navigates to existing object up tree
|
||||
checkObjectNavigation(object, parent);
|
||||
// If currently within path of removed object(s),
|
||||
// navigates to existing object up tree
|
||||
checkObjectNavigation(object, parent);
|
||||
|
||||
return parent.useCapability('mutation', doMutate);
|
||||
}
|
||||
return parent.useCapability('mutation', doMutate);
|
||||
}
|
||||
|
||||
return removeFromContext(domainObject);
|
||||
};
|
||||
/*
|
||||
* Pass in the function to remove the domain object so it can be
|
||||
* associated with an 'OK' button press
|
||||
*/
|
||||
dialog = new RemoveDialog(dialogService, domainObject, removeFromContext);
|
||||
dialog.show();
|
||||
};
|
||||
|
||||
// Object needs to have a parent for Remove to be applicable
|
||||
RemoveAction.appliesTo = function (context) {
|
||||
var object = (context || {}).domainObject,
|
||||
contextCapability = object && object.getCapability("context"),
|
||||
parent = contextCapability && contextCapability.getParent(),
|
||||
parentType = parent && parent.getCapability('type'),
|
||||
parentCreatable = parentType && parentType.hasFeature('creation');
|
||||
// Object needs to have a parent for Remove to be applicable
|
||||
RemoveAction.appliesTo = function (context) {
|
||||
var object = (context || {}).domainObject,
|
||||
contextCapability = object && object.getCapability("context"),
|
||||
parent = contextCapability && contextCapability.getParent(),
|
||||
parentType = parent && parent.getCapability('type'),
|
||||
parentCreatable = parentType && parentType.hasFeature('creation');
|
||||
|
||||
// Only creatable types should be modifiable
|
||||
return parent !== undefined &&
|
||||
Array.isArray(parent.getModel().composition) &&
|
||||
parentCreatable;
|
||||
};
|
||||
// Only creatable types should be modifiable
|
||||
return parent !== undefined &&
|
||||
Array.isArray(parent.getModel().composition) &&
|
||||
parentCreatable;
|
||||
};
|
||||
|
||||
return RemoveAction;
|
||||
}
|
||||
);
|
||||
return RemoveAction;
|
||||
});
|
||||
|
77
platform/commonUI/edit/src/actions/RemoveDialog.js
Normal file
77
platform/commonUI/edit/src/actions/RemoveDialog.js
Normal file
@ -0,0 +1,77 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2017, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define([], function () {
|
||||
|
||||
/**
|
||||
* @callback removeCallback
|
||||
* @param {DomainObject} domainObject the domain object to be removed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Construct a new Remove dialog.
|
||||
*
|
||||
* @param {DialogService} dialogService the service that shows the dialog
|
||||
* @param {DomainObject} domainObject the domain object to be removed
|
||||
* @param {removeCallback} removeCallback callback that handles removal of the domain object
|
||||
* @memberof platform/commonUI/edit
|
||||
* @constructor
|
||||
*/
|
||||
function RemoveDialog(dialogService, domainObject, removeCallback) {
|
||||
this.dialogService = dialogService;
|
||||
this.domainObject = domainObject;
|
||||
this.removeCallback = removeCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a dialog to confirm the removal of a domain object.
|
||||
*/
|
||||
RemoveDialog.prototype.show = function () {
|
||||
var dialog,
|
||||
domainObject = this.domainObject,
|
||||
removeCallback = this.removeCallback,
|
||||
model = {
|
||||
title: 'Remove ' + domainObject.getModel().name,
|
||||
actionText: 'Warning! This action will permanently remove this object. Are you sure you want to continue?',
|
||||
severity: 'alert',
|
||||
primaryOption: {
|
||||
label: 'OK',
|
||||
callback: function () {
|
||||
removeCallback(domainObject);
|
||||
dialog.dismiss();
|
||||
}
|
||||
},
|
||||
options: [
|
||||
{
|
||||
label: 'Cancel',
|
||||
callback: function () {
|
||||
dialog.dismiss();
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
dialog = this.dialogService.showBlockingMessage(model);
|
||||
};
|
||||
|
||||
return RemoveDialog;
|
||||
});
|
@ -1,5 +1,5 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* Open MCT, Copyright (c) 2014-2017, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
@ -31,7 +31,7 @@ define(
|
||||
* @memberof platform/commonUI/browse
|
||||
* @constructor
|
||||
*/
|
||||
function LocatorController($scope, $timeout, objectService) {
|
||||
function LocatorController($scope, $timeout, objectService, typeService, policyService, instantiate) {
|
||||
// Populate values needed by the locator control. These are:
|
||||
// * rootObject: The top-level object, since we want to show
|
||||
// the full tree
|
||||
@ -66,8 +66,8 @@ define(
|
||||
|
||||
// Restrict which locations can be selected
|
||||
if (domainObject &&
|
||||
$scope.structure &&
|
||||
$scope.structure.validate) {
|
||||
$scope.structure &&
|
||||
$scope.structure.validate) {
|
||||
if (!$scope.structure.validate(domainObject)) {
|
||||
setLocatingObject(priorObject, undefined);
|
||||
return;
|
||||
@ -81,11 +81,64 @@ define(
|
||||
!!$scope.treeModel.selectedObject
|
||||
);
|
||||
}
|
||||
|
||||
// Check if create new folder is a valid action for selected object
|
||||
$scope.validParent = function () {
|
||||
if ($scope.treeModel.selectedObject) {
|
||||
return policyService.allow(
|
||||
"composition",
|
||||
$scope.treeModel.selectedObject,
|
||||
instantiate(typeService.getType('folder').getInitialModel())
|
||||
);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$scope.newFolderButtonClickHandler = function () {
|
||||
$scope.newFolderCreationTriggered = true;
|
||||
};
|
||||
|
||||
$scope.newFolderCancelButtonClickHandler = function () {
|
||||
$scope.newFolderCreationTriggered = false;
|
||||
resetNewFolderNameInput();
|
||||
};
|
||||
|
||||
// Get expected input pattern for folder name
|
||||
var folderNamePattern = new RegExp(
|
||||
typeService.getType('folder').getProperties()[0].propertyDefinition.pattern
|
||||
);
|
||||
|
||||
// Validate folder name externally to avoid affecting overall form validation
|
||||
$scope.validFolderName = function () {
|
||||
return $scope.newFolderNameInput && folderNamePattern.test($scope.newFolderNameInput);
|
||||
};
|
||||
|
||||
function selectAndScrollToNewFolder(newFolder) {
|
||||
$scope.treeModel.selectedObject = newFolder;
|
||||
}
|
||||
|
||||
function resetNewFolderNameInput() {
|
||||
$scope.newFolderNameInput = "Unnamed Folder";
|
||||
$scope.newFolderCreationTriggered = false;
|
||||
}
|
||||
|
||||
|
||||
// Create new folder, update selection to new folder and reset new folder button
|
||||
$scope.newFolderCreateButtonClickHandler = function () {
|
||||
var createNewFolderAction = $scope.treeModel.selectedObject.getCapability('action').getActions('create-new-folder')[0];
|
||||
createNewFolderAction.perform($scope.newFolderNameInput)
|
||||
.then(selectAndScrollToNewFolder)
|
||||
.then(resetNewFolderNameInput);
|
||||
};
|
||||
|
||||
// Initial state for the tree's model
|
||||
$scope.treeModel =
|
||||
{ selectedObject: $scope.ngModel[$scope.field] };
|
||||
$scope.treeModel = { selectedObject: $scope.ngModel[$scope.field] };
|
||||
|
||||
//Initial values for new folder action
|
||||
$scope.newFolderNameInput = "Unnamed Folder";
|
||||
$scope.newFolderCreationTriggered = false;
|
||||
|
||||
// Watch for changes from the tree
|
||||
$scope.$watch("treeModel.selectedObject", setLocatingObject);
|
||||
|
117
platform/commonUI/edit/test/actions/CreateNewFolderActionSpec.js
Normal file
117
platform/commonUI/edit/test/actions/CreateNewFolderActionSpec.js
Normal file
@ -0,0 +1,117 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
['../../src/actions/CreateNewFolderAction'],
|
||||
function (CreateNewFolderAction) {
|
||||
|
||||
describe("The Create New Folder Action", function () {
|
||||
var mockDomainObject,
|
||||
mockNewObject,
|
||||
mockType,
|
||||
testModel,
|
||||
mockFolderName,
|
||||
mockTypeService,
|
||||
mockActionContext,
|
||||
mockCompositionCapability,
|
||||
action;
|
||||
function mockPromise(value) {
|
||||
return (value && value.then) ? value : {
|
||||
then: function (callback) {
|
||||
return mockPromise(callback(value));
|
||||
}
|
||||
};
|
||||
}
|
||||
beforeEach(function () {
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
"domainObject",
|
||||
[
|
||||
"getCapability",
|
||||
"useCapability",
|
||||
"hasCapability",
|
||||
"getId"
|
||||
]
|
||||
);
|
||||
mockNewObject = jasmine.createSpyObj(
|
||||
"newObject",
|
||||
[
|
||||
"getCapability",
|
||||
"useCapability",
|
||||
"hasCapability",
|
||||
"getId"
|
||||
]
|
||||
);
|
||||
mockType = jasmine.createSpyObj(
|
||||
"type",
|
||||
[
|
||||
"getKey",
|
||||
"getInitialModel"
|
||||
]
|
||||
);
|
||||
testModel = {
|
||||
type: mockType,
|
||||
name: "Name",
|
||||
location: "someLocation"
|
||||
};
|
||||
mockFolderName = "Name";
|
||||
mockTypeService = jasmine.createSpyObj(
|
||||
"typeService",
|
||||
["getType"]
|
||||
);
|
||||
mockActionContext = { domainObject: mockDomainObject };
|
||||
mockCompositionCapability = jasmine.createSpyObj(
|
||||
"composition",
|
||||
["add"]
|
||||
);
|
||||
mockType.getKey.and.returnValue("test");
|
||||
mockType.getInitialModel.and.returnValue(testModel);
|
||||
mockDomainObject.getCapability.and.callFake(function (capability) {
|
||||
return (capability === 'composition') && mockCompositionCapability;
|
||||
});
|
||||
mockDomainObject.hasCapability.and.returnValue(true);
|
||||
mockCompositionCapability.add.and.returnValue(mockPromise(true));
|
||||
mockDomainObject.useCapability.and.callFake(function (capability) {
|
||||
return (capability === 'instantiation') && mockNewObject;
|
||||
});
|
||||
mockTypeService.getType.and.returnValue(mockType);
|
||||
mockDomainObject.getId.and.returnValue("id");
|
||||
action = new CreateNewFolderAction(mockTypeService, mockActionContext);
|
||||
});
|
||||
it("uses the instantiation capability when performed", function () {
|
||||
action.perform(mockFolderName);
|
||||
expect(mockDomainObject.useCapability)
|
||||
.toHaveBeenCalledWith("instantiation", jasmine.any(Object));
|
||||
});
|
||||
it("adds new objects to the parent's composition", function () {
|
||||
action.perform(mockFolderName);
|
||||
expect(mockDomainObject.getCapability).toHaveBeenCalledWith("composition");
|
||||
expect(mockCompositionCapability.add).toHaveBeenCalled();
|
||||
});
|
||||
it("is only applicable when a domain object is in context", function () {
|
||||
expect(CreateNewFolderAction.appliesTo(mockActionContext)).toBeTruthy();
|
||||
expect(CreateNewFolderAction.appliesTo({})).toBeFalsy();
|
||||
expect(mockDomainObject.hasCapability).toHaveBeenCalledWith('editor');
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
@ -25,50 +25,37 @@ define(
|
||||
function (RemoveAction) {
|
||||
|
||||
describe("The Remove action", function () {
|
||||
var mockQ,
|
||||
mockNavigationService,
|
||||
mockDomainObject,
|
||||
mockParent,
|
||||
mockChildObject,
|
||||
mockGrandchildObject,
|
||||
mockRootObject,
|
||||
mockContext,
|
||||
mockChildContext,
|
||||
mockGrandchildContext,
|
||||
mockRootContext,
|
||||
mockMutation,
|
||||
mockType,
|
||||
var action,
|
||||
actionContext,
|
||||
model,
|
||||
capabilities,
|
||||
action;
|
||||
|
||||
function mockPromise(value) {
|
||||
return {
|
||||
then: function (callback) {
|
||||
return mockPromise(callback(value));
|
||||
}
|
||||
};
|
||||
}
|
||||
mockContext,
|
||||
mockDialogService,
|
||||
mockDomainObject,
|
||||
mockMutation,
|
||||
mockNavigationService,
|
||||
mockParent,
|
||||
mockType,
|
||||
model;
|
||||
|
||||
beforeEach(function () {
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
"domainObject",
|
||||
["getId", "getCapability"]
|
||||
["getId", "getCapability", "getModel"]
|
||||
);
|
||||
mockChildObject = jasmine.createSpyObj(
|
||||
"domainObject",
|
||||
["getId", "getCapability"]
|
||||
);
|
||||
mockGrandchildObject = jasmine.createSpyObj(
|
||||
"domainObject",
|
||||
["getId", "getCapability"]
|
||||
);
|
||||
mockRootObject = jasmine.createSpyObj(
|
||||
"domainObject",
|
||||
["getId", "getCapability"]
|
||||
);
|
||||
mockQ = { when: mockPromise };
|
||||
|
||||
mockMutation = jasmine.createSpyObj("mutation", ["invoke"]);
|
||||
mockType = jasmine.createSpyObj("type", ["hasFeature"]);
|
||||
mockType.hasFeature.and.returnValue(true);
|
||||
|
||||
capabilities = {
|
||||
mutation: mockMutation,
|
||||
type: mockType
|
||||
};
|
||||
|
||||
model = {
|
||||
composition: ["a", "test", "b"]
|
||||
};
|
||||
|
||||
mockParent = {
|
||||
getModel: function () {
|
||||
return model;
|
||||
@ -80,12 +67,12 @@ define(
|
||||
return capabilities[k].invoke(v);
|
||||
}
|
||||
};
|
||||
mockContext = jasmine.createSpyObj("context", ["getParent"]);
|
||||
mockChildContext = jasmine.createSpyObj("context", ["getParent"]);
|
||||
mockGrandchildContext = jasmine.createSpyObj("context", ["getParent"]);
|
||||
mockRootContext = jasmine.createSpyObj("context", ["getParent"]);
|
||||
mockMutation = jasmine.createSpyObj("mutation", ["invoke"]);
|
||||
mockType = jasmine.createSpyObj("type", ["hasFeature"]);
|
||||
|
||||
mockDialogService = jasmine.createSpyObj(
|
||||
"dialogService",
|
||||
["showBlockingMessage"]
|
||||
);
|
||||
|
||||
mockNavigationService = jasmine.createSpyObj(
|
||||
"navigationService",
|
||||
[
|
||||
@ -97,23 +84,19 @@ define(
|
||||
);
|
||||
mockNavigationService.getNavigation.and.returnValue(mockDomainObject);
|
||||
|
||||
mockContext = jasmine.createSpyObj("context", ["getParent"]);
|
||||
mockContext.getParent.and.returnValue(mockParent);
|
||||
|
||||
mockDomainObject.getId.and.returnValue("test");
|
||||
mockDomainObject.getCapability.and.returnValue(mockContext);
|
||||
mockDomainObject.getModel.and.returnValue({name: 'test object'});
|
||||
|
||||
mockContext.getParent.and.returnValue(mockParent);
|
||||
mockType.hasFeature.and.returnValue(true);
|
||||
|
||||
capabilities = {
|
||||
mutation: mockMutation,
|
||||
type: mockType
|
||||
};
|
||||
model = {
|
||||
composition: ["a", "test", "b"]
|
||||
};
|
||||
|
||||
actionContext = { domainObject: mockDomainObject };
|
||||
|
||||
action = new RemoveAction(mockNavigationService, actionContext);
|
||||
action = new RemoveAction(mockDialogService, mockNavigationService, actionContext);
|
||||
});
|
||||
|
||||
it("only applies to objects with parents", function () {
|
||||
@ -127,83 +110,146 @@ define(
|
||||
expect(mockType.hasFeature).toHaveBeenCalledWith('creation');
|
||||
});
|
||||
|
||||
it("mutates the parent when performed", function () {
|
||||
action.perform();
|
||||
expect(mockMutation.invoke)
|
||||
.toHaveBeenCalledWith(jasmine.any(Function));
|
||||
});
|
||||
|
||||
it("changes composition from its mutation function", function () {
|
||||
var mutator, result;
|
||||
action.perform();
|
||||
mutator = mockMutation.invoke.calls.mostRecent().args[0];
|
||||
result = mutator(model);
|
||||
|
||||
// Should not have cancelled the mutation
|
||||
expect(result).not.toBe(false);
|
||||
|
||||
// Simulate mutate's behavior (remove can either return a
|
||||
// new model or modify this one in-place)
|
||||
result = result || model;
|
||||
|
||||
// Should have removed "test" - that was our
|
||||
// mock domain object's id.
|
||||
expect(result.composition).toEqual(["a", "b"]);
|
||||
});
|
||||
|
||||
it("removes parent of object currently navigated to", function () {
|
||||
// Navigates to child object
|
||||
mockNavigationService.getNavigation.and.returnValue(mockChildObject);
|
||||
|
||||
// Test is id of object being removed
|
||||
// Child object has different id
|
||||
mockDomainObject.getId.and.returnValue("test");
|
||||
mockChildObject.getId.and.returnValue("not test");
|
||||
|
||||
// Sets context for the child and domainObject
|
||||
mockDomainObject.getCapability.and.returnValue(mockContext);
|
||||
mockChildObject.getCapability.and.returnValue(mockChildContext);
|
||||
|
||||
// Parents of child and domainObject are set
|
||||
mockContext.getParent.and.returnValue(mockParent);
|
||||
mockChildContext.getParent.and.returnValue(mockDomainObject);
|
||||
|
||||
mockType.hasFeature.and.returnValue(true);
|
||||
it("shows a blocking message dialog", function () {
|
||||
mockParent = jasmine.createSpyObj(
|
||||
"parent",
|
||||
["getModel", "getCapability", "useCapability"]
|
||||
);
|
||||
|
||||
action.perform();
|
||||
|
||||
// Expects navigation to parent of domainObject (removed object)
|
||||
expect(mockNavigationService.setNavigation).toHaveBeenCalledWith(mockParent);
|
||||
expect(mockDialogService.showBlockingMessage).toHaveBeenCalled();
|
||||
|
||||
// Also check that no mutation happens at this point
|
||||
expect(mockParent.useCapability).not.toHaveBeenCalledWith("mutation", jasmine.any(Function));
|
||||
});
|
||||
|
||||
it("checks if removing object not in ascendent path (reaches ROOT)", function () {
|
||||
// Navigates to grandchild of ROOT
|
||||
mockNavigationService.getNavigation.and.returnValue(mockGrandchildObject);
|
||||
describe("after the remove callback is triggered", function () {
|
||||
var mockChildContext,
|
||||
mockChildObject,
|
||||
mockDialogHandle,
|
||||
mockGrandchildContext,
|
||||
mockGrandchildObject,
|
||||
mockRootContext,
|
||||
mockRootObject;
|
||||
|
||||
// domainObject (grandparent) is set as ROOT, child and grandchild
|
||||
// are set objects not being removed
|
||||
mockDomainObject.getId.and.returnValue("test 1");
|
||||
mockRootObject.getId.and.returnValue("ROOT");
|
||||
mockChildObject.getId.and.returnValue("not test 2");
|
||||
mockGrandchildObject.getId.and.returnValue("not test 3");
|
||||
beforeEach(function () {
|
||||
mockChildObject = jasmine.createSpyObj(
|
||||
"domainObject",
|
||||
["getId", "getCapability"]
|
||||
);
|
||||
|
||||
// Sets context for the grandchild, child, and domainObject
|
||||
mockRootObject.getCapability.and.returnValue(mockRootContext);
|
||||
mockChildObject.getCapability.and.returnValue(mockChildContext);
|
||||
mockGrandchildObject.getCapability.and.returnValue(mockGrandchildContext);
|
||||
mockDialogHandle = jasmine.createSpyObj(
|
||||
"dialogHandle",
|
||||
["dismiss"]
|
||||
);
|
||||
|
||||
// Parents of grandchild and child are set
|
||||
mockChildContext.getParent.and.returnValue(mockRootObject);
|
||||
mockGrandchildContext.getParent.and.returnValue(mockChildObject);
|
||||
mockGrandchildObject = jasmine.createSpyObj(
|
||||
"domainObject",
|
||||
["getId", "getCapability"]
|
||||
);
|
||||
|
||||
mockType.hasFeature.and.returnValue(true);
|
||||
mockRootObject = jasmine.createSpyObj(
|
||||
"domainObject",
|
||||
["getId", "getCapability"]
|
||||
);
|
||||
|
||||
action.perform();
|
||||
mockChildContext = jasmine.createSpyObj("context", ["getParent"]);
|
||||
mockGrandchildContext = jasmine.createSpyObj("context", ["getParent"]);
|
||||
mockRootContext = jasmine.createSpyObj("context", ["getParent"]);
|
||||
|
||||
mockDialogService.showBlockingMessage.and.returnValue(mockDialogHandle);
|
||||
});
|
||||
|
||||
it("mutates the parent when performed", function () {
|
||||
action.perform();
|
||||
mockDialogService.showBlockingMessage.calls.mostRecent().args[0]
|
||||
.primaryOption.callback();
|
||||
|
||||
expect(mockMutation.invoke)
|
||||
.toHaveBeenCalledWith(jasmine.any(Function));
|
||||
});
|
||||
|
||||
it("changes composition from its mutation function", function () {
|
||||
var mutator, result;
|
||||
|
||||
action.perform();
|
||||
mockDialogService.showBlockingMessage.calls.mostRecent().args[0]
|
||||
.primaryOption.callback();
|
||||
|
||||
mutator = mockMutation.invoke.calls.mostRecent().args[0];
|
||||
result = mutator(model);
|
||||
|
||||
// Should not have cancelled the mutation
|
||||
expect(result).not.toBe(false);
|
||||
|
||||
// Simulate mutate's behavior (remove can either return a
|
||||
// new model or modify this one in-place)
|
||||
result = result || model;
|
||||
|
||||
// Should have removed "test" - that was our
|
||||
// mock domain object's id.
|
||||
expect(result.composition).toEqual(["a", "b"]);
|
||||
});
|
||||
|
||||
it("removes parent of object currently navigated to", function () {
|
||||
// Navigates to child object
|
||||
mockNavigationService.getNavigation.and.returnValue(mockChildObject);
|
||||
|
||||
// Test is id of object being removed
|
||||
// Child object has different id
|
||||
mockDomainObject.getId.and.returnValue("test");
|
||||
mockChildObject.getId.and.returnValue("not test");
|
||||
|
||||
// Sets context for the child and domainObject
|
||||
mockDomainObject.getCapability.and.returnValue(mockContext);
|
||||
mockChildObject.getCapability.and.returnValue(mockChildContext);
|
||||
|
||||
// Parents of child and domainObject are set
|
||||
mockContext.getParent.and.returnValue(mockParent);
|
||||
mockChildContext.getParent.and.returnValue(mockDomainObject);
|
||||
|
||||
mockType.hasFeature.and.returnValue(true);
|
||||
|
||||
action.perform();
|
||||
mockDialogService.showBlockingMessage.calls.mostRecent().args[0]
|
||||
.primaryOption.callback();
|
||||
|
||||
// Expects navigation to parent of domainObject (removed object)
|
||||
expect(mockNavigationService.setNavigation).toHaveBeenCalledWith(mockParent);
|
||||
});
|
||||
|
||||
it("checks if removing object not in ascendent path (reaches ROOT)", function () {
|
||||
// Navigates to grandchild of ROOT
|
||||
mockNavigationService.getNavigation.and.returnValue(mockGrandchildObject);
|
||||
|
||||
// domainObject (grandparent) is set as ROOT, child and grandchild
|
||||
// are set objects not being removed
|
||||
mockDomainObject.getId.and.returnValue("test 1");
|
||||
mockRootObject.getId.and.returnValue("ROOT");
|
||||
mockChildObject.getId.and.returnValue("not test 2");
|
||||
mockGrandchildObject.getId.and.returnValue("not test 3");
|
||||
|
||||
// Sets context for the grandchild, child, and domainObject
|
||||
mockRootObject.getCapability.and.returnValue(mockRootContext);
|
||||
mockChildObject.getCapability.and.returnValue(mockChildContext);
|
||||
mockGrandchildObject.getCapability.and.returnValue(mockGrandchildContext);
|
||||
|
||||
// Parents of grandchild and child are set
|
||||
mockChildContext.getParent.and.returnValue(mockRootObject);
|
||||
mockGrandchildContext.getParent.and.returnValue(mockChildObject);
|
||||
|
||||
mockType.hasFeature.and.returnValue(true);
|
||||
|
||||
action.perform();
|
||||
mockDialogService.showBlockingMessage.calls.mostRecent().args[0]
|
||||
.primaryOption.callback();
|
||||
|
||||
// Expects no navigation to occur
|
||||
expect(mockNavigationService.setNavigation).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// Expects no navigation to occur
|
||||
expect(mockNavigationService.setNavigation).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
|
@ -31,26 +31,63 @@ define(
|
||||
var mockScope,
|
||||
mockTimeout,
|
||||
mockDomainObject,
|
||||
mockFolderObject,
|
||||
mockRootObject,
|
||||
mockContext,
|
||||
mockActions,
|
||||
mockObjectService,
|
||||
mockTypeService,
|
||||
mockType,
|
||||
mockInstantiate,
|
||||
mockPolicyService,
|
||||
getObjectsPromise,
|
||||
testModel,
|
||||
capabilities,
|
||||
mockCreateNewFolderAction,
|
||||
mockActionCapability,
|
||||
mockProperties,
|
||||
controller;
|
||||
|
||||
beforeEach(function () {
|
||||
mockScope = jasmine.createSpyObj(
|
||||
"$scope",
|
||||
["$watch"]
|
||||
["$watch", "validParent"]
|
||||
);
|
||||
mockTimeout = jasmine.createSpy("$timeout");
|
||||
mockInstantiate = jasmine.createSpy("instantiate");
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
"domainObject",
|
||||
["getCapability"]
|
||||
[
|
||||
"useCapability",
|
||||
"getModel",
|
||||
"getCapability"
|
||||
]
|
||||
);
|
||||
mockFolderObject = jasmine.createSpyObj(
|
||||
"folderObject",
|
||||
[
|
||||
"useCapability",
|
||||
"getModel",
|
||||
"getCapability"
|
||||
]
|
||||
);
|
||||
mockCreateNewFolderAction = jasmine.createSpyObj(
|
||||
"createNewFolderAction",
|
||||
[
|
||||
"perform"
|
||||
]
|
||||
);
|
||||
mockRootObject = jasmine.createSpyObj(
|
||||
"rootObject",
|
||||
["getCapability"]
|
||||
);
|
||||
mockActionCapability = jasmine.createSpyObj(
|
||||
"actionCapability",
|
||||
[
|
||||
"getActions",
|
||||
"perform"
|
||||
]
|
||||
);
|
||||
mockContext = jasmine.createSpyObj(
|
||||
"context",
|
||||
["getRoot"]
|
||||
@ -59,25 +96,70 @@ define(
|
||||
"objectService",
|
||||
["getObjects"]
|
||||
);
|
||||
mockTypeService = jasmine.createSpyObj(
|
||||
"typeService",
|
||||
["getType"]
|
||||
);
|
||||
mockPolicyService = jasmine.createSpyObj(
|
||||
"policyService",
|
||||
["allow"]
|
||||
);
|
||||
getObjectsPromise = jasmine.createSpyObj(
|
||||
"promise",
|
||||
["then"]
|
||||
);
|
||||
|
||||
mockDomainObject.getCapability.and.returnValue(mockContext);
|
||||
mockType = jasmine.createSpyObj(
|
||||
"type",
|
||||
[
|
||||
"getKey",
|
||||
"getProperties",
|
||||
"getInitialModel"
|
||||
]
|
||||
);
|
||||
testModel = { someKey: "some value" };
|
||||
mockProperties = ['a', 'b', 'c'].map(function (k) {
|
||||
var mockProperty = jasmine.createSpyObj(
|
||||
'property-' + k,
|
||||
['propertyDefinition']
|
||||
);
|
||||
mockProperty.propertyDefinition = {
|
||||
key: "name",
|
||||
pattern: "test"
|
||||
};
|
||||
return mockProperty;
|
||||
});
|
||||
capabilities = {
|
||||
"action" : mockActionCapability,
|
||||
"context": mockContext
|
||||
};
|
||||
mockActions = [mockCreateNewFolderAction];
|
||||
mockContext.getRoot.and.returnValue(mockRootObject);
|
||||
mockObjectService.getObjects.and.returnValue(getObjectsPromise);
|
||||
|
||||
mockTypeService.getType.and.callFake(function (typename) {
|
||||
return mockType;
|
||||
});
|
||||
mockInstantiate.and.returnValue(mockFolderObject);
|
||||
mockType.getKey.and.returnValue("test");
|
||||
mockType.getInitialModel.and.returnValue(testModel);
|
||||
mockType.getProperties.and.returnValue(mockProperties);
|
||||
mockDomainObject.getCapability.and.callFake(function (capability) {
|
||||
return capabilities[capability];
|
||||
});
|
||||
mockDomainObject.useCapability.and.returnValue();
|
||||
mockDomainObject.getModel.and.returnValue(testModel);
|
||||
mockFolderObject.getCapability.and.returnValue(capabilities);
|
||||
mockFolderObject.useCapability.and.returnValue();
|
||||
mockFolderObject.getModel.and.returnValue(testModel);
|
||||
mockScope.ngModel = {};
|
||||
mockScope.field = "someField";
|
||||
|
||||
controller = new LocatorController(mockScope, mockTimeout, mockObjectService);
|
||||
controller = new LocatorController(mockScope, mockTimeout, mockObjectService, mockTypeService, mockPolicyService, mockInstantiate);
|
||||
});
|
||||
describe("when context is available", function () {
|
||||
|
||||
beforeEach(function () {
|
||||
mockContext.getRoot.and.returnValue(mockRootObject);
|
||||
controller = new LocatorController(mockScope, mockTimeout, mockObjectService);
|
||||
controller = new LocatorController(mockScope, mockTimeout, mockObjectService, mockTypeService, mockPolicyService, mockInstantiate);
|
||||
});
|
||||
|
||||
it("adds a treeModel to scope", function () {
|
||||
@ -145,7 +227,7 @@ define(
|
||||
getObjectsPromise.then.and.callFake(function (callback) {
|
||||
callback({'ROOT': defaultRoot});
|
||||
});
|
||||
controller = new LocatorController(mockScope, mockTimeout, mockObjectService);
|
||||
controller = new LocatorController(mockScope, mockTimeout, mockObjectService, mockTypeService, mockPolicyService, mockInstantiate);
|
||||
});
|
||||
|
||||
it("provides a default context where none is available", function () {
|
||||
@ -169,3 +251,4 @@ define(
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -34,7 +34,6 @@ define([
|
||||
"./src/controllers/ContextMenuController",
|
||||
"./src/controllers/ClickAwayController",
|
||||
"./src/controllers/ViewSwitcherController",
|
||||
"./src/controllers/BottomBarController",
|
||||
"./src/controllers/GetterSetterController",
|
||||
"./src/controllers/SelectorController",
|
||||
"./src/controllers/ObjectInspectorController",
|
||||
@ -49,13 +48,14 @@ define([
|
||||
"./src/directives/MCTSplitPane",
|
||||
"./src/directives/MCTSplitter",
|
||||
"./src/directives/MCTTree",
|
||||
"./src/directives/MCTIndicators",
|
||||
"./src/directives/MCTPreview",
|
||||
"./src/actions/MCTPreviewAction",
|
||||
"./src/filters/ReverseFilter",
|
||||
"text!./res/templates/bottombar.html",
|
||||
"text!./res/templates/controls/action-button.html",
|
||||
"text!./res/templates/controls/input-filter.html",
|
||||
"text!./res/templates/indicator.html",
|
||||
"text!./res/templates/angular-indicator.html",
|
||||
"text!./res/templates/message-banner.html",
|
||||
"text!./res/templates/progress-bar.html",
|
||||
"text!./res/templates/controls/time-controller.html",
|
||||
@ -87,7 +87,6 @@ define([
|
||||
ContextMenuController,
|
||||
ClickAwayController,
|
||||
ViewSwitcherController,
|
||||
BottomBarController,
|
||||
GetterSetterController,
|
||||
SelectorController,
|
||||
ObjectInspectorController,
|
||||
@ -102,6 +101,7 @@ define([
|
||||
MCTSplitPane,
|
||||
MCTSplitter,
|
||||
MCTTree,
|
||||
MCTIndicators,
|
||||
MCTPreview,
|
||||
MCTPreviewAction,
|
||||
ReverseFilter,
|
||||
@ -281,13 +281,6 @@ define([
|
||||
"$timeout"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "BottomBarController",
|
||||
"implementation": BottomBarController,
|
||||
"depends": [
|
||||
"indicators[]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "GetterSetterController",
|
||||
"implementation": GetterSetterController,
|
||||
@ -403,6 +396,11 @@ define([
|
||||
"implementation": MCTTree,
|
||||
"depends": ['gestureService', 'openmct']
|
||||
},
|
||||
{
|
||||
"key": "mctIndicators",
|
||||
"implementation": MCTIndicators,
|
||||
"depends": ['openmct']
|
||||
},
|
||||
{
|
||||
"key": "mctPreview",
|
||||
"implementation": MCTPreview,
|
||||
|
@ -42,6 +42,7 @@
|
||||
@import "controls/lists";
|
||||
@import "controls/menus";
|
||||
@import "controls/messages";
|
||||
@import "controls/indicators";
|
||||
@import "mobile/controls/menus";
|
||||
|
||||
/********************************* FORMS */
|
||||
|
@ -20,66 +20,120 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*************************************************** MIXINS */
|
||||
@mixin formulateStatusColors($c) {
|
||||
@mixin elementStatusColors($c) {
|
||||
// Sets bg and icon colors for elements
|
||||
background: rgba($c, 0.4) !important;
|
||||
&:before { color: $c !important; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************** GENERAL */
|
||||
.s-limit-yellow,
|
||||
.s-limit-red,
|
||||
.s-limit-yellow-icon,
|
||||
.s-limit-red-icon,
|
||||
.s-status-warning-lo,
|
||||
.s-status-warning-hi,
|
||||
.s-status-diagnostic,
|
||||
.s-status-command,
|
||||
.s-status-info,
|
||||
.s-status-ok,
|
||||
.s-status-warning-lo-icon,
|
||||
.s-status-warning-hi-icon,
|
||||
.s-status-diagnostic-icon,
|
||||
.s-status-command-icon,
|
||||
.s-status-info-icon,
|
||||
.s-status-ok-icon {
|
||||
@include trans-prop-nice($props: background, $dur: 500ms);
|
||||
background: rgba($c, 0.5) !important;
|
||||
&:before {
|
||||
content:'';
|
||||
font-family: symbolsfont;
|
||||
font-size: 0.8em;
|
||||
margin-right: $interiorMarginSm;
|
||||
color: $c !important;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin indicatorStatusColors($c) {
|
||||
&:before, .count {
|
||||
color: $c;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************** GENERAL */
|
||||
.s-limit-upr,
|
||||
.s-limit-lwr,
|
||||
[class*='s-limit-icon'],
|
||||
[class*='s-status-icon'] {
|
||||
&:before {
|
||||
content:'';
|
||||
display: inline-block;
|
||||
font-family: symbolsfont;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************** LIMITS */
|
||||
.s-limit-yellow, .s-limit-yellow-icon {
|
||||
@include formulateStatusColors($colorWarningLo);
|
||||
[class*='s-limit'] {
|
||||
&[class*='icon-'] {
|
||||
&:before {
|
||||
margin-right: $interiorMargin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.s-limit-red, .s-limit-red-icon {
|
||||
@include formulateStatusColors($colorWarningHi);
|
||||
.s-limit-yellow, .s-limit-icon-yellow {
|
||||
@include elementStatusColors($colorWarningLo);
|
||||
}
|
||||
|
||||
.s-limit-upr:before { content: $glyph-icon-arrow-double-up; }
|
||||
.s-limit-lwr:before { content: $glyph-icon-arrow-double-down; }
|
||||
.s-limit-yellow-icon:before,
|
||||
.s-limit-red-icon:before { content: $glyph-icon-alert-triangle; }
|
||||
.s-limit-red, .s-limit-icon-red {
|
||||
@include elementStatusColors($colorWarningHi);
|
||||
}
|
||||
|
||||
.s-limit {
|
||||
&-upr,
|
||||
&-lwr {
|
||||
&:before {
|
||||
margin-right: $interiorMargin;
|
||||
}
|
||||
}
|
||||
|
||||
&-upr:before { content: $glyph-icon-arrow-double-up; }
|
||||
&-lwr:before { content: $glyph-icon-arrow-double-down; }
|
||||
|
||||
&-icon-yellow,
|
||||
&-icon-red {
|
||||
&:before {
|
||||
content: $glyph-icon-alert-triangle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************** STATUS */
|
||||
.s-status-warning-hi, .s-status-warning-hi-icon { @include formulateStatusColors($colorWarningHi); }
|
||||
.s-status-warning-lo, .s-status-warning-lo-icon { @include formulateStatusColors($colorWarningLo); }
|
||||
.s-status-diagnostic, .s-status-diagnostic-icon { @include formulateStatusColors($colorDiagnostic); }
|
||||
.s-status-info, .s-status-info-icon { @include formulateStatusColors($colorInfo); }
|
||||
.s-status-ok, .s-status-ok-icon { @include formulateStatusColors($colorOk); }
|
||||
[class*='s-status'] {
|
||||
&[class*='icon-'] {
|
||||
&:before {
|
||||
margin-right: $interiorMargin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.s-status-warning-hi-icon:before { content: $glyph-icon-alert-triangle; }
|
||||
.s-status-warning-lo-icon:before { content: $glyph-icon-alert-rect; }
|
||||
.s-status-diagnostic-icon:before { content: $glyph-icon-eye-open; }
|
||||
.s-status-info-icon:before { content: $glyph-icon-info; }
|
||||
.s-status-ok-icon:before { content: $glyph-icon-check; }
|
||||
.s-status-warning-hi, .s-status-icon-warning-hi { @include elementStatusColors($colorWarningHi); }
|
||||
.s-status-warning-lo, .s-status-icon-warning-lo { @include elementStatusColors($colorWarningLo); }
|
||||
.s-status-diagnostic, .s-status-icon-diagnostic { @include elementStatusColors($colorDiagnostic); }
|
||||
.s-status-info, .s-status-icon-info { @include elementStatusColors($colorInfo); }
|
||||
.s-status-ok, .s-status-icon-ok { @include elementStatusColors($colorOk); }
|
||||
|
||||
.s-status-icon-warning-hi:before { content: $glyph-icon-alert-triangle; }
|
||||
.s-status-icon-warning-lo:before { content: $glyph-icon-alert-rect; }
|
||||
.s-status-icon-diagnostic:before { content: $glyph-icon-eye-open; }
|
||||
.s-status-icon-info:before { content: $glyph-icon-info; }
|
||||
.s-status-icon-ok:before { content: $glyph-icon-check; }
|
||||
|
||||
/*************************************************** INDICATOR COLORING */
|
||||
.ls-indicator {
|
||||
&.s-status-info {
|
||||
@include indicatorStatusColors($colorInfo);
|
||||
}
|
||||
|
||||
&.s-status-disabled {
|
||||
@include indicatorStatusColors($colorIndicatorDisabled);
|
||||
}
|
||||
|
||||
&.s-status-available {
|
||||
@include indicatorStatusColors($colorIndicatorAvailable);
|
||||
}
|
||||
|
||||
&.s-status-on,
|
||||
&.s-status-enabled {
|
||||
@include indicatorStatusColors($colorIndicatorOn);
|
||||
}
|
||||
|
||||
&.s-status-off {
|
||||
@include indicatorStatusColors($colorIndicatorOff);
|
||||
}
|
||||
|
||||
&.s-status-caution,
|
||||
&.s-status-warning,
|
||||
&.s-status-alert {
|
||||
@include indicatorStatusColors($colorStatusAlert);
|
||||
}
|
||||
|
||||
&.s-status-error {
|
||||
@include indicatorStatusColors($colorStatusError);
|
||||
}
|
||||
}
|
||||
|
147
platform/commonUI/general/res/sass/controls/_indicators.scss
Normal file
147
platform/commonUI/general/res/sass/controls/_indicators.scss
Normal file
@ -0,0 +1,147 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2017, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/* Indicators are generally only displayed in the ue-bottom-bar element of the main interface */
|
||||
|
||||
.h-indicator,
|
||||
mct-indicators mct-include {
|
||||
display: inline; // Fallback for display: contents
|
||||
display: contents;
|
||||
}
|
||||
|
||||
.ls-indicator {
|
||||
$bg: rgba(white, 0.2) !important;
|
||||
$hbg: $colorStatusBarBg;
|
||||
$hshdw: rgba(white, 0.4) 0 0 3px;
|
||||
$br: $controlCr;
|
||||
$hoverYOffset: -35px;
|
||||
background: transparent !important;
|
||||
border-radius: $br;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
padding: 1px $interiorMarginSm; // Use padding instead of margin to keep hover chatter to a minimum
|
||||
|
||||
&:before {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.label {
|
||||
display: inline-block;
|
||||
a,
|
||||
button,
|
||||
.s-button {
|
||||
// Make <a> in label look like buttons
|
||||
@include trans-prop-nice($props: all, $dur: 100ms);
|
||||
background: transparent;
|
||||
border: 1px solid rgba($colorStatusBarFg, 0.5);
|
||||
border-radius: $br;
|
||||
box-sizing: border-box;
|
||||
color: inherit;
|
||||
font-size: inherit;
|
||||
height: auto;
|
||||
line-height: normal;
|
||||
padding: 0 2px;
|
||||
&:hover {
|
||||
background: $bg;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
[class*='icon-'] {
|
||||
// If any elements within label include the class 'icon-*' then deal with their :before's
|
||||
&:before {
|
||||
font-size: 0.8em;
|
||||
margin-right: $interiorMarginSm;
|
||||
}
|
||||
}
|
||||
|
||||
button { text-transform: uppercase !important; }
|
||||
}
|
||||
|
||||
&.no-collapse {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
align-items: center;
|
||||
|
||||
> *,
|
||||
&:before {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
&:before {
|
||||
margin-right: $interiorMarginSm;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.no-collapse) {
|
||||
z-index: 0;
|
||||
|
||||
&:before {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
|
||||
.label {
|
||||
transition: all 250ms ease-in 100ms;
|
||||
background: $hbg;
|
||||
border-radius: $br;
|
||||
font-size: .6rem;
|
||||
left: 0;
|
||||
bottom: 140%;
|
||||
opacity: 0;
|
||||
padding: $interiorMarginSm $interiorMargin;
|
||||
position: absolute;
|
||||
transform-origin: 10px 100%;
|
||||
transform: scale(0.0);
|
||||
white-space: nowrap;
|
||||
&:before {
|
||||
// Infobubble-style arrow element
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
@include triangle('down', $size: 4px, $ratio: 1, $color: $hbg);
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $bg;
|
||||
z-index: 1;
|
||||
.label {
|
||||
opacity: 1;
|
||||
transform: scale(1.0);
|
||||
transition: all 100ms ease-out 0s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.float-right {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mobile */
|
||||
// Hide the clock indicator when we're phone portrait
|
||||
body.phone.portrait {
|
||||
.ls-indicator.t-indicator-clock {
|
||||
display: none;
|
||||
}
|
||||
}
|
@ -19,9 +19,9 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/******************************************************************* STATUS BLOCK ELEMS */
|
||||
|
||||
@mixin statusBannerColors($bg, $fg: $colorStatusFg) {
|
||||
$bgPb: 30%;
|
||||
$bgPb: 10%;
|
||||
$bgPbD: 10%;
|
||||
background-color: darken($bg, $bgPb);
|
||||
color: $fg;
|
||||
@ -36,110 +36,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Status coloring
|
||||
.ok, .info {
|
||||
.status-indicator {
|
||||
color: $colorInfo;
|
||||
}
|
||||
}
|
||||
|
||||
.alert, .caution, .warning {
|
||||
.status-indicator, .count {
|
||||
color: $colorStatusAlert;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.error, .err {
|
||||
.status-indicator, .count {
|
||||
color: $colorStatusError;
|
||||
}
|
||||
}
|
||||
|
||||
.available {
|
||||
.status-indicator, .count {
|
||||
color: $colorStatusAvailable;
|
||||
}
|
||||
}
|
||||
|
||||
.subdued {
|
||||
.status-indicator {
|
||||
color: pullForward($colorStatusBarBg, 40%);
|
||||
}
|
||||
}
|
||||
|
||||
.status-block-holder {
|
||||
// Applied to mct-include element
|
||||
// Contains status.block elements
|
||||
$transDelay: 1.5s;
|
||||
$transSpeed: .25s;
|
||||
display: inline-block;
|
||||
&.clickable { cursor: pointer; }
|
||||
&:not(.clickable) { cursor: default; }
|
||||
&.no-icon .status.block {
|
||||
.status-indicator {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&.float-right {
|
||||
float: right;
|
||||
}
|
||||
&:not(.no-collapse) .status.block {
|
||||
.label {
|
||||
// Max-width silliness is necessary for width transition
|
||||
@include trans-prop-nice(max-width, $transSpeed, $transDelay);
|
||||
overflow: hidden;
|
||||
max-width: 0px;
|
||||
}
|
||||
&:hover {
|
||||
.label {
|
||||
@include trans-prop-nice(max-width, $transSpeed, 0s);
|
||||
max-width: 600px;
|
||||
width: auto;
|
||||
}
|
||||
.count {
|
||||
@include trans-prop-nice(max-width, $transSpeed, 0s);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.status.block {
|
||||
$transDelay: 1.5s;
|
||||
$transSpeed: .25s;
|
||||
color: $colorStatusDefault;
|
||||
display: inline-block;
|
||||
margin-right: $interiorMargin;
|
||||
.status-indicator,
|
||||
.label,
|
||||
.count {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.status-indicator {
|
||||
background: none !important;
|
||||
margin-right: $interiorMarginSm;
|
||||
&[class*='s-status']:before {
|
||||
font-size: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.count {
|
||||
@include trans-prop-nice(opacity, $transSpeed, $transDelay);
|
||||
font-weight: bold;
|
||||
opacity: 1;
|
||||
}
|
||||
.s-button {
|
||||
background: $colorStatusBtnBg;
|
||||
padding: 0 $interiorMargin;
|
||||
height: auto;
|
||||
line-height: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************* MESSAGE BANNERS */
|
||||
.message {
|
||||
&.block {
|
||||
@ -289,7 +185,6 @@
|
||||
|
||||
> div,
|
||||
> span {
|
||||
//@include test(red);
|
||||
margin-bottom: $interiorMargin;
|
||||
}
|
||||
|
||||
|
@ -33,8 +33,8 @@
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
.gl-plot.child-frame {
|
||||
mct-plot {
|
||||
display: flex;
|
||||
mct-plot {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
@ -51,18 +51,15 @@
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
.gl-plot {
|
||||
color: $colorPlotFg;
|
||||
color: $colorPlotFg;
|
||||
display: flex;
|
||||
font-size: 0.7rem;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: 0.7rem;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: $plotMinH;
|
||||
|
||||
/********************************************* AXIS AND DISPLAY AREA */
|
||||
@ -74,7 +71,8 @@
|
||||
position: absolute;
|
||||
display: block;
|
||||
font-size: 1.5em;
|
||||
top: $interiorMarginSm; left: $interiorMarginSm;
|
||||
top: $interiorMarginSm;
|
||||
left: $interiorMarginSm;
|
||||
}
|
||||
}
|
||||
|
||||
@ -105,71 +103,71 @@
|
||||
}
|
||||
}
|
||||
|
||||
.gl-plot-axis-area {
|
||||
position: absolute;
|
||||
&.gl-plot-y {
|
||||
top: nth($plotDisplayArea, 1);
|
||||
right: auto;
|
||||
bottom: nth($plotDisplayArea, 3);
|
||||
left: 0;
|
||||
width: $plotYBarW;
|
||||
}
|
||||
}
|
||||
.gl-plot-axis-area {
|
||||
position: absolute;
|
||||
&.gl-plot-y {
|
||||
top: nth($plotDisplayArea, 1);
|
||||
right: auto;
|
||||
bottom: nth($plotDisplayArea, 3);
|
||||
left: 0;
|
||||
width: $plotYBarW;
|
||||
}
|
||||
}
|
||||
|
||||
.gl-plot-coords {
|
||||
box-sizing: border-box;
|
||||
border-radius: $controlCr;
|
||||
background: black;
|
||||
color: lighten($colorBodyFg, 30%);
|
||||
padding: 2px 5px;
|
||||
position: absolute;
|
||||
top: nth($plotDisplayArea,1) + $interiorMarginLg;
|
||||
right: auto;
|
||||
bottom: auto;
|
||||
left: nth($plotDisplayArea,4) + $interiorMarginLg;
|
||||
z-index: 10;
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.gl-plot-coords {
|
||||
box-sizing: border-box;
|
||||
border-radius: $controlCr;
|
||||
background: black;
|
||||
color: lighten($colorBodyFg, 30%);
|
||||
padding: 2px 5px;
|
||||
position: absolute;
|
||||
top: nth($plotDisplayArea,1) + $interiorMarginLg;
|
||||
right: auto;
|
||||
bottom: auto;
|
||||
left: nth($plotDisplayArea,4) + $interiorMarginLg;
|
||||
z-index: 10;
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.gl-plot-label,
|
||||
.l-plot-label {
|
||||
color: $colorPlotLabelFg;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
.gl-plot-label,
|
||||
.l-plot-label {
|
||||
color: $colorPlotLabelFg;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
|
||||
&.gl-plot-x-label,
|
||||
&.l-plot-x-label {
|
||||
top: auto;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: auto;
|
||||
}
|
||||
&.gl-plot-x-label,
|
||||
&.l-plot-x-label {
|
||||
top: auto;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
&.gl-plot-y-label,
|
||||
&.l-plot-y-label {
|
||||
$x: -50%;
|
||||
$r: -90deg;
|
||||
transform-origin: 50% 0;
|
||||
transform: translateX($x) rotate($r);
|
||||
display: inline-block;
|
||||
margin-left: $interiorMargin; // Kick off the left edge
|
||||
left: 0;
|
||||
top: 50%;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
&.gl-plot-y-label,
|
||||
&.l-plot-y-label {
|
||||
$x: -50%;
|
||||
$r: -90deg;
|
||||
transform-origin: 50% 0;
|
||||
transform: translateX($x) rotate($r);
|
||||
display: inline-block;
|
||||
margin-left: $interiorMargin; // Kick off the left edge
|
||||
left: 0;
|
||||
top: 50%;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.gl-plot-x-options,
|
||||
.gl-plot-x-options,
|
||||
.gl-plot-y-options {
|
||||
$h: 24px;
|
||||
position: absolute;
|
||||
height: $h;
|
||||
min-height: $h;
|
||||
$h: 24px;
|
||||
position: absolute;
|
||||
height: $h;
|
||||
min-height: $h;
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
|
||||
.gl-plot-x-options {
|
||||
transform: translateX(-50%);
|
||||
@ -190,119 +188,192 @@
|
||||
right: $interiorMargin;
|
||||
}
|
||||
|
||||
.gl-plot-hash {
|
||||
position: absolute;
|
||||
border: 0 $colorPlotHash $stylePlotHash;
|
||||
&.hash-v {
|
||||
border-right-width: 1px;
|
||||
height: 100%;
|
||||
}
|
||||
&.hash-h {
|
||||
border-bottom-width: 1px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.gl-plot-hash {
|
||||
position: absolute;
|
||||
opacity: $opacityPlotHash;
|
||||
&.hash-v {
|
||||
border-right: 1px $colorPlotHash $stylePlotHash;
|
||||
height: 100%;
|
||||
}
|
||||
&.hash-h {
|
||||
border-bottom: 1px $colorPlotHash $stylePlotHash;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************** Limits and Out-of-Bounds data */
|
||||
/****************************** Limits and Out-of-Bounds data */
|
||||
|
||||
.l-limit-bar,
|
||||
.l-oob-data {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: auto;
|
||||
}
|
||||
.l-limit-bar,
|
||||
.l-oob-data {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.l-limit-bar {
|
||||
// Limits in plot display area
|
||||
@mixin limitBg($c) {
|
||||
background: rgba($c, 0.2);
|
||||
}
|
||||
.l-limit-bar {
|
||||
// Limits in plot display area
|
||||
@mixin limitBg($c) {
|
||||
background: rgba($c, 0.2);
|
||||
}
|
||||
|
||||
height: auto;
|
||||
z-index: 0;
|
||||
&.s-limit-yellow { @include limitBg($colorLimitYellowBg); }
|
||||
&.s-limit-red { @include limitBg($colorLimitRedBg); }
|
||||
}
|
||||
height: auto;
|
||||
z-index: 0;
|
||||
&.s-limit-yellow {
|
||||
@include limitBg($colorLimitYellowBg);
|
||||
}
|
||||
&.s-limit-red {
|
||||
@include limitBg($colorLimitRedBg);
|
||||
}
|
||||
}
|
||||
|
||||
.l-oob-data {
|
||||
$c: #7748d6;
|
||||
$a: 0.5;
|
||||
$h: 10px;
|
||||
@include absPosDefault();
|
||||
pointer-events: none;
|
||||
height: $h;
|
||||
z-index: 1;
|
||||
&.l-oob-data-up {
|
||||
top: 0;
|
||||
bottom: auto;
|
||||
@include linearGlow(0deg, $c, $a);
|
||||
}
|
||||
&.l-oob-data-dwn {
|
||||
bottom: 0;
|
||||
top: auto;
|
||||
@include linearGlow(180deg, $c, $a);
|
||||
}
|
||||
}
|
||||
.l-oob-data {
|
||||
$c: #7748d6;
|
||||
$a: 0.5;
|
||||
$h: 10px;
|
||||
@include absPosDefault();
|
||||
pointer-events: none;
|
||||
height: $h;
|
||||
z-index: 1;
|
||||
&.l-oob-data-up {
|
||||
top: 0;
|
||||
bottom: auto;
|
||||
@include linearGlow(0deg, $c, $a);
|
||||
}
|
||||
&.l-oob-data-dwn {
|
||||
bottom: 0;
|
||||
top: auto;
|
||||
@include linearGlow(180deg, $c, $a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.gl-plot-display-area,
|
||||
.plot-display-area {
|
||||
@if $colorPlotBg != none { background-color: $colorPlotBg; }
|
||||
@if $colorPlotBg != none {
|
||||
background-color: $colorPlotBg;
|
||||
}
|
||||
cursor: crosshair;
|
||||
border: 1px solid $colorPlotAreaBorder;
|
||||
}
|
||||
|
||||
.tick {
|
||||
position: absolute;
|
||||
border: 0 $colorPlotHash solid;
|
||||
&.tick-x {
|
||||
border-right-width: 1px;
|
||||
height: 100%; // Assumption is that the tick will be in a holder that will set it's height;
|
||||
}
|
||||
position: absolute;
|
||||
border: 0 $colorPlotHash solid;
|
||||
&.tick-x {
|
||||
border-right-width: 1px;
|
||||
height: 100%; // Assumption is that the tick will be in a holder that will set it's height;
|
||||
}
|
||||
}
|
||||
|
||||
.gl-plot-tick,
|
||||
.tick-label {
|
||||
@include reverseEllipsis();
|
||||
font-size: 0.7rem;
|
||||
position: absolute;
|
||||
&.gl-plot-x-tick-label,
|
||||
&.tick-label-x {
|
||||
right: auto;
|
||||
bottom: auto;
|
||||
left: auto;
|
||||
height: auto;
|
||||
width: 20%;
|
||||
margin-left: -10%;
|
||||
text-align: center;
|
||||
}
|
||||
&.gl-plot-y-tick-label,
|
||||
&.tick-label-y {
|
||||
top: auto;
|
||||
height: 1em;
|
||||
width: auto;
|
||||
margin-bottom: -0.5em;
|
||||
text-align: right;
|
||||
}
|
||||
font-size: 0.7rem;
|
||||
position: absolute;
|
||||
&.gl-plot-x-tick-label,
|
||||
&.tick-label-x {
|
||||
right: auto;
|
||||
bottom: auto;
|
||||
left: auto;
|
||||
height: auto;
|
||||
width: 20%;
|
||||
margin-left: -10%;
|
||||
text-align: center;
|
||||
}
|
||||
&.gl-plot-y-tick-label,
|
||||
&.tick-label-y {
|
||||
top: auto;
|
||||
height: 1em;
|
||||
width: auto;
|
||||
margin-bottom: -0.5em;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.gl-plot-tick {
|
||||
&.gl-plot-x-tick-label {
|
||||
top: $interiorMargin;
|
||||
}
|
||||
&.gl-plot-y-tick-label {
|
||||
right: $interiorMargin;
|
||||
left: $interiorMargin;
|
||||
}
|
||||
&.gl-plot-x-tick-label {
|
||||
top: $interiorMargin;
|
||||
}
|
||||
&.gl-plot-y-tick-label {
|
||||
right: $interiorMargin;
|
||||
left: $interiorMargin;
|
||||
}
|
||||
}
|
||||
|
||||
.tick-label {
|
||||
&.tick-label-x {
|
||||
top: 0;
|
||||
}
|
||||
&.tick-label-y {
|
||||
right: 0; left: 0;
|
||||
}
|
||||
&.tick-label-x {
|
||||
top: 0;
|
||||
}
|
||||
&.tick-label-y {
|
||||
right: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.export-plot {
|
||||
$bg: white;
|
||||
$fg: black;
|
||||
$gry: #999;
|
||||
|
||||
background: $bg !important;
|
||||
z-index: -10;
|
||||
|
||||
.l-view-section {
|
||||
$m: $interiorMargin;
|
||||
top: $m !important;
|
||||
right: $m;
|
||||
bottom: $m;
|
||||
left: $m;
|
||||
|
||||
.s-status-timeconductor-unsynced .holder-plot {
|
||||
.t-object-alert.t-alert-unsynced {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.gl-plot-display-area {
|
||||
background: none !important;
|
||||
border-color: $gry !important;
|
||||
|
||||
.gl-plot-local-controls,
|
||||
.h-local-controls {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.gl-plot {
|
||||
color: $fg;
|
||||
|
||||
.gl-plot-hash {
|
||||
opacity: 0.1;
|
||||
border-color: $fg;
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
thead {
|
||||
border-bottom: none;
|
||||
|
||||
th {
|
||||
background: #eee;
|
||||
border-left-color: $bg;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
tr {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
tbody {
|
||||
tr {
|
||||
border-top: 1px solid #ccc;
|
||||
}
|
||||
|
||||
td {
|
||||
color: $fg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,6 +47,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.status-holder {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.s-ue-bottom-bar {
|
||||
background: $colorStatusBarBg;
|
||||
color: $colorStatusBarFg;
|
||||
cursor: default;
|
||||
font-size: .7rem;
|
||||
}
|
||||
|
||||
.user-environ {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
@ -81,21 +93,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
.ue-bottom-bar {
|
||||
@include absPosDefault(0);// New status bar design
|
||||
.l-ue-bottom-bar {
|
||||
$m: $interiorMarginSm;
|
||||
@include absPosDefault(0, $overflow: visible);// New status bar design
|
||||
top: auto;
|
||||
height: $ueFooterH;
|
||||
line-height: $ueFooterH - ($interiorMargin * 2);
|
||||
background: $colorStatusBarBg;
|
||||
color: lighten($colorBodyBg, 30%);
|
||||
font-size: .7rem;
|
||||
line-height: $ueFooterH - ($m * 2);
|
||||
.status-holder {
|
||||
box-sizing: border-box;
|
||||
@include absPosDefault($interiorMargin);
|
||||
@include ellipsize();
|
||||
@include absPosDefault($m, $overflow: visible);
|
||||
right: 120px;
|
||||
text-transform: uppercase;
|
||||
z-index: 1;
|
||||
z-index: 10;
|
||||
}
|
||||
.app-logo {
|
||||
background-position: right center;
|
||||
|
@ -20,14 +20,8 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
|
||||
<div class='status block'
|
||||
<div class="ls-indicator {{ngModel.getCssClass()}}"
|
||||
title="{{ngModel.getDescription()}}"
|
||||
ng-click='ngModel.configure()'
|
||||
ng-show="ngModel.getText().length > 0">
|
||||
<span class="status-indicator {{ngModel.getCssClass()}}"></span><span class="label"
|
||||
ng-class='ngModel.getTextClass()'>
|
||||
{{ngModel.getText()}}
|
||||
<a class="s-button icon-gear" ng-if="ngModel.configure"></a>
|
||||
</span><span class="count">
|
||||
</span>
|
||||
<span class="label">{{ngModel.getText()}}</span>
|
||||
</div>
|
@ -19,14 +19,9 @@
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<div class='abs bottom-bar ue-bottom-bar mobile-disable-select' ng-controller="BottomBarController as bar">
|
||||
<div class='abs bottom-bar l-ue-bottom-bar s-ue-bottom-bar mobile-disable-select'>
|
||||
<div id='status' class='status-holder'>
|
||||
<mct-include ng-repeat="indicator in bar.getIndicators()"
|
||||
ng-model="indicator.ngModel"
|
||||
key="indicator.template"
|
||||
class="status-block-holder"
|
||||
ng-class='indicator.ngModel.getGlyphClass()'>
|
||||
</mct-include>
|
||||
<mct-indicators></mct-indicators>
|
||||
</div>
|
||||
<mct-include key="'message-banner'"></mct-include>
|
||||
<mct-include key="'about-logo'"></mct-include>
|
||||
|
@ -1,59 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
|
||||
/**
|
||||
* Controller for the bottombar template. Exposes
|
||||
* available indicators (of extension category "indicators")
|
||||
* @memberof platform/commonUI/general
|
||||
* @constructor
|
||||
*/
|
||||
function BottomBarController(indicators) {
|
||||
// Utility function used to make indicators presentable
|
||||
// for display.
|
||||
function present(Indicator) {
|
||||
return {
|
||||
template: Indicator.template || "indicator",
|
||||
ngModel: typeof Indicator === 'function' ?
|
||||
new Indicator() : Indicator
|
||||
};
|
||||
}
|
||||
|
||||
this.indicators = indicators.map(present);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all indicators to display.
|
||||
* @returns {Indicator[]} all indicators
|
||||
* to display in the bottom bar.
|
||||
* @memberof platform/commonUI/general.BottomBarController#
|
||||
*/
|
||||
BottomBarController.prototype.getIndicators = function () {
|
||||
return this.indicators;
|
||||
};
|
||||
|
||||
return BottomBarController;
|
||||
}
|
||||
);
|
@ -19,15 +19,22 @@
|
||||
* 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";
|
||||
@import "../../../../commonUI/general/res/sass/glyphs";
|
||||
@import "../../../../commonUI/themes/espresso/res/sass/constants";
|
||||
@import "../../../../commonUI/themes/espresso/res/sass/mixins";
|
||||
@import "constants";
|
||||
@import "constants-espresso";
|
||||
@import "timeline-thematic";
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
function MCTIndicators(openmct) {
|
||||
return {
|
||||
restrict: "E",
|
||||
link: function link(scope, element) {
|
||||
openmct.indicators.indicatorElements
|
||||
.forEach(function (indicatorElement) {
|
||||
element.append(indicatorElement);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return MCTIndicators;
|
||||
}
|
||||
);
|
@ -1,76 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
["../../src/controllers/BottomBarController"],
|
||||
function (BottomBarController) {
|
||||
|
||||
describe("The bottom bar controller", function () {
|
||||
var testIndicators,
|
||||
testIndicatorA,
|
||||
testIndicatorB,
|
||||
testIndicatorC,
|
||||
mockIndicator,
|
||||
controller;
|
||||
|
||||
beforeEach(function () {
|
||||
mockIndicator = jasmine.createSpyObj(
|
||||
"indicator",
|
||||
["getGlyph", "getCssClass", "getText"]
|
||||
);
|
||||
|
||||
testIndicatorA = {};
|
||||
testIndicatorB = function () {
|
||||
return mockIndicator;
|
||||
};
|
||||
testIndicatorC = { template: "someTemplate" };
|
||||
|
||||
testIndicators = [
|
||||
testIndicatorA,
|
||||
testIndicatorB,
|
||||
testIndicatorC
|
||||
];
|
||||
|
||||
controller = new BottomBarController(testIndicators);
|
||||
});
|
||||
|
||||
it("exposes one indicator description per extension", function () {
|
||||
expect(controller.getIndicators().length)
|
||||
.toEqual(testIndicators.length);
|
||||
});
|
||||
|
||||
it("uses template field provided, or its own default", function () {
|
||||
// "indicator" is the default;
|
||||
// only testIndicatorC overrides this.
|
||||
var indicators = controller.getIndicators();
|
||||
expect(indicators[0].template).toEqual("indicator");
|
||||
expect(indicators[1].template).toEqual("indicator");
|
||||
expect(indicators[2].template).toEqual("someTemplate");
|
||||
});
|
||||
|
||||
it("instantiates indicators given as constructors", function () {
|
||||
// testIndicatorB constructs to mockIndicator
|
||||
expect(controller.getIndicators()[1].ngModel).toBe(mockIndicator);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
@ -1,9 +1,8 @@
|
||||
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
|
||||
<a ng-click="showNotificationsList()" ng-show="notifications.length > 0" class="status block"
|
||||
ng-class="highest.severity"
|
||||
<div ng-show="notifications.length > 0" class="ls-indicator s-status-{{highest.severity}} icon-bell"
|
||||
ng-controller="NotificationIndicatorController">
|
||||
<span class="status-indicator icon-bell"></span><span class="label">
|
||||
{{notifications.length}} Notifications
|
||||
<span class="label">
|
||||
<a ng-click="showNotificationsList()">
|
||||
{{notifications.length}} Notification<span ng-show="notifications.length > 1">s</span></a>
|
||||
</span><span class="count">{{notifications.length}}</span>
|
||||
|
||||
</a>
|
||||
</div>
|
||||
|
@ -3,6 +3,8 @@ $colorBodyBg: #333;
|
||||
$colorBodyFg: #999;
|
||||
$colorGenBg: #222;
|
||||
$colorStatusBarBg: #000;
|
||||
$colorStatusBarFg: #999;
|
||||
$colorStatusBarFgHov: #aaa;
|
||||
$colorKey: #0099cc;
|
||||
$colorKeySelectedBg: #005177;
|
||||
$colorKeyFg: #fff;
|
||||
@ -55,7 +57,7 @@ $colorTransLucBg: #666; // Used as a visual blocking element over variable backg
|
||||
|
||||
// Foundation Colors
|
||||
$colorAlt1: #ffc700;
|
||||
$colorAlert: #ff3c00;
|
||||
$colorAlert: #ff9900;
|
||||
$colorWarningHi: #cc0000;
|
||||
$colorWarningLo: #ff9900;
|
||||
$colorDiagnostic: #a4b442;
|
||||
@ -72,7 +74,6 @@ $colorObjHdrTxt: $colorBodyFg;
|
||||
$colorObjHdrIc: lighten($colorObjHdrTxt, 20%);
|
||||
$colorTick: rgba(white, 0.2);
|
||||
$colorSelectableSelectedPrimary: $colorKey;
|
||||
//$colorSelectableSelectedSecondary: pushBack($colorSelectableSelectedPrimary, 20%);
|
||||
$colorSelectableHov: rgba($colorBodyFg, 0.3);
|
||||
|
||||
// Menu colors
|
||||
@ -114,11 +115,10 @@ $colorInspectorSectionHeaderFg: pullForward($colorInspectorBg, 40%);
|
||||
|
||||
// Status colors, mainly used for messaging and item ancillary symbols
|
||||
$colorStatusFg: #ccc;
|
||||
$colorStatusDefault: #ccc;
|
||||
$colorStatusDefault: #999;
|
||||
$colorStatusInfo: $colorInfo;
|
||||
$colorStatusAlert: $colorAlert;
|
||||
$colorStatusError: #d4585c;
|
||||
$colorStatusAvailable: $colorKey;
|
||||
$colorStatusError: #da0004;
|
||||
$colorStatusBtnBg: $colorBtnBg;
|
||||
$colorProgressBarOuter: rgba(#000, 0.1);
|
||||
$colorProgressBarAmt: $colorKey;
|
||||
@ -127,6 +127,12 @@ $progressBarStripeW: 20px;
|
||||
$shdwStatusIc: rgba(black, 0.4) 0 1px 2px;
|
||||
$animPausedPulseDur: 500ms;
|
||||
|
||||
// Indicator colors
|
||||
$colorIndicatorAvailable: $colorKey;
|
||||
$colorIndicatorDisabled: #444;
|
||||
$colorIndicatorOn: $colorOk;
|
||||
$colorIndicatorOff: #666;
|
||||
|
||||
// Selects
|
||||
$colorSelectBg: $colorBtnBg;
|
||||
$colorSelectFg: $colorBtnFg;
|
||||
@ -177,7 +183,8 @@ $colorTabHeaderBorder: $colorBodyBg;
|
||||
// Plot
|
||||
$colorPlotBg: rgba(black, 0.1);
|
||||
$colorPlotFg: $colorBodyFg;
|
||||
$colorPlotHash: $colorTick;
|
||||
$colorPlotHash: white;
|
||||
$opacityPlotHash: 0.2;
|
||||
$stylePlotHash: dashed;
|
||||
$colorPlotAreaBorder: $colorInteriorBorder;
|
||||
$colorPlotLabelFg: pushBack($colorPlotFg, 20%);
|
||||
|
@ -3,6 +3,8 @@ $colorBodyBg: #fcfcfc;
|
||||
$colorBodyFg: #666;
|
||||
$colorGenBg: #fff;
|
||||
$colorStatusBarBg: #000;
|
||||
$colorStatusBarFg: #999;
|
||||
$colorStatusBarFgHov: #aaa;
|
||||
$colorKey: #0099cc;
|
||||
$colorKeySelectedBg: $colorKey;
|
||||
$colorKeyFg: #fff;
|
||||
@ -72,7 +74,6 @@ $colorObjHdrTxt: $colorBodyFg;
|
||||
$colorObjHdrIc: lighten($colorObjHdrTxt, 30%);
|
||||
$colorTick: rgba(black, 0.2);
|
||||
$colorSelectableSelectedPrimary: $colorKey;
|
||||
//$colorSelectableSelectedSecondary: pushBack($colorSelectableSelectedPrimary, 20%);
|
||||
$colorSelectableHov: rgba($colorBodyFg, 0.4);
|
||||
|
||||
// Menu colors
|
||||
@ -117,8 +118,7 @@ $colorStatusFg: #999;
|
||||
$colorStatusDefault: #ccc;
|
||||
$colorStatusInfo: #60ba7b;
|
||||
$colorStatusAlert: #ffb66c;
|
||||
$colorStatusError: #c96b68;
|
||||
$colorStatusAvailable: $colorKey;
|
||||
$colorStatusError: #da0004;
|
||||
$colorStatusBtnBg: #666;
|
||||
$colorProgressBarOuter: rgba(#000, 0.1);
|
||||
$colorProgressBarAmt: #0a0;
|
||||
@ -127,6 +127,12 @@ $progressBarStripeW: 20px;
|
||||
$shdwStatusIc: rgba(white, 0.8) 0 0px 5px;
|
||||
$animPausedPulseDur: 1s;
|
||||
|
||||
// Indicator colors
|
||||
$colorIndicatorAvailable: $colorKey;
|
||||
$colorIndicatorDisabled: #444;
|
||||
$colorIndicatorOn: $colorOk;
|
||||
$colorIndicatorOff: #666;
|
||||
|
||||
// Selects
|
||||
$colorSelectBg: $colorBtnBg;
|
||||
$colorSelectFg: $colorBtnFg;
|
||||
@ -177,7 +183,8 @@ $colorTabHeaderBorder: $colorBodyBg;
|
||||
// Plot
|
||||
$colorPlotBg: rgba(black, 0.05);
|
||||
$colorPlotFg: $colorBodyFg;
|
||||
$colorPlotHash: $colorTick;
|
||||
$colorPlotHash: black;
|
||||
$opacityPlotHash: 0.2;
|
||||
$stylePlotHash: dashed;
|
||||
$colorPlotAreaBorder: $colorInteriorBorder;
|
||||
$colorPlotLabelFg: pushBack($colorPlotFg, 20%);
|
||||
|
@ -55,7 +55,6 @@ define([
|
||||
timerTemplate,
|
||||
legacyRegistry
|
||||
) {
|
||||
|
||||
legacyRegistry.register("platform/features/clock", {
|
||||
"name": "Clocks/Timers",
|
||||
"descriptions": "Domain objects for displaying current & relative times.",
|
||||
@ -86,11 +85,6 @@ define([
|
||||
"CLOCK_INDICATOR_FORMAT"
|
||||
],
|
||||
"priority": "preferred"
|
||||
},
|
||||
{
|
||||
"implementation": FollowIndicator,
|
||||
"depends": ["timerService"],
|
||||
"priority": "fallback"
|
||||
}
|
||||
],
|
||||
"services": [
|
||||
@ -305,6 +299,10 @@ define([
|
||||
}
|
||||
}
|
||||
],
|
||||
"runs": [{
|
||||
"implementation": FollowIndicator,
|
||||
"depends": ["openmct", "timerService"]
|
||||
}],
|
||||
"licenses": [
|
||||
{
|
||||
"name": "moment-duration-format",
|
||||
|
@ -45,11 +45,11 @@ define(
|
||||
}
|
||||
|
||||
ClockIndicator.prototype.getGlyphClass = function () {
|
||||
return "no-collapse float-right subdued";
|
||||
return "";
|
||||
};
|
||||
|
||||
ClockIndicator.prototype.getCssClass = function () {
|
||||
return "icon-clock";
|
||||
return "t-indicator-clock icon-clock no-collapse float-right";
|
||||
};
|
||||
|
||||
ClockIndicator.prototype.getText = function () {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-2016, United States Government
|
||||
* Open MCT, Copyright (c) 2009-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
@ -20,38 +20,32 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
['moment'],
|
||||
function (moment) {
|
||||
var NO_TIMER = "No timer being followed";
|
||||
define([], function () {
|
||||
|
||||
/**
|
||||
* Indicator that displays the active timer, as well as its
|
||||
* current state.
|
||||
* @implements {Indicator}
|
||||
* @memberof platform/features/clock
|
||||
*/
|
||||
function FollowIndicator(timerService) {
|
||||
this.timerService = timerService;
|
||||
/**
|
||||
* Indicator that displays the active timer, as well as its
|
||||
* current state.
|
||||
* @memberof platform/features/clock
|
||||
*/
|
||||
return function installFollowIndicator(openmct, timerService) {
|
||||
var indicator = openmct.indicators.simpleIndicator();
|
||||
var timer = timerService.getTimer();
|
||||
setIndicatorStatus(timer);
|
||||
|
||||
function setIndicatorStatus(newTimer) {
|
||||
if (newTimer !== undefined) {
|
||||
indicator.iconClass('icon-timer');
|
||||
indicator.statusClass('s-status-on');
|
||||
indicator.text('Following timer ' + newTimer.name);
|
||||
} else {
|
||||
indicator.iconClass('icon-timer');
|
||||
indicator.statusClass('s-status-disabled');
|
||||
indicator.text('No timer being followed');
|
||||
}
|
||||
}
|
||||
|
||||
FollowIndicator.prototype.getGlyphClass = function () {
|
||||
return "";
|
||||
};
|
||||
timerService.on('change', setIndicatorStatus);
|
||||
|
||||
FollowIndicator.prototype.getCssClass = function () {
|
||||
return (this.timerService.getTimer()) ? "icon-timer s-status-ok" : "icon-timer";
|
||||
};
|
||||
|
||||
FollowIndicator.prototype.getText = function () {
|
||||
var timer = this.timerService.getTimer();
|
||||
return timer ? ('Following timer ' + timer.name) : NO_TIMER;
|
||||
};
|
||||
|
||||
FollowIndicator.prototype.getDescription = function () {
|
||||
return "";
|
||||
};
|
||||
|
||||
return FollowIndicator;
|
||||
}
|
||||
);
|
||||
openmct.indicators.add(indicator);
|
||||
};
|
||||
});
|
||||
|
@ -44,7 +44,7 @@ define(['EventEmitter'], function (EventEmitter) {
|
||||
*/
|
||||
TimerService.prototype.setTimer = function (timer) {
|
||||
this.timer = timer;
|
||||
this.emit('change');
|
||||
this.emit('change', timer);
|
||||
|
||||
if (this.stopObserving) {
|
||||
this.stopObserving();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-2016, United States Government
|
||||
* Open MCT, Copyright (c) 2009-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
@ -20,39 +20,77 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define(["../../src/indicators/FollowIndicator"], function (FollowIndicator) {
|
||||
var TIMER_SERVICE_METHODS =
|
||||
['setTimer', 'getTimer', 'clearTimer', 'on', 'off'];
|
||||
|
||||
define([
|
||||
"../../src/indicators/FollowIndicator",
|
||||
"../../src/services/TimerService",
|
||||
"../../../../../src/MCT",
|
||||
'zepto'
|
||||
], function (
|
||||
FollowIndicator,
|
||||
TimerService,
|
||||
MCT,
|
||||
$
|
||||
) {
|
||||
describe("The timer-following indicator", function () {
|
||||
var mockTimerService;
|
||||
var indicator;
|
||||
var timerService;
|
||||
var openmct;
|
||||
|
||||
beforeEach(function () {
|
||||
mockTimerService =
|
||||
jasmine.createSpyObj('timerService', TIMER_SERVICE_METHODS);
|
||||
indicator = new FollowIndicator(mockTimerService);
|
||||
openmct = new MCT();
|
||||
timerService = new TimerService(openmct);
|
||||
spyOn(openmct.indicators, "add");
|
||||
});
|
||||
|
||||
it("implements the Indicator interface", function () {
|
||||
expect(indicator.getGlyphClass()).toEqual(jasmine.any(String));
|
||||
expect(indicator.getCssClass()).toEqual(jasmine.any(String));
|
||||
expect(indicator.getText()).toEqual(jasmine.any(String));
|
||||
expect(indicator.getDescription()).toEqual(jasmine.any(String));
|
||||
it("adds an indicator when installed", function () {
|
||||
FollowIndicator(openmct, timerService);
|
||||
expect(openmct.indicators.add).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("indicates that no timer is being followed", function () {
|
||||
FollowIndicator(openmct, timerService);
|
||||
var simpleIndicator = openmct.indicators.add.calls.mostRecent().args[0];
|
||||
var element = simpleIndicator.element;
|
||||
var text = $('.indicator-text', element).text().trim();
|
||||
expect(text).toEqual('No timer being followed');
|
||||
});
|
||||
|
||||
describe("when a timer is set", function () {
|
||||
var testObject;
|
||||
var simpleIndicator;
|
||||
|
||||
beforeEach(function () {
|
||||
testObject = { name: "some timer!" };
|
||||
mockTimerService.getTimer.and.returnValue(testObject);
|
||||
testObject = {
|
||||
identifier: {
|
||||
namespace: 'namespace',
|
||||
key: 'key'
|
||||
},
|
||||
name: "some timer!"
|
||||
};
|
||||
timerService.setTimer(testObject);
|
||||
FollowIndicator(openmct, timerService);
|
||||
simpleIndicator = openmct.indicators.add.calls.mostRecent().args[0];
|
||||
});
|
||||
|
||||
it("displays the timer's name", function () {
|
||||
expect(indicator.getText().indexOf(testObject.name))
|
||||
.not.toEqual(-1);
|
||||
var element = simpleIndicator.element;
|
||||
var text = $('.indicator-text', element).text().trim();
|
||||
expect(text).toEqual('Following timer ' + testObject.name);
|
||||
});
|
||||
|
||||
it("displays the timer's name when it changes", function () {
|
||||
var secondTimer = {
|
||||
identifier: {
|
||||
namespace: 'namespace',
|
||||
key: 'key2'
|
||||
},
|
||||
name: "Some other timer"
|
||||
};
|
||||
var element = simpleIndicator.element;
|
||||
timerService.setTimer(secondTimer);
|
||||
var text = $('.indicator-text', element).text().trim();
|
||||
expect(text).toEqual('Following timer ' + secondTimer.name);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -58,7 +58,8 @@ define([
|
||||
"model": {
|
||||
"entries": [],
|
||||
"composition": [],
|
||||
"entryTypes": []
|
||||
"entryTypes": [],
|
||||
"defaultSort": "-createdOn"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
@ -236,7 +237,6 @@ define([
|
||||
"cssClass": "icon-notebook labeled",
|
||||
"description": "Add a new Notebook entry",
|
||||
"category": [
|
||||
"contextual",
|
||||
"view-control"
|
||||
],
|
||||
"depends": [
|
||||
@ -252,13 +252,13 @@ define([
|
||||
"licenses": [
|
||||
{
|
||||
"name": "painterro",
|
||||
"version": "4.1.0",
|
||||
"author": "Mike Bostock",
|
||||
"description": "D3 (or D3.js) is a JavaScript library for visualizing data using web standards. D3 helps you bring data to life using SVG, Canvas and HTML. D3 combines powerful visualization and interaction techniques with a data-driven approach to DOM manipulation, giving you the full capabilities of modern browsers and the freedom to design the right visual interface for your data.",
|
||||
"website": "https://d3js.org/",
|
||||
"copyright": "Copyright 2010-2016 Mike Bostock",
|
||||
"license": "BSD-3-Clause",
|
||||
"link": "https://github.com/d3/d3/blob/master/LICENSE"
|
||||
"version": "0.2.65",
|
||||
"author": "Ivan Borshchov",
|
||||
"description": "Painterro is JavaScript paint widget which allows editing images directly in a browser.",
|
||||
"website": "https://github.com/ivictbor/painterro",
|
||||
"copyright": "Copyright 2017 Ivan Borshchov",
|
||||
"license": "MIT",
|
||||
"link": "https://github.com/ivictbor/painterro/blob/master/LICENSE"
|
||||
}
|
||||
],
|
||||
"capabilities": [
|
||||
|
@ -185,7 +185,18 @@ define(
|
||||
|
||||
NewEntryContextual.appliesTo = function (context) {
|
||||
var domainObject = context.domainObject;
|
||||
return !!(domainObject && domainObject.getModel().type !== 'notebook');
|
||||
|
||||
if (domainObject) {
|
||||
if (domainObject.getModel().type === 'Notebook') {
|
||||
// do not allow in context of a notebook
|
||||
return false;
|
||||
} else if (domainObject.getModel().type.includes('imagery')) {
|
||||
// do not allow in the context of an object with imagery
|
||||
// (because of cross domain issue with snapshot)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
return NewEntryContextual;
|
||||
|
@ -42,7 +42,7 @@ define(
|
||||
) {
|
||||
|
||||
$scope.entriesEl = $(document.body).find('.t-entries-list');
|
||||
$scope.sortEntries = $scope.domainObject.getModel().defaultSort || "-createdOn";
|
||||
$scope.sortEntries = $scope.domainObject.getModel().defaultSort;
|
||||
$scope.showTime = "0";
|
||||
$scope.editEntry = false;
|
||||
$scope.entrySearch = '';
|
||||
@ -354,6 +354,11 @@ define(
|
||||
|
||||
$scope.$watchCollection("composition", refreshComp);
|
||||
|
||||
$scope.$watch('domainObject.getModel().defaultSort', function (newDefaultSort, oldDefaultSort) {
|
||||
if (newDefaultSort !== oldDefaultSort) {
|
||||
$scope.sortEntries = newDefaultSort;
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$on('$destroy', function () {});
|
||||
|
||||
|
@ -25,7 +25,7 @@ define(['zepto'], function ($) {
|
||||
var document = $document[0];
|
||||
|
||||
function link($scope, $element, $attrs) {
|
||||
var objectElement = $(document.body).find('.overlay')[0] || $(document.body).find("[key='representation.selected.key']")[0],
|
||||
var objectElement = $(document.body).find(".overlay .object-holder")[0] || $(document.body).find("[key='representation.selected.key']")[0],
|
||||
takeSnapshot,
|
||||
makeImg,
|
||||
saveImg;
|
||||
|
@ -20,7 +20,7 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
mct-table {
|
||||
.mct-sizing-table {
|
||||
z-index: -1;
|
||||
visibility: hidden;
|
||||
@ -57,13 +57,18 @@
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mct-table {
|
||||
.l-control-bar {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.mct-table-scroll-forcer {
|
||||
// Force horz scroll when needed; width set via JS
|
||||
font-size: 0;
|
||||
height: 1px; // Height 0 won't force scroll properly
|
||||
position: relative;
|
||||
}
|
||||
|
@ -59,6 +59,10 @@
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="l-tabular-body t-scrolling vscroll--persist" mct-resize="resize()" mct-scroll-x="scroll.x">
|
||||
<div class="mct-table-scroll-forcer"
|
||||
ng-style="{
|
||||
width: totalWidth
|
||||
}"></div>
|
||||
<table class="mct-table"
|
||||
ng-style="{
|
||||
height: totalHeight + 'px',
|
||||
|
@ -50,9 +50,7 @@ define(function () {
|
||||
};
|
||||
|
||||
TableColumn.prototype.getValue = function (telemetryDatum, limitEvaluator) {
|
||||
var isValueColumn = !!(this.metadatum.hints.y || this.metadatum.hints.range);
|
||||
var alarm = isValueColumn &&
|
||||
limitEvaluator &&
|
||||
var alarm = limitEvaluator &&
|
||||
limitEvaluator.evaluate(telemetryDatum, this.metadatum);
|
||||
var value = {
|
||||
text: this.formatter.format(telemetryDatum),
|
||||
|
@ -262,19 +262,26 @@ define(
|
||||
* @private
|
||||
*/
|
||||
MCTTableController.prototype.onScroll = function (event) {
|
||||
this.scrollWindow = {
|
||||
top: this.scrollable[0].scrollTop,
|
||||
bottom: this.scrollable[0].scrollTop + this.scrollable[0].offsetHeight,
|
||||
offsetHeight: this.scrollable[0].offsetHeight,
|
||||
height: this.scrollable[0].scrollHeight
|
||||
};
|
||||
this.$window.requestAnimationFrame(function () {
|
||||
this.setVisibleRows();
|
||||
this.digest();
|
||||
|
||||
// If user scrolls away from bottom, disable auto-scroll.
|
||||
// Auto-scroll will be re-enabled if user scrolls to bottom again.
|
||||
if (this.scrollable[0].scrollTop <
|
||||
(this.scrollable[0].scrollHeight - this.scrollable[0].offsetHeight) - 20) {
|
||||
if (this.scrollWindow.top <
|
||||
(this.scrollWindow.height - this.scrollWindow.offsetHeight) - 20) {
|
||||
this.$scope.autoScroll = false;
|
||||
} else {
|
||||
this.$scope.autoScroll = true;
|
||||
}
|
||||
this.scrolling = false;
|
||||
delete this.scrollWindow;
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
@ -283,15 +290,14 @@ define(
|
||||
* @private
|
||||
*/
|
||||
MCTTableController.prototype.firstVisible = function () {
|
||||
var target = this.scrollable[0],
|
||||
topScroll = target.scrollTop,
|
||||
firstVisible;
|
||||
var topScroll = this.scrollWindow ?
|
||||
this.scrollWindow.top :
|
||||
this.scrollable[0].scrollTop;
|
||||
|
||||
firstVisible = Math.floor(
|
||||
return Math.floor(
|
||||
(topScroll) / this.$scope.rowHeight
|
||||
);
|
||||
|
||||
return firstVisible;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -299,16 +305,14 @@ define(
|
||||
* @private
|
||||
*/
|
||||
MCTTableController.prototype.lastVisible = function () {
|
||||
var target = this.scrollable[0],
|
||||
topScroll = target.scrollTop,
|
||||
bottomScroll = topScroll + target.offsetHeight,
|
||||
lastVisible;
|
||||
var bottomScroll = this.scrollWindow ?
|
||||
this.scrollWindow.bottom :
|
||||
this.scrollable[0].scrollTop + this.scrollable[0].offsetHeight;
|
||||
|
||||
lastVisible = Math.ceil(
|
||||
return Math.ceil(
|
||||
(bottomScroll) /
|
||||
this.$scope.rowHeight
|
||||
);
|
||||
return lastVisible;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -21,597 +21,29 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
"./src/actions/ExportTimelineAsCSVAction",
|
||||
"./src/controllers/TimelineController",
|
||||
"./src/controllers/TimelineGraphController",
|
||||
"./src/controllers/TimelineDateTimeController",
|
||||
"./src/controllers/TimelineZoomController",
|
||||
"./src/controllers/TimelineTickController",
|
||||
"./src/controllers/TimelineTableController",
|
||||
"./src/controllers/TimelineGanttController",
|
||||
"./src/controllers/TimelineTOIController",
|
||||
"./src/controllers/ActivityModeValuesController",
|
||||
"./src/capabilities/ActivityTimespanCapability",
|
||||
"./src/capabilities/TimelineTimespanCapability",
|
||||
"./src/capabilities/UtilizationCapability",
|
||||
"./src/capabilities/GraphCapability",
|
||||
"./src/capabilities/CostCapability",
|
||||
"./src/directives/MCTSwimlaneDrop",
|
||||
"./src/directives/MCTSwimlaneDrag",
|
||||
"./src/directives/MCTResourceGraphDrop",
|
||||
"./src/services/ObjectLoader",
|
||||
"./src/chart/MCTTimelineChart",
|
||||
"text!./res/templates/values.html",
|
||||
"text!./res/templates/timeline.html",
|
||||
"text!./res/templates/activity-gantt.html",
|
||||
"text!./res/templates/tabular-swimlane-cols-tree.html",
|
||||
"text!./res/templates/tabular-swimlane-cols-data.html",
|
||||
"text!./res/templates/resource-graphs.html",
|
||||
"text!./res/templates/resource-graph-labels.html",
|
||||
"text!./res/templates/legend-item.html",
|
||||
"text!./res/templates/ticks.html",
|
||||
"text!./res/templates/controls/datetime.html",
|
||||
"text!./res/templates/deprecated-timeline-message.html",
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
ExportTimelineAsCSVAction,
|
||||
TimelineController,
|
||||
TimelineGraphController,
|
||||
TimelineDateTimeController,
|
||||
TimelineZoomController,
|
||||
TimelineTickController,
|
||||
TimelineTableController,
|
||||
TimelineGanttController,
|
||||
TimelineTOIController,
|
||||
ActivityModeValuesController,
|
||||
ActivityTimespanCapability,
|
||||
TimelineTimespanCapability,
|
||||
UtilizationCapability,
|
||||
GraphCapability,
|
||||
CostCapability,
|
||||
MCTSwimlaneDrop,
|
||||
MCTSwimlaneDrag,
|
||||
MCTResourceGraphDrop,
|
||||
ObjectLoader,
|
||||
MCTTimelineChart,
|
||||
valuesTemplate,
|
||||
timelineTemplate,
|
||||
activityGanttTemplate,
|
||||
tabularSwimlaneColsTreeTemplate,
|
||||
tabularSwimlaneColsDataTemplate,
|
||||
resourceGraphsTemplate,
|
||||
resourceGraphLabelsTemplate,
|
||||
legendItemTemplate,
|
||||
ticksTemplate,
|
||||
datetimeTemplate,
|
||||
deprecatedTimelineMessage,
|
||||
legacyRegistry
|
||||
) {
|
||||
|
||||
legacyRegistry.register("platform/features/timeline", {
|
||||
"name": "Timelines",
|
||||
"description": "Resources, templates, CSS, and code for Timelines.",
|
||||
"resources": "res",
|
||||
"extensions": {
|
||||
"actions": [
|
||||
legacyRegistry.register('platform/features/timeline', {
|
||||
extensions: {
|
||||
types: [
|
||||
{
|
||||
"key": "timeline.export",
|
||||
"name": "Export Timeline as CSV",
|
||||
"category": "contextual",
|
||||
"implementation": ExportTimelineAsCSVAction,
|
||||
"depends": [
|
||||
"$log",
|
||||
"exportService",
|
||||
"notificationService",
|
||||
"resources[]"
|
||||
]
|
||||
key: "timeline",
|
||||
name: "Timeline",
|
||||
description: "Timeline, Activity and Activity Mode objects have been deprecated and will no longer be supported. (07/18/2018)",
|
||||
priority: 502
|
||||
}
|
||||
],
|
||||
"constants": [
|
||||
views: [
|
||||
{
|
||||
"key": "TIMELINE_MINIMUM_DURATION",
|
||||
"description": "The minimum duration to display in a timeline view (one hour.)",
|
||||
"value": 3600000
|
||||
},
|
||||
{
|
||||
"key": "TIMELINE_MAXIMUM_OFFSCREEN",
|
||||
"description": "Maximum amount, in pixels, of a Gantt bar which may go off screen.",
|
||||
"value": 1000
|
||||
},
|
||||
{
|
||||
"key": "TIMELINE_ZOOM_CONFIGURATION",
|
||||
"description": "Describes major tick sizes in milliseconds, and width in pixels.",
|
||||
"value": {
|
||||
"levels": [
|
||||
1000,
|
||||
2000,
|
||||
5000,
|
||||
10000,
|
||||
20000,
|
||||
30000,
|
||||
60000,
|
||||
120000,
|
||||
300000,
|
||||
600000,
|
||||
1200000,
|
||||
1800000,
|
||||
3600000,
|
||||
7200000,
|
||||
14400000,
|
||||
28800000,
|
||||
43200000,
|
||||
86400000,
|
||||
86400000 * 2,
|
||||
86400000 * 5,
|
||||
86400000 * 10,
|
||||
86400000 * 20,
|
||||
86400000 * 30,
|
||||
86400000 * 60,
|
||||
86400000 * 120,
|
||||
86400000 * 240,
|
||||
86400000 * 365
|
||||
],
|
||||
"width": 200
|
||||
}
|
||||
}
|
||||
],
|
||||
"types": [
|
||||
{
|
||||
"key": "timeline",
|
||||
"name": "Timeline",
|
||||
"cssClass": "icon-timeline",
|
||||
"description": "A time-oriented container that lets you enclose and organize other Timelines and Activities. The Timeline view provides both tabular and Gantt views as well as resource utilization graphing of Activities.",
|
||||
"priority": 502,
|
||||
"features": [
|
||||
"creation"
|
||||
],
|
||||
"contains": [
|
||||
"timeline",
|
||||
"activity"
|
||||
],
|
||||
"properties": [
|
||||
{
|
||||
"name": "Start date/time",
|
||||
"control": "timeline-datetime",
|
||||
"required": true,
|
||||
"property": [
|
||||
"start"
|
||||
],
|
||||
"options": [
|
||||
"SET"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Battery capacity (Watt-hours)",
|
||||
"control": "textfield",
|
||||
"required": false,
|
||||
"conversion": "number",
|
||||
"property": [
|
||||
"capacity"
|
||||
],
|
||||
"pattern": "^-?\\d+(\\.\\d*)?$"
|
||||
},
|
||||
{
|
||||
"name": "Battery starting SOC (%)",
|
||||
"control": "textfield",
|
||||
"required": false,
|
||||
"conversion": "number",
|
||||
"property": [
|
||||
"startingSOC"
|
||||
],
|
||||
"pattern": "^([0-9](\\.\\d*)?|[1-9][0-9](\\.\\d*)?|100)%?$"
|
||||
}
|
||||
],
|
||||
"model": {
|
||||
"composition": [],
|
||||
"start": {
|
||||
"timestamp": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "activity",
|
||||
"name": "Activity",
|
||||
"cssClass": "icon-activity",
|
||||
"features": [
|
||||
"creation"
|
||||
],
|
||||
"contains": [
|
||||
"activity"
|
||||
],
|
||||
"description": "An event or process that starts and ends at a discrete datetime. Activities can be nested in other Activities, and can be added to Timelines. Activity Modes can be added to an Activity to define its resource utilization over time.",
|
||||
"priority": 501,
|
||||
"properties": [
|
||||
{
|
||||
"name": "Start date/time",
|
||||
"control": "timeline-datetime",
|
||||
"required": true,
|
||||
"property": [
|
||||
"start"
|
||||
],
|
||||
"options": [
|
||||
"SET"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Duration",
|
||||
"control": "duration",
|
||||
"required": true,
|
||||
"property": [
|
||||
"duration"
|
||||
]
|
||||
}
|
||||
],
|
||||
"model": {
|
||||
"composition": [],
|
||||
"relationships": {
|
||||
"modes": []
|
||||
},
|
||||
"start": {
|
||||
"timestamp": 0
|
||||
},
|
||||
"duration": {
|
||||
"timestamp": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "mode",
|
||||
"name": "Activity Mode",
|
||||
"cssClass": "icon-activity-mode",
|
||||
"features": [
|
||||
"creation"
|
||||
],
|
||||
"description": "When a sub-system utilizes Power or Communications resources over time, you can define those values in an Activity Mode. Activity Modes can then be linked to Activities to allow resource utilization graphing and estimating in a Timeline.",
|
||||
"priority": 500,
|
||||
"model": {
|
||||
"resources": {
|
||||
"comms": 0,
|
||||
"power": 0
|
||||
}
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"name": "Comms (Kbps)",
|
||||
"control": "textfield",
|
||||
"conversion": "number",
|
||||
"pattern": "^-?\\d+(\\.\\d*)?$",
|
||||
"property": [
|
||||
"resources",
|
||||
"comms"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Power (watts)",
|
||||
"control": "textfield",
|
||||
"conversion": "number",
|
||||
"pattern": "^-?\\d+(\\.\\d*)?$",
|
||||
"property": [
|
||||
"resources",
|
||||
"power"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"views": [
|
||||
{
|
||||
"key": "values",
|
||||
"name": "Values",
|
||||
"cssClass": "icon-activity-mode",
|
||||
"template": valuesTemplate,
|
||||
"type": "mode",
|
||||
"uses": [
|
||||
"cost"
|
||||
],
|
||||
"editable": false
|
||||
},
|
||||
{
|
||||
"key": "timeline",
|
||||
"name": "Timeline",
|
||||
"cssClass": "icon-timeline",
|
||||
"type": "timeline",
|
||||
"description": "A time-oriented container that lets you enclose and organize other Timelines and Activities. The Timeline view provides both tabular and Gantt views as well as resource utilization graphing of Activities.",
|
||||
"template": timelineTemplate,
|
||||
"editable": true,
|
||||
"toolbar": {
|
||||
"sections": [
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"method": "add",
|
||||
"control": "menu-button",
|
||||
"text": "Add",
|
||||
"options": [
|
||||
{
|
||||
"name": "Timeline",
|
||||
"cssClass": "icon-timeline",
|
||||
"key": "timeline"
|
||||
},
|
||||
{
|
||||
"name": "Activity",
|
||||
"cssClass": "icon-activity",
|
||||
"key": "activity"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"cssClass": "icon-plot-resource",
|
||||
"description": "Graph Resource Utilization",
|
||||
"control": "button",
|
||||
"method": "toggleGraph"
|
||||
},
|
||||
{
|
||||
"cssClass": "icon-activity-mode",
|
||||
"control": "dialog-button",
|
||||
"description": "Apply Activity Modes...",
|
||||
"title": "Apply Activity Modes",
|
||||
"dialog": {
|
||||
"control": "selector",
|
||||
"name": "Modes",
|
||||
"type": "mode",
|
||||
"layout": "controls-under"
|
||||
},
|
||||
"property": "modes"
|
||||
},
|
||||
{
|
||||
"cssClass": "icon-chain-links",
|
||||
"description": "Edit Activity Link",
|
||||
"title": "Activity Link",
|
||||
"control": "dialog-button",
|
||||
"dialog": {
|
||||
"control": "textfield",
|
||||
"name": "Link",
|
||||
"pattern": "^(ftp|https?)\\:\\/\\/\\w+(\\.\\w+)*(\\:\\d+)?(\\/\\S*)*$",
|
||||
"cssClass": "l-input-lg"
|
||||
},
|
||||
"property": "link"
|
||||
},
|
||||
{
|
||||
"cssClass": "icon-gear",
|
||||
"description": "Edit Properties...",
|
||||
"control": "button",
|
||||
"method": "properties"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"method": "remove",
|
||||
"description": "Remove Item",
|
||||
"control": "button",
|
||||
"cssClass": "icon-trash"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"stylesheets": [
|
||||
{
|
||||
"stylesheetUrl": "css/timeline.css"
|
||||
},
|
||||
{
|
||||
"stylesheetUrl": "css/timeline-espresso.css",
|
||||
"theme": "espresso"
|
||||
},
|
||||
{
|
||||
"stylesheetUrl": "css/timeline-snow.css",
|
||||
"theme": "snow"
|
||||
}
|
||||
],
|
||||
"representations": [
|
||||
{
|
||||
"key": "gantt",
|
||||
"template": activityGanttTemplate,
|
||||
"uses": [
|
||||
"timespan",
|
||||
"type"
|
||||
]
|
||||
}
|
||||
],
|
||||
"templates": [
|
||||
{
|
||||
"key": "timeline-tabular-swimlane-cols-tree",
|
||||
"priority": "mandatory",
|
||||
"template": tabularSwimlaneColsTreeTemplate
|
||||
},
|
||||
{
|
||||
"key": "timeline-tabular-swimlane-cols-data",
|
||||
"priority": "mandatory",
|
||||
"template": tabularSwimlaneColsDataTemplate
|
||||
},
|
||||
{
|
||||
"key": "timeline-resource-graphs",
|
||||
"priority": "mandatory",
|
||||
"template": resourceGraphsTemplate
|
||||
},
|
||||
{
|
||||
"key": "timeline-resource-graph-labels",
|
||||
"priority": "mandatory",
|
||||
"template": resourceGraphLabelsTemplate
|
||||
},
|
||||
{
|
||||
"key": "timeline-legend-item",
|
||||
"priority": "mandatory",
|
||||
"template": legendItemTemplate
|
||||
},
|
||||
{
|
||||
"key": "timeline-ticks",
|
||||
"priority": "mandatory",
|
||||
"template": ticksTemplate
|
||||
}
|
||||
],
|
||||
"controls": [
|
||||
{
|
||||
"key": "timeline-datetime",
|
||||
"template": datetimeTemplate
|
||||
},
|
||||
{
|
||||
"key": "duration",
|
||||
"template": datetimeTemplate
|
||||
}
|
||||
],
|
||||
"controllers": [
|
||||
{
|
||||
"key": "TimelineController",
|
||||
"implementation": TimelineController,
|
||||
"depends": [
|
||||
"$scope",
|
||||
"$q",
|
||||
"objectLoader",
|
||||
"TIMELINE_MINIMUM_DURATION"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "TimelineGraphController",
|
||||
"implementation": TimelineGraphController,
|
||||
"depends": [
|
||||
"$scope",
|
||||
"resources[]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "TimelineDateTimeController",
|
||||
"implementation": TimelineDateTimeController,
|
||||
"depends": [
|
||||
"$scope"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "TimelineZoomController",
|
||||
"implementation": TimelineZoomController,
|
||||
"depends": [
|
||||
"$scope",
|
||||
"$window",
|
||||
"TIMELINE_ZOOM_CONFIGURATION"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "TimelineTickController",
|
||||
"implementation": TimelineTickController
|
||||
},
|
||||
{
|
||||
"key": "TimelineTableController",
|
||||
"implementation": TimelineTableController
|
||||
},
|
||||
{
|
||||
"key": "TimelineGanttController",
|
||||
"implementation": TimelineGanttController,
|
||||
"depends": [
|
||||
"TIMELINE_MAXIMUM_OFFSCREEN"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "TimelineTOIController",
|
||||
"implementation": TimelineTOIController,
|
||||
"depends": [
|
||||
"openmct",
|
||||
"timerService",
|
||||
"$scope"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "ActivityModeValuesController",
|
||||
"implementation": ActivityModeValuesController,
|
||||
"depends": [
|
||||
"resources[]"
|
||||
]
|
||||
}
|
||||
],
|
||||
"capabilities": [
|
||||
{
|
||||
"key": "timespan",
|
||||
"implementation": ActivityTimespanCapability,
|
||||
"depends": [
|
||||
"$q"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "timespan",
|
||||
"implementation": TimelineTimespanCapability,
|
||||
"depends": [
|
||||
"$q"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "utilization",
|
||||
"implementation": UtilizationCapability,
|
||||
"depends": [
|
||||
"$q"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "graph",
|
||||
"implementation": GraphCapability,
|
||||
"depends": [
|
||||
"$q"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "cost",
|
||||
"implementation": CostCapability
|
||||
}
|
||||
],
|
||||
"directives": [
|
||||
{
|
||||
"key": "mctSwimlaneDrop",
|
||||
"implementation": MCTSwimlaneDrop,
|
||||
"depends": [
|
||||
"dndService"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "mctSwimlaneDrag",
|
||||
"implementation": MCTSwimlaneDrag,
|
||||
"depends": [
|
||||
"dndService"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "mctTimelineChart",
|
||||
"implementation": MCTTimelineChart,
|
||||
"depends": [
|
||||
"$interval",
|
||||
"$log"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "mctResourceGraphDrop",
|
||||
"implementation": MCTResourceGraphDrop,
|
||||
"depends": [
|
||||
"dndService"
|
||||
]
|
||||
}
|
||||
],
|
||||
"services": [
|
||||
{
|
||||
"key": "objectLoader",
|
||||
"implementation": ObjectLoader,
|
||||
"depends": [
|
||||
"$q"
|
||||
]
|
||||
}
|
||||
],
|
||||
"resources": [
|
||||
{
|
||||
"key": "power",
|
||||
"name": "Power",
|
||||
"units": "watts"
|
||||
},
|
||||
{
|
||||
"key": "comms",
|
||||
"name": "Comms",
|
||||
"units": "Kbps"
|
||||
},
|
||||
{
|
||||
"key": "battery",
|
||||
"name": "Battery State-of-Charge",
|
||||
"units": "%"
|
||||
key: "timeline",
|
||||
name: "Timeline",
|
||||
type: "timeline",
|
||||
description: "Timeline, Activity and Activity Mode objects have been deprecated and will no longer be supported. (07/18/2018)",
|
||||
template: deprecatedTimelineMessage
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1,77 +0,0 @@
|
||||
.l-timeline-gantt {
|
||||
min-width: 2px;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: $timelineSwimlaneGanttVM; bottom: $timelineSwimlaneGanttVM;
|
||||
|
||||
.bar {
|
||||
@include ellipsize();
|
||||
height: $activityBarH;
|
||||
line-height: $activityBarH;
|
||||
padding: 0 $interiorMargin;
|
||||
|
||||
span {
|
||||
$iconW: 20px;
|
||||
@include absPosDefault();
|
||||
display: block;
|
||||
&.s-activity-type {
|
||||
right: auto; width: $iconW;
|
||||
text-align: center;
|
||||
&.timeline {
|
||||
&:before {
|
||||
content:"S";
|
||||
}
|
||||
}
|
||||
&.activity {
|
||||
&:before {
|
||||
content:"A";
|
||||
}
|
||||
}
|
||||
}
|
||||
&.s-title {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
left: $iconW;
|
||||
}
|
||||
&.duration {
|
||||
left: auto;
|
||||
opacity: 0.75;
|
||||
right: 0;
|
||||
text-align: right;
|
||||
width: 60px;
|
||||
}
|
||||
&.handle {
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
height: auto;
|
||||
width: 15px;
|
||||
&.left {
|
||||
right: auto;
|
||||
}
|
||||
&.middle {
|
||||
right: 15px;
|
||||
left: 15px;
|
||||
width: auto;
|
||||
}
|
||||
&.right {
|
||||
right: 0;
|
||||
left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&.sm .bar span {
|
||||
// Hide icon and label if width is too small
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.edit-mode .s-timeline-gantt,
|
||||
.s-status-editing .s-timeline-gantt {
|
||||
.handle {
|
||||
cursor: col-resize;
|
||||
&.mid {
|
||||
cursor: ew-resize;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
// General
|
||||
$timelineHeaderColorBg: pullForward($colorBodyBg, 5%);
|
||||
$timelineColorAlt1: pullForward($timelineHeaderColorBg, 10%);
|
||||
$colorGanttBarBg: #5555aa;
|
||||
$colorGanttBarFg: #fff;
|
||||
$colorGanttBarSelectedBg: #ccc;
|
||||
$colorGanttBarSelectedFg: #333;
|
||||
$colorGanttBarTabularFgIcon: #8594ff;
|
||||
|
||||
// Swimlane colors
|
||||
$colorDropTarg: rgba($colorGanttBarBg, 0.4);
|
||||
$colorSwimlaneSelectedBg: #222;
|
||||
$colorSwimlaneSelectedFg: #ccc;
|
||||
$colorGanttToggle: $colorKey;
|
||||
$shdwGanttBar: rgba(black, 0.4) 0 1px 3px;
|
||||
|
||||
// Resource graphs
|
||||
$timelineResourceGraphBg: rgba(black, 0.2);
|
||||
$timelineResourceGraphFg: $colorBodyFg;
|
||||
$timelineResourceGraphLegendFg: $colorBodyFg;
|
@ -1,42 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
// General
|
||||
$timelineHeaderColorBg: pullForward($colorBodyBg, 5%);
|
||||
$timelineColorAlt1: pullForward($timelineHeaderColorBg, 10%);
|
||||
$colorGanttBarBg: #5555aa;
|
||||
$colorGanttBarFg: #fff;
|
||||
$colorGanttBarSelectedBg: $colorGanttBarBg;
|
||||
$colorGanttBarSelectedFg: $colorGanttBarFg;
|
||||
$colorGanttBarTabularFgIcon: #8594ff;
|
||||
|
||||
// Swimlane colors
|
||||
$colorDropTarg: rgba($colorGanttBarBg, 0.4);
|
||||
$colorSwimlaneSelectedBg: rgba($colorGanttBarBg, 0.25);
|
||||
$colorSwimlaneSelectedFg: pullForward($colorBodyFg, 10%);
|
||||
$colorGanttToggle: $colorKey;
|
||||
$shdwGanttBar: rgba(black, 0.1) 0 1px 3px;
|
||||
|
||||
// Resource graphs
|
||||
$timelineResourceGraphBg: $colorPlotBg;
|
||||
$timelineResourceGraphFg: $colorBodyFg;
|
||||
$timelineResourceGraphLegendFg: $colorBodyFg;
|
@ -1,63 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
@mixin activityBg($bg, $gamma: 10) {
|
||||
@include background-image(linear-gradient(lighten($bg, $gamma), $bg));
|
||||
}
|
||||
|
||||
// Timeline constants
|
||||
$activityBarH: 17px;
|
||||
$timelinePaneLeftW: 30%;
|
||||
$timelinePaneBtmH: 30%;
|
||||
$timelineResourceGraphYLabelsMargin: 70px;
|
||||
$timelineTopPaneHeaderH: 30px;
|
||||
|
||||
$timelineSwimlaneGanttVM: 2px; // The vertical space above and below the gantt bars
|
||||
$timelineSwimlaneH: $activityBarH + ($timelineSwimlaneGanttVM * 2);
|
||||
$timelineTopPaneHeaderElemMargin: $interiorMargin;
|
||||
|
||||
// Timeline Tabular constants
|
||||
$timelineColIconW: 16px;
|
||||
$timelineColResourcePlotW: $timelineColIconW;
|
||||
$timelineColTitleW: 250px;
|
||||
$timelineColDatetimeW: 110px;
|
||||
$timelineColDurationW: 70px;
|
||||
$timelineColActivityModesW: $timelineColTitleW;
|
||||
$timelineColPadR: 50px;
|
||||
$timelineTabularTitleW: $timelineColResourcePlotW + $timelineColTitleW;
|
||||
$timelineTabularDataW: ($timelineColDatetimeW * 2) + $timelineColDurationW + $timelineColActivityModesW + $timelineColPadR;
|
||||
|
||||
|
||||
// // Ported from legacy timelines SASS
|
||||
$activitiesHolderM: 30px;
|
||||
$scenarioTopPad: 25px;
|
||||
$swimlaneVM: 2px;
|
||||
$timelineVM: 10px;
|
||||
$timelineBPad: $interiorMargin * 2;
|
||||
$graphResourceSummaryH: 200px;
|
||||
$graphResourceSummaryLegendH: 20px;
|
||||
$scenarioTimelineSummaryH: 20px;
|
||||
$scenarioTimelineSummaryHExpanded: $graphResourceSummaryH + 30px;
|
||||
$scenarioPanZoomSliderH: 16px;
|
||||
$scenarioTicksH: 7px;
|
||||
$scenarioTickLabelsH: 10px;
|
||||
|
||||
|
@ -1,185 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
.l-timeline-holder {
|
||||
.l-timeline-pane {
|
||||
&.t-pane-h {
|
||||
&.l-timeline-resource-legend {
|
||||
.l-legend-items {
|
||||
color: $timelineResourceGraphLegendFg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Follow Line
|
||||
.l-follow-line {
|
||||
// TODO: move before and after into l-timeline-gantt so those only render in that pane
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
top: 0; bottom: 0;
|
||||
width: 1px;
|
||||
z-index: 9; // Just below .l-hover-btns-holder
|
||||
}
|
||||
}
|
||||
|
||||
.l-timeline-gantt {
|
||||
.l-follow-line {
|
||||
$d: 0.8rem;
|
||||
top: $interiorMargin;
|
||||
&:before,
|
||||
&:after {
|
||||
content: '';
|
||||
display: block;
|
||||
height: $d;
|
||||
width: $d;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
&:before {
|
||||
// Icon blocker
|
||||
width: 2 * $d;
|
||||
}
|
||||
&:after {
|
||||
// Icon
|
||||
font-size: $d;
|
||||
line-height: $d;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.s-timeline-gantt {
|
||||
.bar {
|
||||
color: $colorGanttBarFg;
|
||||
@include activityBg($colorGanttBarBg);
|
||||
box-shadow: $shdwGanttBar;
|
||||
.s-toggle {
|
||||
color: $colorGanttToggle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.s-timeline-tabular {
|
||||
.l-header .l-cols {
|
||||
.l-col {
|
||||
border-left: 1px solid pullForward($timelineHeaderColorBg, 15%);
|
||||
}
|
||||
}
|
||||
|
||||
.l-pane-l {
|
||||
// Left pane of the tabular area
|
||||
.l-cols {
|
||||
.t-object-label .t-item-icon {
|
||||
color: pullForward($colorGanttBarBg, 10%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.edit-mode .s-timeline-gantt,
|
||||
.s-status-editing .s-timeline-gantt {
|
||||
.bar {
|
||||
&:hover {
|
||||
@include background-image(linear-gradient(lighten($colorGanttBarBg, 20), lighten($colorGanttBarBg, 10)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************** STYLING
|
||||
.s-timeline {
|
||||
font-size: 0.75rem;
|
||||
.s-header {
|
||||
background-color: $timelineHeaderColorBg;
|
||||
}
|
||||
.s-swimlane {
|
||||
border-bottom: 1px solid pullForward($colorBodyBg, 10%);
|
||||
line-height: $activityBarH + 2 + 1;
|
||||
&.exceeded {
|
||||
@include bgDiagonalStripes(#fff, 0.05, $timelineSwimlaneH + 1);
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background-color: $colorSwimlaneSelectedBg;
|
||||
color: $colorSwimlaneSelectedFg;
|
||||
|
||||
.s-timeline-gantt .bar {
|
||||
@include activityBg($colorGanttBarSelectedBg, 10);
|
||||
color: $colorGanttBarSelectedFg;
|
||||
}
|
||||
}
|
||||
|
||||
&.drop-into {
|
||||
background-color: rgba($colorDropTarg, 0.7);
|
||||
.s-timeline-gantt {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
&.drop-after {
|
||||
background-color: rgba(#000, 0.2);
|
||||
border-bottom-color: rgba($colorDropTarg, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
.s-ticks {
|
||||
@include bgTicks( $timelineColorAlt1);
|
||||
}
|
||||
.s-hover-btns-holder {
|
||||
$bg: $timelineHeaderColorBg;
|
||||
$l: 5%;
|
||||
@include user-select(none);
|
||||
@include background-image(linear-gradient(-90deg, rgba($bg, 1), rgba($bg, 1) 75%, rgba($bg, 0) 100%));
|
||||
}
|
||||
|
||||
.l-timeline-resource-graph {
|
||||
.l-graph {
|
||||
background: $timelineResourceGraphBg;
|
||||
}
|
||||
.l-title {
|
||||
color: $timelineResourceGraphFg;
|
||||
}
|
||||
}
|
||||
|
||||
.s-follow-line {
|
||||
background: rgba($timeControllerToiLineColor, 0.5);
|
||||
}
|
||||
|
||||
.s-timeline-gantt {
|
||||
.s-follow-line {
|
||||
&:after {
|
||||
// Icon
|
||||
color: $timeControllerToiLineColor;
|
||||
content: $glyph-icon-timer;
|
||||
font-family: symbolsfont;
|
||||
text-shadow: $shdwItemText;
|
||||
}
|
||||
&:before {
|
||||
// Blocker
|
||||
$bg: $timelineHeaderColorBg;
|
||||
$l: 30%;
|
||||
@include background-image(linear-gradient(90deg, rgba($bg, 0), rgba($bg, 1) $l, rgba($bg, 1) 100% - $l, rgba($bg, 0)));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,333 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
//*************************************************************** LAYOUT
|
||||
.l-timeline-holder {
|
||||
@include absPosDefault();
|
||||
|
||||
&.split-layout {
|
||||
>.splitter {
|
||||
// Top of splitter within Timelines should be 0
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.l-header {
|
||||
@include user-select(none);
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.l-timeline-pane {
|
||||
@include absPosDefault();
|
||||
|
||||
&.drop-over {
|
||||
background-color: lighten($colorEditAreaBg, 5%);
|
||||
}
|
||||
|
||||
.l-width-control {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.l-swimlanes-holder {
|
||||
@include absPosDefault();
|
||||
top: $timelineTopPaneHeaderH + 1;
|
||||
.l-col.l-plot-resource {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
// Overall layout
|
||||
&.t-pane-h {
|
||||
&.s-timeline-tabular .t-pane-v {
|
||||
// Vertical panes within tabular area
|
||||
@include absPosDefault();
|
||||
&.l-tabular-l {
|
||||
// Tree area with item title
|
||||
right: auto; // Set this to auto and uncomment width below when additional tabular columns are added
|
||||
width: $timelineTabularTitleW;
|
||||
.l-swimlanes-holder {
|
||||
bottom: $scrollbarTrackSize;
|
||||
}
|
||||
}
|
||||
&.l-tabular-r {
|
||||
// Start, end, duration, activity modes columns
|
||||
@include scrollH(scroll);
|
||||
left: $timelineTabularTitleW;
|
||||
.l-width {
|
||||
@include absPosDefault(0, visible);
|
||||
min-width: $timelineTabularDataW;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.l-timeline-gantt {
|
||||
.abs.l-timeline-gantt-header-w {
|
||||
overflow: hidden;
|
||||
height: $timelineTopPaneHeaderH;
|
||||
}
|
||||
.l-swimlanes-holder {
|
||||
@include scrollV(scroll);
|
||||
bottom: $scrollbarTrackSize;
|
||||
}
|
||||
}
|
||||
&.l-timeline-resource-legend {
|
||||
box-sizing: border-box;
|
||||
padding: $interiorMargin 0;
|
||||
white-space: nowrap;
|
||||
|
||||
.l-legend-items {
|
||||
@include absPosDefault();
|
||||
@include scrollV();
|
||||
top: 25px;
|
||||
}
|
||||
.legend-item {
|
||||
// Inherits from /platform/commonUI/general/res/sass/plots/_plots-main.scss
|
||||
display: block;
|
||||
margin-bottom: $interiorMarginSm;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
.color-swatch {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
.title-label {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.l-timeline-resource-graph {
|
||||
$m: $interiorMargin;
|
||||
|
||||
.l-graphs-holder {
|
||||
@include absPosDefault();
|
||||
bottom: $scrollbarTrackSize;
|
||||
|
||||
.l-graphs {
|
||||
@include absPosDefault();
|
||||
@include scrollV(scroll);
|
||||
}
|
||||
|
||||
.l-graph-labels-holder {
|
||||
@include absPosDefault();
|
||||
overflow: hidden;
|
||||
right: auto;
|
||||
width: 400px;
|
||||
}
|
||||
}
|
||||
|
||||
.l-scroll-control {
|
||||
@include absPosDefault();
|
||||
overflow-x: scroll;
|
||||
overflow-y: hidden;
|
||||
top: auto; right: $scrollbarTrackSize;
|
||||
height: $scrollbarTrackSize;
|
||||
.l-width-control {
|
||||
height: 10px; // Need to add height to force scrollbar to appear
|
||||
}
|
||||
}
|
||||
|
||||
.l-graph,
|
||||
.l-graph-labels {
|
||||
height: 80px;
|
||||
margin-bottom: $interiorMarginSm;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.l-title {
|
||||
@include ellipsize();
|
||||
top: $m; left: $m;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.l-graph {
|
||||
width: 100%;
|
||||
.l-graph-area {
|
||||
canvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.l-graph-labels {
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.l-graph-area {
|
||||
@include absPosDefault();
|
||||
top: 20px; bottom: 5px;
|
||||
.l-labels-holder {
|
||||
@include absPosDefault();
|
||||
justify-content: space-between;
|
||||
left: $m;
|
||||
.t-resource-graph-tick-label {
|
||||
font-size: 0.9em;
|
||||
&.tick-label-y {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.l-pane-l {
|
||||
right: auto;
|
||||
min-width: 50px;
|
||||
max-width: 90%;
|
||||
width: $timelinePaneLeftW;
|
||||
}
|
||||
|
||||
&.l-pane-r {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
&.l-pane-top {
|
||||
bottom: $timelinePaneBtmH;
|
||||
}
|
||||
&.l-pane-btm {
|
||||
top: auto;
|
||||
min-height: 20px;
|
||||
max-height: 80%;
|
||||
height: $timelinePaneBtmH;
|
||||
}
|
||||
}
|
||||
|
||||
.l-swimlane {
|
||||
height: $timelineSwimlaneH;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
// Header
|
||||
.s-timeline-tabular .l-header,
|
||||
.s-timeline-gantt .l-header {
|
||||
@include absPosDefault(0, visible);
|
||||
bottom: auto; height: $timelineTopPaneHeaderH;
|
||||
|
||||
.l-header-elem {
|
||||
@include absPosDefault($timelineTopPaneHeaderElemMargin, visible);
|
||||
display: block;
|
||||
&.l-labels {
|
||||
.l-label {
|
||||
position: absolute;
|
||||
width: 140px;
|
||||
margin-left: -70px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.l-hover-btns-holder {
|
||||
@include absPosDefault();
|
||||
box-sizing: border-box;
|
||||
height: $timelineTopPaneHeaderH;
|
||||
left: auto;
|
||||
padding: $interiorMargin $interiorMargin $interiorMargin $interiorMargin * 10;
|
||||
text-align: right;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
// Tabular Columns
|
||||
.l-cols {
|
||||
@include absPosDefault(0, visible);
|
||||
text-wrap: none;
|
||||
white-space: nowrap;
|
||||
.l-col {
|
||||
box-sizing: border-box;
|
||||
@include ellipsize();
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
padding: 0 $interiorMargin;
|
||||
position: relative;
|
||||
text-wrap: none;
|
||||
white-space: nowrap;
|
||||
|
||||
&.l-col-icon {
|
||||
width: $timelineColIconW;
|
||||
text-align: center;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&.l-plot-resource {
|
||||
border-left: none !important;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
&.l-title {
|
||||
width: $timelineColTitleW;
|
||||
.rep-object-label {
|
||||
border-radius: $basicCr;
|
||||
display: inline-block;
|
||||
padding: 0 $interiorMargin;
|
||||
}
|
||||
}
|
||||
|
||||
&.l-start,
|
||||
&.l-end,
|
||||
&.l-duration {
|
||||
width: $timelineColDatetimeW;
|
||||
}
|
||||
|
||||
&.l-activity-modes {
|
||||
display: none; // Temp, until modes can be displayed
|
||||
width: $timelineColActivityModesW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.s-timeline-tabular {
|
||||
.l-header .l-cols {
|
||||
top: $timelineTopPaneHeaderElemMargin; bottom: $timelineTopPaneHeaderElemMargin;
|
||||
}
|
||||
|
||||
.l-pane-l {
|
||||
// Left pane of the tabular area
|
||||
.l-cols {
|
||||
left: $timelineTopPaneHeaderElemMargin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ticks
|
||||
.l-ticks,
|
||||
.l-subticks {
|
||||
@include absPosDefault();
|
||||
top: auto; bottom: $interiorMarginSm;
|
||||
}
|
||||
|
||||
.l-ticks {
|
||||
height: 10px
|
||||
}
|
||||
|
||||
.l-subticks {
|
||||
height: 5px
|
||||
}
|
||||
}
|
||||
|
||||
.s-status-editing .l-title .rep-object-label[draggable="true"] {
|
||||
@include transition(background-color, 0.25s);
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background-color: $colorItemTreeHoverBg;
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
$output-bourbon-deprecation-warnings: false;
|
||||
@import "bourbon";
|
||||
|
||||
@import "../../../../commonUI/general/res/sass/constants";
|
||||
@import "../../../../commonUI/general/res/sass/mixins";
|
||||
@import "../../../../commonUI/general/res/sass/glyphs";
|
||||
@import "../../../../commonUI/themes/snow/res/sass/constants";
|
||||
@import "../../../../commonUI/themes/snow/res/sass/mixins";
|
||||
@import "constants";
|
||||
@import "constants-snow";
|
||||
@import "timeline-thematic";
|
@ -1,32 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
$output-bourbon-deprecation-warnings: false;
|
||||
@import "bourbon";
|
||||
|
||||
@import "../../../../commonUI/general/res/sass/constants";
|
||||
@import "../../../../commonUI/general/res/sass/mixins";
|
||||
@import "../../../../commonUI/general/res/sass/glyphs";
|
||||
@import "../../../../commonUI/themes/espresso/res/sass/constants";
|
||||
@import "../../../../commonUI/themes/espresso/res/sass/mixins";
|
||||
@import "constants";
|
||||
@import "activities";
|
||||
@import "timelines";
|
@ -1,38 +0,0 @@
|
||||
<!--
|
||||
Open MCT, Copyright (c) 2009-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.
|
||||
-->
|
||||
<div class="t-timeline-gantt l-timeline-gantt s-timeline-gantt"
|
||||
ng-class="timespan ? { sm: gantt.width(timespan, parameters.scroll, parameters.toPixels) < 25 } : {}"
|
||||
title="{{model.name}}"
|
||||
ng-controller="TimelineGanttController as gantt"
|
||||
ng-style="timespan ? {
|
||||
left: gantt.left(timespan, parameters.scroll, parameters.toPixels) + 'px',
|
||||
width: gantt.width(timespan, parameters.scroll, parameters.toPixels) + 'px'
|
||||
} : {}">
|
||||
|
||||
<div class="bar">
|
||||
<span class="s-activity-type {{type.getCssClass()}}"></span>
|
||||
<span class="s-title">
|
||||
{{model.name}}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
@ -1,83 +0,0 @@
|
||||
<!--
|
||||
Open MCT, Copyright (c) 2009-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.
|
||||
-->
|
||||
<div class='form-control complex datetime'>
|
||||
|
||||
<div class='field-hints'>
|
||||
<span class='hint time sm'>Days</span>
|
||||
<span class='hint time sm'>Hours</span>
|
||||
<span class='hint time sm'>Minutes</span>
|
||||
<span class='hint time sm'>Seconds</span>
|
||||
<span class='hint' ng-if="structure.options.length > 0">Time System</span>
|
||||
</div>
|
||||
|
||||
<ng-form name="mctControl">
|
||||
<div class='fields' ng-controller="TimelineDateTimeController">
|
||||
<span class='field control time sm'>
|
||||
<input type='text'
|
||||
name='days'
|
||||
min='0'
|
||||
max='9999'
|
||||
integer
|
||||
ng-pattern="/\d+/"
|
||||
ng-model='datetime.days'/>
|
||||
</span>
|
||||
<span class='field control time sm'>
|
||||
<input type='text'
|
||||
name='hour'
|
||||
maxlength='2'
|
||||
min='0'
|
||||
max='23'
|
||||
integer
|
||||
ng-pattern='/\d+/'
|
||||
ng-model="datetime.hours"/>
|
||||
</span>
|
||||
<span class='field control time sm'>
|
||||
<input type='text'
|
||||
name='min'
|
||||
maxlength='2'
|
||||
min='0'
|
||||
max='59'
|
||||
integer
|
||||
ng-pattern='/\d+/'
|
||||
ng-model="datetime.minutes"
|
||||
ng-required='true'/>
|
||||
</span>
|
||||
<span class='field control time sm'>
|
||||
<input type='text'
|
||||
name='sec'
|
||||
maxlength='2'
|
||||
min='0'
|
||||
max='59'
|
||||
integer
|
||||
ng-pattern='/\d+/'
|
||||
ng-model="datetime.seconds"
|
||||
ng-required='true'/>
|
||||
</span>
|
||||
<span ng-if="structure.options.length > 0"
|
||||
class='field control'>
|
||||
SET
|
||||
</span>
|
||||
</div>
|
||||
</ng-form>
|
||||
|
||||
|
||||
</div>
|
@ -0,0 +1,10 @@
|
||||
<div>
|
||||
Timeline, Activity and Activity Mode objects have been deprecated and will no longer be supported.
|
||||
</div>
|
||||
<div>
|
||||
Please open an issue in the
|
||||
<a href="https://github.com/nasa/openmct/issues" target="_blank">
|
||||
Open MCT Issue tracker
|
||||
</a>
|
||||
if you have any questions about the timeline plugin.
|
||||
</div>
|
@ -1,34 +0,0 @@
|
||||
<!--
|
||||
Open MCT, Copyright (c) 2009-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.
|
||||
-->
|
||||
<!-- TO-DO: make legend item color-swatch dynamic -->
|
||||
<span
|
||||
class="legend-item s-legend-item"
|
||||
title="{{ngModel.path}}{{ngModel.domainObject.getModel().name}}"
|
||||
>
|
||||
<span class="color-swatch"
|
||||
ng-style="{ 'background-color': ngModel.color() }">
|
||||
</span>
|
||||
<span class="title-label">
|
||||
<span class="l-parent-path">{{ngModel.path}}</span>
|
||||
<span class="l-leaf-title">{{ngModel.domainObject.getModel().name}}</span>
|
||||
</span>
|
||||
</span>
|
@ -1,34 +0,0 @@
|
||||
<!--
|
||||
Open MCT, Copyright (c) 2009-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.
|
||||
-->
|
||||
<span ng-controller="TimelineGraphController as graphController">
|
||||
<div class="t-graph l-graph" ng-repeat="graph in parameters.graphs">
|
||||
<div class="l-graph-area l-canvas-holder">
|
||||
<mct-timeline-chart draw="graph.drawingObject"></mct-timeline-chart>
|
||||
</div>
|
||||
<div class="t-graph-labels l-graph-labels">
|
||||
<mct-include key="'timeline-resource-graph-labels'"
|
||||
parameters="graphController.label(graph)"
|
||||
ng-model="graph">
|
||||
</mct-include>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
@ -1,37 +0,0 @@
|
||||
<!--
|
||||
Open MCT, Copyright (c) 2009-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.
|
||||
-->
|
||||
<div class="t-swimlane s-swimlane l-swimlane {{ngModel.activitystate}} {{ngModel.swimlanestate}}"
|
||||
ng-class="{
|
||||
exceeded: ngModel.exceeded(),
|
||||
selected: ngModel.selected(swimlane),
|
||||
'drop-into': ngModel.highlight(),
|
||||
'drop-after': ngModel.highlightBottom()
|
||||
}">
|
||||
<div
|
||||
class="l-cols"
|
||||
ng-controller="TimelineTableController as tabularVal">
|
||||
<span class="align-right l-col l-start">{{tabularVal.niceTime(ngModel.timespan().getStart())}}</span>
|
||||
<span class="align-right l-col l-end">{{tabularVal.niceTime(ngModel.timespan().getEnd())}}</span>
|
||||
<span class="align-right l-col l-duration">{{tabularVal.niceTime(ngModel.timespan().getDuration())}}</span>
|
||||
<span class="l-col l-activity-modes"></span>
|
||||
</div>
|
||||
</div>
|
@ -1,57 +0,0 @@
|
||||
<!--
|
||||
Open MCT, Copyright (c) 2009-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.
|
||||
-->
|
||||
<div class="t-swimlane s-swimlane l-swimlane {{ngModel.activitystate}} {{ngModel.swimlanestate}}"
|
||||
mct-swimlane-drop="ngModel"
|
||||
ng-class="{
|
||||
exceeded: ngModel.exceeded(),
|
||||
selected: ngModel.selected(swimlane),
|
||||
'drop-into': ngModel.highlight(),
|
||||
'drop-after': ngModel.highlightBottom()
|
||||
}">
|
||||
<div class="l-cols">
|
||||
<span class="l-col l-col-icon l-plot-resource"
|
||||
ng-click="ngModel.toggleGraph(); parameters.commit()"
|
||||
title="Click to enable or disable inclusion in Resource Graphing">
|
||||
<span class="icon-plot-resource s-toggle-icon"
|
||||
ng-class="{ active: ngModel.graph() }">
|
||||
</span>
|
||||
</span>
|
||||
<span class="l-col l-col-icon l-link">
|
||||
<a class="icon-chain-links"
|
||||
target="_blank"
|
||||
ng-href="{{ngModel.link()}}"
|
||||
ng-if="ngModel.link().length > 0"
|
||||
title="{{ngModel.link()}}"
|
||||
>
|
||||
</a>
|
||||
</span>
|
||||
<span class="l-col l-title"
|
||||
ng-click="ngModel.select()"
|
||||
ng-style="{ 'margin-left': 15 * ngModel.depth + 'px' }">
|
||||
<mct-representation key="'label'"
|
||||
mct-object="ngModel.domainObject"
|
||||
class="rep-object-label"
|
||||
mct-swimlane-drag="ngModel">
|
||||
</mct-representation>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
@ -1,39 +0,0 @@
|
||||
<!--
|
||||
Open MCT, Copyright (c) 2009-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.
|
||||
-->
|
||||
<div class="t-header l-header s-header"
|
||||
ng-controller="TimelineTickController as tick"
|
||||
ng-style="{ width: parameters.fullWidth + 'px' }">
|
||||
|
||||
<div class="l-header-elem t-labels l-labels">
|
||||
<div class="t-label l-label s-label"
|
||||
ng-repeat="label in tick.labels(parameters.start, parameters.width, parameters.step, parameters.toMillis)"
|
||||
ng-style="{ left: label.left + 'px' }">
|
||||
{{label.text}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="t-ticks l-ticks s-ticks"
|
||||
ng-style="{ 'background-size': parameters.step + 'px 100%' }">
|
||||
</div>
|
||||
<div class="t-ticks s-ticks l-subticks"
|
||||
ng-style="{ 'background-size': (parameters.step / 40) + 'px 100%' }">
|
||||
</div>
|
||||
</div>
|
@ -1,223 +0,0 @@
|
||||
<!--
|
||||
Open MCT, Copyright (c) 2009-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.
|
||||
-->
|
||||
<div class="s-timeline l-timeline-holder split-layout vertical splitter-sm"
|
||||
ng-click="$event.stopPropagation()"
|
||||
ng-controller="TimelineController as timelineController">
|
||||
|
||||
<mct-split-pane anchor="left" class="abs" position="pane.x">
|
||||
<!-- LEFT PANE: TABULAR AND RESOURCE LEGEND AREAS -->
|
||||
<mct-split-pane anchor="bottom"
|
||||
position="pane.y"
|
||||
class="abs horizontal split-pane-component l-timeline-pane l-pane-l t-pane-v">
|
||||
<!-- TOP PANE TABULAR AREA -->
|
||||
<div class="split-pane-component s-timeline-tabular l-timeline-pane t-pane-h l-pane-top">
|
||||
<!-- TABULAR LEFT FIXED AREA -->
|
||||
<div class="t-pane-v l-pane-l l-tabular-l"
|
||||
ng-if="true">
|
||||
|
||||
<div class="t-header l-header s-header">
|
||||
<div class="l-cols">
|
||||
<span title="Resource Graphing: click a row to toggle" class="l-col l-col-icon l-plot-resource icon-plot-resource"></span>
|
||||
<span title="Activity Links" class="l-col l-col-icon l-col-link icon-chain-links"></span>
|
||||
<span class="l-col l-title">Title</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="t-swimlanes-holder l-swimlanes-holder"
|
||||
mct-scroll-y="scroll.y">
|
||||
<mct-include key="'timeline-tabular-swimlane-cols-tree'"
|
||||
parameters="{ commit: commit }"
|
||||
ng-repeat="swimlane in timelineController.swimlanes()"
|
||||
ng-model="swimlane">
|
||||
</mct-include>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- TABULAR RIGHT HORZ SCROLLING AREA -->
|
||||
<div class="t-pane-v l-pane-r l-tabular-r">
|
||||
<div class="l-width">
|
||||
<div class="t-header l-header s-header">
|
||||
<div class="l-cols">
|
||||
<span class="l-col l-start">Start</span>
|
||||
<span class="l-col l-end">End</span>
|
||||
<span class="l-col l-duration">Duration</span>
|
||||
<span class="l-col l-activity-modes">Activity Modes</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="t-swimlanes-holder l-swimlanes-holder"
|
||||
mct-scroll-y="scroll.y">
|
||||
<mct-include key="'timeline-tabular-swimlane-cols-data'"
|
||||
ng-repeat="swimlane in timelineController.swimlanes()"
|
||||
ng-model="swimlane">
|
||||
</mct-include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- HORZ SPLITTER -->
|
||||
<mct-splitter></mct-splitter>
|
||||
|
||||
<!-- BOTTOM PANE RESOURCE LEGEND -->
|
||||
<div mct-resource-graph-drop
|
||||
class="split-pane-component abs l-timeline-pane t-pane-h l-pane-btm s-timeline-resource-legend l-timeline-resource-legend">
|
||||
<div class="l-title s-title">{{ngModel.title}}Resource Graph Legend</div>
|
||||
<div class="l-legend-items legend">
|
||||
<mct-include key="'timeline-legend-item'"
|
||||
ng-repeat="swimlane in timelineController.swimlanes()"
|
||||
ng-model="swimlane"
|
||||
ng-show="swimlane.graph()">
|
||||
</mct-include>
|
||||
</div>
|
||||
</div>
|
||||
</mct-split-pane>
|
||||
|
||||
|
||||
<!-- MAIN VERTICAL SPLITTER -->
|
||||
<mct-splitter></mct-splitter>
|
||||
|
||||
|
||||
<!-- RIGHT PANE: GANTT AND RESOURCE PLOTS -->
|
||||
<span ng-controller="TimelineZoomController as zoomController" class="abs">
|
||||
|
||||
<span class="toi-control-holder temp" ng-controller="TimelineTOIController as toiController">
|
||||
<mct-split-pane anchor="bottom"
|
||||
position="pane.y"
|
||||
class="abs split-pane-component l-timeline-pane l-pane-r t-pane-v">
|
||||
|
||||
<!-- TOP PANE GANTT BARS -->
|
||||
<div class="split-pane-component l-timeline-pane t-pane-h l-pane-top t-timeline-gantt l-timeline-gantt s-timeline-gantt">
|
||||
<div class="h-local-controls l-hover-btns-holder s-hover-btns-holder">
|
||||
<a class="s-button icon-timer"
|
||||
ng-click="scroll.follow = true"
|
||||
ng-show="!toiController.isFollowing() && toiController.isActive()"
|
||||
title="Follow time bounds">
|
||||
</a>
|
||||
|
||||
<div class="l-btn-set">
|
||||
<a class="s-button icon-reset"
|
||||
ng-click="scroll.follow = false; zoomController.fit()"
|
||||
ng-show="true"
|
||||
title="Zoom to fit">
|
||||
</a>
|
||||
|
||||
<a class="s-button icon-magnify-in"
|
||||
ng-click="scroll.follow = false; zoomController.zoom(-1)"
|
||||
ng-show="true"
|
||||
title="Zoom in">
|
||||
</a>
|
||||
|
||||
<a class="s-button icon-magnify-out"
|
||||
ng-click="scroll.follow = false; zoomController.zoom(1)"
|
||||
ng-show="true"
|
||||
title="Zoom out">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="overflow: hidden; position: absolute; left: 0; top: 0; right: 0; height: 30px;" mct-scroll-x="scroll.x">
|
||||
<mct-include key="'timeline-ticks'"
|
||||
parameters="{
|
||||
fullWidth: zoomController.width(timelineController.end()),
|
||||
start: scroll.x,
|
||||
width: scroll.width,
|
||||
step: zoomController.toPixels(zoomController.zoom()),
|
||||
toMillis: zoomController.toMillis
|
||||
}">
|
||||
</mct-include>
|
||||
</div>
|
||||
<div ng-if="toiController.isActive()" class="l-follow-line s-follow-line"
|
||||
ng-style="{ left: toiController.x() - scroll.x + 'px' }"></div>
|
||||
|
||||
<div class="t-swimlanes-holder l-swimlanes-holder"
|
||||
mct-scroll-x="scroll.x"
|
||||
mct-scroll-y="scroll.y">
|
||||
<div class="l-width-control"
|
||||
ng-style="{ width: zoomController.width(timelineController.end()) + 'px' }">
|
||||
<div class="t-swimlane s-swimlane l-swimlane"
|
||||
ng-repeat="swimlane in timelineController.swimlanes()"
|
||||
ng-class="{
|
||||
exceeded: swimlane.exceeded(),
|
||||
selected: selection.selected(swimlane),
|
||||
'drop-into': swimlane.highlight(),
|
||||
'drop-after': swimlane.highlightBottom()
|
||||
}"
|
||||
ng-click="selection.select(swimlane)"
|
||||
mct-swimlane-drop="swimlane">
|
||||
|
||||
<mct-representation key="'gantt'"
|
||||
mct-object="swimlane.domainObject"
|
||||
parameters="{
|
||||
scroll: scroll,
|
||||
toPixels: zoomController.toPixels
|
||||
}">
|
||||
</mct-representation>
|
||||
|
||||
<span ng-if="selection.selected(swimlane)">
|
||||
<span ng-repeat="handle in timelineController.handles()"
|
||||
ng-style="handle.style(zoomController)"
|
||||
style="position: absolute; top: 0px; bottom: 0px;"
|
||||
class="handle"
|
||||
ng-class="{ start: $index === 0, mid: $index === 1, end: $index > 1 }"
|
||||
mct-drag-down="handle.begin()"
|
||||
mct-drag="handle.drag(delta[0], zoomController); timelineController.refresh()"
|
||||
mct-drag-up="handle.finish()">
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- HORZ SPLITTER -->
|
||||
<mct-splitter></mct-splitter>
|
||||
|
||||
<!-- BOTTOM PANE RESOURCE GRAPHS AND RIGHT PANE HORIZONTAL SCROLL CONTROL -->
|
||||
<div class="split-pane-component l-timeline-resource-graph l-timeline-pane t-pane-h l-pane-btm">
|
||||
<div class="l-graphs-holder"
|
||||
mct-resize="scroll.width = bounds.width">
|
||||
<div class="t-graphs l-graphs">
|
||||
<mct-include key="'timeline-resource-graphs'"
|
||||
parameters="{
|
||||
origin: zoomController.toMillis(scroll.x),
|
||||
duration: zoomController.toMillis(scroll.width),
|
||||
graphs: timelineController.graphs()
|
||||
}">
|
||||
</mct-include>
|
||||
</div>
|
||||
<div ng-if="toiController.isActive()" class="l-follow-line s-follow-line"
|
||||
ng-style="{ left: toiController.x() - scroll.x + 'px' }"></div>
|
||||
</div>
|
||||
<div mct-scroll-x="scroll.x"
|
||||
class="t-pane-r-scroll-h-control l-scroll-control s-scroll-control">
|
||||
<div class="l-width-control"
|
||||
ng-style="{ width: zoomController.width(timelineController.end()) + 'px' }">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mct-split-pane>
|
||||
</span>
|
||||
|
||||
|
||||
</span>
|
||||
</mct-split-pane>
|
||||
</div>
|
@ -1,27 +0,0 @@
|
||||
<!--
|
||||
Open MCT, Copyright (c) 2009-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.
|
||||
-->
|
||||
<ul ng-controller="ActivityModeValuesController as controller" class="cols cols-2-ff properties">
|
||||
<li ng-repeat="(key, value) in cost" class="l-row s-row">
|
||||
<span class="col col-100px s-title">{{controller.metadata(key).name}}</span>
|
||||
<span class="col s-value">{{value}} {{controller.metadata(key).units}}</span>
|
||||
</li>
|
||||
</ul>
|
@ -1,31 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Defines constant values for use in timeline view.
|
||||
*/
|
||||
define({
|
||||
// Pixel width of start/end handles
|
||||
HANDLE_WIDTH: 32,
|
||||
// Pixel tolerance for snapping behavior
|
||||
SNAP_WIDTH: 16
|
||||
});
|
@ -1,76 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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 () {
|
||||
|
||||
// Conversion factors from time units to milliseconds
|
||||
var SECONDS = 1000,
|
||||
MINUTES = SECONDS * 60,
|
||||
HOURS = MINUTES * 60,
|
||||
DAYS = HOURS * 24;
|
||||
|
||||
/**
|
||||
* Formatters for durations shown in a timeline view.
|
||||
* @constructor
|
||||
*/
|
||||
function TimelineFormatter() {
|
||||
|
||||
// Format a numeric value to a string with some number of digits
|
||||
function formatValue(value, digits) {
|
||||
var v = value.toString(10);
|
||||
// Pad with zeroes
|
||||
while (v.length < digits) {
|
||||
v = "0" + v;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
// Format duration to string
|
||||
function formatDuration(duration) {
|
||||
var days = Math.floor(duration / DAYS),
|
||||
hours = Math.floor(duration / HOURS) % 24,
|
||||
minutes = Math.floor(duration / MINUTES) % 60,
|
||||
seconds = Math.floor(duration / SECONDS) % 60,
|
||||
millis = Math.floor(duration) % 1000;
|
||||
|
||||
return formatValue(days, 3) + " " +
|
||||
formatValue(hours, 2) + ":" +
|
||||
formatValue(minutes, 2) + ":" +
|
||||
formatValue(seconds, 2) + "." +
|
||||
formatValue(millis, 3);
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Format the provided duration.
|
||||
* @param {number} duration duration, in milliseconds
|
||||
* @returns {string} displayable representation of duration
|
||||
*/
|
||||
format: formatDuration
|
||||
};
|
||||
}
|
||||
|
||||
return TimelineFormatter;
|
||||
}
|
||||
);
|
@ -1,54 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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 () {
|
||||
|
||||
/**
|
||||
* A column containing references to other objects contained
|
||||
* in a domain object's composition.
|
||||
* @param {number} index the zero-based index of the composition
|
||||
* element associated with this column
|
||||
* @param idMap an object containing key value pairs, where keys
|
||||
* are domain object identifiers and values are whatever
|
||||
* should appear in CSV output in their place
|
||||
* @constructor
|
||||
* @implements {platform/features/timeline.TimelineCSVColumn}
|
||||
*/
|
||||
function CompositionColumn(index, idMap) {
|
||||
this.index = index;
|
||||
this.idMap = idMap;
|
||||
}
|
||||
|
||||
CompositionColumn.prototype.name = function () {
|
||||
return "Child " + (this.index + 1);
|
||||
};
|
||||
|
||||
CompositionColumn.prototype.value = function (domainObject) {
|
||||
var model = domainObject.getModel(),
|
||||
composition = model.composition || [];
|
||||
|
||||
return composition.length > this.index ?
|
||||
this.idMap[composition[this.index]] : "";
|
||||
};
|
||||
|
||||
return CompositionColumn;
|
||||
});
|
@ -1,79 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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(["./ExportTimelineAsCSVTask"], function (ExportTimelineAsCSVTask) {
|
||||
|
||||
/**
|
||||
* Implements the "Export Timeline as CSV" action.
|
||||
*
|
||||
* @param exportService the service used to perform the CSV export
|
||||
* @param notificationService the service used to show notifications
|
||||
* @param {Array} resources an array of `resources` extensions
|
||||
* @param context the Action's context
|
||||
* @implements {Action}
|
||||
* @constructor
|
||||
* @memberof {platform/features/timeline}
|
||||
*/
|
||||
function ExportTimelineAsCSVAction(
|
||||
$log,
|
||||
exportService,
|
||||
notificationService,
|
||||
resources,
|
||||
context
|
||||
) {
|
||||
this.$log = $log;
|
||||
this.task = new ExportTimelineAsCSVTask(
|
||||
exportService,
|
||||
resources,
|
||||
context.domainObject
|
||||
);
|
||||
this.notificationService = notificationService;
|
||||
}
|
||||
|
||||
ExportTimelineAsCSVAction.prototype.perform = function () {
|
||||
var notificationService = this.notificationService,
|
||||
notification = notificationService.notify({
|
||||
title: "Exporting CSV",
|
||||
unknownProgress: true
|
||||
}),
|
||||
$log = this.$log;
|
||||
|
||||
return this.task.run()
|
||||
.then(function () {
|
||||
notification.dismiss();
|
||||
})
|
||||
.catch(function (err) {
|
||||
$log.warn(err);
|
||||
notification.dismiss();
|
||||
notificationService.error("Error exporting CSV");
|
||||
});
|
||||
};
|
||||
|
||||
ExportTimelineAsCSVAction.appliesTo = function (context) {
|
||||
return context.domainObject &&
|
||||
context.domainObject.hasCapability('type') &&
|
||||
context.domainObject.getCapability('type')
|
||||
.instanceOf('timeline');
|
||||
};
|
||||
|
||||
return ExportTimelineAsCSVAction;
|
||||
});
|
@ -1,71 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Module defining ExportTimelineAsCSVTask. Created by vwoeltje on 2/8/16.
|
||||
*/
|
||||
define([
|
||||
"./TimelineTraverser",
|
||||
"./TimelineColumnizer"
|
||||
], function (TimelineTraverser, TimelineColumnizer) {
|
||||
|
||||
/**
|
||||
* Runs (and coordinates) the preparation and export of CSV data
|
||||
* for the "Export Timeline as CSV" action.
|
||||
*
|
||||
* @constructor
|
||||
* @memberof {platform/features/timeline}
|
||||
* @param exportService the service used to export as CSV
|
||||
* @param resources the `resources` extension category
|
||||
* @param {DomainObject} domainObject the timeline being exported
|
||||
*/
|
||||
function ExportTimelineAsCSVTask(exportService, resources, domainObject) {
|
||||
this.domainObject = domainObject;
|
||||
this.exportService = exportService;
|
||||
this.resources = resources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run this CSV export task.
|
||||
*
|
||||
* @returns {Promise} a promise that will be resolved when the
|
||||
* export has finished (or rejected if there are problems.)
|
||||
*/
|
||||
ExportTimelineAsCSVTask.prototype.run = function () {
|
||||
var exportService = this.exportService;
|
||||
var resources = this.resources;
|
||||
|
||||
function doExport(objects) {
|
||||
var exporter = new TimelineColumnizer(objects, resources),
|
||||
options = { headers: exporter.headers() };
|
||||
return exporter.rows().then(function (rows) {
|
||||
return exportService.exportCSV(rows, options);
|
||||
});
|
||||
}
|
||||
|
||||
return new TimelineTraverser(this.domainObject)
|
||||
.buildObjectList()
|
||||
.then(doExport);
|
||||
};
|
||||
|
||||
return ExportTimelineAsCSVTask;
|
||||
});
|
@ -1,46 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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 () {
|
||||
|
||||
/**
|
||||
* A column showing identifying domain objects.
|
||||
* @constructor
|
||||
* @param idMap an object containing key value pairs, where keys
|
||||
* are domain object identifiers and values are whatever
|
||||
* should appear in CSV output in their place
|
||||
* @implements {platform/features/timeline.TimelineCSVColumn}
|
||||
*/
|
||||
function IdColumn(idMap) {
|
||||
this.idMap = idMap;
|
||||
}
|
||||
|
||||
IdColumn.prototype.name = function () {
|
||||
return "Index";
|
||||
};
|
||||
|
||||
IdColumn.prototype.value = function (domainObject) {
|
||||
return this.idMap[domainObject.getId()];
|
||||
};
|
||||
|
||||
return IdColumn;
|
||||
});
|
@ -1,48 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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 () {
|
||||
|
||||
/**
|
||||
* A column reflecting properties from domain object metadata.
|
||||
* @constructor
|
||||
* @implements {platform/features/timeline.TimelineCSVColumn}
|
||||
*/
|
||||
function MetadataColumn(propertyName) {
|
||||
this.propertyName = propertyName;
|
||||
}
|
||||
|
||||
MetadataColumn.prototype.name = function () {
|
||||
return this.propertyName;
|
||||
};
|
||||
|
||||
MetadataColumn.prototype.value = function (domainObject) {
|
||||
var properties = domainObject.useCapability('metadata'),
|
||||
name = this.propertyName;
|
||||
return properties.reduce(function (value, property) {
|
||||
return property.name === name ?
|
||||
property.value : value;
|
||||
}, "");
|
||||
};
|
||||
|
||||
return MetadataColumn;
|
||||
});
|
@ -1,52 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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 () {
|
||||
|
||||
/**
|
||||
* A column showing relationships to activity modes.
|
||||
* @constructor
|
||||
* @param {number} index the zero-based index of the composition
|
||||
* element associated with this column
|
||||
* @param idMap an object containing key value pairs, where keys
|
||||
* are domain object identifiers and values are whatever
|
||||
* should appear in CSV output in their place
|
||||
* @implements {platform/features/timeline.TimelineCSVColumn}
|
||||
*/
|
||||
function ModeColumn(index, idMap) {
|
||||
this.index = index;
|
||||
this.idMap = idMap;
|
||||
}
|
||||
|
||||
ModeColumn.prototype.name = function () {
|
||||
return "Activity Mode " + (this.index + 1);
|
||||
};
|
||||
|
||||
ModeColumn.prototype.value = function (domainObject) {
|
||||
var model = domainObject.getModel(),
|
||||
modes = (model.relationships || {}).modes || [];
|
||||
return modes.length > this.index ?
|
||||
this.idMap[modes[this.index]] : "";
|
||||
};
|
||||
|
||||
return ModeColumn;
|
||||
});
|
@ -1,172 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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([
|
||||
"./IdColumn",
|
||||
"./ModeColumn",
|
||||
"./CompositionColumn",
|
||||
"./MetadataColumn",
|
||||
"./TimespanColumn",
|
||||
"./UtilizationColumn"
|
||||
], function (
|
||||
IdColumn,
|
||||
ModeColumn,
|
||||
CompositionColumn,
|
||||
MetadataColumn,
|
||||
TimespanColumn,
|
||||
UtilizationColumn
|
||||
) {
|
||||
|
||||
/**
|
||||
* A description of how to populate a given column within a
|
||||
* prepared table of domain object data, for CSV export.
|
||||
* @interface platform/features/timeline.TimelineCSVColumn
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the value that belongs in this column for a given
|
||||
* domain object.
|
||||
* @memberof {platform/features/timeline.TimelineCSVColumn#}
|
||||
* @method value
|
||||
* @param {DomainObject} domainObject the domain object
|
||||
* represented by this row
|
||||
* @returns {string|Promise<string>} the value for this cell
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the name of this column, as belongs in a header.
|
||||
* @memberof {platform/features/timeline.TimelineCSVColumn#}
|
||||
* @method name
|
||||
* @returns {string} the name of this column
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles conversion of a list of domain objects to a table
|
||||
* representation appropriate for CSV export.
|
||||
*
|
||||
* @param {DomainObject[]} domainObjects the objects to include
|
||||
* in the exported data
|
||||
* @param {Array} resources an array of `resources` extensions
|
||||
* @constructor
|
||||
* @memberof {platform/features/timeline}
|
||||
*/
|
||||
function TimelineColumnizer(domainObjects, resources) {
|
||||
var maxComposition = 0,
|
||||
maxRelationships = 0,
|
||||
columnNames = {},
|
||||
columns = [],
|
||||
foundTimespan = false,
|
||||
idMap,
|
||||
i;
|
||||
|
||||
function addMetadataProperty(property) {
|
||||
var name = property.name;
|
||||
if (!columnNames[name]) {
|
||||
columnNames[name] = true;
|
||||
columns.push(new MetadataColumn(name));
|
||||
}
|
||||
}
|
||||
|
||||
idMap = domainObjects.reduce(function (map, domainObject, index) {
|
||||
map[domainObject.getId()] = index + 1;
|
||||
return map;
|
||||
}, {});
|
||||
|
||||
columns.push(new IdColumn(idMap));
|
||||
|
||||
domainObjects.forEach(function (domainObject) {
|
||||
var model = domainObject.getModel(),
|
||||
composition = model.composition,
|
||||
relationships = model.relationships,
|
||||
modes = relationships && relationships.modes,
|
||||
metadataProperties = domainObject.useCapability('metadata');
|
||||
|
||||
if (composition) {
|
||||
maxComposition = Math.max(maxComposition, composition.length);
|
||||
}
|
||||
|
||||
if (modes) {
|
||||
maxRelationships = Math.max(maxRelationships, modes.length);
|
||||
}
|
||||
|
||||
if (domainObject.hasCapability('timespan')) {
|
||||
foundTimespan = true;
|
||||
}
|
||||
|
||||
if (metadataProperties) {
|
||||
metadataProperties.forEach(addMetadataProperty);
|
||||
}
|
||||
});
|
||||
|
||||
if (foundTimespan) {
|
||||
columns.push(new TimespanColumn(true));
|
||||
columns.push(new TimespanColumn(false));
|
||||
}
|
||||
|
||||
resources.forEach(function (resource) {
|
||||
columns.push(new UtilizationColumn(resource));
|
||||
});
|
||||
|
||||
for (i = 0; i < maxComposition; i += 1) {
|
||||
columns.push(new CompositionColumn(i, idMap));
|
||||
}
|
||||
|
||||
for (i = 0; i < maxRelationships; i += 1) {
|
||||
columns.push(new ModeColumn(i, idMap));
|
||||
}
|
||||
|
||||
this.domainObjects = domainObjects;
|
||||
this.columns = columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a tabular representation of domain object data.
|
||||
* Each row corresponds to a single object; each element
|
||||
* in each row corresponds to a property designated by
|
||||
* the `headers`, correlated by index.
|
||||
* @returns {Promise.<string[][]>} domain object data
|
||||
*/
|
||||
TimelineColumnizer.prototype.rows = function () {
|
||||
var columns = this.columns;
|
||||
|
||||
function toRow(domainObject) {
|
||||
return Promise.all(columns.map(function (column) {
|
||||
return column.value(domainObject);
|
||||
}));
|
||||
}
|
||||
|
||||
return Promise.all(this.domainObjects.map(toRow));
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the column headers associated with this tabular
|
||||
* representation of objects.
|
||||
* @returns {string[]} column headers
|
||||
*/
|
||||
TimelineColumnizer.prototype.headers = function () {
|
||||
return this.columns.map(function (column) {
|
||||
return column.name();
|
||||
});
|
||||
};
|
||||
|
||||
return TimelineColumnizer;
|
||||
});
|
@ -1,83 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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 () {
|
||||
|
||||
/**
|
||||
* Builds a list of domain objects which should be included
|
||||
* in the CSV export of a given timeline.
|
||||
* @param {DomainObject} domainObject the object being exported
|
||||
* @constructor
|
||||
*/
|
||||
function TimelineTraverser(domainObject) {
|
||||
this.domainObject = domainObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of domain objects for CSV export.
|
||||
* @returns {Promise.<DomainObject[]>} a list of domain objects
|
||||
*/
|
||||
TimelineTraverser.prototype.buildObjectList = function () {
|
||||
var idSet = {},
|
||||
objects = [];
|
||||
|
||||
function addObject(domainObject) {
|
||||
var id = domainObject.getId(),
|
||||
subtasks = [];
|
||||
|
||||
function addCompositionObjects() {
|
||||
return domainObject.useCapability('composition')
|
||||
.then(function (childObjects) {
|
||||
return Promise.all(childObjects.map(addObject));
|
||||
});
|
||||
}
|
||||
|
||||
function addRelationships() {
|
||||
var relationship = domainObject.getCapability('relationship');
|
||||
relationship.getRelatedObjects('modes')
|
||||
.then(function (modeObjects) {
|
||||
return Promise.all(modeObjects.map(addObject));
|
||||
});
|
||||
}
|
||||
|
||||
if (!idSet[id]) {
|
||||
idSet[id] = true;
|
||||
objects.push(domainObject);
|
||||
if (domainObject.hasCapability('composition')) {
|
||||
subtasks.push(addCompositionObjects());
|
||||
}
|
||||
if (domainObject.hasCapability('relationship')) {
|
||||
subtasks.push(addRelationships());
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.all(subtasks);
|
||||
}
|
||||
|
||||
return addObject(this.domainObject).then(function () {
|
||||
return objects;
|
||||
});
|
||||
};
|
||||
|
||||
return TimelineTraverser;
|
||||
|
||||
});
|
@ -1,53 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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(['../TimelineFormatter'], function (TimelineFormatter) {
|
||||
|
||||
var FORMATTER = new TimelineFormatter();
|
||||
|
||||
/**
|
||||
* A column showing start or end times associated with a domain object.
|
||||
* @constructor
|
||||
* @param {boolean} isStart true if this column refers to the object's
|
||||
* start time; false if it refers to the object's end time
|
||||
* @implements {platform/features/timeline.TimelineCSVColumn}
|
||||
*/
|
||||
function TimespanColumn(isStart) {
|
||||
this.isStart = isStart;
|
||||
}
|
||||
|
||||
TimespanColumn.prototype.name = function () {
|
||||
return this.isStart ? "Start" : "End";
|
||||
};
|
||||
|
||||
TimespanColumn.prototype.value = function (domainObject) {
|
||||
var isStart = this.isStart;
|
||||
return domainObject.hasCapability('timespan') ?
|
||||
domainObject.useCapability('timespan').then(function (timespan) {
|
||||
return FORMATTER.format(
|
||||
isStart ? timespan.getStart() : timespan.getEnd()
|
||||
);
|
||||
}) : "";
|
||||
};
|
||||
|
||||
return TimespanColumn;
|
||||
});
|
@ -1,72 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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 () {
|
||||
/**
|
||||
* A column showing utilization costs associated with activities.
|
||||
* @constructor
|
||||
* @param {string} key the key for the particular cost
|
||||
* @implements {platform/features/timeline.TimelineCSVColumn}
|
||||
*/
|
||||
function UtilizationColumn(resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
UtilizationColumn.prototype.name = function () {
|
||||
var units = {
|
||||
"Kbps": "Kb",
|
||||
"watts": "watt-seconds"
|
||||
}[this.resource.units] || "unknown units";
|
||||
|
||||
return this.resource.name + " (" + units + ")";
|
||||
};
|
||||
|
||||
UtilizationColumn.prototype.value = function (domainObject) {
|
||||
var resource = this.resource;
|
||||
|
||||
function getCost(utilization) {
|
||||
var seconds = (utilization.end - utilization.start) / 1000;
|
||||
return seconds * utilization.value;
|
||||
}
|
||||
|
||||
function getUtilizationValue(utilizations) {
|
||||
utilizations = utilizations.filter(function (utilization) {
|
||||
return utilization.key === resource.key;
|
||||
});
|
||||
|
||||
if (utilizations.length === 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return utilizations.map(getCost).reduce(function (a, b) {
|
||||
return a + b;
|
||||
}, 0);
|
||||
}
|
||||
|
||||
return domainObject.hasCapability('utilization') ?
|
||||
domainObject.getCapability('utilization').internal()
|
||||
.then(getUtilizationValue) :
|
||||
"";
|
||||
};
|
||||
|
||||
return UtilizationColumn;
|
||||
});
|
@ -1,119 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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 () {
|
||||
|
||||
/**
|
||||
* Describes the time span of an activity object.
|
||||
* @param model the activity's object model
|
||||
*/
|
||||
function ActivityTimespan(model, mutation) {
|
||||
// Get the start time for this timeline
|
||||
function getStart() {
|
||||
return model.start.timestamp;
|
||||
}
|
||||
|
||||
// Get the end time for this timeline
|
||||
function getEnd() {
|
||||
return model.start.timestamp + model.duration.timestamp;
|
||||
}
|
||||
|
||||
// Get the duration of this timeline
|
||||
function getDuration() {
|
||||
return model.duration.timestamp;
|
||||
}
|
||||
|
||||
// Get the epoch used by this timeline
|
||||
function getEpoch() {
|
||||
return model.start.epoch; // Surface elapsed time
|
||||
}
|
||||
|
||||
// Set the start time associated with this object
|
||||
function setStart(value) {
|
||||
var end = getEnd();
|
||||
mutation.mutate(function (m) {
|
||||
m.start.timestamp = Math.max(value, 0);
|
||||
// Update duration to keep end time
|
||||
m.duration.timestamp = Math.max(end - value, 0);
|
||||
}, model.modified);
|
||||
}
|
||||
|
||||
// Set the duration associated with this object
|
||||
function setDuration(value) {
|
||||
mutation.mutate(function (m) {
|
||||
m.duration.timestamp = Math.max(value, 0);
|
||||
}, model.modified);
|
||||
}
|
||||
|
||||
// Set the end time associated with this object
|
||||
function setEnd(value) {
|
||||
var start = getStart();
|
||||
mutation.mutate(function (m) {
|
||||
m.duration.timestamp = Math.max(value - start, 0);
|
||||
}, model.modified);
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Get the start time, in milliseconds relative to the epoch.
|
||||
* @returns {number} the start time
|
||||
*/
|
||||
getStart: getStart,
|
||||
/**
|
||||
* Get the duration, in milliseconds.
|
||||
* @returns {number} the duration
|
||||
*/
|
||||
getDuration: getDuration,
|
||||
/**
|
||||
* Get the end time, in milliseconds relative to the epoch.
|
||||
* @returns {number} the end time
|
||||
*/
|
||||
getEnd: getEnd,
|
||||
/**
|
||||
* Set the start time, in milliseconds relative to the epoch.
|
||||
* @param {number} the new value
|
||||
*/
|
||||
setStart: setStart,
|
||||
/**
|
||||
* Set the duration, in milliseconds.
|
||||
* @param {number} the new value
|
||||
*/
|
||||
setDuration: setDuration,
|
||||
/**
|
||||
* Set the end time, in milliseconds relative to the epoch.
|
||||
* @param {number} the new value
|
||||
*/
|
||||
setEnd: setEnd,
|
||||
/**
|
||||
* Get a string identifying the reference epoch used for
|
||||
* start and end times.
|
||||
* @returns {string} the epoch
|
||||
*/
|
||||
getEpoch: getEpoch
|
||||
};
|
||||
}
|
||||
|
||||
return ActivityTimespan;
|
||||
}
|
||||
);
|
@ -1,61 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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(
|
||||
['./ActivityTimespan'],
|
||||
function (ActivityTimespan) {
|
||||
|
||||
/**
|
||||
* Implements the `timespan` capability for Activity objects.
|
||||
*
|
||||
* @constructor
|
||||
* @param $q Angular's $q, for promise-handling
|
||||
* @param {DomainObject} domainObject the Activity
|
||||
*/
|
||||
function ActivityTimespanCapability($q, domainObject) {
|
||||
// Promise time span
|
||||
function promiseTimeSpan() {
|
||||
return $q.when(new ActivityTimespan(
|
||||
domainObject.getModel(),
|
||||
domainObject.getCapability('mutation')
|
||||
));
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Get the time span (start, end, duration) of this activity.
|
||||
* @returns {Promise.<ActivityTimespan>} the time span of
|
||||
* this activity
|
||||
*/
|
||||
invoke: promiseTimeSpan
|
||||
};
|
||||
}
|
||||
|
||||
// Only applies to timeline objects
|
||||
ActivityTimespanCapability.appliesTo = function (model) {
|
||||
return model && (model.type === 'activity');
|
||||
};
|
||||
|
||||
return ActivityTimespanCapability;
|
||||
|
||||
}
|
||||
);
|
@ -1,50 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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 () {
|
||||
|
||||
/**
|
||||
* Provides data to populate resource graphs associated
|
||||
* with activities in a timeline view.
|
||||
* This is a placeholder until WTD-918.
|
||||
* @constructor
|
||||
*/
|
||||
function ActivityUtilization() {
|
||||
return {
|
||||
getPointCount: function () {
|
||||
return 0;
|
||||
},
|
||||
getDomainValue: function () {
|
||||
return 0;
|
||||
},
|
||||
getRangeValue: function () {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return ActivityUtilization;
|
||||
}
|
||||
|
||||
);
|
@ -1,75 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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 () {
|
||||
|
||||
/**
|
||||
* Exposes costs associated with a subsystem mode.
|
||||
* @constructor
|
||||
*/
|
||||
function CostCapability(domainObject) {
|
||||
var model = domainObject.getModel();
|
||||
|
||||
return {
|
||||
/**
|
||||
* Get a list of resource types which have associated
|
||||
* costs for this object. Returned values are machine-readable
|
||||
* keys, and should be paired with external metadata for
|
||||
* presentation (see category of extension `resources`).
|
||||
* @returns {string[]} resource types
|
||||
*/
|
||||
resources: function () {
|
||||
return Object.keys(model.resources || {}).sort();
|
||||
},
|
||||
/**
|
||||
* Get the cost associated with a resource of an identified
|
||||
* type (typically, one of the types reported from a
|
||||
* `resources` call.)
|
||||
* @param {string} key the resource type
|
||||
* @returns {number} the associated cost
|
||||
*/
|
||||
cost: function (key) {
|
||||
return (model.resources || {})[key] || 0;
|
||||
},
|
||||
/**
|
||||
* Get an object containing key-value pairs describing
|
||||
* resource utilization as described by this object.
|
||||
* Keys are resource types; values are levels of associated
|
||||
* resource utilization.
|
||||
* @returns {object} resource utilizations
|
||||
*/
|
||||
invoke: function () {
|
||||
return model.resources || {};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Only applies to subsystem modes.
|
||||
CostCapability.appliesTo = function (model) {
|
||||
return (model || {}).type === 'mode';
|
||||
};
|
||||
|
||||
return CostCapability;
|
||||
}
|
||||
);
|
@ -1,152 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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 () {
|
||||
|
||||
/**
|
||||
* Provide points for a cumulative resource summary graph, using
|
||||
* a provided instantaneous resource summary graph.
|
||||
*
|
||||
* @param {ResourceGraph} graph the resource graph
|
||||
* @param {number} minimum the minimum allowable level
|
||||
* @param {number} maximum the maximum allowable level
|
||||
* @param {number} initial the initial state of the resource
|
||||
* @param {number} rate the rate at which one unit of instantaneous
|
||||
* utilization changes the available level in one unit
|
||||
* of domain values (that is, per millisecond)
|
||||
* @constructor
|
||||
*/
|
||||
function CumulativeGraph(graph, minimum, maximum, initial, rate) {
|
||||
var values;
|
||||
|
||||
// Calculate the domain value at which a line starting at
|
||||
// (domain, range) and proceeding with the specified slope
|
||||
// will have the specified range value.
|
||||
function intercept(domain, range, slope, value) {
|
||||
// value = slope * (intercept - domain) + range
|
||||
// value - range = slope * ...
|
||||
// intercept - domain = (value - range) / slope
|
||||
// intercept = domain + (value - range) / slope
|
||||
return domain + (value - range) / slope;
|
||||
}
|
||||
|
||||
// Initialize the data values
|
||||
function initializeValues() {
|
||||
var vals = [],
|
||||
slope = 0,
|
||||
i;
|
||||
|
||||
// Add a point (or points, if needed) reaching to the provided
|
||||
// domain and/or range value
|
||||
function addPoint(domain, range) {
|
||||
var previous = vals[vals.length - 1],
|
||||
delta = domain - previous.domain, // time delta
|
||||
change = delta * slope * rate, // change
|
||||
next = previous.range + change;
|
||||
|
||||
// Crop to minimum boundary...
|
||||
if (next < minimum) {
|
||||
vals.push({
|
||||
domain: intercept(
|
||||
previous.domain,
|
||||
previous.range,
|
||||
slope * rate,
|
||||
minimum
|
||||
),
|
||||
range: minimum
|
||||
});
|
||||
next = minimum;
|
||||
}
|
||||
|
||||
// ...and maximum boundary
|
||||
if (next > maximum) {
|
||||
vals.push({
|
||||
domain: intercept(
|
||||
previous.domain,
|
||||
previous.range,
|
||||
slope * rate,
|
||||
maximum
|
||||
),
|
||||
range: maximum
|
||||
});
|
||||
next = maximum;
|
||||
}
|
||||
|
||||
// Add the new data value
|
||||
if (delta > 0) {
|
||||
vals.push({ domain: domain, range: next });
|
||||
}
|
||||
|
||||
slope = range;
|
||||
}
|
||||
|
||||
vals.push({ domain: 0, range: initial });
|
||||
|
||||
for (i = 0; i < graph.getPointCount(); i += 1) {
|
||||
addPoint(graph.getDomainValue(i), graph.getRangeValue(i));
|
||||
}
|
||||
|
||||
return vals;
|
||||
}
|
||||
|
||||
function convertToPercent(point) {
|
||||
point.range = 100 *
|
||||
(point.range - minimum) / (maximum - minimum);
|
||||
}
|
||||
|
||||
// Calculate cumulative values...
|
||||
values = initializeValues();
|
||||
|
||||
// ...and convert to percentages.
|
||||
values.forEach(convertToPercent);
|
||||
|
||||
return {
|
||||
/**
|
||||
* Get the total number of points in this graph.
|
||||
* @returns {number} the total number of points
|
||||
*/
|
||||
getPointCount: function () {
|
||||
return values.length;
|
||||
},
|
||||
/**
|
||||
* Get the domain value (timestamp) for a point in this graph.
|
||||
* @returns {number} the domain value
|
||||
*/
|
||||
getDomainValue: function (index) {
|
||||
return values[index].domain;
|
||||
},
|
||||
/**
|
||||
* Get the range value (utilization level) for a point in
|
||||
* this graph.
|
||||
* @returns {number} the range value
|
||||
*/
|
||||
getRangeValue: function (index) {
|
||||
return values[index].range;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return CumulativeGraph;
|
||||
}
|
||||
);
|
@ -1,100 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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(
|
||||
['./ResourceGraph', './CumulativeGraph'],
|
||||
function (ResourceGraph, CumulativeGraph) {
|
||||
|
||||
/**
|
||||
* Implements the `graph` capability for Timeline and
|
||||
* Activity objects.
|
||||
*
|
||||
* @constructor
|
||||
* @param {DomainObject} domainObject the Timeline or Activity
|
||||
*/
|
||||
function GraphCapability($q, domainObject) {
|
||||
|
||||
|
||||
// Build graphs for this group of utilizations
|
||||
function buildGraphs(utilizations) {
|
||||
var utilizationMap = {},
|
||||
result = {},
|
||||
startingSOC;
|
||||
|
||||
// Bucket utilizations by type
|
||||
utilizations.forEach(function (u) {
|
||||
var k = u.key;
|
||||
utilizationMap[k] = utilizationMap[k] || [];
|
||||
utilizationMap[k].push(u);
|
||||
});
|
||||
|
||||
// ...then convert to graphs
|
||||
Object.keys(utilizationMap).forEach(function (k) {
|
||||
result[k] = new ResourceGraph(utilizationMap[k]);
|
||||
});
|
||||
|
||||
// Add battery state of charge
|
||||
if (domainObject.getModel().type === 'timeline' &&
|
||||
result.power &&
|
||||
domainObject.getModel().capacity > 0) {
|
||||
startingSOC = isNaN(parseFloat(domainObject.getModel().startingSOC)) ?
|
||||
100 : parseFloat(domainObject.getModel().startingSOC);
|
||||
|
||||
result.battery = new CumulativeGraph(
|
||||
result.power,
|
||||
0,
|
||||
domainObject.getModel().capacity, // Watts
|
||||
(startingSOC / 100) * domainObject.getModel().capacity,
|
||||
1 / 3600000 // millis-to-hour (since units are watt-hours)
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Get resource graphs associated with this object.
|
||||
* This is given as a promise for key-value pairs,
|
||||
* where keys are resource types and values are graph
|
||||
* objects.
|
||||
* @returns {Promise} a promise for resource graphs
|
||||
*/
|
||||
invoke: function () {
|
||||
return $q.when(
|
||||
domainObject.useCapability('utilization') || []
|
||||
).then(buildGraphs);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Only applies to timeline objects
|
||||
GraphCapability.appliesTo = function (model) {
|
||||
return model &&
|
||||
((model.type === 'timeline') ||
|
||||
(model.type === 'activity'));
|
||||
};
|
||||
|
||||
return GraphCapability;
|
||||
|
||||
}
|
||||
);
|
@ -1,147 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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 () {
|
||||
|
||||
// Utility function to copy an array, sorted by a specific field
|
||||
function sort(array, field) {
|
||||
return array.slice().sort(function (a, b) {
|
||||
return a[field] - b[field];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides data to populate resource graphs associated
|
||||
* with timelines and activities.
|
||||
* @param {Array} utilizations resource utilizations
|
||||
* @constructor
|
||||
*/
|
||||
function ResourceGraph(utilizations) {
|
||||
// Overview of algorithm here:
|
||||
// * Goal: Have a list of time/value pairs which represents
|
||||
// points along a stepped chart of resource utilization.
|
||||
// Each change (stepping up or down) should have two points,
|
||||
// at the bottom and top of the step respectively.
|
||||
// * Step 1: Prepare two lists of utilizations sorted by start
|
||||
// and end times. The "starts" will become step-ups, the
|
||||
// "ends" will become step-downs.
|
||||
// * Step 2: Initialize empty arrays for results, and a variable
|
||||
// for the current utilization level.
|
||||
// * Step 3: While there are still start or end times to add...
|
||||
// * Step 3a: Determine whether the next change should be a
|
||||
// step-up (start) or step-down (end) based on which of the
|
||||
// next start/end times comes next (note that starts and ends
|
||||
// are both sorted, so we look at the head of the array.)
|
||||
// * Step 3b: Pull the next start or end (per previous decision)
|
||||
// and convert it to a time-delta pair, negating if it's an
|
||||
// end time (to step down or "un-step")
|
||||
// * Step 3c: Add a point at the new time and the current
|
||||
// running total (first point in the step, before the change)
|
||||
// then increment the running total and add a new point
|
||||
// (second point in the step, after the change)
|
||||
// * Step 4: Filter out unnecessary points (if two activities
|
||||
// run up against each other, there will be a zero-duration
|
||||
// spike if we don't filter out the extra points from their
|
||||
// start/end times.)
|
||||
//
|
||||
var starts = sort(utilizations, "start"),
|
||||
ends = sort(utilizations, "end"),
|
||||
values = [],
|
||||
running = 0;
|
||||
|
||||
// If there are sequences of points with the same timestamp,
|
||||
// allow only the first and last.
|
||||
function filterPoint(value, index, vals) {
|
||||
// Allow the first or last point as a base case; aside from
|
||||
// that, allow only points that have different timestamps
|
||||
// from their predecessor or successor.
|
||||
return (index === 0) || (index === vals.length - 1) ||
|
||||
(value.domain !== vals[index - 1].domain) ||
|
||||
(value.domain !== vals[index + 1].domain);
|
||||
}
|
||||
|
||||
// Add a step up or down (Step 3c above)
|
||||
function addDelta(time, delta) {
|
||||
values.push({ domain: time, range: running });
|
||||
running += delta;
|
||||
values.push({ domain: time, range: running });
|
||||
}
|
||||
|
||||
// Add a start time (Step 3b above)
|
||||
function addStart() {
|
||||
var next = starts.shift();
|
||||
addDelta(next.start, next.value);
|
||||
}
|
||||
|
||||
// Add an end time (Step 3b above)
|
||||
function addEnd() {
|
||||
var next = ends.shift();
|
||||
addDelta(next.end, -next.value);
|
||||
}
|
||||
|
||||
// Decide whether next step should correspond to a start or
|
||||
// an end. (Step 3c above)
|
||||
function pickStart() {
|
||||
return ends.length < 1 ||
|
||||
(starts.length > 0 && starts[0].start <= ends[0].end);
|
||||
}
|
||||
|
||||
// Build up start/end arrays (step 3 above)
|
||||
while (starts.length > 0 || ends.length > 0) {
|
||||
(pickStart() ? addStart : addEnd)();
|
||||
}
|
||||
|
||||
// Filter out excess points
|
||||
values = values.filter(filterPoint);
|
||||
|
||||
return {
|
||||
/**
|
||||
* Get the total number of points in this graph.
|
||||
* @returns {number} the total number of points
|
||||
*/
|
||||
getPointCount: function () {
|
||||
return values.length;
|
||||
},
|
||||
/**
|
||||
* Get the domain value (timestamp) for a point in this graph.
|
||||
* @returns {number} the domain value
|
||||
*/
|
||||
getDomainValue: function (index) {
|
||||
return values[index].domain;
|
||||
},
|
||||
/**
|
||||
* Get the range value (utilization level) for a point in
|
||||
* this graph.
|
||||
* @returns {number} the range value
|
||||
*/
|
||||
getRangeValue: function (index) {
|
||||
return values[index].range;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return ResourceGraph;
|
||||
}
|
||||
|
||||
);
|
@ -1,124 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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 () {
|
||||
|
||||
/**
|
||||
* Describes the time span of a timeline object.
|
||||
* @param model the timeline's object model
|
||||
* @param {Timespan[]} time spans of contained activities
|
||||
*/
|
||||
function TimelineTimespan(model, mutation, timespans) {
|
||||
// Get the start time for this timeline
|
||||
function getStart() {
|
||||
return model.start.timestamp;
|
||||
}
|
||||
|
||||
// Get the end time for another time span
|
||||
function getTimespanEnd(timespan) {
|
||||
return timespan.getEnd();
|
||||
}
|
||||
|
||||
// Wrapper for Math.max; used for max-finding of end time
|
||||
function max(a, b) {
|
||||
return Math.max(a, b);
|
||||
}
|
||||
|
||||
// Get the end time for this timeline
|
||||
function getEnd() {
|
||||
return timespans.map(getTimespanEnd).reduce(max, getStart());
|
||||
}
|
||||
|
||||
// Get the duration of this timeline
|
||||
function getDuration() {
|
||||
return getEnd() - getStart();
|
||||
}
|
||||
|
||||
// Set the start time associated with this object
|
||||
function setStart(value) {
|
||||
mutation.mutate(function (m) {
|
||||
m.start.timestamp = Math.max(value, 0);
|
||||
}, model.modified);
|
||||
}
|
||||
|
||||
// Set the duration associated with this object
|
||||
function setDuration() {
|
||||
// No-op; duration is implicit
|
||||
}
|
||||
|
||||
// Set the end time associated with this object
|
||||
function setEnd() {
|
||||
// No-op; end time is implicit
|
||||
}
|
||||
|
||||
// Get the epoch used by this timeline
|
||||
function getEpoch() {
|
||||
return model.start.epoch;
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Get the start time, in milliseconds relative to the epoch.
|
||||
* @returns {number} the start time
|
||||
*/
|
||||
getStart: getStart,
|
||||
/**
|
||||
* Get the duration, in milliseconds.
|
||||
* @returns {number} the duration
|
||||
*/
|
||||
getDuration: getDuration,
|
||||
/**
|
||||
* Get the end time, in milliseconds relative to the epoch.
|
||||
* @returns {number} the end time
|
||||
*/
|
||||
getEnd: getEnd,
|
||||
/**
|
||||
* Set the start time, in milliseconds relative to the epoch.
|
||||
* @param {number} the new value
|
||||
*/
|
||||
setStart: setStart,
|
||||
/**
|
||||
* Set the duration, in milliseconds. Timeline durations are
|
||||
* implicit, so this is actually a no-op
|
||||
* @param {number} the new value
|
||||
*/
|
||||
setDuration: setDuration,
|
||||
/**
|
||||
* Set the end time, in milliseconds. Timeline end times are
|
||||
* implicit, so this is actually a no-op.
|
||||
* @param {number} the new value
|
||||
*/
|
||||
setEnd: setEnd,
|
||||
/**
|
||||
* Get a string identifying the reference epoch used for
|
||||
* start and end times.
|
||||
* @returns {string} the epoch
|
||||
*/
|
||||
getEpoch: getEpoch
|
||||
};
|
||||
}
|
||||
|
||||
return TimelineTimespan;
|
||||
}
|
||||
);
|
@ -1,87 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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(
|
||||
['./TimelineTimespan'],
|
||||
function (TimelineTimespan) {
|
||||
|
||||
/**
|
||||
* Implements the `timespan` capability for Timeline objects.
|
||||
*
|
||||
* @constructor
|
||||
* @param $q Angular's $q, for promise-handling
|
||||
* @param {DomainObject} domainObject the Timeline
|
||||
*/
|
||||
function TimelineTimespanCapability($q, domainObject) {
|
||||
// Check if a capability is defin
|
||||
|
||||
// Look up a child object's time span
|
||||
function lookupTimeSpan(childObject) {
|
||||
return childObject.useCapability('timespan');
|
||||
}
|
||||
|
||||
// Check if a child object exposes a time span
|
||||
function hasTimeSpan(childObject) {
|
||||
return childObject.hasCapability('timespan');
|
||||
}
|
||||
|
||||
// Instantiate a time span bounding other time spans
|
||||
function giveTimeSpan(timespans) {
|
||||
return new TimelineTimespan(
|
||||
domainObject.getModel(),
|
||||
domainObject.getCapability('mutation'),
|
||||
timespans
|
||||
);
|
||||
}
|
||||
|
||||
// Build a time span object that fits all children
|
||||
function buildTimeSpan(childObjects) {
|
||||
return $q.all(
|
||||
childObjects.filter(hasTimeSpan).map(lookupTimeSpan)
|
||||
).then(giveTimeSpan);
|
||||
}
|
||||
|
||||
// Promise
|
||||
function promiseTimeSpan() {
|
||||
return domainObject.useCapability('composition')
|
||||
.then(buildTimeSpan);
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Get the time span (start, end, duration) of this timeline.
|
||||
* @returns {Promise.<TimelineTimespan>} the time span of
|
||||
* this timeline
|
||||
*/
|
||||
invoke: promiseTimeSpan
|
||||
};
|
||||
}
|
||||
|
||||
// Only applies to timeline objects
|
||||
TimelineTimespanCapability.appliesTo = function (model) {
|
||||
return model && (model.type === 'timeline');
|
||||
};
|
||||
|
||||
return TimelineTimespanCapability;
|
||||
|
||||
}
|
||||
);
|
@ -1,50 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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 () {
|
||||
|
||||
/**
|
||||
* Provides data to populate resource graphs associated
|
||||
* with timelines in a timeline view.
|
||||
* This is a placeholder until WTD-918.
|
||||
* @constructor
|
||||
*/
|
||||
function TimelineUtilization() {
|
||||
return {
|
||||
getPointCount: function () {
|
||||
return 1000;
|
||||
},
|
||||
getDomainValue: function (index) {
|
||||
return 60000 * index;
|
||||
},
|
||||
getRangeValue: function (index) {
|
||||
return Math.sin(index) * (index % 10);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return TimelineUtilization;
|
||||
}
|
||||
|
||||
);
|
@ -1,224 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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 () {
|
||||
|
||||
/**
|
||||
* Provide the resource utilization over time for a timeline
|
||||
* or activity object. A utilization is presented as an object
|
||||
* with four properties:
|
||||
* * `key`: The resource being utilized.
|
||||
* * `value`: The numeric utilization of that resource.
|
||||
* * `start`: The start time of the resource's utilization.
|
||||
* * `end`: The duration of this resource's utilization.
|
||||
* * `epoch`: The epoch to which `start` is relative.
|
||||
* @constructor
|
||||
*/
|
||||
function UtilizationCapability($q, domainObject) {
|
||||
|
||||
// Utility function for array reduction
|
||||
function concatenate(a, b) {
|
||||
return (a || []).concat(b || []);
|
||||
}
|
||||
|
||||
// Check whether an element in an array looks unique (for below)
|
||||
function unique(element, index, array) {
|
||||
return (index === 0) || (array[index - 1] !== element);
|
||||
}
|
||||
|
||||
// Utility function to ensure sorted array is all unique
|
||||
function uniquify(array) {
|
||||
return array.filter(unique);
|
||||
}
|
||||
|
||||
// Utility function for sorting strings arrays
|
||||
function sort(array) {
|
||||
return array.sort();
|
||||
}
|
||||
|
||||
// Combine into one big array
|
||||
function flatten(arrayOfArrays) {
|
||||
return arrayOfArrays.reduce(concatenate, []);
|
||||
}
|
||||
|
||||
// Promise the objects contained by this timeline/activity
|
||||
function promiseComposition() {
|
||||
return $q.when(domainObject.useCapability('composition') || []);
|
||||
}
|
||||
|
||||
// Promise all subsystem modes associated with this object
|
||||
function promiseModes() {
|
||||
var relationship = domainObject.getCapability('relationship'),
|
||||
modes = relationship && relationship.getRelatedObjects('modes');
|
||||
return $q.when(modes || []);
|
||||
}
|
||||
|
||||
// Promise the utilization which results directly from this object
|
||||
function promiseInternalUtilization() {
|
||||
var utilizations = {};
|
||||
|
||||
// Record the cost of a given activity mode
|
||||
function addUtilization(mode) {
|
||||
var cost = mode.getCapability('cost');
|
||||
if (cost) {
|
||||
cost.resources().forEach(function (k) {
|
||||
utilizations[k] = utilizations[k] || 0;
|
||||
utilizations[k] += cost.cost(k);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Record costs for these modes
|
||||
function addUtilizations(modes) {
|
||||
modes.forEach(addUtilization);
|
||||
}
|
||||
|
||||
// Look up start/end times for this object
|
||||
function lookupTimespan() {
|
||||
return domainObject.useCapability('timespan');
|
||||
}
|
||||
|
||||
// Provide the result
|
||||
function giveResult(timespan) {
|
||||
// Convert to utilization objects
|
||||
return Object.keys(utilizations).sort().map(function (k) {
|
||||
return {
|
||||
key: k,
|
||||
value: utilizations[k],
|
||||
start: timespan.getStart(),
|
||||
end: timespan.getEnd(),
|
||||
epoch: timespan.getEpoch()
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
return promiseModes()
|
||||
.then(addUtilizations)
|
||||
.then(lookupTimespan)
|
||||
.then(giveResult);
|
||||
}
|
||||
|
||||
// Look up a specific object's resource utilization
|
||||
function lookupUtilization(object) {
|
||||
return object.useCapability('utilization');
|
||||
}
|
||||
|
||||
// Look up a specific object's resource utilization keys
|
||||
function lookupUtilizationResources(object) {
|
||||
var utilization = object.getCapability('utilization');
|
||||
return utilization && utilization.resources();
|
||||
}
|
||||
|
||||
// Promise a consolidated list of resource utilizations
|
||||
function mapUtilization(objects) {
|
||||
return $q.all(objects.map(lookupUtilization))
|
||||
.then(flatten);
|
||||
}
|
||||
|
||||
// Promise a consolidated list of resource utilization keys
|
||||
function mapUtilizationResources(objects) {
|
||||
return $q.all(objects.map(lookupUtilizationResources))
|
||||
.then(flatten);
|
||||
}
|
||||
|
||||
// Promise utilization associated with contained objects
|
||||
function promiseExternalUtilization() {
|
||||
// Get the composition, then consolidate their utilizations
|
||||
return promiseComposition().then(mapUtilization);
|
||||
}
|
||||
|
||||
// Get resource keys for this mode
|
||||
function getModeKeys(mode) {
|
||||
var cost = mode.getCapability('cost');
|
||||
return cost ? cost.resources() : [];
|
||||
}
|
||||
|
||||
// Map the above (for use in below)
|
||||
function mapModeKeys(modes) {
|
||||
return modes.map(getModeKeys);
|
||||
}
|
||||
|
||||
// Promise identifiers for resources associated with modes
|
||||
function promiseInternalKeys() {
|
||||
return promiseModes().then(mapModeKeys).then(flatten);
|
||||
}
|
||||
|
||||
// Promise identifiers for resources associated with modes
|
||||
function promiseExternalKeys() {
|
||||
return promiseComposition().then(mapUtilizationResources);
|
||||
}
|
||||
|
||||
// Promise identifiers for resources used
|
||||
function promiseResourceKeys() {
|
||||
return $q.all([
|
||||
promiseInternalKeys(),
|
||||
promiseExternalKeys()
|
||||
]).then(flatten).then(sort).then(uniquify);
|
||||
}
|
||||
|
||||
// Promise all utilization
|
||||
function promiseAllUtilization() {
|
||||
// Concatenate internal utilization (from activity modes)
|
||||
// with external utilization (from subactivities)
|
||||
return $q.all([
|
||||
promiseInternalUtilization(),
|
||||
promiseExternalUtilization()
|
||||
]).then(flatten);
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Get the keys for resources associated with this object.
|
||||
* @returns {Promise.<string[]>} a promise for resource identifiers
|
||||
*/
|
||||
resources: promiseResourceKeys,
|
||||
/**
|
||||
* Get the resource utilization associated with this object
|
||||
* directly, not including any resource utilization associated
|
||||
* with contained objects.
|
||||
* @returns {Promise.<Array>}
|
||||
*/
|
||||
internal: promiseInternalUtilization,
|
||||
/**
|
||||
* Get the resource utilization associated with this
|
||||
* object. Results are not sorted. This requires looking
|
||||
* at contained objects, which in turn must happen
|
||||
* asynchronously, so this returns a promise.
|
||||
* @returns {Promise.<Array>} a promise for all resource
|
||||
* utilizations
|
||||
*/
|
||||
invoke: promiseAllUtilization
|
||||
};
|
||||
}
|
||||
|
||||
// Only applies to timelines and activities
|
||||
UtilizationCapability.appliesTo = function (model) {
|
||||
return model &&
|
||||
((model.type === 'timeline') ||
|
||||
(model.type === 'activity'));
|
||||
};
|
||||
|
||||
return UtilizationCapability;
|
||||
}
|
||||
);
|
@ -1,117 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
|
||||
/**
|
||||
* Create a new chart which uses Canvas's 2D API for rendering.
|
||||
*
|
||||
* @memberof platform/features/plot
|
||||
* @constructor
|
||||
* @implements {platform/features/plot.Chart}
|
||||
* @param {CanvasElement} canvas the canvas object to render upon
|
||||
* @throws {Error} an error is thrown if Canvas's 2D API is unavailable.
|
||||
*/
|
||||
function Canvas2DChart(canvas) {
|
||||
this.canvas = canvas;
|
||||
this.c2d = canvas.getContext('2d');
|
||||
this.width = canvas.width;
|
||||
this.height = canvas.height;
|
||||
this.dimensions = [this.width, this.height];
|
||||
this.origin = [0, 0];
|
||||
|
||||
if (!this.c2d) {
|
||||
throw new Error("Canvas 2d API unavailable.");
|
||||
}
|
||||
}
|
||||
|
||||
// Convert from logical to physical x coordinates
|
||||
Canvas2DChart.prototype.x = function (v) {
|
||||
return ((v - this.origin[0]) / this.dimensions[0]) * this.width;
|
||||
};
|
||||
|
||||
// Convert from logical to physical y coordinates
|
||||
Canvas2DChart.prototype.y = function (v) {
|
||||
return this.height -
|
||||
((v - this.origin[1]) / this.dimensions[1]) * this.height;
|
||||
};
|
||||
|
||||
// Set the color to be used for drawing operations
|
||||
Canvas2DChart.prototype.setColor = function (color) {
|
||||
var mappedColor = color.map(function (c, i) {
|
||||
return i < 3 ? Math.floor(c * 255) : (c);
|
||||
}).join(',');
|
||||
this.c2d.strokeStyle = "rgba(" + mappedColor + ")";
|
||||
this.c2d.fillStyle = "rgba(" + mappedColor + ")";
|
||||
};
|
||||
|
||||
|
||||
Canvas2DChart.prototype.clear = function () {
|
||||
var canvas = this.canvas;
|
||||
this.width = canvas.width;
|
||||
this.height = canvas.height;
|
||||
this.c2d.clearRect(0, 0, this.width, this.height);
|
||||
};
|
||||
|
||||
Canvas2DChart.prototype.setDimensions = function (newDimensions, newOrigin) {
|
||||
this.dimensions = newDimensions;
|
||||
this.origin = newOrigin;
|
||||
};
|
||||
|
||||
Canvas2DChart.prototype.drawLine = function (buf, color, points) {
|
||||
var i;
|
||||
|
||||
this.setColor(color);
|
||||
|
||||
// Configure context to draw two-pixel-thick lines
|
||||
this.c2d.lineWidth = 2;
|
||||
|
||||
// Start a new path...
|
||||
if (buf.length > 1) {
|
||||
this.c2d.beginPath();
|
||||
this.c2d.moveTo(this.x(buf[0]), this.y(buf[1]));
|
||||
}
|
||||
|
||||
// ...and add points to it...
|
||||
for (i = 2; i < points * 2; i = i + 2) {
|
||||
this.c2d.lineTo(this.x(buf[i]), this.y(buf[i + 1]));
|
||||
}
|
||||
|
||||
// ...before finally drawing it.
|
||||
this.c2d.stroke();
|
||||
};
|
||||
|
||||
Canvas2DChart.prototype.drawSquare = function (min, max, color) {
|
||||
var x1 = this.x(min[0]),
|
||||
y1 = this.y(min[1]),
|
||||
w = this.x(max[0]) - x1,
|
||||
h = this.y(max[1]) - y1;
|
||||
|
||||
this.setColor(color);
|
||||
this.c2d.fillRect(x1, y1, w, h);
|
||||
};
|
||||
|
||||
return Canvas2DChart;
|
||||
}
|
||||
);
|
@ -1,160 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Module defining GLPlot. Created by vwoeltje on 11/12/14.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
|
||||
// WebGL shader sources (for drawing plain colors)
|
||||
var FRAGMENT_SHADER = [
|
||||
"precision mediump float;",
|
||||
"uniform vec4 uColor;",
|
||||
"void main(void) {",
|
||||
"gl_FragColor = uColor;",
|
||||
"}"
|
||||
].join('\n'),
|
||||
VERTEX_SHADER = [
|
||||
"attribute vec2 aVertexPosition;",
|
||||
"uniform vec2 uDimensions;",
|
||||
"uniform vec2 uOrigin;",
|
||||
"void main(void) {",
|
||||
"gl_Position = vec4(2.0 * ((aVertexPosition - uOrigin) / uDimensions) - vec2(1,1), 0, 1);",
|
||||
"}"
|
||||
].join('\n');
|
||||
|
||||
/**
|
||||
* Create a new chart which uses WebGL for rendering.
|
||||
*
|
||||
* @memberof platform/features/plot
|
||||
* @constructor
|
||||
* @implements {platform/features/plot.Chart}
|
||||
* @param {CanvasElement} canvas the canvas object to render upon
|
||||
* @throws {Error} an error is thrown if WebGL is unavailable.
|
||||
*/
|
||||
function GLChart(canvas) {
|
||||
var gl = canvas.getContext("webgl", { preserveDrawingBuffer: true }) ||
|
||||
canvas.getContext("experimental-webgl", { preserveDrawingBuffer: true }),
|
||||
vertexShader,
|
||||
fragmentShader,
|
||||
program,
|
||||
aVertexPosition,
|
||||
uColor,
|
||||
uDimensions,
|
||||
uOrigin;
|
||||
|
||||
// Ensure a context was actually available before proceeding
|
||||
if (!gl) {
|
||||
throw new Error("WebGL unavailable.");
|
||||
}
|
||||
|
||||
// Initialize shaders
|
||||
vertexShader = gl.createShader(gl.VERTEX_SHADER);
|
||||
gl.shaderSource(vertexShader, VERTEX_SHADER);
|
||||
gl.compileShader(vertexShader);
|
||||
fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
|
||||
gl.shaderSource(fragmentShader, FRAGMENT_SHADER);
|
||||
gl.compileShader(fragmentShader);
|
||||
|
||||
// Assemble vertex/fragment shaders into programs
|
||||
program = gl.createProgram();
|
||||
gl.attachShader(program, vertexShader);
|
||||
gl.attachShader(program, fragmentShader);
|
||||
gl.linkProgram(program);
|
||||
gl.useProgram(program);
|
||||
|
||||
// Get locations for attribs/uniforms from the
|
||||
// shader programs (to pass values into shaders at draw-time)
|
||||
aVertexPosition = gl.getAttribLocation(program, "aVertexPosition");
|
||||
uColor = gl.getUniformLocation(program, "uColor");
|
||||
uDimensions = gl.getUniformLocation(program, "uDimensions");
|
||||
uOrigin = gl.getUniformLocation(program, "uOrigin");
|
||||
gl.enableVertexAttribArray(aVertexPosition);
|
||||
|
||||
// Create a buffer to holds points which will be drawn
|
||||
this.buffer = gl.createBuffer();
|
||||
|
||||
// Use a line width of 2.0 for legibility
|
||||
gl.lineWidth(2.0);
|
||||
|
||||
// Enable blending, for smoothness
|
||||
gl.enable(gl.BLEND);
|
||||
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
this.gl = gl;
|
||||
this.aVertexPosition = aVertexPosition;
|
||||
this.uColor = uColor;
|
||||
this.uDimensions = uDimensions;
|
||||
this.uOrigin = uOrigin;
|
||||
}
|
||||
|
||||
// Utility function to handle drawing of a buffer;
|
||||
// drawType will determine whether this is a box, line, etc.
|
||||
GLChart.prototype.doDraw = function (drawType, buf, color, points) {
|
||||
var gl = this.gl;
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, buf, gl.DYNAMIC_DRAW);
|
||||
gl.vertexAttribPointer(this.aVertexPosition, 2, gl.FLOAT, false, 0, 0);
|
||||
gl.uniform4fv(this.uColor, color);
|
||||
gl.drawArrays(drawType, 0, points);
|
||||
};
|
||||
|
||||
GLChart.prototype.clear = function () {
|
||||
var gl = this.gl;
|
||||
|
||||
// Set the viewport size; note that we use the width/height
|
||||
// that our WebGL context reports, which may be lower
|
||||
// resolution than the canvas we requested.
|
||||
gl.viewport(
|
||||
0,
|
||||
0,
|
||||
gl.drawingBufferWidth,
|
||||
gl.drawingBufferHeight
|
||||
);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT + gl.DEPTH_BUFFER_BIT);
|
||||
};
|
||||
|
||||
|
||||
GLChart.prototype.setDimensions = function (dimensions, origin) {
|
||||
var gl = this.gl;
|
||||
if (dimensions && dimensions.length > 0 &&
|
||||
origin && origin.length > 0) {
|
||||
gl.uniform2fv(this.uDimensions, dimensions);
|
||||
gl.uniform2fv(this.uOrigin, origin);
|
||||
}
|
||||
};
|
||||
|
||||
GLChart.prototype.drawLine = function (buf, color, points) {
|
||||
this.doDraw(this.gl.LINE_STRIP, buf, color, points);
|
||||
};
|
||||
|
||||
GLChart.prototype.drawSquare = function (min, max, color) {
|
||||
this.doDraw(this.gl.TRIANGLE_FAN, new Float32Array(
|
||||
min.concat([min[0], max[1]]).concat(max).concat([max[0], min[1]])
|
||||
), color, 4);
|
||||
};
|
||||
|
||||
return GLChart;
|
||||
}
|
||||
);
|
@ -1,250 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Module defining MCTTimelineChart. Created by vwoeltje on 11/12/14.
|
||||
*/
|
||||
define(
|
||||
["./GLChart", "./Canvas2DChart"],
|
||||
function (GLChart, Canvas2DChart) {
|
||||
|
||||
var TEMPLATE = "<canvas style='position: absolute; background: none; width: 100%; height: 100%;'></canvas>";
|
||||
|
||||
/**
|
||||
* The mct-timeline-chart directive provides a canvas element which can be
|
||||
* drawn upon, to support Plot view and similar visualizations.
|
||||
*
|
||||
* This directive takes one attribute, "draw", which is an Angular
|
||||
* expression which will be two-way bound to a drawing object. This
|
||||
* drawing object should contain:
|
||||
*
|
||||
* * `dimensions`: An object describing the logical bounds of the
|
||||
* drawable area, containing two fields:
|
||||
* * `origin`: The position, in logical coordinates, of the
|
||||
* lower-left corner of the chart area. A two-element array.
|
||||
* * `dimensions`: A two-element array containing the width
|
||||
* and height of the chart area, in logical coordinates.
|
||||
* * `lines`: An array of lines to be drawn, where each line is
|
||||
* expressed as an object containing:
|
||||
* * `buffer`: A Float32Array containing points in the line,
|
||||
* in logical coordinate, in sequential x/y pairs.
|
||||
* * `color`: The color of the line, as a four-element RGBA
|
||||
* array, where each element is in the range of 0.0-1.0
|
||||
* * `points`: The number of points in the line.
|
||||
* * `boxes`: An array of rectangles to draw in the chart area
|
||||
* (used for marquee zoom). Each is an object containing:
|
||||
* * `start`: The first corner of the rectangle (as a two-element
|
||||
* array, logical coordinates)
|
||||
* * `end`: The opposite corner of the rectangle (again, as a
|
||||
* two-element array)
|
||||
* * `color`: The color of the box, as a four-element RGBA
|
||||
* array, where each element is in the range of 0.0-1.0
|
||||
*
|
||||
* @memberof platform/features/plot
|
||||
* @constructor
|
||||
*/
|
||||
function MCTTimelineChart($interval, $log) {
|
||||
// Get an underlying chart implementation
|
||||
function getChart(Charts, canvas) {
|
||||
// Try the first available option...
|
||||
var Chart = Charts[0];
|
||||
|
||||
// This function recursively try-catches all options;
|
||||
// if these all fail, issue a warning.
|
||||
if (!Chart) {
|
||||
$log.warn("Cannot initialize mct-timeline-chart.");
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Try first option; if it fails, try remaining options
|
||||
try {
|
||||
return new Chart(canvas);
|
||||
} catch (e) {
|
||||
$log.warn([
|
||||
"Could not instantiate chart",
|
||||
Chart.name,
|
||||
";",
|
||||
e.message
|
||||
].join(" "));
|
||||
|
||||
return getChart(Charts.slice(1), canvas);
|
||||
}
|
||||
}
|
||||
|
||||
function linkChart(scope, element) {
|
||||
var canvas = element.find("canvas")[0],
|
||||
activeInterval,
|
||||
chart;
|
||||
|
||||
// Handle drawing, based on contents of the "draw" object
|
||||
// in scope
|
||||
function doDraw(draw) {
|
||||
// Ensure canvas context has same resolution
|
||||
// as canvas element
|
||||
canvas.width = canvas.offsetWidth;
|
||||
canvas.height = canvas.offsetHeight;
|
||||
|
||||
// Clear previous contents
|
||||
chart.clear();
|
||||
|
||||
// Nothing to draw if no draw object defined
|
||||
if (!draw) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set logical boundaries for the chart
|
||||
chart.setDimensions(
|
||||
draw.dimensions || [1, 1],
|
||||
draw.origin || [0, 0]
|
||||
);
|
||||
|
||||
// Draw line segments
|
||||
(draw.lines || []).forEach(function (line) {
|
||||
chart.drawLine(
|
||||
line.buffer,
|
||||
line.color,
|
||||
line.points
|
||||
);
|
||||
});
|
||||
|
||||
// Draw boxes (e.g. marquee zoom rect)
|
||||
(draw.boxes || []).forEach(function (box) {
|
||||
chart.drawSquare(
|
||||
box.start,
|
||||
box.end,
|
||||
box.color
|
||||
);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// Issue a drawing call, if-and-only-if canvas size
|
||||
// has changed. This will be called on a timer, since
|
||||
// there is no event to depend on.
|
||||
function drawIfResized() {
|
||||
if (canvas.width !== canvas.offsetWidth ||
|
||||
canvas.height !== canvas.offsetHeight) {
|
||||
doDraw(scope.draw);
|
||||
scope.$apply();
|
||||
}
|
||||
}
|
||||
|
||||
// Stop watching for changes to size (scope destroyed)
|
||||
function releaseInterval() {
|
||||
if (activeInterval) {
|
||||
$interval.cancel(activeInterval);
|
||||
}
|
||||
}
|
||||
|
||||
// Switch from WebGL to plain 2D if context is lost
|
||||
function fallbackFromWebGL() {
|
||||
element.html(TEMPLATE);
|
||||
canvas = element.find("canvas")[0];
|
||||
chart = getChart([Canvas2DChart], canvas);
|
||||
if (chart) {
|
||||
doDraw(scope.draw);
|
||||
}
|
||||
}
|
||||
|
||||
// Try to initialize a chart.
|
||||
chart = getChart([GLChart, Canvas2DChart], canvas);
|
||||
|
||||
// If that failed, there's nothing more we can do here.
|
||||
// (A warning will already have been issued)
|
||||
if (!chart) {
|
||||
return;
|
||||
}
|
||||
|
||||
// WebGL is a bit of a special case; it may work, then fail
|
||||
// later for various reasons, so we need to listen for this
|
||||
// and fall back to plain canvas drawing when it occurs.
|
||||
canvas.addEventListener("webglcontextlost", fallbackFromWebGL);
|
||||
|
||||
// Check for resize, on a timer
|
||||
activeInterval = $interval(drawIfResized, 1000, 0, false);
|
||||
|
||||
// Watch "draw" for external changes to the set of
|
||||
// things to be drawn.
|
||||
scope.$watchCollection("draw", doDraw);
|
||||
|
||||
// Stop checking for resize when scope is destroyed
|
||||
scope.$on("$destroy", releaseInterval);
|
||||
}
|
||||
|
||||
return {
|
||||
// Apply directive only to elements
|
||||
restrict: "E",
|
||||
|
||||
// Template to use (a canvas element)
|
||||
template: TEMPLATE,
|
||||
|
||||
// Link function; set up scope
|
||||
link: linkChart,
|
||||
|
||||
// Initial, isolate scope for the directive
|
||||
scope: { draw: "=" }
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @interface platform/features/plot.Chart
|
||||
* @private
|
||||
*/
|
||||
|
||||
/**
|
||||
* Clear the chart.
|
||||
* @method platform/features/plot.Chart#clear
|
||||
*/
|
||||
/**
|
||||
* Set the logical boundaries of the chart.
|
||||
* @param {number[]} dimensions the horizontal and
|
||||
* vertical dimensions of the chart
|
||||
* @param {number[]} origin the horizontal/vertical
|
||||
* origin of the chart
|
||||
* @memberof platform/features/plot.Chart#setDimensions
|
||||
*/
|
||||
/**
|
||||
* Draw the supplied buffer as a line strip (a sequence
|
||||
* of line segments), in the chosen color.
|
||||
* @param {Float32Array} buf the line strip to draw,
|
||||
* in alternating x/y positions
|
||||
* @param {number[]} color the color to use when drawing
|
||||
* the line, as an RGBA color where each element
|
||||
* is in the range of 0.0-1.0
|
||||
* @param {number} points the number of points to draw
|
||||
* @memberof platform/features/plot.Chart#drawLine
|
||||
*/
|
||||
/**
|
||||
* Draw a rectangle extending from one corner to another,
|
||||
* in the chosen color.
|
||||
* @param {number[]} min the first corner of the rectangle
|
||||
* @param {number[]} max the opposite corner
|
||||
* @param {number[]} color the color to use when drawing
|
||||
* the rectangle, as an RGBA color where each element
|
||||
* is in the range of 0.0-1.0
|
||||
* @memberof platform/features/plot.Chart#drawSquare
|
||||
*/
|
||||
|
||||
return MCTTimelineChart;
|
||||
}
|
||||
);
|
||||
|
@ -1,60 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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 () {
|
||||
|
||||
/**
|
||||
* Controller which support the Values view of Activity Modes.
|
||||
* @constructor
|
||||
* @param {Array} resources definitions for extensions of
|
||||
* category `resources`
|
||||
*/
|
||||
function ActivityModeValuesController(resources) {
|
||||
var metadata = {};
|
||||
|
||||
// Store metadata for a specific resource type
|
||||
function storeMetadata(resource) {
|
||||
var key = (resource || {}).key;
|
||||
if (key) {
|
||||
metadata[key] = resource;
|
||||
}
|
||||
}
|
||||
|
||||
// Populate the lookup table to resource metadata
|
||||
resources.forEach(storeMetadata);
|
||||
|
||||
return {
|
||||
/**
|
||||
* Look up metadata associated with the specified
|
||||
* resource type.
|
||||
*/
|
||||
metadata: function (key) {
|
||||
return metadata[key];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return ActivityModeValuesController;
|
||||
}
|
||||
);
|
@ -1,143 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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(
|
||||
[
|
||||
'./swimlane/TimelineSwimlanePopulator',
|
||||
'./graph/TimelineGraphPopulator',
|
||||
'./drag/TimelineDragPopulator'
|
||||
],
|
||||
function (
|
||||
TimelineSwimlanePopulator,
|
||||
TimelineGraphPopulator,
|
||||
TimelineDragPopulator
|
||||
) {
|
||||
|
||||
/**
|
||||
* Controller for the Timeline view.
|
||||
* @constructor
|
||||
*/
|
||||
function TimelineController($scope, $q, objectLoader, MINIMUM_DURATION) {
|
||||
var swimlanePopulator = new TimelineSwimlanePopulator(
|
||||
objectLoader,
|
||||
$scope.configuration || {},
|
||||
$scope.selection
|
||||
),
|
||||
graphPopulator = new TimelineGraphPopulator($q),
|
||||
dragPopulator = new TimelineDragPopulator(objectLoader);
|
||||
|
||||
// Hash together all modification times. A sum is sufficient here,
|
||||
// since modified timestamps should be non-decreasing.
|
||||
function modificationSum() {
|
||||
var sum = 0;
|
||||
swimlanePopulator.get().forEach(function (swimlane) {
|
||||
sum += swimlane.domainObject.getModel().modified || 0;
|
||||
});
|
||||
return sum;
|
||||
}
|
||||
|
||||
// Reduce graph states to a watch-able number. A bitmask is
|
||||
// sufficient here, since only ~30 graphed elements make sense
|
||||
// (due to limits on recognizably unique line colors)
|
||||
function graphMask() {
|
||||
var mask = 0, bit = 1;
|
||||
swimlanePopulator.get().forEach(function (swimlane) {
|
||||
mask += swimlane.graph() ? 0 : bit;
|
||||
bit *= 2;
|
||||
});
|
||||
return mask;
|
||||
}
|
||||
|
||||
// Repopulate based on detected modification to in-view objects
|
||||
function repopulateSwimlanes() {
|
||||
swimlanePopulator.populate($scope.domainObject);
|
||||
dragPopulator.populate($scope.domainObject);
|
||||
graphPopulator.populate(swimlanePopulator.get());
|
||||
}
|
||||
|
||||
// Repopulate graphs based on modification to swimlane graph state
|
||||
function repopulateGraphs() {
|
||||
graphPopulator.populate(swimlanePopulator.get());
|
||||
}
|
||||
|
||||
// Refresh resource graphs
|
||||
function refresh() {
|
||||
if (graphPopulator) {
|
||||
graphPopulator.get().forEach(function (graph) {
|
||||
graph.refresh();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$scope.$watch("configuration", swimlanePopulator.configure);
|
||||
|
||||
// Recalculate swimlane state on changes
|
||||
$scope.$watch("domainObject", swimlanePopulator.populate);
|
||||
|
||||
// Also recalculate whenever anything in view is modified
|
||||
$scope.$watch(modificationSum, repopulateSwimlanes);
|
||||
|
||||
// Carry over changes in swimlane set to changes in graphs
|
||||
$scope.$watch(graphMask, repopulateGraphs);
|
||||
|
||||
// Pass selection object into swimlane populator
|
||||
$scope.$watch("selection", swimlanePopulator.selection);
|
||||
|
||||
// Convey current selection to drag handle populator
|
||||
$scope.$watch("selection.get()", dragPopulator.select);
|
||||
|
||||
// Provide initial scroll bar state, container for pane positions
|
||||
$scope.scroll = { x: 0, y: 0 };
|
||||
$scope.panes = {};
|
||||
|
||||
// Expose active set of swimlanes
|
||||
return {
|
||||
/**
|
||||
* Get the end of the displayed timeline, in milliseconds.
|
||||
* @returns {number} the end of the displayed timeline
|
||||
*/
|
||||
end: swimlanePopulator.end.bind(swimlanePopulator),
|
||||
/**
|
||||
* Get the swimlanes which should currently be displayed.
|
||||
* @returns {TimelineSwimlane[]} the swimlanes
|
||||
*/
|
||||
swimlanes: swimlanePopulator.get,
|
||||
/**
|
||||
* Get the resource graphs which should currently be displayed.
|
||||
* @returns {TimelineGraph[]} the graphs
|
||||
*/
|
||||
graphs: graphPopulator.get,
|
||||
/**
|
||||
* Get drag handles for the current selection.
|
||||
* @returns {TimelineDragHandle[]} the drag handles
|
||||
*/
|
||||
handles: dragPopulator.get,
|
||||
/**
|
||||
* Refresh resource graphs (during drag.)
|
||||
*/
|
||||
refresh: refresh
|
||||
};
|
||||
}
|
||||
|
||||
return TimelineController;
|
||||
}
|
||||
);
|
@ -1,91 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-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 () {
|
||||
|
||||
/**
|
||||
* Controller for the `datetime` form control.
|
||||
* This is a composite control; it includes multiple
|
||||
* input fields but outputs a single timestamp (in
|
||||
* milliseconds since start of 1970) to the ngModel.
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
function DateTimeController($scope) {
|
||||
|
||||
// Update the data model
|
||||
function updateModel(datetime) {
|
||||
var days = parseInt(datetime.days, 10) || 0,
|
||||
hour = parseInt(datetime.hours, 10) || 0,
|
||||
min = parseInt(datetime.minutes, 10) || 0,
|
||||
sec = parseInt(datetime.seconds, 10) || 0,
|
||||
epoch = "SET", // Only permit SET, for now
|
||||
timestamp;
|
||||
|
||||
// Build up timestamp
|
||||
timestamp = days * 24;
|
||||
timestamp = (hour + timestamp) * 60;
|
||||
timestamp = (min + timestamp) * 60;
|
||||
timestamp = (sec + timestamp) * 1000;
|
||||
|
||||
// Set in the model
|
||||
$scope.ngModel[$scope.field] = {
|
||||
timestamp: timestamp,
|
||||
epoch: epoch
|
||||
};
|
||||
}
|
||||
|
||||
// Update the displayed state
|
||||
function updateForm(modelState) {
|
||||
var timestamp = (modelState || {}).timestamp || 0,
|
||||
datetime = $scope.datetime;
|
||||
|
||||
timestamp = Math.floor(timestamp / 1000);
|
||||
datetime.seconds = timestamp % 60;
|
||||
timestamp = Math.floor(timestamp / 60);
|
||||
datetime.minutes = timestamp % 60;
|
||||
timestamp = Math.floor(timestamp / 60);
|
||||
datetime.hours = timestamp % 24;
|
||||
timestamp = Math.floor(timestamp / 24);
|
||||
datetime.days = timestamp;
|
||||
}
|
||||
|
||||
// Retrieve state from field, for watch
|
||||
function getModelState() {
|
||||
return $scope.ngModel[$scope.field];
|
||||
}
|
||||
|
||||
// Update value whenever any field changes.
|
||||
$scope.$watchCollection("datetime", updateModel);
|
||||
$scope.$watchCollection(getModelState, updateForm);
|
||||
|
||||
// Initialize the scope
|
||||
$scope.datetime = {};
|
||||
updateForm(getModelState());
|
||||
}
|
||||
|
||||
return DateTimeController;
|
||||
|
||||
}
|
||||
);
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user