Merge branch 'open-master' into open1317limits2
WTD-1405 Conflicts: platform/features/layout/res/templates/elements/telemetry.html
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
{
|
||||
"key": "BrowseController",
|
||||
"implementation": "BrowseController.js",
|
||||
"depends": [ "$scope", "$route", "$location", "objectService", "navigationService", "urlService"]
|
||||
"depends": [ "$scope", "$route", "$location", "objectService", "navigationService", "urlService" ]
|
||||
},
|
||||
{
|
||||
"key": "BrowseObjectController",
|
||||
@@ -77,12 +77,7 @@
|
||||
{
|
||||
"key": "navigationService",
|
||||
"implementation": "navigation/NavigationService.js"
|
||||
},
|
||||
{
|
||||
"key": "urlService",
|
||||
"implementation": "services/UrlService.js",
|
||||
"depends": [ "$location" ]
|
||||
},
|
||||
},
|
||||
{
|
||||
"key": "creationService",
|
||||
"implementation": "creation/CreationService.js",
|
||||
@@ -99,18 +94,20 @@
|
||||
"key": "window",
|
||||
"name": "Open in a new tab",
|
||||
"implementation": "windowing/NewTabAction.js",
|
||||
"description": "Open this object in a new tab",
|
||||
"description": "Open in a new browser tab",
|
||||
"category": ["view-control", "contextual"],
|
||||
"depends": [ "urlService", "$window" ],
|
||||
"group": "windowing",
|
||||
"glyph": "y"
|
||||
"glyph": "y",
|
||||
"priority": "preferred"
|
||||
},
|
||||
{
|
||||
"key": "fullscreen",
|
||||
"implementation": "windowing/FullscreenAction.js",
|
||||
"category": "view-control",
|
||||
"group": "windowing",
|
||||
"glyph": "z"
|
||||
"glyph": "z",
|
||||
"priority": "default"
|
||||
}
|
||||
],
|
||||
"views": [
|
||||
|
||||
@@ -22,10 +22,9 @@
|
||||
<div content="jquery-wrapper" class="abs holder-all browse-mode">
|
||||
<mct-include key="'topbar-browse'"></mct-include>
|
||||
<div class="holder browse-area s-browse-area abs" ng-controller="BrowseController">
|
||||
<div class='split-layout vertical contents abs'
|
||||
ng-controller="SplitPaneController as splitter">
|
||||
<mct-split-pane class='contents abs' anchor='left'>
|
||||
<div class='split-pane-component treeview pane'
|
||||
ng-style="{ width: splitter.state() + 'px'}">
|
||||
style="min-width: 150px; max-width: 800px; width: 25%;">
|
||||
<mct-representation key="'create-button'" mct-object="navigatedObject">
|
||||
</mct-representation>
|
||||
<div class='holder tree-holder abs'>
|
||||
@@ -35,18 +34,14 @@
|
||||
</mct-representation>
|
||||
</div>
|
||||
</div>
|
||||
<div class="splitter"
|
||||
ng-style="{ left: splitter.state() + 'px'}"
|
||||
mct-drag-down="splitter.startMove()"
|
||||
mct-drag="splitter.move(delta[0])"></div>
|
||||
<div class='split-pane-component items pane'
|
||||
ng-style="{ left: (splitter.state()+4) + 'px', right: '0px' }">
|
||||
<mct-splitter></mct-splitter>
|
||||
<div class='split-pane-component items pane'>
|
||||
<div class='holder abs' id='content-area'>
|
||||
<mct-representation mct-object="navigatedObject" key="'browse-object'">
|
||||
</mct-representation>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mct-split-pane>
|
||||
</div>
|
||||
<mct-include key="'bottombar'"></mct-include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -52,13 +52,18 @@ define(
|
||||
unlisten;
|
||||
|
||||
unlisten = $scope.$on('$locationChangeSuccess', function () {
|
||||
$route.current = priorRoute;
|
||||
// Checks path to make sure /browse/ is at front
|
||||
// if so, change $route.current
|
||||
if ($location.path().indexOf("/browse/") === 0) {
|
||||
$route.current = priorRoute;
|
||||
}
|
||||
unlisten();
|
||||
});
|
||||
// urlService.urlFor used to adjust current
|
||||
// urlService.urlForLocation used to adjust current
|
||||
// path to new, addressed, path based on
|
||||
// domainObject
|
||||
$location.path(urlService.urlFor("browse", domainObject));
|
||||
$location.path(urlService.urlForLocation("browse", domainObject));
|
||||
|
||||
}
|
||||
|
||||
// Callback for updating the in-scope reference to the object
|
||||
|
||||
@@ -54,7 +54,11 @@ define(
|
||||
if (viewKey) {
|
||||
$location.search('view', viewKey);
|
||||
unlisten = $scope.$on('$locationChangeSuccess', function () {
|
||||
$route.current = priorRoute;
|
||||
// Checks path to make sure /browse/ is at front
|
||||
// if so, change $route.current
|
||||
if ($location.path().indexOf("/browse/") === 0) {
|
||||
$route.current = priorRoute;
|
||||
}
|
||||
unlisten();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -29,8 +29,8 @@ define(
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
var ENTER_FULLSCREEN = "Enter full screen mode.",
|
||||
EXIT_FULLSCREEN = "Exit full screen mode.";
|
||||
var ENTER_FULLSCREEN = "Enter full screen mode",
|
||||
EXIT_FULLSCREEN = "Exit full screen mode";
|
||||
|
||||
/**
|
||||
* The fullscreen action toggles between fullscreen display
|
||||
|
||||
@@ -56,7 +56,7 @@ define(
|
||||
// (browse) and the domainObject is passed in and
|
||||
// the path is returned and opened in a new tab
|
||||
perform: function () {
|
||||
$window.open(urlService.urlFor("browse", getSelectedObject()),
|
||||
$window.open(urlService.urlForNewTab("browse", getSelectedObject()),
|
||||
"_blank");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -61,7 +61,7 @@ define(
|
||||
);
|
||||
mockUrlService = jasmine.createSpyObj(
|
||||
"urlService",
|
||||
["urlFor"]
|
||||
["urlForLocation"]
|
||||
);
|
||||
mockObjectService = jasmine.createSpyObj(
|
||||
"objectService",
|
||||
@@ -222,15 +222,20 @@ define(
|
||||
mockNavigationService.addListener.mostRecentCall.args[0](
|
||||
mockNextObject
|
||||
);
|
||||
// location.path to be called with the urlService's
|
||||
// urlFor function with the next domainObject and mode
|
||||
expect(mockLocation.path).toHaveBeenCalledWith(
|
||||
mockUrlService.urlFor(mockMode, mockNextObject)
|
||||
);
|
||||
|
||||
|
||||
// Allows the path index to be checked
|
||||
// prior to setting $route.current
|
||||
mockLocation.path.andReturn("/browse/");
|
||||
|
||||
// Exercise the Angular workaround
|
||||
mockScope.$on.mostRecentCall.args[1]();
|
||||
expect(mockUnlisten).toHaveBeenCalled();
|
||||
|
||||
// location.path to be called with the urlService's
|
||||
// urlFor function with the next domainObject and mode
|
||||
expect(mockLocation.path).toHaveBeenCalledWith(
|
||||
mockUrlService.urlForLocation(mockMode, mockNextObject)
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -68,6 +68,10 @@ define(
|
||||
fireWatch("representation.selected.key", "xyz");
|
||||
expect(mockLocation.search).toHaveBeenCalledWith('view', "xyz");
|
||||
|
||||
// Allows the path index to be checked
|
||||
// prior to setting $route.current
|
||||
mockLocation.path.andReturn("/browse/");
|
||||
|
||||
// Exercise the Angular workaround
|
||||
mockScope.$on.mostRecentCall.args[1]();
|
||||
expect(mockUnlisten).toHaveBeenCalled();
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
"creation/LocatorController",
|
||||
"navigation/NavigateAction",
|
||||
"navigation/NavigationService",
|
||||
"services/UrlService",
|
||||
"windowing/FullscreenAction",
|
||||
"windowing/NewTabAction",
|
||||
"windowing/WindowTitler"
|
||||
|
||||
@@ -53,7 +53,7 @@ define(
|
||||
|
||||
// Mocks the urlService used to make the new tab's url from a
|
||||
// domainObject and mode
|
||||
mockUrlService = jasmine.createSpyObj("urlService", ["urlFor"]);
|
||||
mockUrlService = jasmine.createSpyObj("urlService", ["urlForNewTab"]);
|
||||
|
||||
// Action done using the current context or mockContextCurrent
|
||||
actionCurrent = new NewTabAction(mockUrlService, mockWindow,
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
"implementation": "actions/SaveAction.js",
|
||||
"name": "Save",
|
||||
"description": "Save changes made to these objects.",
|
||||
"depends": [ "$location" ],
|
||||
"depends": [ "$location", "urlService" ],
|
||||
"priority": "mandatory"
|
||||
},
|
||||
{
|
||||
@@ -76,7 +76,7 @@
|
||||
"implementation": "actions/CancelAction.js",
|
||||
"name": "Cancel",
|
||||
"description": "Discard changes made to these objects.",
|
||||
"depends": [ "$location" ]
|
||||
"depends": [ "$location", "urlService" ]
|
||||
}
|
||||
],
|
||||
"policies": [
|
||||
@@ -116,7 +116,7 @@
|
||||
"key": "topbar-edit",
|
||||
"templateUrl": "templates/topbar-edit.html"
|
||||
}
|
||||
],
|
||||
],
|
||||
"representers": [
|
||||
{
|
||||
"implementation": "representers/EditRepresenter.js",
|
||||
|
||||
@@ -30,7 +30,7 @@ define(
|
||||
* Edit Mode. Exits the editing user interface and invokes object
|
||||
* capabilities to persist the changes that have been made.
|
||||
*/
|
||||
function CancelAction($location, context) {
|
||||
function CancelAction($location, urlService, context) {
|
||||
var domainObject = context.domainObject;
|
||||
|
||||
// Look up the object's "editor.completion" capability;
|
||||
@@ -50,7 +50,10 @@ define(
|
||||
// Discard the current root view (which will be the editing
|
||||
// UI, which will have been pushed atop the Browise UI.)
|
||||
function returnToBrowse() {
|
||||
$location.path("/browse");
|
||||
$location.path($location.path(urlService.urlForLocation(
|
||||
"browse",
|
||||
domainObject
|
||||
)));
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -31,7 +31,7 @@ define(
|
||||
* Edit Mode. Exits the editing user interface and invokes object
|
||||
* capabilities to persist the changes that have been made.
|
||||
*/
|
||||
function SaveAction($location, context) {
|
||||
function SaveAction($location, urlService, context) {
|
||||
var domainObject = context.domainObject;
|
||||
|
||||
// Invoke any save behavior introduced by the editor capability;
|
||||
@@ -45,7 +45,10 @@ define(
|
||||
// Discard the current root view (which will be the editing
|
||||
// UI, which will have been pushed atop the Browise UI.)
|
||||
function returnToBrowse() {
|
||||
return $location.path("/browse");
|
||||
return $location.path(urlService.urlForLocation(
|
||||
"browse",
|
||||
domainObject
|
||||
));
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -30,6 +30,7 @@ define(
|
||||
var mockLocation,
|
||||
mockDomainObject,
|
||||
mockEditorCapability,
|
||||
mockUrlService,
|
||||
actionContext,
|
||||
action;
|
||||
|
||||
@@ -54,7 +55,10 @@ define(
|
||||
"editor",
|
||||
[ "save", "cancel" ]
|
||||
);
|
||||
|
||||
mockUrlService = jasmine.createSpyObj(
|
||||
"urlService",
|
||||
["urlForLocation"]
|
||||
);
|
||||
|
||||
actionContext = {
|
||||
domainObject: mockDomainObject
|
||||
@@ -64,7 +68,7 @@ define(
|
||||
mockDomainObject.getCapability.andReturn(mockEditorCapability);
|
||||
mockEditorCapability.cancel.andReturn(mockPromise(true));
|
||||
|
||||
action = new CancelAction(mockLocation, actionContext);
|
||||
action = new CancelAction(mockLocation, mockUrlService, actionContext);
|
||||
|
||||
});
|
||||
|
||||
@@ -91,7 +95,9 @@ define(
|
||||
|
||||
it("returns to browse when performed", function () {
|
||||
action.perform();
|
||||
expect(mockLocation.path).toHaveBeenCalledWith("/browse");
|
||||
expect(mockLocation.path).toHaveBeenCalledWith(
|
||||
mockUrlService.urlForLocation("browse", mockDomainObject)
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ define(
|
||||
var mockLocation,
|
||||
mockDomainObject,
|
||||
mockEditorCapability,
|
||||
mockUrlService,
|
||||
actionContext,
|
||||
action;
|
||||
|
||||
@@ -54,6 +55,10 @@ define(
|
||||
"editor",
|
||||
[ "save", "cancel" ]
|
||||
);
|
||||
mockUrlService = jasmine.createSpyObj(
|
||||
"urlService",
|
||||
["urlForLocation"]
|
||||
);
|
||||
|
||||
|
||||
actionContext = {
|
||||
@@ -64,7 +69,7 @@ define(
|
||||
mockDomainObject.getCapability.andReturn(mockEditorCapability);
|
||||
mockEditorCapability.save.andReturn(mockPromise(true));
|
||||
|
||||
action = new SaveAction(mockLocation, actionContext);
|
||||
action = new SaveAction(mockLocation, mockUrlService, actionContext);
|
||||
|
||||
});
|
||||
|
||||
@@ -91,7 +96,9 @@ define(
|
||||
|
||||
it("returns to browse when performed", function () {
|
||||
action.perform();
|
||||
expect(mockLocation.path).toHaveBeenCalledWith("/browse");
|
||||
expect(mockLocation.path).toHaveBeenCalledWith(
|
||||
mockUrlService.urlForLocation("browse", mockDomainObject)
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,6 +3,13 @@
|
||||
"description": "General UI elements, meant to be reused across modes",
|
||||
"resources": "res",
|
||||
"extensions": {
|
||||
"services": [
|
||||
{
|
||||
"key": "urlService",
|
||||
"implementation": "/services/UrlService.js",
|
||||
"depends": [ "$location" ]
|
||||
}
|
||||
],
|
||||
"runs": [
|
||||
{
|
||||
"implementation": "StyleSheetLoader.js",
|
||||
@@ -124,6 +131,15 @@
|
||||
"key": "mctScrollY",
|
||||
"implementation": "directives/MCTScroll.js",
|
||||
"depends": [ "$parse", "MCT_SCROLL_Y_PROPERTY", "MCT_SCROLL_Y_ATTRIBUTE" ]
|
||||
},
|
||||
{
|
||||
"key": "mctSplitPane",
|
||||
"implementation": "directives/MCTSplitPane.js",
|
||||
"depends": [ "$parse", "$log" ]
|
||||
},
|
||||
{
|
||||
"key": "mctSplitter",
|
||||
"implementation": "directives/MCTSplitter.js"
|
||||
}
|
||||
],
|
||||
"constants": [
|
||||
|
||||
@@ -40,6 +40,14 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/************************** FEATURES */
|
||||
/************************** VERY INFLUENTIAL GLOBAL DIMENSIONS */
|
||||
/************************** COLORS AND SHADING */
|
||||
/************************** RATIOS */
|
||||
/************************** LAYOUT */
|
||||
/************************** CONTROLS */
|
||||
/************************** PATHS */
|
||||
/************************** TIMINGS */
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
|
||||
@@ -40,6 +40,14 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/************************** FEATURES */
|
||||
/************************** VERY INFLUENTIAL GLOBAL DIMENSIONS */
|
||||
/************************** COLORS AND SHADING */
|
||||
/************************** RATIOS */
|
||||
/************************** LAYOUT */
|
||||
/************************** CONTROLS */
|
||||
/************************** PATHS */
|
||||
/************************** TIMINGS */
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -40,6 +40,14 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/************************** FEATURES */
|
||||
/************************** VERY INFLUENTIAL GLOBAL DIMENSIONS */
|
||||
/************************** COLORS AND SHADING */
|
||||
/************************** RATIOS */
|
||||
/************************** LAYOUT */
|
||||
/************************** CONTROLS */
|
||||
/************************** PATHS */
|
||||
/************************** TIMINGS */
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
@@ -95,7 +103,7 @@
|
||||
ul.tree {
|
||||
margin: 0;
|
||||
padding: 0; }
|
||||
/* line 264, ../sass/_mixins.scss */
|
||||
/* line 266, ../sass/_mixins.scss */
|
||||
ul.tree li {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"metadata": {
|
||||
"name": "WTD Symbols v2.0",
|
||||
"lastOpened": 1435166748369,
|
||||
"created": 1435164872664
|
||||
"name": "WTD Symbols v2.",
|
||||
"lastOpened": 1435266597671,
|
||||
"created": 1435266594435
|
||||
},
|
||||
"iconSets": [
|
||||
{
|
||||
"selection": [
|
||||
{
|
||||
"order": 128,
|
||||
"order": 1,
|
||||
"id": 75,
|
||||
"prevSize": 32,
|
||||
"code": 123,
|
||||
@@ -16,7 +16,7 @@
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 129,
|
||||
"order": 3,
|
||||
"id": 74,
|
||||
"prevSize": 32,
|
||||
"code": 125,
|
||||
@@ -24,7 +24,7 @@
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 127,
|
||||
"order": 4,
|
||||
"id": 73,
|
||||
"prevSize": 32,
|
||||
"code": 80,
|
||||
@@ -32,7 +32,7 @@
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 122,
|
||||
"order": 5,
|
||||
"id": 72,
|
||||
"prevSize": 32,
|
||||
"code": 232,
|
||||
@@ -40,7 +40,7 @@
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 121,
|
||||
"order": 6,
|
||||
"id": 71,
|
||||
"prevSize": 32,
|
||||
"code": 115,
|
||||
@@ -48,7 +48,7 @@
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 120,
|
||||
"order": 7,
|
||||
"id": 70,
|
||||
"prevSize": 32,
|
||||
"code": 114,
|
||||
@@ -56,7 +56,7 @@
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 119,
|
||||
"order": 8,
|
||||
"id": 69,
|
||||
"prevSize": 32,
|
||||
"code": 108,
|
||||
@@ -64,7 +64,7 @@
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 118,
|
||||
"order": 9,
|
||||
"id": 68,
|
||||
"prevSize": 32,
|
||||
"code": 51,
|
||||
@@ -72,503 +72,511 @@
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 0,
|
||||
"order": 10,
|
||||
"id": 67,
|
||||
"prevSize": 32,
|
||||
"code": 58880,
|
||||
"name": "icon-box-with-arrow-cursor",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 53,
|
||||
"order": 11,
|
||||
"id": 66,
|
||||
"prevSize": 32,
|
||||
"code": 65,
|
||||
"name": "icon-activity-mode",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 54,
|
||||
"order": 12,
|
||||
"id": 65,
|
||||
"prevSize": 32,
|
||||
"code": 97,
|
||||
"name": "icon-activity",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 55,
|
||||
"order": 13,
|
||||
"id": 64,
|
||||
"prevSize": 32,
|
||||
"code": 33,
|
||||
"name": "icon-alert-rect",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 56,
|
||||
"order": 14,
|
||||
"id": 63,
|
||||
"prevSize": 32,
|
||||
"code": 58883,
|
||||
"name": "icon-alert-triangle",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 57,
|
||||
"order": 15,
|
||||
"id": 62,
|
||||
"prevSize": 32,
|
||||
"code": 238,
|
||||
"name": "icon-arrow-double-down",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 58,
|
||||
"order": 16,
|
||||
"id": 61,
|
||||
"prevSize": 32,
|
||||
"code": 235,
|
||||
"name": "icon-arrow-double-up",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 59,
|
||||
"order": 2,
|
||||
"id": 60,
|
||||
"prevSize": 32,
|
||||
"code": 118,
|
||||
"name": "icon-arrow-down",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 60,
|
||||
"order": 19,
|
||||
"id": 59,
|
||||
"prevSize": 32,
|
||||
"code": 60,
|
||||
"name": "icon-arrow-left",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 61,
|
||||
"order": 20,
|
||||
"id": 58,
|
||||
"prevSize": 32,
|
||||
"code": 62,
|
||||
"name": "icon-arrow-right",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 62,
|
||||
"order": 21,
|
||||
"id": 57,
|
||||
"prevSize": 32,
|
||||
"code": 236,
|
||||
"name": "icon-arrow-tall-down",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 63,
|
||||
"order": 22,
|
||||
"id": 56,
|
||||
"prevSize": 32,
|
||||
"code": 237,
|
||||
"name": "icon-arrow-tall-up",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 64,
|
||||
"order": 23,
|
||||
"id": 55,
|
||||
"prevSize": 32,
|
||||
"code": 94,
|
||||
"name": "icon-arrow-up",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 65,
|
||||
"order": 24,
|
||||
"id": 54,
|
||||
"prevSize": 32,
|
||||
"code": 73,
|
||||
"name": "icon-arrows-out",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 0,
|
||||
"order": 25,
|
||||
"id": 53,
|
||||
"prevSize": 32,
|
||||
"code": 58893,
|
||||
"name": "icon-arrows-right-left",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 67,
|
||||
"order": 33,
|
||||
"id": 52,
|
||||
"prevSize": 32,
|
||||
"code": 53,
|
||||
"name": "icon-arrows-up-down",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 24,
|
||||
"order": 26,
|
||||
"id": 51,
|
||||
"prevSize": 32,
|
||||
"code": 42,
|
||||
"name": "icon-asterisk",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 25,
|
||||
"order": 27,
|
||||
"id": 50,
|
||||
"prevSize": 32,
|
||||
"code": 72,
|
||||
"name": "icon-autoflow-tabular",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 68,
|
||||
"order": 28,
|
||||
"id": 49,
|
||||
"prevSize": 32,
|
||||
"code": 224,
|
||||
"name": "icon-box-round-corners",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 69,
|
||||
"order": 29,
|
||||
"id": 48,
|
||||
"prevSize": 32,
|
||||
"code": 50,
|
||||
"name": "icon-check",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 26,
|
||||
"order": 30,
|
||||
"id": 47,
|
||||
"prevSize": 32,
|
||||
"code": 67,
|
||||
"name": "icon-clock",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 27,
|
||||
"order": 31,
|
||||
"id": 46,
|
||||
"prevSize": 32,
|
||||
"code": 46,
|
||||
"name": "icon-connectivity",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 28,
|
||||
"order": 32,
|
||||
"id": 45,
|
||||
"prevSize": 32,
|
||||
"code": 100,
|
||||
"name": "icon-database-query",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 29,
|
||||
"order": 17,
|
||||
"id": 44,
|
||||
"prevSize": 32,
|
||||
"code": 68,
|
||||
"name": "icon-database",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 30,
|
||||
"order": 35,
|
||||
"id": 43,
|
||||
"prevSize": 32,
|
||||
"code": 81,
|
||||
"name": "icon-dictionary",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 31,
|
||||
"order": 36,
|
||||
"id": 42,
|
||||
"prevSize": 32,
|
||||
"code": 242,
|
||||
"name": "icon-duplicate",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 32,
|
||||
"order": 37,
|
||||
"id": 41,
|
||||
"prevSize": 32,
|
||||
"code": 102,
|
||||
"name": "icon-folder-new",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 33,
|
||||
"order": 38,
|
||||
"id": 40,
|
||||
"prevSize": 32,
|
||||
"code": 70,
|
||||
"name": "icon-folder",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 34,
|
||||
"order": 39,
|
||||
"id": 39,
|
||||
"prevSize": 32,
|
||||
"code": 95,
|
||||
"name": "icon-fullscreen-collapse",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 35,
|
||||
"order": 40,
|
||||
"id": 38,
|
||||
"prevSize": 32,
|
||||
"code": 122,
|
||||
"name": "icon-fullscreen-expand",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 36,
|
||||
"order": 41,
|
||||
"id": 37,
|
||||
"prevSize": 32,
|
||||
"code": 71,
|
||||
"name": "icon-gear",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 39,
|
||||
"order": 49,
|
||||
"id": 34,
|
||||
"prevSize": 32,
|
||||
"code": 227,
|
||||
"name": "icon-image",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 70,
|
||||
"order": 42,
|
||||
"id": 33,
|
||||
"prevSize": 32,
|
||||
"code": 225,
|
||||
"name": "icon-layers",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 71,
|
||||
"order": 43,
|
||||
"id": 32,
|
||||
"prevSize": 32,
|
||||
"code": 76,
|
||||
"name": "icon-layout",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 40,
|
||||
"order": 44,
|
||||
"id": 31,
|
||||
"prevSize": 32,
|
||||
"code": 226,
|
||||
"name": "icon-line-horz",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 41,
|
||||
"order": 45,
|
||||
"id": 30,
|
||||
"prevSize": 32,
|
||||
"code": 244,
|
||||
"name": "icon-link",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 42,
|
||||
"order": 46,
|
||||
"id": 29,
|
||||
"prevSize": 32,
|
||||
"code": 88,
|
||||
"name": "icon-magnify-in",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 43,
|
||||
"order": 47,
|
||||
"id": 28,
|
||||
"prevSize": 32,
|
||||
"code": 89,
|
||||
"name": "icon-magnify-out",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 44,
|
||||
"order": 48,
|
||||
"id": 27,
|
||||
"prevSize": 32,
|
||||
"code": 77,
|
||||
"name": "icon-magnify",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 45,
|
||||
"order": 34,
|
||||
"id": 26,
|
||||
"prevSize": 32,
|
||||
"code": 109,
|
||||
"name": "icon-menu",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 46,
|
||||
"order": 50,
|
||||
"id": 25,
|
||||
"prevSize": 32,
|
||||
"code": 243,
|
||||
"name": "icon-move",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 47,
|
||||
"order": 51,
|
||||
"id": 24,
|
||||
"prevSize": 32,
|
||||
"code": 121,
|
||||
"name": "icon-new-window",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 48,
|
||||
"order": 52,
|
||||
"id": 23,
|
||||
"prevSize": 32,
|
||||
"code": 111,
|
||||
"name": "icon-object",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 49,
|
||||
"order": 53,
|
||||
"id": 22,
|
||||
"prevSize": 32,
|
||||
"code": 86,
|
||||
"name": "icon-packet",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 50,
|
||||
"order": 54,
|
||||
"id": 21,
|
||||
"prevSize": 32,
|
||||
"code": 234,
|
||||
"name": "icon-page",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 51,
|
||||
"order": 55,
|
||||
"id": 20,
|
||||
"prevSize": 32,
|
||||
"code": 241,
|
||||
"name": "icon-pause",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 52,
|
||||
"order": 56,
|
||||
"id": 19,
|
||||
"prevSize": 32,
|
||||
"code": 112,
|
||||
"name": "icon-pencil",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 87,
|
||||
"order": 65,
|
||||
"id": 18,
|
||||
"prevSize": 32,
|
||||
"code": 79,
|
||||
"name": "icon-people",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 102,
|
||||
"order": 57,
|
||||
"id": 17,
|
||||
"prevSize": 32,
|
||||
"code": 239,
|
||||
"name": "icon-play",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 103,
|
||||
"order": 58,
|
||||
"id": 16,
|
||||
"prevSize": 32,
|
||||
"code": 233,
|
||||
"name": "icon-plot-resource",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 105,
|
||||
"order": 59,
|
||||
"id": 15,
|
||||
"prevSize": 32,
|
||||
"code": 43,
|
||||
"name": "icon-plus",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 109,
|
||||
"order": 60,
|
||||
"id": 76,
|
||||
"prevSize": 32,
|
||||
"code": 45,
|
||||
"name": "icon-minus",
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 61,
|
||||
"id": 11,
|
||||
"prevSize": 32,
|
||||
"code": 54,
|
||||
"name": "icon-sine",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 110,
|
||||
"order": 62,
|
||||
"id": 10,
|
||||
"prevSize": 32,
|
||||
"code": 228,
|
||||
"name": "icon-T",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 132,
|
||||
"order": 63,
|
||||
"id": 9,
|
||||
"prevSize": 32,
|
||||
"code": 116,
|
||||
"name": "icon-telemetry-panel",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 112,
|
||||
"order": 64,
|
||||
"id": 8,
|
||||
"prevSize": 32,
|
||||
"code": 84,
|
||||
"name": "icon-telemetry",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 113,
|
||||
"order": 18,
|
||||
"id": 7,
|
||||
"prevSize": 32,
|
||||
"code": 246,
|
||||
"name": "icon-thumbs-strip",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 114,
|
||||
"order": 67,
|
||||
"id": 6,
|
||||
"prevSize": 32,
|
||||
"code": 83,
|
||||
"name": "icon-timeline",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 104,
|
||||
"order": 68,
|
||||
"id": 5,
|
||||
"prevSize": 32,
|
||||
"code": 245,
|
||||
"name": "icon-timer",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 101,
|
||||
"order": 69,
|
||||
"id": 4,
|
||||
"prevSize": 32,
|
||||
"code": 90,
|
||||
"name": "icon-trash",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 86,
|
||||
"order": 70,
|
||||
"id": 3,
|
||||
"prevSize": 32,
|
||||
"code": 229,
|
||||
"name": "icon-two-parts-both",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 73,
|
||||
"order": 71,
|
||||
"id": 2,
|
||||
"prevSize": 32,
|
||||
"code": 231,
|
||||
"name": "icon-two-parts-one-only",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 116,
|
||||
"order": 72,
|
||||
"id": 1,
|
||||
"prevSize": 32,
|
||||
"code": 120,
|
||||
"name": "icon-x-heavy",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 0,
|
||||
"order": 66,
|
||||
"id": 0,
|
||||
"prevSize": 32,
|
||||
"code": 58946,
|
||||
@@ -580,7 +588,7 @@
|
||||
"metadata": {
|
||||
"name": "Open MCT Web UI Symbols",
|
||||
"importSize": {
|
||||
"width": 256,
|
||||
"width": 512,
|
||||
"height": 512
|
||||
},
|
||||
"designer": "Charles Hacskaylo"
|
||||
@@ -1131,8 +1139,8 @@
|
||||
{
|
||||
"id": 41,
|
||||
"paths": [
|
||||
"M894 188h-384v-64c0-70.4-57.6-128-128-128h-256c-70.4 0-128 57.6-128 128v320c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v-128c0-70.4-57.6-128-128-128z",
|
||||
"M894 444h-768c-70.4 0-128 57.6-128 128v320c0 70.4 57.6 128 128 128h768c70.4 0 128-57.6 128-128v-320c0-70.4-57.6-128-128-128zM702 764h-128v128h-128v-128h-128v-128h128v-128h128v128h128v128z"
|
||||
"M896 192h-320c-16.4-16.4-96.8-96.8-109.2-109.2l-37.4-37.4c-25-25-74.2-45.4-109.4-45.4h-256c-35.2 0-64 28.8-64 64v384c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v-128c0-70.4-57.6-128-128-128z",
|
||||
"M896 448h-768c-70.4 0-128 57.6-128 128v320c0 70.4 57.6 128 128 128h768c70.4 0 128-57.6 128-128v-320c0-70.4-57.6-128-128-128zM704 800h-128v128h-128v-128h-128v-128h128v-128h128v128h128v128z"
|
||||
],
|
||||
"attrs": [
|
||||
{},
|
||||
@@ -1147,8 +1155,8 @@
|
||||
{
|
||||
"id": 40,
|
||||
"paths": [
|
||||
"M896 190h-384v-64c0-70.4-57.6-128-128-128h-256c-70.4 0-128 57.6-128 128v320c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v-128c0-70.4-57.6-128-128-128z",
|
||||
"M896 446h-768c-70.4 0-128 57.6-128 128v320c0 70.4 57.6 128 128 128h768c70.4 0 128-57.6 128-128v-320c0-70.4-57.6-128-128-128z"
|
||||
"M896 192h-320c-16.4-16.4-96.8-96.8-109.2-109.2l-37.4-37.4c-25-25-74.2-45.4-109.4-45.4h-256c-35.2 0-64 28.8-64 64v384c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v-128c0-70.4-57.6-128-128-128z",
|
||||
"M896 448h-768c-70.4 0-128 57.6-128 128v320c0 70.4 57.6 128 128 128h768c70.4 0 128-57.6 128-128v-320c0-70.4-57.6-128-128-128z"
|
||||
],
|
||||
"attrs": [
|
||||
{},
|
||||
@@ -1526,6 +1534,20 @@
|
||||
"icon-plus"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 76,
|
||||
"paths": [
|
||||
"M960 640c35.2 0 64-28.8 64-64v-128c0-35.2-28.8-64-64-64h-896c-35.2 0-64 28.8-64 64v128c0 35.2 28.8 64 64 64h896z"
|
||||
],
|
||||
"attrs": [
|
||||
{}
|
||||
],
|
||||
"isMulticolor": false,
|
||||
"grid": 0,
|
||||
"tags": [
|
||||
"icon-minus"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"paths": [
|
||||
|
||||
Binary file not shown.
@@ -10,6 +10,7 @@
|
||||
<glyph unicode="!" d="M832 960h-640c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h640c105.6 0 192 86.4 192 192v640c0 105.6-86.4 192-192 192zM640 128c0-35.2-28.8-64-64-64h-128c-35.2 0-64 28.8-64 64v64c0 35.2 28.8 64 64 64h128c35.2 0 64-28.8 64-64v-64zM696.062 768.494l-48.124-384.988c-4.366-34.928-36.738-63.506-71.938-63.506h-128c-35.2 0-67.572 28.578-71.938 63.506l-48.124 384.988c-4.366 34.928 20.862 63.506 56.062 63.506h256c35.2 0 60.428-28.578 56.062-63.506z" />
|
||||
<glyph unicode="*" d="M1004.166 619.542l-97.522 168.916-330.534-229.414 33.414 400.956h-195.048l33.414-400.956-330.534 229.414-97.522-168.916 363.944-171.542-363.944-171.542 97.522-168.916 330.534 229.414-33.414-400.956h195.048l-33.414 400.956 330.534-229.414 97.522 168.916-363.944 171.542z" />
|
||||
<glyph unicode="+" d="M960 576h-330v320c0 35.2-28.8 64-64 64h-108c-35.2 0-64-28.8-64-64v-320h-330c-35.2 0-64-28.8-64-64v-128c0-35.2 28.8-64 64-64h330v-320c0-35.2 28.8-64 64-64h108c35.2 0 64 28.8 64 64v320h330c35.2 0 64 28.8 64 64v128c0 35.2-28.8 64-64 64z" />
|
||||
<glyph unicode="-" d="M960 320c35.2 0 64 28.8 64 64v128c0 35.2-28.8 64-64 64h-896c-35.2 0-64-28.8-64-64v-128c0-35.2 28.8-64 64-64h896z" />
|
||||
<glyph unicode="." d="M704 384c0-70.4-57.6-128-128-128h-128c-70.4 0-128 57.6-128 128v128c0 70.4 57.6 128 128 128h128c70.4 0 128-57.6 128-128v-128zM1024 448l-192 320v-640zM0 448l192 320v-640z" />
|
||||
<glyph unicode="2" d="M1024 960l-640-640-384 384v-384l384-384 640 640z" />
|
||||
<glyph unicode="3" d="M640 704h-256c-70.4 0-128-57.6-128-128v-256c0-70.4 57.6-128 128-128h256c70.4 0 128 57.6 128 128v256c0 70.4-57.6 128-128 128zM0 960h192v-192h-192v192zM256 960h192v-128h-192v128zM576 960h192v-128h-192v128zM256 64h192v-128h-192v128zM576 64h192v-128h-192v128zM0 384h128v-192h-128v192zM0 704h128v-192h-128v192zM896 384h128v-192h-128v192zM896 704h128v-192h-128v192zM832 960h192v-192h-192v192zM0 128h192v-192h-192v192zM832 128h192v-192h-192v192z" />
|
||||
@@ -20,7 +21,7 @@
|
||||
<glyph unicode="A" d="M512 960c-214.866 0-398.786-132.372-474.744-320h90.744c56.86 0 107.938-24.724 143.094-64h240.906l-192 192h256l320-320-320-320h-256l192 192h-240.906c-35.156-39.276-86.234-64-143.094-64h-90.744c75.958-187.628 259.878-320 474.744-320 282.77 0 512 229.23 512 512s-229.23 512-512 512z" />
|
||||
<glyph unicode="C" d="M512 960c-282.77 0-512-229.23-512-512s229.23-512 512-512 512 229.23 512 512-229.23 512-512 512zM768 384h-256c-35.2 0-64 28.8-64 64v384c0 35.2 28.8 64 64 64s64-28.8 64-64v-320h192c35.2 0 64-28.8 64-64s-28.8-64-64-64z" />
|
||||
<glyph unicode="D" 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.77 0-512 85.962-512 192v-512c0-106.038 229.23-192 512-192s512 85.962 512 192v512c0-106.038-229.23-192-512-192z" />
|
||||
<glyph unicode="F" d="M896 770h-384v64c0 70.4-57.6 128-128 128h-256c-70.4 0-128-57.6-128-128v-320c0 70.4 57.6 128 128 128h768c70.4 0 128-57.6 128-128v128c0 70.4-57.6 128-128 128zM896 514h-768c-70.4 0-128-57.6-128-128v-320c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v320c0 70.4-57.6 128-128 128z" />
|
||||
<glyph unicode="F" d="M896 768h-320c-16.4 16.4-96.8 96.8-109.2 109.2l-37.4 37.4c-25 25-74.2 45.4-109.4 45.4h-256c-35.2 0-64-28.8-64-64v-384c0 70.4 57.6 128 128 128h768c70.4 0 128-57.6 128-128v128c0 70.4-57.6 128-128 128zM896 512h-768c-70.4 0-128-57.6-128-128v-320c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v320c0 70.4-57.6 128-128 128z" />
|
||||
<glyph unicode="G" d="M1024 384v128l-140.976 35.244c-8.784 32.922-21.818 64.106-38.504 92.918l74.774 124.622-90.51 90.51-124.622-74.774c-28.812 16.686-59.996 29.72-92.918 38.504l-35.244 140.976h-128l-35.244-140.976c-32.922-8.784-64.106-21.818-92.918-38.504l-124.622 74.774-90.51-90.51 74.774-124.622c-16.686-28.812-29.72-59.996-38.504-92.918l-140.976-35.244v-128l140.976-35.244c8.784-32.922 21.818-64.106 38.504-92.918l-74.774-124.622 90.51-90.51 124.622 74.774c28.812-16.686 59.996-29.72 92.918-38.504l35.244-140.976h128l35.244 140.976c32.922 8.784 64.106 21.818 92.918 38.504l124.622-74.774 90.51 90.51-74.774 124.622c16.686 28.812 29.72 59.996 38.504 92.918l140.976 35.244zM704 448c0-106.038-85.962-192-192-192s-192 85.962-192 192 85.962 192 192 192 192-85.962 192-192z" />
|
||||
<glyph unicode="H" d="M192 960c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h64v1024h-64zM384 960h256v-1024h-256v1024zM832 960h-64v-704h256v512c0 105.6-86.4 192-192 192z" />
|
||||
<glyph unicode="I" d="M0 448l256-256v512zM512 960l-256-256h512zM512-64l256 256h-512zM768 704v-512l256 256z" />
|
||||
@@ -39,7 +40,7 @@
|
||||
<glyph unicode="_" d="M191.656 128c0.118-0.1 0.244-0.224 0.344-0.344v-191.656h192v192c0 105.6-86.4 192-192 192h-192v-192h191.656zM192 768.344c-0.1-0.118-0.224-0.244-0.344-0.344h-191.656v-192h192c105.6 0 192 86.4 192 192v192h-192v-191.656zM832 576h192v192h-191.656c-0.118 0.1-0.244 0.226-0.344 0.344v191.656h-192v-192c0-105.6 86.4-192 192-192zM832 127.656c0.1 0.118 0.224 0.244 0.344 0.344h191.656v192h-192c-105.6 0-192-86.4-192-192v-192h192v191.656z" />
|
||||
<glyph unicode="a" d="M576 896h-256l320-320h-290.256c-44.264 76.516-126.99 128-221.744 128h-128v-512h128c94.754 0 177.48 51.484 221.744 128h290.256l-320-320h256l448 448-448 448z" />
|
||||
<glyph unicode="d" d="M683.52 140.714c-50.782-28.456-109.284-44.714-171.52-44.714-194.094 0-352 157.906-352 352s157.906 352 352 352 352-157.906 352-352c0-62.236-16.258-120.738-44.714-171.52l191.692-191.692c8.516 13.89 13.022 28.354 13.022 43.212v640c0 106.038-229.23 192-512 192s-512-85.962-512-192v-640c0-106.038 229.23-192 512-192 126.11 0 241.548 17.108 330.776 45.46l-159.256 159.254zM352 448c0-88.224 71.776-160 160-160s160 71.776 160 160-71.776 160-160 160-160-71.776-160-160z" />
|
||||
<glyph unicode="f" d="M894 772h-384v64c0 70.4-57.6 128-128 128h-256c-70.4 0-128-57.6-128-128v-320c0 70.4 57.6 128 128 128h768c70.4 0 128-57.6 128-128v128c0 70.4-57.6 128-128 128zM894 516h-768c-70.4 0-128-57.6-128-128v-320c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v320c0 70.4-57.6 128-128 128zM702 196h-128v-128h-128v128h-128v128h128v128h128v-128h128v-128z" />
|
||||
<glyph unicode="f" d="M896 768h-320c-16.4 16.4-96.8 96.8-109.2 109.2l-37.4 37.4c-25 25-74.2 45.4-109.4 45.4h-256c-35.2 0-64-28.8-64-64v-384c0 70.4 57.6 128 128 128h768c70.4 0 128-57.6 128-128v128c0 70.4-57.6 128-128 128zM896 512h-768c-70.4 0-128-57.6-128-128v-320c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v320c0 70.4-57.6 128-128 128zM704 160h-128v-128h-128v128h-128v128h128v128h128v-128h128v-128z" />
|
||||
<glyph unicode="l" d="M832 576h-32v96c0 158.8-129.2 288-288 288s-288-129.2-288-288v-96h-32c-70.4 0-128-57.6-128-128v-384c0-70.4 57.6-128 128-128h640c70.4 0 128 57.6 128 128v384c0 70.4-57.6 128-128 128zM416 672c0 53 43 96 96 96s96-43 96-96v-96h-192v96z" />
|
||||
<glyph unicode="m" d="M0 960h1024v-256h-1024v256zM0 576h1024v-256h-1024v256zM0 192h1024v-256h-1024v256z" />
|
||||
<glyph unicode="o" d="M512-64l512 320v384l-512.020 320-511.98-320v-384l512-320zM512 768l358.4-224-358.4-224-358.4 224 358.4 224z" />
|
||||
@@ -74,5 +75,8 @@
|
||||
<glyph unicode="ô" d="M832 960h-640c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h640c105.6 0 192 86.4 192 192v640c0 105.6-86.4 192-192 192zM832 320l-128 128-512-320 320 512-128 128h448v-448z" />
|
||||
<glyph unicode="õ" d="M638 898c0 35.4-28.6 64-64 64h-128c-35.4 0-64-28.6-64-64s28.6-64 64-64h128c35.4 0 64 28.6 64 64zM510 834c-247.4 0-448-200.6-448-448s200.6-448 448-448 448 200.6 448 448-200.6 448-448 448zM510 386h-336c0 185.2 150.8 336 336 336v-336z" />
|
||||
<glyph unicode="ö" d="M448 578c0-35.2-28.8-64-64-64h-320c-35.2 0-64 28.8-64 64v320c0 35.2 28.8 64 64 64h320c35.2 0 64-28.8 64-64v-320zM1024 578c0-35.2-28.8-64-64-64h-320c-35.2 0-64 28.8-64 64v320c0 35.2 28.8 64 64 64h320c35.2 0 64-28.8 64-64v-320zM448 2c0-35.2-28.8-64-64-64h-320c-35.2 0-64 28.8-64 64v320c0 35.2 28.8 64 64 64h320c35.2 0 64-28.8 64-64v-320zM1024 2c0-35.2-28.8-64-64-64h-320c-35.2 0-64 28.8-64 64v320c0 35.2 28.8 64 64 64h320c35.2 0 64-28.8 64-64v-320z" />
|
||||
<glyph unicode="" d="M832 447.6c0 0.2 0 0.2 0 0.4v320c0 105.6-86.4 192-192 192h-448c-105.6 0-192-86.4-192-192v-320c0-105.6 86.4-192 192-192h263.6l-197.2 445.6 573.6-254zM766.8 300.2l193.8 20.4-576.6 255.4 255.4-576.6 20.4 193.8 257-257.2 107.2 107.2z" />
|
||||
<glyph unicode="" 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="" d="M1024 448l-448-512v1024zM448 960l-448-512 448-512z" />
|
||||
<glyph unicode="" 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: 20 KiB After Width: | Height: | Size: 22 KiB |
Binary file not shown.
Binary file not shown.
@@ -20,10 +20,10 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
// Features
|
||||
/************************** FEATURES */
|
||||
$enableImageryThumbs: false; // Set to true if historical imagery thumbnails are supported
|
||||
|
||||
// Margins, spacing, radii
|
||||
/************************** VERY INFLUENTIAL GLOBAL DIMENSIONS */
|
||||
$bodyMargin: 10px;
|
||||
$interiorMargin: 5px;
|
||||
$interiorMarginLg: $interiorMargin * 2;
|
||||
@@ -33,7 +33,7 @@ $controlCr: 2px;
|
||||
$smallCr: 2px;
|
||||
$badgeW: 35px;
|
||||
|
||||
// Colors and shading
|
||||
/************************** COLORS AND SHADING */
|
||||
$colorBodyBg: #333;
|
||||
$colorBodyFg: #999;
|
||||
$colorFooterBg: #000;
|
||||
@@ -44,64 +44,68 @@ $colorAlt1: #ffc700;
|
||||
$colorAlert: #ff3c00;
|
||||
$colorPausedBg: #c56f01;
|
||||
$colorPausedFg: #fff;
|
||||
$colorCheck: $colorKey;
|
||||
$colorCreateBtn: $colorKey;
|
||||
$colorGridLines: rgba(#fff, 0.05);
|
||||
// Menu colors
|
||||
$colorMenuBg: lighten($colorBodyBg, 23%);
|
||||
$colorMenuFg: lighten($colorMenuBg, 70%);
|
||||
$colorMenuIc: lighten($colorKey, 17%);
|
||||
$colorInteriorBorder: lighten($colorBodyBg, 10%);
|
||||
$colorObjFrameBg: darken($colorBodyBg, 5%);
|
||||
// Form colors
|
||||
$colorCheck: $colorKey;
|
||||
$colorFormRequired: #ffc700;
|
||||
$colorFormValid: #33cc33;
|
||||
$colorFormError: #cc0000;
|
||||
$colorFormInvalid: #ff9900;
|
||||
$colorGridLines: rgba(#fff, 0.05);
|
||||
// Limits and staleness colors
|
||||
$colorLimitYellow: #9d7500;
|
||||
$colorLimitRed: #aa0000;
|
||||
$colorTelemFresh: #fff;
|
||||
$colorTelemStale: #888;
|
||||
$styleTelemStale: italic;
|
||||
// Bubble colors
|
||||
$colorInfoBubbleFg: #666;
|
||||
$colorInfoBubbleBg: #ddd;
|
||||
$colorThumbsBubbleFg: lighten($colorBodyFg, 10%);
|
||||
$colorThumbsBubbleBg: lighten($colorBodyBg, 10%);
|
||||
$colorLimitYellow: #9d7500;
|
||||
$colorLimitRed: #aa0000;
|
||||
$colorTelemFresh: #fff;
|
||||
$colorTelemStale: #888;
|
||||
$styleTelemState: italic;
|
||||
$colorInfoBubbleFg: #666;
|
||||
$colorInfoBubbleBg: #ddd;
|
||||
|
||||
// Ratios
|
||||
$ltGamma: 20%;
|
||||
$btnFontSizeToH: 0.45;
|
||||
|
||||
// User Environment
|
||||
$ueTopBarH: 24px; // Change to when breadcrumb is enabled
|
||||
$ueTopBarEditH: 30px;
|
||||
$ueTopBarBtnH: 35px;
|
||||
$ueFooterH: 20px;
|
||||
$ueColMargin: 1.5%;
|
||||
$ueAppLogoW: 105px;
|
||||
//$ueBrowseViewBarH: $ueTopBarH; // was 30px
|
||||
$ueEditToolBarH: 25px;
|
||||
$ueBrowseLeftPaneW: 25%;
|
||||
$ueEditLeftPaneW: 75%;
|
||||
|
||||
// Overlay
|
||||
$colorOvrBlocker: rgba(black, 0.7);
|
||||
$colorOvrBg: $colorBodyBg;
|
||||
$colorOvrFg: $colorBodyFg;
|
||||
$ovrTopBarH: 60px;
|
||||
$ovrFooterH: 40px;
|
||||
|
||||
//Items
|
||||
$ueBrowseGridItemLg: 200px;
|
||||
$ueBrowseGridItemTopBarH: 20px;
|
||||
$ueBrowseGridItemBottomBarH: 30px;
|
||||
// Items
|
||||
$colorItemBase: lighten($colorBodyBg, 5%);
|
||||
$colorItemFg: lighten($colorItemBase, 20%);
|
||||
$colorItemSelected: $colorKey;
|
||||
$itemPadLR: 5px;
|
||||
// Tabular
|
||||
$tabularColorBorder: rgba(white, 0.1);
|
||||
$tabularColorBodyBg: darken($colorBodyBg, 10%);
|
||||
$tabularColorBodyFg: lighten($tabularColorBodyBg, 40%);
|
||||
$tabularColorHeaderBg: lighten($colorBodyBg, 10%);
|
||||
$tabularColorHeaderFg: lighten($tabularColorHeaderBg, 40%);
|
||||
|
||||
/************************** RATIOS */
|
||||
$ltGamma: 20%;
|
||||
$btnFontSizeToH: 0.45;
|
||||
|
||||
/************************** LAYOUT */
|
||||
$ueTopBarH: 24px; // Change when breadcrumb is enabled
|
||||
$ueTopBarEditH: 30px;
|
||||
$ueTopBarBtnH: 35px;
|
||||
$ueFooterH: 25px;
|
||||
$ueColMargin: 1.5%;
|
||||
$ueAppLogoW: 105px;
|
||||
$ueEditToolBarH: 25px;
|
||||
$ueBrowseLeftPaneW: 25%;
|
||||
$ueEditLeftPaneW: 75%;
|
||||
// Overlay
|
||||
$ovrTopBarH: 60px;
|
||||
$ovrFooterH: 40px;
|
||||
// Items
|
||||
$ueBrowseGridItemLg: 200px;
|
||||
$ueBrowseGridItemTopBarH: 20px;
|
||||
$ueBrowseGridItemBottomBarH: 30px;
|
||||
$itemPadLR: 5px;
|
||||
// Tree
|
||||
$treeVCW: 10px;
|
||||
$treeTypeIconW: 20px;
|
||||
@@ -109,18 +113,33 @@ $treeContextTriggerW: 20px;
|
||||
$colorItemTreeIcon: $colorKey;
|
||||
$colorItemTreeIconHover: lighten($colorItemTreeIcon, 20%);
|
||||
$colorItemTreeVCHover: $colorAlt1;
|
||||
|
||||
//Tabular
|
||||
// Tabular
|
||||
$tabularHeaderH: 18px;
|
||||
$tabularTdPadLR: $itemPadLR;
|
||||
$tabularTdPadTB: 2px;
|
||||
$tabularColorBorder: rgba(white, 0.1);
|
||||
$tabularColorBodyBg: darken($colorBodyBg, 10%);
|
||||
$tabularColorBodyFg: lighten($tabularColorBodyBg, 40%);
|
||||
$tabularColorHeaderBg: lighten($colorBodyBg, 10%);
|
||||
$tabularColorHeaderFg: lighten($tabularColorHeaderBg, 40%);
|
||||
// Imagery
|
||||
$imageMainControlBarH: 20px;
|
||||
$imageThumbsD: 120px;
|
||||
$imageThumbsWrapperH: $imageThumbsD * 1.4;
|
||||
$imageThumbPad: 1px;
|
||||
// Ticks
|
||||
$ticksH: 25px;
|
||||
$tickLblVMargin: 3px;
|
||||
$tickLblH: 15px;
|
||||
$tickLblW: 50px;
|
||||
$tickH: $ticksH - $tickLblVMargin - $tickLblH;
|
||||
$tickW: 1px;
|
||||
// Bubbles
|
||||
$bubbleArwSize: 10px;
|
||||
$bubblePad: $interiorMargin;
|
||||
$bubbleMinW: 100px;
|
||||
$bubbleMaxW: 300px;
|
||||
// Forms
|
||||
$reqSymbolW: 15px;
|
||||
$reqSymbolM: $interiorMargin * 2;
|
||||
$reqSymbolFontSize: 0.7em;
|
||||
|
||||
// Controls
|
||||
/************************** CONTROLS */
|
||||
$controlCr: $basicCr;
|
||||
$controlDisabledOpacity: 0.3;
|
||||
$formLabelW: 20%;
|
||||
@@ -132,34 +151,9 @@ $scrollbarTrackColorBg: rgba(#000, 0.4);
|
||||
$btnStdH: 25px;
|
||||
$btnToolbarH: $btnStdH;
|
||||
|
||||
// Paths
|
||||
/************************** PATHS */
|
||||
$dirImgs: '../images/'; // Relative to platform/css/ directory
|
||||
|
||||
// Ticks
|
||||
$ticksH: 25px;
|
||||
$tickLblVMargin: 3px;
|
||||
$tickLblH: 15px;
|
||||
$tickLblW: 50px;
|
||||
$tickH: $ticksH - $tickLblVMargin - $tickLblH;
|
||||
$tickW: 1px;
|
||||
|
||||
// Imagery
|
||||
$imageMainControlBarH: 20px;
|
||||
$imageThumbsD: 120px;
|
||||
$imageThumbsWrapperH: $imageThumbsD * 1.4;
|
||||
$imageThumbPad: 1px;
|
||||
|
||||
// Bubbles
|
||||
$bubbleArwSize: 10px;
|
||||
$bubblePad: $interiorMargin;
|
||||
$bubbleMinW: 100px;
|
||||
$bubbleMaxW: 300px;
|
||||
|
||||
|
||||
// Timing
|
||||
/************************** TIMINGS */
|
||||
$controlFadeMs: 100ms;
|
||||
|
||||
// Forms
|
||||
$reqSymbolW: 15px;
|
||||
$reqSymbolM: $interiorMargin * 2;
|
||||
$reqSymbolFontSize: 0.7em;
|
||||
@@ -29,10 +29,13 @@ a {
|
||||
}
|
||||
|
||||
body, html {
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
background-color: $colorBodyBg;
|
||||
color: $colorBodyFg;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-size: 100%;
|
||||
//font-weight: 500;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
.browse-area.holder {
|
||||
// When .browse.top-bar is hidden, set the top of the browse-area holder
|
||||
top: $interiorMargin;
|
||||
top: $bodyMargin;
|
||||
> .contents.split-layout {
|
||||
// Don't pad in from top and bottom
|
||||
//top: 0; bottom: 0;
|
||||
|
||||
@@ -174,10 +174,11 @@
|
||||
|
||||
@mixin controlGrippy($b, $direction: horizontal, $w: 1px, $style: dotted) {
|
||||
&:before {
|
||||
// Grippy
|
||||
@include trans-prop-nice("border-color",0.75s);
|
||||
content: '';
|
||||
display: block;
|
||||
height: auto;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
|
||||
@@ -195,7 +196,8 @@
|
||||
}
|
||||
}
|
||||
&:not(.disabled):hover:before {
|
||||
border-color: rgba($colorKey, 0.9);
|
||||
@include trans-prop-nice("border-color",50ms);
|
||||
border-color: $colorKey;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ $pad: $interiorMargin * $baseRatio;
|
||||
/******* LAYOUT AND SIZING */
|
||||
.btn,
|
||||
.l-btn {
|
||||
@include user-select(none);
|
||||
line-height: 1.5em; // Was 1.25em
|
||||
padding: 0 $pad;
|
||||
text-decoration: none;
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
ul {
|
||||
@include menuUlReset();
|
||||
li {
|
||||
// @include border-radius($controlCr);
|
||||
@include box-sizing(border-box);
|
||||
border-top: 1px solid lighten($bg, 20%);
|
||||
line-height: $menuLineH;
|
||||
@@ -65,20 +64,39 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.context-menu,
|
||||
.super-menu {
|
||||
$bg: $colorMenuBg;
|
||||
$fg: $colorMenuFg;
|
||||
$ic: $colorMenuIc;
|
||||
//font-size: 0.80rem;
|
||||
pointer-events: auto;
|
||||
@include containerSubtle($bg);
|
||||
ul li {
|
||||
padding-left: 25px;
|
||||
a { color: $fg; }
|
||||
.icon {
|
||||
color: $ic;
|
||||
}
|
||||
.type-icon {
|
||||
left: $interiorMargin;
|
||||
}
|
||||
&:hover .icon {
|
||||
color: lighten($ic, 5%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.super-menu {
|
||||
$w: 450px;
|
||||
$w: 500px;
|
||||
$h: $w - 20;
|
||||
$plw: 50%; //$w * 0.5;
|
||||
$prw: 50%; //$w - $plw;
|
||||
$bg: $colorKey;
|
||||
$fg: $colorKeyFg;
|
||||
$colorMid: lighten($bg, 25%);
|
||||
$bgHover: $bg;
|
||||
@include containerSubtle(darken($bg, 15%), $fg);
|
||||
$fg: #fff; //lighten($colorBodyFg, 40%);
|
||||
$bgHover: $colorKey; //$bg;
|
||||
display: block;
|
||||
.icon {
|
||||
color: $colorMid;
|
||||
}
|
||||
width: $w;
|
||||
height: $h;
|
||||
.contents {
|
||||
@@ -98,21 +116,8 @@
|
||||
ul {
|
||||
li {
|
||||
@include border-radius($controlCr);
|
||||
// @include test(red);
|
||||
padding-left: 30px;
|
||||
border-top: none;
|
||||
color: $fg;
|
||||
// font-size: 0.85em;
|
||||
// line-height: 20px;
|
||||
&:hover {
|
||||
background: $bgHover;
|
||||
.icon {
|
||||
color: lighten($bg, 50%);
|
||||
}
|
||||
}
|
||||
.icon {
|
||||
@include txtShdwSubtle(0.4);
|
||||
left: $interiorMargin;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,13 +127,14 @@
|
||||
right: 0;
|
||||
padding: $interiorMargin * 5;
|
||||
width: $prw;
|
||||
.icon {
|
||||
color: $fg;
|
||||
}
|
||||
}
|
||||
}
|
||||
.menu-item-description {
|
||||
.desc-area {
|
||||
// @include test(green);
|
||||
&.icon {
|
||||
//@include test(red);
|
||||
$h: 150px;
|
||||
position: relative;
|
||||
font-size: 8em;
|
||||
@@ -153,27 +159,7 @@
|
||||
}
|
||||
}
|
||||
.context-menu {
|
||||
$bg: lighten($colorBodyBg, 25%);
|
||||
$fg: lighten($bg, 70%);
|
||||
$ic: lighten($colorKey, 15%);
|
||||
font-size: 0.80rem;
|
||||
pointer-events: auto;
|
||||
&.menu {
|
||||
@include containerSubtle($bg);
|
||||
ul li {
|
||||
padding-left: 30px;
|
||||
a { color: $fg; }
|
||||
.icon {
|
||||
color: $ic;
|
||||
}
|
||||
.type-icon {
|
||||
left: $interiorMargin;
|
||||
}
|
||||
&:hover .icon {
|
||||
color: lighten($ic, 5%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
}
|
||||
|
||||
.l-image-main {
|
||||
cursor: crosshair;
|
||||
//cursor: crosshair;
|
||||
}
|
||||
|
||||
.l-image-main-controlbar {
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// Layout
|
||||
&:hover {
|
||||
.l-btn.control {
|
||||
//display: inline-block;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@@ -20,6 +19,9 @@
|
||||
position: absolute;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
.ui-symbol.direction {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
}
|
||||
&:hover .l-elem.l-value {
|
||||
left: 20px;
|
||||
@@ -35,10 +37,10 @@
|
||||
}
|
||||
.l-btn.control {
|
||||
@include trans-prop-nice-fade($transTime);
|
||||
//display: none;
|
||||
opacity: 0;
|
||||
font-size: 0.9em;
|
||||
line-height: 1em;
|
||||
font-size: 0.65em;
|
||||
vertical-align: top;
|
||||
//line-height: 1em;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,18 +30,18 @@
|
||||
border-collapse: collapse;
|
||||
color: #fff;
|
||||
display: table;
|
||||
font-size: 0.8em;
|
||||
font-size: 0.75em;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
//height: 100%; MOVED
|
||||
width: 100%;
|
||||
thead, .thead,
|
||||
tbody tr, .tbody .tr {
|
||||
display: table;
|
||||
//display: table; MOVED
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
//table-layout: fixed; MOVED
|
||||
}
|
||||
thead, .thead {
|
||||
width: calc(100% - 10px);
|
||||
//width: calc(100% - 10px); MOVED
|
||||
tr, .tr {
|
||||
height: $tabularHeaderH;
|
||||
}
|
||||
@@ -56,12 +56,11 @@
|
||||
}
|
||||
}
|
||||
tbody, .tbody {
|
||||
@include absPosDefault(0);
|
||||
top: $tabularHeaderH;
|
||||
//display: table-row-group;
|
||||
display: block;
|
||||
//width: 100%;
|
||||
overflow-y: scroll;
|
||||
//@include absPosDefault(0); MOVED
|
||||
//top: $tabularHeaderH; MOVED
|
||||
//display: block; MOVED
|
||||
//overflow-y: scroll; MOVED
|
||||
display: table-row-group;
|
||||
tr, .tr {
|
||||
&:hover {
|
||||
background: rgba(white, 0.1);
|
||||
@@ -69,8 +68,7 @@
|
||||
}
|
||||
}
|
||||
tr, .tr {
|
||||
//display: table-row;
|
||||
//width: 100%;
|
||||
display: table-row;
|
||||
&:first-child .td {
|
||||
border-top: none;
|
||||
}
|
||||
@@ -100,30 +98,13 @@
|
||||
content: '1';
|
||||
}
|
||||
}
|
||||
/* em {
|
||||
//background: rgba(green, 0.2);
|
||||
border-left: 1px solid $tabularColorBorder;
|
||||
color: $tabularColorHeaderFg;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
height: $tabularHeaderH;
|
||||
line-height: $tabularHeaderH;
|
||||
margin-left: - $tabularTdPadLR;
|
||||
padding: 0 $tabularTdPadLR;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
vertical-align: middle;
|
||||
&:hover {
|
||||
color: lighten($tabularColorHeaderFg, 20%);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
td, .td {
|
||||
border-top: 1px solid $tabularColorBorder;
|
||||
min-width: 110px;
|
||||
color: $colorTelemFresh;
|
||||
padding: $tabularTdPadTB $tabularTdPadLR;
|
||||
vertical-align: top;
|
||||
&.numeric {
|
||||
text-align: right;
|
||||
}
|
||||
@@ -142,4 +123,27 @@
|
||||
top: $tabularHeaderH * 2;
|
||||
}
|
||||
}
|
||||
|
||||
&.fixed-header {
|
||||
height: 100%;
|
||||
thead, .thead,
|
||||
tbody tr, .tbody .tr {
|
||||
display: table;
|
||||
table-layout: fixed;
|
||||
}
|
||||
thead, .thead {
|
||||
width: calc(100% - 10px);
|
||||
}
|
||||
tbody, .tbody {
|
||||
@include absPosDefault(0);
|
||||
top: $tabularHeaderH;
|
||||
display: block;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
&.t-event-messages {
|
||||
td, .td {
|
||||
min-width: 150px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,8 @@
|
||||
|
||||
.bottom-bar {
|
||||
top: auto; right: 0; bottom: 0; left: 0;
|
||||
font-size: 1em;
|
||||
overflow: visible;
|
||||
//font-size: 1em;
|
||||
height: $ovrFooterH;
|
||||
text-align: right;
|
||||
.btn {
|
||||
|
||||
@@ -19,5 +19,4 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/* CONSTANTS */
|
||||
$bodyMargin: 5px;
|
||||
/* CONSTANTS */
|
||||
@@ -20,24 +20,31 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
.ue-bottom-bar {
|
||||
background: $colorFooterBg;
|
||||
color: lighten($colorBodyBg, 30%);
|
||||
font-size: 0.65rem;
|
||||
line-height: $ueFooterH - 4px;
|
||||
font-size: .7rem;
|
||||
//line-height: $ueFooterH - 4px;
|
||||
//line-height: $ueFooterH; // New status bar design
|
||||
.status-holder {
|
||||
@include border-radius($basicCr * 1.75);
|
||||
//@include border-radius($basicCr * 1.75); // New status bar design
|
||||
@include box-sizing(border-box);
|
||||
background: $colorFooterBg;
|
||||
border-bottom: 1px solid lighten($colorBodyBg, 10%);
|
||||
padding: 2px 5px;
|
||||
//background: $colorFooterBg;
|
||||
//border-bottom: 1px solid lighten($colorBodyBg, 10%); // New status bar design
|
||||
@include absPosDefault($interiorMargin);
|
||||
@include ellipsize();
|
||||
line-height: $ueFooterH - ($interiorMargin * 2);
|
||||
right: 120px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.app-logo {
|
||||
@include box-sizing(border-box);
|
||||
@include absPosDefault($interiorMargin);
|
||||
left: auto;
|
||||
cursor: pointer;
|
||||
font-size: 0.8em;
|
||||
line-height: $ueFooterH - 10px;
|
||||
padding-top: 1px;
|
||||
text-transform: uppercase;
|
||||
//font-size: 0.8em;
|
||||
//line-height: $ueFooterH - 10px;
|
||||
//padding-top: 1px;
|
||||
//text-transform: uppercase;
|
||||
&.logo-openmctweb {
|
||||
background: url($dirImgs + 'logo-openmctweb.svg') no-repeat center center;
|
||||
}
|
||||
@@ -45,16 +52,16 @@
|
||||
}
|
||||
|
||||
.status.block {
|
||||
display: inline-block;
|
||||
margin-right: $interiorMargin * 4;
|
||||
//display: inline-block;
|
||||
display: inline; // New status bar design. Inline to support ellipsis overflow
|
||||
margin-right: $interiorMargin * 2;
|
||||
.status-indicator {
|
||||
@include border-radius($controlCr * 0.9);
|
||||
@include box-shadow(inset rgba(black, 0.5) 0 0 3px);
|
||||
@include text-shadow(rgba(black, 0.3) 0 0 2px);
|
||||
//@include border-radius($controlCr * 0.9);
|
||||
//@include box-shadow(inset rgba(black, 0.5) 0 0 3px);
|
||||
//@include text-shadow(rgba(black, 0.3) 0 0 2px);
|
||||
display: inline-block;
|
||||
//font-size: 1.25em; // Normalized for new wtdsymbols font v2
|
||||
//vertical-align: middle; // Normalized for new wtdsymbols font v2
|
||||
margin-right: $interiorMarginSm;
|
||||
color: $colorKey;
|
||||
&.ok {
|
||||
color: #009900;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
}
|
||||
|
||||
.holder-all {
|
||||
$myM: $interiorMarginSm;
|
||||
$myM: 0; // $interiorMarginSm;
|
||||
top: $myM;
|
||||
right: $myM;
|
||||
bottom: $myM;
|
||||
@@ -93,7 +93,7 @@
|
||||
.editor {
|
||||
top: $bodyMargin + $ueTopBarH + ($interiorMargin);
|
||||
right: $bodyMargin;
|
||||
bottom: $bodyMargin + $ueFooterH + $interiorMargin;
|
||||
bottom: $ueFooterH + $bodyMargin;
|
||||
left: $bodyMargin;
|
||||
}
|
||||
|
||||
@@ -119,15 +119,18 @@
|
||||
}
|
||||
|
||||
.bottom-bar {
|
||||
@include absPosDefault($bodyMargin);
|
||||
//@include absPosDefault($bodyMargin);
|
||||
@include absPosDefault(0);// New status bar design
|
||||
top: auto;
|
||||
height: $ueFooterH;
|
||||
.status-holder {
|
||||
right: $ueAppLogoW + $bodyMargin;
|
||||
//right: $ueAppLogoW + $bodyMargin; New status bar design
|
||||
z-index: 1;
|
||||
}
|
||||
.app-logo {
|
||||
left: auto;
|
||||
width: $ueAppLogoW;
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<div class='abs bottom-bar ue-bottom-bar' ng-controller="BottomBarController as bar">
|
||||
<div id='status' class='status-holder abs'>
|
||||
<div id='status' class='status-holder'>
|
||||
<mct-include ng-repeat="indicator in bar.getIndicators()"
|
||||
ng-model="indicator.ngModel"
|
||||
key="indicator.template">
|
||||
|
||||
@@ -57,13 +57,17 @@ define(
|
||||
// mouse may leave this element during the drag.
|
||||
var body = $document.find('body'),
|
||||
initialPosition,
|
||||
$event,
|
||||
delta;
|
||||
|
||||
// Utility function to cause evaluation of mctDrag,
|
||||
// mctDragUp, etc
|
||||
function fireListener(name) {
|
||||
// Evaluate the expression, with current delta
|
||||
scope.$eval(attrs[name], { delta: delta });
|
||||
scope.$eval(attrs[name], {
|
||||
delta: delta,
|
||||
$event: $event
|
||||
});
|
||||
|
||||
// Trigger prompt digestion
|
||||
scope.$apply();
|
||||
@@ -82,6 +86,9 @@ define(
|
||||
delta = currentPosition.map(function (v, i) {
|
||||
return v - initialPosition[i];
|
||||
});
|
||||
|
||||
// Also track the plain event for firing listeners
|
||||
$event = event;
|
||||
}
|
||||
|
||||
// Called during a drag, on mousemove
|
||||
@@ -106,7 +113,7 @@ define(
|
||||
|
||||
fireListener("mctDragUp");
|
||||
|
||||
// Clear out start-of-drag position
|
||||
// Clear out start-of-drag position, target
|
||||
initialPosition = undefined;
|
||||
|
||||
// Don't show selection highlights, etc
|
||||
@@ -131,6 +138,7 @@ define(
|
||||
|
||||
// Don't show selection highlights, etc
|
||||
event.preventDefault();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -148,4 +156,4 @@ define(
|
||||
|
||||
return MCTDrag;
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
215
platform/commonUI/general/src/directives/MCTSplitPane.js
Normal file
215
platform/commonUI/general/src/directives/MCTSplitPane.js
Normal file
@@ -0,0 +1,215 @@
|
||||
/*****************************************************************************
|
||||
* 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';
|
||||
|
||||
// Pixel width to allocate for the splitter itself
|
||||
var DEFAULT_ANCHOR = 'left',
|
||||
CHILDREN_WARNING_MESSAGE = [
|
||||
"Invalid mct-split-pane contents.",
|
||||
"This element should contain exactly three",
|
||||
"child elements, where the middle-most element",
|
||||
"is an mct-splitter."
|
||||
].join(" "),
|
||||
ANCHOR_WARNING_MESSAGE = [
|
||||
"Unknown anchor provided to mct-split-pane,",
|
||||
"defaulting to",
|
||||
DEFAULT_ANCHOR + "."
|
||||
].join(" "),
|
||||
ANCHORS = {
|
||||
left: {
|
||||
edge: "left",
|
||||
opposite: "right",
|
||||
dimension: "width",
|
||||
orientation: "vertical"
|
||||
},
|
||||
right: {
|
||||
edge: "right",
|
||||
opposite: "left",
|
||||
dimension: "width",
|
||||
orientation: "vertical",
|
||||
reversed: true
|
||||
},
|
||||
top: {
|
||||
edge: "top",
|
||||
opposite: "bottom",
|
||||
dimension: "height",
|
||||
orientation: "horizontal"
|
||||
},
|
||||
bottom: {
|
||||
edge: "bottom",
|
||||
opposite: "top",
|
||||
dimension: "height",
|
||||
orientation: "horizontal",
|
||||
reversed: true
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements `mct-split-pane` directive.
|
||||
*
|
||||
* This takes the following attributes:
|
||||
* * `position`: Two-way bound scope variable which will contain
|
||||
* the pixel position of the splitter, offset from the appropriate
|
||||
* edge.
|
||||
* * `anchor`: Plain string, one of "left", "right", "top",
|
||||
* or "bottom".
|
||||
*
|
||||
* When used, an `mct-split-pane` element should contain exactly
|
||||
* three child elements, where the middle is an `mct-splitter`
|
||||
* element. These should be included in either left-to-right
|
||||
* or top-to-bottom order (depending on anchoring.) If the contents
|
||||
* do not match this form, `mct-split-pane` will issue a warning
|
||||
* and its behavior will be undefined.
|
||||
*
|
||||
* This directive works by setting the width of the element
|
||||
* nearest the anchor edge, and then positioning the other elements
|
||||
* based on its observed width. As such, `min-width`, `max-width`,
|
||||
* etc. can be set on that element to control the splitter's
|
||||
* allowable positions.
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
function MCTSplitPane($parse, $log) {
|
||||
var anchors = {
|
||||
left: true,
|
||||
right: true,
|
||||
top: true,
|
||||
bottom: true
|
||||
};
|
||||
|
||||
function controller($scope, $element, $attrs) {
|
||||
var anchorKey = $attrs.anchor || DEFAULT_ANCHOR,
|
||||
anchor,
|
||||
positionParsed = $parse($attrs.position),
|
||||
position; // Start undefined, until explicitly set
|
||||
|
||||
// Get relevant size (height or width) of DOM element
|
||||
function getSize(domElement) {
|
||||
return (anchor.orientation === 'vertical' ?
|
||||
domElement.offsetWidth : domElement.offsetHeight);
|
||||
}
|
||||
|
||||
// Apply styles to child elements
|
||||
function updateChildren(children) {
|
||||
// Pick out correct elements to update, flowing from
|
||||
// selected anchor edge.
|
||||
var first = children.eq(anchor.reversed ? 2 : 0),
|
||||
splitter = children.eq(1),
|
||||
last = children.eq(anchor.reversed ? 0 : 2),
|
||||
splitterSize = getSize(splitter[0]),
|
||||
firstSize;
|
||||
|
||||
first.css(anchor.edge, "0px");
|
||||
first.css(anchor.dimension, (position - splitterSize) + 'px');
|
||||
|
||||
// Get actual size (to obey min-width etc.)
|
||||
firstSize = getSize(first[0]);
|
||||
first.css(anchor.dimension, firstSize + 'px');
|
||||
splitter.css(anchor.edge, (firstSize + splitterSize) + 'px');
|
||||
splitter.css(anchor.opposite, "auto");
|
||||
|
||||
last.css(anchor.edge, (firstSize + splitterSize * 3) + 'px');
|
||||
last.css(anchor.opposite, "0px");
|
||||
|
||||
position = firstSize + splitterSize;
|
||||
}
|
||||
|
||||
// Update positioning of contained elements
|
||||
function updateElementPositions() {
|
||||
var children = $element.children();
|
||||
|
||||
// Check to make sure contents are well-formed
|
||||
if (children.length !== 3 ||
|
||||
children[1].nodeName.toLowerCase() !== 'mct-splitter') {
|
||||
$log.warn(CHILDREN_WARNING_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
updateChildren(children);
|
||||
}
|
||||
|
||||
// Enforce minimum/maximum positions
|
||||
function enforceExtrema() {
|
||||
position = Math.max(position, 0);
|
||||
position = Math.min(position, getSize($element[0]));
|
||||
}
|
||||
|
||||
// Getter-setter for the pixel offset of the splitter,
|
||||
// relative to the current edge.
|
||||
function getSetPosition(value) {
|
||||
var min, max;
|
||||
if (typeof value === 'number') {
|
||||
position = value;
|
||||
enforceExtrema();
|
||||
updateElementPositions();
|
||||
|
||||
// Pass change up so this state can be shared
|
||||
if (positionParsed.assign) {
|
||||
positionParsed.assign($scope, position);
|
||||
}
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
// Make sure anchor parameter is something we know
|
||||
if (!ANCHORS[anchorKey]) {
|
||||
$log.warn(ANCHOR_WARNING_MESSAGE);
|
||||
anchorKey = DEFAULT_ANCHOR;
|
||||
}
|
||||
anchor = ANCHORS[anchorKey];
|
||||
|
||||
$scope.$watch($attrs.position, getSetPosition);
|
||||
|
||||
$element.addClass("split-layout");
|
||||
$element.addClass(anchor.orientation);
|
||||
|
||||
// Initialize positions
|
||||
getSetPosition(getSize(
|
||||
$element.children().eq(anchor.reversed ? 2 : 0)[0]
|
||||
));
|
||||
|
||||
// Interface exposed by controller, for mct-splitter to user
|
||||
return {
|
||||
position: getSetPosition,
|
||||
anchor: function () {
|
||||
return anchor;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
// Restrict to attributes
|
||||
restrict: "E",
|
||||
// Expose its controller
|
||||
controller: ['$scope', '$element', '$attrs', controller]
|
||||
};
|
||||
}
|
||||
|
||||
return MCTSplitPane;
|
||||
|
||||
}
|
||||
);
|
||||
90
platform/commonUI/general/src/directives/MCTSplitter.js
Normal file
90
platform/commonUI/general/src/directives/MCTSplitter.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(
|
||||
[],
|
||||
function () {
|
||||
'use strict';
|
||||
|
||||
// Pixel width to allocate for the splitter itself
|
||||
var SPLITTER_TEMPLATE = "<div class='abs'" +
|
||||
"mct-drag-down=\"splitter.startMove()\" " +
|
||||
"mct-drag=\"splitter.move(delta)\"></div>",
|
||||
OFFSETS_BY_EDGE = {
|
||||
left: "offsetLeft",
|
||||
right: "offsetRight",
|
||||
top: "offsetTop",
|
||||
bottom: "offsetBottom"
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements `mct-splitter` directive.
|
||||
* @constructor
|
||||
*/
|
||||
function MCTSplitter() {
|
||||
function link(scope, element, attrs, mctSplitPane) {
|
||||
var initialPosition;
|
||||
|
||||
element.addClass("splitter");
|
||||
|
||||
// Now that we have the above class, the splitter width
|
||||
// will have changed, so trigger a positioning update.
|
||||
mctSplitPane.position(mctSplitPane.position());
|
||||
|
||||
scope.splitter = {
|
||||
// Begin moving this splitter
|
||||
startMove: function () {
|
||||
var splitter = element[0];
|
||||
initialPosition = mctSplitPane.position();
|
||||
},
|
||||
// Handle user changes to splitter position
|
||||
move: function (delta) {
|
||||
var anchor = mctSplitPane.anchor(),
|
||||
index = anchor.orientation === "vertical" ? 0 : 1,
|
||||
pixelDelta = delta[index] *
|
||||
(anchor.reversed ? -1 : 1);
|
||||
|
||||
// Update the position of this splitter
|
||||
mctSplitPane.position(initialPosition + pixelDelta);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
// Restrict to attributes
|
||||
restrict: "E",
|
||||
// Utilize the mct-split-pane controller
|
||||
require: "^mctSplitPane",
|
||||
// Expose its controller
|
||||
link: link,
|
||||
// Use the template defined above
|
||||
template: SPLITTER_TEMPLATE,
|
||||
// Create a new scope to put the splitter into
|
||||
scope: true
|
||||
};
|
||||
}
|
||||
|
||||
return MCTSplitter;
|
||||
|
||||
}
|
||||
);
|
||||
@@ -39,34 +39,52 @@ define(
|
||||
// is returned. The view is defaulted to
|
||||
// the current location's (current object's)
|
||||
// view set.
|
||||
function urlFor(mode, domainObject) {
|
||||
function urlForLocation(mode, domainObject) {
|
||||
var context = domainObject &&
|
||||
domainObject.getCapability('context'),
|
||||
objectPath = context ? context.getPath() : [],
|
||||
ids = objectPath.map(function (domainObject) {
|
||||
return domainObject.getId();
|
||||
}),
|
||||
viewPath = "?view=" + $location.search().view,
|
||||
// Parses the path together. Starts with the
|
||||
// default index.html file, then the mode passed
|
||||
// into the service, followed by ids in the url
|
||||
// joined by '/', and lastly the view path from
|
||||
// the current location
|
||||
path = "index.html#/" + mode + "/" +
|
||||
ids.slice(1).join("/") + viewPath;
|
||||
|
||||
path = mode + "/" + ids.slice(1).join("/");
|
||||
return path;
|
||||
}
|
||||
|
||||
// Uses the Url for the current location
|
||||
// from the urlForLocation function and
|
||||
// includes the view and the index path
|
||||
function urlForNewTab(mode, domainObject) {
|
||||
var viewPath = "?view=" + $location.search().view,
|
||||
newTabPath =
|
||||
"index.html#" + urlForLocation(mode, domainObject) + viewPath;
|
||||
return newTabPath;
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Returns the Url path for a specific domain object
|
||||
* without the index.html path and the view path
|
||||
* @param {value} value of the browse or edit mode
|
||||
* for the path
|
||||
* @param {DomainObject} value of the domain object
|
||||
* to get the path of
|
||||
*/
|
||||
urlFor: urlFor
|
||||
urlForNewTab: urlForNewTab,
|
||||
/**
|
||||
* Returns the Url path for a specific domain object
|
||||
* including the index.html path and the view path
|
||||
* allowing a new tab to hold the correct characteristics
|
||||
* @param {value} value of the browse or edit mode
|
||||
* for the path
|
||||
* @param {DomainObject} value of the domain object
|
||||
* to get the path of
|
||||
*/
|
||||
urlForLocation: urlForLocation
|
||||
};
|
||||
}
|
||||
|
||||
@@ -81,10 +81,11 @@ define(
|
||||
});
|
||||
|
||||
it("invokes mctDragDown when dragging begins", function () {
|
||||
mockElement.on.mostRecentCall.args[1](testEvent(42, 60));
|
||||
var event = testEvent(42, 60);
|
||||
mockElement.on.mostRecentCall.args[1](event);
|
||||
expect(mockScope.$eval).toHaveBeenCalledWith(
|
||||
testAttrs.mctDragDown,
|
||||
{ delta: [0, 0] }
|
||||
{ delta: [0, 0], $event: event }
|
||||
);
|
||||
});
|
||||
|
||||
@@ -101,23 +102,27 @@ define(
|
||||
});
|
||||
|
||||
it("invokes mctDrag expression during drag", function () {
|
||||
var event;
|
||||
|
||||
mockElement.on.mostRecentCall.args[1](testEvent(42, 60));
|
||||
|
||||
// Find and invoke the mousemove listener
|
||||
mockBody.on.calls.forEach(function (call) {
|
||||
if (call.args[0] === 'mousemove') {
|
||||
call.args[1](testEvent(52, 200));
|
||||
call.args[1](event = testEvent(52, 200));
|
||||
}
|
||||
});
|
||||
|
||||
// Should have passed that delta to mct-drag expression
|
||||
expect(mockScope.$eval).toHaveBeenCalledWith(
|
||||
testAttrs.mctDrag,
|
||||
{ delta: [10, 140] }
|
||||
{ delta: [10, 140], $event: event }
|
||||
);
|
||||
});
|
||||
|
||||
it("invokes mctDragUp expression after drag", function () {
|
||||
var event;
|
||||
|
||||
mockElement.on.mostRecentCall.args[1](testEvent(42, 60));
|
||||
|
||||
// Find and invoke the mousemove listener
|
||||
@@ -129,7 +134,7 @@ define(
|
||||
// Find and invoke the mousemove listener
|
||||
mockBody.on.calls.forEach(function (call) {
|
||||
if (call.args[0] === 'mouseup') {
|
||||
call.args[1](testEvent(40, 71));
|
||||
call.args[1](event = testEvent(40, 71));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -138,7 +143,7 @@ define(
|
||||
// initial position
|
||||
expect(mockScope.$eval).toHaveBeenCalledWith(
|
||||
testAttrs.mctDragUp,
|
||||
{ delta: [-2, 11] }
|
||||
{ delta: [-2, 11], $event: event }
|
||||
);
|
||||
|
||||
// Should also have unregistered listeners
|
||||
@@ -147,4 +152,4 @@ define(
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
@@ -31,7 +31,11 @@ define(
|
||||
|
||||
describe("The url service", function () {
|
||||
var urlService,
|
||||
mockLocation;
|
||||
mockLocation,
|
||||
mockDomainObject,
|
||||
mockContext,
|
||||
mockMode,
|
||||
testViews;
|
||||
|
||||
beforeEach(function () {
|
||||
// Creates a mockLocation, used to
|
||||
@@ -41,24 +45,20 @@ define(
|
||||
[ "path", "search" ]
|
||||
);
|
||||
|
||||
urlService = new UrlService(mockLocation);
|
||||
});
|
||||
|
||||
it("get url for a domainObject and mode", function () {
|
||||
// The mockDomainObject is initialized as a
|
||||
// The mockDomainObject is initialized as a
|
||||
// spy object to ultimately be passed into the
|
||||
// urlService urlFor function
|
||||
var mockDomainObject = jasmine.createSpyObj(
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
"domainObject",
|
||||
[ "getId", "getCapability", "getModel", "useCapability" ]
|
||||
),
|
||||
mockContext = jasmine.createSpyObj('context', ['getPath']),
|
||||
testViews = [
|
||||
{ key: 'abc' },
|
||||
{ key: 'def', someKey: 'some value' },
|
||||
{ key: 'xyz' }
|
||||
],
|
||||
mockMode = "browse";
|
||||
);
|
||||
mockContext = jasmine.createSpyObj('context', ['getPath']);
|
||||
testViews = [
|
||||
{ key: 'abc' },
|
||||
{ key: 'def', someKey: 'some value' },
|
||||
{ key: 'xyz' }
|
||||
];
|
||||
mockMode = "browse";
|
||||
|
||||
// The mockContext is set a path
|
||||
// for the mockDomainObject
|
||||
@@ -81,8 +81,17 @@ define(
|
||||
// Uses the mockLocation to get the current
|
||||
// "mock" website's view
|
||||
mockLocation.search.andReturn({ view: 'def' });
|
||||
urlService.urlFor(mockMode, mockDomainObject);
|
||||
|
||||
urlService = new UrlService(mockLocation);
|
||||
});
|
||||
|
||||
it("get url for a location using domainObject and mode", function () {
|
||||
urlService.urlForLocation(mockMode, mockDomainObject);
|
||||
});
|
||||
|
||||
it("get url for a new tab using domainObject and mode", function () {
|
||||
urlService.urlForNewTab(mockMode, mockDomainObject);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -13,5 +13,6 @@
|
||||
"directives/MCTDrag",
|
||||
"directives/MCTResize",
|
||||
"directives/MCTScroll",
|
||||
"services/UrlService",
|
||||
"StyleSheetLoader"
|
||||
]
|
||||
@@ -183,7 +183,7 @@
|
||||
{
|
||||
"key": "mutation",
|
||||
"implementation": "capabilities/MutationCapability.js",
|
||||
"depends": [ "now" ]
|
||||
"depends": [ "topic", "now" ]
|
||||
},
|
||||
{
|
||||
"key": "delegation",
|
||||
@@ -200,6 +200,10 @@
|
||||
"key": "throttle",
|
||||
"implementation": "services/Throttle.js",
|
||||
"depends": [ "$timeout" ]
|
||||
},
|
||||
{
|
||||
"key": "topic",
|
||||
"implementation": "services/Topic.js"
|
||||
}
|
||||
],
|
||||
"roots": [
|
||||
|
||||
@@ -29,6 +29,8 @@ define(
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
var TOPIC_PREFIX = "mutation:";
|
||||
|
||||
// Utility function to overwrite a destination object
|
||||
// with the contents of a source object.
|
||||
function copyValues(destination, source) {
|
||||
@@ -71,7 +73,8 @@ define(
|
||||
* which will expose this capability
|
||||
* @constructor
|
||||
*/
|
||||
function MutationCapability(now, domainObject) {
|
||||
function MutationCapability(topic, now, domainObject) {
|
||||
var t = topic(TOPIC_PREFIX + domainObject.getId());
|
||||
|
||||
function mutate(mutator, timestamp) {
|
||||
// Get the object's model and clone it, so the
|
||||
@@ -96,6 +99,7 @@ define(
|
||||
copyValues(model, result);
|
||||
}
|
||||
model.modified = useTimestamp ? timestamp : now();
|
||||
t.notify(model);
|
||||
}
|
||||
|
||||
// Report the result of the mutation
|
||||
@@ -107,6 +111,10 @@ define(
|
||||
return fastPromise(mutator(clone)).then(handleMutation);
|
||||
}
|
||||
|
||||
function listen(listener) {
|
||||
return t.listen(listener);
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Alias of `mutate`, used to support useCapability.
|
||||
@@ -139,10 +147,19 @@ define(
|
||||
* @returns {Promise.<boolean>} a promise for the result
|
||||
* of the mutation; true if changes were made.
|
||||
*/
|
||||
mutate: mutate
|
||||
mutate: mutate,
|
||||
/**
|
||||
* Listen for mutations of this domain object's model.
|
||||
* The provided listener will be invoked with the domain
|
||||
* object's new model after any changes. To stop listening,
|
||||
* invoke the function returned by this method.
|
||||
* @param {Function} listener function to call on mutation
|
||||
* @returns {Function} a function to stop listening
|
||||
*/
|
||||
listen: listen
|
||||
};
|
||||
}
|
||||
|
||||
return MutationCapability;
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*****************************************************************************
|
||||
* 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(
|
||||
|
||||
87
platform/core/src/services/Topic.js
Normal file
87
platform/core/src/services/Topic.js
Normal file
@@ -0,0 +1,87 @@
|
||||
/*****************************************************************************
|
||||
* 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";
|
||||
|
||||
/**
|
||||
* The `topic` service provides a way to create both named,
|
||||
* shared listeners and anonymous, private listeners.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* ```
|
||||
* var t = topic('foo'); // Use/create a named topic
|
||||
* t.listen(function () { ... });
|
||||
* t.notify({ some: "message" });
|
||||
* ```
|
||||
*
|
||||
* Named topics are shared; multiple calls to `topic`
|
||||
* with the same argument will return a single object instance.
|
||||
* Anonymous topics (where `topic` has been called with no
|
||||
* arguments) are private; each call returns a new instance.
|
||||
*
|
||||
* @returns {Function}
|
||||
*/
|
||||
function Topic() {
|
||||
var topics = {};
|
||||
|
||||
function createTopic() {
|
||||
var listeners = [];
|
||||
|
||||
return {
|
||||
listen: function (listener) {
|
||||
listeners.push(listener);
|
||||
return function unlisten() {
|
||||
listeners = listeners.filter(function (l) {
|
||||
return l !== listener;
|
||||
});
|
||||
};
|
||||
},
|
||||
notify: function (message) {
|
||||
listeners.forEach(function (listener) {
|
||||
listener(message);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Use and (if necessary) create a new topic.
|
||||
* @param {string} [key] name of the topic to use
|
||||
*/
|
||||
return function (key) {
|
||||
if (arguments.length < 1) {
|
||||
return createTopic();
|
||||
} else {
|
||||
topics[key] = topics[key] || createTopic();
|
||||
return topics[key];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return Topic;
|
||||
}
|
||||
);
|
||||
@@ -25,21 +25,33 @@
|
||||
* MutationCapabilitySpec. Created by vwoeltje on 11/6/14.
|
||||
*/
|
||||
define(
|
||||
["../../src/capabilities/MutationCapability"],
|
||||
function (MutationCapability) {
|
||||
[
|
||||
"../../src/capabilities/MutationCapability",
|
||||
"../../src/services/Topic"
|
||||
],
|
||||
function (MutationCapability, Topic) {
|
||||
"use strict";
|
||||
|
||||
describe("The mutation capability", function () {
|
||||
var testModel,
|
||||
topic,
|
||||
mockNow,
|
||||
domainObject = { getModel: function () { return testModel; } },
|
||||
domainObject = {
|
||||
getId: function () { return "test-id"; },
|
||||
getModel: function () { return testModel; }
|
||||
},
|
||||
mutation;
|
||||
|
||||
beforeEach(function () {
|
||||
testModel = { number: 6 };
|
||||
topic = new Topic();
|
||||
mockNow = jasmine.createSpy('now');
|
||||
mockNow.andReturn(12321);
|
||||
mutation = new MutationCapability(mockNow, domainObject);
|
||||
mutation = new MutationCapability(
|
||||
topic,
|
||||
mockNow,
|
||||
domainObject
|
||||
);
|
||||
});
|
||||
|
||||
it("allows mutation of a model", function () {
|
||||
@@ -83,6 +95,42 @@ define(
|
||||
// Should have gotten a timestamp from 'now'
|
||||
expect(testModel.modified).toEqual(42);
|
||||
});
|
||||
|
||||
it("notifies listeners of mutation", function () {
|
||||
var mockCallback = jasmine.createSpy('callback');
|
||||
mutation.listen(mockCallback);
|
||||
mutation.invoke(function (m) {
|
||||
m.number = 8;
|
||||
});
|
||||
expect(mockCallback).toHaveBeenCalled();
|
||||
expect(mockCallback.mostRecentCall.args[0].number)
|
||||
.toEqual(8);
|
||||
});
|
||||
|
||||
it("allows listeners to stop listening", function () {
|
||||
var mockCallback = jasmine.createSpy('callback');
|
||||
mutation.listen(mockCallback)(); // Unlisten immediately
|
||||
mutation.invoke(function (m) {
|
||||
m.number = 8;
|
||||
});
|
||||
expect(mockCallback).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("shares listeners across instances", function () {
|
||||
var mockCallback = jasmine.createSpy('callback'),
|
||||
otherMutation = new MutationCapability(
|
||||
topic,
|
||||
mockNow,
|
||||
domainObject
|
||||
);
|
||||
mutation.listen(mockCallback);
|
||||
otherMutation.invoke(function (m) {
|
||||
m.number = 8;
|
||||
});
|
||||
expect(mockCallback).toHaveBeenCalled();
|
||||
expect(mockCallback.mostRecentCall.args[0].number)
|
||||
.toEqual(8);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*****************************************************************************
|
||||
* 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(
|
||||
|
||||
70
platform/core/test/services/TopicSpec.js
Normal file
70
platform/core/test/services/TopicSpec.js
Normal file
@@ -0,0 +1,70 @@
|
||||
/*****************************************************************************
|
||||
* 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/services/Topic"],
|
||||
function (Topic) {
|
||||
"use strict";
|
||||
|
||||
describe("The 'topic' service", function () {
|
||||
var topic,
|
||||
testMessage,
|
||||
mockCallback;
|
||||
|
||||
beforeEach(function () {
|
||||
testMessage = { someKey: "some value"};
|
||||
mockCallback = jasmine.createSpy('callback');
|
||||
topic = new Topic();
|
||||
});
|
||||
|
||||
it("notifies listeners on a topic", function () {
|
||||
topic("abc").listen(mockCallback);
|
||||
topic("abc").notify(testMessage);
|
||||
expect(mockCallback).toHaveBeenCalledWith(testMessage);
|
||||
});
|
||||
|
||||
it("does not notify listeners across topics", function () {
|
||||
topic("abc").listen(mockCallback);
|
||||
topic("xyz").notify(testMessage);
|
||||
expect(mockCallback).not.toHaveBeenCalledWith(testMessage);
|
||||
});
|
||||
|
||||
it("does not notify listeners after unlistening", function () {
|
||||
topic("abc").listen(mockCallback)(); // Unlisten immediately
|
||||
topic("abc").notify(testMessage);
|
||||
expect(mockCallback).not.toHaveBeenCalledWith(testMessage);
|
||||
});
|
||||
|
||||
it("provides anonymous private topics", function () {
|
||||
var t1 = topic(), t2 = topic();
|
||||
|
||||
t1.listen(mockCallback);
|
||||
t2.notify(testMessage);
|
||||
expect(mockCallback).not.toHaveBeenCalledWith(testMessage);
|
||||
t1.notify(testMessage);
|
||||
expect(mockCallback).toHaveBeenCalledWith(testMessage);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
"services/Now",
|
||||
"services/Throttle",
|
||||
"services/Topic",
|
||||
|
||||
"types/MergeModels",
|
||||
"types/TypeCapability",
|
||||
@@ -35,4 +36,4 @@
|
||||
|
||||
"views/ViewCapability",
|
||||
"views/ViewProvider"
|
||||
]
|
||||
]
|
||||
|
||||
37
platform/features/events/bundle.json
Normal file
37
platform/features/events/bundle.json
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "Event Messages",
|
||||
"description": "List of time-ordered event messages",
|
||||
"extensions": {
|
||||
"views": [
|
||||
{
|
||||
"key": "messages",
|
||||
"name": "Messages",
|
||||
"glyph": "5",
|
||||
"description": "Scrolling list of messages.",
|
||||
"templateUrl": "templates/messages.html",
|
||||
"needs": [ "telemetry" ],
|
||||
"delegation": true
|
||||
}
|
||||
],
|
||||
"controllers": [
|
||||
{
|
||||
"key": "EventListController",
|
||||
"implementation": "EventListController.js",
|
||||
"depends": [ "$scope", "telemetryFormatter" ]
|
||||
}
|
||||
],
|
||||
"directives": [
|
||||
{
|
||||
"key": "mctDataTable",
|
||||
"implementation": "directives/MCTDataTable.js",
|
||||
"depends": [ "$window" ]
|
||||
}
|
||||
],
|
||||
"policies": [
|
||||
{
|
||||
"category": "view",
|
||||
"implementation": "policies/MessagesViewPolicy.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
37
platform/features/events/res/templates/mct-data-table.html
Normal file
37
platform/features/events/res/templates/mct-data-table.html
Normal file
@@ -0,0 +1,37 @@
|
||||
<!--
|
||||
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>
|
||||
29
platform/features/events/res/templates/messages.html
Normal file
29
platform/features/events/res/templates/messages.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<!--
|
||||
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>
|
||||
|
||||
|
||||
67
platform/features/events/src/DomainColumn.js
Normal file
67
platform/features/events/src/DomainColumn.js
Normal file
@@ -0,0 +1,67 @@
|
||||
/*****************************************************************************
|
||||
* 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,moment*/
|
||||
|
||||
/**
|
||||
* Module defining DomainColumn. Created by vwoeltje on 11/18/14.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* A column which will report telemetry domain values
|
||||
* (typically, timestamps.) Used by the ScrollingListController.
|
||||
*
|
||||
* @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(domainMetadata, telemetryFormatter) {
|
||||
return {
|
||||
/**
|
||||
* Get the title to display in this column's header.
|
||||
* @returns {string} the title to display
|
||||
*/
|
||||
getTitle: function () {
|
||||
return domainMetadata.name;
|
||||
},
|
||||
/**
|
||||
* Get the text to display inside a row under this
|
||||
* column.
|
||||
* @returns {string} the text to display
|
||||
*/
|
||||
getValue: function (domainObject, data, index) {
|
||||
return telemetryFormatter.formatDomainValue(
|
||||
data.getDomainValue(index, domainMetadata.key)
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return DomainColumn;
|
||||
}
|
||||
);
|
||||
133
platform/features/events/src/EventListController.js
Normal file
133
platform/features/events/src/EventListController.js
Normal file
@@ -0,0 +1,133 @@
|
||||
/*****************************************************************************
|
||||
* 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*/
|
||||
|
||||
/**
|
||||
* Module defining EventListController.
|
||||
* Created by chacskaylo on 06/18/2015.
|
||||
* Modified by shale on 06/23/2015.
|
||||
*/
|
||||
define(
|
||||
["./DomainColumn", "./RangeColumn", "./EventListPopulator"],
|
||||
function (DomainColumn, RangeColumn, EventListPopulator) {
|
||||
"use strict";
|
||||
|
||||
var ROW_COUNT = 100;
|
||||
|
||||
/**
|
||||
* The EventListController is responsible for populating
|
||||
* the contents of the event list view.
|
||||
* @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;
|
||||
}
|
||||
);
|
||||
161
platform/features/events/src/EventListPopulator.js
Normal file
161
platform/features/events/src/EventListPopulator.js
Normal file
@@ -0,0 +1,161 @@
|
||||
/*****************************************************************************
|
||||
* 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";
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param {Column[]} columns the columns to be populated
|
||||
*/
|
||||
function EventListPopulator(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;
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
/**
|
||||
* Get the text which should appear in headers for the
|
||||
* provided columns.
|
||||
* @returns {string[]} column headers
|
||||
*/
|
||||
getHeaders: function () {
|
||||
return 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
|
||||
* @returns {string[][]} an array of rows, each of which
|
||||
* is an array of values which should appear
|
||||
* in that row
|
||||
*/
|
||||
getRows: function (datas, objects, count) {
|
||||
var values = getLatestDataValues(datas, count);
|
||||
|
||||
// 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;
|
||||
|
||||
}
|
||||
);
|
||||
67
platform/features/events/src/RangeColumn.js
Normal file
67
platform/features/events/src/RangeColumn.js
Normal file
@@ -0,0 +1,67 @@
|
||||
/*****************************************************************************
|
||||
* 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*/
|
||||
|
||||
/**
|
||||
* Module defining DomainColumn. Created by vwoeltje on 11/18/14.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* A column which will report telemetry range values
|
||||
* (typically, measurements.) Used by the ScrollingListController.
|
||||
*
|
||||
* @constructor
|
||||
* @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) {
|
||||
return {
|
||||
/**
|
||||
* Get the title to display in this column's header.
|
||||
* @returns {string} the title to display
|
||||
*/
|
||||
getTitle: function () {
|
||||
return rangeMetadata.name;
|
||||
},
|
||||
/**
|
||||
* Get the text to display inside a row under this
|
||||
* column.
|
||||
* @returns {string} the text to display
|
||||
*/
|
||||
getValue: function (domainObject, data, index) {
|
||||
return telemetryFormatter.formatRangeValue(
|
||||
data.getRangeValue(index, rangeMetadata.key)
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return RangeColumn;
|
||||
}
|
||||
);
|
||||
74
platform/features/events/src/directives/MCTDataTable.js
Normal file
74
platform/features/events/src/directives/MCTDataTable.js
Normal file
@@ -0,0 +1,74 @@
|
||||
/*****************************************************************************
|
||||
* 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*/
|
||||
|
||||
/**
|
||||
* Module defining MCTDataTable. Created by shale on 06/22/2015.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
function MCTDataTable($window) {
|
||||
return {
|
||||
restrict: "E",
|
||||
templateUrl: "platform/features/events/res/templates/mct-data-table.html",
|
||||
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;
|
||||
}
|
||||
);
|
||||
74
platform/features/events/src/policies/MessagesViewPolicy.js
Normal file
74
platform/features/events/src/policies/MessagesViewPolicy.js
Normal file
@@ -0,0 +1,74 @@
|
||||
/*****************************************************************************
|
||||
* 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*/
|
||||
|
||||
/**
|
||||
* Module defining MessagesViewPolicy. Created by shale on 06/24/2015.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Policy controlling when the Messages view should be avaliable.
|
||||
* @constructor
|
||||
*/
|
||||
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';
|
||||
});
|
||||
}
|
||||
return {
|
||||
/**
|
||||
* Check whether or not a given action is allowed by this
|
||||
* policy.
|
||||
* @param {Action} action the action
|
||||
* @param domainObject the domain object which will be viewed
|
||||
* @returns {boolean} true if not disallowed
|
||||
*/
|
||||
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;
|
||||
}
|
||||
);
|
||||
84
platform/features/events/test/DomainColumnSpec.js
Normal file
84
platform/features/events/test/DomainColumnSpec.js
Normal file
@@ -0,0 +1,84 @@
|
||||
/*****************************************************************************
|
||||
* 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,it,expect,beforeEach,waitsFor,jasmine*/
|
||||
|
||||
/**
|
||||
* EventSpec. Created by vwoeltje on 11/6/14. Modified by shale on 06/23/2015.
|
||||
*/
|
||||
define(
|
||||
["../src/DomainColumn"],
|
||||
function (DomainColumn) {
|
||||
"use strict";
|
||||
|
||||
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();
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
110
platform/features/events/test/EventListControllerSpec.js
Normal file
110
platform/features/events/test/EventListControllerSpec.js
Normal file
@@ -0,0 +1,110 @@
|
||||
/*****************************************************************************
|
||||
* 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,it,expect,beforeEach,waitsFor,jasmine*/
|
||||
|
||||
/**
|
||||
* EventSpec. Created by shale on 06/24/2015.
|
||||
*/
|
||||
define(
|
||||
["../src/EventListController"],
|
||||
function (EventListController) {
|
||||
"use strict";
|
||||
|
||||
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"]);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
103
platform/features/events/test/EventListPopulatorSpec.js
Normal file
103
platform/features/events/test/EventListPopulatorSpec.js
Normal file
@@ -0,0 +1,103 @@
|
||||
/*****************************************************************************
|
||||
* 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,it,expect,beforeEach,waitsFor,jasmine*/
|
||||
|
||||
/**
|
||||
* EventSpec. Created by shale on 06/24/2015.
|
||||
*/
|
||||
define(
|
||||
["../src/EventListPopulator"],
|
||||
function (EventListPopulator) {
|
||||
"use strict";
|
||||
|
||||
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];
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
81
platform/features/events/test/RangeColumnSpec.js
Normal file
81
platform/features/events/test/RangeColumnSpec.js
Normal file
@@ -0,0 +1,81 @@
|
||||
/*****************************************************************************
|
||||
* 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,it,expect,beforeEach,waitsFor,jasmine*/
|
||||
|
||||
/**
|
||||
* EventSpec. Created by vwoeltje on 11/6/14. Modified by shale on 06/23/2015.
|
||||
*/
|
||||
define(
|
||||
["../src/RangeColumn"],
|
||||
function (RangeColumn) {
|
||||
"use strict";
|
||||
|
||||
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();
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,81 @@
|
||||
/*****************************************************************************
|
||||
* 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,it,expect,beforeEach,jasmine*/
|
||||
|
||||
/**
|
||||
* EventSpec. Created by shale on 06/24/2015.
|
||||
*/
|
||||
define(
|
||||
["../../src/policies/MessagesViewPolicy"],
|
||||
function (MessagesViewPolicy) {
|
||||
"use strict";
|
||||
|
||||
describe("The messages view policy", function () {
|
||||
var mockDomainObject,
|
||||
mockTelemetry,
|
||||
telemetryType,
|
||||
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 (c) {
|
||||
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();
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
7
platform/features/events/test/suite.json
Normal file
7
platform/features/events/test/suite.json
Normal file
@@ -0,0 +1,7 @@
|
||||
[
|
||||
"DomainColumn",
|
||||
"EventListController",
|
||||
"EventListPopulator",
|
||||
"policies/MessagesViewPolicy",
|
||||
"RangeColumn"
|
||||
]
|
||||
@@ -194,6 +194,12 @@
|
||||
"templateUrl": "templates/elements/image.html"
|
||||
}
|
||||
],
|
||||
"policies": [
|
||||
{
|
||||
"category": "composition",
|
||||
"implementation": "LayoutCompositionPolicy.js"
|
||||
}
|
||||
],
|
||||
"types": [
|
||||
{
|
||||
"key": "layout",
|
||||
@@ -267,4 +273,4 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<span
|
||||
class="l-elem l-value l-obj-val-format"
|
||||
data-value="{{ngModel.value}}"
|
||||
ng-class="ngModel.cssClass + ' ' + (ngModel.element.titled ? 'telem-only' : '')"
|
||||
ng-class="ngModel.cssClass"
|
||||
>
|
||||
{{ngModel.value}}
|
||||
</span>
|
||||
|
||||
@@ -20,14 +20,13 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<div class="t-fixed-position l-fixed-position"
|
||||
ng-controller="FixedController as controller"
|
||||
mct-resize="controller.setBounds(bounds)">
|
||||
ng-controller="FixedController as controller">
|
||||
|
||||
<!-- Background grid -->
|
||||
<div class="l-grid-holder" ng-click="controller.clearSelection()">
|
||||
<div class="l-grid l-grid-x"
|
||||
<div class="l-grid l-grid-x"
|
||||
ng-style="{ 'background-size': controller.getGridSize() [0] + 'px 100%' }"></div>
|
||||
<div class="l-grid l-grid-y"
|
||||
<div class="l-grid l-grid-y"
|
||||
ng-style="{ 'background-size': '100% ' + controller.getGridSize() [1] + 'px' }"></div>
|
||||
</div>
|
||||
|
||||
@@ -60,4 +59,4 @@
|
||||
</div>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -27,8 +27,7 @@ define(
|
||||
"use strict";
|
||||
|
||||
var DEFAULT_DIMENSIONS = [ 2, 1 ],
|
||||
DEFAULT_GRID_SIZE = [64, 16],
|
||||
DEFAULT_GRID_EXTENT = [4, 4];
|
||||
DEFAULT_GRID_SIZE = [64, 16];
|
||||
|
||||
/**
|
||||
* The FixedController is responsible for supporting the
|
||||
@@ -40,10 +39,8 @@ define(
|
||||
*/
|
||||
function FixedController($scope, $q, dialogService, telemetrySubscriber, telemetryFormatter) {
|
||||
var gridSize = DEFAULT_GRID_SIZE,
|
||||
gridExtent = DEFAULT_GRID_EXTENT,
|
||||
dragging,
|
||||
subscription,
|
||||
cellStyles = [],
|
||||
elementProxies = [],
|
||||
names = {}, // Cache names by ID
|
||||
values = {}, // Cache values by ID
|
||||
@@ -52,29 +49,6 @@ define(
|
||||
moveHandle,
|
||||
selection;
|
||||
|
||||
// Refresh cell styles (e.g. because grid extent changed)
|
||||
function refreshCellStyles() {
|
||||
var x, y;
|
||||
|
||||
// Clear previous styles
|
||||
cellStyles = [];
|
||||
|
||||
// Update grid size from model
|
||||
gridSize = ($scope.model || {}).layoutGrid || gridSize;
|
||||
|
||||
for (x = 0; x < gridExtent[0]; x += 1) {
|
||||
for (y = 0; y < gridExtent[1]; y += 1) {
|
||||
// Position blocks; subtract out border size from w/h
|
||||
cellStyles.push({
|
||||
left: x * gridSize[0] + 'px',
|
||||
top: y * gridSize[1] + 'px',
|
||||
width: gridSize[0] - 1 + 'px',
|
||||
height: gridSize[1] - 1 + 'px'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert from element x/y/width/height to an
|
||||
// apropriate ng-style argument, to position elements.
|
||||
function convertPosition(elementProxy) {
|
||||
@@ -143,6 +117,16 @@ define(
|
||||
}
|
||||
}
|
||||
|
||||
// Update element positions when grid size changes
|
||||
function updateElementPositions(layoutGrid) {
|
||||
// Update grid size from model
|
||||
gridSize = layoutGrid || DEFAULT_GRID_SIZE;
|
||||
|
||||
elementProxies.forEach(function (elementProxy) {
|
||||
elementProxy.style = convertPosition(elementProxy);
|
||||
});
|
||||
}
|
||||
|
||||
// Update telemetry values based on new data available
|
||||
function updateValues() {
|
||||
if (subscription) {
|
||||
@@ -256,6 +240,11 @@ define(
|
||||
|
||||
// Position a panel after a drop event
|
||||
function handleDrop(e, id, position) {
|
||||
// Don't handle this event if it has already been handled
|
||||
if (e.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
// Store the position of this element.
|
||||
addElement({
|
||||
type: "fixed.telemetry",
|
||||
@@ -284,6 +273,9 @@ define(
|
||||
// Position panes when the model field changes
|
||||
$scope.$watch("model.composition", updateComposition);
|
||||
|
||||
// Detect changes to grid size
|
||||
$scope.$watch("model.layoutGrid", updateElementPositions);
|
||||
|
||||
// Subscribe to telemetry when an object is available
|
||||
$scope.$watch("domainObject", subscribe);
|
||||
|
||||
@@ -293,19 +285,7 @@ define(
|
||||
// Position panes where they are dropped
|
||||
$scope.$on("mctDrop", handleDrop);
|
||||
|
||||
// Initialize styles (position etc.) for cells
|
||||
refreshCellStyles();
|
||||
|
||||
return {
|
||||
/**
|
||||
* Get styles for all background cells, as will populate the
|
||||
* ng-style tag.
|
||||
* @memberof FixedController#
|
||||
* @returns {Array} cell styles
|
||||
*/
|
||||
getCellStyles: function () {
|
||||
return cellStyles;
|
||||
},
|
||||
/**
|
||||
* Get the size of the grid, in pixels. The returned array
|
||||
* is in the form `[x, y]`.
|
||||
@@ -314,19 +294,6 @@ define(
|
||||
getGridSize: function () {
|
||||
return gridSize;
|
||||
},
|
||||
/**
|
||||
* Set the size of the viewable fixed position area.
|
||||
* @memberof FixedController#
|
||||
* @param bounds the width/height, as reported by mct-resize
|
||||
*/
|
||||
setBounds: function (bounds) {
|
||||
var w = Math.ceil(bounds.width / gridSize[0]),
|
||||
h = Math.ceil(bounds.height / gridSize[1]);
|
||||
if (w !== gridExtent[0] || h !== gridExtent[1]) {
|
||||
gridExtent = [w, h];
|
||||
refreshCellStyles();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Get an array of elements in this panel; these are
|
||||
* decorated proxies for both selection and display.
|
||||
|
||||
52
platform/features/layout/src/LayoutCompositionPolicy.js
Normal file
52
platform/features/layout/src/LayoutCompositionPolicy.js
Normal file
@@ -0,0 +1,52 @@
|
||||
/*****************************************************************************
|
||||
* 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";
|
||||
|
||||
/**
|
||||
* Defines composition policy for Display Layout objects.
|
||||
* They cannot contain folders.
|
||||
*/
|
||||
function LayoutCompositionPolicy() {
|
||||
return {
|
||||
/**
|
||||
* Is the type identified by the candidate allowed to
|
||||
* contain the type described by the context?
|
||||
*/
|
||||
allow: function (candidate, context) {
|
||||
var isFolderInLayout =
|
||||
candidate &&
|
||||
context &&
|
||||
candidate.instanceOf('layout') &&
|
||||
context.instanceOf('folder');
|
||||
return !isFolderInLayout;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return LayoutCompositionPolicy;
|
||||
}
|
||||
);
|
||||
@@ -109,6 +109,9 @@ define(
|
||||
|
||||
// Position a panel after a drop event
|
||||
function handleDrop(e, id, position) {
|
||||
if (e.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
// Ensure that configuration field is populated
|
||||
$scope.configuration = $scope.configuration || {};
|
||||
// Make sure there is a "panels" field in the
|
||||
@@ -129,6 +132,10 @@ define(
|
||||
}
|
||||
// Populate template-facing position for this id
|
||||
populatePosition(id);
|
||||
// Layout may contain embedded views which will
|
||||
// listen for drops, so call preventDefault() so
|
||||
// that they can recognize that this event is handled.
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
// Position panes when the model field changes
|
||||
@@ -220,4 +227,4 @@ define(
|
||||
|
||||
return LayoutController;
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
@@ -34,6 +34,7 @@ define(
|
||||
mockFormatter,
|
||||
mockDomainObject,
|
||||
mockSubscription,
|
||||
mockEvent,
|
||||
testGrid,
|
||||
testModel,
|
||||
testValues,
|
||||
@@ -98,6 +99,10 @@ define(
|
||||
'subscription',
|
||||
[ 'unsubscribe', 'getTelemetryObjects', 'getRangeValue', 'getDatum' ]
|
||||
);
|
||||
mockEvent = jasmine.createSpyObj(
|
||||
'event',
|
||||
[ 'preventDefault' ]
|
||||
);
|
||||
|
||||
testGrid = [ 123, 456 ];
|
||||
testModel = {
|
||||
@@ -137,11 +142,6 @@ define(
|
||||
);
|
||||
});
|
||||
|
||||
it("provides styles for cells", function () {
|
||||
expect(controller.getCellStyles())
|
||||
.toEqual(jasmine.any(Array));
|
||||
});
|
||||
|
||||
it("subscribes when a domain object is available", function () {
|
||||
mockScope.domainObject = mockDomainObject;
|
||||
findWatch("domainObject")(mockDomainObject);
|
||||
@@ -266,25 +266,19 @@ define(
|
||||
expect(elements[2].value).toEqual("Formatted 31.42");
|
||||
});
|
||||
|
||||
it("adds grid cells to fill boundaries", function () {
|
||||
var s1 = {
|
||||
width: testGrid[0] * 8,
|
||||
height: testGrid[1] * 4
|
||||
},
|
||||
s2 = {
|
||||
width: testGrid[0] * 10,
|
||||
height: testGrid[1] * 6
|
||||
};
|
||||
it("updates elements styles when grid size changes", function () {
|
||||
var originalLeft;
|
||||
|
||||
mockScope.domainObject = mockDomainObject;
|
||||
mockScope.model = testModel;
|
||||
findWatch("domainObject")(mockDomainObject);
|
||||
findWatch("model.modified")(1);
|
||||
findWatch("model.composition")(mockScope.model.composition);
|
||||
|
||||
// Set first bounds
|
||||
controller.setBounds(s1);
|
||||
expect(controller.getCellStyles().length).toEqual(32); // 8 * 4
|
||||
// Set new bounds
|
||||
controller.setBounds(s2);
|
||||
expect(controller.getCellStyles().length).toEqual(60); // 10 * 6
|
||||
findWatch("model.layoutGrid")([10, 10]);
|
||||
originalLeft = controller.getElements()[0].style.left;
|
||||
findWatch("model.layoutGrid")([20, 20]);
|
||||
expect(controller.getElements()[0].style.left)
|
||||
.not.toEqual(originalLeft);
|
||||
});
|
||||
|
||||
it("listens for drop events", function () {
|
||||
@@ -302,7 +296,7 @@ define(
|
||||
// Notify that a drop occurred
|
||||
testModel.composition.push('d');
|
||||
findOn('mctDrop')(
|
||||
{},
|
||||
mockEvent,
|
||||
'd',
|
||||
{ x: 300, y: 100 }
|
||||
);
|
||||
@@ -310,12 +304,31 @@ define(
|
||||
// Should have added an element
|
||||
expect(testConfiguration.elements.length).toEqual(4);
|
||||
|
||||
// ...and prevented default...
|
||||
expect(mockEvent.preventDefault).toHaveBeenCalled();
|
||||
|
||||
// Should have triggered commit (provided by
|
||||
// EditRepresenter) with some message.
|
||||
expect(mockScope.commit)
|
||||
.toHaveBeenCalledWith(jasmine.any(String));
|
||||
});
|
||||
|
||||
it("ignores drops when default has been prevented", function () {
|
||||
// Avoids redundant drop-handling, WTD-1233
|
||||
mockEvent.defaultPrevented = true;
|
||||
|
||||
// Notify that a drop occurred
|
||||
testModel.composition.push('d');
|
||||
findOn('mctDrop')(
|
||||
mockEvent,
|
||||
'd',
|
||||
{ x: 300, y: 100 }
|
||||
);
|
||||
|
||||
// Should NOT have added an element
|
||||
expect(testConfiguration.elements.length).toEqual(3);
|
||||
});
|
||||
|
||||
it("unsubscribes when destroyed", function () {
|
||||
// Make an object available
|
||||
findWatch('domainObject')(mockDomainObject);
|
||||
@@ -328,6 +341,7 @@ define(
|
||||
});
|
||||
|
||||
it("exposes its grid size", function () {
|
||||
findWatch('model.layoutGrid')(testGrid);
|
||||
// Template needs to be able to pass this into line
|
||||
// elements to size SVGs appropriately
|
||||
expect(controller.getGridSize()).toEqual(testGrid);
|
||||
|
||||
71
platform/features/layout/test/LayoutCompositionPolicySpec.js
Normal file
71
platform/features/layout/test/LayoutCompositionPolicySpec.js
Normal file
@@ -0,0 +1,71 @@
|
||||
/*****************************************************************************
|
||||
* 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/LayoutCompositionPolicy"],
|
||||
function (LayoutCompositionPolicy) {
|
||||
"use strict";
|
||||
describe("Layout's composition policy", function () {
|
||||
var mockCandidate,
|
||||
mockContext,
|
||||
candidateType,
|
||||
contextType,
|
||||
policy;
|
||||
|
||||
beforeEach(function () {
|
||||
mockCandidate =
|
||||
jasmine.createSpyObj('candidateType', ['instanceOf']);
|
||||
mockContext =
|
||||
jasmine.createSpyObj('contextType', ['instanceOf']);
|
||||
|
||||
mockCandidate.instanceOf.andCallFake(function (t) {
|
||||
return t === candidateType;
|
||||
});
|
||||
mockContext.instanceOf.andCallFake(function (t) {
|
||||
return t === contextType;
|
||||
});
|
||||
|
||||
policy = new LayoutCompositionPolicy();
|
||||
});
|
||||
|
||||
it("disallows folders in layouts", function () {
|
||||
candidateType = 'layout';
|
||||
contextType = 'folder';
|
||||
expect(policy.allow(mockCandidate, mockContext)).toBe(false);
|
||||
});
|
||||
|
||||
it("does not disallow folders elsewhere", function () {
|
||||
candidateType = 'nonlayout';
|
||||
contextType = 'folder';
|
||||
expect(policy.allow(mockCandidate, mockContext)).toBe(true);
|
||||
});
|
||||
|
||||
it("allows things other than folders in layouts", function () {
|
||||
candidateType = 'layout';
|
||||
contextType = 'nonfolder';
|
||||
expect(policy.allow(mockCandidate, mockContext)).toBe(true);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -28,6 +28,7 @@ define(
|
||||
|
||||
describe("The Layout controller", function () {
|
||||
var mockScope,
|
||||
mockEvent,
|
||||
testModel,
|
||||
testConfiguration,
|
||||
controller;
|
||||
@@ -37,6 +38,10 @@ define(
|
||||
"$scope",
|
||||
[ "$watch", "$on", "commit" ]
|
||||
);
|
||||
mockEvent = jasmine.createSpyObj(
|
||||
'event',
|
||||
[ 'preventDefault' ]
|
||||
);
|
||||
|
||||
testModel = {
|
||||
composition: [ "a", "b", "c" ]
|
||||
@@ -144,17 +149,32 @@ define(
|
||||
// Notify that a drop occurred
|
||||
testModel.composition.push('d');
|
||||
mockScope.$on.mostRecentCall.args[1](
|
||||
{},
|
||||
mockEvent,
|
||||
'd',
|
||||
{ x: 300, y: 100 }
|
||||
);
|
||||
expect(testConfiguration.panels.d).toBeDefined();
|
||||
expect(mockEvent.preventDefault).toHaveBeenCalled();
|
||||
|
||||
// Should have triggered commit (provided by
|
||||
// EditRepresenter) with some message.
|
||||
expect(mockScope.commit)
|
||||
.toHaveBeenCalledWith(jasmine.any(String));
|
||||
});
|
||||
|
||||
it("ignores drops when default has been prevented", function () {
|
||||
// Avoids redundant drop-handling, WTD-1233
|
||||
mockEvent.defaultPrevented = true;
|
||||
|
||||
// Notify that a drop occurred
|
||||
testModel.composition.push('d');
|
||||
mockScope.$on.mostRecentCall.args[1](
|
||||
mockEvent,
|
||||
'd',
|
||||
{ x: 300, y: 100 }
|
||||
);
|
||||
expect(testConfiguration.panels.d).not.toBeDefined();
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"FixedController",
|
||||
"FixedDragHandle",
|
||||
"FixedProxy",
|
||||
"LayoutCompositionPolicy",
|
||||
"LayoutController",
|
||||
"LayoutDrag",
|
||||
"elements/AccessorMutator",
|
||||
@@ -13,4 +14,4 @@
|
||||
"elements/ResizeHandle",
|
||||
"elements/TelemetryProxy",
|
||||
"elements/TextProxy"
|
||||
]
|
||||
]
|
||||
|
||||
@@ -23,7 +23,21 @@
|
||||
{
|
||||
"key": "PlotController",
|
||||
"implementation": "PlotController.js",
|
||||
"depends": [ "$scope", "telemetryFormatter", "telemetryHandler", "throttle" ]
|
||||
"depends": [
|
||||
"$scope",
|
||||
"telemetryFormatter",
|
||||
"telemetryHandler",
|
||||
"throttle",
|
||||
"PLOT_FIXED_DURATION"
|
||||
]
|
||||
}
|
||||
],
|
||||
"constants": [
|
||||
{
|
||||
"key": "PLOT_FIXED_DURATION",
|
||||
"value": 900000,
|
||||
"priority": "fallback",
|
||||
"comment": "Fifteen minutes."
|
||||
}
|
||||
],
|
||||
"policies": [
|
||||
|
||||
@@ -93,8 +93,9 @@
|
||||
|
||||
<mct-chart draw="subplot.getDrawingObject()"
|
||||
ng-mousemove="subplot.hover($event)"
|
||||
ng-mousedown="subplot.startMarquee($event)"
|
||||
ng-mouseup="subplot.endMarquee($event); plot.update()">
|
||||
mct-drag="subplot.continueDrag($event)"
|
||||
mct-drag-down="subplot.startDrag($event)"
|
||||
mct-drag-up="subplot.endDrag($event); plot.update()">
|
||||
</mct-chart>
|
||||
|
||||
<!-- TODO: Move into correct position; make part of group; infer from set of actions -->
|
||||
|
||||
@@ -52,7 +52,13 @@ define(
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
function PlotController($scope, telemetryFormatter, telemetryHandler, throttle) {
|
||||
function PlotController(
|
||||
$scope,
|
||||
telemetryFormatter,
|
||||
telemetryHandler,
|
||||
throttle,
|
||||
PLOT_FIXED_DURATION
|
||||
) {
|
||||
var subPlotFactory = new SubPlotFactory(telemetryFormatter),
|
||||
modeOptions = new PlotModeOptions([], subPlotFactory),
|
||||
subplots = [],
|
||||
@@ -101,7 +107,8 @@ define(
|
||||
updater = new PlotUpdater(
|
||||
handle,
|
||||
($scope.axes[0].active || {}).key,
|
||||
($scope.axes[1].active || {}).key
|
||||
($scope.axes[1].active || {}).key,
|
||||
PLOT_FIXED_DURATION
|
||||
);
|
||||
limitTracker = new PlotLimitTracker(
|
||||
handle,
|
||||
@@ -170,7 +177,7 @@ define(
|
||||
|
||||
// Unsubscribe when the plot is destroyed
|
||||
$scope.$on("$destroy", releaseSubscription);
|
||||
|
||||
|
||||
// Create a throttled update function
|
||||
scheduleUpdate = throttle(function () {
|
||||
modeOptions.getModeHandler().getSubPlots()
|
||||
@@ -266,4 +273,4 @@ define(
|
||||
|
||||
return PlotController;
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
@@ -56,6 +56,9 @@ define(
|
||||
domainOffset,
|
||||
mousePosition,
|
||||
marqueeStart,
|
||||
panStart,
|
||||
panStartBounds,
|
||||
subPlotBounds,
|
||||
hoverCoordinates,
|
||||
isHovering = false;
|
||||
|
||||
@@ -88,8 +91,7 @@ define(
|
||||
// pixel coordinates in the canvas area) from a mouse
|
||||
// event object.
|
||||
function toMousePosition($event) {
|
||||
var target = $event.target,
|
||||
bounds = target.getBoundingClientRect();
|
||||
var bounds = subPlotBounds;
|
||||
|
||||
return {
|
||||
x: $event.clientX - bounds.left,
|
||||
@@ -155,6 +157,25 @@ define(
|
||||
tickGenerator.generateRangeTicks(RANGE_TICKS);
|
||||
}
|
||||
|
||||
function updatePan() {
|
||||
var start, current, delta, nextOrigin;
|
||||
|
||||
// Clear the previous panning pan-zoom state
|
||||
panZoomStack.popPanZoom();
|
||||
|
||||
// Calculate what the new resulting pan-zoom should be
|
||||
start = mousePositionToDomainRange(panStart);
|
||||
current = mousePositionToDomainRange(mousePosition);
|
||||
delta = [ current[0] - start[0], current[1] - start[1] ];
|
||||
nextOrigin = [
|
||||
panStartBounds.origin[0] - delta[0],
|
||||
panStartBounds.origin[1] - delta[1]
|
||||
];
|
||||
|
||||
// ...and push a new one at the current mouse position
|
||||
panZoomStack.pushPanZoom(nextOrigin, panStartBounds.dimensions);
|
||||
}
|
||||
|
||||
|
||||
// Perform a marquee zoom.
|
||||
function marqueeZoom(start, end) {
|
||||
@@ -241,31 +262,77 @@ define(
|
||||
*/
|
||||
hover: function ($event) {
|
||||
isHovering = true;
|
||||
subPlotBounds = $event.target.getBoundingClientRect();
|
||||
mousePosition = toMousePosition($event);
|
||||
updateHoverCoordinates();
|
||||
if (marqueeStart) {
|
||||
updateMarqueeBox();
|
||||
}
|
||||
if (panStart) {
|
||||
updatePan();
|
||||
updateDrawingBounds();
|
||||
updateTicks();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Continue a previously-start pan or zoom gesture.
|
||||
* @param $event the mouse event
|
||||
*/
|
||||
continueDrag: function ($event) {
|
||||
mousePosition = toMousePosition($event);
|
||||
if (marqueeStart) {
|
||||
updateMarqueeBox();
|
||||
}
|
||||
if (panStart) {
|
||||
updatePan();
|
||||
updateDrawingBounds();
|
||||
updateTicks();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Initiate a marquee zoom action.
|
||||
* @param $event the mouse event
|
||||
*/
|
||||
startMarquee: function ($event) {
|
||||
mousePosition = marqueeStart = toMousePosition($event);
|
||||
updateMarqueeBox();
|
||||
startDrag: function ($event) {
|
||||
subPlotBounds = $event.target.getBoundingClientRect();
|
||||
mousePosition = toMousePosition($event);
|
||||
// Treat any modifier key as a pan
|
||||
if ($event.altKey || $event.shiftKey || $event.ctrlKey) {
|
||||
// Start panning
|
||||
panStart = mousePosition;
|
||||
panStartBounds = panZoomStack.getPanZoom();
|
||||
// We're starting a pan, so add this back as a
|
||||
// state on the stack; it will get replaced
|
||||
// during the pan.
|
||||
panZoomStack.pushPanZoom(
|
||||
panStartBounds.origin,
|
||||
panStartBounds.dimensions
|
||||
);
|
||||
$event.preventDefault();
|
||||
} else {
|
||||
// Start marquee zooming
|
||||
marqueeStart = mousePosition;
|
||||
updateMarqueeBox();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Complete a marquee zoom action.
|
||||
* @param $event the mouse event
|
||||
*/
|
||||
endMarquee: function ($event) {
|
||||
endDrag: function ($event) {
|
||||
mousePosition = toMousePosition($event);
|
||||
subPlotBounds = undefined;
|
||||
if (marqueeStart) {
|
||||
marqueeZoom(marqueeStart, mousePosition);
|
||||
marqueeStart = undefined;
|
||||
updateMarqueeBox();
|
||||
updateDrawingBounds();
|
||||
updateTicks();
|
||||
}
|
||||
if (panStart) {
|
||||
// End panning
|
||||
panStart = undefined;
|
||||
panStartBounds = undefined;
|
||||
}
|
||||
},
|
||||
/**
|
||||
@@ -311,4 +378,4 @@ define(
|
||||
return SubPlot;
|
||||
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
@@ -43,9 +43,9 @@ define(
|
||||
var mid = Math.floor((min + max) / 2),
|
||||
found = buffer[mid * 2];
|
||||
|
||||
// Collisions are not wanted
|
||||
// On collisions, insert at same index
|
||||
if (found === value) {
|
||||
return -1;
|
||||
return mid;
|
||||
}
|
||||
|
||||
// Otherwise, if we're down to a single index,
|
||||
@@ -258,4 +258,4 @@ define(
|
||||
|
||||
return PlotLineBuffer;
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
@@ -42,14 +42,17 @@ define(
|
||||
* @param {TelemetryHandle} handle the handle to telemetry access
|
||||
* @param {string} domain the key to use when looking up domain values
|
||||
* @param {string} range the key to use when looking up range values
|
||||
* @param {number} maxDuration maximum plot duration to display
|
||||
* @param {number} maxPoints maximum number of points to display
|
||||
*/
|
||||
function PlotUpdater(handle, domain, range, maxPoints) {
|
||||
function PlotUpdater(handle, domain, range, fixedDuration, maxPoints) {
|
||||
var ids = [],
|
||||
lines = {},
|
||||
dimensions = [0, 0],
|
||||
origin = [0, 0],
|
||||
domainExtrema,
|
||||
rangeExtrema,
|
||||
buffers = {},
|
||||
bufferArray = [],
|
||||
domainOffset;
|
||||
|
||||
@@ -61,11 +64,10 @@ define(
|
||||
// Check if this set of ids matches the current set of ids
|
||||
// (used to detect if line preparation can be skipped)
|
||||
function idsMatch(nextIds) {
|
||||
return nextIds.map(function (id, index) {
|
||||
return ids[index] === id;
|
||||
}).reduce(function (a, b) {
|
||||
return a && b;
|
||||
}, true);
|
||||
return ids.length === nextIds.length &&
|
||||
nextIds.every(function (id, index) {
|
||||
return ids[index] === id;
|
||||
});
|
||||
}
|
||||
|
||||
// Prepare plot lines for this group of telemetry objects
|
||||
@@ -74,7 +76,7 @@ define(
|
||||
next = {};
|
||||
|
||||
// Detect if we already have everything we need prepared
|
||||
if (ids.length === nextIds.length && idsMatch(nextIds)) {
|
||||
if (idsMatch(nextIds)) {
|
||||
// Nothing to prepare, move on
|
||||
return;
|
||||
}
|
||||
@@ -88,13 +90,13 @@ define(
|
||||
|
||||
// Create buffers for these objects
|
||||
bufferArray = ids.map(function (id) {
|
||||
var buffer = new PlotLineBuffer(
|
||||
domainOffset,
|
||||
INITIAL_SIZE,
|
||||
maxPoints
|
||||
);
|
||||
next[id] = lines[id] || new PlotLine(buffer);
|
||||
return buffer;
|
||||
buffers[id] = buffers[id] || new PlotLineBuffer(
|
||||
domainOffset,
|
||||
INITIAL_SIZE,
|
||||
maxPoints
|
||||
);
|
||||
next[id] = lines[id] || new PlotLine(buffers[id]);
|
||||
return buffers[id];
|
||||
});
|
||||
}
|
||||
|
||||
@@ -107,6 +109,7 @@ define(
|
||||
lines = next;
|
||||
}
|
||||
|
||||
|
||||
// Initialize the domain offset, based on these observed values
|
||||
function initializeDomainOffset(values) {
|
||||
domainOffset =
|
||||
@@ -133,7 +136,7 @@ define(
|
||||
}
|
||||
|
||||
// Update dimensions and origin based on extrema of plots
|
||||
function updateExtrema() {
|
||||
function updateBounds() {
|
||||
if (bufferArray.length > 0) {
|
||||
domainExtrema = bufferArray.map(function (lineBuffer) {
|
||||
return lineBuffer.getDomainExtrema();
|
||||
@@ -143,10 +146,40 @@ define(
|
||||
return lineBuffer.getRangeExtrema();
|
||||
}).reduce(reduceExtrema);
|
||||
|
||||
// Calculate best-fit dimensions
|
||||
dimensions = (rangeExtrema[0] === rangeExtrema[1]) ?
|
||||
[dimensionsOf(domainExtrema), 2.0 ] :
|
||||
[dimensionsOf(domainExtrema), dimensionsOf(rangeExtrema)];
|
||||
origin = [originOf(domainExtrema), originOf(rangeExtrema)];
|
||||
|
||||
// ...then enforce a fixed duration if needed
|
||||
if (fixedDuration !== undefined) {
|
||||
origin[0] = origin[0] + dimensions[0] - fixedDuration;
|
||||
dimensions[0] = fixedDuration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Enforce maximum duration on all plot lines; not that
|
||||
// domain extrema must be up-to-date for this to behave correctly.
|
||||
function enforceDuration() {
|
||||
var cutoff;
|
||||
|
||||
function enforceDurationForBuffer(plotLineBuffer) {
|
||||
var index = plotLineBuffer.findInsertionIndex(cutoff);
|
||||
if (index > 0) {
|
||||
// Leave one point untrimmed, such that line will
|
||||
// continue off left edge of visible plot area.
|
||||
plotLineBuffer.trim(index - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (fixedDuration !== undefined &&
|
||||
domainExtrema !== undefined &&
|
||||
(domainExtrema[1] - domainExtrema[0] > fixedDuration)) {
|
||||
cutoff = domainExtrema[1] - fixedDuration;
|
||||
bufferArray.forEach(enforceDurationForBuffer);
|
||||
updateBounds(); // Extrema may have changed now
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,8 +213,8 @@ define(
|
||||
// Add new data
|
||||
objects.forEach(addPointFor);
|
||||
|
||||
// Finally, update extrema
|
||||
updateExtrema();
|
||||
// Then, update extrema
|
||||
updateBounds();
|
||||
}
|
||||
|
||||
// Add historical data for this domain object
|
||||
@@ -213,12 +246,12 @@ define(
|
||||
line.addSeries(series, domain, range);
|
||||
}
|
||||
|
||||
// Finally, update extrema
|
||||
updateExtrema();
|
||||
// Update extrema
|
||||
updateBounds();
|
||||
}
|
||||
|
||||
// Use a default MAX_POINTS if none is provided
|
||||
maxPoints = maxPoints || MAX_POINTS;
|
||||
maxPoints = maxPoints !== undefined ? maxPoints : MAX_POINTS;
|
||||
|
||||
// Initially prepare state for these objects.
|
||||
// Note that this may be an empty array at this time,
|
||||
@@ -290,4 +323,4 @@ define(
|
||||
return PlotUpdater;
|
||||
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
@@ -127,7 +127,7 @@ define(
|
||||
|
||||
// Simulate a marquee zoom. Note that the mockElement
|
||||
// is 100 by 100 and starts at 10,20
|
||||
subplot.startMarquee({
|
||||
subplot.startDrag({
|
||||
target: mockElement,
|
||||
clientX: 60,
|
||||
clientY: 45
|
||||
@@ -137,7 +137,7 @@ define(
|
||||
clientX: 75,
|
||||
clientY: 85
|
||||
});
|
||||
subplot.endMarquee({
|
||||
subplot.endDrag({
|
||||
target: mockElement,
|
||||
clientX: 80,
|
||||
clientY: 95
|
||||
@@ -162,7 +162,7 @@ define(
|
||||
|
||||
// Simulate a marquee zoom. Note that the mockElement
|
||||
// is 100 by 100 and starts at 10,20
|
||||
subplot.startMarquee({
|
||||
subplot.startDrag({
|
||||
target: mockElement,
|
||||
clientX: 60,
|
||||
clientY: 45
|
||||
@@ -172,7 +172,7 @@ define(
|
||||
clientX: 75,
|
||||
clientY: 85
|
||||
});
|
||||
subplot.endMarquee({
|
||||
subplot.endDrag({
|
||||
target: mockElement,
|
||||
clientX: 60,
|
||||
clientY: 45
|
||||
@@ -198,4 +198,4 @@ define(
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
@@ -83,9 +83,6 @@ define(
|
||||
expect(buffer.findInsertionIndex(10)).toEqual(4);
|
||||
expect(buffer.findInsertionIndex(14.5)).toEqual(5);
|
||||
expect(buffer.findInsertionIndex(20)).toEqual(6);
|
||||
|
||||
// 9 is already in there, disallow insertion
|
||||
expect(buffer.findInsertionIndex(9)).toEqual(-1);
|
||||
});
|
||||
|
||||
it("allows insertion in the middle", function () {
|
||||
@@ -169,4 +166,4 @@ define(
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
37
platform/features/rtevents/bundle.json
Normal file
37
platform/features/rtevents/bundle.json
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"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.",
|
||||
"templateUrl": "templates/rtmessages.html",
|
||||
"needs": [ "telemetry" ],
|
||||
"delegation": true
|
||||
}
|
||||
],
|
||||
"controllers": [
|
||||
{
|
||||
"key": "RTEventListController",
|
||||
"implementation": "RTEventListController.js",
|
||||
"depends": [ "$scope", "telemetryHandler", "telemetryFormatter" ]
|
||||
}
|
||||
],
|
||||
"directives": [
|
||||
{
|
||||
"key": "mctRtDataTable",
|
||||
"implementation": "directives/MCTRTDataTable.js",
|
||||
"depends": [ "$window" ]
|
||||
}
|
||||
],
|
||||
"policies": [
|
||||
{
|
||||
"category": "view",
|
||||
"implementation": "policies/RTMessagesViewPolicy.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<!--
|
||||
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>
|
||||
29
platform/features/rtevents/res/templates/rtmessages.html
Normal file
29
platform/features/rtevents/res/templates/rtmessages.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<!--
|
||||
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">
|
||||
<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>
|
||||
|
||||
|
||||
71
platform/features/rtevents/src/DomainColumn.js
Normal file
71
platform/features/rtevents/src/DomainColumn.js
Normal file
@@ -0,0 +1,71 @@
|
||||
/*****************************************************************************
|
||||
* 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,moment*/
|
||||
|
||||
/**
|
||||
* Module defining DomainColumn. Created by vwoeltje on 11/18/14.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* A column which will report telemetry domain values
|
||||
* (typically, timestamps.) Used by the ScrollingListController.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
getValue: function (domainObject, handle) {
|
||||
return {
|
||||
text: telemetryFormatter.formatDomainValue(
|
||||
handle.getDomainValue(domainObject)
|
||||
)
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return DomainColumn;
|
||||
}
|
||||
);
|
||||
138
platform/features/rtevents/src/RTEventListController.js
Normal file
138
platform/features/rtevents/src/RTEventListController.js
Normal file
@@ -0,0 +1,138 @@
|
||||
/*****************************************************************************
|
||||
* 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*/
|
||||
|
||||
/**
|
||||
* Module defining RTEventListController.
|
||||
* Created by shale on 06/25/2014. Based on RT Scrolling lists.
|
||||
*/
|
||||
define(
|
||||
["./DomainColumn", "./RangeColumn"],
|
||||
function (DomainColumn, RangeColumn) {
|
||||
"use strict";
|
||||
|
||||
var ROW_COUNT = 100;
|
||||
|
||||
/**
|
||||
* The RTEventListController is responsible for populating
|
||||
* the contents of the messages view.
|
||||
* @constructor
|
||||
*/
|
||||
function RTEventListController($scope, telemetryHandler, telemetryFormatter) {
|
||||
var handle,
|
||||
lastUpdated = {},
|
||||
lastIds = [],
|
||||
columns = [],
|
||||
headers = [],
|
||||
rows = [];
|
||||
|
||||
function getTelemetryObjects() {
|
||||
//console.log("handle.getTelemetryObjects() ", handle.getTelemetryObjects());
|
||||
return handle ? handle.getTelemetryObjects() : [];
|
||||
}
|
||||
|
||||
function idsChanged(telemetryObjects) {
|
||||
function mismatch(id, index) {
|
||||
return id !== telemetryObjects[index].getId();
|
||||
}
|
||||
|
||||
return lastIds.length !== telemetryObjects.length ||
|
||||
lastIds.some(mismatch);
|
||||
}
|
||||
|
||||
function setupColumns(telemetryObjects) {
|
||||
var id = $scope.domainObject && $scope.domainObject.getId(),
|
||||
firstId =
|
||||
telemetryObjects[0] && telemetryObjects[0].getId();
|
||||
|
||||
columns = [];
|
||||
|
||||
columns.push(new DomainColumn(telemetryFormatter));
|
||||
columns.push(new RangeColumn());
|
||||
|
||||
headers = columns.map(function (column) {
|
||||
return column.getTitle();
|
||||
});
|
||||
}
|
||||
|
||||
function updateObjects(telemetryObjects) {
|
||||
if (idsChanged(telemetryObjects)) {
|
||||
setupColumns(telemetryObjects);
|
||||
lastIds = telemetryObjects.map(function (telemetryObject) {
|
||||
return telemetryObject.getId();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function addRow(telemetryObject) {
|
||||
var id = telemetryObject.getId(),
|
||||
domainValue = handle.getDomainValue(telemetryObject);
|
||||
if (lastUpdated[id] !== domainValue &&
|
||||
domainValue !== undefined) {
|
||||
// Instead of unshift (scrolling), use push (messages)
|
||||
rows.push(columns.map(function (column) {
|
||||
return column.getValue(telemetryObject, handle).text;
|
||||
}));
|
||||
// Remove first rows when adding past the max rows limit
|
||||
rows.splice(0, rows.length - ROW_COUNT);
|
||||
lastUpdated[id] = domainValue;
|
||||
}
|
||||
}
|
||||
|
||||
function updateValues() {
|
||||
getTelemetryObjects().forEach(addRow);
|
||||
}
|
||||
|
||||
function releaseSubscription() {
|
||||
if (handle) {
|
||||
handle.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
function makeSubscription(domainObject) {
|
||||
releaseSubscription();
|
||||
rows = [];
|
||||
handle = telemetryHandler.handle(
|
||||
domainObject,
|
||||
updateValues,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
$scope.$on("$destroy", releaseSubscription);
|
||||
|
||||
$scope.$watch("domainObject", makeSubscription);
|
||||
$scope.$watch(getTelemetryObjects, updateObjects);
|
||||
|
||||
return {
|
||||
rows: function () {
|
||||
return rows;
|
||||
},
|
||||
headers: function () {
|
||||
return headers;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return RTEventListController;
|
||||
}
|
||||
);
|
||||
68
platform/features/rtevents/src/RangeColumn.js
Normal file
68
platform/features/rtevents/src/RangeColumn.js
Normal file
@@ -0,0 +1,68 @@
|
||||
/*****************************************************************************
|
||||
* 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,moment*/
|
||||
|
||||
/**
|
||||
* Module defining DomainColumn.
|
||||
* Created by vwoeltje on 11/18/14. Modified by shale on 06/25/2015.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* A column which will report telemetry range values
|
||||
* (typically, measurements.) Used by the RTEventListController.
|
||||
*
|
||||
* @constructor
|
||||
* @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() {
|
||||
return {
|
||||
/**
|
||||
* Get the title to display in this column's header.
|
||||
* @returns {string} the title to display
|
||||
*/
|
||||
getTitle: function () {
|
||||
return "Message";
|
||||
},
|
||||
/**
|
||||
* Get the text to display inside a row under this
|
||||
* column.
|
||||
* @returns {string} the text to display
|
||||
*/
|
||||
getValue: function (domainObject, handle) {
|
||||
return {
|
||||
text: handle.getRangeValue(domainObject)
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return RangeColumn;
|
||||
}
|
||||
);
|
||||
74
platform/features/rtevents/src/directives/MCTRTDataTable.js
Normal file
74
platform/features/rtevents/src/directives/MCTRTDataTable.js
Normal file
@@ -0,0 +1,74 @@
|
||||
/*****************************************************************************
|
||||
* 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*/
|
||||
|
||||
/**
|
||||
* Module defining MCTRTDataTable. Created by shale on 06/25/2015.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
function MCTRTDataTable($window) {
|
||||
return {
|
||||
restrict: "E",
|
||||
templateUrl: "platform/features/rtevents/res/templates/mct-rt-data-table.html",
|
||||
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.$watchCollection("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 MCTRTDataTable;
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,74 @@
|
||||
/*****************************************************************************
|
||||
* 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*/
|
||||
|
||||
/**
|
||||
* Module defining MessagesViewPolicy. Created by shale on 06/24/2015.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Policy controlling when the real time Messages view should be avaliable.
|
||||
* @constructor
|
||||
*/
|
||||
function RTMessagesViewPolicy() {
|
||||
|
||||
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';
|
||||
});
|
||||
}
|
||||
return {
|
||||
/**
|
||||
* Check whether or not a given action is allowed by this
|
||||
* policy.
|
||||
* @param {Action} action the action
|
||||
* @param domainObject the domain object which will be viewed
|
||||
* @returns {boolean} true if not disallowed
|
||||
*/
|
||||
allow: function (view, domainObject) {
|
||||
// This policy only applies for the RT Messages view
|
||||
if (view.key === 'rtmessages') {
|
||||
// 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 RTMessagesViewPolicy;
|
||||
}
|
||||
);
|
||||
88
platform/features/rtevents/test/DomainColumnSpec.js
Normal file
88
platform/features/rtevents/test/DomainColumnSpec.js
Normal file
@@ -0,0 +1,88 @@
|
||||
/*****************************************************************************
|
||||
* 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,it,expect,beforeEach,waitsFor,jasmine*/
|
||||
|
||||
/**
|
||||
* RTEventSpec. Created by vwoeltje on 11/6/14. Modified by shale on 06/25/2015.
|
||||
*/
|
||||
define(
|
||||
["../src/DomainColumn"],
|
||||
function (DomainColumn) {
|
||||
"use strict";
|
||||
|
||||
var TEST_DOMAIN_VALUE = "some formatted domain value";
|
||||
|
||||
describe("A real time event list domain column", function () {
|
||||
var mockDomainObject,
|
||||
mockTelemetryHandler,
|
||||
mockHandle,
|
||||
mockFormatter,
|
||||
column;
|
||||
|
||||
beforeEach(function () {
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
"domainObject",
|
||||
["getModel", "getCapability"]
|
||||
);
|
||||
mockTelemetryHandler = jasmine.createSpyObj(
|
||||
"telemetryHandler",
|
||||
["handle"]
|
||||
);
|
||||
mockHandle = jasmine.createSpyObj(
|
||||
"handle",
|
||||
["getDomainValue", "getRangeValue"]
|
||||
);
|
||||
mockFormatter = jasmine.createSpyObj(
|
||||
"formatter",
|
||||
["formatDomainValue", "formatRangeValue"]
|
||||
);
|
||||
mockFormatter.formatDomainValue.andReturn(TEST_DOMAIN_VALUE);
|
||||
|
||||
column = new DomainColumn(mockFormatter);
|
||||
});
|
||||
|
||||
it("reports the domain column header as 'Time'", function () {
|
||||
expect(column.getTitle()).toEqual("Time");
|
||||
});
|
||||
|
||||
it("retrives data from a telemetry provider", function () {
|
||||
column.getValue(mockDomainObject, mockHandle);
|
||||
expect(mockHandle.getDomainValue).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("formats domain values as time", function () {
|
||||
mockHandle.getDomainValue.andReturn(402513731000);
|
||||
|
||||
// Should have just given the value the formatter gave
|
||||
expect(column.getValue(mockDomainObject, mockHandle).text)
|
||||
.toEqual(TEST_DOMAIN_VALUE);
|
||||
|
||||
// Make sure that service interactions were as expected
|
||||
expect(mockFormatter.formatDomainValue)
|
||||
.toHaveBeenCalledWith(402513731000);
|
||||
expect(mockFormatter.formatRangeValue)
|
||||
.not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
130
platform/features/rtevents/test/RTEventListControllerSpec.js
Normal file
130
platform/features/rtevents/test/RTEventListControllerSpec.js
Normal file
@@ -0,0 +1,130 @@
|
||||
/*****************************************************************************
|
||||
* 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,it,expect,beforeEach,waitsFor,jasmine*/
|
||||
|
||||
/**
|
||||
* RTEventSpec. Created by shale on 06/25/2015.
|
||||
*/
|
||||
define(
|
||||
["../src/RTEventListController"],
|
||||
function (RTEventListController) {
|
||||
"use strict";
|
||||
|
||||
describe("The real time event list controller", function () {
|
||||
var mockDomainObject,
|
||||
mockScope,
|
||||
mockTelemetryHandler,
|
||||
mockHandle,
|
||||
mockTelemetryFormatter,
|
||||
controller;
|
||||
|
||||
beforeEach(function () {
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
"domainObject",
|
||||
[ "getId", "getModel", "getCapability" ]
|
||||
);
|
||||
mockScope = jasmine.createSpyObj(
|
||||
"$scope",
|
||||
[ "$on", "$watch" ]
|
||||
);
|
||||
mockTelemetryHandler = jasmine.createSpyObj(
|
||||
"telemetryHandler",
|
||||
["handle"]
|
||||
);
|
||||
mockHandle = jasmine.createSpyObj(
|
||||
"handle",
|
||||
["getDomainValue", "getRangeValue", "getTelemetryObjects", "unsubscribe"]
|
||||
);
|
||||
mockTelemetryFormatter = jasmine.createSpyObj(
|
||||
"formatter",
|
||||
["formatDomainValue", "formatRangeValue"]
|
||||
);
|
||||
|
||||
controller = new RTEventListController(mockScope, mockTelemetryHandler, mockTelemetryFormatter);
|
||||
|
||||
mockHandle.getDomainValue.andReturn("domain value");
|
||||
mockHandle.getRangeValue.andReturn("range value");
|
||||
|
||||
mockTelemetryHandler.handle.andReturn(mockHandle);
|
||||
mockHandle.getTelemetryObjects.andReturn([mockDomainObject]);
|
||||
|
||||
// Subscribe to the RT telemetry
|
||||
// second argument of: $scope.$watch("domainObject", makeSubscription);
|
||||
mockScope.$watch.calls.forEach(function (c) {
|
||||
// There are two possible calls of $watch, so we need to filter
|
||||
// through the calls to get the correct kind
|
||||
if (c.args[0] === 'domainObject') {
|
||||
c.args[1]();
|
||||
}
|
||||
});
|
||||
|
||||
// callback, passed into telemetry handler
|
||||
mockTelemetryHandler.handle.mostRecentCall.args[1]();
|
||||
|
||||
// Update the telemetry objects
|
||||
// second argument of: $scope.$watch(getTelemetryObjects, updateObjects);
|
||||
mockScope.$watch.calls.forEach(function (c) {
|
||||
// There are two possible calls of $watch, so we need to filter
|
||||
// through the calls to get the correct kind
|
||||
if (c.args[0] !== 'domainObject') {
|
||||
c.args[1]([mockDomainObject]);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("provides a domain and a range column", function () {
|
||||
// Should have two columns with these headers
|
||||
expect(controller.headers()).toEqual(["Time", "Message"]);
|
||||
});
|
||||
|
||||
it("listens for telemetry data updates", function () {
|
||||
// Of the two possible $watch calls, this corresponds to
|
||||
// $scope.$watch(getTelemetryObjects, updateObjects);
|
||||
expect(mockScope.$watch).toHaveBeenCalledWith(
|
||||
jasmine.any(Function),
|
||||
jasmine.any(Function)
|
||||
);
|
||||
});
|
||||
|
||||
it("makes telemetry subscriptions", function () {
|
||||
// Of the two possible $watch calls, this corresponds to
|
||||
// $scope.$watch("domainObject", makeSubscription);
|
||||
expect(mockScope.$watch).toHaveBeenCalledWith(
|
||||
"domainObject",
|
||||
jasmine.any(Function)
|
||||
);
|
||||
});
|
||||
|
||||
it("releases telemetry subscriptions on destruction", function () {
|
||||
// Call the second argument of
|
||||
// $scope.$on("$destroy", releaseSubscription);
|
||||
mockScope.$on.mostRecentCall.args[1]();
|
||||
|
||||
expect(mockScope.$on).toHaveBeenCalledWith(
|
||||
"$destroy",
|
||||
jasmine.any(Function)
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
84
platform/features/rtevents/test/RangeColumnSpec.js
Normal file
84
platform/features/rtevents/test/RangeColumnSpec.js
Normal file
@@ -0,0 +1,84 @@
|
||||
/*****************************************************************************
|
||||
* 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,it,expect,beforeEach,waitsFor,jasmine*/
|
||||
|
||||
/**
|
||||
* RTEventSpec. Created by vwoeltje on 11/6/14. Modified by shale on 06/25/2015.
|
||||
*/
|
||||
define(
|
||||
["../src/RangeColumn"],
|
||||
function (RangeColumn) {
|
||||
"use strict";
|
||||
|
||||
var TEST_RANGE_VALUE = "some formatted range value";
|
||||
|
||||
describe("A real time event list range column", function () {
|
||||
var mockDomainObject,
|
||||
mockTelemetryHandler,
|
||||
mockHandle,
|
||||
mockFormatter,
|
||||
column;
|
||||
|
||||
beforeEach(function () {
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
"domainObject",
|
||||
["getModel", "getCapability"]
|
||||
);
|
||||
mockTelemetryHandler = jasmine.createSpyObj(
|
||||
"telemetryHandler",
|
||||
["handle"]
|
||||
);
|
||||
mockHandle = jasmine.createSpyObj(
|
||||
"handle",
|
||||
["getDomainValue", "getRangeValue"]
|
||||
);
|
||||
mockFormatter = jasmine.createSpyObj(
|
||||
"formatter",
|
||||
["formatDomainValue", "formatRangeValue"]
|
||||
);
|
||||
mockFormatter.formatRangeValue.andReturn(TEST_RANGE_VALUE);
|
||||
|
||||
column = new RangeColumn();
|
||||
});
|
||||
|
||||
it("reports a range column header as 'Message'", function () {
|
||||
expect(column.getTitle()).toEqual("Message");
|
||||
});
|
||||
|
||||
it("retrives data from a telemetry provider", function () {
|
||||
column.getValue(mockDomainObject, mockHandle);
|
||||
expect(mockHandle.getRangeValue).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not format range values", function () {
|
||||
mockHandle.getRangeValue.andReturn(123.45678);
|
||||
// Does not format range value as time
|
||||
expect(column.getValue(mockDomainObject, mockHandle).text)
|
||||
.not.toEqual(TEST_RANGE_VALUE);
|
||||
// There should be no additional formatting
|
||||
// i.e. the message string stays a string
|
||||
expect(column.getValue(mockDomainObject, mockHandle).text)
|
||||
.toEqual(123.45678);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,82 @@
|
||||
/*****************************************************************************
|
||||
* 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,it,expect,beforeEach,jasmine*/
|
||||
|
||||
/**
|
||||
* RTEventSpec. Created by shale on 06/25/2015.
|
||||
*/
|
||||
define(
|
||||
["../../src/policies/RTMessagesViewPolicy"],
|
||||
function (RTMessagesViewPolicy) {
|
||||
"use strict";
|
||||
|
||||
describe("The real time Messages view policy", function () {
|
||||
var testView,
|
||||
mockDomainObject,
|
||||
mockTelemetry,
|
||||
testMetadata,
|
||||
policy;
|
||||
|
||||
beforeEach(function () {
|
||||
testView = { key: "rtmessages" };
|
||||
testMetadata = {};
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
'domainObject',
|
||||
['getId', 'getModel', 'getCapability']
|
||||
);
|
||||
mockTelemetry = jasmine.createSpyObj(
|
||||
'telemetry',
|
||||
['getMetadata']
|
||||
);
|
||||
mockDomainObject.getCapability.andCallFake(function (c) {
|
||||
return c === 'telemetry' ? mockTelemetry : undefined;
|
||||
});
|
||||
mockTelemetry.getMetadata.andReturn(testMetadata);
|
||||
|
||||
policy = new RTMessagesViewPolicy();
|
||||
});
|
||||
|
||||
it("allows the real time messages view for domain objects with string telemetry", function () {
|
||||
testMetadata.ranges = [ { key: "foo", format: "string" } ];
|
||||
expect(policy.allow(testView, mockDomainObject)).toBeTruthy();
|
||||
});
|
||||
|
||||
it("disallows the real time messages view for domain objects without string telemetry", function () {
|
||||
testMetadata.ranges = [ { key: "foo", format: "somethingElse" } ];
|
||||
expect(policy.allow(testView, mockDomainObject)).toBeFalsy();
|
||||
});
|
||||
|
||||
it("disallows the real time messages view for domain objects without telemetry", function () {
|
||||
testMetadata.ranges = [ { key: "foo", format: "string" } ];
|
||||
mockDomainObject.getCapability.andReturn(undefined);
|
||||
expect(policy.allow(testView, mockDomainObject)).toBeFalsy();
|
||||
});
|
||||
|
||||
it("allows other views", function () {
|
||||
testView.key = "somethingElse";
|
||||
testMetadata.ranges = [ { key: "foo", format: "somethingElse" } ];
|
||||
expect(policy.allow(testView, mockDomainObject)).toBeTruthy();
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
6
platform/features/rtevents/test/suite.json
Normal file
6
platform/features/rtevents/test/suite.json
Normal file
@@ -0,0 +1,6 @@
|
||||
[
|
||||
"DomainColumn",
|
||||
"policies/RTMessagesViewPolicy",
|
||||
"RangeColumn",
|
||||
"RTEventListController"
|
||||
]
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user