Merged changes from Master

This commit is contained in:
Henry 2015-12-01 10:44:42 -08:00
commit 73ca30e654
404 changed files with 37614 additions and 6952 deletions

2
.gitignore vendored
View File

@ -28,3 +28,5 @@ node_modules
# Protractor logs # Protractor logs
protractor/logs protractor/logs
# npm-debug log
npm-debug.log

View File

@ -345,6 +345,41 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
--- ---
### moment-duration-format
#### Info
* Link: https://github.com/jsmreese/moment-duration-format
* Version: 1.3.0
* Authors: John Madhavan-Reese
* Description: Duration parsing/formatting
#### License
Copyright 2014 John Madhavan-Reese
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
### Json.NET ### Json.NET
#### Info #### Info

View File

@ -1 +1 @@
web: node app.js --port $PORT --include example/localstorage web: node app.js --port $PORT

View File

@ -6,27 +6,33 @@
"platform/commonUI/browse", "platform/commonUI/browse",
"platform/commonUI/edit", "platform/commonUI/edit",
"platform/commonUI/dialog", "platform/commonUI/dialog",
"platform/commonUI/formats",
"platform/commonUI/general", "platform/commonUI/general",
"platform/commonUI/inspect", "platform/commonUI/inspect",
"platform/commonUI/mobile", "platform/commonUI/mobile",
"platform/commonUI/themes/espresso", "platform/commonUI/themes/espresso",
"platform/commonUI/notification",
"platform/containment", "platform/containment",
"platform/execution", "platform/execution",
"platform/telemetry", "platform/telemetry",
"platform/features/clock",
"platform/features/events",
"platform/features/imagery", "platform/features/imagery",
"platform/features/layout", "platform/features/layout",
"platform/features/pages", "platform/features/pages",
"platform/features/plot", "platform/features/plot",
"platform/features/scrolling", "platform/features/scrolling",
"platform/features/events", "platform/features/timeline",
"platform/features/conductor", "platform/features/conductor",
"platform/forms", "platform/forms",
"platform/identity", "platform/identity",
"platform/persistence/aggregator",
"platform/persistence/local", "platform/persistence/local",
"platform/persistence/queue", "platform/persistence/queue",
"platform/policy", "platform/policy",
"platform/entanglement", "platform/entanglement",
"platform/search", "platform/search",
"platform/status",
"example/imagery", "example/imagery",
"example/eventGenerator", "example/eventGenerator",

9
docs/footer.html Normal file
View File

@ -0,0 +1,9 @@
<hr>
<cite>
This document is styled using
<a href="https://github.com/jasonm23/markdown-css-themes">
https://github.com/jasonm23/markdown-css-themes
</a>.
</cite>
</body>
</html>

View File

@ -20,7 +20,7 @@
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global require,process,GLOBAL*/ /*global require,process,__dirname,GLOBAL*/
/*jslint nomen: false */ /*jslint nomen: false */
@ -30,7 +30,8 @@
var CONSTANTS = { var CONSTANTS = {
DIAGRAM_WIDTH: 800, DIAGRAM_WIDTH: 800,
DIAGRAM_HEIGHT: 500 DIAGRAM_HEIGHT: 500
}; },
TOC_HEAD = "# Table of Contents";
GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be defined GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be defined
(function () { (function () {
@ -44,7 +45,10 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define
split = require("split"), split = require("split"),
stream = require("stream"), stream = require("stream"),
nomnoml = require('nomnoml'), nomnoml = require('nomnoml'),
toc = require("markdown-toc"),
Canvas = require('canvas'), Canvas = require('canvas'),
header = fs.readFileSync(path.resolve(__dirname, 'header.html')),
footer = fs.readFileSync(path.resolve(__dirname, 'footer.html')),
options = require("minimist")(process.argv.slice(2)); options = require("minimist")(process.argv.slice(2));
// Convert from nomnoml source to a target PNG file. // Convert from nomnoml source to a target PNG file.
@ -110,9 +114,12 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define
done(); done();
}; };
transform._flush = function (done) { transform._flush = function (done) {
this.push("<html><body>\n"); // Prepend table of contents
markdown =
[ TOC_HEAD, toc(markdown).content, "", markdown ].join("\n");
this.push(header);
this.push(marked(markdown)); this.push(marked(markdown));
this.push("\n</body></html>\n"); this.push(footer);
done(); done();
}; };
return transform; return transform;
@ -133,8 +140,8 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define
customRenderer.link = function (href, title, text) { customRenderer.link = function (href, title, text) {
// ...but only if they look like relative paths // ...but only if they look like relative paths
return (href || "").indexOf(":") === -1 && href[0] !== "/" ? return (href || "").indexOf(":") === -1 && href[0] !== "/" ?
renderer.link(href.replace(/\.md/, ".html"), title, text) : renderer.link(href.replace(/\.md/, ".html"), title, text) :
renderer.link.apply(renderer, arguments); renderer.link.apply(renderer, arguments);
}; };
return customRenderer; return customRenderer;
} }
@ -179,13 +186,17 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define
glob(options['in'] + "/**/*.@(html|css|png)", {}, function (err, files) { glob(options['in'] + "/**/*.@(html|css|png)", {}, function (err, files) {
files.forEach(function (file) { files.forEach(function (file) {
var destination = file.replace(options['in'], options.out), var destination = file.replace(options['in'], options.out),
destPath = path.dirname(destination); destPath = path.dirname(destination),
streamOptions = {};
if (file.match(/png$/)) {
streamOptions.encoding = null;
} else {
streamOptions.encoding = 'utf8';
}
mkdirp(destPath, function (err) { mkdirp(destPath, function (err) {
fs.createReadStream(file, { encoding: 'utf8' }) fs.createReadStream(file, streamOptions)
.pipe(fs.createWriteStream(destination, { .pipe(fs.createWriteStream(destination, streamOptions));
encoding: 'utf8'
}));
}); });
}); });
}); });

7
docs/header.html Normal file
View File

@ -0,0 +1,7 @@
<html>
<head>
<link rel="stylesheet"
href="http://jasonm23.github.io/markdown-css-themes/avenir-white.css">
</head>
<body>

View File

@ -58,13 +58,13 @@ of the software.
These layers are: These layers are:
* [_Framework_](Framework.md): The framework layer is responsible for * [_Framework_](framework.md): The framework layer is responsible for
managing the interactions between application components. It has no managing the interactions between application components. It has no
application-specific knowledge; at this layer, we have only application-specific knowledge; at this layer, we have only
established an abstraction by which different software components established an abstraction by which different software components
may communicate and/or interact. may communicate and/or interact.
* [_Platform_](Platform.md): The platform layer defines the general look, feel, and * [_Platform_](platform.md): The platform layer defines the general look,
behavior of Open MCT Web. This includes user-facing components like feel, and behavior of Open MCT Web. This includes user-facing components like
Browse mode and Edit mode, as well as underlying elements of the Browse mode and Edit mode, as well as underlying elements of the
information model and the general service infrastructure. information model and the general service infrastructure.
* _Application_: The application layer defines specific features of * _Application_: The application layer defines specific features of

View File

