Compare commits

...

46 Commits

Author SHA1 Message Date
Henry
618a6e7e8d Remove unused steps from circleci configuration. Fixes #1782 2017-10-19 15:51:26 -07:00
Andrew Henry
63a8c91f71 Merge pull request #1781 from nasa/view-destroy
[Views] Clear regions on destroy
2017-10-19 12:17:24 -07:00
Victor Woeltjen
e59020fec7 [Views] Clear regions on destroy
Clear regions when a view is destroyed. This causes a view's
destroy method to be correctly invoked, allowing views to do
cleanup. Used by NSS heatmap view for sprint Alice,
https://github.com/nasa/openmct/projects/1
2017-10-19 10:57:53 -07:00
Pete Richards
a2e424203a Merge pull request #1777 from nasa/iframe-border-1776
[Frontend] Review and integrate the death of iframe borders
2017-10-13 20:59:50 -07:00
Charles Hacskaylo
16853644cb [Frontend] Kill iframe borders dead!
Fixes #1776
2017-10-13 17:05:37 -07:00
Victor Woeltjen
2272766c57 Merge pull request #1743 from nasa/layout-issue-1731
[Layout] Deselect object after removal
2017-10-13 13:48:59 -07:00
Victor Woeltjen
1d9cdea2d4 Merge pull request #1767 from nasa/inline-edit-bug-1757
[Edit] Prevent blur to update the model after return key is pressed
2017-10-13 13:07:05 -07:00
Pegah Sarram
715219c44d [Edit] Fix the issue with currentTarget being null and HTML being added on Enter
Remove the line break that is added when the return key is pressed.

Check the current target directly.

Use textContent for inline editing instead of innerHTML, which will hoist up some HTML content implicitly created around user input for a contenteditable span.

Note that there is a removeAllRanges in addition to a blur here; see
https://stackoverflow.com/questions/4878713/how-can-i-blur-a-div-where-contenteditable-true

Fix broken tests.

Fixes #1757
2017-10-13 11:50:40 -07:00
Pegah Sarram
00dc2875bf [Layout] Deselect object after removal
If the selected object is not in the composition, deselect it.

Add tests.

Fixes #1731
2017-10-10 15:39:29 -07:00
Victor Woeltjen
8703f363b8 Merge pull request #1744 from nasa/inspector-issue-1276
Inspector issue 1276
2017-10-10 15:33:27 -07:00
Deep Tailor
26210eaa50 make reviewer requested changes 2017-10-10 14:37:25 -07:00
Deep Tailor
a4a1cb5e05 fix tests by adding listen function, and fix lint/checkstyle errors 2017-10-10 13:32:42 -07:00
Victor Woeltjen
9570f2f7a1 Merge pull request #1766 from nasa/inline-edit-1746
Allow inline-editing for editable objects only
2017-10-10 12:43:07 -07:00
Pegah Sarram
eb4ded39b3 [Edit] Allow inline-editing the name only if the object is editable
Made the contenteditable attribute conditional based on whether the object can be edited or not. If the object is not editable, the attribute is removed.

Add Tests.

