mirror of
https://github.com/nasa/openmct.git
synced 2025-05-30 22:24:18 +00:00
Merge branch 'master' into open671
Conflicts: main.js platform/commonUI/edit/src/policies/EditableMovePolicy.js platform/commonUI/general/src/directives/MCTTree.js platform/commonUI/general/src/ui/ToggleView.js platform/core/src/actions/ActionCapability.js platform/core/test/models/CachingModelDecoratorSpec.js platform/core/test/services/InstantiateSpec.js platform/features/events/bundle.js platform/features/events/src/DomainColumn.js platform/features/events/src/EventListController.js platform/features/events/src/EventListPopulator.js platform/features/events/src/RangeColumn.js platform/features/events/src/directives/MCTDataTable.js platform/features/events/src/policies/MessagesViewPolicy.js platform/features/events/test/DomainColumnSpec.js platform/features/events/test/EventListControllerSpec.js platform/features/events/test/EventListPopulatorSpec.js platform/features/events/test/RangeColumnSpec.js platform/features/events/test/policies/MessagesViewPolicySpec.js platform/features/rtevents/bundle.js platform/features/rtevents/src/DomainColumn.js platform/features/rtevents/src/RTEventListController.js platform/features/rtevents/src/RangeColumn.js platform/features/rtevents/src/directives/MCTRTDataTable.js platform/features/rtevents/src/policies/RTMessagesViewPolicy.js platform/features/rtevents/test/DomainColumnSpec.js platform/features/rtevents/test/RTEventListControllerSpec.js platform/features/rtevents/test/RangeColumnSpec.js platform/features/rtevents/test/policies/RTMessagesViewPolicySpec.js platform/features/rtscrolling/bundle.js platform/features/rtscrolling/src/DomainColumn.js platform/features/rtscrolling/src/NameColumn.js platform/features/rtscrolling/src/RTScrollingListController.js platform/features/rtscrolling/src/RangeColumn.js platform/features/scrolling/src/DomainColumn.js platform/features/scrolling/src/RangeColumn.js platform/features/scrolling/src/ScrollingListController.js platform/features/scrolling/src/ScrollingListPopulator.js platform/features/scrolling/test/DomainColumnSpec.js platform/features/scrolling/test/RangeColumnSpec.js platform/features/scrolling/test/ScrollingListControllerSpec.js platform/features/scrolling/test/ScrollingListPopulatorSpec.js platform/features/table/src/directives/MCTTable.js platform/features/table/test/controllers/TelemetryTableControllerSpec.js platform/representation/src/gestures/DropGesture.js platform/telemetry/src/TelemetryFormatter.js test-main.js
This commit is contained in:
commit
5e44bfc6c7
62
LICENSES.md
62
LICENSES.md
@ -309,30 +309,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
|
||||
---
|
||||
|
||||
### Modernizr
|
||||
|
||||
#### Info
|
||||
|
||||
* Link: http://modernizr.com
|
||||
|
||||
* Version: 2.6.2
|
||||
|
||||
* Author: Faruk Ateş
|
||||
|
||||
* Description: Browser/device capability finding
|
||||
|
||||
#### License
|
||||
|
||||
Copyright (c) 2009–2015
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
### Normalize.css
|
||||
|
||||
#### Info
|
||||
@ -476,6 +452,44 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
|
||||
---
|
||||
|
||||
### Zepto
|
||||
|
||||
#### Info
|
||||
|
||||
* Link: http://zeptojs.com/
|
||||
|
||||
* Version: 1.1.6
|
||||
|
||||
* Authors: Thomas Fuchs
|
||||
|
||||
* Description: DOM manipulation
|
||||
|
||||
#### License
|
||||
|
||||
Copyright (c) 2010-2016 Thomas Fuchs
|
||||
http://zeptojs.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
### Json.NET
|
||||
|
||||
#### Info
|
||||
|
@ -17,6 +17,7 @@
|
||||
"screenfull": "^3.0.0",
|
||||
"node-uuid": "^1.4.7",
|
||||
"comma-separated-values": "^3.6.4",
|
||||
"FileSaver.js": "^0.0.2"
|
||||
"FileSaver.js": "^0.0.2",
|
||||
"zepto": "^1.1.6"
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ define([
|
||||
|
||||
legacyRegistry.register("example/eventGenerator", {
|
||||
"name": "Event Message Generator",
|
||||
"description": "Example of a component that produces event data.",
|
||||
"description": "For development use. Creates sample event message data that mimics a live data stream.",
|
||||
"extensions": {
|
||||
"components": [
|
||||
{
|
||||
@ -49,16 +49,26 @@ define([
|
||||
{
|
||||
"key": "eventGenerator",
|
||||
"name": "Event Message Generator",
|
||||
"glyph": "f",
|
||||
"description": "An event message generator",
|
||||
"glyph": "\u0066",
|
||||
"description": "For development use. Creates sample event message data that mimics a live data stream.",
|
||||
"priority": 10,
|
||||
"features": "creation",
|
||||
"model": {
|
||||
"telemetry": {}
|
||||
},
|
||||
"telemetry": {
|
||||
"source": "eventGenerator",
|
||||
"domains": [
|
||||
{
|
||||
"key": "time",
|
||||
"name": "Time",
|
||||
"format": "utc"
|
||||
}
|
||||
],
|
||||
"ranges": [
|
||||
{
|
||||
"key": "message",
|
||||
"name": "Message",
|
||||
"format": "string"
|
||||
}
|
||||
]
|
||||
|
@ -37,7 +37,8 @@ define(
|
||||
var
|
||||
subscriptions = [],
|
||||
genInterval = 1000,
|
||||
startTime = Date.now();
|
||||
generating = false,
|
||||
id = Math.random() * 100000;
|
||||
|
||||
//
|
||||
function matchesSource(request) {
|
||||
@ -79,11 +80,13 @@ define(
|
||||
}
|
||||
|
||||
function startGenerating() {
|
||||
generating = true;
|
||||
$timeout(function () {
|
||||
//console.log("startGenerating... " + Date.now());
|
||||
handleSubscriptions();
|
||||
if (subscriptions.length > 0) {
|
||||
if (generating && subscriptions.length > 0) {
|
||||
startGenerating();
|
||||
} else {
|
||||
generating = false;
|
||||
}
|
||||
}, genInterval);
|
||||
}
|
||||
@ -93,7 +96,6 @@ define(
|
||||
callback: callback,
|
||||
requests: requests
|
||||
};
|
||||
|
||||
function unsubscribe() {
|
||||
subscriptions = subscriptions.filter(function (s) {
|
||||
return s !== subscription;
|
||||
@ -101,8 +103,7 @@ define(
|
||||
}
|
||||
|
||||
subscriptions.push(subscription);
|
||||
|
||||
if (subscriptions.length === 1) {
|
||||
if (!generating) {
|
||||
startGenerating();
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ define([
|
||||
|
||||
legacyRegistry.register("example/generator", {
|
||||
"name": "Sine Wave Generator",
|
||||
"description": "Example of a component that produces dataa.",
|
||||
"description": "For development use. Generates example streaming telemetry data using a simple sine wave algorithm.",
|
||||
"extensions": {
|
||||
"components": [
|
||||
{
|
||||
@ -86,8 +86,9 @@ define([
|
||||
{
|
||||
"key": "generator",
|
||||
"name": "Sine Wave Generator",
|
||||
"glyph": "T",
|
||||
"description": "A sine wave generator",
|
||||
"glyph": "\u0054",
|
||||
"description": "For development use. Generates example streaming telemetry data using a simple sine wave algorithm.",
|
||||
"priority": 10,
|
||||
"features": "creation",
|
||||
"model": {
|
||||
"telemetry": {
|
||||
@ -126,7 +127,7 @@ define([
|
||||
{
|
||||
"name": "Period",
|
||||
"control": "textfield",
|
||||
"cssclass": "l-small l-numeric",
|
||||
"cssclass": "l-input-sm l-numeric",
|
||||
"key": "period",
|
||||
"required": true,
|
||||
"property": [
|
||||
|
@ -34,7 +34,8 @@ define(
|
||||
* @constructor
|
||||
*/
|
||||
function SinewaveTelemetryProvider($q, $timeout) {
|
||||
var subscriptions = [];
|
||||
var subscriptions = [],
|
||||
generating = false;
|
||||
|
||||
//
|
||||
function matchesSource(request) {
|
||||
@ -75,10 +76,13 @@ define(
|
||||
}
|
||||
|
||||
function startGenerating() {
|
||||
generating = true;
|
||||
$timeout(function () {
|
||||
handleSubscriptions();
|
||||
if (subscriptions.length > 0) {
|
||||
if (generating && subscriptions.length > 0) {
|
||||
startGenerating();
|
||||
} else {
|
||||
generating = false;
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
@ -97,7 +101,7 @@ define(
|
||||
|
||||
subscriptions.push(subscription);
|
||||
|
||||
if (subscriptions.length === 1) {
|
||||
if (!generating) {
|
||||
startGenerating();
|
||||
}
|
||||
|
||||
|
@ -49,8 +49,10 @@ define([
|
||||
{
|
||||
"key": "imagery",
|
||||
"name": "Example Imagery",
|
||||
"glyph": "T",
|
||||
"glyph": "\u00e3",
|
||||
"features": "creation",
|
||||
"description": "For development use. Creates example imagery data that mimics a live imagery stream.",
|
||||
"priority": 10,
|
||||
"model": {
|
||||
"telemetry": {}
|
||||
},
|
||||
|
@ -54,7 +54,7 @@ define([
|
||||
{
|
||||
"name": "Measurement",
|
||||
"key": "msl.measurement",
|
||||
"glyph": "T",
|
||||
"glyph": "\u0054",
|
||||
"model": {"telemetry": {}},
|
||||
"telemetry": {
|
||||
"source": "rems.source",
|
||||
|
@ -80,9 +80,10 @@ define([
|
||||
"types": [
|
||||
{
|
||||
"key": "plot",
|
||||
"name": "Telemetry Plot",
|
||||
"glyph": "t",
|
||||
"description": "A plot for displaying telemetry",
|
||||
"name": "Example Telemetry Plot",
|
||||
"glyph": "\u0074",
|
||||
"description": "For development use. A plot for displaying telemetry.",
|
||||
"priority": 10,
|
||||
"delegates": [
|
||||
"telemetry"
|
||||
],
|
||||
|
@ -85,7 +85,8 @@ var gulp = require('gulp'),
|
||||
singleRun: true
|
||||
},
|
||||
sass: {
|
||||
includePaths: bourbon.includePaths
|
||||
includePaths: bourbon.includePaths,
|
||||
sourceComments: true
|
||||
},
|
||||
replace: {
|
||||
variables: {
|
||||
|
@ -81,7 +81,12 @@ module.exports = function(config) {
|
||||
coverageReporter: {
|
||||
dir: process.env.CIRCLE_ARTIFACTS ?
|
||||
process.env.CIRCLE_ARTIFACTS + '/coverage' :
|
||||
"dist/coverage"
|
||||
"dist/coverage",
|
||||
check: {
|
||||
global: {
|
||||
lines: 80
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// HTML test reporting.
|
||||
|
10
main.js
10
main.js
@ -33,7 +33,8 @@ requirejs.config({
|
||||
"saveAs": "bower_components/FileSaver.js/FileSaver.min",
|
||||
"screenfull": "bower_components/screenfull/dist/screenfull.min",
|
||||
"text": "bower_components/text/text",
|
||||
"uuid": "bower_components/node-uuid/uuid"
|
||||
"uuid": "bower_components/node-uuid/uuid",
|
||||
"zepto": "bower_components/zepto/zepto.min"
|
||||
},
|
||||
"shim": {
|
||||
"angular": {
|
||||
@ -47,6 +48,9 @@ requirejs.config({
|
||||
},
|
||||
"screenfull": {
|
||||
"exports": "screenfull"
|
||||
},
|
||||
"zepto": {
|
||||
"exports": "Zepto"
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -73,12 +77,10 @@ define([
|
||||
'./platform/exporters/bundle',
|
||||
'./platform/telemetry/bundle',
|
||||
'./platform/features/clock/bundle',
|
||||
'./platform/features/events/bundle',
|
||||
'./platform/features/imagery/bundle',
|
||||
'./platform/features/layout/bundle',
|
||||
'./platform/features/pages/bundle',
|
||||
'./platform/features/plot/bundle',
|
||||
'./platform/features/scrolling/bundle',
|
||||
'./platform/features/timeline/bundle',
|
||||
'./platform/features/table/bundle',
|
||||
'./platform/forms/bundle',
|
||||
@ -102,4 +104,4 @@ define([
|
||||
return new Main().run(legacyRegistry);
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "openmctweb",
|
||||
"version": "0.9.2-SNAPSHOT",
|
||||
"description": "The Open MCT Web core platform",
|
||||
"version": "0.10.0-SNAPSHOT",
|
||||
"description": "The Open MCT core platform",
|
||||
"dependencies": {
|
||||
"express": "^4.13.1",
|
||||
"minimist": "^1.1.1",
|
||||
@ -39,7 +39,7 @@
|
||||
"moment": "^2.11.1",
|
||||
"node-bourbon": "^4.2.3",
|
||||
"phantomjs-prebuilt": "^2.1.0",
|
||||
"requirejs": "^2.1.17",
|
||||
"requirejs": "2.1.x",
|
||||
"split": "^1.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
|
@ -44,22 +44,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="holder l-flex-col flex-elem grows l-object-wrapper">
|
||||
<div ng-if="isEditable" class="holder l-flex-col flex-elem grows l-object-wrapper-inner">
|
||||
<!-- Toolbar and Save/Cancel buttons -->
|
||||
<div class="l-edit-controls flex-elem l-flex-row flex-align-end">
|
||||
<mct-representation key="'edit-action-buttons'"
|
||||
mct-object="domainObject"
|
||||
class='flex-elem conclude-editing'>
|
||||
</mct-representation>
|
||||
|
||||
</div>
|
||||
<mct-representation key="representation.selected.key"
|
||||
mct-object="representation.selected.key && domainObject"
|
||||
class="abs flex-elem grows object-holder-main scroll"
|
||||
toolbar="toolbar">
|
||||
</mct-representation>
|
||||
</div>
|
||||
<div ng-if="!isEditable" class="holder l-flex-col flex-elem grows l-object-wrapper-inner">
|
||||
<div class="holder l-flex-col flex-elem grows l-object-wrapper-inner">
|
||||
<!-- Toolbar and Save/Cancel buttons -->
|
||||
<div class="l-edit-controls flex-elem l-flex-row flex-align-end">
|
||||
<mct-representation key="'edit-action-buttons'"
|
||||
|
@ -32,6 +32,7 @@
|
||||
</li>
|
||||
<li ng-if="contextutalParents.length > 0">
|
||||
<em class="t-inspector-part-header" title="The location of this linked object.">Location</em>
|
||||
<div ng-if="primaryParents.length > 0" class="section-header">This Object</div>
|
||||
<span class="inspector-location"
|
||||
ng-repeat="parent in contextutalParents"
|
||||
ng-class="{ last:($index + 1) === contextualParents.length }">
|
||||
@ -44,7 +45,7 @@
|
||||
</span>
|
||||
</li>
|
||||
<li ng-if="primaryParents.length > 0">
|
||||
<em class="t-inspector-part-header" title="The location of the original object that this was linked from.">Original Location</em>
|
||||
<div class="section-header">Object's Original</div>
|
||||
<span class="inspector-location"
|
||||
ng-repeat="parent in primaryParents"
|
||||
ng-class="{ last:($index + 1) === primaryParents.length }">
|
||||
|
@ -29,5 +29,5 @@
|
||||
-->
|
||||
<mct-representation mct-object="domainObject"
|
||||
key="viewObjectTemplate || 'browse-object'"
|
||||
class="abs holder holder-object">
|
||||
class="abs holder">
|
||||
</mct-representation>
|
||||
|
@ -91,27 +91,23 @@ define(
|
||||
return wizard.populateObjectFromInput(formValue, newObject);
|
||||
}
|
||||
|
||||
function addToParent (populatedObject) {
|
||||
parentObject.getCapability('composition').add(populatedObject);
|
||||
return parentObject.getCapability('persistence').persist().then(function(){
|
||||
return parentObject;
|
||||
});
|
||||
function persistAndReturn(domainObject) {
|
||||
return domainObject.getCapability('persistence')
|
||||
.persist()
|
||||
.then(function () {
|
||||
return domainObject;
|
||||
});
|
||||
}
|
||||
|
||||
function save(object) {
|
||||
/*
|
||||
It's necessary to persist the new sub-object in order
|
||||
that it can be retrieved for composition in the parent.
|
||||
Future refactoring that allows temporary objects to be
|
||||
retrieved from object services will make this unnecessary.
|
||||
*/
|
||||
return object.getCapability('editor').save(true);
|
||||
function addToParent (populatedObject) {
|
||||
parentObject.getCapability('composition').add(populatedObject);
|
||||
return persistAndReturn(parentObject);
|
||||
}
|
||||
|
||||
return this.dialogService
|
||||
.getUserInput(wizard.getFormStructure(false), wizard.getInitialFormValue())
|
||||
.then(populateObjectFromInput)
|
||||
.then(save)
|
||||
.then(persistAndReturn)
|
||||
.then(addToParent);
|
||||
|
||||
};
|
||||
|
@ -33,6 +33,8 @@ define([
|
||||
"./src/actions/SaveAction",
|
||||
"./src/actions/CancelAction",
|
||||
"./src/policies/EditActionPolicy",
|
||||
"./src/policies/EditableLinkPolicy",
|
||||
"./src/policies/EditableMovePolicy",
|
||||
"./src/policies/EditNavigationPolicy",
|
||||
"./src/representers/EditRepresenter",
|
||||
"./src/representers/EditToolbarRepresenter",
|
||||
@ -55,6 +57,8 @@ define([
|
||||
SaveAction,
|
||||
CancelAction,
|
||||
EditActionPolicy,
|
||||
EditableLinkPolicy,
|
||||
EditableMovePolicy,
|
||||
EditNavigationPolicy,
|
||||
EditRepresenter,
|
||||
EditToolbarRepresenter,
|
||||
@ -185,6 +189,14 @@ define([
|
||||
"category": "action",
|
||||
"implementation": EditActionPolicy
|
||||
},
|
||||
{
|
||||
"category": "action",
|
||||
"implementation": EditableMovePolicy
|
||||
},
|
||||
{
|
||||
"category": "action",
|
||||
"implementation": EditableLinkPolicy
|
||||
},
|
||||
{
|
||||
"category": "navigation",
|
||||
"message": "There are unsaved changes.",
|
||||
|
@ -19,16 +19,19 @@
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<div ng-controller="ElementsController">
|
||||
<div ng-controller="ElementsController" class="flex-elem l-flex-col holder grows">
|
||||
<mct-include key="'input-filter'"
|
||||
class="flex-elem holder"
|
||||
ng-model="filterBy">
|
||||
</mct-include>
|
||||
<div class="current-elements abs" style="height: 100%;">
|
||||
<div class="flex-elem grows vscroll">
|
||||
<ul class="tree">
|
||||
<li ng-repeat="containedObject in composition | filter:searchText">
|
||||
<span class="tree-item">
|
||||
<mct-representation key="'label'" mct-object="containedObject">
|
||||
<mct-representation
|
||||
class="rep-object-label"
|
||||
key="'label'"
|
||||
mct-object="containedObject">
|
||||
</mct-representation>
|
||||
</span>
|
||||
</li>
|
||||
|
@ -19,33 +19,34 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
.select {
|
||||
@include btnSubtle($colorSelectBg);
|
||||
@if $shdwBtns != none {
|
||||
margin: 0 0 2px 0; // Needed to avoid dropshadow from being clipped by parent containers
|
||||
/*global define*/
|
||||
|
||||
define([], function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Policy suppressing links when the linked-to domain object is in
|
||||
* edit mode. Domain objects being edited may not have been persisted,
|
||||
* so creating links to these can result in inconsistent state.
|
||||
*
|
||||
* @memberof platform/commonUI/edit
|
||||
* @constructor
|
||||
* @implements {Policy.<View, DomainObject>}
|
||||
*/
|
||||
function EditableLinkPolicy() {
|
||||
}
|
||||
padding: 0 $interiorMargin;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
line-height: $formInputH;
|
||||
select {
|
||||
@include appearance(none);
|
||||
box-sizing: border-box;
|
||||
background: none;
|
||||
color: $colorSelectFg;
|
||||
cursor: pointer;
|
||||
border: none !important;
|
||||
padding: 4px 25px 2px 0px;
|
||||
width: 130%;
|
||||
option {
|
||||
margin: $interiorMargin 0; // Firefox
|
||||
|
||||
EditableLinkPolicy.prototype.allow = function (action, context) {
|
||||
var key = action.getMetadata().key;
|
||||
|
||||
if (key === 'link') {
|
||||
return !((context.selectedObject || context.domainObject)
|
||||
.hasCapability('editor'));
|
||||
}
|
||||
}
|
||||
&:after {
|
||||
@include contextArrow();
|
||||
pointer-events: none;
|
||||
color: rgba($colorSelectFg, percentToDecimal($contrastInvokeMenuPercent));
|
||||
position: absolute;
|
||||
right: $interiorMargin; top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Like all policies, allow by default.
|
||||
return true;
|
||||
};
|
||||
|
||||
return EditableLinkPolicy;
|
||||
});
|
@ -20,34 +20,30 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Module defining NameColumn. Created by vwoeltje on 11/18/14.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
define([], function () {
|
||||
|
||||
/**
|
||||
* A column which will report the name of the domain object
|
||||
* which exposed specific telemetry values.
|
||||
*
|
||||
* @memberof platform/features/scrolling
|
||||
* @implements {platform/features/scrolling.ScrollingColumn}
|
||||
* @constructor
|
||||
*/
|
||||
function NameColumn() {
|
||||
/**
|
||||
* Policy suppressing move actions among editable and non-editable
|
||||
* domain objects.
|
||||
* @memberof platform/commonUI/edit
|
||||
* @constructor
|
||||
* @implements {Policy.<View, DomainObject>}
|
||||
*/
|
||||
function EditableMovePolicy() {
|
||||
}
|
||||
|
||||
EditableMovePolicy.prototype.allow = function (action, context) {
|
||||
var domainObject = context.domainObject,
|
||||
selectedObject = context.selectedObject,
|
||||
key = action.getMetadata().key;
|
||||
|
||||
if (key === 'move' && domainObject.hasCapability('editor')) {
|
||||
return !!selectedObject && selectedObject.hasCapability('editor');
|
||||
}
|
||||
|
||||
NameColumn.prototype.getTitle = function () {
|
||||
return "Name";
|
||||
};
|
||||
// Like all policies, allow by default.
|
||||
return true;
|
||||
};
|
||||
|
||||
NameColumn.prototype.getValue = function (domainObject) {
|
||||
return {
|
||||
text: domainObject.getModel().name
|
||||
};
|
||||
};
|
||||
|
||||
return NameColumn;
|
||||
}
|
||||
);
|
||||
return EditableMovePolicy;
|
||||
});
|
@ -116,8 +116,6 @@ define(
|
||||
// Track the represented object
|
||||
this.domainObject = representedObject;
|
||||
|
||||
this.scope.isEditable = representedObject.getCapability('status').get('editing');
|
||||
|
||||
// Ensure existing watches are released
|
||||
this.destroy();
|
||||
|
||||
|
@ -26,9 +26,10 @@ define([
|
||||
moment
|
||||
) {
|
||||
|
||||
var DATE_FORMAT = "YYYY-MM-DD HH:mm:ss",
|
||||
var DATE_FORMAT = "YYYY-MM-DD HH:mm:ss.SSS",
|
||||
DATE_FORMATS = [
|
||||
DATE_FORMAT,
|
||||
"YYYY-MM-DD HH:mm:ss",
|
||||
"YYYY-MM-DD HH:mm",
|
||||
"YYYY-MM-DD"
|
||||
];
|
||||
@ -46,7 +47,7 @@ define([
|
||||
}
|
||||
|
||||
UTCTimeFormat.prototype.format = function (value) {
|
||||
return moment.utc(value).format(DATE_FORMAT);
|
||||
return moment.utc(value).format(DATE_FORMAT) + "Z";
|
||||
};
|
||||
|
||||
UTCTimeFormat.prototype.parse = function (text) {
|
||||
|
@ -38,6 +38,12 @@ define(
|
||||
expect(moment.utc(formatted).valueOf()).toEqual(timestamp);
|
||||
});
|
||||
|
||||
it("displays with millisecond precision", function () {
|
||||
var timestamp = 12345670789,
|
||||
formatted = format.format(timestamp);
|
||||
expect(moment.utc(formatted).valueOf()).toEqual(timestamp);
|
||||
});
|
||||
|
||||
it("validates time inputs", function () {
|
||||
expect(format.validate("1977-05-25 11:21:22")).toBe(true);
|
||||
expect(format.validate("garbage text")).toBe(false);
|
||||
|
@ -48,6 +48,7 @@ define([
|
||||
"./src/directives/MCTScroll",
|
||||
"./src/directives/MCTSplitPane",
|
||||
"./src/directives/MCTSplitter",
|
||||
"./src/directives/MCTTree",
|
||||
"text!./res/templates/bottombar.html",
|
||||
"text!./res/templates/controls/action-button.html",
|
||||
"text!./res/templates/controls/input-filter.html",
|
||||
@ -96,6 +97,7 @@ define([
|
||||
MCTScroll,
|
||||
MCTSplitPane,
|
||||
MCTSplitter,
|
||||
MCTTree,
|
||||
bottombarTemplate,
|
||||
actionButtonTemplate,
|
||||
inputFilterTemplate,
|
||||
@ -173,10 +175,6 @@ define([
|
||||
{
|
||||
"stylesheetUrl": "css/normalize.min.css",
|
||||
"priority": "mandatory"
|
||||
},
|
||||
{
|
||||
"stylesheetUrl": "css/reset.css",
|
||||
"priority": "mandatory"
|
||||
}
|
||||
],
|
||||
"templates": [
|
||||
@ -387,6 +385,11 @@ define([
|
||||
{
|
||||
"key": "mctSplitter",
|
||||
"implementation": MCTSplitter
|
||||
},
|
||||
{
|
||||
"key": "mctTree",
|
||||
"implementation": MCTTree,
|
||||
"depends": [ '$parse', 'gestureService' ]
|
||||
}
|
||||
],
|
||||
"constants": [
|
||||
@ -514,16 +517,6 @@ define([
|
||||
}
|
||||
],
|
||||
"licenses": [
|
||||
{
|
||||
"name": "Modernizr",
|
||||
"version": "2.6.2",
|
||||
"description": "Browser/device capability finding",
|
||||
"author": "Faruk Ateş",
|
||||
"website": "http://modernizr.com",
|
||||
"copyright": "Copyright (c) 2009–2015",
|
||||
"license": "license-mit",
|
||||
"link": "http://modernizr.com/license/"
|
||||
},
|
||||
{
|
||||
"name": "Normalize.css",
|
||||
"version": "1.1.2",
|
||||
@ -533,6 +526,16 @@ define([
|
||||
"copyright": "Copyright (c) Nicolas Gallagher and Jonathan Neal",
|
||||
"license": "license-mit",
|
||||
"link": "https://github.com/necolas/normalize.css/blob/v1.1.2/LICENSE.md"
|
||||
},
|
||||
{
|
||||
"name": "Zepto",
|
||||
"version": "1.1.6",
|
||||
"description": "DOM manipulation",
|
||||
"author": "Thomas Fuchs",
|
||||
"website": "http://zeptojs.com/",
|
||||
"copyright": "Copyright (c) 2010-2016 Thomas Fuchs",
|
||||
"license": "license-mit",
|
||||
"link": "https://github.com/madrobby/zepto/blob/master/MIT-LICENSE"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
Binary file not shown.
@ -80,7 +80,7 @@
|
||||
<glyph unicode="" glyph-name="icon-datatable" d="M1024 768c0-106.039-229.23-192-512-192s-512 85.961-512 192c0 106.039 229.23 192 512 192s512-85.961 512-192zM512 448c-282.8 0-512 86-512 192v-512c0-106 229.2-192 512-192s512 86 512 192v512c0-106-229.2-192-512-192zM896 385v-256c-36.6-15.6-79.8-28.8-128-39.4v256c48.2 10.6 91.4 23.8 128 39.4zM256 345.6v-256c-48.2 10.4-91.4 23.8-128 39.4v256c36.6-15.6 79.8-28.8 128-39.4zM384 70v256c41-4 83.8-6 128-6s87 2.2 128 6v-256c-41-4-83.8-6-128-6s-87 2.2-128 6z" />
|
||||
<glyph unicode="" glyph-name="icon-tabular-scrolling" d="M64 960c-35.2 0-64-28.8-64-64v-192h448v256h-384zM1024 704v192c0 35.2-28.8 64-64 64h-384v-256h448zM0 576v-192c0-35.2 28.8-64 64-64h384v256h-448zM960 320c35.2 0 64 28.8 64 64v192h-448v-256h384zM512-64l-256 256h512z" />
|
||||
<glyph unicode="" glyph-name="icon-alert-triangle" d="M998.208 111.136l-422.702 739.728c-34.928 61.124-92.084 61.124-127.012 0l-422.702-739.728c-34.928-61.126-5.906-111.136 64.494-111.136h843.428c70.4 0 99.422 50.010 64.494 111.136zM512 128c-35.2 0-64 28.8-64 64s28.8 64 64 64 64-28.8 64-64c0-35.2-28.8-64-64-64zM627.448 577.242l-38.898-194.486c-6.902-34.516-41.35-62.756-76.55-62.756s-69.648 28.24-76.552 62.758l-38.898 194.486c-6.902 34.516 16.25 62.756 51.45 62.756h128c35.2 0 58.352-28.24 51.448-62.758z" />
|
||||
<glyph unicode="" glyph-name="icon-tabular" d="M0 896v-192h448v256h-384c-35.2 0-64-28.8-64-64zM960 960h-384v-256h448v192c0 35.2-28.8 64-64 64zM576 576h448v-256h-448v256zM0 576h448v-256h-448v256zM0 0c0-35.2 28.8-64 64-64h384v256h-448v-192zM576-64h384c35.2 0 64 28.8 64 64v192h-448v-256z" />
|
||||
<glyph unicode="" glyph-name="icon-tabular" d="M896 960h-768c-70.4 0-128-57.6-128-128v-768c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v768c0 70.4-57.6 128-128 128zM640 512h-256v192h256v-192zM384 448h256v-192h-256v192zM320 256h-256v192h256v-192zM320 704v-192h-256v192h256zM128 0c-17 0-33 6.6-45.2 18.8s-18.8 28.2-18.8 45.2v128h256v-192h-192zM384 0v192h256v-192h-256zM960 64c0-17-6.6-33-18.8-45.2s-28.2-18.8-45.2-18.8h-192v192h256v-128zM960 256h-256v192h256v-192zM960 512h-256v192h256v-192z" />
|
||||
<glyph unicode="" glyph-name="icon-calendar" d="M896 960h-768c-70.4 0-128-57.6-128-128v-768c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v768c0 70.4-57.6 128-128 128zM640 512h-256v192h256v-192zM384 448h256v-192h-256v192zM320 256h-256v192h256v-192zM320 704v-192h-256v192h256zM128 0c-17 0-33 6.6-45.2 18.8s-18.8 28.2-18.8 45.2v128h256v-192h-192zM384 0v192h256v-192h-256zM960 64c0-17-6.6-33-18.8-45.2s-28.2-18.8-45.2-18.8h-192v192h256v-128zM960 256h-256v192h256v-192zM960 512h-256v192h256v-192z" />
|
||||
<glyph unicode="" glyph-name="icon-paint-bucket" d="M544 736v-224c0-88.4-71.6-160-160-160s-160 71.6-160 160v97.2l-197.4-196.4c-50-50-12.4-215.2 112.4-340s290-162.4 340-112.4l417 423.6-352 352zM896-64c70.6 0 128 57.4 128 128 0 108.6-128 192-128 192s-128-83.4-128-192c0-70.6 57.4-128 128-128zM384 448c-35.4 0-64 28.6-64 64v384c0 35.4 28.6 64 64 64s64-28.6 64-64v-384c0-35.4-28.6-64-64-64z" />
|
||||
<glyph unicode="" glyph-name="icon-x-in-circle" d="M512 960c-282.8 0-512-229.2-512-512s229.2-512 512-512 512 229.2 512 512-229.2 512-512 512zM832 256l-128-128-192 192-192-192-128 128 192 192-192 192 128 128 192-192 192 192 128-128-192-192 192-192z" />
|
||||
@ -94,8 +94,11 @@
|
||||
<glyph unicode="" glyph-name="icon-collapse-pane-right" d="M768 960h256v-1024h-256c-105.6 0-192 86.4-192 192v640c0 105.6 86.4 192 192 192zM512 640l-512-320v640z" />
|
||||
<glyph unicode="" glyph-name="icon-eye-open" d="M512 896c-261 0-480.6-195.4-512-448 31.4-252.6 251-448 512-448s480.6 195.4 512 448c-31.4 252.6-251 448-512 448zM768.2 225.4c-71.4-62.8-162.8-97.4-257.6-97.4s-186.2 34.6-257.6 97.4c-66.6 58.6-110.6 137.2-125 222.6 0 0 0 0.2 0 0.2 76.8 154 220.8 257.6 384 257.6s307.2-103.8 384-257.6c0 0 0-0.2 0-0.2-14.4-85.4-61.2-164-127.8-222.6zM512 672c-123.8 0-224-100.2-224-224s100.2-224 224-224 224 100.2 224 224-100.2 224-224 224z" />
|
||||
<glyph unicode="" glyph-name="icon-eye-open-no-gleam" d="M512 896c-261 0-480.6-195.4-512-448 31.4-252.6 251-448 512-448s480.6 195.4 512 448c-31.4 252.6-251 448-512 448zM768.2 225.4c-71.4-62.8-162.8-97.4-257.6-97.4s-186.2 34.6-257.6 97.4c-66.6 58.6-110.6 137.2-125 222.6 0 0 0 0.2 0 0.2 76.8 154 220.8 257.6 384 257.6s307.2-103.8 384-257.6c0 0 0-0.2 0-0.2-14.4-85.4-61.2-164-127.8-222.6zM512 672c-123.8 0-224-100.2-224-224s100.2-224 224-224 224 100.2 224 224-100.2 224-224 224zM576 416c-53 0-96 43-96 96s43 96 96 96 96-43 96-96c0-53-43-96-96-96z" />
|
||||
<glyph unicode="" glyph-name="icon-topic" d="M546.4 528.8l32 24c31.6 23.8 91.6 23.8 123.2 0l32-24c10.8-8 22.2-15.2 34.4-21.4v201.2c-38 19.6-82.2 30-128 30-60.4 0-118.2-18.2-162.4-51.4l-32-24c-31.6-23.8-91.6-23.8-123.2 0l-32 24c-10.8 8-22.2 15.2-34.4 21.4v-201.2c38-19.6 82.2-30 128-30 60.4 0 118.2 18.2 162.4 51.4zM640 418.6c-60.4 0-118.2-18.2-162.4-51.4l-32-24c-31.6-23.8-91.6-23.8-123.2 0l-32 24c-10.8 8-22.2 15.2-34.4 21.4v-201.2c38-19.6 82.2-30 128-30 60.4 0 118.2 18.2 162.4 51.4l32 24c31.6 23.8 91.6 23.8 123.2 0l32-24c10.8-8 22.2-15.2 34.4-21.4v201.2c-38 19.6-82.2 30-128 30zM832 960h-128v-192h127.6c0.2 0 0.2-0.2 0.4-0.4v-639.4c0-0.2-0.2-0.2-0.4-0.4h-127.6v-192h128c105.6 0 192 86.4 192 192v640.2c0 105.6-86.4 192-192 192zM320 128h-127.6c-0.2 0-0.2 0.2-0.4 0.4v639.4c0 0.2 0.2 0.2 0.4 0.4h127.6v191.8h-128c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h128v192z" />
|
||||
<glyph unicode="" glyph-name="icon-session" d="M923 521.8l-151 100.6c-36 24-103.8 24-139.8 0l-151-100.6c-44.6-29.8-102.6-46.2-163-46.2s-118.4 16.4-163 46.2l-151.4 100.6c-1.8 1.2-3.8 2.4-5.8 3.6v-208c36.6-7.4 70.6-20.8 99-39.8l151-100.6c36-24 103.8-24 139.8 0l151 100.6c44.6 29.8 102.6 46.2 163 46.2s118.4-16.4 163-46.2l151-100.6c1.8-1.2 3.8-2.4 5.8-3.6v208c-36.2 7.2-70.2 20.8-98.6 39.8zM923 137.8l-151 100.6c-36 24-103.8 24-139.8 0l-151-100.6c-44.6-29.8-102.6-46.2-163-46.2s-118.4 16.4-163 46.2l-151.4 100.6c-1.8 1.2-3.8 2.4-5.8 3.6v-112c0-105.6 86.4-192 192-192h640c94.8 0 174.2 69.8 189.4 160.4-35.6 7.4-68.6 20.8-96.4 39.4zM97 762.2l151-100.6c36-24 103.8-24 139.8 0l151 100.6c44.8 29.8 102.6 46.2 163.2 46.2s118.4-16.4 163-46.2l151-100.6c1.8-1.2 3.8-2.4 5.8-3.6v112c0 105.6-86.4 192-192 192h-639.8c-94.8 0-174.2-69.8-189.4-160.4 35.6-7.4 68.6-20.8 96.4-39.4z" />
|
||||
<glyph unicode="" glyph-name="icon-topic" d="M454.36 483.36l86.3 86.3c9.088 8.965 21.577 14.502 35.36 14.502s26.272-5.537 35.366-14.507l86.294-86.294c19.328-19.358 42.832-34.541 69.047-44.082l1.313 171.722-57.64 57.64c-34.407 34.33-81.9 55.558-134.35 55.558s-99.943-21.228-134.354-55.562l-86.296-86.297c-9.088-8.965-21.577-14.502-35.36-14.502s-26.272 5.537-35.366 14.507l-28.674 28.654v-172.14c19.045-7.022 41.040-11.084 63.984-11.084 52.463 0 99.966 21.239 134.379 55.587zM505.64 412.64l-86.3-86.3c-9.088-8.965-21.577-14.502-35.36-14.502s-26.272 5.537-35.366 14.507l-86.294 86.294c-2 2-4.2 4-6.36 6v-197.36c33.664-30.72 78.65-49.537 128.031-49.537 52.44 0 99.923 21.22 134.333 55.541l86.296 86.296c9.088 8.965 21.577 14.502 35.36 14.502s26.272-5.537 35.366-14.507l86.294-86.294c2-2 4.2-4 6.36-6v197.36c-33.664 30.72-78.65 49.537-128.031 49.537-52.44 0-99.923-21.22-134.333-55.541zM832 960h-128v-192h127.66l0.34-0.34v-639.32l-0.34-0.34h-127.66v-192h128c105.6 0 192 86.4 192 192v640c0 105.6-86.4 192-192 192zM320 128h-127.66l-0.34 0.34v639.32l0.34 0.34h127.66v192h-128c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h128v192z" />
|
||||
<glyph unicode="" glyph-name="icon-session" d="M635.6 435.6c6.6-4.2 13.2-8.6 19.2-13.6l120.4-96.4c29.6-23.8 83.8-23.8 113.4 0l135.2 108c0.2 4.8 0.2 9.4 0.2 14.2 0 52.2-7.8 102.4-22.2 149.8l-154.8-123.6c-58.2-46.6-140.2-59.2-211.4-38.4zM248.6 325.8l120.4 96.4c58 46.4 140 59.2 211.2 38.4-6.6 4.2-13.2 8.6-19.2 13.6l-120.4 96.4c-29.6 23.8-83.8 23.8-113.4 0l-120.2-96.6c-40-32-91.4-48-143-48-21.6 0-43 2.8-63.8 8.4 0-0.6 0-1.2 0-1.6 5-3.4 10-6.8 14.6-10.6l120.4-96.4c29.8-23.8 83.8-23.8 113.4 0zM120.6 581.8l120.4 96.4c80.2 64.2 205.6 64.2 285.8 0l120.4-96.4c29.6-23.8 83.8-23.8 113.4 0l181 144.8c-91.2 140.4-249.6 233.4-429.6 233.4-238.6 0-439.2-163.2-496-384.2 30.8-17.6 77.8-15.6 104.6 6zM689 218l-120.4 96.4c-29.6 23.8-83.8 23.8-113.4 0l-120.2-96.4c-40-32-91.4-48-143-48-47.8 0-95.4 13.8-134.2 41.4 85.6-163.6 256.8-275.4 454.2-275.4s368.6 111.8 454.2 275.4c-80.4-57.4-199.8-55.2-277.2 6.6z" />
|
||||
<glyph unicode="" glyph-name="icon-bullet" d="M832 208c0-44-36-80-80-80h-480c-44 0-80 36-80 80v480c0 44 36 80 80 80h480c44 0 80-36 80-80v-480z" />
|
||||
<glyph unicode="" glyph-name="icon-tabular-realtime" d="M896 960h-768c-70.606-0.215-127.785-57.394-128-127.979v-768.021c0.215-70.606 57.394-127.785 127.979-128h768.021c70.606 0.215 127.785 57.394 128 127.979v768.021c-0.215 70.606-57.394 127.785-127.979 128zM448 668l25.060-25.32c7.916-7.922 18.856-12.822 30.94-12.822s23.024 4.9 30.94 12.822l75.5 76.3c29.97 30.338 71.571 49.128 117.56 49.128s87.59-18.79 117.544-49.112l50.456-50.997v-152.2c-24.111 8.83-44.678 22.255-61.542 39.342l-75.518 76.318c-7.916 7.922-18.856 12.822-30.94 12.822s-23.024-4.9-30.94-12.822l-75.5-76.3c-29.971-30.343-71.575-49.137-117.568-49.137-20.084 0-39.331 3.584-57.137 10.146l1.145 151.831zM320 0h-192c-35.26 0.214-63.786 28.74-64 63.98v128.020h256v-192zM320 256h-256v192h256v-192zM320 512h-256v192h256v-192zM640 0h-256v192h256v-192zM448 323.38v174.5c1.88-1.74 3.74-3.5 5.56-5.34l75.5-76.3c7.916-7.922 18.856-12.822 30.94-12.822s23.024 4.9 30.94 12.822l75.5 76.3c29.966 30.333 71.56 49.119 117.542 49.119 43.28 0 82.673-16.644 112.128-43.879l-0.11-174.399c-1.88 1.74-3.74 3.5-5.56 5.34l-75.5 76.3c-7.916 7.922-18.856 12.822-30.94 12.822s-23.024-4.9-30.94-12.822l-75.5-76.3c-29.966-30.333-71.56-49.119-117.542-49.119-43.28 0-82.673 16.644-112.128 43.879zM960 64c-0.214-35.26-28.74-63.786-63.98-64h-192.020v192h256v-128z" />
|
||||
<glyph unicode="" glyph-name="icon-tabular-lad" d="M896 960h-768c-70.606-0.215-127.785-57.394-128-127.979v-768.021c0.215-70.606 57.394-127.785 127.979-128h768.021c70.606 0.215 127.785 57.394 128 127.979v768.021c-0.215 70.606-57.394 127.785-127.979 128zM64 704h256v-192h-256v192zM64 448h256v-192h-256v192zM128 0c-35.26 0.214-63.786 28.74-64 63.98v128.020h256v-192h-192zM384 0v192h256v-192h-256zM960 64c-0.214-35.26-28.74-63.786-63.98-64h-192.020v192h256v-128zM960 448v-192h-576v192h64v64h-64v192h576v-192h-64v-64h64zM782.32 412.62l-110.32 55.16v172.22c0 17.673-14.327 32-32 32s-32-14.327-32-32v-211.78l145.68-72.84c4.172-2.133 9.1-3.383 14.32-3.383 17.675 0 32.003 14.328 32.003 32.003 0 12.454-7.114 23.247-17.501 28.536z" />
|
||||
<glyph unicode="" glyph-name="icon-tabular-lad-set" d="M128 192v576c-70.606-0.215-127.785-57.394-128-127.979v-576.021c0.215-70.606 57.394-127.785 127.979-128h576.021c70.606 0.215 127.785 57.394 128 127.979l-576 0.021c-70.606 0.215-127.785 57.394-128 127.979zM896 960h-576c-70.606-0.215-127.785-57.394-128-127.979v-576.021c0.215-70.606 57.394-127.785 127.979-128h576.021c70.606 0.215 127.785 57.394 128 127.979v576.021c-0.215 70.606-57.394 127.785-127.979 128zM256 768h192v-128h-192v128zM256 576h192v-192h-192v192zM320 192c-35.26 0.214-63.786 28.74-64 63.98v64.020h192v-128h-128zM512 192v128h192v-128h-192zM960 256c-0.214-35.26-28.74-63.786-63.98-64h-128.020v128h192v-64zM960 384h-448v384h448v-384zM832 480c0.002 0 0.005 0 0.007 0 17.673 0 32 14.327 32 32 0 14.055-9.062 25.994-21.662 30.293l-74.345 24.767v104.94c0 17.673-14.327 32-32 32s-32-14.327-32-32v-151.060l117.88-39.3c3.018-1.040 6.495-1.64 10.113-1.64 0.003 0 0.005 0 0.008 0z" />
|
||||
<glyph unicode="" glyph-name="icon-x" d="M384 448l-365.332-365.332c-24.89-24.89-24.89-65.62 0-90.51l37.49-37.49c24.89-24.89 65.62-24.89 90.51 0 0 0 365.332 365.332 365.332 365.332l365.332-365.332c24.89-24.89 65.62-24.89 90.51 0l37.49 37.49c24.89 24.89 24.89 65.62 0 90.51l-365.332 365.332c0 0 365.332 365.332 365.332 365.332 24.89 24.89 24.89 65.62 0 90.51l-37.49 37.49c-24.89 24.89-65.62 24.89-90.51 0 0 0-365.332-365.332-365.332-365.332l-365.332 365.332c-24.89 24.89-65.62 24.89-90.51 0l-37.49-37.49c-24.89-24.89-24.89-65.62 0-90.51 0 0 365.332-365.332 365.332-365.332z" />
|
||||
</font></defs></svg>
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 35 KiB |
Binary file not shown.
Binary file not shown.
@ -98,6 +98,11 @@ $bubbleMaxW: 300px;
|
||||
$reqSymbolW: 15px;
|
||||
$reqSymbolM: $interiorMargin * 2;
|
||||
$reqSymbolFontSize: 0.7em;
|
||||
// Wait Spinner Defaults
|
||||
$waitSpinnerD: 32px;
|
||||
$waitSpinnerTreeD: 20px;
|
||||
$waitSpinnerBorderW: 5px;
|
||||
$waitSpinnerTreeBorderW: 4px;
|
||||
|
||||
/************************** CONTROLS */
|
||||
$controlDisabledOpacity: 0.3;
|
||||
|
@ -53,7 +53,6 @@ body, html {
|
||||
font-weight: 200;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
em {
|
||||
@ -85,6 +84,8 @@ p {
|
||||
margin-bottom: $interiorMarginLg;
|
||||
}
|
||||
|
||||
ol, ul { padding-left: 0; }
|
||||
|
||||
mct-container {
|
||||
display: block;
|
||||
}
|
||||
|
@ -61,9 +61,24 @@
|
||||
.l-inspector-part {
|
||||
box-sizing: border-box;
|
||||
padding-right: $interiorMargin;
|
||||
.form {
|
||||
.tree .form {
|
||||
margin-left: $treeVCW + $interiorMarginLg;
|
||||
margin-bottom: $interiorMarginLg;
|
||||
}
|
||||
.section-header {
|
||||
background: none;
|
||||
color: $colorInspectorPropName;
|
||||
border-radius: unset;
|
||||
font-size: inherit;
|
||||
padding: $interiorMarginSm 0;
|
||||
}
|
||||
|
||||
mct-form:not(:last-child) .form {
|
||||
border-bottom: 1px solid $colorInspectorSectionHeaderBg;
|
||||
}
|
||||
|
||||
.form {
|
||||
margin-bottom: $interiorMarginSm;
|
||||
padding-bottom: $interiorMarginLg;
|
||||
.form-section {
|
||||
margin-bottom: 0;
|
||||
&:not(.first) {
|
||||
@ -72,7 +87,14 @@
|
||||
.form-row {
|
||||
@include align-items(center);
|
||||
border: none;
|
||||
padding: 0;
|
||||
padding: $interiorMarginSm 0;
|
||||
.label {
|
||||
min-width: 80px;
|
||||
}
|
||||
input[type='text'],
|
||||
input[type='search'] {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,6 @@
|
||||
|
||||
/********************************* FORMS */
|
||||
@import "forms/elems";
|
||||
@import "forms/selects";
|
||||
@import "forms/channel-selector";
|
||||
@import "forms/datetime";
|
||||
@import "forms/validation";
|
||||
|
@ -35,15 +35,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
mct-representation {
|
||||
mct-representation,
|
||||
.rep-object-label {
|
||||
&.s-status-pending {
|
||||
.t-object-label {
|
||||
.t-item-icon {
|
||||
&:before {
|
||||
$spinBW: 4px;
|
||||
@include spinner($spinBW);
|
||||
@include spinner($waitSpinnerTreeBorderW, $colorLoadingFg);
|
||||
content: "";
|
||||
padding: 30%;
|
||||
height: $waitSpinnerTreeD; width: $waitSpinnerTreeD;
|
||||
}
|
||||
.t-item-icon-glyph {
|
||||
display: none;
|
||||
@ -57,7 +57,10 @@ mct-representation {
|
||||
}
|
||||
}
|
||||
|
||||
.selected mct-representation.s-status-pending .t-object-label .t-item-icon:before {
|
||||
border-color: rgba($colorItemTreeSelectedFg, 0.25) !important;
|
||||
border-top-color: rgba($colorItemTreeSelectedFg, 1.0) !important;
|
||||
.selected mct-representation,
|
||||
.selected .rep-object-label {
|
||||
.s-status-pending .t-object-label .t-item-icon:before {
|
||||
border-color: rgba($colorItemTreeSelectedFg, 0.25) !important;
|
||||
border-top-color: rgba($colorItemTreeSelectedFg, 1.0) !important;
|
||||
}
|
||||
}
|
@ -74,6 +74,12 @@
|
||||
|
||||
.l-composite-control {
|
||||
vertical-align: middle;
|
||||
&:not(.l-inline) {
|
||||
margin-bottom: $interiorMargin;
|
||||
}
|
||||
&.l-inline {
|
||||
display: inline-block;
|
||||
}
|
||||
&.l-checkbox {
|
||||
.composite-control-label {
|
||||
line-height: 18px;
|
||||
@ -108,12 +114,14 @@
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
|
||||
/******************************************************** CUSTOM CHECKBOXES */
|
||||
label.checkbox.custom,
|
||||
label.radio.custom {
|
||||
$bg: pullForward($colorBodyBg, 10%);
|
||||
$d: $formRowCtrlsH;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
line-height: 120%;
|
||||
margin-right: $interiorMargin * 4;
|
||||
padding-left: $d + $interiorMargin;
|
||||
position: relative;
|
||||
@ -161,7 +169,40 @@ label.radio.custom {
|
||||
label.checkbox.custom input:checked ~ em:before { content: "\32"; }
|
||||
label.radio.custom input:checked ~ em:before { content: "\e619"; }
|
||||
|
||||
.s-menu-btn label.checkbox.custom {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.item .checkbox {
|
||||
&.checked label {
|
||||
box-shadow: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
label.form-control.checkbox {
|
||||
input {
|
||||
margin-right: $interiorMargin;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************** INPUTS */
|
||||
input[type="text"],
|
||||
input[type="search"] {
|
||||
@include nice-input();
|
||||
&.numeric {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.l-input-lg input[type="text"] { width: 100% !important; }
|
||||
.l-input-med input[type="text"] { width: 200px !important; }
|
||||
.l-input-sm input[type="text"] { width: 50px !important; }
|
||||
.l-numeric input[type="text"] { text-align: right; }
|
||||
|
||||
.input-labeled {
|
||||
// Used in toolbar
|
||||
margin-left: $interiorMargin;
|
||||
label {
|
||||
display: inline-block;
|
||||
@ -175,28 +216,36 @@ label.radio.custom input:checked ~ em:before { content: "\e619"; }
|
||||
}
|
||||
}
|
||||
|
||||
.s-menu-btn label.checkbox.custom {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.item .checkbox {
|
||||
&.checked label {
|
||||
box-shadow: none;
|
||||
border-bottom: none;
|
||||
/******************************************************** SELECTS */
|
||||
.select {
|
||||
@include btnSubtle($colorSelectBg);
|
||||
@if $shdwBtns != none {
|
||||
margin: 0 0 2px 0; // Needed to avoid dropshadow from being clipped by parent containers
|
||||
}
|
||||
}
|
||||
|
||||
.context-available,
|
||||
.s-icon-btn {
|
||||
$c: $colorKey;
|
||||
color: $c;
|
||||
&:hover {
|
||||
color: lighten($c, 10%);
|
||||
padding: 0 $interiorMargin;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
line-height: $formInputH;
|
||||
select {
|
||||
@include appearance(none);
|
||||
box-sizing: border-box;
|
||||
background: none;
|
||||
color: $colorSelectFg;
|
||||
cursor: pointer;
|
||||
border: none !important;
|
||||
padding: 4px 25px 2px 0px;
|
||||
width: 130%;
|
||||
option {
|
||||
margin: $interiorMargin 0; // Firefox
|
||||
}
|
||||
}
|
||||
&:after {
|
||||
@include contextArrow();
|
||||
pointer-events: none;
|
||||
color: rgba($colorSelectFg, percentToDecimal($contrastInvokeMenuPercent));
|
||||
position: absolute;
|
||||
right: $interiorMargin; top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.view-switcher {
|
||||
@include trans-prop-nice-fade($controlFadeMs);
|
||||
}
|
||||
|
||||
/******************************************************** OBJECT-HEADER */
|
||||
@ -330,7 +379,6 @@ body.desktop .object-header {
|
||||
}
|
||||
|
||||
/******************************************************** SLIDERS */
|
||||
|
||||
.slider {
|
||||
$knobH: 100%;
|
||||
.slot {
|
||||
@ -424,7 +472,7 @@ body.desktop .object-header {
|
||||
border-top: 1px solid $colorInteriorBorder
|
||||
}
|
||||
.l-time-selects {
|
||||
line-height: $formInputH;
|
||||
line-height: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
@ -478,11 +526,31 @@ body.desktop .object-header {
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************** BROWSER ELEMENTS */
|
||||
/******************************************************** TEXTAREA */
|
||||
textarea {
|
||||
@include nice-textarea($colorInputBg, $colorInputFg);
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/******************************************************** MISC */
|
||||
.context-available,
|
||||
.s-icon-btn {
|
||||
$c: $colorKey;
|
||||
color: $c;
|
||||
&:hover {
|
||||
color: lighten($c, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
.view-switcher {
|
||||
@include trans-prop-nice-fade($controlFadeMs);
|
||||
}
|
||||
|
||||
/******************************************************** BROWSER ELEMENTS */
|
||||
body.desktop {
|
||||
::-webkit-scrollbar {
|
||||
border-radius: 2px;
|
||||
box-sizing: border-box;
|
||||
box-shadow: inset $scrollbarTrackShdw;
|
||||
background-color: $scrollbarTrackColorBg;
|
||||
@ -491,15 +559,15 @@ body.desktop {
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
$bg: $scrollbarThumbColor;
|
||||
$hc: $scrollbarThumbColorHov;
|
||||
$gr: 5%;
|
||||
@include background-image(linear-gradient(lighten($bg, $gr), $bg 20px));
|
||||
border-radius: 2px;
|
||||
box-sizing: border-box;
|
||||
&:hover {
|
||||
@include background-image(linear-gradient(lighten($hc, $gr), $hc 20px));
|
||||
}
|
||||
background: $scrollbarThumbColor;
|
||||
&:hover { background: $scrollbarThumbColorHov; }
|
||||
}
|
||||
|
||||
.overlay ::-webkit-scrollbar-thumb {
|
||||
$lr: 15%;
|
||||
background: $scrollbarThumbColorOverlay;
|
||||
&:hover { background: $scrollbarThumbColorOverlayHov; }
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-corner {
|
||||
|
@ -51,9 +51,6 @@
|
||||
.title-label {
|
||||
font-size: 1rem;
|
||||
}
|
||||
//&:after {
|
||||
// color: rgba($colorInvokeMenu, 0.5);
|
||||
//}
|
||||
}
|
||||
|
||||
.menu {
|
||||
@ -113,12 +110,13 @@
|
||||
|
||||
.menu,
|
||||
.context-menu,
|
||||
.super-menu {
|
||||
.super-menu,
|
||||
.s-menu-btn .menu {
|
||||
pointer-events: auto;
|
||||
ul li {
|
||||
//padding-left: 25px;
|
||||
a {
|
||||
color: $colorMenuFg;
|
||||
display: block;
|
||||
}
|
||||
.icon {
|
||||
color: $colorMenuIc;
|
||||
@ -126,9 +124,6 @@
|
||||
.type-icon {
|
||||
left: $interiorMargin;
|
||||
}
|
||||
&:hover .icon {
|
||||
//color: lighten($colorMenuIc, 5%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,7 +141,7 @@
|
||||
height: $d;
|
||||
width: $d;
|
||||
&:before {
|
||||
font-size: 7px !important;// $d/2;
|
||||
font-size: 7px !important;
|
||||
height: $d;
|
||||
width: $d;
|
||||
line-height: $d;
|
||||
@ -173,7 +168,6 @@
|
||||
.pane {
|
||||
box-sizing: border-box;
|
||||
&.left {
|
||||
//@include test();
|
||||
border-right: 1px solid pullForward($colorMenuBg, 10%);
|
||||
left: 0;
|
||||
padding-right: $interiorMargin;
|
||||
@ -190,7 +184,6 @@
|
||||
}
|
||||
}
|
||||
&.right {
|
||||
//@include test(red);
|
||||
left: auto;
|
||||
right: 0;
|
||||
padding: $interiorMargin * 5;
|
||||
@ -216,7 +209,6 @@
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
&.description {
|
||||
//color: lighten($colorMenuBg, 30%);
|
||||
color: $colorCreateMenuText;
|
||||
font-size: 0.8em;
|
||||
line-height: 1.5em;
|
||||
@ -258,4 +250,4 @@
|
||||
left: auto;
|
||||
right: 0;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
@ -20,13 +20,7 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
.section-header {
|
||||
border-radius: $basicCr;
|
||||
background: $colorFormSectionHeader;
|
||||
$c: lighten($colorBodyFg, 20%);
|
||||
color: $c;
|
||||
font-size: 0.8em;
|
||||
padding: $formTBPad $formLRPad;
|
||||
text-transform: uppercase;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.form {
|
||||
@ -37,12 +31,20 @@
|
||||
margin-bottom: $interiorMarginLg * 2;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
border-radius: $basicCr;
|
||||
background: $colorFormSectionHeader;
|
||||
$c: lighten($colorBodyFg, 20%);
|
||||
color: $c;
|
||||
font-size: 0.8em;
|
||||
padding: $formTBPad $formLRPad;
|
||||
}
|
||||
|
||||
.form-row {
|
||||
$m: $interiorMargin;
|
||||
box-sizing: border-box;
|
||||
@include clearfix;
|
||||
border-top: 1px solid $colorFormLines;
|
||||
margin-top: $m;
|
||||
padding: $formTBPad 0;
|
||||
position: relative;
|
||||
&.first {
|
||||
@ -52,10 +54,7 @@
|
||||
>.label,
|
||||
>.controls {
|
||||
box-sizing: border-box;
|
||||
@include clearfix;
|
||||
font-size: 0.8rem;
|
||||
line-height: $formInputH;
|
||||
min-height: $formInputH;
|
||||
}
|
||||
|
||||
>.label {
|
||||
@ -83,27 +82,12 @@
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.l-med input[type="text"] {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.l-small input[type="text"] {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.l-numeric input[type="text"] {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.select {
|
||||
margin-right: $interiorMargin;
|
||||
}
|
||||
}
|
||||
|
||||
.field-hints {
|
||||
color: darken($colorBodyFg, 20%);
|
||||
}
|
||||
.hint, .field-hints { color: $colorFieldHint; }
|
||||
|
||||
.selector-list {
|
||||
// Used in create overlay to display tree view
|
||||
@ -124,25 +108,31 @@
|
||||
}
|
||||
}
|
||||
|
||||
.l-controls-first {
|
||||
.form .form-row {
|
||||
margin-top: $interiorMarginSm;
|
||||
>.label,
|
||||
>.controls {
|
||||
line-height: inherit;
|
||||
min-height: inherit;;
|
||||
}
|
||||
>.label {
|
||||
@include flex(1 1 auto);
|
||||
min-width: 0;
|
||||
width: auto;
|
||||
order: 2;
|
||||
}
|
||||
>.controls {
|
||||
@include flex(0 0 auto);
|
||||
margin-right: $interiorMargin;
|
||||
order: 1;
|
||||
}
|
||||
.l-controls-first .form .form-row,
|
||||
.form .form-row.l-controls-first {
|
||||
>.label,
|
||||
>.controls {
|
||||
line-height: inherit;
|
||||
min-height: inherit;;
|
||||
}
|
||||
>.label {
|
||||
@include flex(1 1 auto);
|
||||
min-width: 0;
|
||||
width: auto;
|
||||
order: 2;
|
||||
}
|
||||
>.controls {
|
||||
@include flex(0 0 auto);
|
||||
margin-right: $interiorMargin;
|
||||
order: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.l-controls-under.l-flex-row {
|
||||
// Change to use column layout
|
||||
@include flex-direction(column);
|
||||
.flex-elem {
|
||||
margin-bottom: $interiorMarginLg;
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,13 +145,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
label.form-control.checkbox {
|
||||
input {
|
||||
margin-right: $interiorMargin;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
.hint,
|
||||
.s-hint {
|
||||
font-size: 0.9em;
|
||||
@ -181,19 +164,4 @@ label.form-control.checkbox {
|
||||
color: lighten($colorFormInvalid, 30%);
|
||||
padding: $interiorMargin;
|
||||
}
|
||||
}
|
||||
|
||||
input[type="text"],
|
||||
input[type="search"] {
|
||||
@include nice-input();
|
||||
&.numeric {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
textarea {
|
||||
@include nice-textarea($colorInputBg, $colorInputFg);
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
@ -23,9 +23,13 @@
|
||||
> .label {
|
||||
padding-right: $reqSymbolM; // Keep room for validation element
|
||||
&::after {
|
||||
float: right;
|
||||
position: absolute;
|
||||
right: $interiorMargin;
|
||||
font-family: symbolsfont;
|
||||
font-size: $reqSymbolFontSize;
|
||||
height: 100%;
|
||||
line-height: 200%;
|
||||
|
||||
}
|
||||
}
|
||||
&.invalid,
|
||||
|
@ -28,7 +28,7 @@
|
||||
100% { @include transform(translate(-50%, -50%) rotate(360deg)); }
|
||||
}
|
||||
|
||||
@mixin spinner($b: 5px, $c: $colorKey) {
|
||||
@mixin spinner($b: 5px, $c: $colorKey) {
|
||||
@include transform-origin(center);
|
||||
@include animation-name(rotation-centered);
|
||||
@include animation-duration(0.5s);
|
||||
@ -46,10 +46,7 @@
|
||||
}
|
||||
|
||||
.wait-spinner {
|
||||
$d: 5%;
|
||||
@include spinner(0.5em, $colorKey);
|
||||
height: auto; width: auto;
|
||||
padding: $d; // Will size object based on parent container WIDTH
|
||||
@include spinner($waitSpinnerBorderW, $colorKey);
|
||||
pointer-events: none;
|
||||
z-index: 2;
|
||||
&.inline {
|
||||
@ -60,15 +57,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.treeview .wait-spinner {
|
||||
// Only used in subtree.html, which I don't think this is actually being used
|
||||
$d: 10px;
|
||||
height: $d; width: $d;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
top: 2px; left: 0;
|
||||
}
|
||||
|
||||
.loading {
|
||||
// Can be applied to any block element with height and width
|
||||
pointer-events: none;
|
||||
@ -77,8 +65,8 @@
|
||||
content: '';
|
||||
}
|
||||
&:before {
|
||||
@include spinner(5px, $colorLoadingFg);
|
||||
padding: 5%;
|
||||
@include spinner($waitSpinnerBorderW, $colorLoadingFg);
|
||||
height: $waitSpinnerD; width: $waitSpinnerD;
|
||||
z-index: 10;
|
||||
}
|
||||
&:after {
|
||||
@ -87,8 +75,22 @@
|
||||
display: block;
|
||||
z-index: 9;
|
||||
}
|
||||
&.tree-item:before {
|
||||
padding: $menuLineH / 4;
|
||||
border-width: 2px;
|
||||
&.tree-item.t-wait-node {
|
||||
$d: $waitSpinnerTreeD;
|
||||
$spinnerL: $treeVCW + $interiorMargin + 3px + $d/2;
|
||||
padding-left: $spinnerL + $d/2 + $interiorMargin;
|
||||
.t-title-label {
|
||||
font-style: italic;
|
||||
opacity: 0.6;
|
||||
}
|
||||
&:before {
|
||||
height: $d;
|
||||
width: $d;
|
||||
border-width: 4px;
|
||||
left: $spinnerL;
|
||||
}
|
||||
&:after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,6 @@
|
||||
z-index: 100;
|
||||
}
|
||||
> .holder {
|
||||
//$i: 15%;
|
||||
@include containerSubtle($colorOvrBg, $colorOvrFg);
|
||||
border-radius: $basicCr * 3;
|
||||
color: $colorOvrFg;
|
||||
@ -57,15 +56,8 @@
|
||||
right: $m;
|
||||
bottom: $m;
|
||||
left: $m;
|
||||
|
||||
//.top-bar,
|
||||
//.editor,
|
||||
//.bottom-bar {
|
||||
// @include absPosDefault();
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
@include ellipsize();
|
||||
font-size: 1.2em;
|
||||
@ -73,9 +65,7 @@
|
||||
margin-bottom: $interiorMargin;
|
||||
}
|
||||
|
||||
.hint {
|
||||
color: pushBack($colorOvrFg, 20%);
|
||||
}
|
||||
.hint, .field-hints { color: $colorFieldHintOverlay !important; }
|
||||
|
||||
.abs.top-bar {
|
||||
height: $ovrTopBarH;
|
||||
@ -88,7 +78,7 @@
|
||||
left: 0;
|
||||
right: 0;
|
||||
overflow: auto;
|
||||
.field.l-med {
|
||||
.field.l-input-med {
|
||||
input[type='text'] {
|
||||
width: 100%;
|
||||
}
|
||||
@ -120,7 +110,6 @@
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow: visible;
|
||||
//font-size: 1em;
|
||||
height: $ovrFooterH;
|
||||
}
|
||||
|
||||
@ -132,11 +121,14 @@
|
||||
margin: .5em 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.select {
|
||||
box-shadow: $shdwBtnsOverlay;
|
||||
}
|
||||
}
|
||||
|
||||
.t-dialog-sm .overlay > .holder {
|
||||
// Used for blocker and in-progress dialogs, modal alerts, etc.
|
||||
//@include test(red);
|
||||
$h: 225px;
|
||||
min-height: $h;
|
||||
height: $h;
|
||||
|
@ -26,6 +26,10 @@
|
||||
top: $m; right: $m * 1.25; bottom: $m; left: $m * 1.25;
|
||||
}
|
||||
|
||||
body, html {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.l-splash-holder {
|
||||
// Main outer holder.
|
||||
@include transition-property(opacity);
|
||||
|
@ -40,7 +40,7 @@
|
||||
<mct-representation
|
||||
key="'edit-elements'"
|
||||
mct-object="domainObject"
|
||||
class="flex-elem holder grows vscroll current-elements">
|
||||
class="flex-elem l-flex-col holder grows current-elements">
|
||||
</mct-representation>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -19,18 +19,6 @@
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<ul class="tree">
|
||||
<li ng-if="!composition">
|
||||
<span class="tree-item">
|
||||
<span class="icon wait-spinner"></span>
|
||||
<span class="title-label">Loading...</span>
|
||||
</span>
|
||||
</li>
|
||||
<li ng-repeat="child in composition">
|
||||
<mct-representation key="'tree-node'"
|
||||
mct-object="child"
|
||||
parameters="parameters"
|
||||
ng-model="ngModel">
|
||||
</mct-representation>
|
||||
</li>
|
||||
</ul>
|
||||
<mct-tree mct-object="domainObject" mct-model="ngModel.selectedObject">
|
||||
</mct-tree>
|
||||
|
||||
|
4
platform/commonUI/general/res/templates/tree/node.html
Normal file
4
platform/commonUI/general/res/templates/tree/node.html
Normal file
@ -0,0 +1,4 @@
|
||||
<span class="tree-item menus-to-left">
|
||||
</span>
|
||||
<span class="tree-item-subtree">
|
||||
</span>
|
2
platform/commonUI/general/res/templates/tree/toggle.html
Normal file
2
platform/commonUI/general/res/templates/tree/toggle.html
Normal file
@ -0,0 +1,2 @@
|
||||
<span class='ui-symbol view-control flex-elem'>
|
||||
</span>
|
@ -0,0 +1,8 @@
|
||||
<span class="rep-object-label">
|
||||
<div class="t-object-label l-flex-row flex-elem grows">
|
||||
<div class="t-item-icon flex-elem">
|
||||
<div class="t-item-icon-glyph"></div>
|
||||
</div>
|
||||
<div class='t-title-label flex-elem grows'></div>
|
||||
</div>
|
||||
</span>
|
@ -19,11 +19,6 @@
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<div class="w1">
|
||||
<div class="w2"
|
||||
ng-controller="RTEventListController as rtevent">
|
||||
<mct-rt-data-table headers="rtevent.headers()" rows="rtevent.rows()" ascending-scroll="true"></mct-rt-data-table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<li class='tree-item t-wait-node loading'>
|
||||
<span class="t-title-label">Loading...</span>
|
||||
</li>
|
@ -21,42 +21,33 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
"./src/ScrollingListController",
|
||||
"text!./res/templates/scrolling.html",
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
ScrollingListController,
|
||||
scrollingTemplate,
|
||||
legacyRegistry
|
||||
) {
|
||||
'angular',
|
||||
'../ui/TreeView'
|
||||
], function (angular, TreeView) {
|
||||
function MCTTree($parse, gestureService) {
|
||||
function link(scope, element, attrs) {
|
||||
var treeView = new TreeView(gestureService),
|
||||
expr = $parse(attrs.mctModel),
|
||||
unobserve = treeView.observe(function (domainObject) {
|
||||
if (domainObject !== expr(scope.$parent)) {
|
||||
expr.assign(scope.$parent, domainObject);
|
||||
scope.$apply();
|
||||
}
|
||||
});
|
||||
|
||||
legacyRegistry.register("platform/features/scrolling", {
|
||||
"name": "Scrolling Lists",
|
||||
"description": "Time-ordered list of latest data.",
|
||||
"extensions": {
|
||||
"views": [
|
||||
{
|
||||
"key": "scrolling",
|
||||
"name": "Scrolling",
|
||||
"glyph": "5",
|
||||
"description": "Scrolling list of data values.",
|
||||
"template": scrollingTemplate,
|
||||
"needs": [
|
||||
"telemetry"
|
||||
],
|
||||
"delegation": true
|
||||
}
|
||||
],
|
||||
"controllers": [
|
||||
{
|
||||
"key": "ScrollingListController",
|
||||
"implementation": ScrollingListController,
|
||||
"depends": [
|
||||
"$scope",
|
||||
"telemetryFormatter"
|
||||
]
|
||||
}
|
||||
]
|
||||
element.append(angular.element(treeView.elements()));
|
||||
|
||||
scope.$parent.$watch(attrs.mctModel, treeView.value.bind(treeView));
|
||||
scope.$watch('mctObject', treeView.model.bind(treeView));
|
||||
scope.$on('$destroy', unobserve);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
restrict: "E",
|
||||
link: link,
|
||||
scope: { mctObject: "=" }
|
||||
};
|
||||
}
|
||||
|
||||
return MCTTree;
|
||||
});
|
64
platform/commonUI/general/src/ui/ToggleView.js
Normal file
64
platform/commonUI/general/src/ui/ToggleView.js
Normal file
@ -0,0 +1,64 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
'zepto',
|
||||
'text!../../res/templates/tree/toggle.html'
|
||||
], function ($, toggleTemplate) {
|
||||
function ToggleView(state) {
|
||||
this.expanded = !!state;
|
||||
this.callbacks = [];
|
||||
this.el = $(toggleTemplate);
|
||||
this.el.on('click', function () {
|
||||
this.value(!this.expanded);
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
ToggleView.prototype.value = function (state) {
|
||||
this.expanded = state;
|
||||
|
||||
if (state) {
|
||||
this.el.addClass('expanded');
|
||||
} else {
|
||||
this.el.removeClass('expanded');
|
||||
}
|
||||
|
||||
this.callbacks.forEach(function (callback) {
|
||||
callback(state);
|
||||
});
|
||||
};
|
||||
|
||||
ToggleView.prototype.observe = function (callback) {
|
||||
this.callbacks.push(callback);
|
||||
return function () {
|
||||
this.callbacks = this.callbacks.filter(function (c) {
|
||||
return c !== callback;
|
||||
});
|
||||
}.bind(this);
|
||||
};
|
||||
|
||||
ToggleView.prototype.elements = function () {
|
||||
return this.el;
|
||||
};
|
||||
|
||||
return ToggleView;
|
||||
});
|
90
platform/commonUI/general/src/ui/TreeLabelView.js
Normal file
90
platform/commonUI/general/src/ui/TreeLabelView.js
Normal file
@ -0,0 +1,90 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
'zepto',
|
||||
'text!../../res/templates/tree/tree-label.html'
|
||||
], function ($, labelTemplate) {
|
||||
'use strict';
|
||||
|
||||
function TreeLabelView(gestureService) {
|
||||
this.el = $(labelTemplate);
|
||||
this.gestureService = gestureService;
|
||||
}
|
||||
|
||||
function getGlyph(domainObject) {
|
||||
var type = domainObject.getCapability('type');
|
||||
return type.getGlyph();
|
||||
}
|
||||
|
||||
function isLink(domainObject) {
|
||||
var location = domainObject.getCapability('location');
|
||||
return location.isLink();
|
||||
}
|
||||
|
||||
TreeLabelView.prototype.updateView = function (domainObject) {
|
||||
var titleEl = this.el.find('.t-title-label'),
|
||||
glyphEl = this.el.find('.t-item-icon-glyph'),
|
||||
iconEl = this.el.find('.t-item-icon');
|
||||
|
||||
titleEl.text(domainObject ? domainObject.getModel().name : "");
|
||||
glyphEl.text(domainObject ? getGlyph(domainObject) : "");
|
||||
|
||||
if (domainObject && isLink(domainObject)) {
|
||||
iconEl.addClass('l-icon-link');
|
||||
} else {
|
||||
iconEl.removeClass('l-icon-link');
|
||||
}
|
||||
};
|
||||
|
||||
TreeLabelView.prototype.model = function (domainObject) {
|
||||
if (this.unlisten) {
|
||||
this.unlisten();
|
||||
delete this.unlisten;
|
||||
}
|
||||
|
||||
if (this.activeGestures) {
|
||||
this.activeGestures.destroy();
|
||||
delete this.activeGestures;
|
||||
}
|
||||
|
||||
this.updateView(domainObject);
|
||||
|
||||
if (domainObject) {
|
||||
this.unlisten = domainObject.getCapability('mutation')
|
||||
.listen(this.updateView.bind(this, domainObject));
|
||||
|
||||
this.activeGestures = this.gestureService.attachGestures(
|
||||
this.elements(),
|
||||
domainObject,
|
||||
[ 'info', 'menu', 'drag' ]
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
TreeLabelView.prototype.elements = function () {
|
||||
return this.el;
|
||||
};
|
||||
|
||||
return TreeLabelView;
|
||||
});
|
157
platform/commonUI/general/src/ui/TreeNodeView.js
Normal file
157
platform/commonUI/general/src/ui/TreeNodeView.js
Normal file
@ -0,0 +1,157 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
'zepto',
|
||||
'text!../../res/templates/tree/node.html',
|
||||
'./ToggleView',
|
||||
'./TreeLabelView'
|
||||
], function ($, nodeTemplate, ToggleView, TreeLabelView) {
|
||||
'use strict';
|
||||
|
||||
function TreeNodeView(gestureService, subtreeFactory, selectFn) {
|
||||
this.li = $('<li>');
|
||||
|
||||
this.statusClasses = [];
|
||||
|
||||
this.toggleView = new ToggleView(false);
|
||||
this.toggleView.observe(function (state) {
|
||||
if (state) {
|
||||
if (!this.subtreeView) {
|
||||
this.subtreeView = subtreeFactory();
|
||||
this.subtreeView.model(this.activeObject);
|
||||
this.li.find('.tree-item-subtree').eq(0)
|
||||
.append($(this.subtreeView.elements()));
|
||||
}
|
||||
$(this.subtreeView.elements()).removeClass('hidden');
|
||||
} else if (this.subtreeView) {
|
||||
$(this.subtreeView.elements()).addClass('hidden');
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
this.labelView = new TreeLabelView(gestureService);
|
||||
|
||||
$(this.labelView.elements()).on('click', function () {
|
||||
selectFn(this.activeObject);
|
||||
}.bind(this));
|
||||
|
||||
this.li.append($(nodeTemplate));
|
||||
this.li.find('span').eq(0)
|
||||
.append($(this.toggleView.elements()))
|
||||
.append($(this.labelView.elements()));
|
||||
|
||||
this.model(undefined);
|
||||
}
|
||||
|
||||
TreeNodeView.prototype.updateStatusClasses = function (statuses) {
|
||||
this.statusClasses.forEach(function (statusClass) {
|
||||
this.li.removeClass(statusClass);
|
||||
}.bind(this));
|
||||
|
||||
this.statusClasses = statuses.map(function (status) {
|
||||
return 's-status-' + status;
|
||||
});
|
||||
|
||||
this.statusClasses.forEach(function (statusClass) {
|
||||
this.li.addClass(statusClass);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
TreeNodeView.prototype.model = function (domainObject) {
|
||||
if (this.unlisten) {
|
||||
this.unlisten();
|
||||
}
|
||||
|
||||
this.activeObject = domainObject;
|
||||
|
||||
if (domainObject && domainObject.hasCapability('composition')) {
|
||||
$(this.toggleView.elements()).addClass('has-children');
|
||||
} else {
|
||||
$(this.toggleView.elements()).removeClass('has-children');
|
||||
}
|
||||
|
||||
if (domainObject && domainObject.hasCapability('status')) {
|
||||
this.unlisten = domainObject.getCapability('status')
|
||||
.listen(this.updateStatusClasses.bind(this));
|
||||
this.updateStatusClasses(
|
||||
domainObject.getCapability('status').list()
|
||||
);
|
||||
}
|
||||
|
||||
this.labelView.model(domainObject);
|
||||
if (this.subtreeView) {
|
||||
this.subtreeView.model(domainObject);
|
||||
}
|
||||
};
|
||||
|
||||
function getIdPath(domainObject) {
|
||||
var context = domainObject && domainObject.getCapability('context');
|
||||
|
||||
function getId(domainObject) {
|
||||
return domainObject.getId();
|
||||
}
|
||||
|
||||
return context ? context.getPath().map(getId) : [];
|
||||
}
|
||||
|
||||
TreeNodeView.prototype.value = function (domainObject) {
|
||||
var activeIdPath = getIdPath(this.activeObject),
|
||||
selectedIdPath = getIdPath(domainObject);
|
||||
|
||||
if (this.onSelectionPath) {
|
||||
this.li.find('.tree-item').eq(0).removeClass('selected');
|
||||
if (this.subtreeView) {
|
||||
this.subtreeView.value(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
this.onSelectionPath =
|
||||
!!domainObject &&
|
||||
!!this.activeObject &&
|
||||
(activeIdPath.length <= selectedIdPath.length) &&
|
||||
activeIdPath.every(function (id, index) {
|
||||
return selectedIdPath[index] === id;
|
||||
});
|
||||
|
||||
if (this.onSelectionPath) {
|
||||
if (activeIdPath.length === selectedIdPath.length) {
|
||||
this.li.find('.tree-item').eq(0).addClass('selected');
|
||||
} else {
|
||||
// Expand to reveal the selection
|
||||
this.toggleView.value(true);
|
||||
this.subtreeView.value(domainObject);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns {HTMLElement[]}
|
||||
*/
|
||||
TreeNodeView.prototype.elements = function () {
|
||||
return this.li;
|
||||
};
|
||||
|
||||
|
||||
return TreeNodeView;
|
||||
});
|
141
platform/commonUI/general/src/ui/TreeView.js
Normal file
141
platform/commonUI/general/src/ui/TreeView.js
Normal file
@ -0,0 +1,141 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
'zepto',
|
||||
'./TreeNodeView',
|
||||
'text!../../res/templates/tree/wait-node.html'
|
||||
], function ($, TreeNodeView, spinnerTemplate) {
|
||||
'use strict';
|
||||
|
||||
function TreeView(gestureService, selectFn) {
|
||||
this.ul = $('<ul class="tree"></ul>');
|
||||
this.nodeViews = [];
|
||||
this.callbacks = [];
|
||||
this.selectFn = selectFn || this.value.bind(this);
|
||||
this.gestureService = gestureService;
|
||||
this.pending = false;
|
||||
}
|
||||
|
||||
TreeView.prototype.newTreeView = function () {
|
||||
return new TreeView(this.gestureService, this.selectFn);
|
||||
};
|
||||
|
||||
TreeView.prototype.setSize = function (sz) {
|
||||
var nodeView;
|
||||
|
||||
while (this.nodeViews.length < sz) {
|
||||
nodeView = new TreeNodeView(
|
||||
this.gestureService,
|
||||
this.newTreeView.bind(this),
|
||||
this.selectFn
|
||||
);
|
||||
this.nodeViews.push(nodeView);
|
||||
this.ul.append($(nodeView.elements()));
|
||||
}
|
||||
|
||||
while (this.nodeViews.length > sz) {
|
||||
nodeView = this.nodeViews.pop();
|
||||
$(nodeView.elements()).remove();
|
||||
}
|
||||
};
|
||||
|
||||
TreeView.prototype.loadComposition = function () {
|
||||
var self = this,
|
||||
domainObject = this.activeObject;
|
||||
|
||||
function addNode(domainObject, index) {
|
||||
self.nodeViews[index].model(domainObject);
|
||||
}
|
||||
|
||||
function addNodes(domainObjects) {
|
||||
if (self.pending) {
|
||||
self.pending = false;
|
||||
self.nodeViews = [];
|
||||
self.ul.empty();
|
||||
}
|
||||
|
||||
if (domainObject === self.activeObject) {
|
||||
self.setSize(domainObjects.length);
|
||||
domainObjects.forEach(addNode);
|
||||
self.updateNodeViewSelection();
|
||||
}
|
||||
}
|
||||
|
||||
domainObject.useCapability('composition')
|
||||
.then(addNodes);
|
||||
};
|
||||
|
||||
TreeView.prototype.model = function (domainObject) {
|
||||
if (this.unlisten) {
|
||||
this.unlisten();
|
||||
}
|
||||
|
||||
this.activeObject = domainObject;
|
||||
this.ul.empty();
|
||||
|
||||
if (domainObject && domainObject.hasCapability('composition')) {
|
||||
this.pending = true;
|
||||
this.ul.append($(spinnerTemplate));
|
||||
this.unlisten = domainObject.getCapability('mutation')
|
||||
.listen(this.loadComposition.bind(this));
|
||||
this.loadComposition(domainObject);
|
||||
} else {
|
||||
this.setSize(0);
|
||||
}
|
||||
};
|
||||
|
||||
TreeView.prototype.updateNodeViewSelection = function () {
|
||||
this.nodeViews.forEach(function (nodeView) {
|
||||
nodeView.value(this.selectedObject);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
TreeView.prototype.value = function (domainObject) {
|
||||
this.selectedObject = domainObject;
|
||||
this.updateNodeViewSelection();
|
||||
this.callbacks.forEach(function (callback) {
|
||||
callback(domainObject);
|
||||
});
|
||||
};
|
||||
|
||||
TreeView.prototype.observe = function (callback) {
|
||||
this.callbacks.push(callback);
|
||||
return function () {
|
||||
this.callbacks = this.callbacks.filter(function (c) {
|
||||
return c !== callback;
|
||||
});
|
||||
}.bind(this);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns {HTMLElement[]}
|
||||
*/
|
||||
TreeView.prototype.elements = function () {
|
||||
return this.ul;
|
||||
};
|
||||
|
||||
|
||||
return TreeView;
|
||||
});
|
95
platform/commonUI/general/test/directives/MCTTreeSpec.js
Normal file
95
platform/commonUI/general/test/directives/MCTTreeSpec.js
Normal file
@ -0,0 +1,95 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define,describe,beforeEach,jasmine,it,expect*/
|
||||
|
||||
define([
|
||||
'../../src/directives/MCTTree'
|
||||
], function (MCTTree) {
|
||||
describe("The mct-tree directive", function () {
|
||||
var mockParse,
|
||||
mockGestureService,
|
||||
mockExpr,
|
||||
mctTree;
|
||||
|
||||
beforeEach(function () {
|
||||
mockGestureService = jasmine.createSpyObj(
|
||||
'gestureService',
|
||||
[ 'attachGestures' ]
|
||||
);
|
||||
mockParse = jasmine.createSpy('$parse');
|
||||
mockExpr = jasmine.createSpy('expr');
|
||||
mockExpr.assign = jasmine.createSpy('assign');
|
||||
mockParse.andReturn(mockExpr);
|
||||
|
||||
mctTree = new MCTTree(mockParse, mockGestureService);
|
||||
});
|
||||
|
||||
it("is applicable as an element", function () {
|
||||
expect(mctTree.restrict).toEqual("E");
|
||||
});
|
||||
|
||||
it("two-way binds to mctObject", function () {
|
||||
expect(mctTree.scope).toEqual({ mctObject: "=" });
|
||||
});
|
||||
|
||||
describe("link", function () {
|
||||
var mockScope,
|
||||
mockElement,
|
||||
testAttrs;
|
||||
|
||||
beforeEach(function () {
|
||||
mockScope = jasmine.createSpyObj('$scope', ['$watch', '$on']);
|
||||
mockElement = jasmine.createSpyObj('element', ['append']);
|
||||
testAttrs = { mctModel: "some-expression" };
|
||||
mockScope.$parent =
|
||||
jasmine.createSpyObj('$scope', ['$watch', '$on']);
|
||||
mctTree.link(mockScope, mockElement, testAttrs);
|
||||
});
|
||||
|
||||
it("populates the mct-tree element", function () {
|
||||
expect(mockElement.append).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("watches for mct-model's expression in the parent", function () {
|
||||
expect(mockScope.$parent.$watch).toHaveBeenCalledWith(
|
||||
testAttrs.mctModel,
|
||||
jasmine.any(Function)
|
||||
);
|
||||
});
|
||||
|
||||
it("watches for changes to mct-object", function () {
|
||||
expect(mockScope.$watch).toHaveBeenCalledWith(
|
||||
"mctObject",
|
||||
jasmine.any(Function)
|
||||
);
|
||||
});
|
||||
|
||||
it("listens for the $destroy event", function () {
|
||||
expect(mockScope.$on).toHaveBeenCalledWith(
|
||||
"$destroy",
|
||||
jasmine.any(Function)
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
313
platform/commonUI/general/test/ui/TreeViewSpec.js
Normal file
313
platform/commonUI/general/test/ui/TreeViewSpec.js
Normal file
@ -0,0 +1,313 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define,describe,beforeEach,jasmine,it,expect*/
|
||||
|
||||
define([
|
||||
'../../src/ui/TreeView',
|
||||
'zepto'
|
||||
], function (TreeView, $) {
|
||||
'use strict';
|
||||
|
||||
describe("TreeView", function () {
|
||||
var mockGestureService,
|
||||
mockGestureHandle,
|
||||
mockDomainObject,
|
||||
mockMutation,
|
||||
mockUnlisten,
|
||||
testCapabilities,
|
||||
treeView;
|
||||
|
||||
function makeMockDomainObject(id, model, capabilities) {
|
||||
var mockDomainObject = jasmine.createSpyObj(
|
||||
'domainObject-' + id,
|
||||
[
|
||||
'getId',
|
||||
'getModel',
|
||||
'getCapability',
|
||||
'hasCapability',
|
||||
'useCapability'
|
||||
]
|
||||
);
|
||||
mockDomainObject.getId.andReturn(id);
|
||||
mockDomainObject.getModel.andReturn(model);
|
||||
mockDomainObject.hasCapability.andCallFake(function (c) {
|
||||
return !!(capabilities[c]);
|
||||
});
|
||||
mockDomainObject.getCapability.andCallFake(function (c) {
|
||||
return capabilities[c];
|
||||
});
|
||||
mockDomainObject.useCapability.andCallFake(function (c) {
|
||||
return capabilities[c] && capabilities[c].invoke();
|
||||
});
|
||||
return mockDomainObject;
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
mockGestureService = jasmine.createSpyObj(
|
||||
'gestureService',
|
||||
[ 'attachGestures' ]
|
||||
);
|
||||
|
||||
mockGestureHandle = jasmine.createSpyObj('gestures', ['destroy']);
|
||||
|
||||
mockGestureService.attachGestures.andReturn(mockGestureHandle);
|
||||
|
||||
mockMutation = jasmine.createSpyObj('mutation', ['listen']);
|
||||
mockUnlisten = jasmine.createSpy('unlisten');
|
||||
mockMutation.listen.andReturn(mockUnlisten);
|
||||
|
||||
testCapabilities = { mutation: mockMutation };
|
||||
|
||||
mockDomainObject =
|
||||
makeMockDomainObject('parent', {}, testCapabilities);
|
||||
|
||||
treeView = new TreeView(mockGestureService);
|
||||
});
|
||||
|
||||
describe("elements", function () {
|
||||
var elements;
|
||||
|
||||
beforeEach(function () {
|
||||
elements = treeView.elements();
|
||||
});
|
||||
|
||||
it("is an unordered list", function () {
|
||||
expect(elements[0].tagName.toLowerCase())
|
||||
.toEqual('ul');
|
||||
});
|
||||
});
|
||||
|
||||
describe("model", function () {
|
||||
var mockComposition;
|
||||
|
||||
function makeGenericCapabilities() {
|
||||
var mockContext =
|
||||
jasmine.createSpyObj('context', [ 'getPath' ]),
|
||||
mockType =
|
||||
jasmine.createSpyObj('type', [ 'getGlyph' ]),
|
||||
mockLocation =
|
||||
jasmine.createSpyObj('location', [ 'isLink' ]),
|
||||
mockMutation =
|
||||
jasmine.createSpyObj('mutation', [ 'listen' ]),
|
||||
mockStatus =
|
||||
jasmine.createSpyObj('status', [ 'listen', 'list' ]);
|
||||
|
||||
mockStatus.list.andReturn([]);
|
||||
|
||||
return {
|
||||
context: mockContext,
|
||||
type: mockType,
|
||||
mutation: mockMutation,
|
||||
location: mockLocation,
|
||||
status: mockStatus
|
||||
};
|
||||
}
|
||||
|
||||
function waitForCompositionCallback() {
|
||||
var calledBack = false;
|
||||
testCapabilities.composition.invoke().then(function (c) {
|
||||
calledBack = true;
|
||||
});
|
||||
waitsFor(function () {
|
||||
return calledBack;
|
||||
});
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
mockComposition = ['a', 'b', 'c'].map(function (id) {
|
||||
var testCapabilities = makeGenericCapabilities(),
|
||||
mockChild =
|
||||
makeMockDomainObject(id, {}, testCapabilities);
|
||||
|
||||
testCapabilities.context.getPath
|
||||
.andReturn([mockDomainObject, mockChild]);
|
||||
|
||||
return mockChild;
|
||||
});
|
||||
|
||||
testCapabilities.composition =
|
||||
jasmine.createSpyObj('composition', ['invoke']);
|
||||
testCapabilities.composition.invoke
|
||||
.andReturn(Promise.resolve(mockComposition));
|
||||
|
||||
treeView.model(mockDomainObject);
|
||||
waitForCompositionCallback();
|
||||
});
|
||||
|
||||
it("adds one node per composition element", function () {
|
||||
expect(treeView.elements()[0].childElementCount)
|
||||
.toEqual(mockComposition.length);
|
||||
});
|
||||
|
||||
it("listens for mutation", function () {
|
||||
expect(testCapabilities.mutation.listen)
|
||||
.toHaveBeenCalledWith(jasmine.any(Function));
|
||||
});
|
||||
|
||||
describe("when mutation occurs", function () {
|
||||
beforeEach(function () {
|
||||
mockComposition.pop();
|
||||
testCapabilities.mutation.listen
|
||||
.mostRecentCall.args[0](mockDomainObject.getModel());
|
||||
waitForCompositionCallback();
|
||||
});
|
||||
|
||||
it("continues to show one node per composition element", function () {
|
||||
expect(treeView.elements()[0].childElementCount)
|
||||
.toEqual(mockComposition.length);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when replaced with a non-compositional domain object", function () {
|
||||
beforeEach(function () {
|
||||
delete testCapabilities.composition;
|
||||
treeView.model(mockDomainObject);
|
||||
});
|
||||
|
||||
it("stops listening for mutation", function () {
|
||||
expect(mockUnlisten).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("removes all tree nodes", function () {
|
||||
expect(treeView.elements()[0].childElementCount)
|
||||
.toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when selection state changes", function () {
|
||||
var selectionIndex = 1;
|
||||
|
||||
beforeEach(function () {
|
||||
treeView.value(mockComposition[selectionIndex]);
|
||||
});
|
||||
|
||||
it("communicates selection state to an appropriate node", function () {
|
||||
var selected = $(treeView.elements()[0]).find('.selected');
|
||||
expect(selected.length).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when a context-less object is selected", function () {
|
||||
beforeEach(function () {
|
||||
var testCapabilities = makeGenericCapabilities(),
|
||||
mockDomainObject =
|
||||
makeMockDomainObject('xyz', {}, testCapabilities);
|
||||
delete testCapabilities.context;
|
||||
treeView.value(mockDomainObject);
|
||||
});
|
||||
|
||||
it("clears all selection state", function () {
|
||||
var selected = $(treeView.elements()[0]).find('.selected');
|
||||
expect(selected.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when children contain children", function () {
|
||||
beforeEach(function () {
|
||||
var newCapabilities = makeGenericCapabilities(),
|
||||
gcCapabilities = makeGenericCapabilities(),
|
||||
mockNewChild =
|
||||
makeMockDomainObject('d', {}, newCapabilities),
|
||||
mockGrandchild =
|
||||
makeMockDomainObject('gc', {}, gcCapabilities),
|
||||
calledBackInner = false;
|
||||
|
||||
newCapabilities.composition =
|
||||
jasmine.createSpyObj('composition', [ 'invoke' ]);
|
||||
newCapabilities.composition.invoke
|
||||
.andReturn(Promise.resolve([mockGrandchild]));
|
||||
mockComposition.push(mockNewChild);
|
||||
|
||||
newCapabilities.context.getPath.andReturn([
|
||||
mockDomainObject,
|
||||
mockNewChild
|
||||
]);
|
||||
gcCapabilities.context.getPath.andReturn([
|
||||
mockDomainObject,
|
||||
mockNewChild,
|
||||
mockGrandchild
|
||||
]);
|
||||
|
||||
testCapabilities.mutation.listen
|
||||
.mostRecentCall.args[0](mockDomainObject);
|
||||
waitForCompositionCallback();
|
||||
runs(function () {
|
||||
// Select the innermost object to force expansion,
|
||||
// such that we can verify the subtree is present.
|
||||
treeView.value(mockGrandchild);
|
||||
newCapabilities.composition.invoke().then(function () {
|
||||
calledBackInner = true;
|
||||
});
|
||||
});
|
||||
waitsFor(function () {
|
||||
return calledBackInner;
|
||||
});
|
||||
});
|
||||
|
||||
it("creates inner trees", function () {
|
||||
expect($(treeView.elements()[0]).find('ul').length)
|
||||
.toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when status changes", function () {
|
||||
var testStatuses;
|
||||
|
||||
beforeEach(function () {
|
||||
var mockStatus = mockComposition[1].getCapability('status');
|
||||
|
||||
testStatuses = [ 'foo' ];
|
||||
|
||||
mockStatus.list.andReturn(testStatuses);
|
||||
mockStatus.listen.mostRecentCall.args[0](testStatuses);
|
||||
});
|
||||
|
||||
it("reflects the status change in the tree", function () {
|
||||
expect($(treeView.elements()).find('.s-status-foo').length)
|
||||
.toEqual(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("observe", function () {
|
||||
var mockCallback,
|
||||
unobserve;
|
||||
|
||||
beforeEach(function () {
|
||||
mockCallback = jasmine.createSpy('callback');
|
||||
unobserve = treeView.observe(mockCallback);
|
||||
});
|
||||
|
||||
it("notifies listeners when value is changed", function () {
|
||||
treeView.value(mockDomainObject);
|
||||
expect(mockCallback).toHaveBeenCalledWith(mockDomainObject);
|
||||
});
|
||||
|
||||
it("does not notify listeners when deactivated", function () {
|
||||
unobserve();
|
||||
treeView.value(mockDomainObject);
|
||||
expect(mockCallback).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
@ -83,7 +83,6 @@ define(
|
||||
popup.goesUp() ? 'arw-btm' : 'arw-top',
|
||||
popup.goesLeft() ? 'arw-right' : 'arw-left'
|
||||
].join(' ');
|
||||
scope.bubbleLayout = 'arw-top arw-left';
|
||||
|
||||
// Create the info bubble, now that we know how to
|
||||
// point the arrow...
|
||||
|
@ -107,6 +107,35 @@ define(
|
||||
);
|
||||
});
|
||||
|
||||
[ false, true ].forEach(function (goesLeft) {
|
||||
[ false, true].forEach(function (goesUp) {
|
||||
var vertical = goesUp ? "up" : "down",
|
||||
horizontal = goesLeft ? "left" : "right",
|
||||
location = [ vertical, horizontal].join('-');
|
||||
describe("when bubble goes " + location, function () {
|
||||
var expectedLocation = [
|
||||
goesUp ? "bottom" : "top",
|
||||
goesLeft ? "right" : "left"
|
||||
].join('-');
|
||||
|
||||
beforeEach(function () {
|
||||
mockPopup.goesUp.andReturn(goesUp);
|
||||
mockPopup.goesDown.andReturn(!goesUp);
|
||||
mockPopup.goesLeft.andReturn(goesLeft);
|
||||
mockPopup.goesRight.andReturn(!goesLeft);
|
||||
service.display('', '', {}, [ 10, 10 ]);
|
||||
});
|
||||
|
||||
it("positions the arrow in the " + expectedLocation, function () {
|
||||
expect(mockScope.bubbleLayout).toEqual([
|
||||
goesUp ? "arw-btm" : "arw-top",
|
||||
goesLeft ? "arw-right" : "arw-left"
|
||||
].join(' '));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
|
@ -27,6 +27,7 @@ $colorBtnIcon: $colorKey;
|
||||
$colorInvokeMenu: #fff;
|
||||
$contrastInvokeMenuPercent: 20%;
|
||||
$shdwBtns: rgba(black, 0.2) 0 1px 2px;
|
||||
$shdwBtnsOverlay: rgba(black, 0.5) 0 1px 5px;
|
||||
$sliderColorBase: $colorKey;
|
||||
$sliderColorRangeHolder: rgba(black, 0.1);
|
||||
$sliderColorRange: rgba($sliderColorBase, 0.3);
|
||||
@ -76,6 +77,7 @@ $colorInputBg: rgba(#000, 0.1);
|
||||
$colorInputFg: pullForward($colorBodyFg, 20%);
|
||||
$colorFormText: rgba(#fff, 0.5);
|
||||
$colorInputIcon: pushBack($colorBodyFg, 15%);
|
||||
$colorFieldHint: pullForward($colorBodyFg, 20%);
|
||||
|
||||
// Inspector
|
||||
$colorInspectorBg: pullForward($colorBodyBg, 3%);
|
||||
@ -124,6 +126,7 @@ $colorOvrBg: pullForward($colorBodyBg, 10%);
|
||||
$colorOvrFg: pullForward($colorBodyFg, 30%);
|
||||
$colorOvrBtnBg: pullForward($colorOvrBg, 20%);
|
||||
$colorOvrBtnFg: #fff;
|
||||
$colorFieldHintOverlay: pullForward($colorOvrBg, 30%);
|
||||
|
||||
// Items
|
||||
$colorItemBg: lighten($colorBodyBg, 5%);
|
||||
@ -173,6 +176,8 @@ $scrollbarTrackShdw: rgba(#000, 0.7) 0 1px 5px;
|
||||
$scrollbarTrackColorBg: rgba(#000, 0.4);
|
||||
$scrollbarThumbColor: lighten($colorBodyBg, 10%);
|
||||
$scrollbarThumbColorHov: lighten($scrollbarThumbColor, 2%);
|
||||
$scrollbarThumbColorOverlay: lighten($colorOvrBg, 10%);
|
||||
$scrollbarThumbColorOverlayHov: lighten($scrollbarThumbColorOverlay, 2%);
|
||||
|
||||
// Splitter
|
||||
$splitterD: 25px; // splitterD and HandleD should both be odd, or even
|
||||
|
@ -27,6 +27,7 @@ $colorBtnIcon: #eee;
|
||||
$colorInvokeMenu: #000;
|
||||
$contrastInvokeMenuPercent: 40%;
|
||||
$shdwBtns: none;
|
||||
$shdwBtnsOverlay: none;
|
||||
$sliderColorBase: $colorKey;
|
||||
$sliderColorRangeHolder: rgba(black, 0.07);
|
||||
$sliderColorRange: rgba($sliderColorBase, 0.2);
|
||||
@ -76,6 +77,7 @@ $colorInputBg: $colorGenBg;
|
||||
$colorInputFg: $colorBodyFg;
|
||||
$colorFormText: pushBack($colorBodyFg, 10%);
|
||||
$colorInputIcon: pushBack($colorBodyFg, 25%);
|
||||
$colorFieldHint: pullForward($colorBodyFg, 40%);
|
||||
|
||||
// Inspector
|
||||
$colorInspectorBg: pullForward($colorBodyBg, 5%);
|
||||
@ -124,6 +126,7 @@ $colorOvrBg: $colorBodyBg;
|
||||
$colorOvrFg: $colorBodyFg;
|
||||
$colorOvrBtnBg: pullForward($colorOvrBg, 40%);
|
||||
$colorOvrBtnFg: #fff;
|
||||
$colorFieldHintOverlay: pullForward($colorOvrBg, 40%);
|
||||
|
||||
// Items
|
||||
$colorItemBg: #ddd;
|
||||
@ -170,9 +173,11 @@ $shdwItemTreeIcon: none;
|
||||
// Scrollbar
|
||||
$scrollbarTrackSize: 10px;
|
||||
$scrollbarTrackShdw: rgba(#000, 0.2) 0 1px 2px;
|
||||
$scrollbarTrackColorBg: rgba(#000, 0.1);
|
||||
$scrollbarThumbColor: darken($colorBodyBg, 50%);//
|
||||
$scrollbarTrackColorBg: rgba(#000, 0.2);
|
||||
$scrollbarThumbColor: darken($colorBodyBg, 50%);
|
||||
$scrollbarThumbColorHov: $colorKey;
|
||||
$scrollbarThumbColorOverlay: darken($colorOvrBg, 50%);
|
||||
$scrollbarThumbColorOverlayHov: $scrollbarThumbColorHov;
|
||||
|
||||
// Splitter
|
||||
$splitterD: 24px;
|
||||
|
@ -26,6 +26,7 @@ define([
|
||||
"./src/models/StaticModelProvider",
|
||||
"./src/models/RootModelProvider",
|
||||
"./src/models/ModelAggregator",
|
||||
"./src/models/ModelCacheService",
|
||||
"./src/models/PersistedModelProvider",
|
||||
"./src/models/CachingModelDecorator",
|
||||
"./src/models/MissingModelDecorator",
|
||||
@ -57,6 +58,7 @@ define([
|
||||
StaticModelProvider,
|
||||
RootModelProvider,
|
||||
ModelAggregator,
|
||||
ModelCacheService,
|
||||
PersistedModelProvider,
|
||||
CachingModelDecorator,
|
||||
MissingModelDecorator,
|
||||
@ -180,7 +182,10 @@ define([
|
||||
{
|
||||
"provides": "modelService",
|
||||
"type": "decorator",
|
||||
"implementation": CachingModelDecorator
|
||||
"implementation": CachingModelDecorator,
|
||||
"depends": [
|
||||
"cacheService"
|
||||
]
|
||||
},
|
||||
{
|
||||
"provides": "modelService",
|
||||
@ -246,21 +251,22 @@ define([
|
||||
"property": "name",
|
||||
"pattern": "\\S+",
|
||||
"required": true,
|
||||
"cssclass": "l-med"
|
||||
"cssclass": "l-input-lg"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "root",
|
||||
"name": "Root",
|
||||
"glyph": "F"
|
||||
"glyph": "\u0046"
|
||||
},
|
||||
{
|
||||
"key": "folder",
|
||||
"name": "Folder",
|
||||
"glyph": "F",
|
||||
"glyph": "\u0046",
|
||||
"features": "creation",
|
||||
"description": "Useful for storing and organizing domain objects.",
|
||||
"description": "Create folders to organize other objects or links to objects.",
|
||||
"priority": 1000,
|
||||
"model": {
|
||||
"composition": []
|
||||
}
|
||||
@ -268,11 +274,11 @@ define([
|
||||
{
|
||||
"key": "unknown",
|
||||
"name": "Unknown Type",
|
||||
"glyph": "?"
|
||||
"glyph": "\u003f"
|
||||
},
|
||||
{
|
||||
"name": "Unknown Type",
|
||||
"glyph": "?"
|
||||
"glyph": "\u003f"
|
||||
}
|
||||
],
|
||||
"capabilities": [
|
||||
@ -317,6 +323,7 @@ define([
|
||||
"key": "persistence",
|
||||
"implementation": PersistenceCapability,
|
||||
"depends": [
|
||||
"cacheService",
|
||||
"persistenceService",
|
||||
"identifierService",
|
||||
"notificationService",
|
||||
@ -347,11 +354,16 @@ define([
|
||||
"implementation": InstantiationCapability,
|
||||
"depends": [
|
||||
"$injector",
|
||||
"identifierService"
|
||||
"identifierService",
|
||||
"now"
|
||||
]
|
||||
}
|
||||
],
|
||||
"services": [
|
||||
{
|
||||
"key": "cacheService",
|
||||
"implementation": ModelCacheService
|
||||
},
|
||||
{
|
||||
"key": "now",
|
||||
"implementation": Now
|
||||
@ -382,7 +394,8 @@ define([
|
||||
"implementation": Instantiate,
|
||||
"depends": [
|
||||
"capabilityService",
|
||||
"identifierService"
|
||||
"identifierService",
|
||||
"cacheService"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
@ -26,7 +26,8 @@
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
var DISALLOWED_ACTIONS = ["move", "copy", "link", "window", "follow"];
|
||||
var DISALLOWED_ACTIONS = ["copy", "window", "follow"];
|
||||
|
||||
/**
|
||||
* The ActionCapability allows applicable Actions to be retrieved and
|
||||
* performed for specific domain objects, e.g.:
|
||||
|
@ -33,10 +33,16 @@ define(
|
||||
* @param $injector Angular's `$injector`
|
||||
* @implements {Capability}
|
||||
*/
|
||||
function InstantiationCapability($injector, identifierService, domainObject) {
|
||||
function InstantiationCapability(
|
||||
$injector,
|
||||
identifierService,
|
||||
now,
|
||||
domainObject
|
||||
) {
|
||||
this.$injector = $injector;
|
||||
this.identifierService = identifierService;
|
||||
this.domainObject = domainObject;
|
||||
this.now = now;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,6 +61,8 @@ define(
|
||||
space = parsedId.getDefinedSpace(),
|
||||
id = this.identifierService.generate(space);
|
||||
|
||||
model.modified = this.now();
|
||||
|
||||
// Lazily initialize; instantiate depends on capabilityService,
|
||||
// which depends on all capabilities, including this one.
|
||||
this.instantiateFn = this.instantiateFn ||
|
||||
|
@ -44,6 +44,7 @@ define(
|
||||
* @implements {Capability}
|
||||
*/
|
||||
function PersistenceCapability(
|
||||
cacheService,
|
||||
persistenceService,
|
||||
identifierService,
|
||||
notificationService,
|
||||
@ -54,6 +55,7 @@ define(
|
||||
this.modified = domainObject.getModel().modified;
|
||||
|
||||
this.domainObject = domainObject;
|
||||
this.cacheService = cacheService;
|
||||
this.identifierService = identifierService;
|
||||
this.persistenceService = persistenceService;
|
||||
this.notificationService = notificationService;
|
||||
@ -128,6 +130,7 @@ define(
|
||||
domainObject = this.domainObject,
|
||||
model = domainObject.getModel(),
|
||||
modified = model.modified,
|
||||
cacheService = this.cacheService,
|
||||
persistenceService = this.persistenceService,
|
||||
persistenceFn = model.persisted !== undefined ?
|
||||
this.persistenceService.updateObject :
|
||||
|
@ -33,9 +33,8 @@ define(
|
||||
* @param {ModelService} modelService this service to decorate
|
||||
* @implements {ModelService}
|
||||
*/
|
||||
function CachingModelDecorator(modelService) {
|
||||
this.cache = {};
|
||||
this.cached = {};
|
||||
function CachingModelDecorator(cacheService, modelService) {
|
||||
this.cacheService = cacheService;
|
||||
this.modelService = modelService;
|
||||
}
|
||||
|
||||
@ -49,17 +48,16 @@ define(
|
||||
}
|
||||
|
||||
CachingModelDecorator.prototype.getModels = function (ids) {
|
||||
var cache = this.cache,
|
||||
cached = this.cached,
|
||||
var cacheService = this.cacheService,
|
||||
neededIds = ids.filter(function notCached(id) {
|
||||
return !cached[id];
|
||||
return !cacheService.has(id);
|
||||
});
|
||||
|
||||
// Update the cached instance of a model to a new value.
|
||||
// We update in-place to ensure there is only ever one instance
|
||||
// of any given model exposed by the modelService as a whole.
|
||||
function updateModel(id, model) {
|
||||
var oldModel = cache[id];
|
||||
var oldModel = cacheService.get(id);
|
||||
|
||||
// Same object instance is a possibility, so don't copy
|
||||
if (oldModel === model) {
|
||||
@ -69,7 +67,7 @@ define(
|
||||
// If we'd previously cached an undefined value, or are now
|
||||
// seeing undefined, replace the item in the cache entirely.
|
||||
if (oldModel === undefined || model === undefined) {
|
||||
cache[id] = model;
|
||||
cacheService.put(id, model);
|
||||
return model;
|
||||
}
|
||||
|
||||
@ -89,15 +87,15 @@ define(
|
||||
// Store the provided models in our cache
|
||||
function cacheAll(models) {
|
||||
Object.keys(models).forEach(function (id) {
|
||||
cache[id] = cached[id] ?
|
||||
var model = cacheService.has(id) ?
|
||||
updateModel(id, models[id]) : models[id];
|
||||
cached[id] = true;
|
||||
cacheService.put(id, model);
|
||||
});
|
||||
}
|
||||
|
||||
// Expose the cache (for promise chaining)
|
||||
function giveCache() {
|
||||
return cache;
|
||||
return cacheService.all();
|
||||
}
|
||||
|
||||
// Look up if we have unknown IDs
|
||||
@ -108,7 +106,7 @@ define(
|
||||
}
|
||||
|
||||
// Otherwise, just expose the cache directly
|
||||
return fastPromise(cache);
|
||||
return fastPromise(cacheService.all());
|
||||
};
|
||||
|
||||
return CachingModelDecorator;
|
||||
|
83
platform/core/src/models/ModelCacheService.js
Normal file
83
platform/core/src/models/ModelCacheService.js
Normal file
@ -0,0 +1,83 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Provides a cache for domain object models which exist in memory,
|
||||
* but may or may not exist in backing persistene stores.
|
||||
* @constructor
|
||||
* @memberof platform/core
|
||||
*/
|
||||
function ModelCacheService() {
|
||||
this.cache = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a domain object model in the cache.
|
||||
* @param {string} id the domain object's identifier
|
||||
* @param {object} model the domain object's model
|
||||
*/
|
||||
ModelCacheService.prototype.put = function (id, model) {
|
||||
this.cache[id] = model;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve a domain object model from the cache.
|
||||
* @param {string} id the domain object's identifier
|
||||
* @returns {object} the domain object's model
|
||||
*/
|
||||
ModelCacheService.prototype.get = function (id) {
|
||||
return this.cache[id];
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if a domain object model is in the cache.
|
||||
* @param {string} id the domain object's identifier
|
||||
* @returns {boolean} true if present; false if not
|
||||
*/
|
||||
ModelCacheService.prototype.has = function (id) {
|
||||
return this.cache.hasOwnProperty(id);
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove a domain object model from the cache.
|
||||
* @param {string} id the domain object's identifier
|
||||
*/
|
||||
ModelCacheService.prototype.remove = function (id) {
|
||||
delete this.cache[id];
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve all cached domain object models. These are given
|
||||
* as an object containing key-value pairs, where keys are
|
||||
* domain object identifiers and values are domain object models.
|
||||
* @returns {object} all domain object models
|
||||
*/
|
||||
ModelCacheService.prototype.all = function () {
|
||||
return this.cache;
|
||||
};
|
||||
|
||||
return ModelCacheService;
|
||||
});
|
@ -42,10 +42,15 @@ define(
|
||||
* @param {IdentifierService} identifierService service to generate
|
||||
* new identifiers
|
||||
*/
|
||||
function Instantiate(capabilityService, identifierService) {
|
||||
function Instantiate(
|
||||
capabilityService,
|
||||
identifierService,
|
||||
cacheService
|
||||
) {
|
||||
return function (model, id) {
|
||||
var capabilities = capabilityService.getCapabilities(model);
|
||||
id = id || identifierService.generate();
|
||||
cacheService.put(id, model);
|
||||
return new DomainObjectImpl(id, model, capabilities);
|
||||
};
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ define(
|
||||
mockIdentifierService,
|
||||
mockInstantiate,
|
||||
mockIdentifier,
|
||||
mockNow,
|
||||
mockDomainObject,
|
||||
instantiation;
|
||||
|
||||
@ -55,9 +56,13 @@ define(
|
||||
mockIdentifierService.parse.andReturn(mockIdentifier);
|
||||
mockIdentifierService.generate.andReturn("some-id");
|
||||
|
||||
mockNow = jasmine.createSpy();
|
||||
mockNow.andReturn(1234321);
|
||||
|
||||
instantiation = new InstantiationCapability(
|
||||
mockInjector,
|
||||
mockIdentifierService,
|
||||
mockNow,
|
||||
mockDomainObject
|
||||
);
|
||||
});
|
||||
@ -79,7 +84,10 @@ define(
|
||||
expect(instantiation.instantiate(testModel))
|
||||
.toBe(mockDomainObject);
|
||||
expect(mockInstantiate)
|
||||
.toHaveBeenCalledWith(testModel, jasmine.any(String));
|
||||
.toHaveBeenCalledWith({
|
||||
someKey: "some value",
|
||||
modified: mockNow()
|
||||
}, jasmine.any(String));
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -34,6 +34,7 @@ define(
|
||||
mockDomainObject,
|
||||
mockIdentifier,
|
||||
mockNofificationService,
|
||||
mockCacheService,
|
||||
mockQ,
|
||||
id = "object id",
|
||||
model,
|
||||
@ -79,6 +80,10 @@ define(
|
||||
"notificationService",
|
||||
["error"]
|
||||
);
|
||||
mockCacheService = jasmine.createSpyObj(
|
||||
"cacheService",
|
||||
[ "get", "put", "remove", "all" ]
|
||||
);
|
||||
|
||||
mockDomainObject = {
|
||||
getId: function () { return id; },
|
||||
@ -94,6 +99,7 @@ define(
|
||||
mockIdentifierService.parse.andReturn(mockIdentifier);
|
||||
mockIdentifier.getSpace.andReturn(SPACE);
|
||||
persistence = new PersistenceCapability(
|
||||
mockCacheService,
|
||||
mockPersistenceService,
|
||||
mockIdentifierService,
|
||||
mockNofificationService,
|
||||
@ -169,6 +175,7 @@ define(
|
||||
expect(mockNofificationService.error).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("unsuccessful persistence", function() {
|
||||
var sadPromise = {
|
||||
then: function(callback){
|
||||
|
@ -21,8 +21,11 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
["../../src/models/CachingModelDecorator"],
|
||||
function (CachingModelDecorator) {
|
||||
[
|
||||
"../../src/models/CachingModelDecorator",
|
||||
"../../src/models/ModelCacheService"
|
||||
],
|
||||
function (CachingModelDecorator, ModelCacheService) {
|
||||
|
||||
describe("The caching model decorator", function () {
|
||||
var mockModelService,
|
||||
@ -65,7 +68,10 @@ define(
|
||||
b: { someOtherKey: "some other value" }
|
||||
};
|
||||
mockModelService.getModels.andReturn(asPromise(testModels));
|
||||
decorator = new CachingModelDecorator(mockModelService);
|
||||
decorator = new CachingModelDecorator(
|
||||
new ModelCacheService(),
|
||||
mockModelService
|
||||
);
|
||||
});
|
||||
|
||||
it("loads models from its wrapped model service", function () {
|
||||
@ -148,4 +154,4 @@ define(
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
);
|
||||
|
69
platform/core/test/models/ModelCacheServiceSpec.js
Normal file
69
platform/core/test/models/ModelCacheServiceSpec.js
Normal file
@ -0,0 +1,69 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define,Promise,describe,it,expect,beforeEach,waitsFor,jasmine*/
|
||||
|
||||
define(['../../src/models/ModelCacheService'], function (ModelCacheService) {
|
||||
'use strict';
|
||||
describe("ModelCacheService", function () {
|
||||
var testIds,
|
||||
testModels,
|
||||
cacheService;
|
||||
|
||||
beforeEach(function () {
|
||||
testIds = [ 'a', 'b', 'c', 'd' ];
|
||||
testModels = testIds.reduce(function (models, id) {
|
||||
models[id] = { someKey: "some value for " + id };
|
||||
return models;
|
||||
}, {});
|
||||
cacheService = new ModelCacheService();
|
||||
});
|
||||
|
||||
describe("when populated with models", function () {
|
||||
beforeEach(function () {
|
||||
testIds.forEach(function (id) {
|
||||
cacheService.put(id, testModels[id]);
|
||||
});
|
||||
});
|
||||
|
||||
it("indicates that it has these models", function () {
|
||||
testIds.forEach(function (id) {
|
||||
expect(cacheService.has(id)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("provides all of these models", function () {
|
||||
expect(cacheService.all()).toEqual(testModels);
|
||||
});
|
||||
|
||||
it("allows models to be retrieved", function () {
|
||||
testIds.forEach(function (id) {
|
||||
expect(cacheService.get(id)).toEqual(testModels[id]);
|
||||
});
|
||||
});
|
||||
|
||||
it("allows models to be removed", function () {
|
||||
cacheService.remove('a');
|
||||
expect(cacheService.has('a')).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -30,6 +30,7 @@ define(
|
||||
mockIdentifierService,
|
||||
mockCapabilityConstructor,
|
||||
mockCapabilityInstance,
|
||||
mockCacheService,
|
||||
idCounter,
|
||||
testModel,
|
||||
instantiate,
|
||||
@ -58,11 +59,17 @@ define(
|
||||
"some-id-" + (idCounter += 1);
|
||||
});
|
||||
|
||||
mockCacheService = jasmine.createSpyObj(
|
||||
'cacheService',
|
||||
[ 'get', 'put', 'remove', 'all' ]
|
||||
);
|
||||
|
||||
testModel = { someKey: "some value" };
|
||||
|
||||
instantiate = new Instantiate(
|
||||
mockCapabilityService,
|
||||
mockIdentifierService
|
||||
mockIdentifierService,
|
||||
mockCacheService
|
||||
);
|
||||
domainObject = instantiate(testModel);
|
||||
});
|
||||
@ -88,6 +95,13 @@ define(
|
||||
expect(instantiate(testModel).getId())
|
||||
.not.toEqual(domainObject.getId());
|
||||
});
|
||||
|
||||
it("caches the instantiated model", function () {
|
||||
expect(mockCacheService.put).toHaveBeenCalledWith(
|
||||
domainObject.getId(),
|
||||
testModel
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -28,7 +28,9 @@ define([
|
||||
"./src/actions/SetPrimaryLocationAction",
|
||||
"./src/services/LocatingCreationDecorator",
|
||||
"./src/services/LocatingObjectDecorator",
|
||||
"./src/policies/CopyPolicy",
|
||||
"./src/policies/CrossSpacePolicy",
|
||||
"./src/policies/MovePolicy",
|
||||
"./src/capabilities/LocationCapability",
|
||||
"./src/services/MoveService",
|
||||
"./src/services/LinkService",
|
||||
@ -43,7 +45,9 @@ define([
|
||||
SetPrimaryLocationAction,
|
||||
LocatingCreationDecorator,
|
||||
LocatingObjectDecorator,
|
||||
CopyPolicy,
|
||||
CrossSpacePolicy,
|
||||
MovePolicy,
|
||||
LocationCapability,
|
||||
MoveService,
|
||||
LinkService,
|
||||
@ -138,6 +142,14 @@ define([
|
||||
{
|
||||
"category": "action",
|
||||
"implementation": CrossSpacePolicy
|
||||
},
|
||||
{
|
||||
"category": "action",
|
||||
"implementation": CopyPolicy
|
||||
},
|
||||
{
|
||||
"category": "action",
|
||||
"implementation": MovePolicy
|
||||
}
|
||||
],
|
||||
"capabilities": [
|
||||
|
@ -20,37 +20,38 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* MergeModelsSpec. Created by vwoeltje on 11/6/14.
|
||||
*/
|
||||
define(
|
||||
["../src/NameColumn"],
|
||||
function (NameColumn) {
|
||||
/*global define */
|
||||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
describe("A name column", function () {
|
||||
var mockDomainObject,
|
||||
column;
|
||||
|
||||
beforeEach(function () {
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
"domainObject",
|
||||
[ "getModel" ]
|
||||
);
|
||||
mockDomainObject.getModel.andReturn({
|
||||
name: "Test object name"
|
||||
});
|
||||
column = new NameColumn();
|
||||
});
|
||||
|
||||
it("reports a column header", function () {
|
||||
expect(column.getTitle()).toEqual("Name");
|
||||
});
|
||||
|
||||
it("looks up name from an object's model", function () {
|
||||
expect(column.getValue(mockDomainObject).text)
|
||||
.toEqual("Test object name");
|
||||
});
|
||||
|
||||
});
|
||||
/**
|
||||
* Disallow duplication when the object to be duplicated is not
|
||||
* creatable.
|
||||
* @constructor
|
||||
* @implements {Policy}
|
||||
* @memberof platform/entanglement
|
||||
*/
|
||||
function CopyPolicy() {
|
||||
}
|
||||
);
|
||||
|
||||
function allowCreation(domainObject) {
|
||||
var type = domainObject && domainObject.getCapability('type');
|
||||
return !!(type && type.hasFeature('creation'));
|
||||
}
|
||||
|
||||
function selectedObject(context) {
|
||||
return context.selectedObject || context.domainObject;
|
||||
}
|
||||
|
||||
CopyPolicy.prototype.allow = function (action, context) {
|
||||
var key = action.getMetadata().key;
|
||||
|
||||
if (key === 'copy') {
|
||||
return allowCreation(selectedObject(context));
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
return CopyPolicy;
|
||||
});
|
63
platform/entanglement/src/policies/MovePolicy.js
Normal file
63
platform/entanglement/src/policies/MovePolicy.js
Normal file
@ -0,0 +1,63 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/*global define */
|
||||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Disallow moves when either the parent or the child are not
|
||||
* modifiable by users.
|
||||
* @constructor
|
||||
* @implements {Policy}
|
||||
* @memberof platform/entanglement
|
||||
*/
|
||||
function MovePolicy() {
|
||||
}
|
||||
|
||||
function parentOf(domainObject) {
|
||||
var context = domainObject.getCapability('context');
|
||||
return context && context.getParent();
|
||||
}
|
||||
|
||||
function allowMutation(domainObject) {
|
||||
var type = domainObject && domainObject.getCapability('type');
|
||||
return !!(type && type.hasFeature('creation'));
|
||||
}
|
||||
|
||||
function selectedObject(context) {
|
||||
return context.selectedObject || context.domainObject;
|
||||
}
|
||||
|
||||
MovePolicy.prototype.allow = function (action, context) {
|
||||
var key = action.getMetadata().key;
|
||||
|
||||
if (key === 'move') {
|
||||
return allowMutation(selectedObject(context)) &&
|
||||
allowMutation(parentOf(selectedObject(context)));
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
return MovePolicy;
|
||||
});
|
94
platform/entanglement/test/policies/CopyPolicySpec.js
Normal file
94
platform/entanglement/test/policies/CopyPolicySpec.js
Normal file
@ -0,0 +1,94 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/*global define,describe,beforeEach,it,jasmine,expect,spyOn */
|
||||
define([
|
||||
'../../src/policies/CopyPolicy',
|
||||
'../DomainObjectFactory'
|
||||
], function (CopyPolicy, domainObjectFactory) {
|
||||
'use strict';
|
||||
|
||||
describe("CopyPolicy", function () {
|
||||
var testMetadata,
|
||||
testContext,
|
||||
mockDomainObject,
|
||||
mockType,
|
||||
mockAction,
|
||||
policy;
|
||||
|
||||
beforeEach(function () {
|
||||
mockType =
|
||||
jasmine.createSpyObj('type', ['hasFeature']);
|
||||
|
||||
testMetadata = {};
|
||||
|
||||
mockDomainObject = domainObjectFactory({
|
||||
capabilities: { type: mockType }
|
||||
});
|
||||
|
||||
mockType.hasFeature.andCallFake(function (feature) {
|
||||
return feature === 'creation';
|
||||
});
|
||||
|
||||
mockAction = jasmine.createSpyObj('action', ['getMetadata']);
|
||||
mockAction.getMetadata.andReturn(testMetadata);
|
||||
|
||||
testContext = { domainObject: mockDomainObject };
|
||||
|
||||
policy = new CopyPolicy();
|
||||
});
|
||||
|
||||
describe("for copy actions", function () {
|
||||
beforeEach(function () {
|
||||
testMetadata.key = 'copy';
|
||||
});
|
||||
|
||||
describe("when an object is non-creatable", function () {
|
||||
beforeEach(function () {
|
||||
mockType.hasFeature.andReturn(false);
|
||||
});
|
||||
|
||||
it("disallows the action", function () {
|
||||
expect(policy.allow(mockAction, testContext)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when an object is creatable", function () {
|
||||
it("allows the action", function () {
|
||||
expect(policy.allow(mockAction, testContext)).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("for other actions", function () {
|
||||
beforeEach(function () {
|
||||
testMetadata.key = 'foo';
|
||||
});
|
||||
|
||||
it("simply allows the action", function () {
|
||||
expect(policy.allow(mockAction, testContext)).toBe(true);
|
||||
mockType.hasFeature.andReturn(false);
|
||||
expect(policy.allow(mockAction, testContext)).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
127
platform/entanglement/test/policies/MovePolicySpec.js
Normal file
127
platform/entanglement/test/policies/MovePolicySpec.js
Normal file
@ -0,0 +1,127 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/*global define,describe,beforeEach,it,jasmine,expect,spyOn */
|
||||
define([
|
||||
'../../src/policies/MovePolicy',
|
||||
'../DomainObjectFactory'
|
||||
], function (MovePolicy, domainObjectFactory) {
|
||||
'use strict';
|
||||
|
||||
describe("MovePolicy", function () {
|
||||
var testMetadata,
|
||||
testContext,
|
||||
mockDomainObject,
|
||||
mockParent,
|
||||
mockParentType,
|
||||
mockType,
|
||||
mockAction,
|
||||
policy;
|
||||
|
||||
beforeEach(function () {
|
||||
var mockContextCapability =
|
||||
jasmine.createSpyObj('context', ['getParent']);
|
||||
|
||||
mockType =
|
||||
jasmine.createSpyObj('type', ['hasFeature']);
|
||||
mockParentType =
|
||||
jasmine.createSpyObj('parent-type', ['hasFeature']);
|
||||
|
||||
|
||||
testMetadata = {};
|
||||
|
||||
mockDomainObject = domainObjectFactory({
|
||||
capabilities: {
|
||||
context: mockContextCapability,
|
||||
type: mockType
|
||||
}
|
||||
});
|
||||
mockParent = domainObjectFactory({
|
||||
capabilities: {
|
||||
type: mockParentType
|
||||
}
|
||||
});
|
||||
|
||||
mockContextCapability.getParent.andReturn(mockParent);
|
||||
|
||||
mockType.hasFeature.andCallFake(function (feature) {
|
||||
return feature === 'creation';
|
||||
});
|
||||
mockParentType.hasFeature.andCallFake(function (feature) {
|
||||
return feature === 'creation';
|
||||
});
|
||||
|
||||
mockAction = jasmine.createSpyObj('action', ['getMetadata']);
|
||||
mockAction.getMetadata.andReturn(testMetadata);
|
||||
|
||||
testContext = { domainObject: mockDomainObject };
|
||||
|
||||
policy = new MovePolicy();
|
||||
});
|
||||
|
||||
describe("for move actions", function () {
|
||||
beforeEach(function () {
|
||||
testMetadata.key = 'move';
|
||||
});
|
||||
|
||||
describe("when an object is non-modifiable", function () {
|
||||
beforeEach(function () {
|
||||
mockType.hasFeature.andReturn(false);
|
||||
});
|
||||
|
||||
it("disallows the action", function () {
|
||||
expect(policy.allow(mockAction, testContext)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when a parent is non-modifiable", function () {
|
||||
beforeEach(function () {
|
||||
mockParentType.hasFeature.andReturn(false);
|
||||
});
|
||||
|
||||
it("disallows the action", function () {
|
||||
expect(policy.allow(mockAction, testContext)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when an object and its parent are modifiable", function () {
|
||||
it("allows the action", function () {
|
||||
expect(policy.allow(mockAction, testContext)).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("for other actions", function () {
|
||||
beforeEach(function () {
|
||||
testMetadata.key = 'foo';
|
||||
});
|
||||
|
||||
it("simply allows the action", function () {
|
||||
expect(policy.allow(mockAction, testContext)).toBe(true);
|
||||
mockType.hasFeature.andReturn(false);
|
||||
expect(policy.allow(mockAction, testContext)).toBe(true);
|
||||
mockParentType.hasFeature.andReturn(false);
|
||||
expect(policy.allow(mockAction, testContext)).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -155,7 +155,9 @@ define([
|
||||
{
|
||||
"key": "clock",
|
||||
"name": "Clock",
|
||||
"glyph": "C",
|
||||
"glyph": "\u0043",
|
||||
"description": "A UTC-based clock that supports a variety of display formats. Clocks can be added to Display Layouts.",
|
||||
"priority": 101,
|
||||
"features": [
|
||||
"creation"
|
||||
],
|
||||
@ -180,7 +182,8 @@ define([
|
||||
"value": "hh:mm:ss",
|
||||
"name": "hh:mm:ss"
|
||||
}
|
||||
]
|
||||
],
|
||||
"cssclass": "l-inline"
|
||||
},
|
||||
{
|
||||
"control": "select",
|
||||
@ -193,7 +196,8 @@ define([
|
||||
"value": "clock24",
|
||||
"name": "24hr"
|
||||
}
|
||||
]
|
||||
],
|
||||
"cssclass": "l-inline"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -208,7 +212,9 @@ define([
|
||||
{
|
||||
"key": "timer",
|
||||
"name": "Timer",
|
||||
"glyph": "õ",
|
||||
"glyph": "\u00f5",
|
||||
"description": "A timer that counts up or down to a datetime. Timers can be started, stopped and reset whenever needed, and support a variety of display formats. Each Timer displays the same value to all users. Timers can be added to Display Layouts.",
|
||||
"priority": 100,
|
||||
"features": [
|
||||
"creation"
|
||||
],
|
||||
@ -221,6 +227,7 @@ define([
|
||||
{
|
||||
"key": "timerFormat",
|
||||
"control": "select",
|
||||
"name": "Display Format",
|
||||
"options": [
|
||||
{
|
||||
"value": "long",
|
||||
|
@ -1,81 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
"./src/EventListController",
|
||||
"./src/directives/MCTDataTable",
|
||||
"./src/policies/MessagesViewPolicy",
|
||||
"text!./res/templates/messages.html",
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
EventListController,
|
||||
MCTDataTable,
|
||||
MessagesViewPolicy,
|
||||
messagesTemplate,
|
||||
legacyRegistry
|
||||
) {
|
||||
|
||||
legacyRegistry.register("platform/features/events", {
|
||||
"name": "Event Messages",
|
||||
"description": "List of time-ordered event messages",
|
||||
"extensions": {
|
||||
"views": [
|
||||
{
|
||||
"key": "messages",
|
||||
"name": "Messages",
|
||||
"glyph": "5",
|
||||
"description": "Scrolling list of messages.",
|
||||
"template": messagesTemplate,
|
||||
"needs": [
|
||||
"telemetry"
|
||||
],
|
||||
"delegation": true
|
||||
}
|
||||
],
|
||||
"controllers": [
|
||||
{
|
||||
"key": "EventListController",
|
||||
"implementation": EventListController,
|
||||
"depends": [
|
||||
"$scope",
|
||||
"telemetryFormatter"
|
||||
]
|
||||
}
|
||||
],
|
||||
"directives": [
|
||||
{
|
||||
"key": "mctDataTable",
|
||||
"implementation": MCTDataTable,
|
||||
"depends": [
|
||||
"$window"
|
||||
]
|
||||
}
|
||||
],
|
||||
"policies": [
|
||||
{
|
||||
"category": "view",
|
||||
"implementation": MessagesViewPolicy
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
});
|
@ -1,37 +0,0 @@
|
||||
<!--
|
||||
Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
as represented by the Administrator of the National Aeronautics and Space
|
||||
Administration. All rights reserved.
|
||||
|
||||
Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0.
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
Open MCT Web includes source code licensed under additional open source
|
||||
licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<table class="tabular">
|
||||
<thead>
|
||||
<tr>
|
||||
<th ng-repeat="header in headers">
|
||||
{{header}}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="row in rows">
|
||||
<td ng-repeat="cell in row">
|
||||
{{cell}}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
@ -1,29 +0,0 @@
|
||||
<!--
|
||||
Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
as represented by the Administrator of the National Aeronautics and Space
|
||||
Administration. All rights reserved.
|
||||
|
||||
Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0.
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
Open MCT Web includes source code licensed under additional open source
|
||||
licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<div class="w1" ng-controller="TelemetryController as telemetry">
|
||||
<div class="w2"
|
||||
ng-controller="EventListController">
|
||||
<mct-data-table headers="headers" rows="rows" ascending-scroll="true"></mct-data-table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -1,61 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Module defining DomainColumn. Created by vwoeltje on 11/18/14.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
|
||||
/**
|
||||
* A column which will report telemetry domain values
|
||||
* (typically, timestamps.) Used by the ScrollingListController.
|
||||
*
|
||||
* @memberof platform/features/events
|
||||
* @constructor
|
||||
* @implements {platform/features/events.EventsColumn}
|
||||
* @param domainMetadata an object with the machine- and human-
|
||||
* readable names for this domain (in `key` and `name`
|
||||
* fields, respectively.)
|
||||
* @param {TelemetryFormatter} telemetryFormatter the telemetry
|
||||
* formatting service, for making values human-readable.
|
||||
*/
|
||||
function DomainColumn(domainMetadata, telemetryFormatter) {
|
||||
this.domainMetadata = domainMetadata;
|
||||
this.telemetryFormatter = telemetryFormatter;
|
||||
}
|
||||
|
||||
DomainColumn.prototype.getTitle = function () {
|
||||
return this.domainMetadata.name;
|
||||
};
|
||||
|
||||
DomainColumn.prototype.getValue = function (domainObject, data, index) {
|
||||
var domainKey = this.domainMetadata.key;
|
||||
return this.telemetryFormatter.formatDomainValue(
|
||||
data.getDomainValue(index, domainKey)
|
||||
);
|
||||
};
|
||||
|
||||
return DomainColumn;
|
||||
}
|
||||
);
|
@ -1,162 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Module defining EventListController.
|
||||
* Created by chacskaylo on 06/18/2015.
|
||||
* Modified by shale on 06/23/2015.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This bundle implements the "Events" view of string telemetry.
|
||||
* @namespace platform/features/events
|
||||
*/
|
||||
define(
|
||||
["./DomainColumn", "./RangeColumn", "./EventListPopulator"],
|
||||
function (DomainColumn, RangeColumn, EventListPopulator) {
|
||||
|
||||
var ROW_COUNT = 100;
|
||||
|
||||
/**
|
||||
* The EventListController is responsible for populating
|
||||
* the contents of the event list view.
|
||||
* @memberof platform/features/events
|
||||
* @constructor
|
||||
*/
|
||||
function EventListController($scope, formatter) {
|
||||
var populator;
|
||||
|
||||
// Get a set of populated, ready-to-display rows for the
|
||||
// latest data values.
|
||||
function getRows(telemetry) {
|
||||
var datas = telemetry.getResponse(),
|
||||
objects = telemetry.getTelemetryObjects();
|
||||
|
||||
return populator.getRows(datas, objects, ROW_COUNT);
|
||||
}
|
||||
|
||||
// Update the contents
|
||||
function updateRows() {
|
||||
var telemetry = $scope.telemetry;
|
||||
$scope.rows = telemetry ? getRows(telemetry) : [];
|
||||
}
|
||||
|
||||
// Set up columns based on telemetry metadata. This will
|
||||
// include one column for each domain and range type, as
|
||||
// well as a column for the domain object name.
|
||||
function setupColumns(telemetry) {
|
||||
var domainKeys = {},
|
||||
rangeKeys = {},
|
||||
columns = [],
|
||||
metadata;
|
||||
|
||||
// Add a domain to the set of columns, if a domain
|
||||
// with the same key has not yet been inclued.
|
||||
function addDomain(domain) {
|
||||
var key = domain.key;
|
||||
if (key && !domainKeys[key]) {
|
||||
domainKeys[key] = true;
|
||||
columns.push(new DomainColumn(domain, formatter));
|
||||
}
|
||||
}
|
||||
|
||||
// Add a range col to the set of columns, if a range
|
||||
// with the same key has not yet been included.
|
||||
function addRange(range) {
|
||||
var key = range.key;
|
||||
if (key && !rangeKeys[key]) {
|
||||
rangeKeys[key] = true;
|
||||
columns.push(new RangeColumn(range, formatter));
|
||||
}
|
||||
}
|
||||
|
||||
// We cannot proceed if the telemetry controller
|
||||
// is not available; clear all rows/columns.
|
||||
if (!telemetry) {
|
||||
columns = [];
|
||||
$scope.rows = [];
|
||||
$scope.headers = [];
|
||||
return;
|
||||
}
|
||||
|
||||
// Add domain, range, event msg columns
|
||||
metadata = telemetry.getMetadata();
|
||||
(metadata || []).forEach(function (metadata) {
|
||||
(metadata.domains || []).forEach(addDomain);
|
||||
});
|
||||
(metadata || []).forEach(function (metadata) {
|
||||
(metadata.ranges || []).forEach(addRange);
|
||||
});
|
||||
|
||||
// Add default domain and range columns if none
|
||||
// were described in metadata.
|
||||
if (Object.keys(domainKeys).length < 1) {
|
||||
columns.push(new DomainColumn({name: "Time"}, formatter));
|
||||
}
|
||||
if (Object.keys(rangeKeys).length < 1) {
|
||||
columns.push(new RangeColumn({name: "Message"}, formatter));
|
||||
}
|
||||
|
||||
// We have all columns now; use them to initializer
|
||||
// the populator, which will use them to generate
|
||||
// actual rows and headers.
|
||||
populator = new EventListPopulator(columns);
|
||||
|
||||
// Initialize headers
|
||||
$scope.headers = populator.getHeaders();
|
||||
|
||||
// Fill in the contents of the rows.
|
||||
updateRows();
|
||||
}
|
||||
|
||||
$scope.$on("telemetryUpdate", updateRows);
|
||||
$scope.$watch("telemetry", setupColumns);
|
||||
}
|
||||
|
||||
return EventListController;
|
||||
|
||||
/**
|
||||
* A description of how to display a certain column of data in an
|
||||
* Events view.
|
||||
* @interface platform/features/events.EventColumn
|
||||
* @private
|
||||
*/
|
||||
/**
|
||||
* Get the title to display in this column's header.
|
||||
* @returns {string} the title to display
|
||||
* @method platform/features/events.EventColumn#getTitle
|
||||
*/
|
||||
/**
|
||||
* Get the text to display inside a row under this
|
||||
* column.
|
||||
* @param {DomainObject} domainObject the domain object associated
|
||||
* with this row
|
||||
* @param {TelemetrySeries} series the telemetry data associated
|
||||
* with this row
|
||||
* @param {number} index the index of the telemetry datum associated
|
||||
* with this row
|
||||
* @returns {string} the text to display
|
||||
* @method platform/features/events.EventColumn#getValue
|
||||
*/
|
||||
}
|
||||
);
|
||||
|
@ -1,163 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
|
||||
/**
|
||||
* The EventListPopulator is responsible for filling in the
|
||||
* values which should appear within columns of a event list
|
||||
* view, based on received telemetry data.
|
||||
* @constructor
|
||||
* @memberof platform/features/events
|
||||
* @param {Column[]} columns the columns to be populated
|
||||
*/
|
||||
function EventListPopulator(columns) {
|
||||
this.columns = columns;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up the most recent values from a set of data objects.
|
||||
* Returns an array of objects in the order in which data
|
||||
* should be displayed; each element is an object with
|
||||
* two properties:
|
||||
*
|
||||
* * objectIndex: The index of the domain object associated
|
||||
* with the data point to be displayed in that
|
||||
* row.
|
||||
* * pointIndex: The index of the data point itself, within
|
||||
* its data set.
|
||||
*
|
||||
* @param {Array<Telemetry>} datas an array of the most recent
|
||||
* data objects; expected to be in the same order
|
||||
* as the domain objects provided at constructor
|
||||
* @param {number} count the number of rows to provide
|
||||
*/
|
||||
function getLatestDataValues(datas, count) {
|
||||
var latest = [],
|
||||
candidate,
|
||||
candidateTime,
|
||||
used = datas.map(function () { return 0; });
|
||||
|
||||
// This algorithm is O(nk) for n rows and k telemetry elements;
|
||||
// one O(k) linear search for a max is made for each of n rows.
|
||||
// This could be done in O(n lg k + k lg k), using a priority
|
||||
// queue (where priority is max-finding) containing k initial
|
||||
// values. For n rows, pop the max from the queue and replenish
|
||||
// the queue with a value from the data at the same
|
||||
// objectIndex, if available.
|
||||
// But k is small, so this might not give an observable
|
||||
// improvement in performance.
|
||||
|
||||
// Find the most recent unused data point (this will be used
|
||||
// in a loop to find and the N most recent data points)
|
||||
function findCandidate(data, i) {
|
||||
var nextTime,
|
||||
pointCount = data.getPointCount(),
|
||||
pointIndex = pointCount - used[i] - 1;
|
||||
if (data && pointIndex >= 0) {
|
||||
nextTime = data.getDomainValue(pointIndex);
|
||||
if (nextTime > candidateTime) {
|
||||
candidateTime = nextTime;
|
||||
candidate = {
|
||||
objectIndex: i,
|
||||
pointIndex: pointIndex
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Assemble a list of the most recent data points
|
||||
while (latest.length < count) {
|
||||
// Reset variables pre-search
|
||||
candidateTime = Number.NEGATIVE_INFINITY;
|
||||
candidate = undefined;
|
||||
|
||||
// Linear search for most recent
|
||||
datas.forEach(findCandidate);
|
||||
|
||||
if (candidate) {
|
||||
// Record this data point - it is the most recent
|
||||
latest.push(candidate);
|
||||
|
||||
// Track the data points used so we can look farther back
|
||||
// in the data set on the next iteration
|
||||
used[candidate.objectIndex] = used[candidate.objectIndex] + 1;
|
||||
} else {
|
||||
// Ran out of candidates; not enough data points
|
||||
// available to fill all rows.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return latest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text which should appear in headers for the
|
||||
* provided columns.
|
||||
* @memberof platform/features/events.EventListPopulator
|
||||
* @returns {string[]} column headers
|
||||
*/
|
||||
EventListPopulator.prototype.getHeaders = function () {
|
||||
return this.columns.map(function (column) {
|
||||
return column.getTitle();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the contents of rows for the event list view.
|
||||
* @param {TelemetrySeries[]} datas the data sets
|
||||
* @param {DomainObject[]} objects the domain objects which
|
||||
* provided the data sets; these should match
|
||||
* index-to-index with the `datas` argument
|
||||
* @param {number} count the number of rows to populate
|
||||
* @memberof platform/features/events.EventListPopulator
|
||||
* @returns {string[][]} an array of rows, each of which
|
||||
* is an array of values which should appear
|
||||
* in that row
|
||||
*/
|
||||
EventListPopulator.prototype.getRows = function (datas, objects, count) {
|
||||
var values = getLatestDataValues(datas, count),
|
||||
columns = this.columns;
|
||||
|
||||
// Each value will become a row, which will contain
|
||||
// some value in each column (rendering by the
|
||||
// column object itself)
|
||||
// Additionally, we want to display the rows in reverse
|
||||
// order. (i.e. from the top to the bottom of the page)
|
||||
return values.map(function (value) {
|
||||
return columns.map(function (column) {
|
||||
return column.getValue(
|
||||
objects[value.objectIndex],
|
||||
datas[value.objectIndex],
|
||||
value.pointIndex
|
||||
);
|
||||
});
|
||||
}).reverse();
|
||||
};
|
||||
|
||||
return EventListPopulator;
|
||||
|
||||
}
|
||||
);
|
@ -1,60 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Module defining DomainColumn. Created by vwoeltje on 11/18/14.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
|
||||
/**
|
||||
* A column which will report telemetry range values
|
||||
* (typically, measurements.) Used by the ScrollingListController.
|
||||
*
|
||||
* @memberof platform/features/events
|
||||
* @constructor
|
||||
* @implements {platform/features/events.EventsColumn}
|
||||
* @param rangeMetadata an object with the machine- and human-
|
||||
* readable names for this range (in `key` and `name`
|
||||
* fields, respectively.)
|
||||
* @param {TelemetryFormatter} telemetryFormatter the telemetry
|
||||
* formatting service, for making values human-readable.
|
||||
*/
|
||||
function RangeColumn(rangeMetadata, telemetryFormatter) {
|
||||
this.rangeMetadata = rangeMetadata;
|
||||
this.telemetryFormatter = telemetryFormatter;
|
||||
}
|
||||
|
||||
RangeColumn.prototype.getTitle = function () {
|
||||
return this.rangeMetadata.name;
|
||||
};
|
||||
RangeColumn.prototype.getValue = function (domainObject, data, index) {
|
||||
var rangeKey = this.rangeMetadata.key;
|
||||
return this.telemetryFormatter.formatRangeValue(
|
||||
data.getRangeValue(index, rangeKey)
|
||||
);
|
||||
};
|
||||
|
||||
return RangeColumn;
|
||||
}
|
||||
);
|
@ -1,72 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Module defining MCTDataTable. Created by shale on 06/22/2015.
|
||||
*/
|
||||
define(
|
||||
['text!../../res/templates/mct-data-table.html'],
|
||||
function (dataTableTemplate) {
|
||||
|
||||
function MCTDataTable($window) {
|
||||
return {
|
||||
restrict: "E",
|
||||
template: dataTableTemplate,
|
||||
scope: {
|
||||
headers: "=",
|
||||
rows: "=",
|
||||
ascendingScroll: "="
|
||||
},
|
||||
link: function ($scope, $element) {
|
||||
var currentHeight,
|
||||
previousHeight,
|
||||
scrollParent;
|
||||
|
||||
// If the scroll is set to ascending, we want to
|
||||
// check when elements are added to the table, and move the scroll
|
||||
// bar accordingly.
|
||||
// (When viewing at the bottom of the page, the scroll bar will
|
||||
// stay at the bottom despite additions to the table)
|
||||
if ($scope.ascendingScroll) {
|
||||
$scope.$watch("rows", function () {
|
||||
// Wait until the page as been repainted (otherwise the
|
||||
// height will always be zero)
|
||||
$window.requestAnimationFrame(function () {
|
||||
previousHeight = currentHeight;
|
||||
// The height of the table body
|
||||
currentHeight = $element[0].firstElementChild.firstElementChild.nextElementSibling.clientHeight;
|
||||
|
||||
// One of the parents is a div that has vscroll
|
||||
scrollParent = $element[0].parentElement.parentElement.parentElement.parentElement.parentElement;
|
||||
|
||||
// Move the scrollbar down the amount that the height has changed
|
||||
scrollParent.scrollTop = scrollParent.scrollTop + (currentHeight - previousHeight);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return MCTDataTable;
|
||||
}
|
||||
);
|
@ -1,65 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Module defining MessagesViewPolicy. Created by shale on 06/24/2015.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
|
||||
/**
|
||||
* Policy controlling when the Messages view should be avaliable.
|
||||
* @memberof platform/features/events
|
||||
* @constructor
|
||||
* @implements {Policy.<View, DomainObject>}
|
||||
*/
|
||||
function MessagesViewPolicy() {}
|
||||
|
||||
function hasStringTelemetry(domainObject) {
|
||||
var telemetry = domainObject &&
|
||||
domainObject.getCapability('telemetry'),
|
||||
metadata = telemetry ? telemetry.getMetadata() : {},
|
||||
ranges = metadata.ranges || [];
|
||||
|
||||
return ranges.some(function (range) {
|
||||
return range.format === 'string';
|
||||
});
|
||||
}
|
||||
|
||||
MessagesViewPolicy.prototype.allow = function (view, domainObject) {
|
||||
// This policy only applies for the Messages view
|
||||
if (view.key === 'messages') {
|
||||
// The Messages view is allowed only if the domain
|
||||
// object has string telemetry
|
||||
if (!hasStringTelemetry(domainObject)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Like all policies, allow by default.
|
||||
return true;
|
||||
};
|
||||
|
||||
return MessagesViewPolicy;
|
||||
}
|
||||
);
|
@ -1,82 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* EventSpec. Created by vwoeltje on 11/6/14. Modified by shale on 06/23/2015.
|
||||
*/
|
||||
define(
|
||||
["../src/DomainColumn"],
|
||||
function (DomainColumn) {
|
||||
|
||||
var TEST_DOMAIN_VALUE = "some formatted domain value";
|
||||
|
||||
describe("An event list domain column", function () {
|
||||
var mockDataSet,
|
||||
testMetadata,
|
||||
mockFormatter,
|
||||
column;
|
||||
|
||||
beforeEach(function () {
|
||||
mockDataSet = jasmine.createSpyObj(
|
||||
"data",
|
||||
[ "getDomainValue" ]
|
||||
);
|
||||
mockFormatter = jasmine.createSpyObj(
|
||||
"formatter",
|
||||
[ "formatDomainValue", "formatRangeValue" ]
|
||||
);
|
||||
testMetadata = {
|
||||
key: "testKey",
|
||||
name: "Test Name"
|
||||
};
|
||||
mockFormatter.formatDomainValue.andReturn(TEST_DOMAIN_VALUE);
|
||||
|
||||
column = new DomainColumn(testMetadata, mockFormatter);
|
||||
});
|
||||
|
||||
it("reports a column header from domain metadata", function () {
|
||||
expect(column.getTitle()).toEqual("Test Name");
|
||||
});
|
||||
|
||||
it("looks up data from a data set", function () {
|
||||
column.getValue(undefined, mockDataSet, 42);
|
||||
expect(mockDataSet.getDomainValue)
|
||||
.toHaveBeenCalledWith(42, "testKey");
|
||||
});
|
||||
|
||||
it("formats domain values as time", function () {
|
||||
mockDataSet.getDomainValue.andReturn(402513731000);
|
||||
|
||||
// Should have just given the value the formatter gave
|
||||
expect(column.getValue(undefined, mockDataSet, 42))
|
||||
.toEqual(TEST_DOMAIN_VALUE);
|
||||
|
||||
// Make sure that service interactions were as expected
|
||||
expect(mockFormatter.formatDomainValue)
|
||||
.toHaveBeenCalledWith(402513731000);
|
||||
expect(mockFormatter.formatRangeValue)
|
||||
.not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
@ -1,108 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* EventSpec. Created by shale on 06/24/2015.
|
||||
*/
|
||||
define(
|
||||
["../src/EventListController"],
|
||||
function (EventListController) {
|
||||
|
||||
describe("The event list controller", function () {
|
||||
var mockScope,
|
||||
mockTelemetry,
|
||||
testMetadata,
|
||||
controller;
|
||||
|
||||
beforeEach(function () {
|
||||
mockScope = jasmine.createSpyObj(
|
||||
"$scope",
|
||||
[ "$on", "$watch" ]
|
||||
);
|
||||
mockTelemetry = jasmine.createSpyObj(
|
||||
"telemetryController",
|
||||
[ "getResponse", "getMetadata", "getTelemetryObjects" ]
|
||||
);
|
||||
testMetadata = [
|
||||
{
|
||||
domains: [
|
||||
{ key: "d0", name: "D0" },
|
||||
{ key: "d1", name: "D1" }
|
||||
],
|
||||
ranges: [
|
||||
{ key: "r0", name: "R0" },
|
||||
{ key: "r1", name: "R1" }
|
||||
]
|
||||
},
|
||||
{
|
||||
domains: [
|
||||
{ key: "d0", name: "D0" },
|
||||
{ key: "d2", name: "D2" }
|
||||
],
|
||||
ranges: [
|
||||
{ key: "r0", name: "R0" }
|
||||
]
|
||||
}
|
||||
];
|
||||
mockTelemetry.getMetadata.andReturn(testMetadata);
|
||||
mockTelemetry.getResponse.andReturn([]);
|
||||
mockTelemetry.getTelemetryObjects.andReturn([]);
|
||||
mockScope.telemetry = mockTelemetry;
|
||||
controller = new EventListController(mockScope);
|
||||
});
|
||||
|
||||
it("listens for telemetry data updates", function () {
|
||||
expect(mockScope.$on).toHaveBeenCalledWith(
|
||||
"telemetryUpdate",
|
||||
jasmine.any(Function)
|
||||
);
|
||||
});
|
||||
|
||||
it("watches for telemetry controller changes", function () {
|
||||
expect(mockScope.$watch).toHaveBeenCalledWith(
|
||||
"telemetry",
|
||||
jasmine.any(Function)
|
||||
);
|
||||
});
|
||||
|
||||
it("provides a column for each unique domain and range", function () {
|
||||
// Should have five columns based on metadata above,
|
||||
// (d0, d1, d2, r0, r1)
|
||||
mockScope.$watch.mostRecentCall.args[1](mockTelemetry);
|
||||
expect(mockScope.headers).toEqual(["D0", "D1", "D2", "R0", "R1"]);
|
||||
});
|
||||
|
||||
it("does not throw if telemetry controller is undefined", function () {
|
||||
// Just a general robustness check
|
||||
mockScope.telemetry = undefined;
|
||||
expect(mockScope.$watch.mostRecentCall.args[1])
|
||||
.not.toThrow();
|
||||
});
|
||||
|
||||
it("provides default columns if domain/range metadata is unavailable", function () {
|
||||
mockTelemetry.getMetadata.andReturn([]);
|
||||
mockScope.$watch.mostRecentCall.args[1](mockTelemetry);
|
||||
expect(mockScope.headers).toEqual(["Time", "Message"]);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
@ -1,101 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* EventSpec. Created by shale on 06/24/2015.
|
||||
*/
|
||||
define(
|
||||
["../src/EventListPopulator"],
|
||||
function (EventListPopulator) {
|
||||
|
||||
describe("The event list populator", function () {
|
||||
var mockColumns,
|
||||
mockDatas,
|
||||
mockDomainObjects,
|
||||
populator;
|
||||
|
||||
function makeMockColumn(name, index) {
|
||||
var mockColumn = jasmine.createSpyObj(
|
||||
"column" + index,
|
||||
[ "getTitle", "getValue" ]
|
||||
);
|
||||
mockColumn.getTitle.andReturn(name);
|
||||
mockColumn.getValue.andCallFake(function (obj, data, i) {
|
||||
return data.getDomainValue(i);
|
||||
});
|
||||
return mockColumn;
|
||||
}
|
||||
|
||||
function makeMockData(bias, index) {
|
||||
var mockData = jasmine.createSpyObj(
|
||||
"data" + index,
|
||||
[ "getDomainValue", "getPointCount" ]
|
||||
);
|
||||
mockData.getPointCount.andReturn(1000);
|
||||
mockData.getDomainValue.andCallFake(function (i) {
|
||||
return i + bias;
|
||||
});
|
||||
return mockData;
|
||||
}
|
||||
|
||||
function makeMockDomainObject(name, index) {
|
||||
var mockDomainObject = jasmine.createSpyObj(
|
||||
"domainObject" + index,
|
||||
[ "getId", "getModel" ]
|
||||
);
|
||||
return mockDomainObject;
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
mockColumns = ["A", "B", "C", "D"].map(makeMockColumn);
|
||||
mockDatas = [ 10, 0, 3 ].map(makeMockData);
|
||||
mockDomainObjects = ["A", "B", "C"].map(makeMockDomainObject);
|
||||
populator = new EventListPopulator(mockColumns);
|
||||
});
|
||||
|
||||
it("returns column headers", function () {
|
||||
expect(populator.getHeaders()).toEqual(["A", "B", "C", "D"]);
|
||||
});
|
||||
|
||||
it("provides rows on request, with all columns in each row", function () {
|
||||
var rows = populator.getRows(mockDatas, mockDomainObjects, 84);
|
||||
expect(rows.length).toEqual(84);
|
||||
rows.forEach(function (row) {
|
||||
expect(row.length).toEqual(4); // number of columns
|
||||
});
|
||||
});
|
||||
|
||||
it("returns rows in most-recent-last order", function () {
|
||||
var rows = populator.getRows(mockDatas, mockDomainObjects, 84),
|
||||
previous = Number.NEGATIVE_INFINITY;
|
||||
|
||||
// Should always be most-recent-last
|
||||
rows.forEach(function (row) {
|
||||
expect(row[0]).not.toBeLessThan(previous);
|
||||
previous = row[0];
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
@ -1,79 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* EventSpec. Created by vwoeltje on 11/6/14. Modified by shale on 06/23/2015.
|
||||
*/
|
||||
define(
|
||||
["../src/RangeColumn"],
|
||||
function (RangeColumn) {
|
||||
|
||||
var TEST_RANGE_VALUE = "some formatted range value";
|
||||
|
||||
describe("An event list range column", function () {
|
||||
var mockDataSet,
|
||||
testMetadata,
|
||||
mockFormatter,
|
||||
column;
|
||||
|
||||
beforeEach(function () {
|
||||
mockDataSet = jasmine.createSpyObj(
|
||||
"data",
|
||||
[ "getRangeValue" ]
|
||||
);
|
||||
mockFormatter = jasmine.createSpyObj(
|
||||
"formatter",
|
||||
[ "formatDomainValue", "formatRangeValue" ]
|
||||
);
|
||||
testMetadata = {
|
||||
key: "testKey",
|
||||
name: "Test Name"
|
||||
};
|
||||
mockFormatter.formatRangeValue.andReturn(TEST_RANGE_VALUE);
|
||||
|
||||
column = new RangeColumn(testMetadata, mockFormatter);
|
||||
});
|
||||
|
||||
it("reports a column header from range metadata", function () {
|
||||
expect(column.getTitle()).toEqual("Test Name");
|
||||
});
|
||||
|
||||
it("looks up data from a data set", function () {
|
||||
column.getValue(undefined, mockDataSet, 42);
|
||||
expect(mockDataSet.getRangeValue)
|
||||
.toHaveBeenCalledWith(42, "testKey");
|
||||
});
|
||||
|
||||
it("formats range values as time", function () {
|
||||
mockDataSet.getRangeValue.andReturn(123.45678);
|
||||
expect(column.getValue(undefined, mockDataSet, 42))
|
||||
.toEqual(TEST_RANGE_VALUE);
|
||||
|
||||
// Make sure that service interactions were as expected
|
||||
expect(mockFormatter.formatRangeValue)
|
||||
.toHaveBeenCalledWith(123.45678);
|
||||
expect(mockFormatter.formatDomainValue)
|
||||
.not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
@ -1,78 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* EventSpec. Created by shale on 06/24/2015.
|
||||
*/
|
||||
define(
|
||||
["../../src/policies/MessagesViewPolicy"],
|
||||
function (MessagesViewPolicy) {
|
||||
|
||||
describe("The messages view policy", function () {
|
||||
var mockDomainObject,
|
||||
mockTelemetry,
|
||||
testType,
|
||||
testView,
|
||||
testMetadata,
|
||||
policy;
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
testView = { key: "string" };
|
||||
testMetadata = {};
|
||||
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
'domainObject',
|
||||
['getModel', 'getCapability']
|
||||
);
|
||||
mockTelemetry = jasmine.createSpyObj(
|
||||
'telemetry',
|
||||
['getMetadata']
|
||||
);
|
||||
|
||||
mockDomainObject.getModel.andCallFake(function () {
|
||||
return {type: testType};
|
||||
});
|
||||
mockDomainObject.getCapability.andCallFake(function (c) {
|
||||
return c === 'telemetry' ? mockTelemetry : undefined;
|
||||
});
|
||||
mockTelemetry.getMetadata.andReturn(testMetadata);
|
||||
|
||||
policy = new MessagesViewPolicy();
|
||||
});
|
||||
|
||||
it("disallows the message view for objects without string telemetry", function () {
|
||||
testMetadata.ranges = [ { format: 'notString' } ];
|
||||
expect(policy.allow({ key: 'messages' }, mockDomainObject)).toBeFalsy();
|
||||
});
|
||||
|
||||
it("allows the message view for objects with string telemetry", function () {
|
||||
testMetadata.ranges = [ { format: 'string' } ];
|
||||
expect(policy.allow({ key: 'messages' }, mockDomainObject)).toBeTruthy();
|
||||
});
|
||||
|
||||
it("returns true when the current view is not the Messages view", function () {
|
||||
expect(policy.allow({ key: 'notMessages' }, mockDomainObject)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
@ -56,7 +56,7 @@ define([
|
||||
{
|
||||
"key": "layout",
|
||||
"name": "Display Layout",
|
||||
"glyph": "L",
|
||||
"glyph": "\u004c",
|
||||
"type": "layout",
|
||||
"template": layoutTemplate,
|
||||
"editable": true,
|
||||
@ -80,28 +80,28 @@ define([
|
||||
"items": [
|
||||
{
|
||||
"method": "add",
|
||||
"glyph": "+",
|
||||
"glyph": "\u002b",
|
||||
"control": "menu-button",
|
||||
"text": "Add",
|
||||
"options": [
|
||||
{
|
||||
"name": "Box",
|
||||
"glyph": "à",
|
||||
"glyph": "\u00e0",
|
||||
"key": "fixed.box"
|
||||
},
|
||||
{
|
||||
"name": "Line",
|
||||
"glyph": "â",
|
||||
"glyph": "\u00e2",
|
||||
"key": "fixed.line"
|
||||
},
|
||||
{
|
||||
"name": "Text",
|
||||
"glyph": "ä",
|
||||
"glyph": "\u00e4",
|
||||
"key": "fixed.text"
|
||||
},
|
||||
{
|
||||
"name": "Image",
|
||||
"glyph": "ã",
|
||||
"glyph": "\u00e3",
|
||||
"key": "fixed.image"
|
||||
}
|
||||
]
|
||||
@ -117,22 +117,22 @@ define([
|
||||
"options": [
|
||||
{
|
||||
"name": "Move to Top",
|
||||
"glyph": "^",
|
||||
"glyph": "\u00eb",
|
||||
"key": "top"
|
||||
},
|
||||
{
|
||||
"name": "Move Up",
|
||||
"glyph": "^",
|
||||
"glyph": "\u005e",
|
||||
"key": "up"
|
||||
},
|
||||
{
|
||||
"name": "Move Down",
|
||||
"glyph": "v",
|
||||
"glyph": "\u0076",
|
||||
"key": "down"
|
||||
},
|
||||
{
|
||||
"name": "Move to Bottom",
|
||||
"glyph": "v",
|
||||
"glyph": "\u00ee",
|
||||
"key": "bottom"
|
||||
}
|
||||
]
|
||||
@ -261,8 +261,9 @@ define([
|
||||
{
|
||||
"key": "layout",
|
||||
"name": "Display Layout",
|
||||
"glyph": "L",
|
||||
"description": "A layout in which multiple telemetry panels may be displayed.",
|
||||
"glyph": "\u004c",
|
||||
"description": "Assemble other objects and components together into a reusable screen layout. Working in a simple canvas workspace, simply drag in the objects you want, position and size them. Save your design and view or edit it at any time.",
|
||||
"priority": 900,
|
||||
"features": "creation",
|
||||
"model": {
|
||||
"composition": []
|
||||
@ -276,12 +277,12 @@ define([
|
||||
{
|
||||
"name": "Horizontal grid (px)",
|
||||
"control": "textfield",
|
||||
"cssclass": "l-small l-numeric"
|
||||
"cssclass": "l-input-sm l-numeric"
|
||||
},
|
||||
{
|
||||
"name": "Vertical grid (px)",
|
||||
"control": "textfield",
|
||||
"cssclass": "l-small l-numeric"
|
||||
"cssclass": "l-input-sm l-numeric"
|
||||
}
|
||||
],
|
||||
"key": "layoutGrid",
|
||||
@ -294,6 +295,7 @@ define([
|
||||
"name": "Telemetry Panel",
|
||||
"glyph": "t",
|
||||
"description": "A panel for collecting telemetry elements.",
|
||||
"priority": 899,
|
||||
"delegates": [
|
||||
"telemetry"
|
||||
],
|
||||
|
@ -36,8 +36,9 @@ define([
|
||||
{
|
||||
"key": "example.page",
|
||||
"name": "Web Page",
|
||||
"glyph": "ê",
|
||||
"description": "A component to display a web page or image with a valid URL. Can be added to a Display Layout.",
|
||||
"glyph": "\u00ea",
|
||||
"description": "Embed a web page or web-based image in a resizeable window component. Can be added to Display Layouts. Note that the URL being embedded must allow iframing.",
|
||||
"priority": 50,
|
||||
"features": [
|
||||
"creation"
|
||||
],
|
||||
@ -47,7 +48,8 @@ define([
|
||||
"name": "URL",
|
||||
"control": "textfield",
|
||||
"pattern": "^(ftp|https?)\\:\\/\\/\\w+(\\.\\w+)*(\\:\\d+)?(\\/\\S*)*$",
|
||||
"required": true
|
||||
"required": true,
|
||||
"cssclass": "l-input-lg"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -19,58 +19,52 @@
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<style>
|
||||
.l-inspect .l-inspector-part .no-margin .form {
|
||||
margin-left: 0;
|
||||
}
|
||||
.reduced-min-width .form .form-row > .label {
|
||||
min-width: 80px;
|
||||
}
|
||||
</style>
|
||||
<div ng-controller="PlotOptionsController" class="flex-elem grows l-inspector-part">
|
||||
<em class="t-inspector-part-header" title="Display properties for this object">Display</em>
|
||||
<em class="t-inspector-part-header" title="Display properties for this object">Plot Options</em>
|
||||
<mct-form
|
||||
ng-model="configuration.plot.xAxis"
|
||||
structure="xAxisForm"
|
||||
name="xAxisFormState"
|
||||
class="flex-elem l-flex-row no-validate no-margin reduced-min-width">
|
||||
class="flex-elem l-flex-row no-validate no-margin">
|
||||
</mct-form>
|
||||
<mct-form
|
||||
ng-model="configuration.plot.yAxis"
|
||||
structure="yAxisForm"
|
||||
name="yAxisFormState"
|
||||
class="flex-elem l-flex-row no-validate no-margin reduced-min-width">
|
||||
class="flex-elem l-flex-row no-validate no-margin">
|
||||
</mct-form>
|
||||
<div class="section-header ng-binding ng-scope">
|
||||
Plot Series
|
||||
</div>
|
||||
<ul class="first flex-elem grows vscroll">
|
||||
<ul class="tree">
|
||||
<li ng-repeat="child in children">
|
||||
<span ng-controller="ToggleController as toggle">
|
||||
<span ng-controller="TreeNodeController as treeNode">
|
||||
<span class="tree-item menus-to-left">
|
||||
<span
|
||||
class='ui-symbol view-control flex-elem has-children'
|
||||
ng-class="{ expanded: toggle.isActive() }"
|
||||
ng-click="toggle.toggle(); treeNode.trackExpansion()">
|
||||
<div class="form">
|
||||
<div class="section-header ng-binding ng-scope">
|
||||
Plot Series
|
||||
</div>
|
||||
<ul class="first flex-elem grows vscroll">
|
||||
<ul class="tree">
|
||||
<li ng-repeat="child in children">
|
||||
<span ng-controller="ToggleController as toggle">
|
||||
<span ng-controller="TreeNodeController as treeNode">
|
||||
<span class="tree-item menus-to-left">
|
||||
<span
|
||||
class='ui-symbol view-control flex-elem has-children'
|
||||
ng-class="{ expanded: toggle.isActive() }"
|
||||
ng-click="toggle.toggle(); treeNode.trackExpansion()">
|
||||
</span>
|
||||
<mct-representation
|
||||
class="rep-object-label"
|
||||
key="'label'"
|
||||
mct-object="child">
|
||||
</mct-representation>
|
||||
</span>
|
||||
<mct-representation
|
||||
class="rep-object-label"
|
||||
key="'label'"
|
||||
mct-object="child">
|
||||
</mct-representation>
|
||||
</span>
|
||||
<mct-form
|
||||
ng-class="{hidden: !toggle.isActive()}"
|
||||
ng-model="configuration.plot.series[$index]"
|
||||
structure="plotSeriesForm"
|
||||
name="plotOptionsState"
|
||||
class="flex-elem l-flex-row no-validate">
|
||||
</mct-form>
|
||||
</span>
|
||||
<mct-form
|
||||
ng-class="{hidden: !toggle.isActive()}"
|
||||
ng-model="configuration.plot.series[$index]"
|
||||
structure="plotSeriesForm"
|
||||
name="plotOptionsState"
|
||||
class="flex-elem l-flex-row l-controls-first no-validate">
|
||||
</mct-form>
|
||||
</span>
|
||||
</li>
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
@ -46,9 +46,9 @@ define(
|
||||
'control': 'select',
|
||||
'key': 'key',
|
||||
'options': [
|
||||
{'name':'scet', 'value': 'scet'},
|
||||
{'name':'sclk', 'value': 'sclk'},
|
||||
{'name':'lst', 'value': 'lst'}
|
||||
{'name':'SCET', 'value': 'scet'},
|
||||
{'name':'SCLK', 'value': 'sclk'},
|
||||
{'name':'LST', 'value': 'lst'}
|
||||
]
|
||||
}
|
||||
]
|
||||
@ -62,6 +62,16 @@ define(
|
||||
// itself.
|
||||
'name': 'y-axis',
|
||||
'rows': [
|
||||
{
|
||||
'name': 'Range',
|
||||
'control': 'select',
|
||||
'key': 'key',
|
||||
'options': [
|
||||
{'name':'EU', 'value': 'eu'},
|
||||
{'name':'DN', 'value': 'dn'},
|
||||
{'name':'Status', 'value': 'status'}
|
||||
]
|
||||
},
|
||||
{
|
||||
'name': 'Autoscale',
|
||||
'control': 'checkbox',
|
||||
@ -71,23 +81,15 @@ define(
|
||||
'name': 'Min',
|
||||
'control': 'textfield',
|
||||
'key': 'min',
|
||||
'pattern': '[0-9]'
|
||||
'pattern': '[0-9]',
|
||||
'inputsize' : 'sm'
|
||||
},
|
||||
{
|
||||
'name': 'Max',
|
||||
'control': 'textfield',
|
||||
'key': 'max',
|
||||
'pattern': '[0-9]'
|
||||
},
|
||||
{
|
||||
'name': 'Range',
|
||||
'control': 'select',
|
||||
'key': 'key',
|
||||
'options': [
|
||||
{'name':'eu', 'value': 'eu'},
|
||||
{'name':'dn', 'value': 'dn'},
|
||||
{'name':'status', 'value': 'status'}
|
||||
]
|
||||
'pattern': '[0-9]',
|
||||
'inputsize' : 'sm'
|
||||
}
|
||||
]
|
||||
}]
|
||||
@ -108,7 +110,8 @@ define(
|
||||
{
|
||||
'name': 'Markers',
|
||||
'control': 'checkbox',
|
||||
'key': 'markers'
|
||||
'key': 'markers',
|
||||
'layout': 'control-first'
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -118,19 +121,22 @@ define(
|
||||
'name': 'No Line',
|
||||
'control': 'radio',
|
||||
'key': 'lineType',
|
||||
'value': 'noLine'
|
||||
'value': 'noLine',
|
||||
'layout': 'control-first'
|
||||
},
|
||||
{
|
||||
'name': 'Step Line',
|
||||
'control': 'radio',
|
||||
'key': 'lineType',
|
||||
'value': 'stepLine'
|
||||
'value': 'stepLine',
|
||||
'layout': 'control-first'
|
||||
},
|
||||
{
|
||||
'name': 'Linear Line',
|
||||
'control': 'radio',
|
||||
'key': 'lineType',
|
||||
'value': 'linearLine'
|
||||
'value': 'linearLine',
|
||||
'layout': 'control-first'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -24,6 +24,8 @@ define(
|
||||
[],
|
||||
function () {
|
||||
|
||||
var DIGITS = 3;
|
||||
|
||||
/**
|
||||
* Wraps a `TelemetryFormatter` to provide formats for domain and
|
||||
* range values; provides a single place to track domain/range
|
||||
@ -61,6 +63,10 @@ define(
|
||||
};
|
||||
|
||||
PlotTelemetryFormatter.prototype.formatRangeValue = function (value) {
|
||||
if (typeof value === 'number') {
|
||||
return value.toFixed(DIGITS);
|
||||
}
|
||||
|
||||
return this.telemetryFormatter
|
||||
.formatRangeValue(value, this.rangeFormat);
|
||||
};
|
||||
|
@ -53,14 +53,17 @@ define(
|
||||
.toHaveBeenCalledWith(12321, domainFormat);
|
||||
});
|
||||
|
||||
it("includes format in formatRangeValue calls", function () {
|
||||
it("includes format in formatRangeValue calls for strings", function () {
|
||||
mockFormatter.formatRangeValue.andReturn("formatted!");
|
||||
expect(formatter.formatRangeValue(12321))
|
||||
expect(formatter.formatRangeValue('foo'))
|
||||
.toEqual("formatted!");
|
||||
expect(mockFormatter.formatRangeValue)
|
||||
.toHaveBeenCalledWith(12321, rangeFormat);
|
||||
.toHaveBeenCalledWith('foo', rangeFormat);
|
||||
});
|
||||
|
||||
it("formats numeric values with three fixed digits", function () {
|
||||
expect(formatter.formatRangeValue(10)).toEqual("10.000");
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -1,82 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
"./src/RTEventListController",
|
||||
"./src/directives/MCTRTDataTable",
|
||||
"./src/policies/RTMessagesViewPolicy",
|
||||
"text!./res/templates/rtmessages.html",
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
RTEventListController,
|
||||
MCTRTDataTable,
|
||||
RTMessagesViewPolicy,
|
||||
rtmessagesTemplate,
|
||||
legacyRegistry
|
||||
) {
|
||||
|
||||
legacyRegistry.register("platform/features/rtevents", {
|
||||
"name": "Event Messages",
|
||||
"description": "List of time-ordered event messages",
|
||||
"extensions": {
|
||||
"views": [
|
||||
{
|
||||
"key": "rtmessages",
|
||||
"name": "RT Messages",
|
||||
"glyph": "5",
|
||||
"description": "Scrolling list of real time messages.",
|
||||
"template": rtmessagesTemplate,
|
||||
"needs": [
|
||||
"telemetry"
|
||||
],
|
||||
"delegation": true
|
||||
}
|
||||
],
|
||||
"controllers": [
|
||||
{
|
||||
"key": "RTEventListController",
|
||||
"implementation": RTEventListController,
|
||||
"depends": [
|
||||
"$scope",
|
||||
"telemetryHandler",
|
||||
"telemetryFormatter"
|
||||
]
|
||||
}
|
||||
],
|
||||
"directives": [
|
||||
{
|
||||
"key": "mctRtDataTable",
|
||||
"implementation": MCTRTDataTable,
|
||||
"depends": [
|
||||
"$window"
|
||||
]
|
||||
}
|
||||
],
|
||||
"policies": [
|
||||
{
|
||||
"category": "view",
|
||||
"implementation": RTMessagesViewPolicy
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
});
|
@ -1,37 +0,0 @@
|
||||
<!--
|
||||
Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
as represented by the Administrator of the National Aeronautics and Space
|
||||
Administration. All rights reserved.
|
||||
|
||||
Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0.
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
Open MCT Web includes source code licensed under additional open source
|
||||
licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<table class="tabular">
|
||||
<thead>
|
||||
<tr>
|
||||
<th ng-repeat="header in headers">
|
||||
{{header}}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="row in rows">
|
||||
<td ng-repeat="cell in row">
|
||||
{{cell}}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
@ -1,73 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Module defining DomainColumn. Created by vwoeltje on 11/18/14.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
|
||||
/**
|
||||
* A column which will report telemetry domain values
|
||||
* (typically, timestamps.) Used by the ScrollingListController.
|
||||
*
|
||||
* @memberof platform/features/rtevents
|
||||
* @constructor
|
||||
* @param domainMetadata an object with the machine- and human-
|
||||
* readable names for this domain (in `key` and `name`
|
||||
* fields, respectively.)
|
||||
* @param {TelemetryFormatter} telemetryFormatter the telemetry
|
||||
* formatting service, for making values human-readable.
|
||||
*/
|
||||
function DomainColumn(telemetryFormatter) {
|
||||
return {
|
||||
/**
|
||||
* Get the title to display in this column's header.
|
||||
* @returns {string} the title to display
|
||||
* @memberof platform/features/rtevents.DomainColumn#
|
||||
*/
|
||||
getTitle: function () {
|
||||
// At the moment there does not appear to be a way to get the
|
||||
// column's title through metadata for real time telemetry
|
||||
return "Time";
|
||||
},
|
||||
/**
|
||||
* Get the text to display inside a row under this
|
||||
* column.
|
||||
* @returns {string} the text to display
|
||||
* @memberof platform/features/rtevents.DomainColumn#
|
||||
*/
|
||||
getValue: function (domainObject, handle) {
|
||||
return {
|
||||
text: telemetryFormatter.formatDomainValue(
|
||||
handle.getDomainValue(domainObject)
|
||||
)
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return DomainColumn;
|
||||
}
|
||||
);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user