mirror of
https://github.com/nasa/openmct.git
synced 2024-12-19 21:27:52 +00:00
Merge remote-tracking branch 'github/master' into open229b
Conflicts: platform/features/conductor/src/ConductorRepresenter.js
This commit is contained in:
commit
99376391a9
@ -11,6 +11,7 @@
|
||||
"platform/commonUI/inspect",
|
||||
"platform/commonUI/mobile",
|
||||
"platform/commonUI/themes/espresso",
|
||||
"platform/commonUI/notification",
|
||||
"platform/containment",
|
||||
"platform/execution",
|
||||
"platform/telemetry",
|
||||
|
47
example/notifications/bundle.json
Normal file
47
example/notifications/bundle.json
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
10
example/notifications/res/dialog-launch.html
Normal file
10
example/notifications/res/dialog-launch.html
Normal file
@ -0,0 +1,10 @@
|
||||
<span class="status block ok" ng-controller="DialogLaunchController">
|
||||
<span class="ui-symbol status-indicator"></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>
|
10
example/notifications/res/notification-launch.html
Normal file
10
example/notifications/res/notification-launch.html
Normal file
@ -0,0 +1,10 @@
|
||||
<span class="status block ok" ng-controller="NotificationLaunchController">
|
||||
<span class="ui-symbol status-indicator"></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>
|
150
example/notifications/src/DialogLaunchController.js
Normal file
150
example/notifications/src/DialogLaunchController.js
Normal 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;
|
||||
}
|
||||
);
|
56
example/notifications/src/DialogLaunchIndicator.js
Normal file
56
example/notifications/src/DialogLaunchIndicator.js
Normal 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;
|
||||
}
|
||||
);
|
172
example/notifications/src/NotificationLaunchController.js
Normal file
172
example/notifications/src/NotificationLaunchController.js
Normal 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;
|
||||
}
|
||||
);
|
50
example/notifications/src/NotificationLaunchIndicator.js
Normal file
50
example/notifications/src/NotificationLaunchIndicator.js
Normal 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;
|
||||
}
|
||||
);
|
@ -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": [
|
||||
|
@ -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'
|
||||
|
32
platform/commonUI/dialog/res/templates/message.html
Normal file
32
platform/commonUI/dialog/res/templates/message.html
Normal 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>
|
@ -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>
|
@ -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>
|
@ -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"
|
||||
|
@ -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>
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
);
|
||||
|
@ -7,7 +7,7 @@
|
||||
"provides": "formatService",
|
||||
"type": "provider",
|
||||
"implementation": "FormatProvider.js",
|
||||
"depends": [ "formats[]", "$log" ]
|
||||
"depends": [ "formats[]" ]
|
||||
}
|
||||
],
|
||||
"formats": [
|
||||
|
@ -72,9 +72,11 @@ define([
|
||||
|
||||
/**
|
||||
* Look up a format by its symbolic identifier.
|
||||
* @method getFormat
|
||||
* @memberof FormatService#
|
||||
* @param {string} key the identifier for this format
|
||||
* @returns {Format} the format, or `undefined` if no such format
|
||||
* is known.
|
||||
* @returns {Format} the format
|
||||
* @throws {Error} errors when the requested format is unrecognized
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -85,7 +87,7 @@ define([
|
||||
* @param {Array.<function(new : Format)>} format constructors,
|
||||
* from the `formats` extension category.
|
||||
*/
|
||||
function FormatProvider(formats, $log) {
|
||||
function FormatProvider(formats) {
|
||||
var formatMap = {};
|
||||
|
||||
function addToMap(Format) {
|
||||
@ -97,13 +99,12 @@ define([
|
||||
|
||||
formats.forEach(addToMap);
|
||||
this.formatMap = formatMap;
|
||||
this.$log = $log;
|
||||
}
|
||||
|
||||
FormatProvider.prototype.getFormat = function (key) {
|
||||
var format = this.formatMap[key];
|
||||
if (!format) {
|
||||
this.$log.warn("No format found for " + key);
|
||||
throw new Error("FormatProvider: No format found for " + key);
|
||||
}
|
||||
return format;
|
||||
};
|
||||
|
@ -41,14 +41,13 @@ define(
|
||||
[ 'parse', 'validate', 'format' ]
|
||||
);
|
||||
});
|
||||
mockLog = jasmine.createSpyObj('$log', ['error', 'warn']);
|
||||
// Return constructors
|
||||
mockFormats = KEYS.map(function (k, i) {
|
||||
function MockFormat() { return mockFormatInstances[i]; }
|
||||
MockFormat.key = k;
|
||||
return MockFormat;
|
||||
});
|
||||
provider = new FormatProvider(mockFormats, mockLog);
|
||||
provider = new FormatProvider(mockFormats);
|
||||
});
|
||||
|
||||
it("looks up formats by key", function () {
|
||||
@ -58,11 +57,10 @@ define(
|
||||
});
|
||||
});
|
||||
|
||||
it("warns about unknown formats", function () {
|
||||
provider.getFormat('a'); // known format
|
||||
expect(mockLog.warn).not.toHaveBeenCalled();
|
||||
provider.getFormat('some-unknown-format');
|
||||
expect(mockLog.warn).toHaveBeenCalledWith(jasmine.any(String));
|
||||
it("throws an error about unknown formats", function () {
|
||||
expect(function () {
|
||||
provider.getFormat('some-unknown-format');
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -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"
|
||||
@ -112,6 +120,11 @@
|
||||
"key": "SelectorController",
|
||||
"implementation": "controllers/SelectorController.js",
|
||||
"depends": [ "objectService", "$scope" ]
|
||||
},
|
||||
{
|
||||
"key": "BannerController",
|
||||
"implementation": "controllers/BannerController.js",
|
||||
"depends": ["$scope", "notificationService", "dialogService"]
|
||||
}
|
||||
],
|
||||
"directives": [
|
||||
|
@ -1,14 +1,30 @@
|
||||
{
|
||||
"metadata": {
|
||||
"name": "WTD Symbols v24",
|
||||
"lastOpened": 1441992412958,
|
||||
"created": 1441992410384
|
||||
"name": "WTD Symbols v2.3",
|
||||
"lastOpened": 1444267493342,
|
||||
"created": 1444266013303
|
||||
},
|
||||
"iconSets": [
|
||||
{
|
||||
"selection": [
|
||||
{
|
||||
"order": 86,
|
||||
"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 +34,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 +154,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 58880,
|
||||
"name": "icon-box-with-arrow-cursor",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 11,
|
||||
@ -146,7 +162,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 65,
|
||||
"name": "icon-activity-mode",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 12,
|
||||
@ -154,15 +170,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 +186,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 58883,
|
||||
"name": "icon-alert-triangle",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 15,
|
||||
@ -178,7 +194,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 238,
|
||||
"name": "icon-arrow-double-down",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 16,
|
||||
@ -186,7 +202,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 235,
|
||||
"name": "icon-arrow-double-up",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 2,
|
||||
@ -194,7 +210,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 118,
|
||||
"name": "icon-arrow-down",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 19,
|
||||
@ -202,7 +218,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 60,
|
||||
"name": "icon-arrow-left",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 20,
|
||||
@ -210,7 +226,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 62,
|
||||
"name": "icon-arrow-right",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 21,
|
||||
@ -218,7 +234,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 236,
|
||||
"name": "icon-arrow-tall-down",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 22,
|
||||
@ -226,7 +242,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 237,
|
||||
"name": "icon-arrow-tall-up",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 23,
|
||||
@ -234,7 +250,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 94,
|
||||
"name": "icon-arrow-up",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 24,
|
||||
@ -242,7 +258,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 73,
|
||||
"name": "icon-arrows-out",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 25,
|
||||
@ -250,7 +266,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 58893,
|
||||
"name": "icon-arrows-right-left",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 33,
|
||||
@ -258,7 +274,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 53,
|
||||
"name": "icon-arrows-up-down",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 26,
|
||||
@ -266,7 +282,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 42,
|
||||
"name": "icon-asterisk",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 27,
|
||||
@ -274,7 +290,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 72,
|
||||
"name": "icon-autoflow-tabular",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 28,
|
||||
@ -282,7 +298,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 224,
|
||||
"name": "icon-box",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 29,
|
||||
@ -290,7 +306,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 50,
|
||||
"name": "icon-check",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 30,
|
||||
@ -298,7 +314,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 67,
|
||||
"name": "icon-clock",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 31,
|
||||
@ -306,7 +322,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 46,
|
||||
"name": "icon-connectivity",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 32,
|
||||
@ -314,7 +330,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 100,
|
||||
"name": "icon-database-query",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 17,
|
||||
@ -322,7 +338,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 68,
|
||||
"name": "icon-database",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 35,
|
||||
@ -330,7 +346,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 81,
|
||||
"name": "icon-dictionary",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 36,
|
||||
@ -338,7 +354,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 242,
|
||||
"name": "icon-duplicate",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 37,
|
||||
@ -346,7 +362,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 102,
|
||||
"name": "icon-folder-new",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 38,
|
||||
@ -354,7 +370,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 70,
|
||||
"name": "icon-folder",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 39,
|
||||
@ -362,7 +378,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 95,
|
||||
"name": "icon-fullscreen-collapse",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 40,
|
||||
@ -370,7 +386,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 122,
|
||||
"name": "icon-fullscreen-expand",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 41,
|
||||
@ -378,7 +394,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 71,
|
||||
"name": "icon-gear",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 49,
|
||||
@ -386,7 +402,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 227,
|
||||
"name": "icon-image",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 42,
|
||||
@ -394,7 +410,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 225,
|
||||
"name": "icon-layers",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 43,
|
||||
@ -402,7 +418,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 76,
|
||||
"name": "icon-layout",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 44,
|
||||
@ -410,7 +426,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 226,
|
||||
"name": "icon-line-horz",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 75,
|
||||
@ -418,7 +434,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 244,
|
||||
"name": "icon-link",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 46,
|
||||
@ -426,7 +442,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 88,
|
||||
"name": "icon-magnify-in",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 47,
|
||||
@ -434,7 +450,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 89,
|
||||
"name": "icon-magnify-out",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 48,
|
||||
@ -442,7 +458,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 77,
|
||||
"name": "icon-magnify",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 34,
|
||||
@ -450,7 +466,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 109,
|
||||
"name": "icon-menu",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 50,
|
||||
@ -458,7 +474,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 243,
|
||||
"name": "icon-move",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 51,
|
||||
@ -466,7 +482,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 121,
|
||||
"name": "icon-new-window",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 52,
|
||||
@ -474,7 +490,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 111,
|
||||
"name": "icon-object",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 73,
|
||||
@ -482,7 +498,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 63,
|
||||
"name": "icon-object-unknown",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 53,
|
||||
@ -490,7 +506,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 86,
|
||||
"name": "icon-packet",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 54,
|
||||
@ -498,7 +514,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 234,
|
||||
"name": "icon-page",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 55,
|
||||
@ -506,7 +522,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 241,
|
||||
"name": "icon-pause",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 56,
|
||||
@ -514,7 +530,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 112,
|
||||
"name": "icon-pencil",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 65,
|
||||
@ -522,7 +538,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 79,
|
||||
"name": "icon-people",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 57,
|
||||
@ -530,7 +546,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 239,
|
||||
"name": "icon-play",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 58,
|
||||
@ -538,7 +554,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 233,
|
||||
"name": "icon-plot-resource",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 59,
|
||||
@ -546,7 +562,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 43,
|
||||
"name": "icon-plus",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 60,
|
||||
@ -554,7 +570,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 45,
|
||||
"name": "icon-minus",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 61,
|
||||
@ -562,7 +578,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 54,
|
||||
"name": "icon-sine",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 62,
|
||||
@ -570,7 +586,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 228,
|
||||
"name": "icon-T",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 63,
|
||||
@ -578,7 +594,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 116,
|
||||
"name": "icon-telemetry-panel",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 64,
|
||||
@ -586,7 +602,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 84,
|
||||
"name": "icon-telemetry",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 18,
|
||||
@ -594,7 +610,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 246,
|
||||
"name": "icon-thumbs-strip",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 67,
|
||||
@ -602,7 +618,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 83,
|
||||
"name": "icon-timeline",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 68,
|
||||
@ -610,7 +626,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 245,
|
||||
"name": "icon-timer",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 69,
|
||||
@ -618,7 +634,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 90,
|
||||
"name": "icon-trash",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 70,
|
||||
@ -626,7 +642,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 229,
|
||||
"name": "icon-two-parts-both",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 71,
|
||||
@ -634,7 +650,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 231,
|
||||
"name": "icon-two-parts-one-only",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 72,
|
||||
@ -642,7 +658,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 120,
|
||||
"name": "icon-x-heavy",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 66,
|
||||
@ -650,7 +666,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 58946,
|
||||
"name": "icon-x",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
}
|
||||
],
|
||||
"id": 2,
|
||||
@ -665,6 +681,58 @@
|
||||
"height": 1024,
|
||||
"prevSize": 32,
|
||||
"icons": [
|
||||
{
|
||||
"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 +766,8 @@
|
||||
"icon-x-in-circle"
|
||||
],
|
||||
"colorPermutations": {
|
||||
"16161751": []
|
||||
"16161751": [],
|
||||
"125525525516161751": []
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -899,6 +968,11 @@
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"125525525516161751": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -1051,18 +1125,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 +1422,9 @@
|
||||
"colorPermutations": {
|
||||
"16161751": [
|
||||
0
|
||||
],
|
||||
"125525525516161751": [
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -14853,6 +14940,5 @@
|
||||
"gridSize": 16,
|
||||
"showLiga": false
|
||||
},
|
||||
"uid": -1,
|
||||
"time": 1441993324496
|
||||
"uid": -1
|
||||
}
|
Binary file not shown.
@ -76,7 +76,7 @@
|
||||
<glyph unicode="ô" glyph-name="icon-link" d="M1024 448l-512 512v-307.2l-512-204.8v-256h512v-256z" />
|
||||
<glyph unicode="õ" 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="ö" 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="" 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="" 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="" glyph-name="icon-datatable" d="M1024 768c0-106.039-229.23-192-512-192s-512 85.961-512 192c0 106.039 229.23 192 512 192s512-85.961 512-192zM512 448c-282.8 0-512 86-512 192v-512c0-106 229.2-192 512-192s512 86 512 192v512c0-106-229.2-192-512-192zM896 385v-256c-36.6-15.6-79.8-28.8-128-39.4v256c48.2 10.6 91.4 23.8 128 39.4zM256 345.6v-256c-48.2 10.4-91.4 23.8-128 39.4v256c36.6-15.6 79.8-28.8 128-39.4zM384 70v256c41-4 83.8-6 128-6s87 2.2 128 6v-256c-41-4-83.8-6-128-6s-87 2.2-128 6z" />
|
||||
<glyph unicode="" glyph-name="icon-tabular-scrolling" d="M64 960c-35.2 0-64-28.8-64-64v-192h448v256h-384zM1024 704v192c0 35.2-28.8 64-64 64h-384v-256h448zM0 576v-192c0-35.2 28.8-64 64-64h384v256h-448zM960 320c35.2 0 64 28.8 64 64v192h-448v-256h384zM512-64l-256 256h512z" />
|
||||
<glyph unicode="" glyph-name="icon-alert-triangle" d="M998.208 111.136l-422.702 739.728c-34.928 61.124-92.084 61.124-127.012 0l-422.702-739.728c-34.928-61.126-5.906-111.136 64.494-111.136h843.428c70.4 0 99.422 50.010 64.494 111.136zM512 128c-35.2 0-64 28.8-64 64s28.8 64 64 64 64-28.8 64-64c0-35.2-28.8-64-64-64zM627.448 577.242l-38.898-194.486c-6.902-34.516-41.35-62.756-76.55-62.756s-69.648 28.24-76.552 62.758l-38.898 194.486c-6.902 34.516 16.25 62.756 51.45 62.756h128c35.2 0 58.352-28.24 51.448-62.758z" />
|
||||
@ -85,6 +85,8 @@
|
||||
<glyph unicode="" glyph-name="icon-paint-bucket" d="M544 736v-224c0-88.4-71.6-160-160-160s-160 71.6-160 160v97.2l-197.4-196.4c-50-50-12.4-215.2 112.4-340s290-162.4 340-112.4l417 423.6-352 352zM896-64c70.6 0 128 57.4 128 128 0 108.6-128 192-128 192s-128-83.4-128-192c0-70.6 57.4-128 128-128zM384 448c-35.4 0-64 28.6-64 64v384c0 35.4 28.6 64 64 64s64-28.6 64-64v-384c0-35.4-28.6-64-64-64z" />
|
||||
<glyph unicode="" glyph-name="icon-x-in-circle" d="M512 960c-282.8 0-512-229.2-512-512s229.2-512 512-512 512 229.2 512 512-229.2 512-512 512zM832 256l-128-128-192 192-192-192-128 128 192 192-192 192 128 128 192-192 192 192 128-128-192-192 192-192z" />
|
||||
<glyph unicode="" 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="" 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="" glyph-name="icon-arrows-right-left" d="M1024 448l-448-512v1024zM448 960l-448-512 448-512z" />
|
||||
<glyph unicode="" 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="" 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: 27 KiB |
Binary file not shown.
Binary file not shown.
@ -47,8 +47,8 @@ $ueEditLeftPaneW: 75%;
|
||||
$treeSearchInputBarH: 25px;
|
||||
$ueTimeControlH: (33px, 20px, 20px);
|
||||
// Overlay
|
||||
$ovrTopBarH: 60px;
|
||||
$ovrFooterH: 30px;
|
||||
$ovrTopBarH: 45px;
|
||||
$ovrFooterH: 24px;
|
||||
$overlayMargin: 25px;
|
||||
// Items
|
||||
$ueBrowseGridItemLg: 200px;
|
||||
|
@ -29,7 +29,6 @@
|
||||
@import "helpers/bubbles";
|
||||
@import "helpers/splitter";
|
||||
@import "helpers/wait-spinner";
|
||||
@import "messages";
|
||||
@import "properties";
|
||||
|
||||
/********************************* CONTROLS */
|
||||
@ -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 */
|
||||
|
@ -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%);
|
||||
}
|
||||
}
|
@ -94,7 +94,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 +128,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') {
|
||||
|
@ -19,34 +19,6 @@
|
||||
* 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;
|
||||
@ -291,6 +263,88 @@ label.checkbox.custom {
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************** 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 {
|
||||
|
306
platform/commonUI/general/res/sass/controls/_messages.scss
Normal file
306
platform/commonUI/general/res/sass/controls/_messages.scss
Normal 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; }
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@
|
||||
/************************** MOBILE REPRESENTATION ITEMS DIMENSIONS */
|
||||
$mobileListIconSize: 30px;
|
||||
$mobileTitleDescH: 35px;
|
||||
$mobileOverlayMargin: 10px;
|
||||
$mobileOverlayMargin: 20px;
|
||||
$phoneItemH: floor($ueBrowseGridItemLg/4);
|
||||
$tabletItemH: floor($ueBrowseGridItemLg/3);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -43,9 +43,9 @@
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.editor {
|
||||
@include border-radius($basicCr * 1.5);
|
||||
}
|
||||
//.editor {
|
||||
// @include border-radius($basicCr * 1.5);
|
||||
//}
|
||||
|
||||
.contents {
|
||||
$myM: 0; //$interiorMargin;
|
||||
@ -125,21 +125,37 @@
|
||||
}
|
||||
}
|
||||
|
||||
.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 {
|
||||
@ -343,4 +359,4 @@
|
||||
@include webkitProp(flex, '1 1 0');
|
||||
padding-right: $interiorMarginLg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
@ -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
|
||||
|
21
platform/commonUI/general/res/templates/message-banner.html
Normal file
21
platform/commonUI/general/res/templates/message-banner.html
Normal 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)">
|
||||
x</a>
|
||||
</div>
|
10
platform/commonUI/general/res/templates/progress-bar.html
Normal file
10
platform/commonUI/general/res/templates/progress-bar.html
Normal 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>
|
@ -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;
|
||||
});
|
@ -26,9 +26,6 @@ define(
|
||||
function () {
|
||||
'use strict';
|
||||
|
||||
var UNRECOGNIZED_FORMAT_ERROR =
|
||||
"Unrecognized format for date-time field.";
|
||||
|
||||
/**
|
||||
* Controller to support the date-time entry field.
|
||||
*
|
||||
@ -69,9 +66,6 @@ define(
|
||||
|
||||
function setFormat(format) {
|
||||
formatter = formatService.getFormat(format || defaultFormat);
|
||||
if (!formatter) {
|
||||
throw new Error(UNRECOGNIZED_FORMAT_ERROR);
|
||||
}
|
||||
updateFromModel($scope.ngModel[$scope.field]);
|
||||
}
|
||||
|
||||
|
@ -26,9 +26,7 @@ define(
|
||||
function (moment) {
|
||||
"use strict";
|
||||
|
||||
var TICK_SPACING_PX = 150,
|
||||
UNRECOGNIZED_FORMAT_ERROR =
|
||||
"Unrecognized format for time range control.";
|
||||
var TICK_SPACING_PX = 150;
|
||||
|
||||
|
||||
/**
|
||||
@ -221,11 +219,6 @@ define(
|
||||
|
||||
function updateFormat(key) {
|
||||
formatter = formatService.getFormat(key || defaultFormat);
|
||||
|
||||
if (!formatter) {
|
||||
throw new Error(UNRECOGNIZED_FORMAT_ERROR);
|
||||
}
|
||||
|
||||
updateViewForInnerSpanFromModel($scope.ngModel);
|
||||
updateTicks();
|
||||
}
|
||||
|
45
platform/commonUI/notification/bundle.json
Normal file
45
platform/commonUI/notification/bundle.json
Normal 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" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -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"></span>
|
||||
<span class="label">
|
||||
<a ng-click="showNotificationsList()">{{notifications.length}}
|
||||
Notifications</a>
|
||||
</span>
|
||||
<span class="count">{{notifications.length}}</span>
|
||||
</span>
|
35
platform/commonUI/notification/src/NotificationIndicator.js
Normal file
35
platform/commonUI/notification/src/NotificationIndicator.js
Normal file
@ -0,0 +1,35 @@
|
||||
/*****************************************************************************
|
||||
* 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 NotificationIndicator() {}
|
||||
|
||||
NotificationIndicator.template = 'notificationIndicatorTemplate';
|
||||
|
||||
return NotificationIndicator;
|
||||
}
|
||||
);
|
@ -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;
|
||||
}
|
||||
);
|
||||
|
387
platform/commonUI/notification/src/NotificationService.js
Normal file
387
platform/commonUI/notification/src/NotificationService.js
Normal 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;
|
||||
}
|
||||
);
|
@ -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();
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
219
platform/commonUI/notification/test/NotificationServiceSpec.js
Normal file
219
platform/commonUI/notification/test/NotificationServiceSpec.js
Normal 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);
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
4
platform/commonUI/notification/test/suite.json
Normal file
4
platform/commonUI/notification/test/suite.json
Normal file
@ -0,0 +1,4 @@
|
||||
[
|
||||
"NotificationService",
|
||||
"NotificationIndicatorController"
|
||||
]
|
File diff suppressed because it is too large
Load Diff
@ -10,7 +10,7 @@ $colorInteriorBorder: rgba($colorBodyFg, 0.1);
|
||||
$colorA: #ccc;
|
||||
$colorAHov: #fff;
|
||||
$contrastRatioPercent: 7%;
|
||||
$basicCr: 2px;
|
||||
$basicCr: 3px;
|
||||
$controlCr: 3px;
|
||||
$smallCr: 2px;
|
||||
|
||||
@ -37,14 +37,12 @@ $timeControllerToiLineColorHov: #fff;
|
||||
|
||||
// General Colors
|
||||
$colorAlt1: #ffc700;
|
||||
$colorAlert: #ff3c00;
|
||||
$colorAlert: #ff533a;
|
||||
$colorIconLink: #49dedb;
|
||||
$colorPausedBg: #c56f01;
|
||||
$colorPausedFg: #fff;
|
||||
$colorCreateBtn: $colorKey;
|
||||
$colorGridLines: rgba(#fff, 0.05);
|
||||
$colorFormLines: rgba(#fff, 0.1);
|
||||
$colorFormSectionHeader: rgba(#000, 0.2);
|
||||
$colorInvokeMenu: #fff;
|
||||
$colorObjHdrTxt: $colorBodyFg;
|
||||
$colorObjHdrIc: pullForward($colorObjHdrTxt, 20%);
|
||||
@ -57,10 +55,10 @@ $colorMenuIc: pullForward($colorKey, 17%);
|
||||
$colorMenuHovBg: pullForward($colorMenuBg, 10%);
|
||||
$colorMenuHovFg: #fff;
|
||||
$colorMenuHovIc: $colorMenuHovFg;
|
||||
$shdwMenu: none;
|
||||
$shdwMenuText: rgba(black, 0.1) 0 1px 2px;
|
||||
$colorCreateMenuLgIcon: $colorMenuFg;
|
||||
$colorCreateMenuText: $colorMenuFg;
|
||||
$shdwMenu: none;
|
||||
$shdwMenuText: rgba(black, 0.1) 0 1px 2px;
|
||||
|
||||
// Form colors
|
||||
$colorCheck: $colorKey;
|
||||
@ -68,11 +66,25 @@ $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%);
|
||||
|
||||
// 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;
|
||||
@ -167,4 +179,4 @@ $colorAboutLink: #84b3ff;
|
||||
|
||||
// Loading
|
||||
$colorLoadingBg: rgba($colorBodyFg, 0.2);
|
||||
$colorLoadingFg: $colorAlt1;
|
||||
$colorLoadingFg: $colorAlt1;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -72,6 +72,20 @@ $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;
|
||||
|
||||
|
@ -101,8 +101,7 @@ define(
|
||||
|
||||
function updateDomain(value) {
|
||||
var newDomain = conductor.domain(value);
|
||||
conductorScope.parameters.format =
|
||||
newDomain && newDomain.format;
|
||||
conductorScope.parameters.format = newDomain.format;
|
||||
broadcastBounds();
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,6 @@ define(
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
|
||||
/**
|
||||
* Defines the mct-representation directive. This may be used to
|
||||
* present domain objects as HTML (with event wiring), with the
|
||||
@ -96,6 +95,9 @@ define(
|
||||
}),
|
||||
toClear = [], // Properties to clear out of scope on change
|
||||
counter = 0,
|
||||
couldRepresent = false,
|
||||
lastId,
|
||||
lastKey,
|
||||
changeTemplate = templateLinker.link($scope, element);
|
||||
|
||||
// Populate scope with any capabilities indicated by the
|
||||
@ -141,6 +143,13 @@ define(
|
||||
});
|
||||
}
|
||||
|
||||
function unchanged(canRepresent, id, key) {
|
||||
return canRepresent &&
|
||||
couldRepresent &&
|
||||
id === lastId &&
|
||||
key === lastKey;
|
||||
}
|
||||
|
||||
// General-purpose refresh mechanism; should set up the scope
|
||||
// as appropriate for current representation key and
|
||||
// domain object.
|
||||
@ -149,7 +158,13 @@ define(
|
||||
representation = lookup($scope.key, domainObject),
|
||||
path = representation && getPath(representation),
|
||||
uses = ((representation || {}).uses || []),
|
||||
canRepresent = !!(path && domainObject);
|
||||
canRepresent = !!(path && domainObject),
|
||||
id = domainObject && domainObject.getId(),
|
||||
key = $scope.key;
|
||||
|
||||
if (unchanged(canRepresent, id, key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create an empty object named "representation", for this
|
||||
// representation to store local variables into.
|
||||
@ -173,6 +188,11 @@ define(
|
||||
delete $scope[property];
|
||||
});
|
||||
|
||||
// To allow simplified change detection next time around
|
||||
couldRepresent = canRepresent;
|
||||
lastId = id;
|
||||
lastKey = key;
|
||||
|
||||
// Populate scope with fields associated with the current
|
||||
// domain object (if one has been passed in)
|
||||
if (canRepresent) {
|
||||
|
@ -92,10 +92,19 @@ define(
|
||||
var activeElement = element,
|
||||
activeTemplateUrl,
|
||||
comment = this.$compile('<!-- hidden mct element -->')(scope),
|
||||
activeScope,
|
||||
self = this;
|
||||
|
||||
function destroyScope() {
|
||||
if (activeScope) {
|
||||
activeScope.$destroy();
|
||||
activeScope = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function removeElement() {
|
||||
if (activeElement !== comment) {
|
||||
destroyScope();
|
||||
activeElement.replaceWith(comment);
|
||||
activeElement = comment;
|
||||
}
|
||||
@ -110,8 +119,10 @@ define(
|
||||
}
|
||||
|
||||
function populateElement(template) {
|
||||
element.empty();
|
||||
element.append(self.$compile(template)(scope));
|
||||
destroyScope();
|
||||
activeScope = scope.$new(false);
|
||||
element.html(template);
|
||||
self.$compile(element.contents())(activeScope);
|
||||
}
|
||||
|
||||
function badTemplate(templateUrl) {
|
||||
@ -120,22 +131,21 @@ define(
|
||||
}
|
||||
|
||||
function changeTemplate(templateUrl) {
|
||||
if (templateUrl !== activeTemplateUrl) {
|
||||
if (templateUrl) {
|
||||
addElement();
|
||||
self.load(templateUrl).then(function (template) {
|
||||
// Avoid race conditions
|
||||
if (templateUrl === activeTemplateUrl) {
|
||||
populateElement(template);
|
||||
}
|
||||
}, function () {
|
||||
badTemplate(templateUrl);
|
||||
});
|
||||
} else {
|
||||
removeElement();
|
||||
}
|
||||
activeTemplateUrl = templateUrl;
|
||||
if (templateUrl) {
|
||||
destroyScope();
|
||||
addElement();
|
||||
self.load(templateUrl).then(function (template) {
|
||||
// Avoid race conditions
|
||||
if (templateUrl === activeTemplateUrl) {
|
||||
populateElement(template);
|
||||
}
|
||||
}, function () {
|
||||
badTemplate(templateUrl);
|
||||
});
|
||||
} else {
|
||||
removeElement();
|
||||
}
|
||||
activeTemplateUrl = templateUrl;
|
||||
}
|
||||
|
||||
if (templateUrl) {
|
||||
|
@ -27,7 +27,8 @@ define(
|
||||
function (TemplateLinker) {
|
||||
'use strict';
|
||||
|
||||
var JQLITE_METHODS = [ 'replaceWith', 'empty', 'append' ];
|
||||
var JQLITE_METHODS = [ 'replaceWith', 'empty', 'html', 'contents' ],
|
||||
SCOPE_METHODS = [ '$on', '$new', '$destroy' ];
|
||||
|
||||
describe("TemplateLinker", function () {
|
||||
var mockTemplateRequest,
|
||||
@ -38,6 +39,8 @@ define(
|
||||
mockElement,
|
||||
mockTemplates,
|
||||
mockElements,
|
||||
mockContents,
|
||||
mockNewScope,
|
||||
mockPromise,
|
||||
linker;
|
||||
|
||||
@ -46,14 +49,18 @@ define(
|
||||
mockSce = jasmine.createSpyObj('$sce', ['trustAsResourceUrl']);
|
||||
mockCompile = jasmine.createSpy('$compile');
|
||||
mockLog = jasmine.createSpyObj('$log', ['error', 'warn']);
|
||||
mockScope = jasmine.createSpyObj('$scope', ['$on']);
|
||||
mockScope = jasmine.createSpyObj('$scope', SCOPE_METHODS);
|
||||
mockNewScope = jasmine.createSpyObj('$scope', SCOPE_METHODS);
|
||||
mockElement = jasmine.createSpyObj('element', JQLITE_METHODS);
|
||||
mockPromise = jasmine.createSpyObj('promise', ['then']);
|
||||
mockTemplates = {};
|
||||
mockElements = {};
|
||||
mockContents = {};
|
||||
|
||||
mockTemplateRequest.andReturn(mockPromise);
|
||||
mockCompile.andCallFake(function (html) {
|
||||
mockCompile.andCallFake(function (toCompile) {
|
||||
var html = typeof toCompile === 'string' ?
|
||||
toCompile : toCompile.testHtml;
|
||||
mockTemplates[html] = jasmine.createSpy('template');
|
||||
mockElements[html] =
|
||||
jasmine.createSpyObj('templateEl', JQLITE_METHODS);
|
||||
@ -63,6 +70,17 @@ define(
|
||||
mockSce.trustAsResourceUrl.andCallFake(function (url) {
|
||||
return { trusted: url };
|
||||
});
|
||||
mockScope.$new.andReturn(mockNewScope);
|
||||
mockElement.html.andCallFake(function (html) {
|
||||
mockContents[html] =
|
||||
jasmine.createSpyObj('contentsEl', JQLITE_METHODS);
|
||||
mockContents[html].testHtml = html;
|
||||
});
|
||||
mockElement.contents.andCallFake(function () {
|
||||
return mockContents[
|
||||
mockElement.html.mostRecentCall.args[0]
|
||||
];
|
||||
});
|
||||
|
||||
linker = new TemplateLinker(
|
||||
mockTemplateRequest,
|
||||
@ -131,10 +149,11 @@ define(
|
||||
}, false);
|
||||
});
|
||||
|
||||
it("compiles loaded templates with linked scope", function () {
|
||||
expect(mockCompile).toHaveBeenCalledWith(testTemplate);
|
||||
it("compiles element contents with a new scope", function () {
|
||||
expect(mockCompile)
|
||||
.toHaveBeenCalledWith(mockContents[testTemplate]);
|
||||
expect(mockTemplates[testTemplate])
|
||||
.toHaveBeenCalledWith(mockScope);
|
||||
.toHaveBeenCalledWith(mockNewScope);
|
||||
});
|
||||
|
||||
it("replaces comments with specified element", function () {
|
||||
@ -142,9 +161,9 @@ define(
|
||||
.toHaveBeenCalledWith(mockElement);
|
||||
});
|
||||
|
||||
it("appends rendered content to the specified element", function () {
|
||||
expect(mockElement.append)
|
||||
.toHaveBeenCalledWith(mockElements[testTemplate]);
|
||||
it("inserts HTML content into the specified element", function () {
|
||||
expect(mockElement.html)
|
||||
.toHaveBeenCalledWith(testTemplate);
|
||||
});
|
||||
|
||||
it("clears templates when called with undefined", function () {
|
||||
|
@ -38,7 +38,7 @@
|
||||
{
|
||||
"key": "telemetryFormatter",
|
||||
"implementation": "TelemetryFormatter.js",
|
||||
"depends": [ "formatService", "DEFAULT_TIME_FORMAT", "$log" ]
|
||||
"depends": [ "formatService", "DEFAULT_TIME_FORMAT" ]
|
||||
},
|
||||
{
|
||||
"key": "telemetrySubscriber",
|
||||
|
@ -40,12 +40,10 @@ define(
|
||||
* domain values
|
||||
* @param {string} defaultFormatKey the format to request when no
|
||||
* format has been otherwise specified
|
||||
* @param $log Angular's `$log`, to log warnings
|
||||
*/
|
||||
function TelemetryFormatter(formatService, defaultFormatKey, $log) {
|
||||
function TelemetryFormatter(formatService, defaultFormatKey) {
|
||||
this.formatService = formatService;
|
||||
this.defaultFormat = formatService.getFormat(defaultFormatKey);
|
||||
this.$log = $log;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,7 +60,7 @@ define(
|
||||
this.defaultFormat :
|
||||
this.formatService.getFormat(key);
|
||||
|
||||
return isNaN(v) ? "" : formatter ? formatter.format(v) : String(v);
|
||||
return isNaN(v) ? "" : formatter.format(v);
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user