Fixes #1746
2017-10-10 12:32:51 -07:00
Deep Tailor
7deb3cd025 add if statement to check is objects are not equal before reassigning metadata 2017-10-03 14:34:01 -07:00
Deep Tailor
06779e6cd9 add mutation listener to Inspector Controller 2017-10-03 13:33:09 -07:00
Charles Hacskaylo
7f43c0bf1a Add Notebook icon (#1742)
* Add Notebook icon

Fixes #1739
Added to Style Guide as well

* Add icomoon project file

Fixes #1739
2017-10-02 13:09:58 -07:00
Victor Woeltjen
bfa3bbcdc7 Merge pull request #1735 from nasa/import-export-1695
Review and integrate usage of new Import/Export glyphs
2017-09-25 16:50:11 -07:00
Victor Woeltjen
2baf3f8bb0 Merge pull request #1733 from nasa/create-menu-1729
Review and integrate super-menu fixes and enhancements
2017-09-25 16:29:54 -07:00
Charles Hacskaylo
10ac13ac5c [Front-end] Updated to use new glyphs
Fixes #1695
2017-09-25 15:22:35 -07:00
Charles Hacskaylo
138cb199bb [Front-end] Markup and CSS refinements
Fixes #1729
Internal markup and CSS now sets heights
internally - menu height will now not be smaller
than the list of menu items OR the description
area;
2017-09-25 14:59:12 -07:00
Victor Woeltjen
374c363a78 [Plot] Handle telemetry panels from plot policy (#1732)
* [Plot] Check for telemetry panels

...from plot view policy, and don't try to interrogate them
for telemetry metadata that they will not have.

Fixes #1728

* [Plot] Update test case for policy

...to provide an adapted object with expected properties

* [Plot] Add tests to very plot policy for panels

...to verify fix for #1728
2017-09-25 14:27:32 -07:00
Charles Hacskaylo
e9cb5cd639 [Front-end] Scrollbar-related color and padding
Fixes #1729
2017-09-25 12:08:59 -07:00
Charles Hacskaylo
bc7d92ee0d [Front-end] Menu tweaks
Fixes #1729
Mini super-menu and related description text
2017-09-25 12:08:04 -07:00
Charles Hacskaylo
78f49784a0 [Front-end] Tweaks
Fixes #1729
CSS and markup mods to convert
to flex from abs pos;
2017-09-25 11:10:58 -07:00
Victor Woeltjen
8754c438cc Merge pull request #1725 from nasa/legacy-telem-source-mapping
[Telemetry] Legacy adapter handles source remap
2017-09-21 11:47:07 -07:00
Pegah Sarram
1419c75503 Inline edit object names (#1700)
* Inline edit object name.

Change the title-label span to a conteneditable span to allow editing object names inline. Implement a controller to handle updaing the name. Add tests.

Fixes #1679

[Front-end] Add span contenteditable to input styling
[Front-end] Styling for contenteditable span
styling for span[contenteditable].s-status-editing in _controls.scss;
removed s-filter class;
[Front-end] min-width added to .s-inline-edit

* [Frontend] Style tweaks, cleanup and simplification

Fixes #1679

Style sanding on .s-inline-edit; added
:focus outline:0 to select in _controls.scss;

New .s-input-inline class; removed ng-class from object-header.html,
uses :focus instead; refactoring of input-related mixins;

Bring Time Conductor real-time inputs into parity

Apply .s-input-inline to TC inputs; finesse .s-input-inline selector;

Prevent nested inline inputs from editing

Fixed nested editing prevention selector

* Create an object header template for objects inside a frame.

Fix code review requests.

Fixes 1679
2017-09-21 11:16:04 -07:00
Pete Richards
ca8cad0a74 [Telemetry] Legacy adapter handles source remap
Update the Legacy Telemetry Adapter to handle source remapping
for telemetry which has it.

fixes https://github.com/nasa/openmct/issues/1724
2017-09-21 10:51:16 -07:00
Victor Woeltjen
a3a55d3b48 [Build] Modify version info injection to fix sourcemaps (#1708)
* [Build] Preserve comments instead of adding header

...to avoid disrupting sourcemaps. Fixes #1707

[Build] Remove extraneous horizontal rule from header

[Build] Remove obsolete header-handling

...as this is handled by the replace task after fix for #1707

[Build] Move version headers into start.frag

...so that UMD boilerplate does not wrap it.

[Build] Handle version info entirely in start.frag

[Build] Replace build variables in start.frag explicitly

[Build] Inject build info dynamically

[Build] Test MCT.specifyBuildInfo

[Build] Mark BUILD_CONSTANTS as global for jshint

[Build] Give names to version line items

[Build] Fix specifyBuildInfo test case

* [Build] Update fix to sourcemaps for code review feedback

https://github.com/nasa/openmct/pull/1708

[Build] Move build info registration to plugin

https://github.com/nasa/openmct/pull/1708#discussion_r138999027

[Build] Use build info plugin

...instead of specifyBuildInfo

[Build] Revert changes to MCT, per code review
2017-09-20 11:50:17 -07:00
Victor Woeltjen
e66f818996 Merge pull request #1714 from nasa/plot-telem-fixes
Plot telem fixes
2017-09-18 15:54:52 -07:00
Pete Richards
ae5ef33487 [Plot] Update policy to detect any range
Update policy to detect any range.  As a simple way to prevent
detecting messages, it will not apply when every range is a string
format.

fixes https://github.com/nasa/openmct/issues/1713
2017-09-16 09:58:58 -07:00
Pete Richards
59c5430579 [Generator] API Compatibility
The telemetry API does not pass request options for subscriptions, updated
generator provider to match this API.

fixes https://github.com/nasa/openmct/issues/1705
2017-09-16 09:37:48 -07:00
Pete Richards
6d52f094d9 Merge pull request #1703 from nasa/text-size-1496
Text size control for text and telemetry elements
2017-09-14 16:00:07 -07:00
Pegah Sarram
740db8da75 [Fixed Position] Add tests and fix checkstyle error.
Fixes #1496
2017-09-14 15:15:15 -07:00
Charles Hacskaylo
68abc15ed5 [Frontend] Fix alignment and font-size issues in tool-bar
Fixes #1496
2017-09-14 15:02:22 -07:00
Pegah Sarram
bb47feb517 [Fixed Position] Text size control for text and telemetry objects
Add a select control for text and telemetry objects to allow setting text size. Set the default size to 13px.

Fixes # 1496
2017-09-14 14:49:28 -07:00
Victor Woeltjen
469820fb0f Merge pull request #1712 from nasa/link-1710
Review and merge fixes for Hyperlinks
2017-09-14 12:15:09 -07:00
Victor Woeltjen
92dd99b26c Merge pull request #1711 from nasa/pause-button-1704
Review and merge fix for hidden Imagery controls
2017-09-14 12:13:56 -07:00
Charles Hacskaylo
9fe1923189 [Front-end] Fixes for Hyperlinks
Fixes #1710
Converted to span to confine clickable area
to text only;
Link now uses `overflow: hidden` in frame;
Normalized font-size when .s-button;
2017-09-14 11:05:05 -07:00
Charles Hacskaylo
42ddb38629 [Front-end] Cleanups to imagery in frame
Fixes #1704
Imagery now lays out better when very small
in a Layout; refactored .left and .right classes;
2017-09-14 10:37:41 -07:00
Charles Hacskaylo
fe60d7abbc [Front-end] Fix CSS targeting
Fixes #1704
Pause/play and New Tab buttons now
display properly;
2017-09-14 10:25:34 -07:00
Pete Richards
54b975f242 Merge pull request #1699 from nasa/imagery-issue-1676
Imagery issue #1676
2017-09-12 11:28:40 -07:00
Deep Tailor
7f75e089e8 remove workaround for Imagery Thumbnail resizing from MCTSplitPane and add box sizing to thumbs wrapper to fix phantom resizing 2017-09-11 16:35:14 -07:00
Charles Hacskaylo
8e8c66280f Fix for Issue #1676
Add history imagery under large imagery view.
Allow users to click on history imagery thumbs to set main image and pause the imagery view.
Allow users to unpause and continue imagery stream.
Users can adjust the height of the imagery panes, and the user selected height is persisted.
2017-09-11 12:51:04 -07:00
Pete Richards
d3d874e209 Merge pull request #1702 from nasa/glyphs-update-import-export
[Glyphs] Add import and export icons
2017-09-11 12:01:04 -07:00
Charles Hacskaylo
ce561e1598 [Glyphs] Add import and export icons
For #1695
2017-09-11 11:41:19 -07:00
71 changed files with 1249 additions and 496 deletions

View File

@@ -4,12 +4,6 @@ deployment:
commands:
- npm install canvas nomnoml
- ./build-docs.sh
- git fetch --unshallow
- git push git@heroku.com:openmctweb-demo.git $CIRCLE_SHA1:refs/heads/master
openmct-demo:
branch: live_demo
heroku:
appname: openmct-demo
openmctweb-staging-deux:
branch: mobile
heroku:

View File

@@ -78,8 +78,8 @@ define([
return this.workerInterface.request(workerRequest);
};
GeneratorProvider.prototype.subscribe = function (domainObject, callback, request) {
var workerRequest = this.makeWorkerRequest(domainObject, request);
GeneratorProvider.prototype.subscribe = function (domainObject, callback) {
var workerRequest = this.makeWorkerRequest(domainObject, {});
return this.workerInterface.subscribe(workerRequest, callback);
};

View File

@@ -127,7 +127,8 @@
{ 'meaning': 'Timer object', 'cssClass': 'icon-timer', 'cssContent': 'e1127', 'htmlEntity': '&#xe1127' },
{ 'meaning': 'Data Topic', 'cssClass': 'icon-topic', 'cssContent': 'e1128', 'htmlEntity': '&#xe1128' },
{ 'meaning': 'Fixed Position object', 'cssClass': 'icon-box-with-dashed-lines', 'cssContent': 'e1129', 'htmlEntity': '&#xe1129' },
{ 'meaning': 'Summary Widget', 'cssClass': 'icon-summary-widget', 'cssContent': 'e1130', 'htmlEntity': '&#xe1130' }
{ 'meaning': 'Summary Widget', 'cssClass': 'icon-summary-widget', 'cssContent': 'e1130', 'htmlEntity': '&#xe1130' },
{ 'meaning': 'Notebook object', 'cssClass': 'icon-notebook', 'cssContent': 'e1131', 'htmlEntity': '&#xe1131' }
];
"></div>

View File

@@ -46,9 +46,22 @@ var gulp = require('gulp'),
name: 'bower_components/almond/almond.js',
include: paths.main.replace('.js', ''),
wrap: {
startFile: "src/start.frag",
start: (function () {
var buildVariables = {
version: project.version,
timestamp: moment.utc(Date.now()).format(),
revision: fs.existsSync('.git') ? git.long() : 'Unknown',
branch: fs.existsSync('.git') ? git.branch() : 'Unknown'
};
return fs.readFileSync("src/start.frag", 'utf-8')
.replace(/@@(\w+)/g, function (match, key) {
return buildVariables[key];
});;
}()),
endFile: "src/end.frag"
},
optimize: 'uglify2',
uglify2: { output: { comments: /@preserve/ } },
mainConfigFile: paths.main,
wrapShim: true
},
@@ -58,14 +71,6 @@ var gulp = require('gulp'),
},
sass: {
sourceComments: true
},
replace: {
variables: {
version: project.version,
timestamp: moment.utc(Date.now()).format(),
revision: fs.existsSync('.git') ? git.long() : 'Unknown',
branch: fs.existsSync('.git') ? git.branch() : 'Unknown'
}
}
};
@@ -76,16 +81,11 @@ if (process.env.NODE_ENV === 'development') {
gulp.task('scripts', function () {
var requirejsOptimize = require('gulp-requirejs-optimize');
var replace = require('gulp-replace-task');
var header = require('gulp-header');
var comment = fs.readFileSync('src/about.frag');
return gulp.src(paths.main)
.pipe(sourcemaps.init())
.pipe(requirejsOptimize(options.requirejsOptimize))
.pipe(sourcemaps.write('.'))
.pipe(replace(options.replace))
.pipe(header(comment, options.replace.variables))
.pipe(gulp.dest(paths.dist));
});

View File

@@ -19,7 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global requirejs*/
/*global requirejs,BUILD_CONSTANTS*/
requirejs.config({
"paths": {
@@ -91,12 +91,17 @@ requirejs.config({
define([
'./platform/framework/src/Main',
'./src/defaultRegistry',
'./src/MCT'
], function (Main, defaultRegistry, MCT) {
'./src/MCT',
'./src/plugins/buildInfo/plugin'
], function (Main, defaultRegistry, MCT, buildInfo) {
var openmct = new MCT();
openmct.legacyRegistry = defaultRegistry;
if (typeof BUILD_CONSTANTS !== 'undefined') {
openmct.install(buildInfo(BUILD_CONSTANTS));
}
openmct.on('start', function () {
return new Main().run(defaultRegistry);
});

View File

@@ -22,12 +22,10 @@
"git-rev-sync": "^1.4.0",
"glob": ">= 3.0.0",
"gulp": "^3.9.1",
"gulp-header": "^1.8.8",
"gulp-jscs": "^3.0.2",
"gulp-jshint": "^2.0.0",
"gulp-jshint-html-reporter": "^0.1.3",
"gulp-rename": "^1.2.2",
"gulp-replace-task": "^0.11.0",
"gulp-requirejs-optimize": "^0.3.1",
"gulp-sass": "^2.2.0",
"gulp-sourcemaps": "^1.6.0",

View File

@@ -26,6 +26,7 @@ define([
"./src/InspectorPaneController",
"./src/BrowseObjectController",
"./src/MenuArrowController",
"./src/ObjectHeaderController",
"./src/navigation/NavigationService",
"./src/navigation/NavigateAction",
"./src/navigation/OrphanNavigationHandler",
@@ -36,6 +37,7 @@ define([
"text!./res/templates/browse-object.html",
"text!./res/templates/items/grid-item.html",
"text!./res/templates/browse/object-header.html",
"text!./res/templates/browse/object-header-frame.html",
"text!./res/templates/menu-arrow.html",
"text!./res/templates/back-arrow.html",
"text!./res/templates/items/items.html",
@@ -48,6 +50,7 @@ define([
InspectorPaneController,
BrowseObjectController,
MenuArrowController,
ObjectHeaderController,
NavigationService,
NavigateAction,
OrphanNavigationHandler,
@@ -58,6 +61,7 @@ define([
browseObjectTemplate,
gridItemTemplate,
objectHeaderTemplate,
objectHeaderFrameTemplate,
menuArrowTemplate,
backArrowTemplate,
itemsTemplate,
@@ -140,6 +144,13 @@ define([
"$location",
"$attrs"
]
},
{
"key": "ObjectHeaderController",
"implementation": ObjectHeaderController,
"depends": [
"$scope"
]
}
],
"representations": [
@@ -173,6 +184,13 @@ define([
"type"
]
},
{
"key": "object-header-frame",
"template": objectHeaderFrameTemplate,
"uses": [
"type"
]
},
{
"key": "menu-arrow",
"template": menuArrowTemplate,

View File

@@ -0,0 +1,31 @@
<!--
Open MCT, Copyright (c) 2014-2017, United States Government
as represented by the Administrator of the National Aeronautics and Space
Administration. All rights reserved.
Open MCT is licensed under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Open MCT includes source code licensed under additional open source
licenses. See the Open Source Licenses file (LICENSES.md) included with
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<span class='type-icon flex-elem {{type.getCssClass()}}'></span>
<span class="l-elem-wrapper l-flex-row flex-elem grows" ng-controller="ObjectHeaderController as controller">
<span ng-if="parameters.mode" class='action flex-elem'>{{parameters.mode}}</span>
<span class='title-label flex-elem holder flex-can-shrink s-input-inline'>{{model.name}}</span>
<span class='t-object-alert t-alert-unsynced flex-elem holder' title='This object is not currently displaying real-time data'></span>
<mct-representation
key="'menu-arrow'"
mct-object='domainObject'
class="flex-elem context-available-w"></mct-representation>
</span>

View File

@@ -20,9 +20,13 @@
at runtime from the About dialog for additional information.
-->
<span class='type-icon flex-elem {{type.getCssClass()}}'></span>
<span class="l-elem-wrapper l-flex-row flex-elem grows">
<span class="l-elem-wrapper l-flex-row flex-elem grows" ng-controller="ObjectHeaderController as controller">
<span ng-if="parameters.mode" class='action flex-elem'>{{parameters.mode}}</span>
<span class='title-label flex-elem holder flex-can-shrink'>{{model.name}}</span>
<span ng-attr-contenteditable="{{ controller.editable ? true : undefined }}"
class='title-label flex-elem holder flex-can-shrink s-input-inline'
ng-click="controller.edit()"
ng-blur="controller.updateName($event)"
ng-keypress="controller.updateName($event)">{{model.name}}</span>
<span class='t-object-alert t-alert-unsynced flex-elem holder' title='This object is not currently displaying real-time data'></span>
<mct-representation
key="'menu-arrow'"

View File

@@ -0,0 +1,92 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define(
[],
function () {
/**
* Controller to provide the ability to inline edit an object name.
*
* @constructor
* @memberof platform/commonUI/browse
*/
function ObjectHeaderController($scope) {
this.$scope = $scope;
this.domainObject = $scope.domainObject;
this.editable = this.allowEdit();
}
/**
* Updates the object name on blur and enter keypress events.
*
* @param event the mouse event
*/
ObjectHeaderController.prototype.updateName = function (event) {
if (!event || !event.currentTarget) {
return;
}
if (event.type === 'blur') {
this.updateModel(event);
} else if (event.which === 13) {
this.updateModel(event);
event.currentTarget.blur();
window.getSelection().removeAllRanges();
}
};
/**
* Updates the model.
*
* @param event the mouse event
* @param private
*/
ObjectHeaderController.prototype.updateModel = function (event) {
var name = event.currentTarget.textContent.replace(/\n/g, ' ');
if (name.length === 0) {
name = "Unnamed " + this.domainObject.getCapability("type").typeDef.name;
event.currentTarget.textContent = name;
}
if (name !== this.domainObject.getModel().name) {
this.domainObject.getCapability('mutation').mutate(function (model) {
model.name = name;
});
}
};
/**
* Checks if the domain object is editable.
*
* @private
* @return true if object is editable
*/
ObjectHeaderController.prototype.allowEdit = function () {
var type = this.domainObject && this.domainObject.getCapability('type');
return !!(type && type.hasFeature('creation'));
};
return ObjectHeaderController;
}
);

View File

@@ -0,0 +1,137 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define(
["../src/ObjectHeaderController"],
function (ObjectHeaderController) {
describe("The object header controller", function () {
var mockScope,
mockDomainObject,
mockCapabilities,
mockMutationCapability,
mockTypeCapability,
mockEvent,
mockCurrentTarget,
model,
controller;
beforeEach(function () {
mockMutationCapability = jasmine.createSpyObj("mutation", ["mutate"]);
mockTypeCapability = jasmine.createSpyObj("type", ["typeDef", "hasFeature"]);
mockTypeCapability.typeDef = { name: ""};
mockTypeCapability.hasFeature.andCallFake(function (feature) {
return feature === 'creation';
});
mockCapabilities = {
mutation: mockMutationCapability,
type: mockTypeCapability
};
model = {
name: "Test name"
};
mockDomainObject = jasmine.createSpyObj("domainObject", ["getCapability", "getModel"]);
mockDomainObject.getModel.andReturn(model);
mockDomainObject.getCapability.andCallFake(function (key) {
return mockCapabilities[key];
});
mockScope = {
domainObject: mockDomainObject
};
mockCurrentTarget = jasmine.createSpyObj("currentTarget", ["blur", "textContent"]);
mockCurrentTarget.blur.andReturn(mockCurrentTarget);
mockEvent = {
which: {},
type: {},
currentTarget: mockCurrentTarget
};
controller = new ObjectHeaderController(mockScope);
});
it("updates the model with new name on blur", function () {
mockEvent.type = "blur";
mockCurrentTarget.textContent = "New name";
controller.updateName(mockEvent);
expect(mockMutationCapability.mutate).toHaveBeenCalled();
});
it("updates the model with a default for blank names", function () {
mockEvent.type = "blur";
mockCurrentTarget.textContent = "";
controller.updateName(mockEvent);
expect(mockCurrentTarget.textContent.length).not.toEqual(0);
expect(mockMutationCapability.mutate).toHaveBeenCalled();
});
it("does not update the model if the same name", function () {
mockEvent.type = "blur";
mockCurrentTarget.textContent = mockDomainObject.getModel().name;
controller.updateName(mockEvent);
expect(mockMutationCapability.mutate).not.toHaveBeenCalled();
});
it("updates the model on enter keypress event only", function () {
mockCurrentTarget.textContent = "New name";
controller.updateName(mockEvent);
expect(mockMutationCapability.mutate).not.toHaveBeenCalled();
mockEvent.which = 13;
controller.updateName(mockEvent);
expect(mockMutationCapability.mutate).toHaveBeenCalledWith(jasmine.any(Function));
mockMutationCapability.mutate.mostRecentCall.args[0](model);
expect(mockDomainObject.getModel().name).toBe("New name");
});
it("blurs the field on enter key press", function () {
mockCurrentTarget.textContent = "New name";
mockEvent.which = 13;
controller.updateName(mockEvent);
expect(mockEvent.currentTarget.blur).toHaveBeenCalled();
});
it("allows editting name when object is creatable", function () {
expect(controller.allowEdit()).toBe(true);
});
it("disallows editting name when object is non-creatable", function () {
mockTypeCapability.hasFeature.andReturn(false);
expect(controller.allowEdit()).toBe(false);
});
});
}
);

View File

@@ -23,7 +23,7 @@
<div class="s-menu-button major create-button" ng-click="createController.toggle()">
<span class="title-label">Create</span>
</div>
<div class="menu super-menu" ng-show="createController.isActive()">
<div class="menu super-menu l-create-menu" ng-show="createController.isActive()">
<mct-representation mct-object="domainObject" key="'create-menu'">
</mct-representation>
</div>

View File

@@ -19,8 +19,8 @@
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<div class="contents" ng-controller="CreateMenuController">
<div class="pane left menu-items">
<div class="w-menu" ng-controller="CreateMenuController">
<div class="col menu-items">
<ul>
<li ng-repeat="createAction in createActions" ng-click="createAction.perform()">
<a ng-mouseover="representation.activeMetadata = createAction.getMetadata()"
@@ -31,13 +31,15 @@
</li>
</ul>
</div>
<div class="pane right menu-item-description">
<div class="col menu-item-description">
<div class="desc-area icon {{ representation.activeMetadata.cssClass }}"></div>
<div class="desc-area title">
{{representation.activeMetadata.name}}
</div>
<div class="desc-area description">
{{representation.activeMetadata.description}}
<div class="w-title-desc">
<div class="desc-area title">
{{representation.activeMetadata.name}}
</div>
<div class="desc-area description">
{{representation.activeMetadata.description}}
</div>
</div>
</div>
</div>

View File

@@ -2,7 +2,7 @@
"metadata": {
"name": "openmct-symbols-16px",
"lastOpened": 0,
"created": 1502487054429
"created": 1506973656040
},
"iconSets": [
{
@@ -636,13 +636,29 @@
"code": 921670,
"tempChar": ""
},
{
"order": 138,
"id": 115,
"name": "icon-import",
"prevSize": 24,
"code": 921671,
"tempChar": ""
},
{
"order": 136,
"id": 116,
"name": "icon-export",
"prevSize": 24,
"code": 921672,
"tempChar": ""
},
{
"order": 37,
"prevSize": 24,
"name": "icon-activity",
"id": 32,
"code": 921856,
"tempChar": ""
"tempChar": ""
},
{
"order": 36,
@@ -650,7 +666,7 @@
"name": "icon-activity-mode",
"id": 31,
"code": 921857,
"tempChar": ""
"tempChar": ""
},
{
"order": 52,
@@ -658,7 +674,7 @@
"name": "icon-autoflow-tabular",
"id": 47,
"code": 921858,
"tempChar": ""
"tempChar": ""
},
{
"order": 55,
@@ -666,7 +682,7 @@
"name": "icon-clock",
"id": 50,
"code": 921859,
"tempChar": ""
"tempChar": ""
},
{
"order": 58,
@@ -674,7 +690,7 @@
"name": "icon-database",
"id": 53,
"code": 921860,
"tempChar": ""
"tempChar": ""
},
{
"order": 57,
@@ -682,7 +698,7 @@
"name": "icon-database-query",
"id": 52,
"code": 921861,
"tempChar": ""
"tempChar": ""
},
{
"order": 17,
@@ -690,7 +706,7 @@
"name": "icon-dataset",
"id": 12,
"code": 921862,
"tempChar": ""
"tempChar": ""
},
{
"order": 22,
@@ -698,7 +714,7 @@
"name": "icon-datatable",
"id": 17,
"code": 921863,
"tempChar": ""
"tempChar": ""
},
{
"order": 59,
@@ -706,7 +722,7 @@
"name": "icon-dictionary",
"id": 54,
"code": 921864,
"tempChar": ""
"tempChar": ""
},
{
"order": 62,
@@ -714,7 +730,7 @@
"name": "icon-folder",
"id": 57,
"code": 921865,
"tempChar": ""
"tempChar": ""
},
{
"order": 66,
@@ -722,7 +738,7 @@
"name": "icon-image",
"id": 61,
"code": 921872,
"tempChar": ""
"tempChar": ""
},
{
"order": 68,
@@ -730,7 +746,7 @@
"name": "icon-layout",
"id": 63,
"code": 921873,
"tempChar": ""
"tempChar": ""
},
{
"order": 77,
@@ -738,7 +754,7 @@
"name": "icon-object",
"id": 72,
"code": 921874,
"tempChar": ""
"tempChar": ""
},
{
"order": 78,
@@ -746,7 +762,7 @@
"name": "icon-object-unknown",
"id": 73,
"code": 921875,
"tempChar": ""
"tempChar": ""
},
{
"order": 79,
@@ -754,7 +770,7 @@
"name": "icon-packet",
"id": 74,
"code": 921876,
"tempChar": ""
"tempChar": ""
},
{
"order": 80,
@@ -762,7 +778,7 @@
"name": "icon-page",
"id": 75,
"code": 921877,
"tempChar": ""
"tempChar": ""
},
{
"order": 135,
@@ -770,7 +786,7 @@
"name": "icon-plot-overlay",
"prevSize": 24,
"code": 921878,
"tempChar": ""
"tempChar": ""
},
{
"order": 113,
@@ -778,7 +794,7 @@
"name": "icon-plot-stacked",
"prevSize": 24,
"code": 921879,
"tempChar": ""
"tempChar": ""
},
{
"order": 10,
@@ -786,7 +802,7 @@
"name": "icon-session",
"id": 5,
"code": 921880,
"tempChar": ""
"tempChar": ""
},
{
"order": 24,
@@ -794,7 +810,7 @@
"name": "icon-tabular",
"id": 19,
"code": 921881,
"tempChar": ""
"tempChar": ""
},
{
"order": 7,
@@ -802,7 +818,7 @@
"name": "icon-tabular-lad",
"id": 2,
"code": 921888,
"tempChar": ""
"tempChar": ""
},
{
"order": 6,
@@ -810,7 +826,7 @@
"name": "icon-tabular-lad-set",
"id": 1,
"code": 921889,
"tempChar": ""
"tempChar": ""
},
{
"order": 8,
@@ -818,7 +834,7 @@
"name": "icon-tabular-realtime",
"id": 3,
"code": 921890,
"tempChar": ""
"tempChar": ""
},
{
"order": 23,
@@ -826,7 +842,7 @@
"name": "icon-tabular-scrolling",
"id": 18,
"code": 921891,
"tempChar": ""
"tempChar": ""
},
{
"order": 112,
@@ -834,7 +850,7 @@
"name": "icon-telemetry",
"id": 86,
"code": 921892,
"tempChar": ""
"tempChar": ""
},
{
"order": 90,
@@ -842,7 +858,7 @@
"name": "icon-telemetry-panel",
"id": 85,
"code": 921893,
"tempChar": ""
"tempChar": ""
},
{
"order": 93,
@@ -850,7 +866,7 @@
"name": "icon-timeline",
"id": 88,
"code": 921894,
"tempChar": ""
"tempChar": ""
},
{
"order": 116,
@@ -858,7 +874,7 @@
"name": "icon-timer-v1.5",
"prevSize": 24,
"code": 921895,
"tempChar": ""
"tempChar": ""
},
{
"order": 11,
@@ -866,7 +882,7 @@
"name": "icon-topic",
"id": 6,
"code": 921896,
"tempChar": ""
"tempChar": ""
},
{
"order": 115,
@@ -874,7 +890,7 @@
"name": "icon-box-with-dashed-lines",
"id": 29,
"code": 921897,
"tempChar": ""
"tempChar": ""
},
{
"order": 126,
@@ -882,7 +898,15 @@
"name": "icon-summary-widget",
"prevSize": 24,
"code": 921904,
"tempChar": ""
"tempChar": ""
},
{
"order": 139,
"id": 117,
"name": "icon-notebook",
"prevSize": 24,
"code": 921905,
"tempChar": ""
}
],
"metadata": {
@@ -2683,6 +2707,52 @@
]
}
},
{
"id": 115,
"paths": [
"M832 192.4v639.4c0 0.2-0.2 0.2-0.4 0.4h-319.6v192h320c105.6 0 192-86.4 192-192v-640.2c0-105.6-86.4-192-192-192h-320v192h319.6c0.2 0 0.4 0.2 0.4 0.4z",
"M192 704v192l384-384-384-384v192h-192v384z"
],
"attrs": [
{},
{}
],
"grid": 16,
"tags": [
"icon-import"
],
"isMulticolor": false,
"isMulticolor2": false,
"colorPermutations": {
"1161751207457516161751": [
{},
{}
]
}
},
{
"id": 116,
"paths": [
"M192 831.66v-639.32l0.34-0.34h319.66v-192h-320c-105.6 0-192 86.4-192 192v640c0 105.6 86.4 192 192 192h320v-192h-319.66z",
"M1024 512l-384-384v192h-192v384h192v192l384-384z"
],
"attrs": [
{},
{}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 16,
"tags": [
"icon-export"
],
"colorPermutations": {
"1161751207457516161751": [
{},
{}
]
}
},
{
"paths": [
"M576 64h-256l320 320h-290.256c-44.264-76.516-126.99-128-221.744-128h-128v512h128c94.754 0 177.48-51.484 221.744-128h290.256l-320 320h256l448-448-448-448z"
@@ -3462,6 +3532,29 @@
{}
]
}
},
{
"id": 117,
"paths": [
"M896 110.8c0-79.8-55.4-127.4-123-105.4l-773 250.6h896v-145.2z",
"M896 320h-896v576c0 70.4 57.6 128 128 128h768c70.4 0 128-57.6 128-128v-448c0-70.4-57.6-128-128-128zM832 832h-384v-320h384v320z"
],
"attrs": [
{},
{}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 16,
"tags": [
"icon-notebook"
],
"colorPermutations": {
"1161751207457516161751": [
{},
{}
]
}
}
],
"colorThemes": [

View File

@@ -85,6 +85,8 @@
<glyph unicode="&#xe1044;" glyph-name="icon-grid-snap-no" d="M768 384h192v-64h-192v64zM256 384h192v-64h-192v64zM0 384h192v-64h-192v64zM640 448h-64v-64h-64v-64h64v-64h64v64h64v64h-64zM576 704h64v-192h-64v192zM576 960h64v-192h-64v192zM576 192h64v-192h-64v192z" />
<glyph unicode="&#xe1045;" glyph-name="icon-frame-show" d="M0 896v-896h1024v896h-1024zM896 128h-768v640h768v-640zM192 704h384v-128h-384v128z" />
<glyph unicode="&#xe1046;" glyph-name="icon-frame-hide" d="M128 770h420l104 128h-652v-802.4l128 157.4zM896 130h-420l-104-128h652v802.4l-128-157.4zM832 962l-832-1024h192l832 1024zM392 578l104 128h-304v-128z" />
<glyph unicode="&#xe1047;" glyph-name="icon-import" d="M832 767.6v-639.4c0-0.2-0.2-0.2-0.4-0.4h-319.6v-192h320c105.6 0 192 86.4 192 192v640.2c0 105.6-86.4 192-192 192h-320v-192h319.6c0.2 0 0.4-0.2 0.4-0.4zM192 256v-192l384 384-384 384v-192h-192v-384z" />
<glyph unicode="&#xe1048;" glyph-name="icon-export" d="M192 128.34v639.32l0.34 0.34h319.66v192h-320c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h320v192h-319.66zM1024 448l-384 384v-192h-192v-384h192v-192l384 384z" />
<glyph unicode="&#xe1100;" glyph-name="icon-activity" d="M576 896h-256l320-320h-290.256c-44.264 76.516-126.99 128-221.744 128h-128v-512h128c94.754 0 177.48 51.484 221.744 128h290.256l-320-320h256l448 448-448 448z" />
<glyph unicode="&#xe1101;" glyph-name="icon-activity-mode" d="M512 960c-214.866 0-398.786-132.372-474.744-320h90.744c56.86 0 107.938-24.724 143.094-64h240.906l-192 192h256l320-320-320-320h-256l192 192h-240.906c-35.156-39.276-86.234-64-143.094-64h-90.744c75.958-187.628 259.878-320 474.744-320 282.77 0 512 229.23 512 512s-229.23 512-512 512z" />
<glyph unicode="&#xe1102;" glyph-name="icon-autoflow-tabular" d="M192 960c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h64v1024h-64zM384 960h256v-1024h-256v1024zM832 960h-64v-704h256v512c0 105.6-86.4 192-192 192z" />
@@ -116,4 +118,5 @@
<glyph unicode="&#xe1128;" glyph-name="icon-topic" d="M454.36 483.36l86.3 86.3c9.088 8.965 21.577 14.502 35.36 14.502s26.272-5.537 35.366-14.507l86.294-86.294c19.328-19.358 42.832-34.541 69.047-44.082l1.313 171.722-57.64 57.64c-34.407 34.33-81.9 55.558-134.35 55.558s-99.943-21.228-134.354-55.562l-86.296-86.297c-9.088-8.965-21.577-14.502-35.36-14.502s-26.272 5.537-35.366 14.507l-28.674 28.654v-172.14c19.045-7.022 41.040-11.084 63.984-11.084 52.463 0 99.966 21.239 134.379 55.587zM505.64 412.64l-86.3-86.3c-9.088-8.965-21.577-14.502-35.36-14.502s-26.272 5.537-35.366 14.507l-86.294 86.294c-2 2-4.2 4-6.36 6v-197.36c33.664-30.72 78.65-49.537 128.031-49.537 52.44 0 99.923 21.22 134.333 55.541l86.296 86.296c9.088 8.965 21.577 14.502 35.36 14.502s26.272-5.537 35.366-14.507l86.294-86.294c2-2 4.2-4 6.36-6v197.36c-33.664 30.72-78.65 49.537-128.031 49.537-52.44 0-99.923-21.22-134.333-55.541zM832 960h-128v-192h127.66l0.34-0.34v-639.32l-0.34-0.34h-127.66v-192h128c105.6 0 192 86.4 192 192v640c0 105.6-86.4 192-192 192zM320 128h-127.66l-0.34 0.34v639.32l0.34 0.34h127.66v192h-128c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h128v192z" />
<glyph unicode="&#xe1129;" glyph-name="icon-box-with-dashed-lines" d="M0 576h128v-256h-128v256zM128 831.78l0.22 0.22h191.78v128h-192c-70.606-0.215-127.785-57.394-128-127.979v-192.021h128v191.78zM128 64.22v191.78h-128v-192c0.215-70.606 57.394-127.785 127.979-128h192.021v128h-191.78zM384 960h256v-128h-256v128zM896 64.22l-0.22-0.22h-191.78v-128h192c70.606 0.215 127.785 57.394 128 127.979v192.021h-128v-191.78zM896 960h-192v-128h191.78l0.22-0.22v-191.78h128v192c-0.215 70.606-57.394 127.785-127.979 128zM896 576h128v-256h-128v256zM384 64h256v-128h-256v128zM256 704h512v-512h-512v512z" />
<glyph unicode="&#xe1130;" glyph-name="icon-summary-widget" d="M896 960h-768c-70.4 0-128-57.6-128-128v-768c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v768c0 70.4-57.6 128-128 128zM847.8 349.6l-82.6-143.2-189.6 131.6 19.2-230h-165.4l19.2 230-189.6-131.6-82.6 143.2 208.6 98.4-208.8 98.4 82.6 143.2 189.6-131.6-19.2 230h165.4l-19.2-230 189.6 131.6 82.6-143.2-208.6-98.4 208.8-98.4z" />
<glyph unicode="&#xe1131;" glyph-name="icon-notebook" d="M896 849.2c0 79.8-55.4 127.4-123 105.4l-773-250.6h896v145.2zM896 640h-896v-576c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v448c0 70.4-57.6 128-128 128zM832 128h-384v320h384v-320z" />
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

@@ -21,7 +21,7 @@
*****************************************************************************/
/************************** FEATURES */
$enableImageryThumbs: false; // Set to true if historical imagery thumbnails are supported
$enableImageryThumbs: true; // Set to true if historical imagery thumbnails are supported
/************************** VERY INFLUENTIAL GLOBAL DIMENSIONS */
$bodyMargin: 10px;
@@ -82,7 +82,7 @@ $tabularTdPadTB: 2px;
/*************** Imagery */
$imageMainControlBarH: 25px;
$imageThumbsD: 120px;
$imageThumbsWrapperH: $imageThumbsD * 1.4;
$imageThumbsWrapperH: 155px;
$imageThumbPad: 1px;
/*************** Ticks */
$ticksH: 25px;
@@ -111,7 +111,9 @@ $bubbleMaxW: 300px;
$reqSymbolW: 15px;
$reqSymbolM: $interiorMargin * 2;
$reqSymbolFontSize: 0.75em;
$inputTextP: 3px 5px;
$inputTextPTopBtm: 3px;
$inputTextPLeftRight: 5px;
$inputTextP: $inputTextPTopBtm $inputTextPLeftRight;
/*************** Wait Spinner Defaults */
$waitSpinnerD: 32px;
$waitSpinnerTreeD: 20px;

View File

@@ -52,6 +52,7 @@
font-size: 0.8rem;
$p: 1px;
line-height: 100%;
overflow: hidden;
&.l-static-text {
padding: $p;
}

View File

@@ -113,6 +113,8 @@ $glyph-icon-grid-snap-to: '\e1043';
$glyph-icon-grid-snap-no: '\e1044';
$glyph-icon-frame-show: '\e1045';
$glyph-icon-frame-hide: '\e1046';
$glyph-icon-import: '\e1047';
$glyph-icon-export: '\e1048';
$glyph-icon-activity: '\e1100';
$glyph-icon-activity-mode: '\e1101';
$glyph-icon-autoflow-tabular: '\e1102';
@@ -144,6 +146,7 @@ $glyph-icon-timer: '\e1127';
$glyph-icon-topic: '\e1128';
$glyph-icon-box-with-dashed-lines: '\e1129';
$glyph-icon-summary-widget: '\e1130';
$glyph-icon-notebook: '\e1131';
/************************** 16 PX CLASSES */
@@ -225,6 +228,8 @@ $glyph-icon-summary-widget: '\e1130';
.icon-grid-snap-no { @include glyphBefore($glyph-icon-grid-snap-no); }
.icon-frame-show { @include glyphBefore($glyph-icon-frame-show); }
.icon-frame-hide { @include glyphBefore($glyph-icon-frame-hide); }
.icon-import { @include glyphBefore($glyph-icon-import); }
.icon-export { @include glyphBefore($glyph-icon-export); }
.icon-activity { @include glyphBefore($glyph-icon-activity); }
.icon-activity-mode { @include glyphBefore($glyph-icon-activity-mode); }
.icon-autoflow-tabular { @include glyphBefore($glyph-icon-autoflow-tabular); }
@@ -256,6 +261,7 @@ $glyph-icon-summary-widget: '\e1130';
.icon-topic { @include glyphBefore($glyph-icon-topic); }
.icon-box-with-dashed-lines { @include glyphBefore($glyph-icon-box-with-dashed-lines); }
.icon-summary-widget { @include glyphBefore($glyph-icon-summary-widget); }
.icon-notebook { @include glyphBefore($glyph-icon-notebook); }
/************************** 12 PX CLASSES */
.icon-crosshair-12px { @include glyphBefore($glyph-icon-crosshair,'symbolsfont-12px'); }

View File

@@ -26,5 +26,6 @@
display: block;
height: 100%;
width: 100%;
border: none;
}
}

View File

@@ -316,23 +316,28 @@
text-shadow: $shdwItemText;
}
@mixin input-base($bg: $colorInputBg, $fg: $colorInputFg, $shdw: rgba(black, 0.6) 0 1px 3px) {
@mixin input-base() {
@include appearance(none);
border-radius: $controlCr;
box-sizing: border-box;
box-shadow: inset $shdw;
background: $bg;
border: none;
color: $fg;
outline: none;
&:focus { outline: 0; }
&.error {
background-color: $colorFormFieldErrorBg;
color: $colorFormFieldErrorFg;
}
}
@mixin nice-input($bg: $colorInputBg, $fg: $colorInputFg) {
@include input-base($bg, $fg);
@mixin s-input($bg: $colorInputBg, $fg: $colorInputFg, $shdw: rgba(black, 0.6) 0 1px 3px) {
@include input-base();
background: $bg;
box-shadow: inset $shdw;
color: $fg;
}
@mixin nice-input($bg: $colorInputBg, $fg: $colorInputFg, $shdw: rgba(black, 0.6) 0 1px 3px) {
@include s-input($bg, $fg, $shdw);
border: none;
outline: none;
}
@mixin contextArrow() {
@@ -344,7 +349,7 @@
}
@mixin nice-textarea($bg: $colorBodyBg, $fg: $colorBodyFg) {
@include input-base($bg, $fg);
@include nice-input($bg, $fg);
padding: $interiorMargin;
}

View File

@@ -33,7 +33,6 @@ $pad: $interiorMargin * $baseRatio;
height: $btnStdH;
line-height: $btnStdH;
padding: 0 $pad;
vertical-align: top;
&.labeled:before {
// Icon when it's included

View File

@@ -72,11 +72,13 @@
}
}
// Hyperlink objects
.s-hyperlink {
// Hyperlink objects
.label {
font-size: 0.8rem !important;
}
&:not(.s-button) {
color: $colorKey;
font-size: 0.8rem;
&:hover { color: $colorKeyHov; }
}
}
@@ -232,12 +234,16 @@ textarea {
}
/******************************************************** INPUTS */
%input-base {
@include input-base();
}
input[type="text"],
input[type="search"],
input[type="number"] {
@include nice-input();
vertical-align: baseline;
padding: $inputTextP;
padding: $inputTextPTopBtm $inputTextPLeftRight;
&.numeric {
text-align: right;
}
@@ -281,6 +287,32 @@ textarea.lg { position: relative; height: 300px; }
}
}
*[contenteditable].s-input-inline,
input[type="text"].s-input-inline,
.s-input-inline input[type="text"] {
// A text input or contenteditable element that indicates edit affordance on hover and looks like an input on focus
@extend %input-base;
@include trans-prop-nice((padding, box-shadow), 250ms);
background: none;
box-shadow: none;
border: 1px solid transparent;
min-width: 20px;
padding-left: 0;
padding-right: 0;
&:hover,
&:focus {
padding-left: $inputTextPLeftRight;
padding-right: $inputTextPLeftRight;
}
&:hover {
border-color: rgba($colorBodyFg, 0.2);
}
&:focus {
@include s-input();
border-color: transparent;
}
}
/******************************************************** SELECTS */
.select {
@include btnSubtle($bg: $colorSelectBg);
@@ -296,6 +328,7 @@ textarea.lg { position: relative; height: 300px; }
select {
@include appearance(none);
box-sizing: border-box;
&:focus { outline: 0; }
background: none;
color: $colorSelectFg;
cursor: pointer;
@@ -307,9 +340,8 @@ textarea.lg { position: relative; height: 300px; }
}
}
&:before {
//@include contextArrow();
pointer-events: none;
color: rgba($colorSelectFg, percentToDecimal($contrastInvokeMenuPercent));
color: rgba($colorInvokeMenu, percentToDecimal($contrastInvokeMenuPercent));
display: block;
position: absolute;
right: $interiorMargin; top: 0;
@@ -721,11 +753,15 @@ body.desktop {
}
.overlay ::-webkit-scrollbar-thumb {
$lr: 15%;
background: $scrollbarThumbColorOverlay;
&:hover { background: $scrollbarThumbColorOverlayHov; }
}
.menu ::-webkit-scrollbar-thumb {
background: $scrollbarThumbColorMenu;
&:hover { background: $scrollbarThumbColorMenuHov; }
}
::-webkit-scrollbar-corner {
background: $scrollbarTrackColorBg;
}

View File

@@ -21,92 +21,87 @@
*****************************************************************************/
/******************************************************** MENU BUTTONS */
.s-menu-button {
// Formerly .btn-menu
@extend .s-button;
span.l-click-area {
// In markup, this element should not enclose anything.
@extend .abs;
}
// Formerly .btn-menu
@extend .s-button;
span.l-click-area {
// In markup, this element should not enclose anything.
@extend .abs;
}
.icon {
font-size: 16px; //120%;
}
.icon {
font-size: 16px; //120%;
}
.title-label {
margin-left: $interiorMarginSm;
}
.title-label {
margin-left: $interiorMarginSm;
}
.color-swatch {
// Used in color menu buttons in toolbar
$d: 10px;
display: inline-block;
border: 1px solid rgba($colorBtnFg, 0.2);
height: $d; width: $d;
height: $d;
width: $d;
vertical-align: middle;
margin-left: $interiorMarginSm;
margin-top: -2px;
}
&:after {
// Adds the downward facing 'context available / invoke menu' arrow element
@include contextArrow();
color: rgba($colorInvokeMenu, percentToDecimal($contrastInvokeMenuPercent));
}
&:after {
// Adds the downward facing 'context available / invoke menu' arrow element
@include contextArrow();
color: rgba($colorInvokeMenu, percentToDecimal($contrastInvokeMenuPercent));
}
&.create-button {
&.create-button {
@extend .icon-plus;
.title-label {
font-size: 1rem;
}
}
.title-label {
font-size: 1rem;
}
}
.menu {
left: 0;
text-align: left;
}
.menu {
left: 0;
text-align: left;
}
}
/******************************************************** MENUS THEMSELVES */
.menu-element {
cursor: pointer;
position: relative;
}
.s-menu {
border-radius: $basicCr;
@include containerSubtle($colorMenuBg, $colorMenuFg);
@include boxShdw($shdwMenu);
@include txtShdw($shdwMenuText);
padding: $interiorMarginSm 0;
cursor: pointer;
position: relative;
}
.menu {
// TODO: reduce size of icons
@extend .s-menu;
display: block;
position: absolute;
z-index: 10;
ul {
@include menuUlReset();
li {
box-sizing: border-box;
border-top: 1px solid pullForward($colorMenuBg, 10%);
border-radius: $basicCr;
@include containerSubtle($colorMenuBg, $colorMenuFg);
@include boxShdw($shdwMenu);
@include txtShdw($shdwMenuText);
padding: $interiorMarginSm 0;
display: block;
position: absolute;
z-index: 10;
ul {
@include menuUlReset();
li {
box-sizing: border-box;
border-top: 1px solid pullForward($colorMenuBg, 10%);
color: $colorMenuFg;
//color: pullForward($colorMenuBg, 60%);
line-height: $menuLineH;
padding: $interiorMarginSm $interiorMargin * 2 $interiorMarginSm ($interiorMargin * 2) + $treeTypeIconW;
position: relative;
white-space: nowrap;
&:first-child {
border: none;
}
&:hover {
background: $colorMenuHovBg;
color: $colorMenuHovFg;
line-height: $menuLineH;
padding: $interiorMarginSm $interiorMargin * 2 $interiorMarginSm ($interiorMargin * 2) + $treeTypeIconW;
position: relative;
white-space: nowrap;
&:first-child {
border: none;
}
&:hover {
background: $colorMenuHovBg;
color: $colorMenuHovFg;
&:before {
color: $colorMenuHovIc;
}
}
}
&:before {
@extend .ui-symbol;
@extend .type-icon;
@@ -114,8 +109,8 @@
display: inline-block;
left: $interiorMargin * 2;
}
}
}
}
}
}
.menu,
@@ -123,94 +118,97 @@
.context-menu,
.super-menu,
.s-menu-button .menu {
pointer-events: auto;
ul li {
a.menu-item-a {
pointer-events: auto;
ul li {
a.menu-item-a {
color: $colorMenuFg;
display: block;
}
}
&:before,
a.menu-item-a:before {
color: $colorMenuIc;
left: $interiorMargin;
}
}
}
}
.checkbox-menu {
// Used in search dropdown in tree
@extend .context-menu;
ul li {
padding-left: 50px;
.checkbox {
$d: 0.7rem;
position: absolute;
left: $interiorMargin;
top: ($menuLineH - $d) / 1.5;
em {
height: $d;
width: $d;
&:before {
font-size: 7px !important;
height: $d;
width: $d;
line-height: $d;
}
}
}
&:before {
// Used in search dropdown in tree
@extend .context-menu;
ul li {
padding-left: 50px;
.checkbox {
$d: 0.7rem;
position: absolute;
left: $interiorMargin;
top: ($menuLineH - $d) / 1.5;
em {
height: $d;
width: $d;
&:before {
font-size: 7px !important;
height: $d;
width: $d;
line-height: $d;
}
}
}
&:before {
// Type icon
left: 25px;
}
}
left: 25px;
}
}
}
.super-menu,
.super-menu > mct-representation,
.super-menu > .contents {
box-sizing: border-box;
display: block;
position: relative;
}
.super-menu {
$w: 500px;
$h: $w - 20;
$plw: 50%;
$prw: 50%;
display: block;
width: $w;
height: $h;
.contents {
@include absPosDefault($interiorMargin);
}
.pane {
box-sizing: border-box;
&.menu-items {
border-right: 1px solid pullForward($colorMenuBg, 10%);
left: 0;
padding-right: $interiorMargin;
right: auto;
width: $plw;
overflow-x: hidden;
overflow-y: auto;
ul {
li {
border-radius: $controlCr;
padding-left: 30px;
border-top: none;
}
}
}
&.menu-item-description {
left: auto;
right: 0;
padding: $interiorMargin * 5;
width: $prw;
$plw: 50%;
$prw: 100% - $plw;
position: absolute;
.w-menu {
align-items: stretch;
display: flex;
flex-direction: row;
margin: $interiorMarginLg;
}
.col {
box-sizing: border-box;
flex: 1 1 auto;
overflow-x: hidden;
&.menu-items {
border-right: 1px solid pullForward($colorMenuBg, 10%);
overflow-y: auto;
padding-right: $interiorMargin;
width: $plw;
ul {
li {
border-radius: $controlCr;
padding-left: 30px;
border-top: none;
}
}
}
&.menu-item-description {
$p: $interiorMargin * 3;
overflow-y: hidden;
padding: $p $p 0 $p;
width: $prw;
.desc-area {
&.icon {
color: $colorCreateMenuLgIcon;
font-size: 8em;
margin-bottom: $interiorMargin * 3;
position: relative;
text-align: center;
}
&.title {
color: $colorCreateMenuText;
font-size: 1.2em;
margin-bottom: $interiorMargin * 2;
}
&.description {
color: pushBack($colorCreateMenuText, 20%);
@@ -218,67 +216,104 @@
line-height: 1.5em;
}
}
}
}
}
}
.w-title-desc {
display: flex;
flex-direction: column;
overflow: hidden; // Height set in specific menu instances
}
// Specific menu instances
&.l-create-menu {
width: 500px;
.col {
max-height: 70vh;
}
.w-title-desc {
height: 190px;
}
.desc-area {
&.icon {
font-size: 8em;
height: 135px;
margin-bottom: $interiorMargin * 3;
}
&.title {
font-size: 1.2em;
margin-bottom: $interiorMargin * 2;
}
}
}
&.mini {
width: 400px;
height: 300px;
.pane {
.col {
max-height: 50vh;
&.menu-items {
font-size: 0.8em;
}
&.menu-item-description {
padding: $interiorMargin * 3;
.desc-area {
&.icon {
font-size: 4em;
}
&.title {
font-size: 1em;
}
}
$p: $interiorMargin * 2;
padding: $p $p 0 $p;
}
}
.w-title-desc {
height: 180px;
}
.desc-area {
&.icon {
font-size: 4em;
height: 70px;
margin-bottom: $interiorMargin * 3;
}
&.title {
font-size: 1em;
margin-bottom: $interiorMargin * 2;
}
}
}
}
.context-menu {
font-size: 0.80rem;
font-size: 0.80rem;
}
.context-menu-holder,
.menu-holder {
position: absolute;
z-index: 120;
.context-menu-wrapper {
position: absolute;
height: 100%;
width: 100%;
}
&.go-left .context-menu,
&.go-left .menu {
right: 0;
}
&.go-up .context-menu,
&.go-up .menu {
bottom: 0;
}
position: absolute;
z-index: 120;
.context-menu-wrapper {
position: absolute;
height: 100%;
width: 100%;
}
&.go-left .context-menu,
&.go-left .menu {
right: 0;
}
&.go-up .context-menu,
&.go-up .menu {
bottom: 0;
}
}
.context-menu-holder {
pointer-events: none;
height: 200px;
width: 170px;
pointer-events: none;
height: 200px;
width: 170px;
}
.btn-bar.right .menu,
.menus-to-left .menu {
z-index: 79;
left: auto;
right: 0;
width: auto;
left: auto;
right: 0;
width: auto;
}
.menus-up .menu {
bottom: $btnStdH; top: auto;
bottom: $btnStdH;
top: auto;
}

View File

@@ -9,7 +9,6 @@
@if $enableImageryThumbs == true {
bottom: $interiorMargin*2 + $imageThumbsWrapperH;
}
min-height: 100px;
min-width: 150px;
.l-image-main {
background-color: $colorPlotBg;
@@ -22,7 +21,9 @@
.l-image-thumbs-wrapper {
top: auto;
height: $imageThumbsWrapperH;
min-height: $imageThumbsWrapperH;
max-height: 60%;
box-sizing: border-box;
}
.l-date,
@@ -43,14 +44,16 @@
.l-image-main-controlbar {
font-size: 0.8em;
line-height: inherit;
.left, .right {
.l-datetime-w, .l-controls-w {
direction: rtl;
overflow: hidden;
}
.left {
.l-datetime-w {
@include ellipsize();
margin-right: $interiorMarginSm;
text-align: left;
}
.right {
.l-controls-w {
z-index: 2;
}
.l-date,
@@ -82,9 +85,8 @@
/*************************************** THUMBS */
.l-image-thumbs-wrapper {
//@include test(green);
overflow-x: auto;
overflow-y: hidden;
overflow-x: hidden;
overflow-y: auto;
padding-bottom: $interiorMargin;
white-space: nowrap;
}
@@ -92,8 +94,17 @@
.l-image-thumb-item {
@include transition(background-color, 0.25s);
box-sizing: border-box;
cursor: pointer;
direction: ltr;
display: inline-block;
float: left;
font-size: 0.8em;
padding: 1px;
position: relative;
margin-left: $interiorMarginSm;
position: relative;
text-align: left;
width: $imageThumbsD + $imageThumbPad*2;
white-space: normal;
.l-thumb,
.l-date,
.l-time {
@@ -103,14 +114,7 @@
.l-time {
padding: 2px 3px;
}
cursor: pointer;
direction: ltr;
display: inline-block;
font-size: 0.8em;
margin-left: $interiorMarginSm;
text-align: left;
width: $imageThumbsD + $imageThumbPad*2;
white-space: normal;
&:hover {
background: $colorThumbHoverBg;
.l-date,
@@ -136,6 +140,7 @@
/*************************************** LOCAL CONTROLS */
.l-local-controls {
max-width: 200px;
min-width: 100px;
width: 35%;
input[type="range"] {
display: block;
@@ -184,7 +189,8 @@
/*************************************** WHEN IN FRAME */
.frame .t-imagery {
.l-image-main-wrapper {
bottom: 0;
bottom: 0 !important;
height: 100% !important;
.l-image-main-controlbar {
font-size: 0.7em;
}
@@ -194,7 +200,8 @@
}
}
}
.l-image-thumbs-wrapper {
.l-image-thumbs-wrapper,
mct-splitter {
display: none;
}
}

View File

@@ -129,9 +129,6 @@
}
.s-filter {
input[type="search"] {
@include input-base();
}
.clear-icon,
.menu-icon,
&:before {

View File

@@ -156,6 +156,8 @@
left: 0;
right: 0;
overflow: auto;
padding-right: $interiorMargin;
padding-bottom: $interiorMargin;
.field.l-input-med {
input[type='text'] {
width: 100%;

View File

@@ -47,7 +47,7 @@
&.t-object-type-hyperlink {
// Hide the right side buttons for objects where they don't make sense
// Note that this will hide the view Switcher button if applied
// to an object that it.
// to an object that has it.
.object-browse-bar .right { display: none; }
}
@@ -120,9 +120,17 @@
}
}
/********************************************************** OBJECT TYPES */
&.t-frame-outer .s-input-inline {
// Prevent inline inputs from being edited when nested in a Layout
pointer-events: none !important;
}
/********************************************************** OBJECT TYPES */
.t-object-type-hyperlink {
.s-hyperlink.s-button {
.object-holder {
overflow: hidden;
}
.l-hyperlink.s-button {
// When a hyperlink is a button in a frame, make it expand to fill out to the object-holder
@extend .abs;
.label {
@@ -142,7 +150,7 @@
body.desktop .frame {
// Hide local controls initially and show it them on hover when they're in an element that's in a frame context
// Frame template is used because we need to target the lowest nested frame
.right {
.object-browse-bar .btn-bar {
opacity: 0;
pointer-events: none;
}
@@ -150,7 +158,7 @@ body.desktop .frame {
// Target the first descendant so that we only show the elements in the outermost container.
// Handles the case where we have layouts in layouts.
&:hover > .object-browse-bar {
.right {
.btn-bar {
opacity: 1;
pointer-events: inherit;
}

View File

@@ -240,7 +240,9 @@ body.desktop .pane .mini-tab-icon.toggle-pane {
.top-bar .buttons-main .s-button,
.top-bar .s-menu-button,
.tool-bar .s-button,
.tool-bar .s-menu-button {
.tool-bar .s-menu-button,
.tool-bar .select,
.tool-bar .input-labeled {
$h: $btnToolbarH;
height: $h;
line-height: $h;

View File

@@ -20,6 +20,7 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
.tool-bar {
font-size: 0.7rem;
&.btn-bar {
white-space: nowrap;
}
@@ -30,9 +31,7 @@
input[type="search"],
input[type="number"] {
box-sizing: border-box;
font-size: .8em;
height: $btnToolbarH;
margin-bottom: 1px;
position: relative;
&.sm {
width: $btnToolbarH;

View File

@@ -20,7 +20,7 @@
at runtime from the About dialog for additional information.
-->
<!-- look at action-button for example -->
<span class="t-filter l-filter s-filter"
<span class="t-filter l-filter"
ng-controller="GetterSetterController">
<input type="search"
class="t-filter-input"

View File

@@ -108,8 +108,11 @@ define(
getMetadata();
});
}
var mutation = $scope.ngModel.selectedObject.getCapability('mutation');
var unlisten = mutation.listen(getMetadata);
$scope.$on('$destroy', unlisten);
}
return ObjectInspectorController;
}
);

View File

@@ -117,9 +117,7 @@ define(
// Apply styles to child elements
function updateChildren(children) {
if (alias) {
position = userWidthPreference || position;
}
position = userWidthPreference || position;
// Pick out correct elements to update, flowing from
// selected anchor edge.
@@ -182,7 +180,9 @@ define(
}
function setUserWidthPreference(value) {
userWidthPreference = value;
if (alias) {
userWidthPreference = value;
}
}
function persistToLocalStorage(value) {

View File

@@ -39,10 +39,18 @@ define(
beforeEach(function () {
mockScope = jasmine.createSpyObj(
"$scope",
["$watch"]
["$watch", "$on"]
);
mockScope.ngModel = {};
mockScope.ngModel.selectedObject = 'mock selected object';
mockScope.ngModel.selectedObject = {
getCapability: function () {
return {
listen: function () {
return true;
}
};
}
};
mockObjectService = jasmine.createSpyObj(
"objectService",

View File

@@ -201,13 +201,15 @@ $shdwItemTreeIcon: 0.6;
$colorThumbHoverBg: $colorItemTreeHoverBg;
// Scrollbar
$scrollbarTrackSize: 10px;
$scrollbarTrackShdw: rgba(#000, 0.7) 0 1px 5px;
$scrollbarTrackColorBg: rgba(#000, 0.4);
$scrollbarTrackSize: 7px;
$scrollbarTrackShdw: rgba(#000, 0.5) 0 1px 5px;
$scrollbarTrackColorBg: transparent; //rgba(#000, 0.4);
$scrollbarThumbColor: pullForward($colorBodyBg, 10%);
$scrollbarThumbColorHov: pullForward($scrollbarThumbColor, 2%);
$scrollbarThumbColorOverlay: pullForward($colorOvrBg, 10%);
$scrollbarThumbColorOverlayHov: pullForward($scrollbarThumbColorOverlay, 2%);
$scrollbarThumbColorMenu: pullForward($colorMenuBg, 20%);
$scrollbarThumbColorMenuHov: pullForward($scrollbarThumbColorMenu, 2%);
// Splitter
// All splitterD* values MUST both be either odd or even numbers

View File

@@ -201,13 +201,15 @@ $shdwItemTreeIcon: none;
$colorThumbHoverBg: $colorItemTreeHoverBg;
// Scrollbar
$scrollbarTrackSize: 10px;
$scrollbarTrackSize: 7px;
$scrollbarTrackShdw: rgba(#000, 0.2) 0 1px 2px;
$scrollbarTrackColorBg: rgba(#000, 0.2);
$scrollbarThumbColor: darken($colorBodyBg, 50%);
$scrollbarThumbColorHov: $colorKey;
$scrollbarThumbColorOverlay: darken($colorOvrBg, 50%);
$scrollbarThumbColorOverlayHov: $scrollbarThumbColorHov;
$scrollbarThumbColorMenu: pullForward($colorMenuBg, 10%);
$scrollbarThumbColorMenuHov: pullForward($scrollbarThumbColorMenu, 2%);
// Splitter
// All splitterD* values MUST both be either odd or even numbers

View File

@@ -94,31 +94,6 @@ define([
}
},
"extensions": {
"versions": [
{
"name": "Version",
"value": "@@version",
"priority": 999
},
{
"name": "Built",
"value": "@@timestamp",
"description": "The date on which this version of the client was built.",
"priority": 990
},
{
"name": "Revision",
"value": "@@revision",
"description": "A unique revision identifier for the client sources.",
"priority": 995
},
{
"name": "Branch",
"value": "@@branch",
"description": "The name of the branch that was used during the build.",
"priority": 994
}
],
"components": [
{
"provides": "objectService",

View File

@@ -1,7 +1,7 @@
$ueTimeConductorH: (25px, 16px, 20px); // Heights for Ticks, Data Visualization, Controls elements
$ueTimeConductorRtH: (25px, 3px, 20px); // Heights for elements in Real-time mode
$timeCondInputTimeSysDefW: 165px; // Default width for datetime value inputs
$timeCondInputDeltaDefW: 60px; // Default width for delta value inputs, typically 00:00:00
$timeCondInputDeltaDefW: 65px; // Default width for delta value inputs, typically 00:00:00
$timeCondTOIIconD: 12px; // height and width of icon used for TOI indicator
$timeCondTOIValOffset: 0px;
$ticksBlockerFadeW: 50px;

View File

@@ -162,9 +162,6 @@
.l-time-conductor-inputs {
pointer-events: auto;
}
input[type="text"] {
@include trans-prop-nice(padding, 250ms);
}
.time-range-input input[type="text"] {
width: $timeCondInputTimeSysDefW;
}
@@ -290,18 +287,6 @@
.l-time-conductor-inputs-holder {
.l-time-range-input-w {
input[type="text"]:not(.error) {
background: transparent;
box-shadow: none;
border-radius: 0;
padding-left: 0;
padding-right: 0;
&:hover,
&:focus {
@include nice-input();
padding: $inputTextP;
}
}
.icon-calendar {
display: none;
}
@@ -309,8 +294,11 @@
display: none;
}
&.end-date {
// Displays the current time
pointer-events: none;
input[type="text"] {
background: none;
box-shadow: none;
color: pullForward($colorTimeCondKeyBg, 5%);
margin-right: $interiorMargin;
tab-index: -1;

View File

@@ -19,8 +19,8 @@
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<div class="contents">
<div class="pane left menu-items">
<div class="w-menu">
<div class="col menu-items">
<ul>
<li ng-repeat="metadata in ngModel.options"
ng-click="ngModel.select(metadata)">
@@ -32,13 +32,15 @@
</li>
</ul>
</div>
<div class="pane right menu-item-description">
<div class="col menu-item-description">
<div class="desc-area ui-symbol icon type-icon {{ngModel.activeMetadata.cssClass}}"></div>
<div class="desc-area title">
{{ngModel.activeMetadata.name}}
</div>
<div class="desc-area description">
{{ngModel.activeMetadata.description}}
<div class="w-title-desc">
<div class="desc-area title">
{{ngModel.activeMetadata.name}}
</div>
<div class="desc-area description">
{{ngModel.activeMetadata.description}}
</div>
</div>
</div>
</div>

View File

@@ -24,7 +24,7 @@
ng-click="modeController.toggle()">
<span class="title-label">{{ngModel.selected.name}}</span>
</div>
<div class="menu super-menu mini mode-selector-menu"
<div class="menu super-menu mini l-mode-selector-menu"
ng-show="modeController.isActive()">
<mct-include key="'mode-menu'"
ng-model="ngModel">

View File

@@ -38,7 +38,7 @@
ng-model="boundsModel"
ng-blur="tcController.setOffsetsFromView(boundsModel)"
field="'startOffset'"
class="hrs-min-input">
class="s-input-inline hrs-min-input">
</mct-control>
</span>
</span>
@@ -71,7 +71,7 @@
ng-model="boundsModel"
ng-blur="tcController.setOffsetsFromView(boundsModel)"
field="'endOffset'"
class="hrs-min-input">
class="s-input-inline hrs-min-input">
</mct-control>
</span>
</span>

View File

@@ -201,7 +201,7 @@ define(
var options = [{
key: 'fixed',
name: 'Fixed Timespan Mode',
description: 'Query and explore data that falls between two fixed datetimes',
description: 'Query and explore data that falls between two fixed datetimes.',
cssClass: 'icon-calendar'
}];
var clocks = {};

View File

@@ -122,14 +122,6 @@ define([
"description": "Set border color",
"control": "color"
},
{
"property": "color",
"cssClass": "icon-T",
"title": "Text color",
"description": "Set text color",
"mandatory": true,
"control": "color"
},
{
"property": "url",
"cssClass": "icon-image",
@@ -145,6 +137,27 @@ define([
}
]
},
{
"items": [
{
"property": "color",
"cssClass": "icon-T",
"title": "Text color",
"description": "Set text color",
"mandatory": true,
"control": "color"
},
{
"property": "size",
"title": "Text size",
"description": "Set text size",
"control": "select",
"options": [9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 30, 36, 48, 72, 96].map(function (size) {
return { "name": size + " px", "value": size + "px" };
})
}
]
},
{
"items": [
{
@@ -212,11 +225,7 @@ define([
"control": "numberfield",
"description": "Resize object width",
"min": "1"
}
]
},
{
"items": [
},
{
"property": "useGrid",
"name": "Snap to Grid",

View File

@@ -19,10 +19,10 @@
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<a class="s-hyperlink" ng-controller="HyperlinkController as hyperlink" href="{{domainObject.getModel().url}}"
<a class="l-hyperlink s-hyperlink" ng-controller="HyperlinkController as hyperlink" href="{{domainObject.getModel().url}}"
ng-attr-target="{{hyperlink.openNewTab() ? '_blank' : undefined}}"
ng-class="{
's-button': hyperlink.isButton()
}">
<div class="label">{{domainObject.getModel().displayText}}</div>
<span class="label">{{domainObject.getModel().displayText}}</span>
</a>

View File

@@ -25,14 +25,12 @@ define([
"./src/controllers/ImageryController",
"./src/directives/MCTBackgroundImage",
"text!./res/templates/imagery.html",
"text!./res/templates/imageryTimeline.html",
'legacyRegistry'
], function (
ImageryViewPolicy,
ImageryController,
MCTBackgroundImage,
imageryTemplate,
imageryTimelineTemplate,
legacyRegistry
) {
@@ -50,17 +48,6 @@ define([
"telemetry"
],
"editable": false
},
{
"name": "Historical Imagery",
"key": "historical-imagery",
"cssClass": "icon-image",
"template": imageryTimelineTemplate,
"priority": "preferred",
"needs": [
"telemetry"
],
"editable": false
}
],
"policies": [

View File

@@ -1,5 +1,6 @@
<div class="t-imagery" ng-controller="ImageryController as imagery">
<div class="l-image-main-wrapper l-flex-col"
<mct-split-pane class='abs' anchor="bottom" alias="imagery">
<div class="split-pane-component l-image-main-wrapper l-flex-col"
ng-mouseenter="showLocalControls = true;"
ng-mouseleave="showLocalControls = false;">
<div class="l-local-controls s-local-controls s-wrapper-transluc l-flex-row"
@@ -32,12 +33,12 @@
</div>
<div class="l-image-main-controlbar flex-elem l-flex-row">
<div class="left flex-elem grows">
<div class="l-datetime-w flex-elem grows">
<a class="s-button show-thumbs sm hidden icon-thumbs-strip"
ng-click="showThumbsBubble = (showThumbsBubble) ? false:true"></a>
<span class="l-time">{{imagery.getTime()}}</span>
</div>
<div class="right flex-elem">
<div class="l-controls-w flex-elem">
<a class="s-button pause-play"
ng-click="imagery.paused(!imagery.paused())"
ng-class="{ paused: imagery.paused() }"></a>
@@ -55,4 +56,14 @@
</div>
</div>
</div>
<mct-splitter></mct-splitter>
<div class="split-pane-component l-image-thumbs-wrapper">
<div class="l-image-thumb-item" ng-class="{selected: image.selected}" ng-repeat="image in imageHistory track by $index"
ng-click="imagery.setSelectedImage(image)" ng-init="imagery.scrollToBottom()">
<img class="l-thumb"
ng-src={{imagery.getImageUrl(image)}}>
<div class="l-time">{{imagery.getTime(image)}}</div>
</div>
</div>
</mct-split-pane>
</div>

View File

@@ -1,8 +0,0 @@
<div class="l-image-thumbs-wrapper" ng-controller="ImageryController as imagery">
<div class="l-image-thumb-item" ng-repeat="image in imageHistory track by $index">
<img class="l-thumb" ng-init="imagery.scrollToRight()"
ng-src={{imagery.getImageUrl(image)}} >
<div class="l-time">{{imagery.getTime(image)}}</div>
</div>
</div>

View File

@@ -48,9 +48,8 @@ define(
this.zone = "";
this.imageUrl = "";
this.requestCount = 0;
this.scrollable = $(element[0]);
this.scrollable = $(".l-image-thumbs-wrapper");
this.autoScroll = openmct.time.clock() ? true : false;
this.$scope.imageHistory = [];
this.$scope.filters = {
brightness: 100,
@@ -63,6 +62,7 @@ define(
this.updateHistory = this.updateHistory.bind(this);
this.onBoundsChange = this.onBoundsChange.bind(this);
this.onScroll = this.onScroll.bind(this);
this.setSelectedImage = this.setSelectedImage.bind(this);
this.subscribe(this.$scope.domainObject);
@@ -80,10 +80,10 @@ define(
var metadata = this.openmct
.telemetry
.getMetadata(this.domainObject);
var timeKey = this.openmct.time.timeSystem().key;
this.timeKey = this.openmct.time.timeSystem().key;
this.timeFormat = this.openmct
.telemetry
.getValueFormatter(metadata.value(timeKey));
.getValueFormatter(metadata.value(this.timeKey));
this.imageFormat = this.openmct
.telemetry
.getValueFormatter(metadata.valuesForHints(['image'])[0]);
@@ -161,7 +161,7 @@ define(
/**
* Updates displayable values to match those of the most
* recently recieved datum.
* recently received datum.
* @param {object} [datum] the datum
* @private
*/
@@ -170,7 +170,6 @@ define(
this.nextDatum = datum;
return;
}
this.time = this.timeFormat.format(datum);
this.imageUrl = this.imageFormat.format(datum);
@@ -185,8 +184,7 @@ define(
ImageryController.prototype.updateHistory = function (datum) {
if (this.$scope.imageHistory.length === 0 ||
!_.isEqual(this.$scope.imageHistory.slice(-1)[0], datum)) {
var index = _.sortedIndex(this.$scope.imageHistory, datum, 'utc');
var index = _.sortedIndex(this.$scope.imageHistory, datum, this.timeFormat.format.bind(this.timeFormat));
this.$scope.imageHistory.splice(index, 0, datum);
return true;
}
@@ -196,8 +194,12 @@ define(
ImageryController.prototype.onScroll = function (event) {
this.$window.requestAnimationFrame(function () {
var thumbnailWrapperHeight = this.scrollable[0].offsetHeight;
var thumbnailWrapperWidth = this.scrollable[0].offsetWidth;
if (this.scrollable[0].scrollLeft <
(this.scrollable[0].scrollWidth - this.scrollable[0].clientWidth) - 20) {
(this.scrollable[0].scrollWidth - this.scrollable[0].clientWidth) - (thumbnailWrapperWidth) ||
this.scrollable[0].scrollTop <
(this.scrollable[0].scrollHeight - this.scrollable[0].clientHeight) - (thumbnailWrapperHeight)) {
this.autoScroll = false;
} else {
this.autoScroll = true;
@@ -205,12 +207,16 @@ define(
}.bind(this));
};
ImageryController.prototype.scrollToRight = function () {
/**
* Force history imagery div to scroll to bottom.
*/
ImageryController.prototype.scrollToBottom = function () {
if (this.autoScroll) {
this.scrollable[0].scrollLeft = this.scrollable[0].scrollWidth;
this.scrollable[0].scrollTop = this.scrollable[0].scrollHeight;
}
};
/**
* Get the time portion (hours, minutes, seconds) of the
* timestamp associated with the incoming image telemetry
@@ -243,16 +249,38 @@ define(
* @returns {boolean} the current state
*/
ImageryController.prototype.paused = function (state) {
if (arguments.length > 0 && state !== this.isPaused) {
this.isPaused = state;
if (this.nextDatum) {
this.updateValues(this.nextDatum);
delete this.nextDatum;
}
if (arguments.length > 0 && state !== this.isPaused) {
this.unselectAllImages();
this.isPaused = state;
if (this.nextDatum) {
this.updateValues(this.nextDatum);
delete this.nextDatum;
}
return this.isPaused;
};
this.autoScroll = true;
}
return this.isPaused;
};
/**
* Set the selected image on the state for the large imagery div to use.
* @param {object} [image] the image object to get url from.
*/
ImageryController.prototype.setSelectedImage = function (image) {
this.imageUrl = this.getImageUrl(image);
this.time = this.getTime(image);
this.paused(true);
this.unselectAllImages();
image.selected = true;
};
/**
* Loop through the history imagery data to set all images to unselected.
*/
ImageryController.prototype.unselectAllImages = function () {
for (var i = 0; i < this.$scope.imageHistory.length; i++) {
this.$scope.imageHistory[i].selected = false;
}
};
return ImageryController;
}
);

View File

@@ -226,6 +226,28 @@ define(
expect(controller.updateHistory(mockDatum)).toBe(false);
expect(controller.updateHistory(mockDatum)).toBe(false);
});
describe("user clicks on imagery thumbnail", function () {
var mockDatum = { utc: 1434600258123, url: 'some/url', selected: false};
it("pauses and adds selected class to imagery thumbnail", function () {
controller.setSelectedImage(mockDatum);
expect(controller.paused()).toBeTruthy();
expect(mockDatum.selected).toBeTruthy();
});
it("unselects previously selected image", function () {
$scope.imageHistory = [{ utc: 1434600258123, url: 'some/url', selected: true}];
controller.unselectAllImages();
expect($scope.imageHistory[0].selected).toBeFalsy();
});
it("updates larger image url and time", function () {
controller.setSelectedImage(mockDatum);
expect(controller.getImageUrl()).toEqual(controller.getImageUrl(mockDatum));
expect(controller.getTime()).toEqual(controller.timeFormat.format(mockDatum.utc));
});
});
});
it("initially shows an empty string for date/time", function () {

View File

@@ -21,7 +21,7 @@
-->
<div
class="l-fixed-position-text l-telemetry"
ng-style="{ background: ngModel.fill(), 'border-color': ngModel.stroke(), color: ngModel.color() }"
ng-style="{ background: ngModel.fill(), 'border-color': ngModel.stroke(), color: ngModel.color(), 'font-size': ngModel.size() }"
>
<span
class="l-elem l-value l-obj-val-format"

View File

@@ -21,7 +21,7 @@
-->
<div
class="l-fixed-position-text l-static-text"
ng-style="{ background: ngModel.fill(), 'border-color': ngModel.stroke(), color: ngModel.color() }"
ng-style="{ background: ngModel.fill(), 'border-color': ngModel.stroke(), color: ngModel.color(), 'font-size': ngModel.size() }"
>
{{ngModel.element.text}}
</div>

View File

@@ -23,7 +23,7 @@
<div class="abs object-browse-bar l-flex-row">
<div class="left flex-elem l-flex-row grows">
<mct-representation
key="'object-header'"
key="'object-header-frame'"
mct-object="domainObject"
class="l-flex-row flex-elem object-header grows">
</mct-representation>

View File

@@ -26,8 +26,12 @@
* @namespace platform/features/layout
*/
define(
['./LayoutDrag'],
function (LayoutDrag) {
[
'./LayoutDrag'
],
function (
LayoutDrag
) {
var DEFAULT_DIMENSIONS = [12, 8],
DEFAULT_GRID_SIZE = [32, 32],
@@ -124,6 +128,10 @@ define(
self.select(null, self.droppedIdToSelectAfterRefresh);
delete self.droppedIdToSelectAfterRefresh;
}
if (composition.indexOf(self.selectedId) === -1) {
self.clearSelection();
}
}
});
}

View File

@@ -58,6 +58,19 @@ define(
*/
proxy.text = new AccessorMutator(element, 'text');
/**
* Get and/or set the text size of this element.
*
* @param {string} [size] the new text size (if setting)
* @returns {string} the text size
* @memberof platform/features/layout.TextProxy#
*/
proxy.size = new AccessorMutator(element, 'size');
if (proxy.size() === undefined) {
proxy.size("13px");
}
return proxy;
}

View File

@@ -424,6 +424,17 @@ define(
expect(selectedObj.showFrame).toEqual(jasmine.any(Function));
});
it("deselects the object that is no longer in the composition", function () {
mockScope.$watchCollection.mostRecentCall.args[1]();
var childObj = mockCompositionObjects[0];
controller.select(mockEvent, childObj.getId());
var composition = ["b", "c"];
mockScope.$watchCollection.mostRecentCall.args[1](composition);
expect(controller.selected(childObj)).toBe(false);
});
});
}
);

View File

@@ -35,7 +35,8 @@ define(
y: 2,
width: 42,
height: 24,
fill: "transparent"
fill: "transparent",
size: "20px"
};
testElements = [{}, {}, testElement, {}];
proxy = new TextProxy(
@@ -50,6 +51,20 @@ define(
expect(proxy.fill('#FFF')).toEqual('#FFF');
expect(proxy.fill()).toEqual('#FFF');
});
it("provides getter/setter for text size", function () {
expect(proxy.size()).toEqual('20px');
expect(proxy.size('12px')).toEqual('12px');
expect(proxy.size()).toEqual('12px');
});
it("defaults to 13px for unspecified text size", function () {
testElement = {x: 1, y: 2};
proxy = new TextProxy(testElement, 0, [testElement]);
expect(proxy.size()).toEqual('13px');
});
});
}
);

View File

@@ -118,7 +118,10 @@ define([
"policies": [
{
"category": "view",
"implementation": PlotViewPolicy
"implementation": PlotViewPolicy,
"depends": [
"openmct"
]
}
],
"representations": [

View File

@@ -30,30 +30,32 @@ define(
* @constructor
* @memberof platform/features/plot
*/
function PlotViewPolicy() {
function PlotViewPolicy(openmct) {
this.openmct = openmct;
}
function hasNumericTelemetry(domainObject) {
var telemetry = domainObject &&
domainObject.getCapability('telemetry'),
metadata = telemetry ? telemetry.getMetadata() : {},
ranges = metadata.ranges || [];
PlotViewPolicy.prototype.hasNumericTelemetry = function (domainObject) {
var adaptedObject = domainObject.useCapability('adapter');
// Generally, we want to allow Plot for telemetry-providing
// objects (most telemetry is plottable.) We only want to
// suppress this for telemetry which only has explicitly
// non-numeric values.
return ranges.length === 0 || ranges.some(function (range) {
// Assume format is numeric if it is undefined
// (numeric telemetry is the common case)
return range.format === undefined ||
range.format === 'number';
});
}
if (!adaptedObject.telemetry) {
return domainObject.hasCapability('delegation') &&
domainObject.getCapability('delegation')
.doesDelegateCapability('telemetry');
}
var metadata = this.openmct.telemetry.getMetadata(adaptedObject);
var rangeValues = metadata.valuesForHints(['range']);
if (rangeValues.length === 0) {
return false;
}
return !rangeValues.every(function (value) {
return value.format === 'string';
});
};
PlotViewPolicy.prototype.allow = function (view, domainObject) {
if (view.key === 'plot') {
return hasNumericTelemetry(domainObject);
return this.hasNumericTelemetry(domainObject);
}
return true;

View File

@@ -27,51 +27,97 @@ define(
describe("Plot view policy", function () {
var testView,
mockDomainObject,
mockTelemetry,
testMetadata,
testAdaptedObject,
openmct,
telemetryMetadata,
policy;
beforeEach(function () {
testView = { key: "plot" };
testMetadata = {};
testAdaptedObject = { telemetry: {} };
mockDomainObject = jasmine.createSpyObj(
'domainObject',
['getId', 'getModel', 'getCapability']
['useCapability', 'hasCapability', 'getCapability']
);
mockTelemetry = jasmine.createSpyObj(
'telemetry',
['getMetadata']
);
mockDomainObject.getCapability.andCallFake(function (c) {
return c === 'telemetry' ? mockTelemetry : undefined;
mockDomainObject.useCapability.andReturn(testAdaptedObject);
openmct = {
telemetry: jasmine.createSpyObj('telemetryAPI', [
'getMetadata'
])
};
telemetryMetadata = jasmine.createSpyObj('telemetryMetadata', [
'valuesForHints'
]);
telemetryMetadata.valuesForHints.andReturn([]);
openmct.telemetry.getMetadata.andReturn(telemetryMetadata);
policy = new PlotViewPolicy(openmct);
});
it('fetches metadata from telem api', function () {
policy.allow(testView, mockDomainObject);
expect(mockDomainObject.useCapability)
.toHaveBeenCalledWith('adapter');
expect(openmct.telemetry.getMetadata)
.toHaveBeenCalledWith(testAdaptedObject);
expect(telemetryMetadata.valuesForHints)
.toHaveBeenCalledWith(['range']);
});
it('returns false if no ranges exist', function () {
telemetryMetadata.valuesForHints.andReturn([]);
expect(policy.allow(testView, mockDomainObject)).toBe(false);
});
it('returns true if any ranges exist', function () {
telemetryMetadata.valuesForHints.andReturn([{}]);
expect(policy.allow(testView, mockDomainObject)).toBe(true);
});
it('returns false if all ranges are strings', function () {
telemetryMetadata.valuesForHints.andReturn([{
format: 'string'
}, {
format: 'string'
}]);
expect(policy.allow(testView, mockDomainObject)).toBe(false);
});
it('returns true if only some ranges are strings', function () {
telemetryMetadata.valuesForHints.andReturn([{
format: 'string'
}, {}]);
expect(policy.allow(testView, mockDomainObject)).toBe(true);
});
it('returns true for telemetry delegators', function () {
delete testAdaptedObject.telemetry;
mockDomainObject.hasCapability.andCallFake(function (c) {
return c === 'delegation';
});
mockTelemetry.getMetadata.andReturn(testMetadata);
policy = new PlotViewPolicy();
mockDomainObject.getCapability.andReturn(
jasmine.createSpyObj('delegation', [
'doesDelegateCapability'
])
);
mockDomainObject.getCapability('delegation')
.doesDelegateCapability.andCallFake(function (c) {
return c === 'telemetry';
});
expect(policy.allow(testView, mockDomainObject)).toBe(true);
expect(openmct.telemetry.getMetadata).not.toHaveBeenCalled();
});
it("allows the imagery view for domain objects with numeric telemetry", function () {
testMetadata.ranges = [{ key: "foo", format: "number" }];
expect(policy.allow(testView, mockDomainObject)).toBeTruthy();
});
it("allows the imagery view for domain objects with unspecified telemetry", function () {
testMetadata.ranges = [{ key: "foo" }];
expect(policy.allow(testView, mockDomainObject)).toBeTruthy();
});
it("disallows the imagery view for domain objects without image telemetry", function () {
testMetadata.ranges = [{ key: "foo", format: "somethingElse" }];
expect(policy.allow(testView, mockDomainObject)).toBeFalsy();
it('returns true for non-telemetry non-delegators', function () {
delete testAdaptedObject.telemetry;
mockDomainObject.hasCapability.andReturn(false);
expect(policy.allow(testView, mockDomainObject)).toBe(false);
});
it("allows other views", function () {
testView.key = "somethingElse";
testMetadata.ranges = [{ key: "foo", format: "somethingElse" }];
expect(policy.allow(testView, mockDomainObject)).toBeTruthy();
expect(policy.allow(testView, mockDomainObject)).toBe(true);
});
});
}
);

View File

@@ -47,7 +47,7 @@ define([
"name": "Export as JSON",
"implementation": ExportAsJSONAction,
"category": "contextual",
"cssClass": "icon-save",
"cssClass": "icon-export",
"depends": [
"exportService",
"policyService",
@@ -59,7 +59,7 @@ define([
"name": "Import from JSON",
"implementation": ImportAsJSONAction,
"category": "contextual",
"cssClass": "icon-download",
"cssClass": "icon-import",
"depends": [
"exportService",
"identifierService",

View File

@@ -25,10 +25,12 @@
*/
define(
[
'../../../src/api/objects/object-utils'
'../../../src/api/objects/object-utils',
'lodash'
],
function (
objectUtils
objectUtils,
_
) {
var ZERO = function () {
@@ -189,14 +191,17 @@ define(
return fullRequest;
};
function asSeries(telemetry, defaultDomain, defaultRange, sourceMap) {
function getValue(index, key) {
return telemetry[index][sourceMap[key].source];
}
function asSeries(telemetry, defaultDomain, defaultRange) {
return {
getRangeValue: function (index, range) {
return telemetry[index][range || defaultRange];
return getValue(index, range || defaultRange);
},
getDomainValue: function (index, domain) {
return telemetry[index][domain || defaultDomain];
return getValue(index, domain || defaultDomain);
},
getPointCount: function () {
return telemetry.length;
@@ -223,9 +228,11 @@ define(
var telemetryAPI = this.openmct.telemetry;
var metadata = telemetryAPI.getMetadata(domainObject);
var defaultDomain = metadata.valuesForHints(['domain'])[0].source;
var defaultDomain = metadata.valuesForHints(['domain'])[0].key;
var defaultRange = metadata.valuesForHints(['range'])[0];
defaultRange = defaultRange ? defaultRange.source : undefined;
defaultRange = defaultRange ? defaultRange.key : undefined;
var sourceMap = _.indexBy(metadata.values(), 'key');
var isLegacyProvider = telemetryAPI.findRequestProvider(domainObject) ===
telemetryAPI.legacyProvider;
@@ -250,7 +257,7 @@ define(
requestTelemetryFromService().then(getRelevantResponse);
} else {
return telemetryAPI.request(domainObject, fullRequest).then(function (telemetry) {
return asSeries(telemetry, defaultDomain, defaultRange);
return asSeries(telemetry, defaultDomain, defaultRange, sourceMap);
});
}
};
@@ -286,15 +293,17 @@ define(
var telemetryAPI = this.openmct.telemetry;
var metadata = telemetryAPI.getMetadata(domainObject);
var defaultDomain = metadata.valuesForHints(['domain'])[0].source;
var defaultDomain = metadata.valuesForHints(['domain'])[0].key;
var defaultRange = metadata.valuesForHints(['range'])[0];
defaultRange = defaultRange ? defaultRange.source : undefined;
defaultRange = defaultRange ? defaultRange.key : undefined;
var sourceMap = _.indexBy(metadata.values(), 'key');
var isLegacyProvider = telemetryAPI.findSubscriptionProvider(domainObject) ===
telemetryAPI.legacyProvider;
function update(telemetry) {
callback(asSeries([telemetry], defaultDomain, defaultRange));
callback(asSeries([telemetry], defaultDomain, defaultRange, sourceMap));
}
// Unpack the relevant telemetry series

View File

@@ -34,6 +34,7 @@ define(
mockUnsubscribe,
telemetry,
mockTelemetryAPI,
mockMetadata,
mockAPI;
function mockPromise(value) {
@@ -90,14 +91,23 @@ define(
"findRequestProvider",
"findSubscriptionProvider"
]);
mockTelemetryAPI.getMetadata.andReturn({
valuesForHints: function (hint) {
var metadatum = {};
metadatum[hint] = "foo";
return [metadatum];
}
mockMetadata = jasmine.createSpyObj('telemetryMetadata', [
'valuesForHints',
'values'
]);
mockMetadata.valuesForHints.andCallFake(function (hints) {
var hint = hints[0];
var metadatum = {
key: 'default' + hint
};
metadatum[hint] = "foo";
return [metadatum];
});
mockTelemetryAPI.getMetadata.andReturn(mockMetadata);
mockAPI = {
telemetry: mockTelemetryAPI,
time: {
@@ -150,8 +160,8 @@ define(
key: "testKey", // from model
start: 42, // from argument
domain: 'mockTimeSystem',
domains: [{ domain: "foo" }],
ranges: [{ range: "foo" }]
domains: [{ domain: "foo", key: 'defaultdomain' }],
ranges: [{ range: "foo", key: 'defaultrange' }]
}]);
});
@@ -172,8 +182,8 @@ define(
start: 0,
end: 1,
domain: 'mockTimeSystem',
domains: [{ domain: "foo" }],
ranges: [{ range: "foo" }]
domains: [{ domain: "foo", key: 'defaultdomain' }],
ranges: [{ range: "foo", key: 'defaultrange' }]
});
});
@@ -191,8 +201,8 @@ define(
start: 0,
end: 1,
domain: 'mockTimeSystem',
domains: [{ domain: "foo" }],
ranges: [{ range: "foo" }]
domains: [{ domain: "foo", key: 'defaultdomain' }],
ranges: [{ range: "foo", key: 'defaultrange' }]
});
});
@@ -240,6 +250,21 @@ define(
var mockProvider = {};
var dunzo = false;
mockMetadata.values.andReturn([
{
key: 'defaultrange',
source: 'prop1'
},
{
key: 'defaultdomain',
source: 'prop2'
},
{
key: 'prop3',
source: 'prop3'
}
]);
mockTelemetryAPI.findRequestProvider.andReturn(mockProvider);
mockTelemetryAPI.request.andReturn(Promise.resolve(mockTelemetry));
@@ -257,6 +282,18 @@ define(
expect(returnedTelemetry.getDomainValue).toBeDefined();
expect(returnedTelemetry.getRangeValue).toBeDefined();
expect(returnedTelemetry.getPointCount()).toBe(2);
// Default domain + remap should work.
expect(returnedTelemetry.getDomainValue(0)).toBe('val2');
expect(returnedTelemetry.getDomainValue(1)).toBe('val5');
// explicit domain should work
expect(returnedTelemetry.getDomainValue(0, 'prop3')).toBe('val3');
expect(returnedTelemetry.getDomainValue(1, 'prop3')).toBe('val6');
// default range + remap should work
expect(returnedTelemetry.getRangeValue(0)).toBe('val1');
expect(returnedTelemetry.getRangeValue(1)).toBe('val4');
// explicit range should work
expect(returnedTelemetry.getRangeValue(0, 'prop3')).toBe('val3');
expect(returnedTelemetry.getRangeValue(1, 'prop3')).toBe('val6');
});
});
@@ -275,8 +312,8 @@ define(
start: 0,
end: 1,
domain: 'mockTimeSystem',
domains: [{ domain: "foo" }],
ranges: [{ range: "foo" }]
domains: [{ domain: "foo", key: "defaultdomain" }],
ranges: [{ range: "foo", key: "defaultrange" }]
}]
);

View File

@@ -1,7 +0,0 @@
/**
* Open MCT https://nasa.github.io/openmct/
* Version: ${version}
* Built: ${timestamp}
* Revision: ${revision}
* Branch: ${branch}
*/

View File

@@ -33,6 +33,7 @@ define([
link: function (scope, element, attrs) {
var region = new Region(element[0]);
scope.$watch(attrs.mctView, region.show.bind(region));
scope.$on("$destroy", region.clear.bind(region));
}
};
}

View File

@@ -0,0 +1,45 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define([
], function (
) {
return function (buildInfo) {
return function (openmct) {
var aliases = { timestamp: "Built" };
var descriptions = {
timestamp: "The date on which this version of Open MCT was built.",
revision: "A unique revision identifier for the client sources.",
branch: "The name of the branch that was used during the build."
};
Object.keys(buildInfo).forEach(function (key) {
openmct.legacyExtension("versions", {
key: key,
name: aliases[key] || (key.charAt(0).toUpperCase() + key.substring(1)),
value: buildInfo[key],
description: descriptions[key]
});
});
};
};
});

View File

@@ -0,0 +1,50 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define([
'./plugin'
], function (plugin) {
describe("The buildInfo plugin", function () {
var mockmct;
var testInfo;
beforeEach(function () {
mockmct = jasmine.createSpyObj('openmct', ['legacyExtension']);
testInfo = { foo: 123, bar: "baz" };
plugin(testInfo)(mockmct);
});
it("registers versions extensions", function () {
Object.keys(testInfo).forEach(function (key) {
expect(mockmct.legacyExtension).toHaveBeenCalledWith(
"versions",
{
key: key,
name: jasmine.any(String),
value: testInfo[key],
description: undefined
}
);
});
});
});
});

View File

@@ -37,8 +37,7 @@ define(['EventEmitter'], function (EventEmitter) {
this.key = 'local';
this.cssClass = 'icon-clock';
this.name = 'Local Clock';
this.description = "Updates every second, providing UTC timestamps from " +
"user's local computer.";
this.description = "Provides UTC timestamps every second from the local system clock.";
this.period = period;
this.timeoutHandle = undefined;

View File

@@ -18,6 +18,14 @@
* 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.
*
* Open MCT https://nasa.github.io/openmct/
* Version: @@version
* Built: @@timestamp
* Revision: @@revision
* Branch: @@branch
*
* @preserve
*****************************************************************************/
(function (root, factory) {
@@ -29,3 +37,9 @@
root.openmct = factory();
}
}(this, function() {
var BUILD_CONSTANTS = {
version: "@@version",
timestamp: "@@timestamp",
revision: "@@revision",
branch: "@@branch"
};