From 5b31b206a761e9b422bc5c38ad6d571a3040fb5c Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 29 Nov 2014 19:18:38 -0800 Subject: [PATCH] GUAC-605: Add guacNotification directive. --- .../src/main/webapp/app/index/indexModule.js | 3 +- .../directives/guacNotification.js | 151 ++++++++++++++++++ .../app/notification/notificationModule.js | 26 +++ .../app/notification/styles/notification.css | 102 ++++++++++++ .../templates/guacNotification.html | 47 ++++++ 5 files changed, 328 insertions(+), 1 deletion(-) create mode 100644 guacamole/src/main/webapp/app/notification/directives/guacNotification.js create mode 100644 guacamole/src/main/webapp/app/notification/notificationModule.js create mode 100644 guacamole/src/main/webapp/app/notification/styles/notification.css create mode 100644 guacamole/src/main/webapp/app/notification/templates/guacNotification.html diff --git a/guacamole/src/main/webapp/app/index/indexModule.js b/guacamole/src/main/webapp/app/index/indexModule.js index 1eb80c9fd..2911a14c2 100644 --- a/guacamole/src/main/webapp/app/index/indexModule.js +++ b/guacamole/src/main/webapp/app/index/indexModule.js @@ -23,4 +23,5 @@ /** * The module for the root of the application. */ -angular.module('index', ['ngRoute', 'pascalprecht.translate', 'auth', 'home', 'manage', 'login', 'client']); +angular.module('index', ['ngRoute', 'pascalprecht.translate', + 'auth', 'home', 'manage', 'login', 'client', 'notification']); diff --git a/guacamole/src/main/webapp/app/notification/directives/guacNotification.js b/guacamole/src/main/webapp/app/notification/directives/guacNotification.js new file mode 100644 index 000000000..b37ff8ffd --- /dev/null +++ b/guacamole/src/main/webapp/app/notification/directives/guacNotification.js @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2014 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * A directive for the guacamole client. + */ +angular.module('notification').directive('guacNotification', [function guacNotification() { + + return { + restrict: 'E', + replace: true, + scope: { + + /** + * The CSS class to apply to the notification. + * + * @type String + */ + className : '=', + + /** + * The title of the notification. + * + * @type String + */ + title : '=', + + /** + * The body text of the notification. + * + * @type String + */ + text : '=', + + /** + * The text to use for displaying the countdown. For the sake of + * i18n, the variable REMAINING will be applied within the + * translation string for formatting plurals, etc. + * + * @type String + * @example + * "Only {REMAINING} {REMAINING, plural, one{second} other{seconds}} remain." + */ + countdownText : '=', + + /** + * The number of seconds to wait before automatically calling the + * default callback. + * + * @type Number + */ + countdown : '=', + + /** + * The function to call when timeRemaining expires. If timeRemaining + * is not set, this does not apply. + * + * @type Function + */ + defaultCallback : '=', + + /** + * Arbitrary value denoting how much progress has been made + * in some ongoing task that this notification represents. + * + * @type Number + */ + progress : '=', + + /** + * Array of name/callback pairs for each action the user is allowed + * to take once the notification is shown. + * + * @type Array + * @example + * [ + * { + * name : "Action 1 name", + * callback : actionCallback1 + * }, + * { + * name : "Action 2 text", + * callback : actionCallback2 + * } + * ] + */ + actions : '=' + + }, + + templateUrl: 'app/notification/templates/guacNotification.html', + controller: ['$scope', '$interval', function guacNotificationController($scope, $interval) { + + // Set countdown interval when associated property is set + $scope.$watch("countdown", function resetTimeRemaining(countdown) { + + $scope.timeRemaining = countdown; + + // Clean up any existing interval + if ($scope.interval) + $interval.cancel($scope.interval); + + // Update and handle countdown, if provided + if ($scope.timeRemaining) { + + $scope.interval = $interval(function updateTimeRemaining() { + + // Update time remaining + $scope.timeRemaining--; + + // Call countdown callback when time remaining expires + if ($scope.timeRemaining === 0 && $scope.defaultCallback) + $scope.defaultCallback(); + + }, 1000, $scope.timeRemaining); + + } + + }); + + // Clean up interval upon destruction + $scope.$on("$destroy", function destroyNotification() { + + if ($scope.interval) + $interval.cancel($scope.interval); + + }); + + }] + + }; +}]); \ No newline at end of file diff --git a/guacamole/src/main/webapp/app/notification/notificationModule.js b/guacamole/src/main/webapp/app/notification/notificationModule.js new file mode 100644 index 000000000..54c64fdfb --- /dev/null +++ b/guacamole/src/main/webapp/app/notification/notificationModule.js @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2014 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * The module for code used to display arbitrary notifications. + */ +angular.module('notification', []); diff --git a/guacamole/src/main/webapp/app/notification/styles/notification.css b/guacamole/src/main/webapp/app/notification/styles/notification.css new file mode 100644 index 000000000..9322773d2 --- /dev/null +++ b/guacamole/src/main/webapp/app/notification/styles/notification.css @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2013 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +.notification { + border: 1px solid rgba(0, 0, 0, 0.125); + box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.125); + background: white; + color: black; +} + +.notification .body { + margin: 0.5em; +} + +.notification .buttons { + margin: 0.5em; +} + +@keyframes notification-progress { + from {background-position: 0px 0px;} + to {background-position: 64px 0px;} +} + +@-webkit-keyframes notification-progress { + from {background-position: 0px 0px;} + to {background-position: 64px 0px;} +} + +.notification .title-bar { + font-size: 1.25em; + font-weight: bold; + + text-transform: uppercase; + border-bottom: 1px solid rgba(0, 0, 0, 0.125); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.125); + background: rgba(0, 0, 0, 0.04); + + padding: 0.5em; + margin-bottom: 1em; +} + +.notification .progress .bar { + background: #A3D655; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 0; + box-shadow: inset 1px 1px 0 rgba(255, 255, 255, 0.5), + inset -1px -1px 0 rgba( 0, 0, 0, 0.1), + 1px 1px 0 gray; +} + +.notification .progress { + + width: 100%; + background: #C2C2C2 url('images/progress.png'); + background-size: 16px 16px; + -moz-background-size: 16px 16px; + -webkit-background-size: 16px 16px; + -khtml-background-size: 16px 16px; + + animation-name: notification-progress; + animation-duration: 2s; + animation-timing-function: linear; + animation-iteration-count: infinite; + + -webkit-animation-name: notification-progress; + -webkit-animation-duration: 2s; + -webkit-animation-timing-function: linear; + -webkit-animation-iteration-count: infinite; + + padding: 0.25em; + + border: 1px solid gray; + -moz-border-radius: 0.2em; + -webkit-border-radius: 0.2em; + -khtml-border-radius: 0.2em; + border-radius: 0.2em; + + position: relative; + +} diff --git a/guacamole/src/main/webapp/app/notification/templates/guacNotification.html b/guacamole/src/main/webapp/app/notification/templates/guacNotification.html new file mode 100644 index 000000000..710c9986f --- /dev/null +++ b/guacamole/src/main/webapp/app/notification/templates/guacNotification.html @@ -0,0 +1,47 @@ +
+ + + +
+
{{title | translate}}
+
+ +
+ + +

{{text | translate}}

+ + +
{{progress}}
+ + +

{{countdownText | translate:"{ REMAINING: timeRemaining}"}}

+ +
+ + +
+ +
+ +
\ No newline at end of file