@ -35,16 +35,26 @@ in __any of these tiers__.
* _DOM_: The rendered HTML document, composed from HTML templates which * _DOM_: The rendered HTML document, composed from HTML templates which
have been processed by AngularJS and will be updated by AngularJS have been processed by AngularJS and will be updated by AngularJS
to reflect changes from the presentation layer. User interactions to reflect changes from the presentation layer. User interactions
are initiated from here and invoke behavior in the presentation layer. are initiated from here and invoke behavior in the presentation layer. HTML 
templates are written in Angulars template syntax; see the [Angular documentation on templates](https://docs.angularjs.org/guide/templates). 
These describe the page as actually seen by the user. Conceptually, 
stylesheets (controlling the look­and­feel of the rendered templates) belong 
in this grouping as well. 
* [_Presentation layer_](#presentation-layer): The presentation layer * [_Presentation layer_](#presentation-layer): The presentation layer
is responsible for updating (and providing information to update) is responsible for updating (and providing information to update)
the displayed state of the application. The presentation layer consists the displayed state of the application. The presentation layer consists
primarily of _controllers_ and _directives_. The presentation layer is primarily of _controllers_ and _directives_. The presentation layer is
concerned with inspecting the information model and preparing it for concerned with inspecting the information model and preparing it for
display. display.
* [_Information model_](#information-model): The information model * [_Information model_](#information-model): Provides a common (within Open MCT 
describes the state and behavior of the objects with which the user Web) set of interfaces for dealing with “things” ­ domain objects ­ within the 
interacts. system. User­facing concerns in a Open MCT Web application are expressed as 
domain objects; examples include folders (used to organize other domain 
objects), layouts (used to build displays), or telemetry points (used as 
handles for streams of remote measurements.) These domain objects expose a 
common set of interfaces to allow reusable user interfaces to be built in the 
presentation and template tiers; the specifics of these behaviors are then 
mapped to interactions with underlying services. 
* [_Service infrastructure_](#service-infrastructure): The service * [_Service infrastructure_](#service-infrastructure): The service
infrastructure is responsible for providing the underlying general infrastructure is responsible for providing the underlying general
functionality needed to support the information model. This includes functionality needed to support the information model. This includes
@ -52,7 +62,9 @@ in __any of these tiers__.
back-end. back-end.
* _Back-end_: The back-end is out of the scope of Open MCT Web, except * _Back-end_: The back-end is out of the scope of Open MCT Web, except
for the interfaces which are utilized by adapters participating in the for the interfaces which are utilized by adapters participating in the
service infrastructure. service infrastructure. Includes the underlying persistence stores, telemetry 
streams, and so forth which the Open MCT Web client is being used to interact 
with.
## Application Start-up ## Application Start-up

File diff suppressed because it is too large Load Diff

View File

@ -29,8 +29,10 @@
Sections: Sections:
<ul> <ul>
<li><a href="api/">API</a></li> <li><a href="api/">API</a></li>
<li><a href="guide/">Developer Guide</a></li>
<li><a href="architecture/">Architecture Overview</a></li> <li><a href="architecture/">Architecture Overview</a></li>
<li><a href="guide/">Developer Guide</a></li>
<li><a href="tutorials/">Tutorials</a></li>
<li><a href="process/">Development Process</a></li>
</ul> </ul>
</body> </body>
</html> </html>

156
docs/src/process/index.md Normal file
View File

@ -0,0 +1,156 @@
# Development Cycle
Development of Open MCT Web occurs on an iterative cycle of
sprints and releases.
* A _sprint_ is three weeks in duration, and represents a
set of improvements that can be completed and tested by the
development team. Software at the end of the sprint is
"semi-stable"; it will have undergone reduced testing and may carry
defects or usability issues of lower severity, particularly if
there are workarounds.
* A _release_ occurs every four sprints. Releases are stable, and
will have undergone full acceptance testing to ensure that the
software behaves correctly and usably.
## Roles
The sprint process assumes the presence of a __project manager.__
The project manager is responsible for
making tactical decisions about what development work will be
performed, and for coordinating with stakeholders to arrive at
higher-level strategic decisions about desired functionality
and characteristics of the software, major external milestones,
and so forth.
In the absence of a dedicated project manager, this role may be rotated
among members of the development team on a per-sprint basis.
Responsibilities of the project manager including:
* Maintaining (with agreement of stakeholders) a "road map" of work
planned for future releases/sprints; this should be higher-level,
usually expressed as "themes",
with just enough specificity to gauge feasibility of plans,
relate work back to milestones, and identify longer-term
dependencies.
* Determining (with assistance from the rest of the team) which
issues to work on in a given sprint and how they shall be
assigned.
* Pre-planning subsequent sprints to ensure that all members of the
team always have a clear direction.
* Scheduling and/or ensuring adherence to
[process points](#process-points).
* Responding to changes within the sprint (shifting priorities,
new issues) and re-allocating work for the sprint as needed.
## Sprint Calendar
Certain [process points](#process-points) are regularly scheduled in
the sprint cycle.
### Sprints by Release
Allocation of work among sprints should be planned relative to release
goals and milestones. As a general guideline, higher-risk work (large
new features which may carry new defects, major refactoring, design
changes with uncertain effects on usability) should be allocated to
earlier sprints, allowing for time in later sprints to ensure stability.
| Sprint | Focus |
|:------:|:--------------------------------------------------------|
| __1__ | Prototyping, design, experimentation. |
| __2__ | New features, refinements, enhancements. |
| __3__ | Feature completion, low-risk enhancements, bug fixing. |
| __4__ | Stability & quality assurance. |
### Sprints 1-3
The first three sprints of a release are primarily centered around
development work, with regular acceptance testing in the third
week. During this third week, the top priority should be passing
acceptance testing (e.g. by resolving any blockers found); any
resources not needed for this effort should be used to begin work
for the subsequent sprint.
| Week | Mon | Tue | Wed | Thu | Fri |
|:-----:|:-------------------------:|:------:|:---:|:----------------------------:|:-----------:|
| __1__ | Sprint plan | Tag-up | | | |
| __2__ | | Tag-up | | | Code freeze |
| __3__ | Sprint acceptance testing | Triage | | _Sprint acceptance testing*_ | Ship |
&ast; If necessary.
### Sprint 4
The software must be stable at the end of the fourth sprint; because of
this, the fourth sprint is scheduled differently, with a heightened
emphasis on testing.
| Week | Mon | Tue | Wed | Thu | Fri |
|-------:|:-------------------------:|:------:|:---:|:----------------------------:|:-----------:|
| __1__ | Sprint plan | Tag-up | | | Code freeze |
| __2__ | Acceptance testing | Triage | | | |
| __3__ | _Acceptance testing*_ | Triage | | _Acceptance testing*_ | Ship |
&ast; If necessary.
## Process Points
* __Sprint plan.__ Project manager allocates issues based on
theme(s) for sprint, then reviews with team. Each team member
should have roughly two weeks of work allocated (to allow time
in the third week for testing of work completed.)
* Project manager should also sketch out subsequent sprint so
that team may begin work for that sprint during the
third week, since testing and blocker resolution is unlikely
to require all available resources.
* __Tag-up.__ Check in and status update among development team.
May amend plan for sprint as-needed.
* __Code freeze.__ Any new work from this sprint
(features, bug fixes, enhancements) must be integrated by the
end of the second week of the sprint. After code freeze
(and until the end of the sprint) the only changes that should be
merged into the master branch should directly address issues
needed to pass acceptance testing.
* __Acceptance Testing.__ Structured testing with predefined
success criteria. No release should ship without passing
acceptance tests. Time is allocated in each sprint for subsequent
rounds of acceptance testing if issues are identified during a
prior round. Specific details of acceptance testing need to be
agreed-upon with relevant stakeholders and delivery recipients,
and should be flexible enough to allow changes to plans
(e.g. deferring delivery of some feature in order to ensure
stability of other features.) Baseline testing includes:
* __Testathon.__ Multi-user testing, involving as many users as
is feasible, plus development team. Open-ended; should verify
completed work from this sprint, test exploratorily for
regressions, et cetera.
* __24-Hour Test.__ A test to verify that the software remains
stable after running for longer durations. May include some
combination of automated testing and user verification (e.g.
checking to verify that software remains subjectively
responsive at conclusion of test.)
* __Automated Testing.__ Automated testing integrated into the
build. (These tests are verified to pass more often than once
per sprint, as they run before any merge to master, but still
play an important role in acceptance testing.)
* __Sprint Acceptance Testing.__ Subset of Acceptance Testing
which should be performed before shipping at the end of any
sprint. Time is allocated for a second round of
Sprint Acceptance Testing if the first round is not passed.
* __Triage.__ Team reviews issues from acceptance testing and uses
success criteria to determine whether or not they should block
release, then formulates a plan to address these issues before
the next round of acceptance testing. Focus here should be on
ensuring software passes that testing in order to ship on time;
may prefer to disable malfunctioning components and fix them
in a subsequent sprint, for example.
* __Ship.__ Tag a code snapshot that has passed acceptance
testing and deploy that version. (Only true if acceptance
testing has passed by this point; if acceptance testing has not
been passed, will need to make ad hoc decisions with stakeholders,
e.g. "extend the sprint" or "defer shipment until end of next
sprint.")

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

3122
docs/src/tutorials/index.md Normal file

File diff suppressed because it is too large Load Diff

View File

@ -16,6 +16,23 @@
"implementation": "SinewaveLimitCapability.js" "implementation": "SinewaveLimitCapability.js"
} }
], ],
"formats": [
{
"key": "example.delta",
"implementation": "SinewaveDeltaFormat.js"
}
],
"constants": [
{
"key": "TIME_CONDUCTOR_DOMAINS",
"value": [
{ "key": "time", "name": "Time" },
{ "key": "yesterday", "name": "Yesterday" },
{ "key": "delta", "name": "Delta", "format": "example.delta" }
],
"priority": -1
}
],
"types": [ "types": [
{ {
"key": "generator", "key": "generator",
@ -38,6 +55,11 @@
{ {
"key": "yesterday", "key": "yesterday",
"name": "Yesterday" "name": "Yesterday"
},
{
"key": "delta",
"name": "Delta",
"format": "example.delta"
} }
], ],
"ranges": [ "ranges": [

View File

@ -19,18 +19,8 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
// Styles to temporarily hide non-functional elements /*global define,Promise*/
/******************************** BROWSE */ define({
.browse-mode { START_TIME: Date.now() - 24 * 60 * 60 * 1000 // Now minus a day.
.browse { });
&.top-bar {
display: none;
}
}
.browse-area.holder {
// When .browse.top-bar is hidden, set the top of the browse-area holder
top: $bodyMargin;
}
}

View 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,Promise*/
define(
['./SinewaveConstants', 'moment'],
function (SinewaveConstants, moment) {
"use strict";
var START_TIME = SinewaveConstants.START_TIME,
FORMAT_REGEX = /^-?\d+:\d+:\d+$/,
SECOND = 1000,
MINUTE = SECOND * 60,
HOUR = MINUTE * 60;
function SinewaveDeltaFormat() {
}
function twoDigit(v) {
return v >= 10 ? String(v) : ('0' + v);
}
SinewaveDeltaFormat.prototype.format = function (value) {
var delta = Math.abs(value - START_TIME),
negative = value < START_TIME,
seconds = Math.floor(delta / SECOND) % 60,
minutes = Math.floor(delta / MINUTE) % 60,
hours = Math.floor(delta / HOUR);
return (negative ? "-" : "") +
[ hours, minutes, seconds ].map(twoDigit).join(":");
};
SinewaveDeltaFormat.prototype.validate = function (text) {
return FORMAT_REGEX.test(text);
};
SinewaveDeltaFormat.prototype.parse = function (text) {
var negative = text[0] === "-",
parts = text.replace("-", "").split(":");
return [ HOUR, MINUTE, SECOND ].map(function (sz, i) {
return parseInt(parts[i], 10) * sz;
}).reduce(function (a, b) {
return a + b;
}, 0) * (negative ? -1 : 1) + START_TIME;
};
return SinewaveDeltaFormat;
}
);

View File

@ -30,25 +30,25 @@ define(
YELLOW = 0.5, YELLOW = 0.5,
LIMITS = { LIMITS = {
rh: { rh: {
cssClass: "s-limit-upr-red", cssClass: "s-limit-upr s-limit-red",
low: RED, low: RED,
high: Number.POSITIVE_INFINITY, high: Number.POSITIVE_INFINITY,
name: "Red High" name: "Red High"
}, },
rl: { rl: {
cssClass: "s-limit-lwr-red", cssClass: "s-limit-lwr s-limit-red",
high: -RED, high: -RED,
low: Number.NEGATIVE_INFINITY, low: Number.NEGATIVE_INFINITY,
name: "Red Low" name: "Red Low"
}, },
yh: { yh: {
cssClass: "s-limit-upr-yellow", cssClass: "s-limit-upr s-limit-yellow",
low: YELLOW, low: YELLOW,
high: RED, high: RED,
name: "Yellow High" name: "Yellow High"
}, },
yl: { yl: {
cssClass: "s-limit-lwr-yellow", cssClass: "s-limit-lwr s-limit-yellow",
low: -RED, low: -RED,
high: -YELLOW, high: -YELLOW,
name: "Yellow Low" name: "Yellow Low"

View File

@ -25,12 +25,12 @@
* Module defining SinewaveTelemetry. Created by vwoeltje on 11/12/14. * Module defining SinewaveTelemetry. Created by vwoeltje on 11/12/14.
*/ */
define( define(
[], ['./SinewaveConstants'],
function () { function (SinewaveConstants) {
"use strict"; "use strict";
var ONE_DAY = 60 * 60 * 24, var ONE_DAY = 60 * 60 * 24,
firstObservedTime = Math.floor(Date.now() / 1000) - ONE_DAY; firstObservedTime = Math.floor(SinewaveConstants.START_TIME / 1000);
/** /**
* *
@ -58,8 +58,11 @@ define(
}; };
generatorData.getDomainValue = function (i, domain) { generatorData.getDomainValue = function (i, domain) {
// delta uses the same numeric values as the default domain,
// so it's not checked for here, just formatted for display
// differently.
return (i + offset) * 1000 + firstTime * 1000 - return (i + offset) * 1000 + firstTime * 1000 -
(domain === 'yesterday' ? ONE_DAY : 0); (domain === 'yesterday' ? (ONE_DAY * 1000) : 0);
}; };
generatorData.getRangeValue = function (i, range) { generatorData.getRangeValue = function (i, range) {

View File

@ -0,0 +1,12 @@
{
"name": "Mobile",
"description": "Allows elements with pertinence to mobile usage and development",
"extensions": {
"stylesheets": [
{
"stylesheetUrl": "css/mobile-example.css",
"priority": "mandatory"
}
]
}
}

26
example/mobile/res/config.rb Executable file
View File

@ -0,0 +1,26 @@
# Require any additional compass plugins here.
# require "compass-growl"
# Set this to the root of your project when deployed:
http_path = "/"
css_dir = "css"
sass_dir = "sass"
images_dir = "images"
javascripts_dir = "js"
# You can select your preferred output style here (can be overridden via the command line):
# :expanded, :compressed, :nested
output_style = :nested
# To enable relative paths to assets via compass helper functions. Uncomment:
relative_assets = true
# To disable debugging comments that display the original location of your selectors. Uncomment:
# line_comments = false
# If you prefer the indented syntax, you might want to regenerate this
# project again passing --syntax sass, or you can uncomment this:
# preferred_syntax = :sass
# and then run:
# sass-convert -R --from scss --to sass vfn_platform/static/sass scss && rm -rf sass && mv scss sass

View 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.
*****************************************************************************/
/*****************************************************************************
* 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.
*****************************************************************************/
/************************** FEATURES */
/************************** VERY INFLUENTIAL GLOBAL DIMENSIONS */
/************************** RATIOS */
/************************** LAYOUT */
/************************** CONTROLS */
/************************** PATHS */
/************************** TIMINGS */
/************************** LIMITS */
/*****************************************************************************
* 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.
*****************************************************************************/
/************************** MOBILE REPRESENTATION ITEMS DIMENSIONS */
/************************** MOBILE TREE MENU DIMENSIONS */
/************************** WINDOW DIMENSIONS FOR RWD */
/************************** MEDIA QUERIES: WINDOW CHECKS FOR SPECIFIC ORIENTATIONS FOR EACH DEVICE */
/************************** MEDIA QUERIES: WINDOWS FOR SPECIFIC ORIENTATIONS FOR EACH DEVICE */
/************************** DEVICE PARAMETERS FOR MENUS/REPRESENTATIONS */
/*****************************************************************************
* 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.
*****************************************************************************/
/* REQUIRES mobile/_constants */
@media screen and (orientation: portrait) and (max-width: 514px) and (max-height: 740px) and (max-device-width: 799px) and (max-device-height: 1024px), screen and (orientation: landscape) and (max-height: 514px) and (max-width: 740px) and (max-device-width: 799px) and (max-device-height: 1024px), screen and (orientation: landscape) and (max-height: 514px) and (max-width: 740px) and (max-device-width: 1024px) and (max-device-height: 799px), screen and (orientation: portrait) and (min-width: 515px) and (max-width: 799px) and (min-height: 741px) and (max-height: 1024px) and (max-device-width: 799px) and (max-device-height: 1024px), screen and (orientation: landscape) and (min-height: 515px) and (max-height: 799px) and (min-width: 741px) and (max-width: 1024px) and (max-device-width: 799px) and (max-device-height: 1024px), screen and (orientation: landscape) and (min-height: 515px) and (max-height: 799px) and (min-width: 741px) and (max-width: 1024px) and (max-device-width: 1024px) and (max-device-height: 799px) {
/* line 28, ../sass/mobile-example.scss */
.create-btn-holder {
display: block !important; } }

View File

@ -0,0 +1,31 @@
/*****************************************************************************
* 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.
*****************************************************************************/
@import "../../../../platform/commonUI/general/res/sass/constants";
@import "../../../../platform/commonUI/general/res/sass/mobile/constants";
@import "../../../../platform/commonUI/general/res/sass/mobile/mixins";
@include phoneandtablet {
// Show the Create button
.create-btn-holder {
display: block !important;
}
}

View File

@ -0,0 +1,47 @@
{
"extensions": {
"templates": [
{
"key": "dialogLaunchTemplate",
"templateUrl": "dialog-launch.html"
},
{
"key": "notificationLaunchTemplate",
"templateUrl": "notification-launch.html"
}
],
"controllers": [
{
"key": "DialogLaunchController",
"implementation": "DialogLaunchController.js",
"depends": [
"$scope",
"$timeout",
"$log",
"dialogService",
"notificationService"
]
},
{
"key": "NotificationLaunchController",
"implementation": "NotificationLaunchController.js",
"depends": [
"$scope",
"$timeout",
"$log",
"notificationService"
]
}
],
"indicators": [
{
"implementation": "DialogLaunchIndicator.js",
"priority": "fallback"
},
{
"implementation": "NotificationLaunchIndicator.js",
"priority": "fallback"
}
]
}
}

View File

@ -0,0 +1,10 @@
<span class="status block ok" ng-controller="DialogLaunchController">
<span class="ui-symbol status-indicator">&#xe600;</span>
<span class="label">
<a ng-click="launchProgress(true)">Known</a> |
<a ng-click="launchProgress(false)">Unknown</a> |
<a ng-click="launchError()">Error</a> |
<a ng-click="launchInfo()">Info</a>
</span>
<span class="count">Dialogs</span>
</span>

View File

@ -0,0 +1,10 @@
<span class="status block ok" ng-controller="NotificationLaunchController">
<span class="ui-symbol status-indicator">&#xe600;</span>
<span class="label">
<a ng-click="newInfo()">Success</a> |
<a ng-click="newError()">Error</a> |
<a ng-click="newAlert()">Alert</a> |
<a ng-click="newProgress()">Progress</a>
</span>
<span class="count">Notifications</span>
</span>

View File

@ -0,0 +1,150 @@
/*****************************************************************************
* 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";
/**
* A controller for the dialog launch view. This view allows manual
* launching of dialogs for demonstration and testing purposes. It
* also demonstrates the use of the DialogService.
* @param $scope
* @param $timeout
* @param $log
* @param dialogService
* @param notificationService
* @constructor
*/
function DialogLaunchController($scope, $timeout, $log, dialogService, notificationService) {
/*
Demonstrates launching a progress dialog and updating it
periodically with the progress of an ongoing process.
*/
$scope.launchProgress = function (knownProgress) {
var model = {
title: "Progress Dialog Example",
progress: 0,
hint: "Do not navigate away from this page or close this browser tab while this operation is in progress.",
actionText: "Calculating...",
unknownProgress: !knownProgress,
unknownDuration: false,
severity: "info",
options: [
{
label: "Cancel Operation",
callback: function () {
$log.debug("Operation cancelled");
dialogService.dismiss();
}
},
{
label: "Do something else...",
callback: function () {
$log.debug("Something else pressed");
}
}
]
};
function incrementProgress() {
model.progress = Math.min(100, Math.floor(model.progress + Math.random() * 30));
model.progressText = ["Estimated time remaining: about ", 60 - Math.floor((model.progress / 100) * 60), " seconds"].join(" ");
if (model.progress < 100) {
$timeout(incrementProgress, 1000);
}
}
if (dialogService.showBlockingMessage(model)) {
//Do processing here
model.actionText = "Processing 100 objects...";
if (knownProgress) {
$timeout(incrementProgress, 1000);
}
} else {
$log.error("Could not display modal dialog");
}
};
/*
Demonstrates launching an error dialog
*/
$scope.launchError = function () {
var model = {
title: "Error Dialog Example",
actionText: "Something happened, and it was not good.",
severity: "error",
options: [
{
label: "Try Again",
callback: function () {
$log.debug("Try Again Pressed");
dialogService.dismiss();
}
},
{
label: "Cancel",
callback: function () {
$log.debug("Cancel Pressed");
dialogService.dismiss();
}
}
]
};
if (!dialogService.showBlockingMessage(model)) {
$log.error("Could not display modal dialog");
}
};
/*
Demonstrates launching an error dialog
*/
$scope.launchInfo = function () {
var model = {
title: "Info Dialog Example",
actionText: "This is an example of a blocking info" +
" dialog. This dialog can be used to draw the user's" +
" attention to an event.",
severity: "info",
primaryOption: {
label: "OK",
callback: function () {
$log.debug("OK Pressed");
dialogService.dismiss();
}
}
};
if (!dialogService.showBlockingMessage(model)) {
$log.error("Could not display modal dialog");
}
};
}
return DialogLaunchController;
}
);

View File

@ -0,0 +1,56 @@
/*****************************************************************************
* 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,window*/
define(
[],
function () {
"use strict";
/**
* A tool for manually invoking dialogs. When included this
* indicator will allow for dialogs of different types to be
* launched for demonstration and testing purposes.
* @constructor
*/
function DialogLaunchIndicator() {
}
DialogLaunchIndicator.template = 'dialogLaunchTemplate';
DialogLaunchIndicator.prototype.getGlyph = function () {
return "i";
};
DialogLaunchIndicator.prototype.getGlyphClass = function () {
return 'caution';
};
DialogLaunchIndicator.prototype.getText = function () {
return "Launch test dialog";
};
DialogLaunchIndicator.prototype.getDescription = function () {
return "Launch test dialog";
};
return DialogLaunchIndicator;
}
);

View File

@ -0,0 +1,172 @@
/*****************************************************************************
* 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";
/**
* Allows launching of notification messages for the purposes of
* demonstration and testing. Also demonstrates use of
* the NotificationService. Notifications are non-blocking messages that
* appear at the bottom of the screen to inform the user of events
* in a non-intrusive way. For more information see the
* {@link NotificationService}
* @param $scope
* @param $timeout
* @param $log
* @param notificationService
* @constructor
*/
function NotificationLaunchController($scope, $timeout, $log, notificationService) {
var messageCounter = 1;
function getExampleActionText() {
var actionTexts = [
"Adipiscing turpis mauris in enim elementu hac, enim aliquam etiam.",
"Eros turpis, pulvinar turpis eros eu",
"Lundium nascetur a, lectus montes ac, parturient in natoque, duis risus risus pulvinar pid rhoncus, habitasse auctor natoque!"
];
return actionTexts[Math.floor(Math.random()*3)];
}
function getExampleActions() {
var actions = [
{
label: "Try Again",
callback: function () {
$log.debug("Try Again pressed");
}
},
{
label: "Remove",
callback: function () {
$log.debug("Remove pressed");
}
},
{
label: "Cancel",
callback: function () {
$log.debug("Cancel pressed");
}
}
];
// Randomly remove some actions off the top; leave at least one
actions.splice(0,Math.floor(Math.random() * actions.length));
return actions;
}
function getExampleSeverity() {
var severities = [
"info",
"alert",
"error"
];
return severities[Math.floor(Math.random() * severities.length)];
}
/**
* Launch a new notification with a severity level of 'Error'.
*/
$scope.newError = function(){
notificationService.notify({
title: "Example error notification " + messageCounter++,
hint: "An error has occurred",
severity: "error",
primaryOption: {
label: 'Retry',
callback: function() {
$log.info('Retry clicked');
}
},
options: getExampleActions()});
};
/**
* Launch a new notification with a severity of 'Alert'.
*/
$scope.newAlert = function(){
notificationService.notify({
title: "Alert notification " + (messageCounter++),
hint: "This is an alert message",
severity: "alert",
primaryOption: {
label: 'Retry',
callback: function() {
$log.info('Retry clicked');
}
},
options: getExampleActions()});
};
/**
* Launch a new notification with a progress bar that is updated
* periodically, tracking an ongoing process.
*/
$scope.newProgress = function(){
var notificationModel = {
title: "Progress notification example",
severity: "info",
progress: 0,
actionText: getExampleActionText(),
unknownProgress: false
};
/**
* Simulate an ongoing process and update the progress bar.
* @param notification
*/
function incrementProgress(notificationModel) {
notificationModel.progress = Math.min(100, Math.floor(notificationModel.progress + Math.random() * 30));
notificationModel.progressText = ["Estimated time" +
" remaining:" +
" about ", 60 - Math.floor((notificationModel.progress / 100) * 60), " seconds"].join(" ");
if (notificationModel.progress < 100) {
$timeout(function(){incrementProgress(notificationModel);}, 1000);
}
}
notificationService.notify(notificationModel);
incrementProgress(notificationModel);
};
/**
* Launch a new notification with severity level of INFO.
*/
$scope.newInfo = function(){
notificationService.info({
title: "Example Info notification " + messageCounter++
});
};
}
return NotificationLaunchController;
}
);

View File

@ -0,0 +1,50 @@
/*****************************************************************************
* 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,window*/
define(
[],
function () {
"use strict";
function NotificationLaunchIndicator() {
}
NotificationLaunchIndicator.template = 'notificationLaunchTemplate';
NotificationLaunchIndicator.prototype.getGlyph = function () {
return "i";
};
NotificationLaunchIndicator.prototype.getGlyphClass = function () {
return 'caution';
};
NotificationLaunchIndicator.prototype.getText = function () {
return "Launch notification";
};
NotificationLaunchIndicator.prototype.getDescription = function () {
return "Launch notification";
};
return NotificationLaunchIndicator;
}
);

View File

@ -0,0 +1,2 @@
Example of using multiple persistence stores by exposing a root
object with a different space prefix.

View File

@ -0,0 +1,23 @@
{
"extensions": {
"roots": [
{
"id": "scratch:root",
"model": {
"type": "folder",
"composition": [],
"name": "Scratchpad"
},
"priority": "preferred"
}
],
"components": [
{
"provides": "persistenceService",
"type": "provider",
"implementation": "ScratchPersistenceProvider.js",
"depends": [ "$q" ]
}
]
}
}

View File

@ -0,0 +1,79 @@
/*****************************************************************************
* 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,window*/
define(
[],
function () {
'use strict';
/**
* The ScratchPersistenceProvider keeps JSON documents in memory
* and provides a persistence interface, but changes are lost on reload.
* @memberof example/scratchpad
* @constructor
* @implements {PersistenceService}
* @param q Angular's $q, for promises
*/
function ScratchPersistenceProvider($q) {
this.$q = $q;
this.table = {};
}
ScratchPersistenceProvider.prototype.listSpaces = function () {
return this.$q.when(['scratch']);
};
ScratchPersistenceProvider.prototype.listObjects = function (space) {
return this.$q.when(
space === 'scratch' ? Object.keys(this.table) : []
);
};
ScratchPersistenceProvider.prototype.createObject = function (space, key, value) {
if (space === 'scratch') {
this.table[key] = JSON.stringify(value);
}
return this.$q.when(space === 'scratch');
};
ScratchPersistenceProvider.prototype.readObject = function (space, key) {
return this.$q.when(
(space === 'scratch' && this.table[key]) ?
JSON.parse(this.table[key]) : undefined
);
};
ScratchPersistenceProvider.prototype.deleteObject = function (space, key, value) {
if (space === 'scratch') {
delete this.table[key];
}
return this.$q.when(space === 'scratch');
};
ScratchPersistenceProvider.prototype.updateObject =
ScratchPersistenceProvider.prototype.createObject;
return ScratchPersistenceProvider;
}
);

View File

@ -34,7 +34,6 @@ module.exports = function(config) {
// List of files / patterns to load in the browser. // List of files / patterns to load in the browser.
// By default, files are also included in a script tag. // By default, files are also included in a script tag.
files: [ files: [
'**/moment*',
{pattern: 'example/**/*.js', included: false}, {pattern: 'example/**/*.js', included: false},
{pattern: 'platform/**/*.js', included: false}, {pattern: 'platform/**/*.js', included: false},
{pattern: 'warp/**/*.js', included: false}, {pattern: 'warp/**/*.js', included: false},

View File

@ -22,7 +22,8 @@
"split": "^1.0.0", "split": "^1.0.0",
"mkdirp": "^0.5.1", "mkdirp": "^0.5.1",
"nomnoml": "^0.0.3", "nomnoml": "^0.0.3",
"canvas": "^1.2.7" "canvas": "^1.2.7",
"markdown-toc": "^0.11.7"
}, },
"scripts": { "scripts": {
"start": "node app.js", "start": "node app.js",

View File

@ -26,10 +26,10 @@
] ]
}, },
{ {
"key": "BrowseTreeController", "key": "PaneController",
"implementation": "BrowseTreeController.js", "implementation": "PaneController.js",
"priority": "preferred", "priority": "preferred",
"depends": [ "$scope", "agentService" ] "depends": [ "$scope", "agentService","$window" ]
}, },
{ {
"key": "BrowseObjectController", "key": "BrowseObjectController",
@ -154,7 +154,7 @@
"provides": "creationService", "provides": "creationService",
"type": "provider", "type": "provider",
"implementation": "creation/CreationService.js", "implementation": "creation/CreationService.js",
"depends": [ "persistenceService", "now", "$q", "$log" ] "depends": [ "$q", "$log" ]
} }
], ],
"runs": [ "runs": [
@ -173,16 +173,6 @@
"copyright": "Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)", "copyright": "Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)",
"license": "license-mit", "license": "license-mit",
"link": "https://github.com/sindresorhus/screenfull.js/blob/gh-pages/license" "link": "https://github.com/sindresorhus/screenfull.js/blob/gh-pages/license"
},
{
"name": "Math.uuid.js",
"version": "1.4",
"description": "Unique identifer generation (code adapted.)",
"author": "Robert Kieffer",
"website": "https://github.com/broofa/node-uuid",
"copyright": "Copyright (c) 2010 Robert Kieffer",
"license": "license-mit",
"link": "http://opensource.org/licenses/MIT"
} }
] ]
} }

View File

@ -20,15 +20,17 @@
at runtime from the About dialog for additional information. at runtime from the About dialog for additional information.
--> -->
<span ng-controller="BrowseObjectController"> <span ng-controller="BrowseObjectController">
<div class="object-browse-bar bar l-flex"> <div class="object-browse-bar l-flex-row">
<div class="items-select left"> <div class="items-select left flex-elem l-flex-row grows">
<mct-representation key="'back-arrow'" <mct-representation key="'back-arrow'"
mct-object="domainObject" mct-object="domainObject"
class="l-back"></mct-representation> class="flex-elem l-back"></mct-representation>
<mct-representation key="'object-header'" mct-object="domainObject"> <mct-representation key="'object-header'"
mct-object="domainObject"
class="l-flex-row flex-elem grows object-header">
</mct-representation> </mct-representation>
</div> </div>
<div class="btn-bar right"> <div class="btn-bar right l-flex-row flex-elem flex-justify-end flex-fixed">
<mct-representation key="'switcher'" <mct-representation key="'switcher'"
mct-object="domainObject" mct-object="domainObject"
ng-model="representation"> ng-model="representation">
@ -41,7 +43,6 @@
</mct-representation> </mct-representation>
</div> </div>
</div> </div>
<mct-representation key="representation.selected.key" <mct-representation key="representation.selected.key"
mct-object="representation.selected.key && domainObject" mct-object="representation.selected.key && domainObject"
class="abs object-holder"> class="abs object-holder">

View File

@ -22,45 +22,66 @@
<div class="abs holder-all browse-mode" ng-controller="BrowseController"> <div class="abs holder-all browse-mode" ng-controller="BrowseController">
<mct-include key="'topbar-browse'"></mct-include> <mct-include key="'topbar-browse'"></mct-include>
<div class="holder browse-area s-browse-area abs browse-wrapper" <div class="abs holder holder-main browse-area s-browse-area browse-wrapper"
ng-controller="BrowseTreeController as tree" ng-controller="PaneController as modelPaneTree"
ng-class="tree.visible() ? 'browse-showtree' : 'browse-hidetree'"> ng-class="modelPaneTree.visible() ? 'pane-tree-showing' : 'pane-tree-hidden'">
<mct-split-pane class='contents abs' anchor='left'> <mct-split-pane class='abs contents'
anchor='left'>
<div class='split-pane-component treeview pane left'> <div class='split-pane-component treeview pane left'>
<div class="holder abs l-mobile"> <div class="abs holder l-flex-col holder-treeview-elements">
<mct-representation key="'create-button'" <mct-representation key="'create-button'"
mct-object="navigatedObject" mct-object="navigatedObject"
mct-device="desktop"> class="holder flex-elem create-btn-holder">
</mct-representation>
<mct-include key="'search'"
ng-model="treeModel"
class="holder l-flex-col flex-elem search-holder"
ng-class="{ active: treeModel.search, grows: treeModel.search }">
</mct-include>
<mct-representation key="'tree'"
mct-object="domainObject"
parameters="tree"
ng-model="treeModel"
class="holder flex-elem grows vscroll tree-holder"
ng-hide="treeModel.search">
</mct-representation> </mct-representation>
<div class='holder search-holder abs'
ng-class="{active: treeModel.search}">
<mct-representation key="'search'"
mct-object="domainObject"
ng-model="treeModel">
</mct-representation>
</div>
<div class='tree-holder abs mobile-tree-holder'
ng-hide="treeModel.search">
<mct-representation key="'tree'"
mct-object="domainObject"
parameters="tree"
ng-model="treeModel">
</mct-representation>
</div>
</div> </div>
</div> </div>
<mct-splitter class="mobile-hide"></mct-splitter> <mct-splitter class="splitter-treeview mobile-hide"></mct-splitter>
<div class='split-pane-component items pane right-repr'> <div class='split-pane-component items pane primary-pane right'>
<div class='holder abs l-mobile' id='content-area'> <a class="mini-tab-icon anchor-left toggle-pane toggle-tree"
<mct-representation mct-object="navigatedObject" title="{{ modelPaneTree.visible()? 'Hide' : 'Show' }} this pane"
key="'browse-object'"> ng-click="modelPaneTree.toggle()"
</mct-representation> ng-class="{ collapsed : !modelPaneTree.visible() }"></a>
<div class='holder holder-object-and-inspector abs' id='content-area'
ng-controller="PaneController as modelPaneInspect"
ng-class="modelPaneInspect.visible() ? 'pane-inspect-showing' : 'pane-inspect-hidden'">
<mct-split-pane class='l-object-and-inspector contents abs' anchor='right'>
<div class='split-pane-component t-object pane primary-pane left'>
<mct-representation mct-object="navigatedObject"
key="'browse-object'"
class="abs holder holder-object">
</mct-representation>
</div>
<mct-splitter class="splitter-inspect mobile-hide flush-right edge-shdw"></mct-splitter>
<div class="split-pane-component t-inspect pane right mobile-hide">
<mct-representation key="'object-inspector'"
mct-object="domainObject"
ng-model="treeModel">
</mct-representation>
<a class="mini-tab-icon anchor-right mobile-hide toggle-pane toggle-inspect"
title="{{ modelPaneInspect.visible()? 'Hide' : 'Show' }} the Inspection pane"
ng-click="modelPaneInspect.toggle()"
ng-class="{ collapsed : !modelPaneInspect.visible() }"></a>
</div>
</mct-split-pane>
</div> </div>
<div class="key-properties ui-symbol icon mobile-menu-icon desktop-hide"
mct-device="mobile"
ng-click="tree.toggle()">m</div>
</div> </div>
</mct-split-pane> </mct-split-pane>
</div> </div>

View File

@ -19,12 +19,12 @@
this source code distribution or the Licensing information page available this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information. at runtime from the About dialog for additional information.
--> -->
<div class='object-header object-header-mobile'> <span class='type-icon ui-symbol flex-elem'>{{type.getGlyph()}}</span>
<span class='type-icon ui-symbol'>{{type.getGlyph()}}</span> <span class="l-elem-wrapper l-flex-row flex-elem grows">
<!--span class='type-name mobile-important-hide'>{{type.getName()}}</span--> <span ng-if="parameters.mode" class='action flex-elem'>{{parameters.mode}}</span>
<span class="l-elem-wrapper l-flex"> <span class='title-label flex-elem flex-can-shrink'>{{model.name}}</span>
<span ng-if="parameters.mode" class='action'>{{parameters.mode}}</span> <mct-representation
<span class='title-label'>{{model.name}}</span> key="'menu-arrow'"
<mct-representation key="'menu-arrow'" mct-object='domainObject'></mct-representation> mct-object='domainObject'
</span> class="flex-elem"></mct-representation>
</div> </span>

View File

@ -19,13 +19,12 @@
this source code distribution or the Licensing information page available this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information. at runtime from the About dialog for additional information.
--> -->
<div class="menu-element wrapper" ng-controller="ClickAwayController as createController"> <span ng-controller="ClickAwayController as createController">
<div class="s-menu-btn major create-btn" ng-click="createController.toggle()"> <div class="s-menu-btn major create-btn" ng-click="createController.toggle()">
<span class="ui-symbol icon type-icon">&#x2b;</span>
<span class="title-label">Create</span> <span class="title-label">Create</span>
</div> </div>
<div class="menu super-menu" ng-show="createController.isActive()"> <div class="menu super-menu" ng-show="createController.isActive()">
<mct-representation mct-object="domainObject" key="'create-menu'"> <mct-representation mct-object="domainObject" key="'create-menu'">
</mct-representation> </mct-representation>
</div> </div>
</div> </span>

View File

@ -26,14 +26,8 @@
<div class='ui-symbol profile' title='Shared'>&#x4f;</div> <div class='ui-symbol profile' title='Shared'>&#x4f;</div>
<mct-representation class="desktop-hide" key="'info-button'" mct-object="domainObject"></mct-representation> <mct-representation class="desktop-hide" key="'info-button'" mct-object="domainObject"></mct-representation>
</div> </div>
<div class='item-main abs'> <div class='item-main abs lg'>
<div class='ui-symbol icon lg item-type'> <span class="t-item-icon" ng-class="{ 'l-icon-link':location.isLink() }">{{type.getGlyph()}}</span>
{{type.getGlyph()}}
<span
class="ui-symbol l-icon-link" title="This object is a link"
ng-show="location.isLink()"
></span>
</div>
<div class='ui-symbol abs item-open'>}</div> <div class='ui-symbol abs item-open'>}</div>
</div> </div>
<div class='bottom-bar bar abs'> <div class='bottom-bar bar abs'>

View File

@ -153,7 +153,6 @@ define(
$scope.$on("$destroy", function () { $scope.$on("$destroy", function () {
navigationService.removeListener(setNavigation); navigationService.removeListener(setNavigation);
}); });
} }
return BrowseController; return BrowseController;

View File

@ -33,10 +33,12 @@ define(
* @constructor * @constructor
* @memberof platform/commonUI/browse * @memberof platform/commonUI/browse
*/ */
function BrowseTreeController($scope, agentService) { function PaneController($scope, agentService, $window) {
var self = this; var self = this;
this.agentService = agentService; this.agentService = agentService;
this.state = true;
// Fast and cheap: if this has been opened in a new window, hide panes by default
this.state = !$window.opener;
/** /**
* Callback to invoke when any selection occurs in the tree. * Callback to invoke when any selection occurs in the tree.
@ -44,7 +46,7 @@ define(
* to the tree representation. * to the tree representation.
* *
* @property {Function} callback * @property {Function} callback
* @memberof platform/commonUI/browse.BrowseTreeController# * @memberof platform/commonUI/browse.PaneController#
*/ */
this.callback = function () { this.callback = function () {
// Note that, since this is a callback to pass, this is not // Note that, since this is a callback to pass, this is not
@ -59,20 +61,20 @@ define(
} }
/** /**
* Toggle the visibility of the tree. * Toggle the visibility of the pane.
*/ */
BrowseTreeController.prototype.toggle = function () { PaneController.prototype.toggle = function () {
this.state = !this.state; this.state = !this.state;
}; };
/** /**
* Get the desired visibility state of the tree. * Get the desired visibility state of the pane.
* @returns {boolean} true when visible * @returns {boolean} true when visible
*/ */
BrowseTreeController.prototype.visible = function () { PaneController.prototype.visible = function () {
return this.state; return this.state;
}; };
return BrowseTreeController; return PaneController;
} }
); );

View File

@ -25,8 +25,8 @@
* Module defining CreateService. Created by vwoeltje on 11/10/14. * Module defining CreateService. Created by vwoeltje on 11/10/14.
*/ */
define( define(
["../../lib/uuid"], [],
function (uuid) { function () {
"use strict"; "use strict";
var NON_PERSISTENT_WARNING = var NON_PERSISTENT_WARNING =
@ -42,11 +42,9 @@ define(
* @memberof platform/commonUI/browse * @memberof platform/commonUI/browse
* @constructor * @constructor
*/ */
function CreationService(persistenceService, now, $q, $log) { function CreationService($q, $log) {
this.persistenceService = persistenceService;
this.$q = $q; this.$q = $q;
this.$log = $log; this.$log = $log;
this.now = now;
} }
/** /**
@ -70,26 +68,17 @@ define(
*/ */
CreationService.prototype.createObject = function (model, parent) { CreationService.prototype.createObject = function (model, parent) {
var persistence = parent.getCapability("persistence"), var persistence = parent.getCapability("persistence"),
newObject = parent.useCapability("instantiation", model),
newObjectPersistence = newObject.getCapability("persistence"),
self = this; self = this;
// Persist the new domain object's model; it will be fully
// constituted as a domain object when loaded back, as all
// domain object models are.
function doPersist(space, id, model) {
return self.persistenceService.createObject(
space,
id,
model
).then(function () { return id; });
}
// Add the newly-created object's id to the parent's // Add the newly-created object's id to the parent's
// composition, so that it will subsequently appear // composition, so that it will subsequently appear
// as a child contained by that parent. // as a child contained by that parent.
function addToComposition(id, parent, parentPersistence) { function addToComposition() {
var compositionCapability = parent.getCapability('composition'), var compositionCapability = parent.getCapability('composition'),
addResult = compositionCapability && addResult = compositionCapability &&
compositionCapability.add(id); compositionCapability.add(newObject);
return self.$q.when(addResult).then(function (result) { return self.$q.when(addResult).then(function (result) {
if (!result) { if (!result) {
@ -97,7 +86,7 @@ define(
return undefined; return undefined;
} }
return parentPersistence.persist().then(function () { return persistence.persist().then(function () {
return result; return result;
}); });
}); });
@ -105,21 +94,13 @@ define(
// We need the parent's persistence capability to determine // We need the parent's persistence capability to determine
// what space to create the new object's model in. // what space to create the new object's model in.
if (!persistence) { if (!persistence || !newObjectPersistence) {
self.$log.warn(NON_PERSISTENT_WARNING); self.$log.warn(NON_PERSISTENT_WARNING);
return self.$q.reject(new Error(NON_PERSISTENT_WARNING)); return self.$q.reject(new Error(NON_PERSISTENT_WARNING));
} }
// We create a new domain object in three sequential steps: // Persist the new object, then add it to composition.
// 1. Get a new UUID for the object return newObjectPersistence.persist().then(addToComposition);
// 2. Create a model with that ID in the persistence space
// 3. Add that ID to
return self.$q.when(uuid()).then(function (id) {
model.persisted = self.now();
return doPersist(persistence.getSpace(), id, model);
}).then(function (id) {
return addToComposition(id, parent, persistence);
});
}; };

View File

@ -22,22 +22,24 @@
/*global define,Promise,describe,it,expect,beforeEach,waitsFor,jasmine*/ /*global define,Promise,describe,it,expect,beforeEach,waitsFor,jasmine*/
define( define(
["../src/BrowseTreeController"], ["../src/PaneController"],
function (BrowseTreeController) { function (PaneController) {
'use strict'; 'use strict';
describe("The BrowseTreeController", function () { describe("The PaneController", function () {
var mockScope, var mockScope,
mockAgentService, mockAgentService,
mockDomainObjects, mockDomainObjects,
mockWindow,
controller; controller;
// We want to reinstantiate for each test case // We want to reinstantiate for each test case
// because device state can influence constructor-time behavior // because device state can influence constructor-time behavior
function instantiateController() { function instantiateController() {
return new BrowseTreeController( return new PaneController(
mockScope, mockScope,
mockAgentService mockAgentService,
mockWindow
); );
} }
@ -58,6 +60,7 @@ define(
"agentService", "agentService",
[ "isMobile", "isPhone", "isTablet", "isPortrait", "isLandscape" ] [ "isMobile", "isPhone", "isTablet", "isPortrait", "isLandscape" ]
); );
mockWindow = jasmine.createSpyObj("$window", ["open"]);
}); });
it("is initially visible", function () { it("is initially visible", function () {

View File

@ -30,9 +30,7 @@ define(
"use strict"; "use strict";
describe("The creation service", function () { describe("The creation service", function () {
var mockPersistenceService, var mockQ,
mockNow,
mockQ,
mockLog, mockLog,
mockParentObject, mockParentObject,
mockNewObject, mockNewObject,
@ -40,7 +38,9 @@ define(
mockPersistenceCapability, mockPersistenceCapability,
mockCompositionCapability, mockCompositionCapability,
mockContextCapability, mockContextCapability,
mockCreationCapability,
mockCapabilities, mockCapabilities,
mockNewPersistenceCapability,
creationService; creationService;
function mockPromise(value) { function mockPromise(value) {
@ -60,11 +60,6 @@ define(
} }
beforeEach(function () { beforeEach(function () {
mockPersistenceService = jasmine.createSpyObj(
"persistenceService",
[ "createObject" ]
);
mockNow = jasmine.createSpy('now');
mockQ = { when: mockPromise, reject: mockReject }; mockQ = { when: mockPromise, reject: mockReject };
mockLog = jasmine.createSpyObj( mockLog = jasmine.createSpyObj(
"$log", "$log",
@ -76,7 +71,7 @@ define(
); );
mockNewObject = jasmine.createSpyObj( mockNewObject = jasmine.createSpyObj(
"newObject", "newObject",
[ "getId" ] [ "getId", "getCapability", "useCapability" ]
); );
mockMutationCapability = jasmine.createSpyObj( mockMutationCapability = jasmine.createSpyObj(
"mutation", "mutation",
@ -94,19 +89,22 @@ define(
"context", "context",
["getPath"] ["getPath"]
); );
mockCreationCapability = jasmine.createSpyObj(
"creation",
["instantiate", "invoke"]
);
mockCapabilities = { mockCapabilities = {
mutation: mockMutationCapability, mutation: mockMutationCapability,
persistence: mockPersistenceCapability, persistence: mockPersistenceCapability,
composition: mockCompositionCapability, composition: mockCompositionCapability,
context: mockContextCapability context: mockContextCapability,
instantiation: mockCreationCapability
}; };
mockNewPersistenceCapability = jasmine.createSpyObj(
mockPersistenceService.createObject.andReturn( "new-persistence",
mockPromise(true) [ "persist", "getSpace" ]
); );
mockNow.andReturn(12321);
mockParentObject.getCapability.andCallFake(function (key) { mockParentObject.getCapability.andCallFake(function (key) {
return mockCapabilities[key]; return mockCapabilities[key];
}); });
@ -115,9 +113,16 @@ define(
}); });
mockParentObject.getId.andReturn('parentId'); mockParentObject.getId.andReturn('parentId');
mockPersistenceCapability.persist.andReturn( mockNewObject.getId.andReturn('newId');
mockPromise(true) mockNewObject.getCapability.andCallFake(function (c) {
); return c === 'persistence' ?
mockNewPersistenceCapability : undefined;
});
mockPersistenceCapability.persist
.andReturn(mockPromise(true));
mockNewPersistenceCapability.persist
.andReturn(mockPromise(true));
mockMutationCapability.invoke.andReturn(mockPromise(true)); mockMutationCapability.invoke.andReturn(mockPromise(true));
mockPersistenceCapability.getSpace.andReturn("testSpace"); mockPersistenceCapability.getSpace.andReturn("testSpace");
@ -125,10 +130,12 @@ define(
mockPromise([mockNewObject]) mockPromise([mockNewObject])
); );
mockCompositionCapability.add.andReturn(mockPromise(true)); mockCompositionCapability.add.andReturn(mockPromise(true));
mockCreationCapability.instantiate.andReturn(mockNewObject);
mockCreationCapability.invoke.andCallFake(function (model) {
return mockCreationCapability.instantiate(model);
});
creationService = new CreationService( creationService = new CreationService(
mockPersistenceService,
mockNow,
mockQ, mockQ,
mockLog mockLog
); );
@ -137,21 +144,18 @@ define(
it("allows new objects to be created", function () { it("allows new objects to be created", function () {
var model = { someKey: "some value" }; var model = { someKey: "some value" };
creationService.createObject(model, mockParentObject); creationService.createObject(model, mockParentObject);
expect(mockPersistenceService.createObject).toHaveBeenCalledWith( expect(mockCreationCapability.instantiate)
"testSpace", .toHaveBeenCalledWith(model);
jasmine.any(String), // the object id; generated UUID
model
);
}); });
it("adds new id's to the parent's composition", function () { it("adds new objects to the parent's composition", function () {
var model = { someKey: "some value" }, var model = { someKey: "some value" },
parentModel = { composition: ["notAnyUUID"] }; parentModel = { composition: ["notAnyUUID"] };
creationService.createObject(model, mockParentObject); creationService.createObject(model, mockParentObject);
// Verify that a new ID was added // Verify that a new ID was added
expect(mockCompositionCapability.add) expect(mockCompositionCapability.add)
.toHaveBeenCalledWith(jasmine.any(String)); .toHaveBeenCalledWith(mockNewObject);
}); });
it("provides the newly-created object", function () { it("provides the newly-created object", function () {
@ -207,11 +211,6 @@ define(
expect(mockLog.error).toHaveBeenCalled(); expect(mockLog.error).toHaveBeenCalled();
}); });
it("attaches a 'persisted' timestamp", function () {
var model = { someKey: "some value" };
creationService.createObject(model, mockParentObject);
expect(model.persisted).toEqual(mockNow());
});
}); });
} }

View File

@ -1,7 +1,7 @@
[ [
"BrowseController", "BrowseController",
"BrowseObjectController", "BrowseObjectController",
"BrowseTreeController", "PaneController",
"MenuArrowController", "MenuArrowController",
"creation/CreateAction", "creation/CreateAction",
"creation/CreateActionProvider", "creation/CreateActionProvider",

View File

@ -24,6 +24,18 @@
{ {
"key": "form-dialog", "key": "form-dialog",
"templateUrl": "templates/dialog.html" "templateUrl": "templates/dialog.html"
},
{
"key": "overlay-blocking-message",
"templateUrl": "templates/overlay-blocking-message.html"
},
{
"key": "message",
"templateUrl": "templates/message.html"
},
{
"key": "overlay-message-list",
"templateUrl": "templates/overlay-message-list.html"
} }
], ],
"containers": [ "containers": [

View File

@ -21,17 +21,13 @@
--> -->
<div class="abs top-bar"> <div class="abs top-bar">
<div class="title">{{ngModel.title}}</div> <div class="title">{{ngModel.title}}</div>
<div class="hint"> <div class="hint">All fields marked <span class="ui-symbol req">*</span> are required.</div>
All fields marked <span class="ui-symbol req">*</span> are required.
</div>
</div> </div>
<div class="abs form editor"> <div class='abs editor'>
<div class='abs contents l-dialog'> <mct-form ng-model="ngModel.value"
<mct-form ng-model="ngModel.value" structure="ngModel.structure"
structure="ngModel.structure" name="createForm">
name="createForm"> </mct-form>
</mct-form>
</div>
</div> </div>
<div class="abs bottom-bar"> <div class="abs bottom-bar">
<a class='s-btn major' <a class='s-btn major'

View File

@ -0,0 +1,32 @@
<div class="l-message"
ng-class="'message-severity-' + ngModel.severity">
<div class="ui-symbol type-icon message-type"></div>
<div class="message-contents">
<div class="top-bar">
<div class="title">{{ngModel.title}}</div>
<div class="hint" ng-hide="ngModel.hint === undefined">{{ngModel.hint}}</div>
</div>
<div class="message-body">
<div class="message-action">
{{ngModel.actionText}}
</div>
<mct-include key="'progress-bar'"
ng-model="ngModel"
ng-show="ngModel.progress !== undefined || ngModel.unknownProgress"></mct-include>
</div>
<div class="bottom-bar">
<a ng-repeat="dialogOption in ngModel.options"
class="s-btn major"
ng-click="dialogOption.callback()">
{{dialogOption.label}}
</a>
<a class="s-btn major"
ng-if="ngModel.primaryOption"
ng-click="ngModel.primaryOption.callback()">
{{ngModel.primaryOption.label}}
</a>
</div>
</div>
</div>

View File

@ -0,0 +1,25 @@
<!--
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.
-->
<mct-container key="overlay" class="t-message-single">
<mct-include key="'message'" ng-model="ngModel">
</mct-include>
</mct-container>

View File

@ -0,0 +1,19 @@
<mct-container key="overlay" class="t-message-list">
<div class="message-contents">
<div class="abs top-bar">
<div class="title">{{ngModel.dialog.title}}</div>
<div class="hint">Displaying {{ngModel.dialog.messages.length}} message<span ng-show="ngModel.dialog.messages.length > 1">s</span>
</div>
</div>
<div class="abs message-body">
<mct-include ng-repeat="msg in ngModel.dialog.messages | orderBy: '-'" key="'message'" ng-model="msg"></mct-include>
</div>
<div class="abs bottom-bar">
<a ng-repeat="dialogAction in ngModel.dialog.actions"
class="s-btn major"
ng-click="dialogAction.action()">
{{dialogAction.label}}
</a>
</div>
</div>
</mct-container>

View File

@ -24,13 +24,11 @@
<div class="title">{{ngModel.dialog.title}}</div> <div class="title">{{ngModel.dialog.title}}</div>
<div class="hint">{{ngModel.dialog.hint}}</div> <div class="hint">{{ngModel.dialog.hint}}</div>
</div> </div>
<div class="abs form outline editor"> <div class='abs editor'>
<div class='abs contents l-dialog'> <mct-include key="ngModel.dialog.template"
<mct-include key="ngModel.dialog.template" parameters="ngModel.dialog.parameters"
parameters="ngModel.dialog.parameters" ng-model="ngModel.dialog.model">
ng-model="ngModel.dialog.model"> </mct-include>
</mct-include>
</div>
</div> </div>
<div class="abs bottom-bar"> <div class="abs bottom-bar">
<a ng-repeat="option in ngModel.dialog.options" <a ng-repeat="option in ngModel.dialog.options"

View File

@ -22,14 +22,9 @@
<div class="abs overlay"> <div class="abs overlay">
<div class="abs blocker"></div> <div class="abs blocker"></div>
<div class="abs holder"> <div class="abs holder">
<a href="" <a ng-click="ngModel.cancel()"
ng-click="ngModel.cancel()"
ng-if="ngModel.cancel" ng-if="ngModel.cancel"
class="clk-icon icon ui-symbol close"> class="clk-icon icon ui-symbol close">x</a>
x <div class="abs contents" ng-transclude></div>
</a>
<div class="abs contents" ng-transclude>
</div>
</div> </div>
</div> </div>

View File

@ -55,7 +55,7 @@ define(
this.dialogVisible = false; this.dialogVisible = false;
}; };
DialogService.prototype.getDialogResponse = function (key, model, resultGetter) { DialogService.prototype.getDialogResponse = function (key, model, resultGetter, typeClass) {
// We will return this result as a promise, because user // We will return this result as a promise, because user
// input is asynchronous. // input is asynchronous.
var deferred = this.$q.defer(), var deferred = this.$q.defer(),
@ -84,27 +84,20 @@ define(
model.confirm = confirm; model.confirm = confirm;
model.cancel = cancel; model.cancel = cancel;
if (this.dialogVisible) { if (this.canShowDialog(model)) {
// Only one dialog should be shown at a time.
// The application design should be such that
// we never even try to do this.
this.$log.warn([
"Dialog already showing; ",
"unable to show ",
model.name
].join(""));
deferred.reject();
} else {
// Add the overlay using the OverlayService, which // Add the overlay using the OverlayService, which
// will handle actual insertion into the DOM // will handle actual insertion into the DOM
this.overlay = this.overlayService.createOverlay( this.overlay = this.overlayService.createOverlay(
key, key,
model model,
typeClass || "t-dialog"
); );
// Track that a dialog is already visible, to // Track that a dialog is already visible, to
// avoid spawning multiple dialogs at once. // avoid spawning multiple dialogs at once.
this.dialogVisible = true; this.dialogVisible = true;
} else {
deferred.reject();
} }
return deferred.promise; return deferred.promise;
@ -157,6 +150,99 @@ define(
); );
}; };
/**
* Tests if a dialog can be displayed. A modal dialog may only be
* displayed if one is not already visible.
* Will log a warning message if it can't display a dialog.
* @returns {boolean} true if dialog is currently visible, false
* otherwise
*/
DialogService.prototype.canShowDialog = function(dialogModel){
if (this.dialogVisible){
// Only one dialog should be shown at a time.
// The application design should be such that
// we never even try to do this.
this.$log.warn([
"Dialog already showing; ",
"unable to show ",
dialogModel.title
].join(""));
return false;
} else {
return true;
}
};
/**
* A user action that can be performed from a blocking dialog. These
* actions will be rendered as buttons within a blocking dialog.
*
* @typedef DialogOption
* @property {string} label a label to be displayed as the button
* text for this action
* @property {function} callback a function to be called when the
* button is clicked
*/
/**
* A description of the model options that may be passed to the
* showBlockingMessage method. Note that the DialogModel desribed
* here is shared with the Notifications framework.
* @see NotificationService
*
* @typedef DialogModel
* @property {string} title the title to use for the dialog
* @property {string} severity the severity level of this message.
* These are defined in a bundle constant with key 'dialogSeverity'
* @property {string} hint the 'hint' message to show below the title
* @property {string} actionText text that indicates a current action,
* shown above a progress bar to indicate what's happening.
* @property {number} progress a percentage value (1-100)
* indicating the completion of the blocking task
* @property {string} progressText the message to show below a
* progress bar to indicate progress. For example, this might be
* used to indicate time remaining, or items still to process.
* @property {boolean} unknownProgress some tasks may be
* impossible to provide an estimate for. Providing a true value for
* this attribute will indicate to the user that the progress and
* duration cannot be estimated.
* @property {DialogOption} primaryOption an action that will
* be added to the dialog as a button. The primary action can be
* used as the suggested course of action for the user. Making it
* distinct from other actions allows it to be styled differently,
* and treated preferentially in banner mode.
* @property {DialogOption[]} options a list of actions that will
* be added to the dialog as buttons.
*/
/**
* Displays a blocking (modal) dialog. This dialog can be used for
* displaying messages that require the user's
* immediate attention. The message may include an indication of
* progress, as well as a series of actions that
* the user can take if necessary
* @param {DialogModel} dialogModel defines options for the dialog
* @param {typeClass} string tells overlayService that this overlay should use appropriate CSS class
* @returns {boolean}
*/
DialogService.prototype.showBlockingMessage = function(dialogModel) {
if (this.canShowDialog(dialogModel)) {
// Add the overlay using the OverlayService, which
// will handle actual insertion into the DOM
this.overlay = this.overlayService.createOverlay(
"overlay-blocking-message",
dialogModel,
"t-dialog-sm"
);
// Track that a dialog is already visible, to
// avoid spawning multiple dialogs at once.
this.dialogVisible = true;
return true;
} else {
return false;
}
};
return DialogService; return DialogService;
} }

View File

@ -28,7 +28,7 @@ define(
// Template to inject into the DOM to show the dialog; really just points to // Template to inject into the DOM to show the dialog; really just points to
// the a specific template that can be included via mct-include // the a specific template that can be included via mct-include
var TEMPLATE = '<mct-include ng-model="overlay" key="key"></mct-include>'; var TEMPLATE = '<mct-include ng-model="overlay" key="key" ng-class="typeClass"></mct-include>';
/** /**
@ -71,8 +71,11 @@ define(
* @param {object} overlayModel the model to pass to the * @param {object} overlayModel the model to pass to the
* included overlay template (this will be passed * included overlay template (this will be passed
* in via ng-model) * in via ng-model)
* @param {string} typeClass the element class to use in rendering
* the overlay. Can be specified to provide custom styling of
* overlays
*/ */
OverlayService.prototype.createOverlay = function (key, overlayModel) { OverlayService.prototype.createOverlay = function (key, overlayModel, typeClass) {
// Create a new scope for this overlay // Create a new scope for this overlay
var scope = this.newScope(), var scope = this.newScope(),
element; element;
@ -90,6 +93,7 @@ define(
// Populate the scope; will be passed directly to the template // Populate the scope; will be passed directly to the template
scope.overlay = overlayModel; scope.overlay = overlayModel;
scope.key = key; scope.key = key;
scope.typeClass = typeClass || 't-dialog';
// Create the overlay element and add it to the document's body // Create the overlay element and add it to the document's body
element = this.$compile(TEMPLATE)(scope); element = this.$compile(TEMPLATE)(scope);

View File

@ -116,10 +116,22 @@ define(
dialog: dialogModel, dialog: dialogModel,
confirm: jasmine.any(Function), confirm: jasmine.any(Function),
cancel: jasmine.any(Function) cancel: jasmine.any(Function)
} },
't-dialog'
);
});
it("invokes the overlay service with the correct parameters when" +
" a blocking dialog is requested", function() {
var dialogModel = {};
expect(dialogService.showBlockingMessage(dialogModel)).toBe(true);
expect(mockOverlayService.createOverlay).toHaveBeenCalledWith(
"overlay-blocking-message",
dialogModel,
"t-dialog-sm"
); );
}); });
}); });
} }
); );

View File

@ -22,7 +22,8 @@
<div class='top-bar edit abs'> <div class='top-bar edit abs'>
<mct-representation key="'object-header'" <mct-representation key="'object-header'"
mct-object="domainObject" mct-object="domainObject"
parameters="{ mode: 'Edit' }"> parameters="{ mode: 'Edit' }"
class="l-flex-row flex-elem grows object-header">
</mct-representation> </mct-representation>
<div class='buttons-main btn-bar buttons abs'> <div class='buttons-main btn-bar buttons abs'>
<mct-representation key="'switcher'" <mct-representation key="'switcher'"

View File

@ -0,0 +1,26 @@
{
"name": "Time services bundle",
"description": "Defines interfaces and provides default implementations for handling different time systems.",
"extensions": {
"components": [
{
"provides": "formatService",
"type": "provider",
"implementation": "FormatProvider.js",
"depends": [ "formats[]" ]
}
],
"formats": [
{
"key": "utc",
"implementation": "UTCTimeFormat.js"
}
],
"constants": [
{
"key": "DEFAULT_TIME_FORMAT",
"value": "utc"
}
]
}
}

View File

@ -0,0 +1,114 @@
/*****************************************************************************
* 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";
/**
* An object used to convert between numeric values and text values,
* typically used to display these values to the user and to convert
* user input to a numeric format, particularly for time formats.
* @interface {Format}
*/
/**
* Parse text (typically user input) to a numeric value.
* Behavior is undefined when the text cannot be parsed;
* `validate` should be called first if the text may be invalid.
* @method parse
* @memberof Format#
* @param {string} text the text to parse
* @returns {number} the parsed numeric value
*/
/**
* Determine whether or not some text (typically user input) can
* be parsed to a numeric value by this format.
* @method validate
* @memberof Format#
* @param {string} text the text to parse
* @returns {boolean} true if the text can be parsed
*/
/**
* Convert a numeric value to a text value for display using
* this format.
* @method format
* @memberof Format#
* @param {number} value the numeric value to format
* @returns {string} the text representation of the value
*/
/**
* Provides access to `Format` objects which can be used to
* convert values between human-readable text and numeric
* representations.
* @interface FormatService
*/
/**
* Look up a format by its symbolic identifier.
* @method getFormat
* @memberof FormatService#
* @param {string} key the identifier for this format
* @returns {Format} the format
* @throws {Error} errors when the requested format is unrecognized
*/
/**
* Provides formats from the `formats` extension category.
* @constructor
* @implements {FormatService}
* @memberof platform/commonUI/formats
* @param {Array.<function(new : Format)>} format constructors,
* from the `formats` extension category.
*/
function FormatProvider(formats) {
var formatMap = {};
function addToMap(Format) {
var key = Format.key;
if (key && !formatMap[key]) {
formatMap[key] = new Format();
}
}
formats.forEach(addToMap);
this.formatMap = formatMap;
}
FormatProvider.prototype.getFormat = function (key) {
var format = this.formatMap[key];
if (!format) {
throw new Error("FormatProvider: No format found for " + key);
}
return format;
};
return FormatProvider;
});

View File

@ -0,0 +1,63 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define([
'moment'
], function (
moment
) {
"use strict";
var DATE_FORMAT = "YYYY-MM-DD HH:mm:ss",
DATE_FORMATS = [
DATE_FORMAT,
"YYYY-MM-DD HH:mm",
"YYYY-MM-DD"
];
/**
* Formatter for UTC timestamps. Interprets numeric values as
* milliseconds since the start of 1970.
*
* @implements {Format}
* @constructor
* @memberof platform/commonUI/formats
*/
function UTCTimeFormat() {
}
UTCTimeFormat.prototype.format = function (value) {
return moment.utc(value).format(DATE_FORMAT);
};
UTCTimeFormat.prototype.parse = function (text) {
return moment.utc(text, DATE_FORMATS).valueOf();
};
UTCTimeFormat.prototype.validate = function (text) {
return moment.utc(text, DATE_FORMATS).isValid();
};
return UTCTimeFormat;
});

View 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,Promise,describe,it,expect,beforeEach,waitsFor,jasmine*/
define(
['../src/FormatProvider'],
function (FormatProvider) {
'use strict';
var KEYS = [ 'a', 'b', 'c' ];
describe("The FormatProvider", function () {
var mockFormats,
mockLog,
mockFormatInstances,
provider;
beforeEach(function () {
mockFormatInstances = KEYS.map(function (k) {
return jasmine.createSpyObj(
'format-' + k,
[ 'parse', 'validate', 'format' ]
);
});
// Return constructors
mockFormats = KEYS.map(function (k, i) {
function MockFormat() { return mockFormatInstances[i]; }
MockFormat.key = k;
return MockFormat;
});
provider = new FormatProvider(mockFormats);
});
it("looks up formats by key", function () {
KEYS.forEach(function (k, i) {
expect(provider.getFormat(k))
.toEqual(mockFormatInstances[i]);
});
});
it("throws an error about unknown formats", function () {
expect(function () {
provider.getFormat('some-unknown-format');
}).toThrow();
});
});
}
);

View File

@ -0,0 +1,56 @@
/*****************************************************************************
* 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/UTCTimeFormat', 'moment'],
function (UTCTimeFormat, moment) {
'use strict';
describe("The UTCTimeFormat", function () {
var format;
beforeEach(function () {
format = new UTCTimeFormat();
});
it("formats UTC timestamps", function () {
var timestamp = 12345670000,
formatted = format.format(timestamp);
expect(formatted).toEqual(jasmine.any(String));
expect(moment.utc(formatted).valueOf()).toEqual(timestamp);
});
it("validates time inputs", function () {
expect(format.validate("1977-05-25 11:21:22")).toBe(true);
expect(format.validate("garbage text")).toBe(false);
});
it("parses valid input", function () {
var text = "1977-05-25 11:21:22",
parsed = format.parse(text);
expect(parsed).toEqual(jasmine.any(Number));
expect(parsed).toEqual(moment.utc(text).valueOf());
});
});
}
);

View File

@ -0,0 +1,4 @@
[
"FormatProvider",
"UTCTimeFormat"
]

View File

@ -18,7 +18,7 @@
"runs": [ "runs": [
{ {
"implementation": "StyleSheetLoader.js", "implementation": "StyleSheetLoader.js",
"depends": [ "stylesheets[]", "$document" ] "depends": [ "stylesheets[]", "$document", "THEME" ]
} }
], ],
"stylesheets": [ "stylesheets": [
@ -44,6 +44,14 @@
"key": "indicator", "key": "indicator",
"templateUrl": "templates/indicator.html" "templateUrl": "templates/indicator.html"
}, },
{
"key": "message-banner",
"templateUrl": "templates/message-banner.html"
},
{
"key": "progress-bar",
"templateUrl": "templates/progress-bar.html"
},
{ {
"key": "time-controller", "key": "time-controller",
"templateUrl": "templates/controls/time-controller.html" "templateUrl": "templates/controls/time-controller.html"
@ -53,13 +61,18 @@
{ {
"key": "TimeRangeController", "key": "TimeRangeController",
"implementation": "controllers/TimeRangeController.js", "implementation": "controllers/TimeRangeController.js",
"depends": [ "$scope", "now" ] "depends": [ "$scope", "formatService", "DEFAULT_TIME_FORMAT", "now" ]
}, },
{ {
"key": "DateTimePickerController", "key": "DateTimePickerController",
"implementation": "controllers/DateTimePickerController.js", "implementation": "controllers/DateTimePickerController.js",
"depends": [ "$scope", "now" ] "depends": [ "$scope", "now" ]
}, },
{
"key": "DateTimeFieldController",
"implementation": "controllers/DateTimeFieldController.js",
"depends": [ "$scope", "formatService", "DEFAULT_TIME_FORMAT" ]
},
{ {
"key": "TreeNodeController", "key": "TreeNodeController",
"implementation": "controllers/TreeNodeController.js", "implementation": "controllers/TreeNodeController.js",
@ -107,6 +120,16 @@
"key": "SelectorController", "key": "SelectorController",
"implementation": "controllers/SelectorController.js", "implementation": "controllers/SelectorController.js",
"depends": [ "objectService", "$scope" ] "depends": [ "objectService", "$scope" ]
},
{
"key": "ObjectInspectorController",
"implementation": "controllers/ObjectInspectorController.js",
"depends": [ "$scope", "objectService" ]
},
{
"key": "BannerController",
"implementation": "controllers/BannerController.js",
"depends": ["$scope", "notificationService", "dialogService"]
} }
], ],
"directives": [ "directives": [
@ -171,6 +194,11 @@
{ {
"key": "MCT_SCROLL_Y_ATTRIBUTE", "key": "MCT_SCROLL_Y_ATTRIBUTE",
"value": "mctScrollY" "value": "mctScrollY"
},
{
"key": "THEME",
"value": "unspecified",
"priority": "fallback"
} }
], ],
"containers": [ "containers": [
@ -232,6 +260,10 @@
"key": "switcher", "key": "switcher",
"templateUrl": "templates/controls/switcher.html", "templateUrl": "templates/controls/switcher.html",
"uses": [ "view" ] "uses": [ "view" ]
},
{
"key": "object-inspector",
"templateUrl": "templates/object-inspector.html"
} }
], ],
"controls": [ "controls": [
@ -242,6 +274,10 @@
{ {
"key": "datetime-picker", "key": "datetime-picker",
"templateUrl": "templates/controls/datetime-picker.html" "templateUrl": "templates/controls/datetime-picker.html"
},
{
"key": "datetime-field",
"templateUrl": "templates/controls/datetime-field.html"
} }
], ],
"licenses": [ "licenses": [

View File

@ -76,7 +76,7 @@
<glyph unicode="&#xf4;" glyph-name="icon-link" d="M1024 448l-512 512v-307.2l-512-204.8v-256h512v-256z" /> <glyph unicode="&#xf4;" glyph-name="icon-link" d="M1024 448l-512 512v-307.2l-512-204.8v-256h512v-256z" />
<glyph unicode="&#xf5;" glyph-name="icon-timer" 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="&#xf5;" glyph-name="icon-timer" 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="&#xf6;" glyph-name="icon-thumbs-strip" 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="&#xf6;" glyph-name="icon-thumbs-strip" 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="&#xe600;" glyph-name="icon-box-with-arrow-cursor" 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="&#xe600;" glyph-name="icon-box-with-arrow-cursor" d="M894 962h-768c-70.4 0-128-57.6-128-128v-768c0-70.4 57.6-128 128-128h400c-2.2 3.8-4 7.6-5.8 11.4l-255.2 576.8c-21.4 48.4-10.8 105 26.6 142.4 24.4 24.4 57.2 37.4 90.4 37.4 17.4 0 35.2-3.6 51.8-11l576.6-255.4c4-1.8 7.8-3.8 11.4-5.8v400.2c0.2 70.4-57.4 128-127.8 128zM958.6 322.6l-576.6 255.4 255.4-576.6 64.6 128.6 192-192 128 128-192 192z" />
<glyph unicode="&#xe601;" glyph-name="icon-datatable" d="M1024 768c0-106.039-229.23-192-512-192s-512 85.961-512 192c0 106.039 229.23 192 512 192s512-85.961 512-192zM512 448c-282.8 0-512 86-512 192v-512c0-106 229.2-192 512-192s512 86 512 192v512c0-106-229.2-192-512-192zM896 385v-256c-36.6-15.6-79.8-28.8-128-39.4v256c48.2 10.6 91.4 23.8 128 39.4zM256 345.6v-256c-48.2 10.4-91.4 23.8-128 39.4v256c36.6-15.6 79.8-28.8 128-39.4zM384 70v256c41-4 83.8-6 128-6s87 2.2 128 6v-256c-41-4-83.8-6-128-6s-87 2.2-128 6z" /> <glyph unicode="&#xe601;" glyph-name="icon-datatable" d="M1024 768c0-106.039-229.23-192-512-192s-512 85.961-512 192c0 106.039 229.23 192 512 192s512-85.961 512-192zM512 448c-282.8 0-512 86-512 192v-512c0-106 229.2-192 512-192s512 86 512 192v512c0-106-229.2-192-512-192zM896 385v-256c-36.6-15.6-79.8-28.8-128-39.4v256c48.2 10.6 91.4 23.8 128 39.4zM256 345.6v-256c-48.2 10.4-91.4 23.8-128 39.4v256c36.6-15.6 79.8-28.8 128-39.4zM384 70v256c41-4 83.8-6 128-6s87 2.2 128 6v-256c-41-4-83.8-6-128-6s-87 2.2-128 6z" />
<glyph unicode="&#xe602;" glyph-name="icon-tabular-scrolling" d="M64 960c-35.2 0-64-28.8-64-64v-192h448v256h-384zM1024 704v192c0 35.2-28.8 64-64 64h-384v-256h448zM0 576v-192c0-35.2 28.8-64 64-64h384v256h-448zM960 320c35.2 0 64 28.8 64 64v192h-448v-256h384zM512-64l-256 256h512z" /> <glyph unicode="&#xe602;" glyph-name="icon-tabular-scrolling" d="M64 960c-35.2 0-64-28.8-64-64v-192h448v256h-384zM1024 704v192c0 35.2-28.8 64-64 64h-384v-256h448zM0 576v-192c0-35.2 28.8-64 64-64h384v256h-448zM960 320c35.2 0 64 28.8 64 64v192h-448v-256h384zM512-64l-256 256h512z" />
<glyph unicode="&#xe603;" glyph-name="icon-alert-triangle" d="M998.208 111.136l-422.702 739.728c-34.928 61.124-92.084 61.124-127.012 0l-422.702-739.728c-34.928-61.126-5.906-111.136 64.494-111.136h843.428c70.4 0 99.422 50.010 64.494 111.136zM512 128c-35.2 0-64 28.8-64 64s28.8 64 64 64 64-28.8 64-64c0-35.2-28.8-64-64-64zM627.448 577.242l-38.898-194.486c-6.902-34.516-41.35-62.756-76.55-62.756s-69.648 28.24-76.552 62.758l-38.898 194.486c-6.902 34.516 16.25 62.756 51.45 62.756h128c35.2 0 58.352-28.24 51.448-62.758z" /> <glyph unicode="&#xe603;" glyph-name="icon-alert-triangle" d="M998.208 111.136l-422.702 739.728c-34.928 61.124-92.084 61.124-127.012 0l-422.702-739.728c-34.928-61.126-5.906-111.136 64.494-111.136h843.428c70.4 0 99.422 50.010 64.494 111.136zM512 128c-35.2 0-64 28.8-64 64s28.8 64 64 64 64-28.8 64-64c0-35.2-28.8-64-64-64zM627.448 577.242l-38.898-194.486c-6.902-34.516-41.35-62.756-76.55-62.756s-69.648 28.24-76.552 62.758l-38.898 194.486c-6.902 34.516 16.25 62.756 51.45 62.756h128c35.2 0 58.352-28.24 51.448-62.758z" />
@ -85,6 +85,14 @@
<glyph unicode="&#xe606;" glyph-name="icon-paint-bucket" d="M544 736v-224c0-88.4-71.6-160-160-160s-160 71.6-160 160v97.2l-197.4-196.4c-50-50-12.4-215.2 112.4-340s290-162.4 340-112.4l417 423.6-352 352zM896-64c70.6 0 128 57.4 128 128 0 108.6-128 192-128 192s-128-83.4-128-192c0-70.6 57.4-128 128-128zM384 448c-35.4 0-64 28.6-64 64v384c0 35.4 28.6 64 64 64s64-28.6 64-64v-384c0-35.4-28.6-64-64-64z" /> <glyph unicode="&#xe606;" glyph-name="icon-paint-bucket" d="M544 736v-224c0-88.4-71.6-160-160-160s-160 71.6-160 160v97.2l-197.4-196.4c-50-50-12.4-215.2 112.4-340s290-162.4 340-112.4l417 423.6-352 352zM896-64c70.6 0 128 57.4 128 128 0 108.6-128 192-128 192s-128-83.4-128-192c0-70.6 57.4-128 128-128zM384 448c-35.4 0-64 28.6-64 64v384c0 35.4 28.6 64 64 64s64-28.6 64-64v-384c0-35.4-28.6-64-64-64z" />
<glyph unicode="&#xe607;" glyph-name="icon-x-in-circle" d="M512 960c-282.8 0-512-229.2-512-512s229.2-512 512-512 512 229.2 512 512-229.2 512-512 512zM832 256l-128-128-192 192-192-192-128 128 192 192-192 192 128 128 192-192 192 192 128-128-192-192 192-192z" /> <glyph unicode="&#xe607;" glyph-name="icon-x-in-circle" d="M512 960c-282.8 0-512-229.2-512-512s229.2-512 512-512 512 229.2 512 512-229.2 512-512 512zM832 256l-128-128-192 192-192-192-128 128 192 192-192 192 128 128 192-192 192 192 128-128-192-192 192-192z" />
<glyph unicode="&#xe608;" glyph-name="icon-info-v15" d="M512 960c-282.8 0-512-229.2-512-512s229.2-512 512-512 512 229.2 512 512-229.2 512-512 512zM512 832c70.6 0 128-57.4 128-128s-57.4-128-128-128c-70.6 0-128 57.4-128 128s57.4 128 128 128zM704 128h-384v128h64v256h256v-256h64v-128z" /> <glyph unicode="&#xe608;" glyph-name="icon-info-v15" d="M512 960c-282.8 0-512-229.2-512-512s229.2-512 512-512 512 229.2 512 512-229.2 512-512 512zM512 832c70.6 0 128-57.4 128-128s-57.4-128-128-128c-70.6 0-128 57.4-128 128s57.4 128 128 128zM704 128h-384v128h64v256h256v-256h64v-128z" />
<glyph unicode="&#xe609;" glyph-name="icon-hourglass" d="M1024 960h-1024c0-282.8 229.2-512 512-512s512 229.2 512 512zM512 576c-102.6 0-199 40-271.6 112.4-41.2 41.2-72 90.2-90.8 143.6h724.6c-18.8-53.4-49.6-102.4-90.8-143.6-72.4-72.4-168.8-112.4-271.4-112.4zM512 448c-282.8 0-512-229.2-512-512h1024c0 282.8-229.2 512-512 512z" />
<glyph unicode="&#xe60d;" glyph-name="icon-arrows-right-left" d="M1024 448l-448-512v1024zM448 960l-448-512 448-512z" /> <glyph unicode="&#xe60d;" glyph-name="icon-arrows-right-left" d="M1024 448l-448-512v1024zM448 960l-448-512 448-512z" />
<glyph unicode="&#xe610;" glyph-name="icon-bell" d="M512-64c106 0 192 86 192 192h-384c0-106 86-192 192-192zM896 512v64c0 212-172 384-384 384s-384-172-384-384v-64c0-70.6-57.4-128-128-128v-128h1024v128c-70.6 0-128 57.4-128 128z" />
<glyph unicode="&#xe611;" glyph-name="icon-dataset" 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 128zM320 64h-128v320h128v-320zM576 64h-128v320h128v-320zM832 64h-128v320h128v-320z" />
<glyph unicode="&#xe612;" glyph-name="icon-save" d="M192.2 384c-0.2 0-0.2 0 0 0l-0.2-448h640v447.8c0 0 0 0-0.2 0.2h-639.6zM978.8 749.2l-165.4 165.4c-25 25-74.2 45.4-109.4 45.4h-576c-70.4 0-128-57.6-128-128v-768c0-70.4 57.6-128 128-128v448c0 35.2 28.8 64 64 64h640c35.2 0 64-28.8 64-64v-448c70.4 0 128 57.6 128 128v576c0 35.2-20.4 84.4-45.2 109.2zM704 704c0-35.2-28.8-64-64-64h-448c-35.2 0-64 28.8-64 64v192h320v-192h128v192h128v-192z" />
<glyph unicode="&#xe613;" glyph-name="icon-collapse-pane-left" d="M256 960h-256v-1024h256c105.6 0 192 86.4 192 192v640c0 105.6-86.4 192-192 192zM512 640l512-320v640z" />
<glyph unicode="&#xe614;" glyph-name="icon-collapse-pane-right" d="M768 960h256v-1024h-256c-105.6 0-192 86.4-192 192v640c0 105.6 86.4 192 192 192zM512 640l-512-320v640z" />
<glyph unicode="&#xe615;" glyph-name="icon-eye-open" d="M512 896c-261 0-480.6-195.4-512-448 31.4-252.6 251-448 512-448s480.6 195.4 512 448c-31.4 252.6-251 448-512 448zM768.2 225.4c-71.4-62.8-162.8-97.4-257.6-97.4s-186.2 34.6-257.6 97.4c-66.6 58.6-110.6 137.2-125 222.6 0 0 0 0.2 0 0.2 76.8 154 220.8 257.6 384 257.6s307.2-103.8 384-257.6c0 0 0-0.2 0-0.2-14.4-85.4-61.2-164-127.8-222.6zM512 672c-123.8 0-224-100.2-224-224s100.2-224 224-224 224 100.2 224 224-100.2 224-224 224z" />
<glyph unicode="&#xe616;" glyph-name="icon-eye-open-no-gleam" d="M512 896c-261 0-480.6-195.4-512-448 31.4-252.6 251-448 512-448s480.6 195.4 512 448c-31.4 252.6-251 448-512 448zM768.2 225.4c-71.4-62.8-162.8-97.4-257.6-97.4s-186.2 34.6-257.6 97.4c-66.6 58.6-110.6 137.2-125 222.6 0 0 0 0.2 0 0.2 76.8 154 220.8 257.6 384 257.6s307.2-103.8 384-257.6c0 0 0-0.2 0-0.2-14.4-85.4-61.2-164-127.8-222.6zM512 672c-123.8 0-224-100.2-224-224s100.2-224 224-224 224 100.2 224 224-100.2 224-224 224zM576 416c-53 0-96 43-96 96s43 96 96 96 96-43 96-96c0-53-43-96-96-96z" />
<glyph unicode="&#xe642;" glyph-name="icon-x" d="M384 448l-365.332-365.332c-24.89-24.89-24.89-65.62 0-90.51l37.49-37.49c24.89-24.89 65.62-24.89 90.51 0 0 0 365.332 365.332 365.332 365.332l365.332-365.332c24.89-24.89 65.62-24.89 90.51 0l37.49 37.49c24.89 24.89 24.89 65.62 0 90.51l-365.332 365.332c0 0 365.332 365.332 365.332 365.332 24.89 24.89 24.89 65.62 0 90.51l-37.49 37.49c-24.89 24.89-65.62 24.89-90.51 0 0 0-365.332-365.332-365.332-365.332l-365.332 365.332c-24.89 24.89-65.62 24.89-90.51 0l-37.49-37.49c-24.89-24.89-24.89-65.62 0-90.51 0 0 365.332-365.332 365.332-365.332z" /> <glyph unicode="&#xe642;" glyph-name="icon-x" d="M384 448l-365.332-365.332c-24.89-24.89-24.89-65.62 0-90.51l37.49-37.49c24.89-24.89 65.62-24.89 90.51 0 0 0 365.332 365.332 365.332 365.332l365.332-365.332c24.89-24.89 65.62-24.89 90.51 0l37.49 37.49c24.89 24.89 24.89 65.62 0 90.51l-365.332 365.332c0 0 365.332 365.332 365.332 365.332 24.89 24.89 24.89 65.62 0 90.51l-37.49 37.49c-24.89 24.89-65.62 24.89-90.51 0 0 0-365.332-365.332-365.332-365.332l-365.332 365.332c-24.89 24.89-65.62 24.89-90.51 0l-37.49-37.49c-24.89-24.89-24.89-65.62 0-90.51 0 0 365.332-365.332 365.332-365.332z" />
</font></defs></svg> </font></defs></svg>

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -0,0 +1,147 @@
/*****************************************************************************
* 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.
*****************************************************************************/
/********************************************* COLUMN LAYOUTS STYLES */
@mixin cols($totalCols, $span) {
$cw: 100% / $totalCols;
min-width: (500px / $totalCols) * $span;
@if ($totalCols != $span) {
width: ($cw * $span) - $ueColMargin;
} @else {
width: $cw;
}
}
.cols {
@include clearfix;
.col {
@include box-sizing(border-box);
@include clearfix;
float: left;
margin-left: $ueColMargin;
padding-left: $interiorMargin;
position: relative;
&:first-child {
margin-left: 0;
padding-left: 0;
}
}
&.cols-2 {
$nc: 2;
.col-1 {
@include cols($nc, 1);
}
}
&.cols-2-ff {
// 2 columns, first column is fixed, second is fluid
.col-100px {
width: 100px;
}
}
&.cols-6 {
$nc: 6;
.col-1 {
@include cols($nc, 1);
}
}
&.cols-16 {
$nc: 16;
.col-1 {
@include cols($nc, 1);
}
.col-2 {
@include cols($nc, 2);
}
.col-7 {
@include cols($nc, 7);
}
}
&.cols-32 {
$nc: 32;
.col-2 {
@include cols($nc, 2);
}
.col-15 {
@include cols($nc, 15);
}
}
.l-row {
@include clearfix;
padding: $interiorMargin 0;
}
}
/********************************************* FLEX STYLES */
.l-flex-row,
.l-flex-col {
@include display-flex;
@include flex-wrap(nowrap);
.flex-elem {
min-height: 0; // Needed to allow element to shrink within parent
position: relative;
&:not(.grows) {
@include flex(0 0 auto);
&.flex-can-shrink {
@include flex(0 1 auto);
}
}
&.grows {
@include flex(1 1 auto);
}
}
.flex-container {
// Apply to wrapping elements, mct-includes, etc.
@include display-flex;
@include flex-wrap(nowrap);
@include flex(1 1 auto);
min-height:0;
}
}
.l-flex-row {
@include flex-direction(row);
&.flex-elem { @include flex(1 1 auto); }
.flex-elem {
height: inherit;
line-height: inherit;
min-width: 0;
}
.flex-container { @include flex-direction(row); }
}
.l-flex-col {
@include flex-direction(column);
.flex-elem {
min-height: 0;
&.holder:not(:last-child) { margin-bottom: $interiorMarginLg; }
}
.flex-container { @include flex-direction(column); }
}
.flex-fixed {
@include flex(0 0 auto);
}
.flex-justify-end {
@include justify-content(flex-end);
}

View File

@ -35,20 +35,32 @@ $ltGamma: 20%;
$btnFontSizeToH: 0.45; $btnFontSizeToH: 0.45;
/************************** LAYOUT */ /************************** LAYOUT */
$ueTopBarH: 24px; // Change when breadcrumb is enabled $ueTopBarH: 24px;
$ueTopBarEditH: 30px; $ueTopBarEditH: 30px;
$ueTopBarBtnH: 35px; $ueTopBarBtnH: 35px;
$ueFooterH: 25px; $ueFooterH: 25px;
$ueColMargin: 1.5%; $ueColMargin: 1.5%;
$ueAppLogoW: 105px; $ueAppLogoW: 105px;
$ueEditToolBarH: 25px; $ueEditToolBarH: 25px;
$ueBrowseLeftPaneW: 25%; $ueCollapsedPaneEdgeM: 22px;
$uePaneMiniTabH: $ueTopBarH;
$uePaneMiniTabW: 9px;
$uePaneMiniTabCollapsedW: 11px;
$ueEditLeftPaneW: 75%; $ueEditLeftPaneW: 75%;
$treeSearchInputBarH: 25px; $treeSearchInputBarH: 25px;
$ueTimeControlH: (33px, 20px, 20px); $ueTimeControlH: (33px, 20px, 20px);
// Panes
$ueBrowseLeftPaneTreeMinW: 150px;
$ueBrowseLeftPaneTreeMaxW: 35%;
$ueBrowseLeftPaneTreeW: 25%;
$ueBrowseRightPaneInspectMinW: 200px;
$ueBrowseRightPaneInspectMaxW: 35%;
$ueBrowseRightPaneInspectW: 20%;
$ueDesktopMinW: 600px;
// Overlay // Overlay
$ovrTopBarH: 60px; $ovrTopBarH: 45px;
$ovrFooterH: 30px; $ovrFooterH: 24px;
$overlayMargin: 25px; $overlayMargin: 25px;
// Items // Items
$ueBrowseGridItemLg: 200px; $ueBrowseGridItemLg: 200px;
@ -57,7 +69,8 @@ $ueBrowseGridItemBottomBarH: 30px;
$itemPadLR: 5px; $itemPadLR: 5px;
// Tree // Tree
$treeVCW: 10px; $treeVCW: 10px;
$treeTypeIconH: 16px; $treeTypeIconH: 1.4em; // was 16px
$treeTypeIconHPx: 16px;
$treeTypeIconW: 20px; $treeTypeIconW: 20px;
$treeContextTriggerW: 20px; $treeContextTriggerW: 20px;
// Tabular // Tabular
@ -106,3 +119,8 @@ $dirImgs: $dirCommonRes + 'images/';
/************************** TIMINGS */ /************************** TIMINGS */
$controlFadeMs: 100ms; $controlFadeMs: 100ms;
/************************** LIMITS */
$glyphLimit: '\e603';
$glyphLimitUpr: '\0000eb';
$glyphLimitLwr: '\0000ee';

View File

@ -34,10 +34,6 @@
font-style: normal; font-style: normal;
} }
.ui-symbol {
font-family: 'symbolsfont';
}
/************************** HTML ENTITIES */ /************************** HTML ENTITIES */
a { a {
color: $colorA; color: $colorA;
@ -55,7 +51,7 @@ body, html {
color: $colorBodyFg; color: $colorBodyFg;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 100%; font-size: 100%;
//font-weight: 500; font-weight: 200;
height: 100%; height: 100%;
width: 100%; width: 100%;
overflow: hidden; overflow: hidden;
@ -146,6 +142,16 @@ mct-container {
display: none !important; display: none !important;
} }
.off {
visibility: hidden;
opacity: 0;
height: 0;
margin: 0;
padding: 0;
border: 0;
margin: 0 !important;
}
.sep { .sep {
color: rgba(#fff, 0.2); color: rgba(#fff, 0.2);
} }

View File

@ -29,11 +29,14 @@
} }
.ui-symbol { .ui-symbol {
font-family: 'symbolsfont';
&.type-icon { &.type-icon {
color: $colorObjHdrIc; color: $colorObjHdrIc;
} }
&.icon { &.icon {
color: $colorKey; color: $colorKey;
//position: relative;
font-size: inherit;
&.alert { &.alert {
color: $colorAlert; color: $colorAlert;
&:hover { &:hover {
@ -69,18 +72,32 @@
position: absolute; position: absolute;
} }
//.tree-item .type-icon {
// font-size: 16px; // 16px is crisp size
//}
.l-icon-link:before {
content: "\f4";
}
.l-icon-alert { .l-icon-alert {
display: none !important; // Remove this when alerts are enabled display: none !important; // Remove this when alerts are enabled
&:before { &:before {
color: $colorAlert; color: $colorAlert;
content: "!"; content: "!";
} }
}
// NEW!!
.t-item-icon {
// Used in grid-item.html, tree-item, inspector location, more?
@extend .ui-symbol;
@extend .icon;
display: inline-block;
line-height: normal; // This is Ok for the symbolsfont
position: relative;
&.l-icon-link {
&:before {
color: $colorIconLink;
content: "\f4";
height: auto; width: auto;
position: absolute;
left: 0; top: 0; right: 0; bottom: 10%;
@include transform-origin(bottom, left);
@include transform(scale(0.3));
z-index: 2;
}
}
} }

View File

@ -0,0 +1,112 @@
/*****************************************************************************
* 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.
*****************************************************************************/
/* Styles for the Inspector pane */
.l-inspect,
.l-inspect table tr td {
font-size: 0.7rem;
}
.l-inspect {
@extend .abs;
background: $colorInspectorBg;
color: $colorInspectorFg;
line-height: 140%;
.pane-header {
color: pushBack($colorInspectorFg, 20%);
font-size: 0.8rem;
&:before {
color: pushBack($colorInspectorFg, 10%);
content:'\e615'; // e615 Crosshair symbol
display: inline;
font-family: symbolsfont;
margin-right: $interiorMargin;
vertical-align: bottom;
}
}
ul {
@include box-sizing(border-box);
padding-right: $interiorMargin;
}
ul li,
em {
display: block;
position: relative;
}
ul li {
margin-bottom: $interiorMarginLg;
}
em {
@include border-radius($basicCr);
background-color: $colorInspectorSectionHeaderBg;
color: $colorInspectorSectionHeaderFg;
margin-bottom: $interiorMargin;
padding: $formTBPad $formLRPad;
text-transform: uppercase;
}
.inspector-properties {
&:not(.first) {
border-top: 1px solid $colorInspectorSectionHeaderBg;
}
padding: $interiorMarginSm 0;
.label {
color: $colorInspectorPropName;
text-transform: uppercase;
}
.value {
color: $colorInspectorPropVal;
word-break: break-all;
}
}
.inspector-location {
//line-height: 180%;
.location-item {
cursor: pointer;
display: inline-block;
position: relative;
padding: 2px 4px;
&:hover {
background: $colorItemTreeHoverBg;
color: $colorItemTreeHoverFg;
.icon {
color: $colorItemTreeIconHover;
}
}
}
&:not(.last) .t-object-label .t-title-label:after {
color: pushBack($colorInspectorFg, 15%);
content: '\3e';
display: inline-block;
font-family: symbolsfont;
font-size: 8px;
line-height: inherit;
margin-left: $interiorMarginSm;
width: 4px;
}
}
}

View File

@ -1,26 +1,39 @@
@mixin limit($bg, $ic, $glyph) { @mixin limitGlyph($iconColor, $glyph: $glyphLimit) {
background: $bg !important; &:before {
//color: $fg !important; color: $iconColor;
&:before { content: $glyph;
//@include pulse(1000ms); font-family: symbolsfont;
color: $ic; font-size: 0.8em;
content: $glyph; display: inline;
} margin-right: $interiorMarginSm;
}
} }
[class*="s-limit"] { .s-limit-red { background: $colorLimitRedBg !important; }
//white-space: nowrap; .s-limit-yellow { background: $colorLimitYellowBg !important; }
&:before {
display: inline-block; // Handle limit when applied to a tr
font-family: symbolsfont; tr[class*="s-limit"] {
font-size: 0.75em; &.s-limit-red td:first-child {
font-style: normal !important; @include limitGlyph($colorLimitRedIc);
margin-right: $interiorMarginSm; }
vertical-align: middle; &.s-limit-yellow td:first-child {
} @include limitGlyph($colorLimitYellowIc);
}
&.s-limit-upr td:first-child:before { content:$glyphLimitUpr; }
&.s-limit-lwr td:first-child:before { content:$glyphLimitLwr; }
} }
.s-limit-upr-red { @include limit($colorLimitRedBg, $colorLimitRedIc, "\0000eb"); }; // Handle limit when applied directly to a non-tr element
.s-limit-upr-yellow { @include limit($colorLimitYellowBg, $colorLimitYellowIc, "\0000ed"); }; // Assume this is applied to the element that displays the limit value
.s-limit-lwr-yellow { @include limit($colorLimitYellowBg, $colorLimitYellowIc, "\0000ec"); }; :not(tr)[class*="s-limit"] {
.s-limit-lwr-red { @include limit($colorLimitRedBg, $colorLimitRedIc, "\0000ee"); }; &.s-limit-red {
@include limitGlyph($colorLimitRedIc);
}
&.s-limit-yellow {
@include limitGlyph($colorLimitYellowIc);
}
&.s-limit-upr:before { content:$glyphLimitUpr; }
&.s-limit-lwr:before { content:$glyphLimitLwr; }
}

View File

@ -21,6 +21,7 @@
*****************************************************************************/ *****************************************************************************/
@import "effects"; @import "effects";
@import "global"; @import "global";
@import "archetypes";
@import "about"; @import "about";
@import "text"; @import "text";
@import "icons"; @import "icons";
@ -29,8 +30,7 @@
@import "helpers/bubbles"; @import "helpers/bubbles";
@import "helpers/splitter"; @import "helpers/splitter";
@import "helpers/wait-spinner"; @import "helpers/wait-spinner";
@import "messages"; @import "inspector";
@import "properties";
/********************************* CONTROLS */ /********************************* CONTROLS */
@import "controls/breadcrumb"; @import "controls/breadcrumb";
@ -39,6 +39,7 @@
@import "controls/controls"; @import "controls/controls";
@import "controls/lists"; @import "controls/lists";
@import "controls/menus"; @import "controls/menus";
@import "controls/messages";
@import "controls/time-controller"; @import "controls/time-controller";
@import "mobile/controls/menus"; @import "mobile/controls/menus";
@ -62,7 +63,6 @@
@import "mobile/tree"; @import "mobile/tree";
@import "user-environ/frame"; @import "user-environ/frame";
@import "user-environ/top-bar"; @import "user-environ/top-bar";
@import "user-environ/bottom-bar";
@import "user-environ/tool-bar"; @import "user-environ/tool-bar";
/********************************* VIEWS */ /********************************* VIEWS */
@ -70,7 +70,6 @@
@import "lists/tabular"; @import "lists/tabular";
@import "plots/plots-main"; @import "plots/plots-main";
@import "iframe"; @import "iframe";
@import "hide-non-functional";
@import "views"; @import "views";
@import "items/item"; @import "items/item";
@import "mobile/item"; @import "mobile/item";

View File

@ -1,12 +0,0 @@
/* Styles for messages */
.message {
&.block {
@include border-radius($basicCr);
padding: $interiorMarginLg;
}
&.error {
background-color: rgba($colorAlert,0.3);
color: lighten($colorAlert, 20%);
}
}

View File

@ -41,36 +41,41 @@
width: $d; width: $d;
} }
@mixin trans-prop-nice($props, $t: 500ms) { @mixin trans-prop-nice($props, $dur: 500ms, $delay: 0) {
@if $t == 0 { // Multiple $props must be in parans like this: (left, right)
@if $dur == 0 {
@include transition-property(none); @include transition-property(none);
} @else { } @else {
@include transition-property($props); @include transition-property($props);
@include transition-duration($t); @include transition-duration($dur);
@include transition-timing-function(ease-in-out); @include transition-timing-function(ease-in-out);
@include transition-delay($delay);
} }
} }
@mixin trans-prop-nice-fade($t: 0.5s) { @mixin trans-prop-nice-fade($dur: 500ms, $delay: 0) {
@if $t == 0 { @if $dur == 0 {
@include transition-property(none); @include transition-property(none);
} @else { } @else {
@include transition-property(visibility, opacity, background-color, border-color); @include transition-property(opacity, background-color, border-color, color);
@include transition-duration($t); @include transition-duration($dur);
@include transition-timing-function(ease-in-out); @include transition-timing-function(ease-in-out);
@include transition-delay($delay);
} }
} }
@mixin trans-prop-nice-resize-h($t: 0.5s) { @mixin trans-prop-nice-resize-h($dur: 500ms, $delay: 0) {
@include transition-property(height, bottom, top); @include transition-property(height, bottom, top);
@include transition-duration($t); @include transition-duration($dur);
@include transition-timing-function(ease-in-out); @include transition-timing-function(ease-in-out);
@include transition-delay($delay);
} }
@mixin trans-prop-nice-resize-w($t: 0.5s) { @mixin trans-prop-nice-resize-w($dur: 500ms, $delay: 0) {
@include transition-property(width, left, right); @include transition-property(width, left, right);
@include transition-duration($t); @include transition-duration($dur);
@include transition-timing-function(ease-in-out); @include transition-timing-function(ease-in-out);
@include transition-delay($delay);
} }
@mixin triangle-right($size, $color) { @mixin triangle-right($size, $color) {
@ -94,7 +99,6 @@
} }
@mixin triangle($dir: "left", $size: 5px, $ratio: 1, $color: red) { @mixin triangle($dir: "left", $size: 5px, $ratio: 1, $color: red) {
//$size: $size*2;
width: 0; width: 0;
height: 0; height: 0;
$slopedB: $size/$ratio solid transparent; $slopedB: $size/$ratio solid transparent;
@ -129,6 +133,24 @@
background-size: $d $d; background-size: $d $d;
} }
@mixin bgVertStripes($c: yellow, $a: 0.1, $d: 40px) {
@include background-image(linear-gradient(-90deg,
rgba($c, $a) 0%, rgba($c, $a) 50%,
transparent 50%, transparent 100%
));
background-repeat: repeat;
background-size: $d $d;
}
@mixin bgVertFuzzyStripes($c: yellow, $a: 0.1, $d: 40px) {
@include background-image(linear-gradient(-90deg,
rgba($c, $a) 0%, transparent 50%,
transparent 50%, rgba($c, $a) 100%
));
background-repeat: repeat;
background-size: $d $d;
}
@mixin bgTicks($c: $colorBodyFg, $repeatDir: 'x') { @mixin bgTicks($c: $colorBodyFg, $repeatDir: 'x') {
$deg: 90deg; $deg: 90deg;
@if ($repeatDir != 'x') { @if ($repeatDir != 'x') {
@ -156,31 +178,28 @@
} }
@mixin controlGrippy($b, $direction: horizontal, $w: 1px, $style: dotted) { @mixin controlGrippy($b, $direction: horizontal, $w: 1px, $style: dotted) {
&:before { //&:before {
@include trans-prop-nice("border-color", 0.75s); //@include trans-prop-nice("border-color", 25ms);
content: ''; content: '';
display: block; display: block;
height: auto; //height: auto;
pointer-events: none; pointer-events: none;
position: absolute; position: absolute;
z-index: 2; z-index: 2;
@if $direction == "horizontal" { @if $direction == "horizontal" {
border-top: $w $style darken($b, 15%); border-top: $w $style darken($b, 15%);
top: 2px; top: 2px;
left: 5px; left: 5px;
right: 5px; right: 5px;
height: 1px;
} @else if $direction == "vertical" { } @else if $direction == "vertical" {
border-left: $w $style darken($b, 15%); border-left: $w $style darken($b, 15%);
left: 2px; left: 2px;
bottom: 5px; bottom: 5px;
top: 5px; top: 5px;
} width: 1px;
}
&:not(.disabled):hover:before {
@include trans-prop-nice("border-color", 25ms);
border-color: $colorGrippyInteriorHover;
} }
} }
@ -256,6 +275,12 @@
@return percentage($d); @return percentage($d);
} }
@function splitterHandleInset($splitterD: 21px, $splitterHandleD: 1px) {
// Space to either side of the handle
@return ($splitterD - $splitterHandleD) * 0.5;
}
/*********************************************** CONTROLS, FORM ELEMENTS */ /*********************************************** CONTROLS, FORM ELEMENTS */
@mixin containerBase($bg: $colorBodyBg, $fg: $colorBodyFg) { @mixin containerBase($bg: $colorBodyBg, $fg: $colorBodyFg) {
@ -347,10 +372,7 @@
/* This doesn't work on an element inside an element with absolute positioning that has height: auto */ /* This doesn't work on an element inside an element with absolute positioning that has height: auto */
//position: relative; //position: relative;
top: 50%; top: 50%;
@include webkitProp(transform, translateY(-50%)); @include transform(translateY(-50%));
//-webkit-transform: translateY(-50%);
//-ms-transform: translateY(-50%);
//transform: translateY(-50%);
} }
@mixin verticalCenterBlock($holderH, $itemH) { @mixin verticalCenterBlock($holderH, $itemH) {

View File

@ -22,13 +22,17 @@
$baseRatio: 1.5; $baseRatio: 1.5;
$pad: $interiorMargin * $baseRatio; $pad: $interiorMargin * $baseRatio;
.s-btn { .s-btn,
@include box-sizing(border-box); .s-icon-btn {
@include user-select(none); @include user-select(none);
cursor: pointer; cursor: pointer;
text-decoration: none; text-decoration: none;
height: $btnStdH; height: $btnStdH;
line-height: $btnStdH; line-height: $btnStdH;
}
.s-btn {
@include box-sizing(border-box);
padding: 0 $pad; padding: 0 $pad;
font-size: 0.7rem; font-size: 0.7rem;
@ -89,6 +93,157 @@ $pad: $interiorMargin * $baseRatio;
} }
} }
.s-icon-btn {
@extend .ui-symbol;
// Color and styling additionally in _controls.scss
}
.mini-tab {
// Meant to be used as pane hide/show control elements in concert with mct-splitter
//@extend .ui-symbol;
@include desktop {
//@include test(green);
$iconH: $uePaneMiniTabH;
$iconW: $uePaneMiniTabW;
$iconInnerLR: 0;
$arwD: 9px;
$arwOffsetX: 0px;
$arwAnimOffsetX: 2px + $iconInnerLR;
$cBg: pullForward($colorBodyBg, 15%);
$cFg: $cBg;
@include border-radius($basicCr);
//@include boxShdw($shdwBtns);
@include box-sizing(border-box);
@include trans-prop-nice((color, background-color), 100ms);
color: $cFg;
cursor: pointer;
font-family: symbolsfont;
font-size: $arwD;
display: block;
position: absolute;
line-height: $iconH;
height: $iconH; width: $iconW;
text-align: center;
&:hover {
//background-color: $cBg;
color: $colorKey; //pullForward($cFg, $ltGamma);
}
&.collapsed {
// State when the pane this element controls has been collapsed
@include btnSubtle($colorBtnBg, $colorKey, $colorBtnFg, $colorBtnIcon);
&:before { opacity: 0; }
&:after { opacity: 1; }
&:hover {
&:before { opacity: 1; }
&:after { opacity: 0; }
}
}
&:before,
&:after {
//@include test();
@include trans-prop-nice((left, right, opacity), 250ms);
display: block;
height: 100%;
position: absolute;
}
&:before {
// Always the arrow icon
//@include test(green);
//font-size: $arwD;
width: $arwD;
}
&:after {
// Always icon; content is set in _layout.scss
width: 100%;
text-align: center;
opacity: 0;
}
&.anchor-left {
// |<
text-align: right;
&:before {
content:'\3c'; // Collapse left icon e613
right: $iconInnerLR;
}
//&:hover:before { right: $arwAnimOffsetX; }
&.collapsed {
@include border-left-radius(0);
text-align: left;
&:before {
content:'\3e';
left: $iconInnerLR;
}
&:hover:before { left: $arwAnimOffsetX; }
}
}
&.anchor-right {
// >|
text-align: left;
&:before {
content:'\3e'; // Collapse right icon e614
left: $iconInnerLR;
}
//&:hover:before { left: $arwAnimOffsetX; }
&.collapsed {
@include border-right-radius(0);
&:before {
text-align: right;
content:'\3c';
right: $iconInnerLR;
}
&:hover:before { right: $arwAnimOffsetX; }
}
}
}
}
.mini-tab-icon {
// Meant to be used as pane hide/show control elements in concert with mct-splitter
//@extend .ui-symbol;
@include desktop {
$d: $uePaneMiniTabW;
//@include trans-prop-nice(transform, 150ms);
color: pullForward($colorBodyBg, 15%);
cursor: pointer;
display: block;
font-family: symbolsfont;
font-size: $d;
position: absolute;
height: $d; width: $d;
line-height: $d;
overflow: hidden;
word-break: break-all;
&.collapsed {
$d: $uePaneMiniTabCollapsedW;
width: $d; font-size: $d;
}
&:before,
&:after {
position: absolute;
display: inherit;
}
&:before {
content: '\78'; // X icon
}
&:hover {
color: $colorKey;
//@include transform(scale(1.2));
}
}
}
.l-btn-set { .l-btn-set {
// Buttons that have a very tight conceptual grouping - no internal space between them. // Buttons that have a very tight conceptual grouping - no internal space between them.
// Structure: .btn-set > mct-representation class=first|last > .s-btn // Structure: .btn-set > mct-representation class=first|last > .s-btn

View File

@ -19,462 +19,491 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*.control {
// UNUSED?
&.view-control {
.icon {
display: inline-block;
margin: -1px 5px 1px 2px;
vertical-align: middle;
&.triangle-down {
margin: 2px 2px -2px 0px;
}
}
.label {
display: inline-block;
font-size: 11px;
vertical-align: middle;
}
.toggle {
@include border-radius(3px);
display: inline-block;
padding: 1px 6px 4px 4px;
&:hover {
background: rgba(white, 0.1);
}
}
}
}*/
.accordion { .accordion {
$accordionHeadH: 18px; $accordionHeadH: 18px;
margin-top: $interiorMargin; margin-top: $interiorMargin;
&:first-child { &:first-child {
margin-top: 0; margin-top: 0;
} }
.accordion-head { .accordion-head {
$op: 0.2; $op: 0.2;
@include border-radius($basicCr * 0.75); @include border-radius($basicCr * 0.75);
@include box-sizing("border-box"); @include box-sizing("border-box");
background: rgba($colorBodyFg, $op); background: rgba($colorBodyFg, $op);
cursor: pointer; cursor: pointer;
font-size: 0.75em; font-size: 0.75em;
line-height: $accordionHeadH; line-height: $accordionHeadH;
margin-bottom: $interiorMargin; margin-bottom: $interiorMargin;
padding: 0 $interiorMargin; padding: 0 $interiorMargin;
position: absolute; position: absolute;
top: 0; top: 0;
right: 0; right: 0;
bottom: auto; bottom: auto;
left: 0; left: 0;
width: auto; width: auto;
height: $accordionHeadH; height: $accordionHeadH;
text-transform: uppercase; text-transform: uppercase;
&:hover { &:hover {
background: rgba($colorBodyFg, $op * 2); background: rgba($colorBodyFg, $op * 2);
} }
&:after { &:after {
content: "^"; content: "^";
display: block; display: block;
font-family: 'symbolsfont'; font-family: 'symbolsfont';
font-size: 0.9em; font-size: 0.9em;
position: absolute; position: absolute;
right: $interiorMargin; right: $interiorMargin;
text-transform: none; text-transform: none;
top: 0; top: 0;
} }
&:not(.expanded):after { &:not(.expanded):after {
content: "v"; content: "v";
} }
} }
.accordion-contents { .accordion-contents {
position: absolute; position: absolute;
top: $accordionHeadH + $interiorMargin; top: $accordionHeadH + $interiorMargin;
right: 0; right: 0;
bottom: 0; bottom: 0;
left: 0; left: 0;
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
} }
} }
.l-composite-control { .l-composite-control {
vertical-align: middle; vertical-align: middle;
&.l-checkbox { &.l-checkbox {
.composite-control-label { .composite-control-label {
line-height: 18px; line-height: 18px;
} }
} }
} }
.l-control-group { .l-control-group {
// Buttons that have a conceptual grouping - internal space between, and a divider between groups. // Buttons that have a conceptual grouping - internal space between, and a divider between groups.
// @include test(); // @include test();
@include box-sizing(border-box); @include box-sizing(border-box);
border-left: 1px solid $colorInteriorBorder; border-left: 1px solid $colorInteriorBorder;
display: inline-block; display: inline-block;
padding: 0 $interiorMargin; padding: 0 $interiorMargin;
position: relative; position: relative;
&:first-child { &:first-child {
border-left: none; border-left: none;
padding-left: 0; padding-left: 0;
} }
} }
.l-local-controls { .l-local-controls {
// Control shown when hovering over an object, like plots and imagery // Control shown when hovering over an object, like plots and imagery
// Default position is upper right // Default position is upper right
$p: $interiorMargin; $p: $interiorMargin;
position: absolute; position: absolute;
top: $p; top: $p;
right: $p; right: $p;
z-index: 5; z-index: 5;
} }
.s-local-controls { .s-local-controls {
font-size: 0.7rem; font-size: 0.7rem;
} }
label.checkbox.custom { label.checkbox.custom {
$bg: pullForward($colorBodyBg, 10%); $bg: pullForward($colorBodyBg, 10%);
$d: $formRowCtrlsH; $d: $formRowCtrlsH;
cursor: pointer; cursor: pointer;
display: inline-block; display: inline-block;
line-height: $d; line-height: $d;
margin-right: $interiorMargin * 4; margin-right: $interiorMargin * 4;
padding-left: $d + $interiorMargin; padding-left: $d + $interiorMargin;
position: relative; position: relative;
vertical-align: middle; // was top vertical-align: middle; // was top
em { em {
color: $colorBodyFg; color: $colorBodyFg;
display: inline-block; display: inline-block;
height: $d; height: $d;
min-width: $d; min-width: $d;
&:before { &:before {
@include border-radius($basicCr * .75); @include border-radius($basicCr * .75);
background: $bg; background: $bg;
//border-bottom: 1px solid lighten($bg, 10%); @include box-shadow(inset rgba(black, 0.4) 0 1px 2px);
@include box-shadow(inset rgba(black, 0.4) 0 1px 2px); box-sizing: border-box;
box-sizing: border-box; content: " ";
content: " "; font-family: 'symbolsfont';
font-family: 'symbolsfont'; font-size: 0.8em;
font-size: 0.8em; display: inline-block;
display: inline-block; margin-right: $interiorMargin;
margin-right: $interiorMargin; height: $d;
height: $d; width: $d;
width: $d; left: 0;
left: 0; top: 0;
top: 0; position: absolute;
position: absolute; text-align: center;
text-align: center; }
} }
} &.no-text {
&.no-text { overflow: hidden;
overflow: hidden; margin-right: 0;
margin-right: 0; padding-left: 0;
padding-left: 0; height: $d;
height: $d; width: $d;
width: $d; em {
em { overflow: hidden;
overflow: hidden; }
} }
} input {
input { display: none;
display: none; &:checked ~ em:before {
&:checked ~ em:before { background: $colorCheck;
background: $colorCheck; color: lighten($colorCheck, 50%);
color: lighten($colorCheck, 50%); content: "2";
content: "2"; }
} }
}
} }
.input-labeled { .input-labeled {
margin-left: $interiorMargin; margin-left: $interiorMargin;
label { label {
display: inline-block; display: inline-block;
margin-right: $interiorMarginSm; margin-right: $interiorMarginSm;
} }
&.inline { &.inline {
display: inline-block; display: inline-block;
} }
&:first-child { &:first-child {
margin-left: 0; margin-left: 0;
} }
} }
.s-menu-btn label.checkbox.custom { .s-menu-btn label.checkbox.custom {
margin-left: 5px; margin-left: 5px;
} }
.item .checkbox { .item .checkbox {
&.checked label { &.checked label {
@include box-shadow(none); @include box-shadow(none);
border-bottom: none; border-bottom: none;
} }
} }
.context-available { .context-available,
$c: $colorKey; .s-icon-btn {
color: $c; $c: $colorKey;
&:hover { color: $c;
color: lighten($c, 10%); &:hover {
} color: lighten($c, 10%);
}
} }
.view-switcher { .view-switcher {
@include trans-prop-nice-fade($controlFadeMs); @include trans-prop-nice-fade($controlFadeMs);
} }
/******************************************************** OBJECT-HEADER */ /******************************************************** OBJECT-HEADER */
.object-header { .object-header {
//@include test(); font-size: 1em;
font-size: 1em;
//> .title-label, > .type-icon {
//> .type-icon, color: $colorObjHdrIc;
//> .context-available { font-size: 120%;
// //@include tmpBorder(#6666ff); float: left;
// //vertical-align: middle; margin-right: $interiorMargin;
//} }
> .type-icon { .l-elem-wrapper {
color: $colorObjHdrIc; mct-representation {
font-size: 120%; // Holds the context-available item
float: left; // Must have min-width to make flex work properly
margin-right: $interiorMargin; // in Safari
} min-width: 0.7em;
}
}
.l-elem-wrapper { .action {
//@include test(#66f, 0.2); margin-right: $interiorMargin;
@include webkitProp(justify-content, flex-start); }
mct-representation {
// Holds the context-available item
// Must have min-width to make flex work properly
// in Safari
min-width: 0.7em;
}
}
.action { .title-label {
margin-right: $interiorMargin; color: $colorObjHdrTxt;
} @include ellipsize();
@include webkitProp(flex, '0 1 auto');
padding-right: 0.35em; // For context arrow. Done with em's so pad is relative to the scale of the text.
}
.title-label { .context-available {
//@include test(green, 0.9); font-size: 0.7em;
color: $colorObjHdrTxt; @include webkitProp(flex, '0 0 1');
@include ellipsize(); }
//color: pushBack($colorBodyFg, 40%);
@include webkitProp(flex, '0 1 auto');
padding-right: 0.35em; // For context arrow. Done with em's so pad is relative to the scale of the text.
//position: relative;
}
.context-available { @include desktop {
font-size: 0.7em; .context-available {
@include webkitProp(flex, '0 0 1'); @include trans-prop-nice(opacity, 0.25s);
//margin-right: $interiorMargin; opacity: 0;
} }
&:hover {
.context-available {
opacity: 1;
}
}
}
}
@include desktop { /******************************************************** PROGRESS BAR */
.context-available { @include keyframes(progress) {
@include trans-prop-nice(opacity, 0.25s); 100% { background-position: $progressBarStripeW center; }
opacity: 0; }
}
&:hover { @mixin bgProgressAnim($c: yellow, $a: 0.1, $d: 20px) {
.context-available { @include background-image(linear-gradient(-90deg,
opacity: 1; rgba($c, $a) 0%, transparent 50%,
} transparent 50%, rgba($c, $a) 100%
} ));
} background-position: 0 center;
background-repeat: repeat-x;
background-size: $d 40%;
}
.l-progress-bar {
// Assume will be determinate by default
display: inline-block;
overflow: hidden;
position: relative;
.progress-amt-holder {
@include absPosDefault(1px);
}
.progress-amt,
.progress-amt:before,
.progress-amt:after {
@include absPosDefault();
display: block;
content: '';
}
.progress-amt {
right: auto; // Allow inline width to control }
}
&.indeterminate {
.progress-amt {
width: 100% !important;
}
}
}
.s-progress-bar {
@include border-radius($basicCr);
@include boxIncised(0.3, 4px);
background: $colorProgressBarOuter;
.progress-amt {
@include border-radius($basicCr);
@include boxShdw();
@include border-radius($basicCr - 1);
@include trans-prop-nice(width);
&:before {
background-color: $colorProgressBarAmt;
}
&:after {
// Sheen
@include background-image(linear-gradient(
transparent 5%, rgba(#fff,0.25) 30%, transparent 100%
));
}
}
&:not(.indeterminate) {
.progress-amt:before {
// More subtle anim for determinate progress
@include animation(progress .4s linear infinite);
@include bgProgressAnim(#fff, 0.1, $progressBarStripeW);
}
}
&.indeterminate .progress-amt {
&:before {
// More visible std diag stripe anim for indeterminate progress
@include animation(progress .6s linear infinite);
@include bgDiagonalStripes(#fff, 0.2, $progressBarStripeW);
}
&:after { display: none; }
}
} }
/******************************************************** SLIDERS */ /******************************************************** SLIDERS */
.slider { .slider {
$knobH: 100%; //14px; $knobH: 100%; //14px;
.slot { .slot {
// @include border-radius($basicCr * .75); width: auto;
//@include sliderTrack(); position: absolute;
width: auto; top: 0;
position: absolute; right: 0;
top: 0; bottom: 0;
right: 0; left: 0;
bottom: 0; }
left: 0; .knob {
} @include trans-prop-nice-fade(.25s);
.knob { background-color: $sliderColorKnob;
//@include btnSubtle(); &:hover {
//@include controlGrippy(rgba(black, 0.3), vertical, 1px, solid); background-color: $sliderColorKnobHov;
@include trans-prop-nice-fade(.25s); }
background-color: $sliderColorKnob; position: absolute;
&:hover { height: $knobH;
background-color: $sliderColorKnobHov; width: $sliderKnobW;
} top: 0;
position: absolute; auto: 0;
height: $knobH; bottom: auto;
width: $sliderKnobW; left: auto;
top: 0; }
auto: 0; .knob-l {
bottom: auto; @include border-left-radius($sliderKnobW);
left: auto; cursor: w-resize;
} }
.knob-l { .knob-r {
@include border-left-radius($sliderKnobW); @include border-right-radius($sliderKnobW);
cursor: w-resize; cursor: e-resize;
} }
.knob-r { .range {
@include border-right-radius($sliderKnobW); @include trans-prop-nice-fade(.25s);
cursor: e-resize; background-color: $sliderColorRange;
} cursor: ew-resize;
.range { position: absolute;
@include trans-prop-nice-fade(.25s); top: 0; //$tbOffset;
background-color: $sliderColorRange; right: auto;
cursor: ew-resize; bottom: 0;
position: absolute; left: auto;
top: 0; //$tbOffset; height: auto;
right: auto; width: auto;
bottom: 0; &:hover {
left: auto; background-color: $sliderColorRangeHov;
height: auto; }
width: auto; }
&:hover {
background-color: $sliderColorRangeHov;
}
}
} }
/******************************************************** DATETIME PICKER */ /******************************************************** DATETIME PICKER */
.l-datetime-picker { .l-datetime-picker {
$r1H: 15px; $r1H: 15px;
@include user-select(none); @include user-select(none);
font-size: 0.8rem; font-size: 0.8rem;
padding: $interiorMarginLg !important; padding: $interiorMarginLg !important;
width: 230px; width: 230px;
.l-month-year-pager { .l-month-year-pager {
$pagerW: 20px; $pagerW: 20px;
//@include test(); height: $r1H;
//font-size: 0.8rem; margin-bottom: $interiorMargin;
height: $r1H; position: relative;
margin-bottom: $interiorMargin; .pager,
position: relative; .val {
.pager, @extend .abs;
.val { }
//@include test(red); .pager {
@extend .abs; width: $pagerW;
} @extend .ui-symbol;
.pager { &.prev {
width: $pagerW; right: auto;
@extend .ui-symbol; &:before {
&.prev { content: "\3c";
right: auto; }
&:before { }
content: "\3c"; &.next {
} left: auto;
} text-align: right;
&.next { &:before {
left: auto; content: "\3e";
text-align: right; }
&:before { }
content: "\3e"; }
} .val {
} text-align: center;
} left: $pagerW + $interiorMargin;
.val { right: $pagerW + $interiorMargin;
text-align: center; }
left: $pagerW + $interiorMargin; }
right: $pagerW + $interiorMargin; .l-calendar,
} .l-time-selects {
} border-top: 1px solid $colorInteriorBorder
.l-calendar, }
.l-time-selects { .l-time-selects {
border-top: 1px solid $colorInteriorBorder line-height: $formInputH;
} }
.l-time-selects {
line-height: $formInputH;
}
} }
/******************************************************** CALENDAR */ /******************************************************** CALENDAR */
.l-calendar { .l-calendar {
$colorMuted: pushBack($colorMenuFg, 30%); $colorMuted: pushBack($colorMenuFg, 30%);
ul.l-cal-row { ul.l-cal-row {
@include display-flex; @include display-flex;
@include flex-flow(row nowrap); @include flex-flow(row nowrap);
margin-top: 1px; margin-top: 1px;
&:first-child { &:first-child {
margin-top: 0; margin-top: 0;
} }
li { li {
@include flex(1 0); @include flex(1 0);
//@include test(); margin-left: 1px;
margin-left: 1px; padding: $interiorMargin;
padding: $interiorMargin; text-align: center;
text-align: center; &:first-child {
&:first-child { margin-left: 0;
margin-left: 0; }
} }
} &.l-header li {
&.l-header li { color: $colorMuted;
color: $colorMuted; }
} &.l-body li {
&.l-body li { @include trans-prop-nice(background-color, .25s);
@include trans-prop-nice(background-color, .25s); cursor: pointer;
cursor: pointer; &.in-month {
&.in-month { background-color: $colorCalCellInMonthBg;
background-color: $colorCalCellInMonthBg; }
} .sub {
.sub { color: $colorMuted;
color: $colorMuted; font-size: 0.8em;
font-size: 0.8em; }
} &.selected {
&.selected { background: $colorCalCellSelectedBg;
background: $colorCalCellSelectedBg; color: $colorCalCellSelectedFg;
color: $colorCalCellSelectedFg; .sub {
.sub { color: inherit;
color: inherit; }
} }
} &:hover {
&:hover { background-color: $colorCalCellHovBg;
background-color: $colorCalCellHovBg; color: $colorCalCellHovFg;
color: $colorCalCellHovFg; .sub {
.sub { color: inherit;
color: inherit; }
} }
} }
} }
}
} }
/******************************************************** BROWSER ELEMENTS */ /******************************************************** BROWSER ELEMENTS */
@include desktop { @include desktop {
::-webkit-scrollbar { ::-webkit-scrollbar {
@include border-radius(2px); @include border-radius(2px);
@include box-sizing(border-box); @include box-sizing(border-box);
@include box-shadow(inset $scrollbarTrackShdw); @include box-shadow(inset $scrollbarTrackShdw);
background-color: $scrollbarTrackColorBg; background-color: $scrollbarTrackColorBg;
height: $scrollbarTrackSize; height: $scrollbarTrackSize;
width: $scrollbarTrackSize; width: $scrollbarTrackSize;
} }
::-webkit-scrollbar-thumb { ::-webkit-scrollbar-thumb {
$bg: $scrollbarThumbColor; $bg: $scrollbarThumbColor;
$hc: $scrollbarThumbColorHov; $hc: $scrollbarThumbColorHov;
$gr: 5%; $gr: 5%;
@include background-image(linear-gradient(lighten($bg, $gr), $bg 20px)); @include background-image(linear-gradient(lighten($bg, $gr), $bg 20px));
@include border-radius(2px); @include border-radius(2px);
@include box-sizing(border-box); @include box-sizing(border-box);
//@include boxShdwSubtle(); &:hover {
//border-top: 1px solid lighten($bg, 20%); @include background-image(linear-gradient(lighten($hc, $gr), $hc 20px));
&:hover { }
@include background-image(linear-gradient(lighten($hc, $gr), $hc 20px)); }
}
}
::-webkit-scrollbar-corner { ::-webkit-scrollbar-corner {
background: $scrollbarTrackColorBg; background: $scrollbarTrackColorBg;
} }
} }

View File

@ -32,7 +32,7 @@
.l-tree-item-flat-list { .l-tree-item-flat-list {
// For lists of tree-items that are flat. Remove margin, etc. normally needed for the expansion arrow. // For lists of tree-items that are flat. Remove margin, etc. normally needed for the expansion arrow.
.tree-item { .tree-item {
.label { .t-object-label {
left: $interiorMargin !important; left: $interiorMargin !important;
} }
} }

View File

@ -43,6 +43,11 @@
} }
&.create-btn { &.create-btn {
&:before {
content:'\2b';
display: inline;
font-family: symbolsfont;
}
.title-label { .title-label {
font-size: 1rem; font-size: 1rem;
} }
@ -83,7 +88,7 @@
@include menuUlReset(); @include menuUlReset();
li { li {
@include box-sizing(border-box); @include box-sizing(border-box);
border-top: 1px solid lighten($colorMenuBg, 20%); border-top: 1px solid pullForward($colorMenuBg, 10%);
color: pullForward($colorMenuBg, 60%); color: pullForward($colorMenuBg, 60%);
line-height: $menuLineH; line-height: $menuLineH;
padding: $interiorMarginSm $interiorMargin * 2 $interiorMarginSm ($interiorMargin * 2) + $treeTypeIconW; padding: $interiorMarginSm $interiorMargin * 2 $interiorMarginSm ($interiorMargin * 2) + $treeTypeIconW;

View File

@ -0,0 +1,306 @@
/*****************************************************************************
* 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.
*****************************************************************************/
@mixin statusBannerColors($bg, $fg: $colorStatusFg) {
$bgPb: 30%;
$bgPbD: 10%;
background-color: darken($bg, $bgPb);
color: $fg;
&:hover {
background-color: darken($bg, $bgPb - $bgPbD);
}
.s-action {
background-color: darken($bg, $bgPb + $bgPbD);
&:hover {
background-color: darken($bg, $bgPb);
}
}
}
.status.block {
color: $colorStatusDefault;
cursor: default;
display: inline-block;
margin-right: $interiorMargin;
.status-indicator,
.label,
.count {
//@include test(#00ff00);
display: inline-block;
vertical-align: top;
}
.status-indicator {
margin-right: $interiorMarginSm;
}
&.ok .status-indicator,
&.info .status-indicator {
color: $colorStatusInfo;
}
&.alert .status-indicator,
&.warning .status-indicator,
&.caution .status-indicator {
color: $colorStatusAlert;
}
&.error .status-indicator {
color: $colorStatusError;
}
.label {
// Max-width silliness is necessary for width transition
@include trans-prop-nice(max-width, .25s);
overflow: hidden;
max-width: 0px;
}
.count {
@include trans-prop-nice(opacity, .25s);
font-weight: bold;
opacity: 1;
}
&:hover {
.label {
max-width: 450px;
width: auto;
}
.count {
opacity: 0;
}
}
}
/* Styles for messages and message banners */
.message {
&.block {
@include border-radius($basicCr);
padding: $interiorMarginLg;
}
&.error {
background-color: rgba($colorAlert,0.3);
color: lighten($colorAlert, 20%);
}
}
.l-message-banner {
$m: $interiorMarginSm;
$lh: $ueFooterH - ($m*2) - 1;
@include box-sizing(border-box);
@include ellipsize();
@include display-flex;
@include flex-direction(row);
@include align-items(center);
position: absolute;
top: $m; right: auto; bottom: $m; left: 50%;
height: auto; width: auto;
line-height: $lh;
max-width: 300px;
padding: 0 $interiorMargin 0 $interiorMargin;
@include transform(translateX(-50%));
&.minimized {
@include transition-property(left, opacity);
@include transition-duration(0.3s);
@include transition-timing-function(ease-in-out);
left: 0;
opacity: 0;
}
&.new {
left: 50%;
opacity: 1;
&:not(.info) {
@include pulse(100ms, 10);
}
}
.banner-elem {
@include flex(0 1 auto);
margin-left: $interiorMargin;
}
a {
display: inline-block;
}
.l-action {
line-height: $lh - 3;
padding: 0 $interiorMargin;
}
.close {
//@include test(red, 0.7);
cursor: pointer;
font-size: 7px;
width: 8px;
}
.l-progress-bar {
$h: $lh - 10;
height: $h;
line-height: $h;
width: 100px;
}
.progress-info { display: none; }
z-index: 10;
}
.s-message-banner {
//@include transition-property(left, opacity);
//@include transition-duration(0.35s);
//@include transition-timing-function(ease-in-out);
}
.s-message-banner {
@include border-radius($controlCr);
@include statusBannerColors($colorStatusDefault, $colorStatusFg);
cursor: pointer;
a { color: inherit; }
.s-action {
@include border-radius($basicCr);
@include trans-prop-nice(background-color);
}
.close {
opacity: 0.5;
&:hover {
opacity: 1;
}
}
&.ok,
&.info {
@include statusBannerColors($colorStatusInfo);
}
&.caution,
&.warning,
&.alert {
@include statusBannerColors($colorStatusAlert);
}
&.error {
@include statusBannerColors($colorStatusError);
}
}
@mixin messageBlock($iconW: 32px) {
.type-icon.message-type {
@include txtShdw($shdwStatusIc);
&:before { content:"\e608"; }
color: $colorStatusDefault;
font-size: $iconW;
padding: 1px;
width: $iconW + 2;
}
.message-severity-info .type-icon.message-type {
&:before { content:"\e608"; }
color: $colorStatusInfo;
}
.message-severity-alert .type-icon.message-type {
&:before { content:"\e610"; }
color: $colorStatusAlert;
}
.message-severity-error .type-icon.message-type {
&:before { content:"\21"; }
color: $colorStatusError;
}
}
/* Paths:
t-dialog | t-dialog-sm > t-message-single | t-message-list > overlay > holder > contents > l-message >
message-type > (icon)
message-contents >
top-bar >
title
hint
editor >
(if displaying list of messages)
ul > li > l-message >
... same as above
bottom-bar
*/
.l-message {
@include display-flex;
@include flex-direction(row);
@include align-items(stretch);
.type-icon.message-type {
//@include test(red);
@include flex(0 1 auto);
position: relative;
}
.message-contents {
//@include test(blue);
@include flex(1 1 auto);
margin-left: $overlayMargin;
position: relative;
.top-bar,
.message-body {
margin-bottom: $interiorMarginLg * 2;
}
}
}
// Message as singleton
.t-message-single {
@include messageBlock(80px);
@include desktop {
.l-message,
.bottom-bar {
@include absPosDefault();
}
.bottom-bar {
top: auto;
height: $ovrFooterH;
}
}
}
// Messages in list
.t-message-list {
@include messageBlock(32px);
.message-contents {
.l-message {
//border-bottom: 1px solid pullForward($colorOvrBg, 20%);
@include border-radius($controlCr);
background: rgba($colorOvrFg, 0.1);
margin-bottom: $interiorMargin;
padding: $interiorMarginLg;
.message-contents,
.bottom-bar {
//@include test(green);
position: relative;
}
.message-contents {
font-size: 0.9em;
margin-left: $interiorMarginLg;
.message-action { color: pushBack($colorOvrFg, 20%); }
.bottom-bar { text-align: left; }
}
.top-bar,
.message-body {
margin-bottom: $interiorMarginLg;
}
}
}
@include desktop {
.message-contents .l-message { margin-right: $interiorMarginLg; }
}
}

View File

@ -1,46 +1,32 @@
.l-time-display { .l-time-display {
$transTime: 200ms; $transTime: 200ms;
// Layout line-height: 140%;
&:hover { &:hover {
.l-btn.control { .l-btn.control {
opacity: 1; opacity: 1;
} }
} }
.l-elem-wrapper {
position: relative;
}
.l-elem {
display: inline-block;
}
&.l-timer { &.l-timer {
.l-elem.l-value { .control {
@include trans-prop-nice(left, $transTime); @include trans-prop-nice((width, opacity), $transTime);
position: absolute; line-height: inherit;
left: 0; margin-right: 0;
z-index: 1; opacity: 0;
.ui-symbol.direction { width: 0;
font-size: 0.8em; }
} &:hover .control {
} margin-right: $interiorMargin;
&:hover .l-elem.l-value { opacity: 1;
left: 20px; width: 1em;
} }
} }
// Look-and-feel .value {
.l-elem { color: pullForward($colorBodyFg, 50%);
.value.active, font-weight: 400;
&.value.active { .direction {
color: $colorKeyFg; font-size: 0.8em;
} }
} }
.l-btn.control {
@include trans-prop-nice-fade($transTime);
opacity: 0;
font-size: 0.65em;
vertical-align: top;
//line-height: 1em;
}
} }

Some files were not shown because too many files have changed in this diff Show More