Merge remote-tracking branch 'github/master' into open236

Resolve CSS conflicts for nasa/openmctweb#236

Conflicts:
	platform/commonUI/general/res/sass/controls/_controls.scss
	platform/commonUI/themes/espresso/res/css/theme-espresso.css
	platform/commonUI/themes/snow/res/css/theme-snow.css
This commit is contained in:
Victor Woeltjen 2015-11-04 13:02:17 -08:00
commit ab01f64cea
125 changed files with 9727 additions and 3378 deletions

View File

@ -6,10 +6,12 @@
"platform/commonUI/browse",
"platform/commonUI/edit",
"platform/commonUI/dialog",
"platform/commonUI/formats",
"platform/commonUI/general",
"platform/commonUI/inspect",
"platform/commonUI/mobile",
"platform/commonUI/themes/espresso",
"platform/commonUI/notification",
"platform/containment",
"platform/execution",
"platform/telemetry",

View File

@ -16,6 +16,23 @@
"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": [
{
"key": "generator",
@ -38,6 +55,11 @@
{
"key": "yesterday",
"name": "Yesterday"
},
{
"key": "delta",
"name": "Delta",
"format": "example.delta"
}
],
"ranges": [

View File

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

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

@ -25,12 +25,12 @@
* Module defining SinewaveTelemetry. Created by vwoeltje on 11/12/14.
*/
define(
[],
function () {
['./SinewaveConstants'],
function (SinewaveConstants) {
"use strict";
var ONE_DAY = 60 * 60 * 24,
firstObservedTime = Math.floor(Date.now() / 1000) - ONE_DAY;
firstObservedTime = Math.floor(SinewaveConstants.START_TIME / 1000);
/**
*
@ -58,6 +58,9 @@ define(
};
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 -
(domain === 'yesterday' ? ONE_DAY : 0);
};

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

@ -31,10 +31,10 @@
]
},
{
"key": "BrowseTreeController",
"implementation": "BrowseTreeController.js",
"key": "PaneController",
"implementation": "PaneController.js",
"priority": "preferred",
"depends": [ "$scope", "agentService" ]
"depends": [ "$scope", "agentService","$window" ]
},
{
"key": "BrowseObjectController",

View File

@ -41,7 +41,6 @@
</mct-representation>
</div>
</div>
<mct-representation key="representation.selected.key"
mct-object="representation.selected.key && domainObject"
class="abs object-holder">

View File

@ -22,22 +22,27 @@
<div class="abs holder-all browse-mode" ng-controller="BrowseController">
<mct-include key="'topbar-browse'"></mct-include>
<div class="holder browse-area s-browse-area abs browse-wrapper"
ng-controller="BrowseTreeController as tree"
ng-class="tree.visible() ? 'browse-showtree' : 'browse-hidetree'">
<mct-split-pane class='contents abs' anchor='left'>
<div class="abs holder holder-main browse-area s-browse-area browse-wrapper"
ng-controller="PaneController as modelPaneTree"
ng-class="modelPaneTree.visible() ? 'pane-tree-showing' : 'pane-tree-hidden'">
<mct-split-pane class='abs contents'
anchor='left'>
<div class='split-pane-component treeview pane left'>
<div class="holder abs l-mobile">
<!--<a class="mini-tab-icon anchor-left toggle-pane toggle-search mobile-hide"
title="Enable search"
ng-click="modelPaneTree.toggle()"
ng-class="{ collapsed : !modelPaneTree.visible() }"
ng-style="{ opacity: modelPaneTree.visible()? 0:1 }"></a>-->
<div class="holder holder-create-and-search abs l-mobile">
<mct-representation key="'create-button'"
mct-object="navigatedObject"
mct-device="desktop">
</mct-representation>
<div class='holder search-holder abs'
ng-class="{active: treeModel.search}">
<mct-representation key="'search'"
mct-object="domainObject"
<mct-include key="'search'"
ng-model="treeModel">
</mct-representation>
</mct-include>
</div>
<div class='tree-holder abs mobile-tree-holder'
ng-hide="treeModel.search">
@ -50,17 +55,40 @@
</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='holder abs l-mobile' id='content-area'>
<mct-representation mct-object="navigatedObject"
key="'browse-object'">
</mct-representation>
<div class='split-pane-component items pane primary-pane right'>
<a class="mini-tab-icon anchor-left toggle-pane toggle-tree"
title="{{ modelPaneTree.visible()? 'Hide' : 'Show' }} this pane"
ng-click="modelPaneTree.toggle()"
ng-class="{ collapsed : !modelPaneTree.visible() }"></a>
<div class='holder holder-object-and-inspector abs l-mobile' 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 class="key-properties ui-symbol icon mobile-menu-icon desktop-hide"
mct-device="mobile"
ng-click="tree.toggle()">m</div>
</div>
</mct-split-pane>
</div>

View File

@ -19,7 +19,7 @@
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<div class='object-header object-header-mobile'>
<div class='object-header'>
<span class='type-icon ui-symbol'>{{type.getGlyph()}}</span>
<!--span class='type-name mobile-important-hide'>{{type.getName()}}</span-->
<span class="l-elem-wrapper l-flex">

View File

@ -19,13 +19,12 @@
this source code distribution or the Licensing information page available
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()">
<span class="ui-symbol icon type-icon">&#x2b;</span>
<span class="title-label">Create</span>
</div>
<div class="menu super-menu" ng-show="createController.isActive()">
<mct-representation mct-object="domainObject" key="'create-menu'">
</mct-representation>
</div>
</div>
</span>

View File

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

View File

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

View File

@ -33,10 +33,12 @@ define(
* @constructor
* @memberof platform/commonUI/browse
*/
function BrowseTreeController($scope, agentService) {
function PaneController($scope, agentService, $window) {
var self = this;
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.
@ -44,7 +46,7 @@ define(
* to the tree representation.
*
* @property {Function} callback
* @memberof platform/commonUI/browse.BrowseTreeController#
* @memberof platform/commonUI/browse.PaneController#
*/
this.callback = function () {
// 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;
};
/**
* Get the desired visibility state of the tree.
* Get the desired visibility state of the pane.
* @returns {boolean} true when visible
*/
BrowseTreeController.prototype.visible = function () {
PaneController.prototype.visible = function () {
return this.state;
};
return BrowseTreeController;
return PaneController;
}
);

View File

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

View File

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

View File

@ -24,6 +24,18 @@
{
"key": "form-dialog",
"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": [

View File

@ -21,17 +21,13 @@
-->
<div class="abs top-bar">
<div class="title">{{ngModel.title}}</div>
<div class="hint">
All fields marked <span class="ui-symbol req">*</span> are required.
</div>
<div class="hint">All fields marked <span class="ui-symbol req">*</span> are required.</div>
</div>
<div class="abs form editor">
<div class='abs contents l-dialog'>
<mct-form ng-model="ngModel.value"
structure="ngModel.structure"
name="createForm">
</mct-form>
</div>
<div class='abs editor'>
<mct-form ng-model="ngModel.value"
structure="ngModel.structure"
name="createForm">
</mct-form>
</div>
<div class="abs bottom-bar">
<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="hint">{{ngModel.dialog.hint}}</div>
</div>
<div class="abs form outline editor">
<div class='abs contents l-dialog'>
<mct-include key="ngModel.dialog.template"
parameters="ngModel.dialog.parameters"
ng-model="ngModel.dialog.model">
</mct-include>
</div>
<div class='abs editor'>
<mct-include key="ngModel.dialog.template"
parameters="ngModel.dialog.parameters"
ng-model="ngModel.dialog.model">
</mct-include>
</div>
<div class="abs bottom-bar">
<a ng-repeat="option in ngModel.dialog.options"

View File

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

View File

@ -55,7 +55,7 @@ define(
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
// input is asynchronous.
var deferred = this.$q.defer(),
@ -84,27 +84,20 @@ define(
model.confirm = confirm;
model.cancel = cancel;
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 ",
model.name
].join(""));
deferred.reject();
} else {
if (this.canShowDialog(model)) {
// Add the overlay using the OverlayService, which
// will handle actual insertion into the DOM
this.overlay = this.overlayService.createOverlay(
key,
model
model,
typeClass || "t-dialog"
);
// Track that a dialog is already visible, to
// avoid spawning multiple dialogs at once.
this.dialogVisible = true;
} else {
deferred.reject();
}
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} action 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;
}

View File

@ -28,7 +28,7 @@ define(
// 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
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
* included overlay template (this will be passed
* 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
var scope = this.newScope(),
element;
@ -90,6 +93,7 @@ define(
// Populate the scope; will be passed directly to the template
scope.overlay = overlayModel;
scope.key = key;
scope.typeClass = typeClass || 't-dialog';
// Create the overlay element and add it to the document's body
element = this.$compile(TEMPLATE)(scope);

View File

@ -116,10 +116,22 @@ define(
dialog: dialogModel,
confirm: 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

@ -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

@ -44,6 +44,14 @@
"key": "indicator",
"templateUrl": "templates/indicator.html"
},
{
"key": "message-banner",
"templateUrl": "templates/message-banner.html"
},
{
"key": "progress-bar",
"templateUrl": "templates/progress-bar.html"
},
{
"key": "time-controller",
"templateUrl": "templates/controls/time-controller.html"
@ -53,13 +61,18 @@
{
"key": "TimeRangeController",
"implementation": "controllers/TimeRangeController.js",
"depends": [ "$scope", "now" ]
"depends": [ "$scope", "formatService", "DEFAULT_TIME_FORMAT", "now" ]
},
{
"key": "DateTimePickerController",
"implementation": "controllers/DateTimePickerController.js",
"depends": [ "$scope", "now" ]
},
{
"key": "DateTimeFieldController",
"implementation": "controllers/DateTimeFieldController.js",
"depends": [ "$scope", "formatService", "DEFAULT_TIME_FORMAT" ]
},
{
"key": "TreeNodeController",
"implementation": "controllers/TreeNodeController.js",
@ -107,6 +120,16 @@
"key": "SelectorController",
"implementation": "controllers/SelectorController.js",
"depends": [ "objectService", "$scope" ]
},
{
"key": "ObjectInspectorController",
"implementation": "controllers/ObjectInspectorController.js",
"depends": [ "$scope", "objectService" ]
},
{
"key": "BannerController",
"implementation": "controllers/BannerController.js",
"depends": ["$scope", "notificationService", "dialogService"]
}
],
"directives": [
@ -232,6 +255,10 @@
"key": "switcher",
"templateUrl": "templates/controls/switcher.html",
"uses": [ "view" ]
},
{
"key": "object-inspector",
"templateUrl": "templates/object-inspector.html"
}
],
"controls": [
@ -242,6 +269,10 @@
{
"key": "datetime-picker",
"templateUrl": "templates/controls/datetime-picker.html"
},
{
"key": "datetime-field",
"templateUrl": "templates/controls/datetime-field.html"
}
],
"licenses": [

View File

@ -1,14 +1,70 @@
{
"metadata": {
"name": "WTD Symbols v24",
"lastOpened": 1441992412958,
"created": 1441992410384
"name": "WTD Symbols",
"lastOpened": 1446490786311,
"created": 1446489891263
},
"iconSets": [
{
"selection": [
{
"order": 86,
"order": 113,
"id": 92,
"prevSize": 32,
"code": 58901,
"name": "icon-crosshair",
"tempChar": ""
},
{
"order": 110,
"id": 91,
"prevSize": 32,
"code": 58899,
"name": "icon-collapse-pane-left",
"tempChar": ""
},
{
"order": 111,
"id": 90,
"prevSize": 32,
"code": 58900,
"name": "icon-collapse-pane-right",
"tempChar": ""
},
{
"order": 109,
"id": 89,
"prevSize": 32,
"code": 58898,
"name": "icon-save",
"tempChar": ""
},
{
"order": 108,
"id": 88,
"prevSize": 32,
"code": 58897,
"name": "icon-dataset",
"tempChar": ""
},
{
"order": 90,
"id": 87,
"prevSize": 32,
"code": 58896,
"name": "icon-bell",
"tempChar": ""
},
{
"order": 91,
"id": 86,
"prevSize": 32,
"code": 58889,
"name": "icon-hourglass",
"tempChar": ""
},
{
"order": 92,
"id": 85,
"prevSize": 32,
"code": 58888,
@ -18,119 +74,119 @@
58890
],
"name": "icon-info-v15",
"tempChar": ""
"tempChar": ""
},
{
"order": 82,
"order": 93,
"id": 84,
"prevSize": 32,
"code": 58887,
"name": "icon-x-in-circle",
"tempChar": ""
"tempChar": ""
},
{
"order": 77,
"order": 94,
"id": 83,
"prevSize": 32,
"code": 58881,
"name": "icon-datatable",
"tempChar": ""
"tempChar": ""
},
{
"order": 78,
"order": 95,
"id": 82,
"prevSize": 32,
"code": 58882,
"name": "icon-tabular-scrolling",
"tempChar": ""
"tempChar": ""
},
{
"order": 79,
"order": 96,
"id": 81,
"prevSize": 32,
"code": 58884,
"name": "icon-tabular",
"tempChar": ""
"tempChar": ""
},
{
"order": 80,
"order": 97,
"id": 80,
"prevSize": 32,
"code": 58885,
"name": "icon-calendar",
"tempChar": ""
"tempChar": ""
},
{
"order": 83,
"order": 98,
"id": 78,
"prevSize": 32,
"code": 58886,
"name": "icon-paint-bucket",
"tempChar": ""
"tempChar": ""
},
{
"order": 1,
"order": 99,
"id": 75,
"prevSize": 32,
"code": 123,
"name": "icon-pointer-left",
"tempChar": ""
"tempChar": ""
},
{
"order": 3,
"order": 100,
"id": 74,
"prevSize": 32,
"code": 125,
"name": "icon-pointer-right",
"tempChar": ""
"tempChar": ""
},
{
"order": 4,
"order": 101,
"id": 73,
"prevSize": 32,
"code": 80,
"name": "icon-person",
"tempChar": ""
"tempChar": ""
},
{
"order": 5,
"order": 102,
"id": 72,
"prevSize": 32,
"code": 232,
"name": "icon-chain-links",
"tempChar": ""
"tempChar": ""
},
{
"order": 6,
"order": 103,
"id": 71,
"prevSize": 32,
"code": 115,
"name": "icon-database-in-brackets",
"tempChar": ""
"tempChar": ""
},
{
"order": 7,
"order": 104,
"id": 70,
"prevSize": 32,
"code": 114,
"name": "icon-refresh",
"tempChar": ""
"tempChar": ""
},
{
"order": 8,
"order": 105,
"id": 69,
"prevSize": 32,
"code": 108,
"name": "icon-lock",
"tempChar": ""
"tempChar": ""
},
{
"order": 9,
"order": 106,
"id": 68,
"prevSize": 32,
"code": 51,
"name": "icon-box-with-dashed-lines",
"tempChar": ""
"tempChar": ""
},
{
"order": 10,
@ -138,7 +194,7 @@
"prevSize": 32,
"code": 58880,
"name": "icon-box-with-arrow-cursor",
"tempChar": ""
"tempChar": ""
},
{
"order": 11,
@ -146,7 +202,7 @@
"prevSize": 32,
"code": 65,
"name": "icon-activity-mode",
"tempChar": ""
"tempChar": ""
},
{
"order": 12,
@ -154,15 +210,15 @@
"prevSize": 32,
"code": 97,
"name": "icon-activity",
"tempChar": ""
"tempChar": ""
},
{
"order": 13,
"order": 87,
"id": 64,
"prevSize": 32,
"code": 33,
"name": "icon-alert-rect",
"tempChar": ""
"tempChar": ""
},
{
"order": 14,
@ -170,7 +226,7 @@
"prevSize": 32,
"code": 58883,
"name": "icon-alert-triangle",
"tempChar": ""
"tempChar": ""
},
{
"order": 15,
@ -178,7 +234,7 @@
"prevSize": 32,
"code": 238,
"name": "icon-arrow-double-down",
"tempChar": ""
"tempChar": ""
},
{
"order": 16,
@ -186,7 +242,7 @@
"prevSize": 32,
"code": 235,
"name": "icon-arrow-double-up",
"tempChar": ""
"tempChar": ""
},
{
"order": 2,
@ -194,7 +250,7 @@
"prevSize": 32,
"code": 118,
"name": "icon-arrow-down",
"tempChar": ""
"tempChar": ""
},
{
"order": 19,
@ -202,7 +258,7 @@
"prevSize": 32,
"code": 60,
"name": "icon-arrow-left",
"tempChar": ""
"tempChar": ""
},
{
"order": 20,
@ -210,7 +266,7 @@
"prevSize": 32,
"code": 62,
"name": "icon-arrow-right",
"tempChar": ""
"tempChar": ""
},
{
"order": 21,
@ -218,7 +274,7 @@
"prevSize": 32,
"code": 236,
"name": "icon-arrow-tall-down",
"tempChar": ""
"tempChar": ""
},
{
"order": 22,
@ -226,7 +282,7 @@
"prevSize": 32,
"code": 237,
"name": "icon-arrow-tall-up",
"tempChar": ""
"tempChar": ""
},
{
"order": 23,
@ -234,7 +290,7 @@
"prevSize": 32,
"code": 94,
"name": "icon-arrow-up",
"tempChar": ""
"tempChar": ""
},
{
"order": 24,
@ -242,7 +298,7 @@
"prevSize": 32,
"code": 73,
"name": "icon-arrows-out",
"tempChar": ""
"tempChar": ""
},
{
"order": 25,
@ -250,7 +306,7 @@
"prevSize": 32,
"code": 58893,
"name": "icon-arrows-right-left",
"tempChar": ""
"tempChar": ""
},
{
"order": 33,
@ -258,7 +314,7 @@
"prevSize": 32,
"code": 53,
"name": "icon-arrows-up-down",
"tempChar": ""
"tempChar": ""
},
{
"order": 26,
@ -266,7 +322,7 @@
"prevSize": 32,
"code": 42,
"name": "icon-asterisk",
"tempChar": ""
"tempChar": ""
},
{
"order": 27,
@ -274,7 +330,7 @@
"prevSize": 32,
"code": 72,
"name": "icon-autoflow-tabular",
"tempChar": ""
"tempChar": ""
},
{
"order": 28,
@ -282,7 +338,7 @@
"prevSize": 32,
"code": 224,
"name": "icon-box",
"tempChar": ""
"tempChar": ""
},
{
"order": 29,
@ -290,7 +346,7 @@
"prevSize": 32,
"code": 50,
"name": "icon-check",
"tempChar": ""
"tempChar": ""
},
{
"order": 30,
@ -298,7 +354,7 @@
"prevSize": 32,
"code": 67,
"name": "icon-clock",
"tempChar": ""
"tempChar": ""
},
{
"order": 31,
@ -306,7 +362,7 @@
"prevSize": 32,
"code": 46,
"name": "icon-connectivity",
"tempChar": ""
"tempChar": ""
},
{
"order": 32,
@ -314,7 +370,7 @@
"prevSize": 32,
"code": 100,
"name": "icon-database-query",
"tempChar": ""
"tempChar": ""
},
{
"order": 17,
@ -322,7 +378,7 @@
"prevSize": 32,
"code": 68,
"name": "icon-database",
"tempChar": ""
"tempChar": ""
},
{
"order": 35,
@ -330,7 +386,7 @@
"prevSize": 32,
"code": 81,
"name": "icon-dictionary",
"tempChar": ""
"tempChar": ""
},
{
"order": 36,
@ -338,7 +394,7 @@
"prevSize": 32,
"code": 242,
"name": "icon-duplicate",
"tempChar": ""
"tempChar": ""
},
{
"order": 37,
@ -346,7 +402,7 @@
"prevSize": 32,
"code": 102,
"name": "icon-folder-new",
"tempChar": ""
"tempChar": ""
},
{
"order": 38,
@ -354,7 +410,7 @@
"prevSize": 32,
"code": 70,
"name": "icon-folder",
"tempChar": ""
"tempChar": ""
},
{
"order": 39,
@ -362,7 +418,7 @@
"prevSize": 32,
"code": 95,
"name": "icon-fullscreen-collapse",
"tempChar": ""
"tempChar": ""
},
{
"order": 40,
@ -370,7 +426,7 @@
"prevSize": 32,
"code": 122,
"name": "icon-fullscreen-expand",
"tempChar": ""
"tempChar": ""
},
{
"order": 41,
@ -378,7 +434,7 @@
"prevSize": 32,
"code": 71,
"name": "icon-gear",
"tempChar": ""
"tempChar": ""
},
{
"order": 49,
@ -386,7 +442,7 @@
"prevSize": 32,
"code": 227,
"name": "icon-image",
"tempChar": ""
"tempChar": ""
},
{
"order": 42,
@ -394,7 +450,7 @@
"prevSize": 32,
"code": 225,
"name": "icon-layers",
"tempChar": ""
"tempChar": ""
},
{
"order": 43,
@ -402,7 +458,7 @@
"prevSize": 32,
"code": 76,
"name": "icon-layout",
"tempChar": ""
"tempChar": ""
},
{
"order": 44,
@ -410,7 +466,7 @@
"prevSize": 32,
"code": 226,
"name": "icon-line-horz",
"tempChar": ""
"tempChar": ""
},
{
"order": 75,
@ -418,7 +474,7 @@
"prevSize": 32,
"code": 244,
"name": "icon-link",
"tempChar": ""
"tempChar": ""
},
{
"order": 46,
@ -426,7 +482,7 @@
"prevSize": 32,
"code": 88,
"name": "icon-magnify-in",
"tempChar": ""
"tempChar": ""
},
{
"order": 47,
@ -434,7 +490,7 @@
"prevSize": 32,
"code": 89,
"name": "icon-magnify-out",
"tempChar": ""
"tempChar": ""
},
{
"order": 48,
@ -442,7 +498,7 @@
"prevSize": 32,
"code": 77,
"name": "icon-magnify",
"tempChar": ""
"tempChar": ""
},
{
"order": 34,
@ -450,7 +506,7 @@
"prevSize": 32,
"code": 109,
"name": "icon-menu",
"tempChar": ""
"tempChar": ""
},
{
"order": 50,
@ -458,7 +514,7 @@
"prevSize": 32,
"code": 243,
"name": "icon-move",
"tempChar": ""
"tempChar": ""
},
{
"order": 51,
@ -466,7 +522,7 @@
"prevSize": 32,
"code": 121,
"name": "icon-new-window",
"tempChar": ""
"tempChar": ""
},
{
"order": 52,
@ -474,7 +530,7 @@
"prevSize": 32,
"code": 111,
"name": "icon-object",
"tempChar": ""
"tempChar": ""
},
{
"order": 73,
@ -482,7 +538,7 @@
"prevSize": 32,
"code": 63,
"name": "icon-object-unknown",
"tempChar": ""
"tempChar": ""
},
{
"order": 53,
@ -490,7 +546,7 @@
"prevSize": 32,
"code": 86,
"name": "icon-packet",
"tempChar": ""
"tempChar": ""
},
{
"order": 54,
@ -498,7 +554,7 @@
"prevSize": 32,
"code": 234,
"name": "icon-page",
"tempChar": ""
"tempChar": ""
},
{
"order": 55,
@ -506,7 +562,7 @@
"prevSize": 32,
"code": 241,
"name": "icon-pause",
"tempChar": ""
"tempChar": ""
},
{
"order": 56,
@ -514,7 +570,7 @@
"prevSize": 32,
"code": 112,
"name": "icon-pencil",
"tempChar": ""
"tempChar": ""
},
{
"order": 65,
@ -522,7 +578,7 @@
"prevSize": 32,
"code": 79,
"name": "icon-people",
"tempChar": ""
"tempChar": ""
},
{
"order": 57,
@ -530,7 +586,7 @@
"prevSize": 32,
"code": 239,
"name": "icon-play",
"tempChar": ""
"tempChar": ""
},
{
"order": 58,
@ -538,7 +594,7 @@
"prevSize": 32,
"code": 233,
"name": "icon-plot-resource",
"tempChar": ""
"tempChar": ""
},
{
"order": 59,
@ -546,7 +602,7 @@
"prevSize": 32,
"code": 43,
"name": "icon-plus",
"tempChar": ""
"tempChar": ""
},
{
"order": 60,
@ -554,7 +610,7 @@
"prevSize": 32,
"code": 45,
"name": "icon-minus",
"tempChar": ""
"tempChar": ""
},
{
"order": 61,
@ -562,7 +618,7 @@
"prevSize": 32,
"code": 54,
"name": "icon-sine",
"tempChar": ""
"tempChar": ""
},
{
"order": 62,
@ -570,7 +626,7 @@
"prevSize": 32,
"code": 228,
"name": "icon-T",
"tempChar": ""
"tempChar": ""
},
{
"order": 63,
@ -578,7 +634,7 @@
"prevSize": 32,
"code": 116,
"name": "icon-telemetry-panel",
"tempChar": ""
"tempChar": ""
},
{
"order": 64,
@ -586,7 +642,7 @@
"prevSize": 32,
"code": 84,
"name": "icon-telemetry",
"tempChar": ""
"tempChar": ""
},
{
"order": 18,
@ -594,7 +650,7 @@
"prevSize": 32,
"code": 246,
"name": "icon-thumbs-strip",
"tempChar": ""
"tempChar": ""
},
{
"order": 67,
@ -602,7 +658,7 @@
"prevSize": 32,
"code": 83,
"name": "icon-timeline",
"tempChar": ""
"tempChar": ""
},
{
"order": 68,
@ -610,7 +666,7 @@
"prevSize": 32,
"code": 245,
"name": "icon-timer",
"tempChar": ""
"tempChar": ""
},
{
"order": 69,
@ -618,7 +674,7 @@
"prevSize": 32,
"code": 90,
"name": "icon-trash",
"tempChar": ""
"tempChar": ""
},
{
"order": 70,
@ -626,7 +682,7 @@
"prevSize": 32,
"code": 229,
"name": "icon-two-parts-both",
"tempChar": ""
"tempChar": ""
},
{
"order": 71,
@ -634,7 +690,7 @@
"prevSize": 32,
"code": 231,
"name": "icon-two-parts-one-only",
"tempChar": ""
"tempChar": ""
},
{
"order": 72,
@ -642,7 +698,7 @@
"prevSize": 32,
"code": 120,
"name": "icon-x-heavy",
"tempChar": ""
"tempChar": ""
},
{
"order": 66,
@ -650,7 +706,7 @@
"prevSize": 32,
"code": 58946,
"name": "icon-x",
"tempChar": ""
"tempChar": ""
}
],
"id": 2,
@ -665,6 +721,173 @@
"height": 1024,
"prevSize": 32,
"icons": [
{
"id": 92,
"paths": [
"M514 2c-282.8 0-512 229.2-512 512s229.2 512 512 512 512-229.2 512-512-229.2-512-512-512zM860.2 450h-282.2v-282.2c69.6 12.8 133.8 46.2 185 97.4 51 51 84.4 115.2 97.2 184.8zM450 167.8v282.2h-282.2c12.8-69.6 46.2-133.8 97.4-185 51-51 115.2-84.4 184.8-97.2zM167.8 578h282.2v282.2c-69.6-12.8-133.8-46.2-185-97.4-51-51-84.4-115.2-97.2-184.8zM578 860.2v-282.2h282.2c-12.8 69.6-46.2 133.8-97.4 185-51 51-115.2 84.4-184.8 97.2z"
],
"attrs": [
{
"fill": "rgb(0, 0, 0)"
}
],
"isMulticolor": false,
"grid": 0,
"tags": [
"icon-crosshair"
],
"colorPermutations": {
"125525525516161751": [
0
]
}
},
{
"id": 91,
"paths": [
"M256 0h-256v1024h256c105.6 0 192-86.4 192-192v-640c0-105.6-86.4-192-192-192z",
"M512 320l512 320v-640z"
],
"attrs": [
{
"fill": "rgb(0, 0, 0)"
},
{
"fill": "rgb(0, 0, 0)"
}
],
"isMulticolor": false,
"grid": 0,
"tags": [
"icon-collapse-pane-left"
],
"colorPermutations": {
"125525525516161751": [
0,
0
]
}
},
{
"id": 90,
"paths": [
"M768 0h256v1024h-256c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192z",
"M512 320l-512 320v-640z"
],
"attrs": [
{
"fill": "rgb(0, 0, 0)"
},
{
"fill": "rgb(0, 0, 0)"
}
],
"isMulticolor": false,
"grid": 0,
"tags": [
"icon-collapse-pane-right"
],
"colorPermutations": {
"125525525516161751": [
0,
0
]
}
},
{
"id": 89,
"paths": [
"M192.2 576c-0.2 0-0.2 0 0 0l-0.2 448h640v-447.8c0 0 0 0-0.2-0.2h-639.6z",
"M978.8 210.8l-165.4-165.4c-25-25-74.2-45.4-109.4-45.4h-576c-70.4 0-128 57.6-128 128v768c0 70.4 57.6 128 128 128v-448c0-35.2 28.8-64 64-64h640c35.2 0 64 28.8 64 64v448c70.4 0 128-57.6 128-128v-576c0-35.2-20.4-84.4-45.2-109.2zM704 256c0 35.2-28.8 64-64 64h-448c-35.2 0-64-28.8-64-64v-192h320v192h128v-192h128v192z"
],
"attrs": [
{
"fill": "rgb(0, 0, 0)"
},
{
"fill": "rgb(0, 0, 0)"
}
],
"isMulticolor": false,
"grid": 0,
"tags": [
"icon-save-v2"
],
"colorPermutations": {
"125525525516161751": [
0,
0
]
}
},
{
"id": 88,
"paths": [
"M896 192h-320c-16.4-16.4-96.8-96.8-109.2-109.2l-37.4-37.4c-25-25-74.2-45.4-109.4-45.4h-256c-35.2 0-64 28.8-64 64v384c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v-128c0-70.4-57.6-128-128-128z",
"M896 448h-768c-70.4 0-128 57.6-128 128v320c0 70.4 57.6 128 128 128h768c70.4 0 128-57.6 128-128v-320c0-70.4-57.6-128-128-128zM320 896h-128v-320h128v320zM576 896h-128v-320h128v320zM832 896h-128v-320h128v320z"
],
"attrs": [],
"isMulticolor": false,
"grid": 0,
"tags": [
"icon-dataset"
],
"colorPermutations": {
"125525525516161751": []
}
},
{
"id": 87,
"paths": [
"M512 1024c106 0 192-86 192-192h-384c0 106 86 192 192 192z",
"M896 448v-64c0-212-172-384-384-384s-384 172-384 384v64c0 70.6-57.4 128-128 128v128h1024v-128c-70.6 0-128-57.4-128-128z"
],
"attrs": [
{
"fill": "rgb(6, 161, 75)"
},
{
"fill": "rgb(6, 161, 75)"
}
],
"isMulticolor": false,
"grid": 0,
"tags": [
"icon-bell"
],
"colorPermutations": {
"125525525516161751": [
1,
1
]
}
},
{
"id": 86,
"paths": [
"M1024 0h-1024c0 282.8 229.2 512 512 512s512-229.2 512-512zM512 384c-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.4z",
"M512 512c-282.8 0-512 229.2-512 512h1024c0-282.8-229.2-512-512-512z"
],
"attrs": [
{
"fill": "rgb(6, 161, 75)"
},
{
"fill": "rgb(6, 161, 75)"
}
],
"isMulticolor": false,
"grid": 0,
"tags": [
"icon-hourglass"
],
"colorPermutations": {
"125525525516161751": [
1,
1
]
}
},
{
"id": 85,
"paths": [
@ -698,7 +921,8 @@
"icon-x-in-circle"
],
"colorPermutations": {
"16161751": []
"16161751": [],
"125525525516161751": []
}
},
{
@ -899,6 +1123,11 @@
1,
1,
1
],
"125525525516161751": [
1,
1,
1
]
}
},
@ -1051,18 +1280,28 @@
{
"id": 67,
"paths": [
"M832 512.4c0-0.2 0-0.2 0-0.4v-320c0-105.6-86.4-192-192-192h-448c-105.6 0-192 86.4-192 192v320c0 105.6 86.4 192 192 192h263.6l-197.2-445.6 573.6 254z",
"M766.8 659.8l193.8-20.4-576.6-255.4 255.4 576.6 20.4-193.8 257 257.2 107.2-107.2z"
"M894-2h-768c-70.4 0-128 57.6-128 128v768c0 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.8v-400.2c0.2-70.4-57.4-128-127.8-128z",
"M958.6 637.4l-576.6-255.4 255.4 576.6 64.6-128.6 192 192 128-128-192-192z"
],
"attrs": [
{},
{}
{
"fill": "rgb(0, 0, 0)"
},
{
"fill": "rgb(0, 0, 0)"
}
],
"isMulticolor": false,
"grid": 0,
"tags": [
"icon-box-with-arrow-cursor"
]
],
"colorPermutations": {
"125525525516161751": [
0,
0
]
}
},
{
"id": 66,
@ -1338,6 +1577,9 @@
"colorPermutations": {
"16161751": [
0
],
"125525525516161751": [
0
]
}
},
@ -14853,6 +15095,5 @@
"gridSize": 16,
"showLiga": false
},
"uid": -1,
"time": 1441993324496
"uid": -1
}

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="&#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="&#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="&#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" />
@ -85,6 +85,13 @@
<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="&#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="&#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-crosshair" d="M514 958c-282.8 0-512-229.2-512-512s229.2-512 512-512 512 229.2 512 512-229.2 512-512 512zM860.2 510h-282.2v282.2c69.6-12.8 133.8-46.2 185-97.4 51-51 84.4-115.2 97.2-184.8zM450 792.2v-282.2h-282.2c12.8 69.6 46.2 133.8 97.4 185 51 51 115.2 84.4 184.8 97.2zM167.8 382h282.2v-282.2c-69.6 12.8-133.8 46.2-185 97.4-51 51-84.4 115.2-97.2 184.8zM578 99.8v282.2h282.2c-12.8-69.6-46.2-133.8-97.4-185-51-51-115.2-84.4-184.8-97.2z" />
<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>

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -42,13 +42,17 @@ $ueFooterH: 25px;
$ueColMargin: 1.5%;
$ueAppLogoW: 105px;
$ueEditToolBarH: 25px;
$ueBrowseLeftPaneW: 25%;
$ueBrowseLeftPaneTreeW: 25%;
$ueBrowseRightPaneInspectW: 20%;
$ueCollapsedPaneEdgeM: 20px;
$uePaneMiniTabH: $ueTopBarH;
$uePaneMiniTabW: 9px;
$ueEditLeftPaneW: 75%;
$treeSearchInputBarH: 25px;
$ueTimeControlH: (33px, 20px, 20px);
// Overlay
$ovrTopBarH: 60px;
$ovrFooterH: 30px;
$ovrTopBarH: 45px;
$ovrFooterH: 24px;
$overlayMargin: 25px;
// Items
$ueBrowseGridItemLg: 200px;
@ -57,7 +61,8 @@ $ueBrowseGridItemBottomBarH: 30px;
$itemPadLR: 5px;
// Tree
$treeVCW: 10px;
$treeTypeIconH: 16px;
$treeTypeIconH: 1.4em; // was 16px
$treeTypeIconHPx: 16px;
$treeTypeIconW: 20px;
$treeContextTriggerW: 20px;
// Tabular

View File

@ -34,10 +34,6 @@
font-style: normal;
}
.ui-symbol {
font-family: 'symbolsfont';
}
/************************** HTML ENTITIES */
a {
color: $colorA;
@ -55,7 +51,7 @@ body, html {
color: $colorBodyFg;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 100%;
//font-weight: 500;
font-weight: 200;
height: 100%;
width: 100%;
overflow: hidden;

View File

@ -29,11 +29,14 @@
}
.ui-symbol {
font-family: 'symbolsfont';
&.type-icon {
color: $colorObjHdrIc;
}
&.icon {
color: $colorKey;
//position: relative;
font-size: inherit;
&.alert {
color: $colorAlert;
&:hover {
@ -69,18 +72,32 @@
position: absolute;
}
//.tree-item .type-icon {
// font-size: 16px; // 16px is crisp size
//}
.l-icon-link:before {
content: "\f4";
}
.l-icon-alert {
display: none !important; // Remove this when alerts are enabled
&:before {
color: $colorAlert;
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,107 @@
/*****************************************************************************
* 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 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

@ -29,8 +29,7 @@
@import "helpers/bubbles";
@import "helpers/splitter";
@import "helpers/wait-spinner";
@import "messages";
@import "properties";
@import "inspector";
/********************************* CONTROLS */
@import "controls/breadcrumb";
@ -39,6 +38,7 @@
@import "controls/controls";
@import "controls/lists";
@import "controls/menus";
@import "controls/messages";
@import "controls/time-controller";
@import "mobile/controls/menus";
@ -62,7 +62,6 @@
@import "mobile/tree";
@import "user-environ/frame";
@import "user-environ/top-bar";
@import "user-environ/bottom-bar";
@import "user-environ/tool-bar";
/********************************* VIEWS */
@ -70,7 +69,6 @@
@import "lists/tabular";
@import "plots/plots-main";
@import "iframe";
@import "hide-non-functional";
@import "views";
@import "items/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;
}
@mixin trans-prop-nice($props, $t: 500ms) {
@if $t == 0 {
@mixin trans-prop-nice($props, $dur: 500ms, $delay: 0) {
// Multiple $props must be in parans like this: (left, right)
@if $dur == 0 {
@include transition-property(none);
} @else {
@include transition-property($props);
@include transition-duration($t);
@include transition-duration($dur);
@include transition-timing-function(ease-in-out);
@include transition-delay($delay);
}
}
@mixin trans-prop-nice-fade($t: 0.5s) {
@if $t == 0 {
@mixin trans-prop-nice-fade($dur: 500ms, $delay: 0) {
@if $dur == 0 {
@include transition-property(none);
} @else {
@include transition-property(visibility, opacity, background-color, border-color);
@include transition-duration($t);
@include transition-property(opacity, background-color, border-color, color);
@include transition-duration($dur);
@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-duration($t);
@include transition-duration($dur);
@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-duration($t);
@include transition-duration($dur);
@include transition-timing-function(ease-in-out);
@include transition-delay($delay);
}
@mixin triangle-right($size, $color) {
@ -94,7 +99,6 @@
}
@mixin triangle($dir: "left", $size: 5px, $ratio: 1, $color: red) {
//$size: $size*2;
width: 0;
height: 0;
$slopedB: $size/$ratio solid transparent;
@ -129,6 +133,24 @@
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') {
$deg: 90deg;
@if ($repeatDir != 'x') {
@ -156,31 +178,28 @@
}
@mixin controlGrippy($b, $direction: horizontal, $w: 1px, $style: dotted) {
&:before {
@include trans-prop-nice("border-color", 0.75s);
content: '';
display: block;
height: auto;
pointer-events: none;
position: absolute;
z-index: 2;
//&:before {
//@include trans-prop-nice("border-color", 25ms);
content: '';
display: block;
//height: auto;
pointer-events: none;
position: absolute;
z-index: 2;
@if $direction == "horizontal" {
border-top: $w $style darken($b, 15%);
top: 2px;
left: 5px;
right: 5px;
@if $direction == "horizontal" {
border-top: $w $style darken($b, 15%);
top: 2px;
left: 5px;
right: 5px;
height: 1px;
} @else if $direction == "vertical" {
border-left: $w $style darken($b, 15%);
left: 2px;
bottom: 5px;
top: 5px;
}
}
&:not(.disabled):hover:before {
@include trans-prop-nice("border-color", 25ms);
border-color: $colorGrippyInteriorHover;
} @else if $direction == "vertical" {
border-left: $w $style darken($b, 15%);
left: 2px;
bottom: 5px;
top: 5px;
width: 1px;
}
}
@ -256,6 +275,12 @@
@return percentage($d);
}
@function splitterHandleInset($splitterD: 21px, $splitterHandleD: 1px) {
// Space to either side of the handle
@return ($splitterD - $splitterHandleD) * 0.5;
}
/*********************************************** CONTROLS, FORM ELEMENTS */
@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 */
//position: relative;
top: 50%;
@include webkitProp(transform, translateY(-50%));
//-webkit-transform: translateY(-50%);
//-ms-transform: translateY(-50%);
//transform: translateY(-50%);
@include transform(translateY(-50%));
}
@mixin verticalCenterBlock($holderH, $itemH) {

View File

@ -22,13 +22,17 @@
$baseRatio: 1.5;
$pad: $interiorMargin * $baseRatio;
.s-btn {
@include box-sizing(border-box);
.s-btn,
.s-icon-btn {
@include user-select(none);
cursor: pointer;
text-decoration: none;
height: $btnStdH;
line-height: $btnStdH;
}
.s-btn {
@include box-sizing(border-box);
padding: 0 $pad;
font-size: 0.7rem;
@ -89,6 +93,155 @@ $pad: $interiorMargin * $baseRatio;
}
}
.s-icon-btn {
@extend .ui-symbol;
color: $colorBtnIcon;
&:hover {
color: lighten($colorBtnIcon, $ltGamma);
}
}
.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;
&:before,
&:after {
position: absolute;
display: inherit;
}
&:before {
content: '\78'; // X icon
}
&:hover {
color: $colorKey;
//@include transform(scale(1.2));
}
}
}
.l-btn-set {
// Buttons that have a very tight conceptual grouping - no internal space between them.
// Structure: .btn-set > mct-representation class=first|last > .s-btn

View File

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

View File

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

View File

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

@ -19,68 +19,114 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
.split-layout {
$b: pullForward($colorBodyBg, $contrastRatioPercent);
.splitter {
background-color: $b;
@include border-radius($splitterEndCr);
@include boxShdw($splitterShdw);
overflow: hidden;
position: absolute;
z-index: 1;
//@if $colorSplitterHover != 'none' {
&:hover {
background-color: $colorSplitterHover;
}
//}
}
&.horizontal {
// Slides vertically up and down, splitting the element horizontally
overflow: hidden; // Suppress overall scroll; each internal pane handles its own overflow
.pane {
left: 0;
right: 0;
&.top {
bottom: auto;
}
&.bottom {
top: auto;
}
}
>.splitter {
@include controlGrippy($colorSplitterInterior, horizontal);
cursor: row-resize;
left: 0; right: 0;
width: auto;
height: $splitterW;
}
}
&.vertical {
// Slides horizontally left to right, splitting the element vertically
.pane {
top: 0;
bottom: 0;
&.left {
right: auto;
}
&.right {
left: auto;
}
}
>.splitter {
@include controlGrippy($colorBodyBg, vertical);
bottom: 0;
cursor: col-resize;
width: $splitterW;
}
}
.splitter {
// Redo the splitter.
// New look is a simple line.
// Main width is used to provide a good click area, and is always transparent
// :after will be a positioned and colored element that is the handle
//@include test(red);
display: block;
position: absolute;
z-index: 1;
&:after {
// The handle
content:"";
pointer-events: none;
@include absPosDefault(0);
background: $colorSplitterBg;
display: block;
@if $splitterEndCr != 'none' {
@include border-radius($splitterEndCr);
}
}
&:active {
//@include test();
&:after {
background-color: $colorSplitterActive !important;
}
}
@if $colorSplitterHover != 'none' {
&:not(:active) {
&:hover {
&:after {
background-color: $colorSplitterHover !important;
@include trans-prop-nice(background-color, 150ms);
}
}
}
}
}
.browse-area .splitter {
top: $ueTopBarH + $interiorMarginLg;
.split-layout {
$inset: splitterHandleInset($splitterD,$splitterHandleD);
&.horizontal {
// Slides vertically up and down, splitting the element horizontally
overflow: hidden; // Suppress overall scroll; each internal pane handles its own overflow
.pane {
left: 0;
right: 0;
&.top {
bottom: auto;
}
&.bottom {
top: auto;
}
}
>.splitter {
cursor: row-resize;
left: 0;
right: 0;
height: $splitterD;
&:after {
top: $inset; bottom: $inset;
}
}
}
&.vertical {
// Slides horizontally left to right, splitting the element vertically
.pane {
top: 0;
bottom: 0;
&.left {
right: auto;
}
&.right {
left: auto;
}
}
>.splitter {
cursor: col-resize;
top: 0;
bottom: 0;
&:not(.flush-right) {
width: $splitterD;
&:after {
left: $inset; right: $inset;
}
}
&.flush-right {
width: ceil($splitterD / 2);
&:after {
background-color: transparent;
left: auto; right: 0; width: $splitterHandleD;
}
&.edge-shdw {
@include background-image(linear-gradient(90deg, rgba(black, 0) 40%, rgba(black, 0.05) 70%, rgba(black, 0.2) 100%));
}
}
}
}
}
/*.browse-area .splitter {
top: 0; //$ueTopBarH + $interiorMarginLg;
}
.edit-area .splitter {
top: 0;
}
}*/

View File

@ -86,27 +86,16 @@
//top: $ueBrowseGridItemTopBarH; bottom: $ueBrowseGridItemBottomBarH; //
line-height: $lh;
z-index: 1;
.item-type {
//@include trans-prop-nice("color", $transTime);
@include absPosDefault($iconMargin, false);
//@include test(red);
//color: $colorItemIc;
text-align: center;
.item-type,
.t-item-icon {
//@include test();
@include transform(translateX(-50%) translateY(-55%));
position: absolute;
top: 50%; left: 50%;
//height: $iconD; width: $iconD;
font-size: $iconD * 0.95; //6em;
line-height: $iconD;
bottom: auto;
height: $iconD;
top: $iconMargin - 10;
.l-icon-link {
color: $colorIconLink;
height: auto;
line-height: 100%;
position: absolute;
font-size: 0.3em;
left: 0px;
bottom: 10px;
z-index: 2;
}
//line-height: normal;
//text-align: center;
}
.item-open {
@include trans-prop-nice("opacity", $transTime);

View File

@ -23,7 +23,7 @@
/************************** MOBILE REPRESENTATION ITEMS DIMENSIONS */
$mobileListIconSize: 30px;
$mobileTitleDescH: 35px;
$mobileOverlayMargin: 10px;
$mobileOverlayMargin: 20px;
$phoneItemH: floor($ueBrowseGridItemLg/4);
$tabletItemH: floor($ueBrowseGridItemLg/3);

View File

@ -49,18 +49,11 @@
}
.item-main {
.item-type {
//@include test(blue);
.item-type,
.t-item-icon {
font-size: $mobileListIconSize;
right: auto;
bottom: auto;
left: 0;
line-height: 100%;
text-align: left;
width: $mobileListIconSize;
.l-icon-link {
bottom: 0;
}
left: $interiorMarginLg + $interiorMargin;
line-height: normal;
}
.item-open {
display: block;

View File

@ -32,7 +32,7 @@
background-color: $colorMobilePaneLeft;
}
.pane.right-repr {
.pane.right.items {
//@include test();
@include slMenuTransitions;
margin-left: 0 !important;
@ -42,78 +42,66 @@
}
}
.user-environ .browse-area,
.user-environ .edit-area,
.user-environ .editor {
top: 0; left: 0; right: 0; bottom: $ueFooterH;
}
.holder.l-mobile {
top: $bodyMargin !important;
.holder.holder-create-and-search {
right: $bodyMargin !important;
bottom: $bodyMargin !important;
left: $bodyMargin !important;
}
// When the tree is hidden, these are the
// When the tree is hidden, these are the
// classes used for the left menu and the
// right representation.
.browse-hidetree {
@include user-select(none);
.pane-tree-hidden {
// Sets the left tree menu when the tree
// is hidden.
.pane.left.treeview {
opacity: 0;
right: 100% !important;
width: auto !important;
overflow-y: hidden;
overflow-x: hidden;
@include trans-prop-nice(opacity, 150ms);
//right: 100% !important;
//width: auto !important;
//overflow-y: hidden;
//overflow-x: hidden;
opacity: 0 !important;
}
// Sets the right represenation when
// the tree is hidden.
.pane.right-repr {
.pane.right.items {
left: 0 !important;
}
}
.browse-showtree {
.pane-tree-showing {
// NOTE: DISABLED SELECTION
// Selection disabled in both panes
// causing cut/copy/paste menu to
// not appear. Should me moved in
// future to properly work
@include user-select(none);
//@include user-select(none);
// Sets the left tree menu when the tree is shown.
.pane.left.treeview {
@include trans-prop-nice(opacity, .4s);
@include trans-prop-nice(opacity, 250ms, $delay: 250ms);
@include background-image(linear-gradient(90deg, rgba(black, 0) 98%, rgba(black, 0.3) 100%));
opacity: 1;
display: block !important;
//width: auto !important; // CH CO
right: auto !important;
width: $proporMenuWithView !important;
}
// Sets the right representation when the tree is shown.
.pane.right-repr {
.pane.right.items {
left: $proporMenuWithView !important;
//width: auto !important;
//left: 0 !important;
//transform: translateX($proporMenuWithView);
}
}
.mobile-menu-icon {
.toggle-tree {
color: $colorKey !important;
font-size: 110%;
position: absolute;
top: $bodyMargin + 2;
left: $bodyMargin;
&:after {
content:'m' !important;
font-family: symbolsfont;
}
}
.object-browse-bar {
//@include test();
left: 30px !important;
left: 45px !important;
.context-available {
opacity: 1 !important;
}
@ -153,13 +141,13 @@
}
@include phonePortrait {
.browse-showtree {
.pane-tree-showing {
.pane.left.treeview {
width: $proporMenuOnly !important;
}
.pane.right-repr {
.pane.right.items {
left: 0 !important;
@include webkitProp(transform, translateX($proporMenuOnly));
@include transform(translateX($proporMenuOnly));
#content-area {
opacity: 0;
}

View File

@ -37,21 +37,18 @@
//@include test(red);
position: absolute;
font-size: 1.1em;
height: $mobileTreeItemH;
line-height: inherit;
right: 0px;
width: $mobileTreeRightArrowW;
text-align: center;
}
.label {
.label,
.t-object-label {
left: 0;
right: $mobileTreeRightArrowW + $interiorMargin; // Allows tree item name to stop prior to the arrow
line-height: $mobileTreeItemH;
//font-size: 1.1em; // CH CO
.type-icon {
@include verticalCenterBlock($mobileTreeItemH, $treeTypeIconH);
}
.title-label {
}
line-height: inherit;
}
}
}

View File

@ -1,16 +1,12 @@
@include phoneandtablet {
.overlay {
$m: 0;
.clk-icon.close {
top: $mobileOverlayMargin; right: $mobileOverlayMargin;
}
> .holder {
@include border-radius($m);
top: $m;
right: $m;
bottom: $m;
left: $m;
height: 90%; width: 90%;
> .contents {
top: $mobileOverlayMargin;
right: $mobileOverlayMargin;
@ -22,35 +18,64 @@
margin-right: 1.2em;
}
}
.form.editor {
border: none;
.contents {
top: 0;
right: 0;
bottom: 0;
left: 0;
}
}
}
}
}
}
@include phone {
.overlay > .holder > .contents .form.editor .contents .form-row {
> .label,
> .controls {
//@include test(blue);
display: block;
float: none;
width: 100%;
.overlay > .holder {
//@include test(orange); // This works!
$m: 0;
@include border-radius($m);
top: $m;
right: $m;
bottom: $m;
left: $m;
height: auto; width: auto;
min-width: 200px; min-height: 200px;
max-height: 100%; max-width: 100%;
overflow: auto;
@include transform(none);
.editor .form .form-row {
> .label,
> .controls {
//@include test(blue);
display: block;
float: none;
width: 100%;
}
> .label {
&:after {
float: none;
}
}
}
.contents {
.abs.top-bar,
.abs.editor,
.abs.message-body,
.abs.bottom-bar {
//@include test(orange);
top: auto; right: auto; bottom: auto; left: auto;
height: auto; width: auto;
margin-bottom: $interiorMarginLg * 2;
position: relative;
}
}
}
.t-dialog-sm .overlay > .holder {
//@include test(blue);
height: auto; max-height: 100%;
}
}
@include phonePortrait {
.overlay > .holder {
.contents .bottom-bar {
text-align: center;
}
> .label {
&:after {
float: none;
}
}
}
}

View File

@ -20,79 +20,124 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
.overlay {
.blocker {
background: $colorOvrBlocker;
z-index: 100;
}
font-size: 90%;
.blocker {
background: $colorOvrBlocker;
z-index: 100;
}
.clk-icon.close {
font-size: 0.8rem;
position: absolute;
top: $interiorMarginLg; right: $interiorMarginLg; bottom: auto; left: auto;
z-index: 100;
top: $interiorMarginLg;
right: $interiorMarginLg;
bottom: auto;
left: auto;
z-index: 100;
}
>.holder {
$i: 15%;
@include containerSubtle($colorOvrBg, $colorOvrFg);
@include border-radius($basicCr * 3);
color: $colorOvrFg;
top: $i; right: $i; bottom: $i; left: $i;
z-index: 101;
>.contents {
> .holder {
//$i: 15%;
@include containerSubtle($colorOvrBg, $colorOvrFg);
@include border-radius($basicCr * 3);
color: $colorOvrFg;
top: 50%;
right: auto;
bottom: auto;
left: 50%;
@include transform(translateX(-50%) translateY(-50%));
height: 70%;
width: 50%;
min-height: 300px;
max-height: 800px;
min-width: 600px;
max-width: 1000px;
z-index: 101;
> .contents {
$m: $overlayMargin;
top: $m; right: $m; bottom: $m; left: $m;
top: $m;
right: $m;
bottom: $m;
left: $m;
//.top-bar,
//.editor,
//.bottom-bar {
// @include absPosDefault();
//}
}
}
.title {
@include ellipsize();
font-size: 1.2em;
margin-bottom: $interiorMargin;
}
.top-bar {
.title {
@include ellipsize();
font-size: 1.2em;
line-height: 120%;
margin-bottom: $interiorMargin;
}
.hint {
color: pushBack($colorOvrFg, 20%);
}
.abs.top-bar {
height: $ovrTopBarH;
}
.editor {
top: $ovrTopBarH + ($interiorMargin * 2);
bottom: $ovrFooterH + $interiorMargin * 2;
left: 0; right: 0;
}
.bottom-bar {
top: auto; right: 0; bottom: 0; left: 0;
overflow: visible;
//font-size: 1em;
height: $ovrFooterH;
text-align: right;
.s-btn {
$bg: $colorOvrBtnBg;
&:not(.major) {
@include btnSubtle($bg, pullForward($bg, 10%), $colorOvrBtnFg, $colorOvrBtnFg);
}
font-size: 95%;
height: $ovrFooterH;
line-height: $ovrFooterH;
margin-left: $interiorMargin;
padding: 0 $interiorMargin * 3;
//&.major {
// @extend .s-btn.major;
// &:hover {
// @extend .s-btn.major:hover;
// }
//}
.abs.editor,
.abs.message-body {
top: $ovrTopBarH + $interiorMarginLg;
bottom: $ovrFooterH + $interiorMarginLg;
left: 0;
right: 0;
overflow: auto;
.field.l-med {
input[type='text'] {
width: 100%;
}
}
}
.contents.l-dialog {
$myM: $interiorMargin;
top: $myM;
right: $myM;
bottom: $myM;
left: $myM;
overflow: auto;
.field.l-med {
input[type='text'] {
width: 100%;
}
}
.bottom-bar {
text-align: right;
.s-btn {
$bg: $colorOvrBtnBg;
&:not(.major) {
@include btnSubtle($bg, pullForward($bg, 10%), $colorOvrBtnFg, $colorOvrBtnFg);
}
font-size: 95%;
height: $ovrFooterH;
line-height: $ovrFooterH;
margin-left: $interiorMargin;
padding: 0 $interiorMargin * 3;
&:first-child {
margin-left: 0;
}
}
}
.abs.bottom-bar {
top: auto;
right: 0;
bottom: 0;
left: 0;
overflow: visible;
//font-size: 1em;
height: $ovrFooterH;
}
.l-progress-bar {
$h: $progressBarHOverlay;
display: block;
height: $h;
line-height: $h;
margin: .5em 0;
width: 100%;
}
}
.t-dialog-sm .overlay > .holder {
// Used for blocker and in-progress dialogs, modal alerts, etc.
//@include test(red);
$h: 225px;
min-height: $h;
height: $h;
}

View File

@ -52,7 +52,6 @@ ul.tree {
font-size: 0.75em;
width: $treeVCW;
$runningItemW: $interiorMargin + $treeVCW;
// NOTE: [Mobile] Removed Hover on Mobile
@include desktop {
&:hover {
color: $colorItemTreeVCHover !important;
@ -60,25 +59,34 @@ ul.tree {
}
}
.label {
.label,
.t-object-label {
display: block;
// @include test(orange);
@include absPosDefault();
//left: $runningItemW + $interiorMargin; // Adding pad to left to make room for link icon
line-height: $menuLineH;
//left: $runningItemW;
.t-item-icon {
@include txtShdwSubtle($shdwItemTreeIcon);
font-size: $treeTypeIconH;
color: $colorItemTreeIcon;
position: absolute;
left: $interiorMargin;
top: 50%;
width: $treeTypeIconH;
@include transform(translateY(-50%));
}
.type-icon {
//@include absPosDefault(0, false);
$d: $treeTypeIconH; // 16px is crisp size
$d: $treeTypeIconH;
@include txtShdwSubtle($shdwItemTreeIcon);
font-size: $d;
font-size: $treeTypeIconH;
color: $colorItemTreeIcon;
left: $interiorMargin;
position: absolute;
@include verticalCenterBlock($menuLineHPx, $d);
@include verticalCenterBlock($menuLineHPx, $treeTypeIconHPx);
line-height: 100%;
right: auto; width: $d;
right: auto; width: $treeTypeIconH;
.icon {
&.l-icon-link,
@ -100,7 +108,8 @@ ul.tree {
}
}
}
.title-label {
.title-label,
.t-title-label {
@include absPosDefault();
display: block;
left: $runningItemW + ($interiorMargin * 3);
@ -116,7 +125,7 @@ ul.tree {
.view-control {
color: $colorItemTreeSelectedVC;
}
.label .type-icon {
.t-object-label .t-item-icon {
color: $colorItemTreeSelectedFg; //$colorItemTreeIconHover;
}
}
@ -125,9 +134,9 @@ ul.tree {
// NOTE: [Mobile] Removed Hover on Mobile
@include desktop {
&:hover {
background: rgba($colorBodyFg, 0.1); //lighten($colorBodyBg, 5%);
color: pullForward($colorBodyFg, 20%);
.icon {
background: $colorItemTreeHoverBg;
color: $colorItemTreeHoverFg;
.t-item-icon {
color: $colorItemTreeIconHover;
}
}
@ -152,7 +161,7 @@ ul.tree {
}
.tree-item {
.label {
.t-object-label {
left: $interiorMargin + $treeVCW;
}
}

View File

@ -1,72 +0,0 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
.ue-bottom-bar {
background: $colorFooterBg;
color: lighten($colorBodyBg, 30%);
font-size: .7rem;
//line-height: $ueFooterH - 4px;
//line-height: $ueFooterH; // New status bar design
.status-holder {
//@include border-radius($basicCr * 1.75); // New status bar design
@include box-sizing(border-box);
//background: $colorFooterBg;
//border-bottom: 1px solid lighten($colorBodyBg, 10%); // New status bar design
@include absPosDefault($interiorMargin);
@include ellipsize();
line-height: $ueFooterH - ($interiorMargin * 2);
right: 120px;
text-transform: uppercase;
}
.app-logo {
@include box-sizing(border-box);
@include absPosDefault($interiorMargin);
left: auto;
cursor: pointer;
//font-size: 0.8em;
//line-height: $ueFooterH - 10px;
//padding-top: 1px;
//text-transform: uppercase;
&.logo-openmctweb {
background: url($dirImgs + 'logo-openmctweb.svg') no-repeat center center;
}
}
}
.status.block {
//display: inline-block;
display: inline; // New status bar design. Inline to support ellipsis overflow
margin-right: $interiorMarginLg;
.status-indicator {
//@include border-radius($controlCr * 0.9);
//@include box-shadow(inset rgba(black, 0.5) 0 0 3px);
//@include text-shadow(rgba(black, 0.3) 0 0 2px);
display: inline-block;
margin-right: $interiorMarginSm;
color: $colorKey;
&.ok {
color: #009900;
}
&.caution {
color: #ffaa00;
}
}
}

View File

@ -29,13 +29,13 @@
}
}
.holder-all {
/*.holder-all {
$myM: 0; // $interiorMarginSm;
top: $myM;
right: $myM;
bottom: $myM;
left: $myM;
}
}*/
.browse-area,
.edit-area,
@ -96,12 +96,8 @@
.user-environ {
.browse-area,
.edit-area,
.editor {
top: $bodyMargin + $ueTopBarH + ($interiorMargin);
right: $bodyMargin;
bottom: $ueFooterH + $bodyMargin;
left: $bodyMargin;
top: 0; left: 0; right: 0; bottom: $ueFooterH;
}
.browse-area,
@ -115,31 +111,51 @@
.edit-area {
$tbH: $btnToolbarH + $interiorMargin;
top: $bodyMargin + $ueTopBarEditH + ($interiorMargin);
left: $bodyMargin;
right: $bodyMargin;
bottom: $bodyMargin + $ueFooterH;
.tool-bar {
bottom: auto;
height: $tbH;
line-height: $btnToolbarH;
}
.work-area {
.object-holder.work-area {
top: $tbH + $interiorMargin * 2;
overflow: auto;
}
}
.ue-bottom-bar {
//@include absPosDefault($bodyMargin);
@include absPosDefault(0); // New status bar design
top: auto;
height: $ueFooterH;
.status-holder {
//right: $ueAppLogoW + $bodyMargin; New status bar design
z-index: 1;
}
.app-logo {
left: auto;
width: $ueAppLogoW;
z-index: 2;
}
}
// from _bottom-bar.scss
.ue-bottom-bar {
@include absPosDefault(0);// New status bar design
top: auto;
height: $ueFooterH;
line-height: $ueFooterH - ($interiorMargin * 2);
background: $colorFooterBg;
color: lighten($colorBodyBg, 30%);
font-size: .7rem;
.status-holder {
@include box-sizing(border-box);
@include absPosDefault($interiorMargin);
@include ellipsize();
//line-height: $ueFooterH - ($interiorMargin * 2);
right: 120px;
text-transform: uppercase;
z-index: 1;
}
.app-logo {
@include box-sizing(border-box);
@include absPosDefault($interiorMargin);
cursor: pointer;
left: auto;
width: $ueAppLogoW;
z-index: 2;
&.logo-openmctweb {
background: url($dirImgs + 'logo-openmctweb.svg') no-repeat center center;
}
}
}
}
.cols {
@ -205,10 +221,19 @@
.browse-mode {
.split-layout {
.split-pane-component.pane.left {
min-width: 150px;
max-width: 800px;
width: $ueBrowseLeftPaneW;
.split-pane-component.pane {
//@include test(green);
&.treeview.left {
min-width: 150px;
max-width: 800px;
width: $ueBrowseLeftPaneTreeW;
}
&.t-inspect.right {
min-width: 200px;
max-width: 600px;
//padding-left: $ueCollapsedPaneEdgeM; // Allow room for mini-tab element
width: $ueBrowseRightPaneInspectW;
}
}
}
}
@ -226,16 +251,33 @@
}
.pane {
@include box-sizing(border-box);
position: absolute;
.pane-header {
text-transform: uppercase;
height: $ueTopBarH;
line-height: $ueTopBarH;
margin-bottom: $interiorMargin;
}
.primary-pane {
// Need to lift up this pane to ensure that 'collapsed' panes don't block user interactions
z-index: 2;
}
&.treeview.left {
.create-btn-holder {
bottom: auto;
top: 0;
height: $ueTopBarH;
.wrapper.menu-element {
position: absolute;
bottom: $interiorMargin;
}
//.create-btn-holder {
// //bottom: auto;
// //top: 0;
// height: $ueTopBarH;
// .wrapper.menu-element {
// position: absolute;
// bottom: $interiorMargin;
// }
//}
.holder-create-and-search{
}
.search-holder {
top: $ueTopBarH + $interiorMarginLg;
@ -245,6 +287,54 @@
top: $ueTopBarH + $interiorMarginLg + $treeSearchInputBarH + $interiorMargin;
}
}
.mini-tab-icon.toggle-pane {
//@include test(blue, 0.3);
z-index: 5;
@include desktop {
$d: $uePaneMiniTabH;
$paneExpandedOffset: $splitterD + $uePaneMiniTabW;
top: $bodyMargin;
height: $d;
line-height: $d;
&:after {
// Always the icon that shows when the pane is collapsed
opacity: 0;
}
&.collapsed {
&:before {
opacity: 0;
}
&:after {
opacity: 1;
}
}
&.toggle-tree.anchor-left {
left: 0;
@include transform(translateX(-1 * $paneExpandedOffset));
&:after {
content: '\6d'; // Menu 'hamburger' icon
}
&.collapsed {
left: 0;
@include transform(translateX((-1 * $ueCollapsedPaneEdgeM) + $interiorMargin));
}
&:not(.collapsed):before {
@include trans-prop-nice(opacity, 200ms, 200ms);
}
}
&.toggle-inspect.anchor-right {
right: $bodyMargin;
&:after {
content: '\e615'; // e615: Crosshair icon; was e608: Info "i" icon
}
&.collapsed {
right: $interiorMargin;
}
}
}
}
&.items {
.object-browse-bar {
.left.abs,
@ -266,23 +356,44 @@
}
}
}
&.vertical {
/* &.vertical {
// Slides left and right
> .pane {
// @include test();
margin-left: $interiorMargin;
> .pane.left {
> .holder {
left: 0;
right: 0;
}
&:first-child {
margin-left: 0;
.holder {
right: $interiorMarginSm;
}
left: $bodyMargin;
}
}
> .pane.right {
> .holder {
right: $bodyMargin;
}
}
}*/
// Specific elements margins
.holder.holder-create-and-search {
top: $bodyMargin;
right: 0;
bottom: $bodyMargin;
left: $bodyMargin;
}
.holder.holder-object-and-inspector {
top: 0;
right: 0;
bottom: 0;
left: 0;
.holder-object {
top: $bodyMargin;
bottom: $bodyMargin;
}
.holder-inspector-elements {
top: $bodyMargin;
bottom: $bodyMargin;
left: $bodyMargin;
right: $bodyMargin;
}
}
}
@ -340,4 +451,84 @@
@include webkitProp(flex, '1 1 0');
padding-right: $interiorMarginLg;
}
}
}
// When the tree is hidden, these are the
// classes used for the left menu and the
// right representation.
.pane-tree-hidden {
// Sets the left tree menu when the tree is hidden.
//.pane.left.treeview,
.tree-holder,
.splitter-treeview,
.holder-create-and-search {
opacity: 0;
}
/*.holder-create-and-search {
@include trans-prop-nice((top, left), 250ms);
top: $ueTopBarH + $interiorMargin;
left: -1 * $bodyMargin !important;
.create-btn {
@include border-left-radius(0);
@include trans-prop-nice((width), 250ms);
width: $uePaneMiniTabW !important;
text-align: center !important;
padding: 0;
.title-label,
&:after {
display: none;
}
&:before {
font-size: 9px;
}
}
}*/
}
.pane-tree-showing {
// Sets the left tree menu when the tree is shown.
//.pane.left.treeview,
.tree-holder,
.splitter-treeview {
@include trans-prop-nice(opacity, $dur: 250ms, $delay: 250ms);
opacity: 1;
}
.holder-create-and-search {
@include trans-prop-nice(opacity, $dur: 250ms, $delay: 200ms);
}
}
.pane-inspect-showing {
.l-object-and-inspector {
.l-inspect,
.splitter-inspect {
@include trans-prop-nice(opacity, $dur: 250ms, $delay: 250ms);
opacity: 1;
}
}
}
.pane-inspect-hidden {
.l-object-and-inspector {
.l-inspect,
.splitter-inspect {
opacity: 0;
}
}
}
@include desktop {
.pane.treeview.left .tree-holder {
padding-right: $interiorMargin;
}
.pane-tree-hidden {
.pane.right.primary-pane { left: $ueCollapsedPaneEdgeM !important; }
}
.pane-inspect-hidden .l-object-and-inspector {
.pane.left { right: $ueCollapsedPaneEdgeM !important; }
}
.pane:not(.resizing) {
@include trans-prop-nice-resize-w(250ms);
}
}

View File

@ -26,5 +26,6 @@
key="indicator.template">
</mct-include>
</div>
<mct-include key="'message-banner'"></mct-include>
<mct-include key="'about-logo'"></mct-include>
</div>

View File

@ -0,0 +1,20 @@
<span class="s-btn"
ng-controller="DateTimeFieldController">
<input type="text"
ng-model="textValue"
ng-class="{ error: textInvalid }">
</input>
<a class="ui-symbol icon icon-calendar"
ng-if="structure.format === 'utc' || !structure.format"
ng-click="pickerActive = !pickerActive">
</a>
<mct-popup ng-if="pickerActive">
<div mct-click-elsewhere="pickerActive = false">
<mct-control key="'datetime-picker'"
ng-model="ngModel"
field="field"
options="{ hours: true }">
</mct-control>
</div>
</mct-popup>
</span>

View File

@ -22,47 +22,24 @@
<div ng-controller="TimeRangeController">
<div class="l-time-range-inputs-holder">
<span class="l-time-range-inputs-elem ui-symbol type-icon">&#x43;</span>
<span class="l-time-range-input" ng-controller="ToggleController as t1">
<!--<span class="lbl">Start</span>-->
<span class="s-btn time-range-start">
<input type="text"
ng-model="boundsModel.start"
ng-class="{ error: !boundsModel.startValid }">
</input>
<a class="ui-symbol icon icon-calendar" ng-click="t1.toggle()"></a>
<mct-popup ng-if="t1.isActive()">
<div mct-click-elsewhere="t1.setState(false)">
<mct-control key="'datetime-picker'"
ng-model="ngModel.outer"
field="'start'"
options="{ hours: true }">
</mct-control>
</div>
</mct-popup>
</span>
<span class="l-time-range-input">
<mct-control key="'datetime-field'"
structure="{ format: parameters.format }"
ng-model="ngModel.outer"
field="'start'"
class="time-range-start">
</mct-control>
</span>
<span class="l-time-range-inputs-elem lbl">to</span>
<span class="l-time-range-input" ng-controller="ToggleController as t2">
<!--<span class="lbl">End</span>-->
<span class="s-btn l-time-range-input">
<input type="text"
ng-model="boundsModel.end"
ng-class="{ error: !boundsModel.endValid }">
</input>
<a class="ui-symbol icon icon-calendar" ng-click="t2.toggle()">
</a>
<mct-popup ng-if="t2.isActive()">
<div mct-click-elsewhere="t2.setState(false)">
<mct-control key="'datetime-picker'"
ng-model="ngModel.outer"
field="'end'"
options="{ hours: true }">
</mct-control>
</div>
</mct-popup>
</span>&nbsp;
<mct-control key="'datetime-field'"
structure="{ format: parameters.format }"
ng-model="ngModel.outer"
field="'end'"
class="time-range-end">
</mct-control>&nbsp;
</span>
</div>
@ -97,7 +74,7 @@
<div class="l-time-range-ticks-holder">
<div class="l-time-range-ticks">
<div
ng-repeat="tick in ticks"
ng-repeat="tick in ticks track by $index"
ng-style="{ left: $index * (100 / (ticks.length - 1)) + '%' }"
class="tick tick-x"
>

View File

@ -19,20 +19,21 @@
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
<!--<div ng-init="reps = [1,2,3]"></div>-->
<div class='status block'
title="{{ngModel.getDescription()}}"
ng-click='ngModel.configure()'
ng-class='ngModel.getClass()'
ng-show="ngModel.getText().length > 0">
<span class="ui-symbol status-indicator"
ng-class='ngModel.getGlyphClass()'>
{{ngModel.getGlyph()}}
</span>
<span class="label"
ng-class='ngModel.getTextClass()'>
{{ngModel.getText()}}
</span>
<a href=''
title="{{ngModel.getDescription()}}"
ng-click='ngModel.configure()'
ng-class='ngModel.getGlyphClass()'
ng-show="ngModel.getText().length > 0">
<span class="ui-symbol status-indicator">
{{ngModel.getGlyph()}}
</span><span class="label"
ng-class='ngModel.getTextClass()'>
{{ngModel.getText()}}
</span><span class="count">
<!-- Add int count value here if this type of indicator has one or more messages associated with it -->
</span><a href=''
class="ui-symbol"
ng-if="ngModel.configure">
G

View File

@ -19,16 +19,7 @@
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<span class="label s-label">
<span class='ui-symbol icon type-icon'>
{{type.getGlyph()}}
<span
class='ui-symbol icon l-icon-link'
ng-show="location.isLink()"
></span>
<span class='ui-symbol icon l-icon-alert'></span>
</span>
<span class='title-label'>
{{model.name}}
</span>
<span class="t-object-label">
<span class="t-item-icon" ng-class="{ 'l-icon-link':location.isLink() }">{{type.getGlyph()}}</span>
<span class='t-title-label'>{{model.name}}</span>
</span>

View File

@ -0,0 +1,21 @@
<div ng-controller="BannerController" ng-show="active.notification"
class="l-message-banner s-message-banner {{active.notification.model.severity}}" ng-class="{
'minimized': active.notification.model.minimized,
'new': !active.notification.model.minimized}"
ng-click="maximize(active.notification)">
<span class="banner-elem label">
{{active.notification.model.title}}
</span>
<span ng-show="active.notification.model.progress !== undefined || active.notification.model.unknownProgress">
<mct-include key="'progress-bar'" class="banner-elem"
ng-model="active.notification.model">
</mct-include>
</span>
<a ng-hide="active.notification.model.primaryOption === undefined"
class="banner-elem l-action s-action"
ng-click="action(active.notification.model.primaryOption.callback, $event)">
{{active.notification.model.primaryOption.label}}
</a>
<a class="banner-elem ui-symbol close" ng-click="dismiss(active.notification, $event)">
&#x78;</a>
</div>

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.
-->
<span class="l-inspect" ng-controller="ObjectInspectorController as controller">
<div class="abs holder holder-inspector-elements">
<div class="pane-header">Inspection</div>
<ul>
<li>
<em>Properties</em>
<div class="inspector-properties"
ng-repeat="data in metadata"
ng-class="{ first:$index === 0 }">
<div class="label">{{ data.name }}</div>
<div class="value">{{ data.value }}</div>
</div>
</li>
<li ng-if="contextutalParents.length > 0">
<em title="The location of this linked object.">Location</em>
<span class="inspector-location"
ng-repeat="parent in contextutalParents"
ng-class="{ last:($index + 1) === contextualParents.length }">
<mct-representation key="'label'"
mct-object="parent"
ng-model="ngModel"
ng-click="ngModel.selectedObject = parent"
class="location-item">
</mct-representation>
</span>
</li>
<li ng-if="primaryParents.length > 0">
<em title="The location of the original object that this was linked from.">Original Location</em>
<span class="inspector-location"
ng-repeat="parent in primaryParents"
ng-class="{ last:($index + 1) === primaryParents.length }">
<mct-representation key="'label'"
mct-object="parent"
ng-model="ngModel"
ng-click="ngModel.selectedObject = parent"
class="location-item">
</mct-representation>
</span>
</li>
</ul>
</div>
</span>

View File

@ -0,0 +1,10 @@
<span class="l-progress-bar s-progress-bar"
ng-class="{ indeterminate:ngModel.unknownProgress }">
<span class="progress-amt-holder">
<span class="progress-amt" style="width: {{ngModel.progress}}%"></span>
</span>
</span>
<div class="progress-info hint" ng-hide="ngModel.progressText === undefined">
<span class="progress-amt-text" ng-show="ngModel.progress > 0">{{ngModel.progress}}% complete. </span>
{{ngModel.progressText}}
</div>

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*/
define(
[],
function () {
"use strict";
/**
* A controller for banner notifications. Banner notifications are a
* non-blocking way of drawing the user's attention to an event such
* as system errors, or the progress or successful completion of an
* ongoing task. This controller provides scoped functions for
* dismissing and 'maximizing' notifications. See {@link NotificationService}
* for more details on Notifications.
*
* @param $scope
* @param notificationService
* @param dialogService
* @constructor
*/
function BannerController($scope, notificationService, dialogService) {
$scope.active = notificationService.active;
$scope.action = function (action, $event){
/*
Prevents default 'maximize' behaviour when clicking on
notification button
*/
$event.stopPropagation();
return action();
};
$scope.dismiss = function(notification, $event) {
$event.stopPropagation();
notification.dismissOrMinimize();
};
$scope.maximize = function(notification) {
if (notification.model.severity !== "info"){
notification.model.cancel = function(){
dialogService.dismiss();
};
dialogService.showBlockingMessage(notification.model);
}
};
}
return BannerController;
});

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,Promise*/
define(
[],
function () {
'use strict';
/**
* Controller to support the date-time entry field.
*
* Accepts a `format` property in the `structure` attribute
* which allows a date/time to be specified via its symbolic
* key (as will be used to look up said format from the
* `formatService`.)
*
* {@see FormatService}
* @constructor
* @memberof platform/commonUI/general
* @param $scope the Angular scope for this controller
* @param {FormatService} formatService the service to user to format
* domain values
* @param {string} defaultFormat the format to request when no
* format has been otherwise specified
*/
function DateTimeFieldController($scope, formatService, defaultFormat) {
var formatter = formatService.getFormat(defaultFormat);
function updateFromModel(value) {
// Only reformat if the value is different from user
// input (to avoid reformatting valid input while typing.)
if (!formatter.validate($scope.textValue) ||
formatter.parse($scope.textValue) !== value) {
$scope.textValue = formatter.format(value);
$scope.textInvalid = false;
}
}
function updateFromView(textValue) {
$scope.textInvalid = !formatter.validate(textValue);
if (!$scope.textInvalid) {
$scope.ngModel[$scope.field] =
formatter.parse(textValue);
}
}
function setFormat(format) {
formatter = formatService.getFormat(format || defaultFormat);
updateFromModel($scope.ngModel[$scope.field]);
}
$scope.$watch('structure.format', setFormat);
$scope.$watch('ngModel[field]', updateFromModel);
$scope.$watch('textValue', updateFromView);
}
return DateTimeFieldController;
}
);

View File

@ -0,0 +1,117 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,Promise*/
/**
* Module defining ObjectInspectorController. Created by shale on 08/21/2015.
*/
define(
[],
function () {
"use strict";
/**
* The ObjectInspectorController gets and formats the data for
* the inspector display
*
* @constructor
*/
function ObjectInspectorController($scope, objectService) {
$scope.primaryParents = [];
$scope.contextutalParents = [];
//$scope.isLink = false;
// Gets an array of the contextual parents/anscestors of the selected object
function getContextualPath() {
var currentObj = $scope.ngModel.selectedObject,
currentParent,
parents = [];
currentParent = currentObj &&
currentObj.hasCapability('context') &&
currentObj.getCapability('context').getParent();
while (currentParent && currentParent.getModel().type !== 'root' &&
currentParent.hasCapability('context')) {
// Record this object
parents.unshift(currentParent);
// Get the next one up the tree
currentObj = currentParent;
currentParent = currentObj.getCapability('context').getParent();
}
$scope.contextutalParents = parents;
}
// Gets an array of the parents/anscestors of the selected object's
// primary location (locational of original non-link)
function getPrimaryPath(current) {
var location;
// If this the the initial call of this recursive function
if (!current) {
current = $scope.ngModel.selectedObject;
$scope.primaryParents = [];
}
location = current.getModel().location;
if (location && location !== 'root') {
objectService.getObjects([location]).then(function (obj) {
var next = obj[location];
$scope.primaryParents.unshift(next);
getPrimaryPath(next);
});
}
}
// Gets the metadata for the selected object
function getMetadata() {
$scope.metadata = $scope.ngModel.selectedObject &&
$scope.ngModel.selectedObject.hasCapability('metadata') &&
$scope.ngModel.selectedObject.useCapability('metadata');
}
// Set scope variables when the selected object changes
$scope.$watch('ngModel.selectedObject', function () {
$scope.isLink = $scope.ngModel.selectedObject &&
$scope.ngModel.selectedObject.hasCapability('location') &&
$scope.ngModel.selectedObject.getCapability('location').isLink();
if ($scope.isLink) {
getPrimaryPath();
getContextualPath();
} else {
$scope.primaryParents = [];
getContextualPath();
}
getMetadata();
});
}
return ObjectInspectorController;
}
);

View File

@ -26,33 +26,32 @@ define(
function (moment) {
"use strict";
var DATE_FORMAT = "YYYY-MM-DD HH:mm:ss",
TICK_SPACING_PX = 150;
var TICK_SPACING_PX = 150;
/**
* Controller used by the `time-controller` template.
* @memberof platform/commonUI/general
* @constructor
* @param $scope the Angular scope for this controller
* @param {FormatService} formatService the service to user to format
* domain values
* @param {string} defaultFormat the format to request when no
* format has been otherwise specified
* @param {Function} now a function to return current system time
*/
function TimeConductorController($scope, now) {
function TimeRangeController($scope, formatService, defaultFormat, now) {
var tickCount = 2,
innerMinimumSpan = 1000, // 1 second
outerMinimumSpan = 1000 * 60 * 60, // 1 hour
initialDragValue;
initialDragValue,
formatter = formatService.getFormat(defaultFormat);
function formatTimestamp(ts) {
return moment.utc(ts).format(DATE_FORMAT);
return formatter.format(ts);
}
function parseTimestamp(text) {
var m = moment.utc(text, DATE_FORMAT);
if (m.isValid()) {
return m.valueOf();
} else {
throw new Error("Could not parse " + text);
}
}
// From 0.0-1.0 to "0%"-"1%"
// From 0.0-1.0 to "0%"-"100%"
function toPercent(p) {
return (100 * p) + "%";
}
@ -101,41 +100,15 @@ define(
return { start: bounds.start, end: bounds.end };
}
function updateBoundsTextForProperty(ngModel, property) {
try {
if (!$scope.boundsModel[property] ||
parseTimestamp($scope.boundsModel[property]) !==
ngModel.outer[property]) {
$scope.boundsModel[property] =
formatTimestamp(ngModel.outer[property]);
}
} catch (e) {
// User-entered text is invalid, so leave it be
// until they fix it.
}
}
function updateBoundsText(ngModel) {
updateBoundsTextForProperty(ngModel, 'start');
updateBoundsTextForProperty(ngModel, 'end');
}
function updateViewFromModel(ngModel) {
var t = now();
ngModel = ngModel || {};
ngModel.outer = ngModel.outer || defaultBounds();
ngModel.inner = ngModel.inner || copyBounds(ngModel.outer);
// First, dates for the date pickers for outer bounds
updateBoundsText(ngModel);
// Then various updates for the inner span
updateViewForInnerSpanFromModel(ngModel);
// Stick it back is scope (in case we just set defaults)
$scope.ngModel = ngModel;
updateViewForInnerSpanFromModel(ngModel);
updateTicks();
}
@ -155,7 +128,8 @@ define(
}
function toMillis(pixels) {
var span = $scope.ngModel.outer.end - $scope.ngModel.outer.start;
var span =
$scope.ngModel.outer.end - $scope.ngModel.outer.start;
return (pixels / $scope.spanWidth) * span;
}
@ -243,36 +217,10 @@ define(
updateTicks();
}
function updateStartFromText(value) {
try {
updateOuterStart(parseTimestamp(value));
updateBoundsTextForProperty($scope.ngModel, 'end');
$scope.boundsModel.startValid = true;
} catch (e) {
$scope.boundsModel.startValid = false;
return;
}
}
function updateEndFromText(value) {
try {
updateOuterEnd(parseTimestamp(value));
updateBoundsTextForProperty($scope.ngModel, 'start');
$scope.boundsModel.endValid = true;
} catch (e) {
$scope.boundsModel.endValid = false;
return;
}
}
function updateStartFromPicker(value) {
updateOuterStart(value);
updateBoundsText($scope.ngModel);
}
function updateEndFromPicker(value) {
updateOuterEnd(value);
updateBoundsText($scope.ngModel);
function updateFormat(key) {
formatter = formatService.getFormat(key || defaultFormat);
updateViewForInnerSpanFromModel($scope.ngModel);
updateTicks();
}
$scope.startLeftDrag = startLeftDrag;
@ -282,21 +230,18 @@ define(
$scope.rightDrag = rightDrag;
$scope.middleDrag = middleDrag;
$scope.state = false;
$scope.ticks = [];
$scope.boundsModel = {};
// Initialize scope to defaults
updateViewFromModel($scope.ngModel);
$scope.$watchCollection("ngModel", updateViewFromModel);
$scope.$watch("spanWidth", updateSpanWidth);
$scope.$watch("ngModel.outer.start", updateStartFromPicker);
$scope.$watch("ngModel.outer.end", updateEndFromPicker);
$scope.$watch("boundsModel.start", updateStartFromText);
$scope.$watch("boundsModel.end", updateEndFromText);
$scope.$watch("ngModel.outer.start", updateOuterStart);
$scope.$watch("ngModel.outer.end", updateOuterEnd);
$scope.$watch("parameters.format", updateFormat);
}
return TimeConductorController;
return TimeRangeController;
}
);

View File

@ -132,10 +132,10 @@ define(
// Get actual size (to obey min-width etc.)
firstSize = getSize(first[0]);
first.css(anchor.dimension, firstSize + 'px');
splitter.css(anchor.edge, (firstSize + splitterSize) + 'px');
splitter.css(anchor.edge, firstSize + 'px');
splitter.css(anchor.opposite, "auto");
last.css(anchor.edge, (firstSize + splitterSize * 3) + 'px');
last.css(anchor.edge, (firstSize + splitterSize) + 'px');
last.css(anchor.opposite, "0px");
position = firstSize + splitterSize;
@ -178,6 +178,12 @@ define(
return position;
}
// Dynamically apply a CSS class to elements when the user
// is actively resizing
function toggleClass(classToToggle) {
$element.children().toggleClass(classToToggle);
}
// Make sure anchor parameter is something we know
if (!ANCHORS[anchorKey]) {
$log.warn(ANCHOR_WARNING_MESSAGE);
@ -208,6 +214,7 @@ define(
// Interface exposed by controller, for mct-splitter to user
return {
position: getSetPosition,
toggleClass: toggleClass,
anchor: function () {
return anchor;
}

View File

@ -29,7 +29,8 @@ define(
// Pixel width to allocate for the splitter itself
var SPLITTER_TEMPLATE = "<div class='abs'" +
"mct-drag-down=\"splitter.startMove()\" " +
"mct-drag=\"splitter.move(delta)\"></div>",
"mct-drag=\"splitter.move(delta)\" " +
"mct-drag-up=\"splitter.endMove()\"></div>",
OFFSETS_BY_EDGE = {
left: "offsetLeft",
right: "offsetRight",
@ -53,6 +54,7 @@ define(
startMove: function () {
var splitter = element[0];
initialPosition = mctSplitPane.position();
mctSplitPane.toggleClass('resizing');
},
// Handle user changes to splitter position
move: function (delta) {
@ -63,6 +65,11 @@ define(
// Update the position of this splitter
mctSplitPane.position(initialPosition + pixelDelta);
},
// Grab the event when the user is done moving
// the splitter and pass it on
endMove: function() {
mctSplitPane.toggleClass('resizing');
}
};
}

View File

@ -0,0 +1,183 @@
/*****************************************************************************
* 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/controllers/DateTimeFieldController", "moment"],
function (DateTimeFieldController, moment) {
'use strict';
var TEST_FORMAT = "YYYY-MM-DD HH:mm:ss";
describe("The DateTimeFieldController", function () {
var mockScope,
mockFormatService,
mockFormat,
controller;
function fireWatch(expr, value) {
mockScope.$watch.calls.forEach(function (call) {
if (call.args[0] === expr) {
call.args[1](value);
}
});
}
beforeEach(function () {
mockScope = jasmine.createSpyObj('$scope', ['$watch']);
mockFormatService =
jasmine.createSpyObj('formatService', ['getFormat']);
mockFormat = jasmine.createSpyObj('format', [
'parse',
'validate',
'format'
]);
mockFormatService.getFormat.andReturn(mockFormat);
mockFormat.validate.andCallFake(function (text) {
return moment.utc(text, TEST_FORMAT).isValid();
});
mockFormat.parse.andCallFake(function (text) {
return moment.utc(text, TEST_FORMAT).valueOf();
});
mockFormat.format.andCallFake(function (value) {
return moment.utc(value).format(TEST_FORMAT);
});
mockScope.ngModel = { testField: 12321 };
mockScope.field = "testField";
mockScope.structure = { format: "someFormat" };
controller = new DateTimeFieldController(
mockScope,
mockFormatService
);
});
it("updates models from user-entered text", function () {
var newText = "1977-05-25 17:30:00";
mockScope.textValue = newText;
fireWatch("textValue", newText);
expect(mockScope.ngModel.testField)
.toEqual(mockFormat.parse(newText));
expect(mockScope.textInvalid).toBeFalsy();
});
it("updates text from model values", function () {
var testTime = mockFormat.parse("1977-05-25 17:30:00");
mockScope.ngModel.testField = testTime;
fireWatch("ngModel[field]", testTime);
expect(mockScope.textValue).toEqual("1977-05-25 17:30:00");
});
describe("when user input is invalid", function () {
var newText, oldValue;
beforeEach(function () {
newText = "Not a date";
oldValue = mockScope.ngModel.testField;
mockScope.textValue = newText;
fireWatch("textValue", newText);
});
it("displays error state", function () {
expect(mockScope.textInvalid).toBeTruthy();
});
it("does not modify model state", function () {
expect(mockScope.ngModel.testField).toEqual(oldValue);
});
it("does not modify user input", function () {
expect(mockScope.textValue).toEqual(newText);
});
});
it("does not modify valid but irregular user input", function () {
// Don't want the controller "fixing" bad or
// irregularly-formatted input out from under
// the user's fingertips.
var newText = "2015-3-3 01:02:04",
oldValue = mockScope.ngModel.testField;
mockFormat.validate.andReturn(true);
mockFormat.parse.andReturn(42);
mockScope.textValue = newText;
fireWatch("textValue", newText);
expect(mockScope.textValue).toEqual(newText);
expect(mockScope.ngModel.testField).toEqual(42);
expect(mockScope.ngModel.testField).not.toEqual(oldValue);
});
it("obtains a format from the format service", function () {
fireWatch('structure.format', mockScope.structure.format);
expect(mockFormatService.getFormat)
.toHaveBeenCalledWith(mockScope.structure.format);
});
it("throws an error for unknown formats", function () {
mockFormatService.getFormat.andReturn(undefined);
expect(function () {
fireWatch("structure.format", "some-format");
}).toThrow();
});
describe("using the obtained format", function () {
var testValue = 1234321,
testText = "some text";
beforeEach(function () {
mockFormat.validate.andReturn(true);
mockFormat.parse.andReturn(testValue);
mockFormat.format.andReturn(testText);
});
it("parses user input", function () {
var newText = "some other new text";
mockScope.textValue = newText;
fireWatch("textValue", newText);
expect(mockFormat.parse).toHaveBeenCalledWith(newText);
expect(mockScope.ngModel.testField).toEqual(testValue);
});
it("validates user input", function () {
var newText = "some other new text";
mockScope.textValue = newText;
fireWatch("textValue", newText);
expect(mockFormat.validate).toHaveBeenCalledWith(newText);
});
it("formats model data for display", function () {
var newValue = 42;
mockScope.ngModel.testField = newValue;
fireWatch("ngModel[field]", newValue);
expect(mockFormat.format).toHaveBeenCalledWith(newValue);
expect(mockScope.textValue).toEqual(testText);
});
});
});
}
);

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.
*****************************************************************************/
/*global define,Promise,describe,it,expect,beforeEach,waitsFor,jasmine*/
/**
* Created by shale on 08/24/2015.
*/
define(
["../../src/controllers/ObjectInspectorController"],
function (ObjectInspectorController) {
"use strict";
describe("The object inspector controller ", function () {
var mockScope,
mockObjectService,
mockPromise,
mockDomainObject,
mockContextCapability,
mockLocationCapability,
controller;
beforeEach(function () {
mockScope = jasmine.createSpyObj(
"$scope",
[ "$watch" ]
);
mockScope.ngModel = {};
mockScope.ngModel.selectedObject = 'mock selected object';
mockObjectService = jasmine.createSpyObj(
"objectService",
[ "getObjects" ]
);
mockPromise = jasmine.createSpyObj(
"promise",
[ "then" ]
);
mockObjectService.getObjects.andReturn(mockPromise);
mockDomainObject = jasmine.createSpyObj(
"selectedObject",
[ "hasCapability", "getCapability", "useCapability", "getModel" ]
);
mockDomainObject.getModel.andReturn({location: 'somewhere'});
mockDomainObject.hasCapability.andReturn(true);
mockContextCapability = jasmine.createSpyObj(
"context capability",
[ "getParent" ]
);
mockLocationCapability = jasmine.createSpyObj(
"location capability",
[ "isLink" ]
);
mockDomainObject.getCapability.andCallFake(function (param) {
if (param === 'location') {
return mockLocationCapability;
} else if (param === 'context') {
return mockContextCapability;
}
});
controller = new ObjectInspectorController(mockScope, mockObjectService);
// Change the selected object to trigger the watch call
mockScope.ngModel.selectedObject = mockDomainObject;
});
it("watches for changes to the selected object", function () {
expect(mockScope.$watch).toHaveBeenCalledWith('ngModel.selectedObject', jasmine.any(Function));
});
it("looks for contextual parent objects", function () {
mockScope.$watch.mostRecentCall.args[1]();
expect(mockContextCapability.getParent).toHaveBeenCalled();
});
it("if link, looks for primary parent objects", function () {
mockLocationCapability.isLink.andReturn(true);
mockScope.$watch.mostRecentCall.args[1]();
expect(mockDomainObject.getModel).toHaveBeenCalled();
expect(mockObjectService.getObjects).toHaveBeenCalled();
mockPromise.then.mostRecentCall.args[0]({'somewhere': mockDomainObject});
});
it("gets metadata", function () {
mockScope.$watch.mostRecentCall.args[1]();
expect(mockDomainObject.useCapability).toHaveBeenCalledWith('metadata');
});
});
}
);

View File

@ -33,7 +33,10 @@ define(
describe("The TimeRangeController", function () {
var mockScope,
mockFormatService,
testDefaultFormat,
mockNow,
mockFormat,
controller;
function fireWatch(expr, value) {
@ -57,8 +60,30 @@ define(
"$scope",
[ "$apply", "$watch", "$watchCollection" ]
);
mockFormatService = jasmine.createSpyObj(
"formatService",
[ "getFormat" ]
);
testDefaultFormat = 'utc';
mockFormat = jasmine.createSpyObj(
"format",
[ "validate", "format", "parse" ]
);
mockFormatService.getFormat.andReturn(mockFormat);
mockFormat.format.andCallFake(function (value) {
return moment.utc(value).format("YYYY-MM-DD HH:mm:ss");
});
mockNow = jasmine.createSpy('now');
controller = new TimeRangeController(mockScope, mockNow);
controller = new TimeRangeController(
mockScope,
mockFormatService,
testDefaultFormat,
mockNow
);
});
it("watches the model that was passed in", function () {
@ -167,70 +192,22 @@ define(
.toBeGreaterThan(mockScope.ngModel.inner.start);
});
describe("by typing", function () {
it("updates models", function () {
var newStart = "1977-05-25 17:30:00",
newEnd = "2015-12-18 03:30:00";
mockScope.boundsModel.start = newStart;
fireWatch("boundsModel.start", newStart);
expect(mockScope.ngModel.outer.start)
.toEqual(moment.utc(newStart).valueOf());
expect(mockScope.boundsModel.startValid)
.toBeTruthy();
mockScope.boundsModel.end = newEnd;
fireWatch("boundsModel.end", newEnd);
expect(mockScope.ngModel.outer.end)
.toEqual(moment.utc(newEnd).valueOf());
expect(mockScope.boundsModel.endValid)
.toBeTruthy();
});
it("displays error state", function () {
var newStart = "Not a date",
newEnd = "Definitely not a date",
oldStart = mockScope.ngModel.outer.start,
oldEnd = mockScope.ngModel.outer.end;
mockScope.boundsModel.start = newStart;
fireWatch("boundsModel.start", newStart);
expect(mockScope.ngModel.outer.start)
.toEqual(oldStart);
expect(mockScope.boundsModel.startValid)
.toBeFalsy();
mockScope.boundsModel.end = newEnd;
fireWatch("boundsModel.end", newEnd);
expect(mockScope.ngModel.outer.end)
.toEqual(oldEnd);
expect(mockScope.boundsModel.endValid)
.toBeFalsy();
});
it("does not modify user input", function () {
// Don't want the controller "fixing" bad or
// irregularly-formatted input out from under
// the user's fingertips.
var newStart = "Not a date",
newEnd = "2015-3-3 01:02:04",
oldStart = mockScope.ngModel.outer.start,
oldEnd = mockScope.ngModel.outer.end;
mockScope.boundsModel.start = newStart;
fireWatch("boundsModel.start", newStart);
expect(mockScope.boundsModel.start)
.toEqual(newStart);
mockScope.boundsModel.end = newEnd;
fireWatch("boundsModel.end", newEnd);
expect(mockScope.boundsModel.end)
.toEqual(newEnd);
});
});
});
it("watches for changes in format selection", function () {
expect(mockFormatService.getFormat)
.not.toHaveBeenCalledWith('test-format');
fireWatch("parameters.format", 'test-format');
expect(mockFormatService.getFormat)
.toHaveBeenCalledWith('test-format');
});
it("throws an error for unknown formats", function () {
mockFormatService.getFormat.andReturn(undefined);
expect(function () {
fireWatch("parameters.format", "some-format");
}).toThrow();
});
});
}

View File

@ -3,8 +3,10 @@
"controllers/BottomBarController",
"controllers/ClickAwayController",
"controllers/ContextMenuController",
"controllers/DateTimeFieldController",
"controllers/DateTimePickerController",
"controllers/GetterSetterController",
"controllers/ObjectInspectorController",
"controllers/SelectorController",
"controllers/SplitPaneController",
"controllers/TimeRangeController",

View File

@ -0,0 +1,45 @@
{
"extensions": {
"constants": [
{
"key": "DEFAULT_AUTO_DISMISS",
"value": 3000
},
{
"key": "FORCE_AUTO_DISMISS",
"value": 1000
},
{
"key": "MINIMIZE_TIMEOUT",
"value": 300
}
],
"templates": [
{
"key":"notificationIndicatorTemplate",
"templateUrl": "notification-indicator.html"
}
],
"controllers": [
{
"key": "NotificationIndicatorController",
"implementation": "NotificationIndicatorController.js",
"depends": ["$scope", "notificationService", "dialogService"]
}
],
"indicators": [
{
"implementation": "NotificationIndicator.js",
"priority": "fallback"
}
],
"services": [
{
"key": "notificationService",
"implementation": "NotificationService.js",
"depends": [ "$timeout", "DEFAULT_AUTO_DISMISS",
"MINIMIZE_TIMEOUT" ]
}
]
}
}

View File

@ -0,0 +1,10 @@
<span ng-show="notifications.length > 0" class="status block"
ng-class="highest.severity"
ng-controller="NotificationIndicatorController">
<span class="ui-symbol status-indicator">&#xe610;</span>
<span class="label">
<a ng-click="showNotificationsList()">{{notifications.length}}
Notifications</a>
</span>
<span class="count">{{notifications.length}}</span>
</span>

View File

@ -19,17 +19,17 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/* Classes to be used for lists of properties and values */
/*global define,window*/
.properties {
.s-row {
border-top: 1px solid $colorInteriorBorder;
font-size: 0.8em;
&:first-child {
border: none;
}
.s-value {
color: #fff;
}
define(
[],
function () {
"use strict";
function NotificationIndicator() {}
NotificationIndicator.template = 'notificationIndicatorTemplate';
return NotificationIndicator;
}
}
);

View File

@ -0,0 +1,67 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define(
[],
function () {
"use strict";
/**
* Provides an indicator that is visible when there are
* banner notifications that have been minimized. Will also indicate
* the number of notifications. Notifications can be viewed by
* clicking on the indicator to launch a dialog showing a list of
* notifications.
* @param $scope
* @param notificationService
* @param dialogService
* @constructor
*/
function NotificationIndicatorController($scope, notificationService, dialogService) {
$scope.notifications = notificationService.notifications;
$scope.highest = notificationService.highest;
/**
* Launch a dialog showing a list of current notifications.
*/
$scope.showNotificationsList = function(){
dialogService.getDialogResponse('overlay-message-list', {
dialog: {
title: "Messages",
//Launch the message list dialog with the models
// from the notifications
messages: notificationService.notifications && notificationService.notifications.map(function(notification){
return notification.model;
})
},
cancel: function(){
dialogService.dismiss();
}
});
};
}
return NotificationIndicatorController;
}
);

View File

@ -0,0 +1,387 @@
/*****************************************************************************
* 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*/
/**
* This bundle implements the notification service, which can be used to
* show banner notifications to the user. Banner notifications
* are used to inform users of events in a non-intrusive way. As
* much as possible, notifications share a model with blocking
* dialogs so that the same information can be provided in a dialog
* and then minimized to a banner notification if needed.
*
* @namespace platform/commonUI/notification
*/
define(
[],
function () {
"use strict";
/**
* A representation of a user action. Options are provided to
* dialogs and notifications and are shown as buttons.
*
* @typedef {object} NotificationOption
* @property {string} label the label to appear on the button for
* this action
* @property {function} callback a callback function to be invoked
* when the button is clicked
*/
/**
* A representation of a banner notification. Banner notifications
* are used to inform users of events in a non-intrusive way. As
* much as possible, notifications share a model with blocking
* dialogs so that the same information can be provided in a dialog
* and then minimized to a banner notification if needed, or vice-versa.
*
* @typedef {object} NotificationModel
* @property {string} title The title of the message
* @property {string} severity The importance of the message (one of
* 'info', 'alert', or 'error' where info < alert <error)
* @property {number} progress The completion status of a task
* represented numerically
* @property {boolean} unknownProgress a boolean indicating that the
* progress of the underlying task is unknown. This will result in a
* visually distinct progress bar.
* @property {boolean | number} autoDismiss If truthy, dialog will
* be automatically minimized or dismissed (depending on severity).
* Additionally, if the provided value is a number, it will be used
* as the delay period before being dismissed.
* @property {NotificationOption} primaryOption the default user
* response to
* this message. Will be represented as a button with the provided
* label and action. May be used by banner notifications to display
* only the most important option to users.
* @property {NotificationOption[]} options any additional
* actions the user can take. Will be represented as additional buttons
* that may or may not be available from a banner.
* @see DialogModel
*/
/**
* A wrapper object that is returned as a handle to a newly created
* notification. Wraps the notifications model and decorates with
* functions to dismiss or minimize the notification.
*
* @typedef {object} Notification
* @property {function} dismiss This method is added to the object
* returned by {@link NotificationService#notify} and can be used to
* dismiss this notification. Dismissing a notification will remove
* it completely and it will not appear in the notification indicator
* @property {function} minimize This method is added to the object
* returned by {@link NotificationService#notify} and can be used to
* minimize this notification. Minimizing a notification will send
* it to the notification indicator
* @property {function} dismissOrMinimize This method is added to the
* object returned by {@link NotificationService#notify}. It will
* hide the notification by either dismissing or minimizing it,
* depending on severity. Typically this is the method that should
* be used for dismissing a notification. If more control is
* required, then the minimize or dismiss functions can be called
* individually.
*/
/**
* The notification service is responsible for informing the user of
* events via the use of banner notifications.
* @memberof platform/commonUI/notification
* @constructor
* @param $timeout the Angular $timeout service
* @param DEFAULT_AUTO_DISMISS The period of time that an
* auto-dismissed message will be displayed for.
* @param MINIMIZE_TIMEOUT When notifications are minimized, a brief
* animation is shown. This animation requires some time to execute,
* so a timeout is required before the notification is hidden
*/
function NotificationService($timeout, DEFAULT_AUTO_DISMISS, MINIMIZE_TIMEOUT) {
this.notifications = [];
this.$timeout = $timeout;
this.highest ={ severity: "info" };
this.DEFAULT_AUTO_DISMISS = DEFAULT_AUTO_DISMISS;
this.MINIMIZE_TIMEOUT = MINIMIZE_TIMEOUT;
/*
* A context in which to hold the active notification and a
* handle to its timeout.
*/
this.active = {};
}
/*
* Minimize a notification. The notification will still be available
* from the notification list. Typically notifications with a
* severity of 'info' should not be minimized, but rather
* dismissed. If you're not sure which is appropriate,
* use {@link Notification#dismissOrMinimize}
*/
function minimize (service, notification) {
//Check this is a known notification
var index = service.notifications.indexOf(notification);
if (service.active.timeout){
/*
Method can be called manually (clicking dismiss) or
automatically from an auto-timeout. this.active.timeout
acts as a semaphore to prevent race conditions. Cancel any
timeout in progress (for the case where a manual dismiss
has shortcut an active auto-dismiss), and clear the
semaphore.
*/
service.$timeout.cancel(service.active.timeout);
delete service.active.timeout;
}
if (index >= 0) {
notification.model.minimized=true;
//Add a brief timeout before showing the next notification
// in order to allow the minimize animation to run through.
service.$timeout(function() {
service.setActiveNotification(service.selectNextNotification());
}, service.MINIMIZE_TIMEOUT);
}
}
/*
* Completely removes a notification. This will dismiss it from the
* message banner and remove it from the list of notifications.
* Typically only notifications with a severity of info should be
* dismissed. If you're not sure whether to dismiss or minimize a
* notification, use {@link Notification#dismissOrMinimize}.
* dismiss
*/
function dismiss (service, notification) {
//Check this is a known notification
var index = service.notifications.indexOf(notification);
if (service.active.timeout){
/* Method can be called manually (clicking dismiss) or
* automatically from an auto-timeout. this.active.timeout
* acts as a semaphore to prevent race conditions. Cancel any
* timeout in progress (for the case where a manual dismiss
* has shortcut an active auto-dismiss), and clear the
* semaphore.
*/
service.$timeout.cancel(service.active.timeout);
delete service.active.timeout;
}
if (index >= 0) {
service.notifications.splice(index, 1);
}
service.setActiveNotification(service.selectNextNotification());
}
/*
* Depending on the severity of the notification will selectively
* dismiss or minimize where appropriate.
*/
function dismissOrMinimize (notification){
//For now minimize everything, and have discussion around which
//kind of messages should or should not be in the minimized
//notifications list
notification.minimize();
}
/**
* Returns the notification that is currently visible in the banner area
* @returns {Notification}
*/
NotificationService.prototype.getActiveNotification = function (){
return this.active.notification;
};
/**
* A convenience method for info notifications. Notifications
* created via this method will be auto-dismissed after a default
* wait period
* @param {NotificationModel | string} message either a string for
* the title of the notification message, or a {@link NotificationModel}
* defining the options notification to display
* @returns {Notification} the provided notification decorated with
* functions to dismiss or minimize
*/
NotificationService.prototype.info = function (message) {
var notificationModel = typeof message === "string" ? {title: message} : message;
notificationModel.autoDismiss = notificationModel.autoDismiss || true;
notificationModel.severity = "info";
return this.notify(notificationModel);
};
/**
* A convenience method for alert notifications. Notifications
* created via this method will will have severity of "alert" enforced
* @param {NotificationModel | string} message either a string for
* the title of the alert message with default options, or a
* {@link NotificationModel} defining the options notification to
* display
* @returns {Notification} the provided notification decorated with
* functions to dismiss or minimize
*/
NotificationService.prototype.alert = function (message) {
var notificationModel = typeof message === "string" ? {title: message} : message;
notificationModel.severity = "alert";
return this.notify(notificationModel);
};
/**
* A convenience method for error notifications. Notifications
* created via this method will will have severity of "error" enforced
* @param {NotificationModel | string} message either a string for
* the title of the error message with default options, or a
* {@link NotificationModel} defining the options notification to
* display
* @returns {Notification} the provided notification decorated with
* functions to dismiss or minimize
*/
NotificationService.prototype.error = function (message) {
var notificationModel = typeof message === "string" ? {title: message} : message;
notificationModel.severity = "error";
return this.notify(notificationModel);
};
/**
* Notifies the user of an event. If there is a banner notification
* already active, then it will be dismissed or minimized automatically,
* and the provided notification displayed in its place.
*
* @param {NotificationModel} notificationModel The notification to
* display
* @returns {Notification} the provided notification decorated with
* functions to {@link Notification#dismiss} or {@link Notification#minimize}
*/
NotificationService.prototype.notify = function (notificationModel) {
var self = this,
notification,
ordinality = {
"info": 1,
"alert": 2,
"error": 3
},
activeNotification = self.active.notification;
notification = {
model: notificationModel,
minimize: function() {
minimize(self, notification);
},
dismiss: function(){
dismiss(self, notification);
},
dismissOrMinimize: function(){
dismissOrMinimize(notification);
}
};
notificationModel.severity = notificationModel.severity || "info";
if (notificationModel.autoDismiss === true){
notificationModel.autoDismiss = this.DEFAULT_AUTO_DISMISS;
}
if (ordinality[notificationModel.severity.toLowerCase()] > ordinality[this.highest.severity.toLowerCase()]){
this.highest.severity = notificationModel.severity;
}
this.notifications.push(notification);
/*
Check if there is already an active (ie. visible) notification
*/
if (!this.active.notification){
this.setActiveNotification(notification);
} else if (!this.active.timeout){
/*
If there is already an active notification, time it out. If it's
already got a timeout in progress (either because it has had
timeout forced because of a queue of messages, or it had an
autodismiss specified), leave it to run. Otherwise force a
timeout.
This notifcation has been added to queue and will be
serviced as soon as possible.
*/
this.active.timeout = this.$timeout(function () {
activeNotification.dismissOrMinimize();
}, this.DEFAULT_AUTO_DISMISS);
}
return notification;
};
/**
* Used internally by the NotificationService
* @private
*/
NotificationService.prototype.setActiveNotification =
function (notification) {
var self = this,
timeout;
this.active.notification = notification;
/*
If autoDismiss has been specified, OR there are other
notifications queued for display, setup a timeout to
dismiss the dialog.
*/
if (notification && (notification.model.autoDismiss
|| this.selectNextNotification())) {
timeout = notification.model.autoDismiss || this.DEFAULT_AUTO_DISMISS;
this.active.timeout = this.$timeout(function () {
notification.dismissOrMinimize();
}, timeout);
} else {
delete this.active.timeout;
}
};
/**
* Used internally by the NotificationService
*
* @private
*/
NotificationService.prototype.selectNextNotification = function () {
var notification,
i=0;
/*
Loop through the notifications queue and find the first one that
has not already been minimized (manually or otherwise).
*/
for (; i< this.notifications.length; i++) {
notification = this.notifications[i];
if (!notification.model.minimized
&& notification!== this.active.notification) {
return notification;
}
}
};
return NotificationService;
}
);

View File

@ -0,0 +1,78 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,describe,it,expect,beforeEach,waitsFor,jasmine */
define(
['../src/NotificationIndicatorController'],
function (NotificationIndicatorController) {
"use strict";
describe("The notification indicator controller ", function () {
var mockNotificationService,
mockScope,
mockDialogService;
beforeEach(function(){
mockNotificationService = jasmine.createSpy("notificationService");
mockScope = jasmine.createSpy("$scope");
mockDialogService = jasmine.createSpyObj(
"dialogService",
["getDialogResponse","dismiss"]
);
});
it("exposes the highest notification severity to the template", function() {
mockNotificationService.highest = {
severity: "error"
};
var controller = new NotificationIndicatorController(mockScope, mockNotificationService, mockDialogService);
expect(mockScope.highest).toBeTruthy();
expect(mockScope.highest.severity).toBe("error");
});
it("invokes the dialog service to show list of messages", function() {
var controller = new NotificationIndicatorController(mockScope, mockNotificationService, mockDialogService);
expect(mockScope.showNotificationsList).toBeDefined();
mockScope.showNotificationsList();
expect(mockDialogService.getDialogResponse).toHaveBeenCalled();
expect(mockDialogService.getDialogResponse.mostRecentCall.args[0]).toBe('overlay-message-list');
expect(mockDialogService.getDialogResponse.mostRecentCall.args[1].dialog).toBeDefined();
expect(mockDialogService.getDialogResponse.mostRecentCall.args[1].cancel).toBeDefined();
//Invoke the cancel callback
mockDialogService.getDialogResponse.mostRecentCall.args[1].cancel();
expect(mockDialogService.dismiss).toHaveBeenCalled();
});
it("provides a means of dismissing the message list", function() {
var controller = new NotificationIndicatorController(mockScope, mockNotificationService, mockDialogService);
expect(mockScope.showNotificationsList).toBeDefined();
mockScope.showNotificationsList();
expect(mockDialogService.getDialogResponse).toHaveBeenCalled();
expect(mockDialogService.getDialogResponse.mostRecentCall.args[1].cancel).toBeDefined();
//Invoke the cancel callback
mockDialogService.getDialogResponse.mostRecentCall.args[1].cancel();
expect(mockDialogService.dismiss).toHaveBeenCalled();
});
});
}
);

View File

@ -0,0 +1,219 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,describe,it,expect,beforeEach,waitsFor,jasmine */
define(
['../src/NotificationService'],
function (NotificationService) {
"use strict";
describe("The notification service ", function () {
var notificationService,
mockTimeout,
mockAutoDismiss,
mockMinimizeTimeout,
successModel,
errorModel;
beforeEach(function(){
mockTimeout = jasmine.createSpy("$timeout");
mockAutoDismiss = mockMinimizeTimeout = 1000;
notificationService = new NotificationService(
mockTimeout, mockAutoDismiss, mockMinimizeTimeout);
successModel = {
title: "Mock Success Notification",
severity: "info"
};
errorModel = {
title: "Mock Error Notification",
severity: "error"
};
});
it("gets a new success notification, making" +
" the notification active", function() {
var activeNotification;
notificationService.notify(successModel);
activeNotification = notificationService.getActiveNotification();
expect(activeNotification.model).toBe(successModel);
});
it("allows specification of an info notification given just a" +
" title, making the notification active", function() {
var activeNotification,
notificationTitle = "Test info notification";
notificationService.info(notificationTitle);
activeNotification = notificationService.getActiveNotification();
expect(activeNotification.model.title).toBe(notificationTitle);
expect(activeNotification.model.severity).toBe("info");
});
it("gets a new success notification with" +
" numerical auto-dismiss specified. ", function() {
var activeNotification;
successModel.autoDismiss = 1000;
notificationService.notify(successModel);
activeNotification = notificationService.getActiveNotification();
expect(activeNotification.model).toBe(successModel);
mockTimeout.mostRecentCall.args[0]();
expect(mockTimeout.calls.length).toBe(2);
mockTimeout.mostRecentCall.args[0]();
activeNotification = notificationService.getActiveNotification();
expect(activeNotification).toBeUndefined();
});
it("gets a new notification with" +
" boolean auto-dismiss specified. ", function() {
var activeNotification;
successModel.autoDismiss = true;
notificationService.notify(successModel);
activeNotification = notificationService.getActiveNotification();
expect(activeNotification.model).toBe(successModel);
mockTimeout.mostRecentCall.args[0]();
expect(mockTimeout.calls.length).toBe(2);
mockTimeout.mostRecentCall.args[0]();
activeNotification = notificationService.getActiveNotification();
expect(activeNotification).toBeUndefined();
});
it("allows minimization of notifications", function() {
var notification,
activeNotification;
successModel.autoDismiss = false;
notification = notificationService.notify(successModel);
activeNotification = notificationService.getActiveNotification();
expect(activeNotification.model).toBe(successModel);
notification.minimize();
mockTimeout.mostRecentCall.args[0]();
activeNotification = notificationService.getActiveNotification();
expect(activeNotification).toBeUndefined();
expect(notificationService.notifications.length).toBe(1);
});
it("allows dismissal of notifications", function() {
var notification,
activeNotification;
successModel.autoDismiss = false;
notification = notificationService.notify(successModel);
activeNotification = notificationService.getActiveNotification();
expect(activeNotification.model).toBe(successModel);
notification.dismiss();
activeNotification = notificationService.getActiveNotification();
expect(activeNotification).toBeUndefined();
expect(notificationService.notifications.length).toBe(0);
});
describe(" gets called with multiple notifications", function(){
it("auto-dismisses the previously active notification, making" +
" the new notification active", function() {
var activeNotification;
//First pre-load with a info message
notificationService.notify(successModel);
activeNotification =
notificationService.getActiveNotification();
//Initially expect the active notification to be info
expect(activeNotification.model).toBe(successModel);
//Then notify of an error
notificationService.notify(errorModel);
//But it should be auto-dismissed and replaced with the
// error notification
mockTimeout.mostRecentCall.args[0]();
//Two timeouts, one is to force minimization after
// displaying the message for a minimum period, the
// second is to allow minimization animation to take place.
mockTimeout.mostRecentCall.args[0]();
activeNotification = notificationService.getActiveNotification();
expect(activeNotification.model).toBe(errorModel);
});
it("auto-minimizes an active error notification", function() {
var activeNotification;
//First pre-load with an error message
notificationService.notify(errorModel);
//Then notify of info
notificationService.notify(successModel);
expect(notificationService.notifications.length).toEqual(2);
//Mock the auto-minimize
mockTimeout.mostRecentCall.args[0]();
//Two timeouts, one is to force minimization after
// displaying the message for a minimum period, the
// second is to allow minimization animation to take place.
mockTimeout.mostRecentCall.args[0]();
//Previous error message should be minimized, not
// dismissed
expect(notificationService.notifications.length).toEqual(2);
activeNotification =
notificationService.getActiveNotification();
expect(activeNotification.model).toBe(successModel);
expect(errorModel.minimized).toEqual(true);
});
it("auto-minimizes errors when a number of them arrive in" +
" short succession ", function() {
var activeNotification,
error2 = {
title: "Second Mock Error Notification",
severity: "error"
},
error3 = {
title: "Third Mock Error Notification",
severity: "error"
};
//First pre-load with a info message
notificationService.notify(errorModel);
//Then notify of a third error
notificationService.notify(error2);
notificationService.notify(error3);
expect(notificationService.notifications.length).toEqual(3);
//Mock the auto-minimize
mockTimeout.mostRecentCall.args[0]();
//Two timeouts, one is to force minimization after
// displaying the message for a minimum period, the
// second is to allow minimization animation to take place.
mockTimeout.mostRecentCall.args[0]();
//Previous error message should be minimized, not
// dismissed
expect(notificationService.notifications.length).toEqual(3);
activeNotification =
notificationService.getActiveNotification();
expect(activeNotification.model).toBe(error2);
expect(errorModel.minimized).toEqual(true);
//Mock the second auto-minimize
mockTimeout.mostRecentCall.args[0]();
//Two timeouts, one is to force minimization after
// displaying the message for a minimum period, the
// second is to allow minimization animation to take place.
mockTimeout.mostRecentCall.args[0]();
activeNotification =
notificationService.getActiveNotification();
expect(activeNotification.model).toBe(error3);
expect(error2.minimized).toEqual(true);
});
});
});
}
);

View File

@ -0,0 +1,4 @@
[
"NotificationService",
"NotificationIndicatorController"
]

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,7 @@ $colorInteriorBorder: rgba($colorBodyFg, 0.1);
$colorA: #ccc;
$colorAHov: #fff;
$contrastRatioPercent: 7%;
$basicCr: 2px;
$basicCr: 3px;
$controlCr: 3px;
$smallCr: 2px;
@ -68,11 +68,33 @@ $colorFormRequired: $colorAlt1;
$colorFormValid: #33cc33;
$colorFormError: #cc0000;
$colorFormInvalid: #ff3300;
$colorFormLines: rgba(#fff, 0.1);
$colorFormSectionHeader: rgba(#000, 0.2);
$colorInputBg: rgba(#fff, 0.1);
$colorInputFg: pullForward($colorBodyFg, 20%);
$colorFormText: rgba(#fff, 0.5);
$colorInputIcon: pushBack($colorBodyFg, 15%);
// Inspector
$colorInspectorBg: pullForward($colorBodyBg, 3%);
$colorInspectorFg: $colorBodyFg;
$colorInspectorPropName: pushBack($colorBodyFg, 15%);
$colorInspectorPropVal: pullForward($colorInspectorFg, 15%);
$colorInspectorSectionHeaderBg: pullForward($colorInspectorBg, 5%);
$colorInspectorSectionHeaderFg: pullForward($colorInspectorBg, 40%);
// Status colors, mainly used for messaging and item ancillary symbols
$colorStatusFg: #ccc;
$colorStatusDefault: #ccc;
$colorStatusInfo: #62ba72;
$colorStatusAlert: #ffa66d;
$colorStatusError: #d4585c;
$colorProgressBarOuter: rgba(#000, 0.1);
$colorProgressBarAmt: $colorKey;
$progressBarHOverlay: 15px;
$progressBarStripeW: 20px;
$shdwStatusIc: rgba(black, 0.4) 0 1px 2px;
// Selects
$colorSelectBg: $colorBtnBg;
$colorSelectFg: $colorBtnFg;
@ -127,6 +149,8 @@ $colorPlotAreaBorder: $colorInteriorBorder;
$colorPlotLabelFg: pushBack($colorPlotFg, 20%);
// Tree
$colorItemTreeHoverBg: rgba($colorBodyFg, 0.1);
$colorItemTreeHoverFg: pullForward($colorBodyFg, 20%);
$colorItemTreeIcon: $colorKey;
$colorItemTreeIconHover: lighten($colorItemTreeIcon, 20%);
$colorItemTreeFg: $colorBodyFg;
@ -145,12 +169,13 @@ $scrollbarThumbColorHov: lighten($scrollbarThumbColor, 2%);
$scrollbarTrackShdw: rgba(#000, 0.7) 0 1px 5px;
// Splitter
$splitterD: 25px; // splitterD and HandleD should both be odd, or even
$splitterHandleD: 1px;
$colorSplitterBg: pullForward($colorBodyBg, 5%);
$splitterShdw: rgba(black, 0.4) 0 0 3px;
$colorSplitterInterior: $colorBodyBg;
$colorSplitterHover: none;
$splitterW: 5px;
$splitterEndCr: 1px;
$colorGrippyInteriorHover: $colorKey;
$splitterEndCr: none;
$colorSplitterHover: pullForward($colorBodyBg, 15%);
$colorSplitterActive: $colorKey;
// Mobile
$colorMobilePaneLeft: darken($colorBodyBg, 5%);
@ -167,4 +192,4 @@ $colorAboutLink: #84b3ff;
// Loading
$colorLoadingBg: rgba($colorBodyFg, 0.2);
$colorLoadingFg: $colorAlt1;
$colorLoadingFg: $colorAlt1;

View File

@ -4,7 +4,7 @@
@include boxShdw($shdwBtns);
}
@mixin btnSubtle($bg: $colorBodyBg, $bgHov: none, $fg: $colorBodyFg, $ic: $colorBtnIcon) {
@mixin btnSubtle($bg: $colorBodyBg, $bgHov: none, $fg: $colorBodyFg, $ic: $colorBtnIcon) {
@include containerSubtle($bg, $fg);
@include btnBase($bg, linear-gradient(lighten($bg, 15%), lighten($bg, 10%)), $fg, $ic);
@include text-shadow($shdwItemText);

File diff suppressed because it is too large Load Diff

View File

@ -72,9 +72,31 @@ $colorInputBg: $colorGenBg;
$colorInputFg: $colorBodyFg;
$colorFormText: pushBack($colorBodyFg, 10%);
$colorInputIcon: pushBack($colorBodyFg, 25%);
// Status colors, mainly used for messaging and item ancillary symbols
$colorStatusFg: #fff;
$colorStatusDefault: #ccc;
$colorStatusInfo: #60ba7b;
$colorStatusAlert: #ffb66c;
$colorStatusError: #c96b68;
$colorProgressBarOuter: rgba(#000, 0.1);
$colorProgressBarAmt: #0a0;
$progressBarHOverlay: 15px;
$progressBarStripeW: 20px;
$shdwStatusIc: rgba(white, 0.8) 0 0px 5px;
// Selects
$colorSelectBg: #ddd;
$colorSelectFg: $colorBodyFg;
// Inspector
$colorInspectorBg: pullForward($colorBodyBg, 5%);
$colorInspectorFg: $colorBodyFg;
$colorInspectorPropName: pushBack($colorBodyFg, 20%);
$colorInspectorPropVal: pullForward($colorInspectorFg, 15%);
$colorInspectorSectionHeaderBg: pullForward($colorInspectorBg, 5%);
$colorInspectorSectionHeaderFg: pullForward($colorInspectorBg, 40%);
// Limits and staleness colors//
$colorTelemFresh: pullForward($colorBodyFg, 20%);
$colorTelemStale: pushBack($colorBodyFg, 20%);
@ -110,6 +132,7 @@ $colorItemBgSelected: $colorKey;
// Tabular
$colorTabBorder: pullForward($colorBodyBg, 10%);
$colorItemTreeHoverFg: pullForward($colorBodyFg, 20%);
$colorTabBodyBg: $colorBodyBg;
$colorTabBodyFg: pullForward($colorBodyFg, 20%);
$colorTabHeaderBg: pullForward($colorBodyBg, 10%);
@ -125,6 +148,7 @@ $colorPlotAreaBorder: $colorInteriorBorder;
$colorPlotLabelFg: pushBack($colorPlotFg, 20%);
// Tree
$colorItemTreeHoverBg: rgba($colorBodyFg, 0.1);
$colorItemTreeIcon: $colorKey;
$colorItemTreeIconHover: $colorItemTreeIcon; //pushBack($colorItemTreeIcon, 20%);
$colorItemTreeVCHover: $colorKey;
@ -143,12 +167,13 @@ $scrollbarThumbColor: darken($colorBodyBg, 50%);//
$scrollbarThumbColorHov: $colorKey;
// Splitter
$splitterD: 24px;
$splitterHandleD: 2px;
$colorSplitterBg: pullForward($colorBodyBg, 10%);
$splitterShdw: none;
$colorSplitterInterior: $colorBodyBg;
$colorSplitterHover: $colorKey;
$splitterW: 5px;
$splitterEndCr: $splitterW;
$colorGrippyInteriorHover: $colorBodyBg;
$splitterEndCr: none;
$colorSplitterHover: none;
$colorSplitterActive: $colorKey;
// Mobile
$colorMobilePaneLeft: darken($colorBodyBg, 2%);

View File

@ -36,9 +36,9 @@
{
"key": "TIME_CONDUCTOR_DOMAINS",
"value": [
{ "key": "time", "name": "Time" },
{ "key": "yesterday", "name": "Yesterday" }
{ "key": "time", "name": "UTC", "format": "utc" }
],
"priority": "fallback",
"comment": "Placeholder; to be replaced by inspection of available domains."
}
]

View File

@ -1,4 +1,5 @@
<mct-include key="'time-controller'"
parameters='parameters'
ng-model='ngModel.conductor'>
</mct-include>
<mct-control key="'select'"

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