From 8434a67229632bebd819ff313ae9d996187dd9b4 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 26 Mar 2015 11:58:58 -0700 Subject: [PATCH 1/9] GUAC-1138: Add more spacing within and surrounding the filter box. --- .../src/main/webapp/app/manage/styles/sessions.css | 10 ++++++++-- .../webapp/app/manage/templates/manageSessions.html | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/guacamole/src/main/webapp/app/manage/styles/sessions.css b/guacamole/src/main/webapp/app/manage/styles/sessions.css index 0a0fbd8e9..96a991262 100644 --- a/guacamole/src/main/webapp/app/manage/styles/sessions.css +++ b/guacamole/src/main/webapp/app/manage/styles/sessions.css @@ -77,11 +77,17 @@ background-image: url('images/arrows/up.png'); } -.manage .sessions .filter{ +.manage .sessions .filter { + margin: 0.5em 0; +} + +.manage .sessions .filter-string { background-image: url('images/magnifier.png'); background-repeat: no-repeat; background-size: 1.75em; - padding-left: 1.75em; + background-position: 0.25em center; + padding: 0.5em; + padding-left: 2.25em; width: 100%; max-width: none; } diff --git a/guacamole/src/main/webapp/app/manage/templates/manageSessions.html b/guacamole/src/main/webapp/app/manage/templates/manageSessions.html index 26fc52b6c..875fb3f6f 100644 --- a/guacamole/src/main/webapp/app/manage/templates/manageSessions.html +++ b/guacamole/src/main/webapp/app/manage/templates/manageSessions.html @@ -36,8 +36,8 @@ THE SOFTWARE. -
- +
+
From 468a50de9e28ccd04d2e78af3c24bc159e47f722 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 26 Mar 2015 12:01:50 -0700 Subject: [PATCH 2/9] GUAC-1138: Generalize "pager" module into "list" module. --- guacamole/src/main/webapp/app/groupList/groupListModule.js | 2 +- .../src/main/webapp/app/{pager => list}/directives/guacPager.js | 2 +- .../webapp/app/{pager/pagerModule.js => list/listModule.js} | 2 +- guacamole/src/main/webapp/app/{pager => list}/styles/pager.css | 0 .../main/webapp/app/{pager => list}/templates/guacPager.html | 0 guacamole/src/main/webapp/app/manage/manageModule.js | 2 +- 6 files changed, 4 insertions(+), 4 deletions(-) rename guacamole/src/main/webapp/app/{pager => list}/directives/guacPager.js (99%) rename guacamole/src/main/webapp/app/{pager/pagerModule.js => list/listModule.js} (97%) rename guacamole/src/main/webapp/app/{pager => list}/styles/pager.css (100%) rename guacamole/src/main/webapp/app/{pager => list}/templates/guacPager.html (100%) diff --git a/guacamole/src/main/webapp/app/groupList/groupListModule.js b/guacamole/src/main/webapp/app/groupList/groupListModule.js index 084f3b931..57447fdb5 100644 --- a/guacamole/src/main/webapp/app/groupList/groupListModule.js +++ b/guacamole/src/main/webapp/app/groupList/groupListModule.js @@ -24,4 +24,4 @@ * Module for displaying the contents of a connection group, allowing the user * to select individual connections or groups. */ -angular.module('groupList', ['pager', 'rest']); +angular.module('groupList', ['list', 'rest']); diff --git a/guacamole/src/main/webapp/app/pager/directives/guacPager.js b/guacamole/src/main/webapp/app/list/directives/guacPager.js similarity index 99% rename from guacamole/src/main/webapp/app/pager/directives/guacPager.js rename to guacamole/src/main/webapp/app/list/directives/guacPager.js index 8074f1362..2f6be52a1 100644 --- a/guacamole/src/main/webapp/app/pager/directives/guacPager.js +++ b/guacamole/src/main/webapp/app/list/directives/guacPager.js @@ -24,7 +24,7 @@ * A directive which provides pagination controls, along with a paginated * subset of the elements of some given array. */ -angular.module('pager').directive('guacPager', [function guacPager() { +angular.module('list').directive('guacPager', [function guacPager() { return { restrict: 'E', diff --git a/guacamole/src/main/webapp/app/pager/pagerModule.js b/guacamole/src/main/webapp/app/list/listModule.js similarity index 97% rename from guacamole/src/main/webapp/app/pager/pagerModule.js rename to guacamole/src/main/webapp/app/list/listModule.js index 026a64286..0bcd6bbec 100644 --- a/guacamole/src/main/webapp/app/pager/pagerModule.js +++ b/guacamole/src/main/webapp/app/list/listModule.js @@ -23,4 +23,4 @@ /** * Module for displaying the contents of a list, split into multiple pages. */ -angular.module('pager', []); +angular.module('list', []); diff --git a/guacamole/src/main/webapp/app/pager/styles/pager.css b/guacamole/src/main/webapp/app/list/styles/pager.css similarity index 100% rename from guacamole/src/main/webapp/app/pager/styles/pager.css rename to guacamole/src/main/webapp/app/list/styles/pager.css diff --git a/guacamole/src/main/webapp/app/pager/templates/guacPager.html b/guacamole/src/main/webapp/app/list/templates/guacPager.html similarity index 100% rename from guacamole/src/main/webapp/app/pager/templates/guacPager.html rename to guacamole/src/main/webapp/app/list/templates/guacPager.html diff --git a/guacamole/src/main/webapp/app/manage/manageModule.js b/guacamole/src/main/webapp/app/manage/manageModule.js index e6fffae7b..69a7a1198 100644 --- a/guacamole/src/main/webapp/app/manage/manageModule.js +++ b/guacamole/src/main/webapp/app/manage/manageModule.js @@ -25,9 +25,9 @@ */ angular.module('manage', [ 'groupList', + 'list', 'locale', 'notification', - 'pager', 'rest', 'userMenu' ]); From a0468fb2e29bf2334bfbe61a1afd6bcb167ef6b9 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 26 Mar 2015 12:03:38 -0700 Subject: [PATCH 3/9] GUAC-1138: Move StableSort and FilterPattern into list module. --- guacamole/src/main/webapp/app/list/listModule.js | 3 ++- .../main/webapp/app/{manage => list}/types/FilterPattern.js | 2 +- .../src/main/webapp/app/{manage => list}/types/StableSort.js | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) rename guacamole/src/main/webapp/app/{manage => list}/types/FilterPattern.js (98%) rename guacamole/src/main/webapp/app/{manage => list}/types/StableSort.js (98%) diff --git a/guacamole/src/main/webapp/app/list/listModule.js b/guacamole/src/main/webapp/app/list/listModule.js index 0bcd6bbec..4273aca1f 100644 --- a/guacamole/src/main/webapp/app/list/listModule.js +++ b/guacamole/src/main/webapp/app/list/listModule.js @@ -21,6 +21,7 @@ */ /** - * Module for displaying the contents of a list, split into multiple pages. + * Module for displaying, sorting, and filtering the contents of a list, split + * into multiple pages. */ angular.module('list', []); diff --git a/guacamole/src/main/webapp/app/manage/types/FilterPattern.js b/guacamole/src/main/webapp/app/list/types/FilterPattern.js similarity index 98% rename from guacamole/src/main/webapp/app/manage/types/FilterPattern.js rename to guacamole/src/main/webapp/app/list/types/FilterPattern.js index 2aaeddc2e..722083eef 100644 --- a/guacamole/src/main/webapp/app/manage/types/FilterPattern.js +++ b/guacamole/src/main/webapp/app/list/types/FilterPattern.js @@ -23,7 +23,7 @@ /** * A service for defining the FilterPattern class. */ -angular.module('manage').factory('FilterPattern', [ +angular.module('list').factory('FilterPattern', [ function defineFilterPattern() { /** diff --git a/guacamole/src/main/webapp/app/manage/types/StableSort.js b/guacamole/src/main/webapp/app/list/types/StableSort.js similarity index 98% rename from guacamole/src/main/webapp/app/manage/types/StableSort.js rename to guacamole/src/main/webapp/app/list/types/StableSort.js index 36c21fc78..16b85bfed 100644 --- a/guacamole/src/main/webapp/app/manage/types/StableSort.js +++ b/guacamole/src/main/webapp/app/list/types/StableSort.js @@ -23,7 +23,7 @@ /** * A service for defining the StableSort class. */ -angular.module('manage').factory('StableSort', [ +angular.module('list').factory('StableSort', [ function defineStableSort() { /** From b582aa45ef1e7774d6d5df5619ef9f5de1fc39c3 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 26 Mar 2015 12:13:43 -0700 Subject: [PATCH 4/9] GUAC-1138: Fix guacPager template path. --- guacamole/src/main/webapp/app/list/directives/guacPager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guacamole/src/main/webapp/app/list/directives/guacPager.js b/guacamole/src/main/webapp/app/list/directives/guacPager.js index 2f6be52a1..6b9d59010 100644 --- a/guacamole/src/main/webapp/app/list/directives/guacPager.js +++ b/guacamole/src/main/webapp/app/list/directives/guacPager.js @@ -64,7 +64,7 @@ angular.module('list').directive('guacPager', [function guacPager() { }, - templateUrl: 'app/pager/templates/guacPager.html', + templateUrl: 'app/list/templates/guacPager.html', controller: ['$scope', function guacPagerController($scope) { /** From 647a1b15b31317970337f5b48e9bc2a4686ddf5b Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 26 Mar 2015 12:14:08 -0700 Subject: [PATCH 5/9] GUAC-1138: Add missing semicolon within guacPager controller. --- guacamole/src/main/webapp/app/list/directives/guacPager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guacamole/src/main/webapp/app/list/directives/guacPager.js b/guacamole/src/main/webapp/app/list/directives/guacPager.js index 6b9d59010..8031ddd4f 100644 --- a/guacamole/src/main/webapp/app/list/directives/guacPager.js +++ b/guacamole/src/main/webapp/app/list/directives/guacPager.js @@ -265,7 +265,7 @@ angular.module('list').directive('guacPager', [function guacPager() { * pageNumbers array, false otherwise. */ $scope.hasMorePagesBefore = function hasMorePagesBefore() { - var firstPageNumber = $scope.pageNumbers[0] + var firstPageNumber = $scope.pageNumbers[0]; return firstPageNumber !== $scope.firstPage; }; From 2df72c308c2d52a19edc507a361f0a32d546fecf Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 26 Mar 2015 13:17:23 -0700 Subject: [PATCH 6/9] GUAC-1138: Move filtering logic into own directive. --- .../webapp/app/list/directives/guacFilter.js | 108 ++++++++++++++++++ .../main/webapp/app/list/styles/filter.css | 36 ++++++ .../webapp/app/list/templates/guacFilter.html | 27 +++++ .../controllers/manageSessionsController.js | 20 ---- .../webapp/app/manage/styles/sessions.css | 15 --- .../app/manage/templates/manageSessions.html | 10 +- 6 files changed, 176 insertions(+), 40 deletions(-) create mode 100644 guacamole/src/main/webapp/app/list/directives/guacFilter.js create mode 100644 guacamole/src/main/webapp/app/list/styles/filter.css create mode 100644 guacamole/src/main/webapp/app/list/templates/guacFilter.html diff --git a/guacamole/src/main/webapp/app/list/directives/guacFilter.js b/guacamole/src/main/webapp/app/list/directives/guacFilter.js new file mode 100644 index 000000000..e1b498f81 --- /dev/null +++ b/guacamole/src/main/webapp/app/list/directives/guacFilter.js @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2015 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 which provides a filtering text input field which automatically + * produces a filtered subset of the elements of some given array. + */ +angular.module('list').directive('guacFilter', [function guacFilter() { + + return { + restrict: 'E', + replace: true, + scope: { + + /** + * The property to which a subset of the provided array will be + * assigned. + * + * @type Array + */ + filteredItems : '=', + + /** + * The placeholder text to display within the filter input field + * when no filter has been provided. + * + * @type String + */ + placeholder : '&', + + /** + * An array objects to filter. A subset of this array will be + * exposed as filteredItems. + * + * @type Array + */ + items : '&' + + }, + + templateUrl: 'app/list/templates/guacFilter.html', + controller: ['$scope', '$injector', function guacFilterController($scope, $injector) { + + // Required types + var FilterPattern = $injector.get('FilterPattern'); + + /** + * The pattern object to use when filtering items. + * + * @type FilterPattern + */ + var filterPattern = new FilterPattern(); + + /** + * The filter search string to use to restrict the displayed items. + * + * @type String + */ + $scope.searchString = null; + + /** + * Applies the current filter predicate, filtering all provided + * items and storing the result in filteredItems. + */ + var updateFilteredItems = function updateFilteredItems() { + + var items = $scope.items(); + if (items) + $scope.filteredItems = items.filter(filterPattern.predicate); + else + $scope.filteredItems = []; + + }; + + // Recompile and refilter when pattern is changed + $scope.$watch('searchString', function searchStringChanged(searchString) { + filterPattern.compile(searchString); + updateFilteredItems(); + }); + + // Refilter when items change + $scope.$watchCollection($scope.items, function itemsChanged() { + updateFilteredItems(); + }); + + }] + + }; +}]); diff --git a/guacamole/src/main/webapp/app/list/styles/filter.css b/guacamole/src/main/webapp/app/list/styles/filter.css new file mode 100644 index 000000000..b319750c7 --- /dev/null +++ b/guacamole/src/main/webapp/app/list/styles/filter.css @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2015 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. + */ + +.filter { + margin: 0.5em 0; +} + +.filter .search-string { + background-image: url('images/magnifier.png'); + background-repeat: no-repeat; + background-size: 1.75em; + background-position: 0.25em center; + padding: 0.5em; + padding-left: 2.25em; + width: 100%; + max-width: none; +} diff --git a/guacamole/src/main/webapp/app/list/templates/guacFilter.html b/guacamole/src/main/webapp/app/list/templates/guacFilter.html new file mode 100644 index 000000000..a5eeb0c19 --- /dev/null +++ b/guacamole/src/main/webapp/app/list/templates/guacFilter.html @@ -0,0 +1,27 @@ +
+ + + + + +
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageSessionsController.js b/guacamole/src/main/webapp/app/manage/controllers/manageSessionsController.js index aa81a16ff..3f80b325c 100644 --- a/guacamole/src/main/webapp/app/manage/controllers/manageSessionsController.js +++ b/guacamole/src/main/webapp/app/manage/controllers/manageSessionsController.js @@ -29,7 +29,6 @@ angular.module('manage').controller('manageSessionsController', ['$scope', '$inj // Required types var ActiveConnectionWrapper = $injector.get('ActiveConnectionWrapper'); var ConnectionGroup = $injector.get('ConnectionGroup'); - var FilterPattern = $injector.get('FilterPattern'); var StableSort = $injector.get('StableSort'); // Required services @@ -55,20 +54,6 @@ angular.module('manage').controller('manageSessionsController', ['$scope', '$inj */ $scope.wrappers = null; - /** - * The filter search string to use to restrict the displayed active sessions - * - * @type String - */ - $scope.filterSearchString = null; - - /** - * The pattern object to use when filtering active sessions. - * - * @type FilterPattern - */ - $scope.filterPattern = new FilterPattern(); - /** * StableSort instance which maintains the sort order of the visible * connection wrappers. @@ -361,9 +346,4 @@ angular.module('manage').controller('manageSessionsController', ['$scope', '$inj }; - // Recompile the filter pattern when changed - $scope.$watch('filterSearchString', function recompilePredicate(searchString) { - $scope.filterPattern.compile(searchString); - }); - }]); diff --git a/guacamole/src/main/webapp/app/manage/styles/sessions.css b/guacamole/src/main/webapp/app/manage/styles/sessions.css index 96a991262..30b486828 100644 --- a/guacamole/src/main/webapp/app/manage/styles/sessions.css +++ b/guacamole/src/main/webapp/app/manage/styles/sessions.css @@ -76,18 +76,3 @@ .manage table.session-list th.sort-primary.sort-descending:after { background-image: url('images/arrows/up.png'); } - -.manage .sessions .filter { - margin: 0.5em 0; -} - -.manage .sessions .filter-string { - background-image: url('images/magnifier.png'); - background-repeat: no-repeat; - background-size: 1.75em; - background-position: 0.25em center; - padding: 0.5em; - padding-left: 2.25em; - width: 100%; - max-width: none; -} diff --git a/guacamole/src/main/webapp/app/manage/templates/manageSessions.html b/guacamole/src/main/webapp/app/manage/templates/manageSessions.html index 875fb3f6f..1f45c462b 100644 --- a/guacamole/src/main/webapp/app/manage/templates/manageSessions.html +++ b/guacamole/src/main/webapp/app/manage/templates/manageSessions.html @@ -35,10 +35,10 @@ THE SOFTWARE.
- -
- -
+ + + @@ -83,7 +83,7 @@ THE SOFTWARE. + items="filteredWrappers | orderBy : wrapperOrder.predicate"> \ No newline at end of file From 5abd8326b2d9d20c9325b4dca0842b6bfded333b Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 26 Mar 2015 13:23:44 -0700 Subject: [PATCH 7/9] GUAC-1138: Move common sorting logic into StableSort. --- .../main/webapp/app/list/types/StableSort.js | 34 +++++++++++++++++++ .../controllers/manageSessionsController.js | 34 ------------------- .../app/manage/templates/manageSessions.html | 16 ++++----- 3 files changed, 42 insertions(+), 42 deletions(-) diff --git a/guacamole/src/main/webapp/app/list/types/StableSort.js b/guacamole/src/main/webapp/app/list/types/StableSort.js index 16b85bfed..0dcdc84a8 100644 --- a/guacamole/src/main/webapp/app/list/types/StableSort.js +++ b/guacamole/src/main/webapp/app/list/types/StableSort.js @@ -108,6 +108,40 @@ angular.module('list').factory('StableSort', [ }; + /** + * Returns whether the sort order is primarily determined by the given + * property. + * + * @param {String} property + * The name of the property to check. + * + * @returns {Boolean} + * true if the sort order is primarily determined by the given + * property, false otherwise. + */ + this.isSortedBy = function isSortedBy(property) { + return stableSort.primary === property; + }; + + /** + * Sets the primary sorting property to the given property, if not already + * set. If already set, the ascending/descending sort order is toggled. + * + * @param {String} property + * The name of the property to assign as the primary sorting property. + */ + this.togglePrimary = function togglePrimary(property) { + + // Sort in ascending order by new property, if different + if (!stableSort.isSortedBy(property)) + stableSort.reorder(property, false); + + // Otherwise, toggle sort order + else + stableSort.reorder(property, !stableSort.descending); + + }; + }; return StableSort; diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageSessionsController.js b/guacamole/src/main/webapp/app/manage/controllers/manageSessionsController.js index 3f80b325c..479f0223c 100644 --- a/guacamole/src/main/webapp/app/manage/controllers/manageSessionsController.js +++ b/guacamole/src/main/webapp/app/manage/controllers/manageSessionsController.js @@ -195,40 +195,6 @@ angular.module('manage').controller('manageSessionsController', ['$scope', '$inj }; - /** - * Returns whether the wrapped session list is sorted by the given - * property. - * - * @param {String} property - * The name of the property to check. - * - * @returns {Boolean} - * true if the wrapped session list is sorted by the given property, - * false otherwise. - */ - $scope.isSortedBy = function isSortedBy(property) { - return $scope.wrapperOrder.primary === property; - }; - - /** - * Sets the primary sorting property to the given property, if not already - * set. If already set, the ascending/descending sort order is toggled. - * - * @param {String} property - * The name of the property to assign as the primary sorting property. - */ - $scope.toggleSort = function toggleSort(property) { - - // Sort in ascending order by new property, if different - if (!$scope.isSortedBy(property)) - $scope.wrapperOrder.reorder(property, false); - - // Otherwise, toggle sort order - else - $scope.wrapperOrder.reorder(property, !$scope.wrapperOrder.descending); - - }; - /** * An action to be provided along with the object sent to showStatus which * closes the currently-shown status dialog. diff --git a/guacamole/src/main/webapp/app/manage/templates/manageSessions.html b/guacamole/src/main/webapp/app/manage/templates/manageSessions.html index 1f45c462b..b20d3e1e5 100644 --- a/guacamole/src/main/webapp/app/manage/templates/manageSessions.html +++ b/guacamole/src/main/webapp/app/manage/templates/manageSessions.html @@ -45,20 +45,20 @@ THE SOFTWARE. - - - - From 4f5c757b43eb04e33fb13cc7c9301bcb5df5f081 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 26 Mar 2015 14:28:51 -0700 Subject: [PATCH 8/9] GUAC-1138: Generalize sorting logic. --- .../webapp/app/index/styles/sorted-tables.css | 64 +++++++++++ .../app/list/directives/guacSortOrder.js | 104 ++++++++++++++++++ .../webapp/app/manage/styles/sessions.css | 44 -------- .../app/manage/templates/manageSessions.html | 14 +-- 4 files changed, 173 insertions(+), 53 deletions(-) create mode 100644 guacamole/src/main/webapp/app/index/styles/sorted-tables.css create mode 100644 guacamole/src/main/webapp/app/list/directives/guacSortOrder.js diff --git a/guacamole/src/main/webapp/app/index/styles/sorted-tables.css b/guacamole/src/main/webapp/app/index/styles/sorted-tables.css new file mode 100644 index 000000000..2c84bcae4 --- /dev/null +++ b/guacamole/src/main/webapp/app/index/styles/sorted-tables.css @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2015 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. + */ + +table.sorted { + border-collapse: collapse; +} + +table.sorted th { + background: rgba(0, 0, 0, 0.125); + font-weight: normal; +} + +table.sorted th, +table.sorted td { + border: 1px solid #AAA; + padding: 0.5em 1em; +} + +table.sorted th.sortable { + cursor: pointer; +} + +table.sorted th.sort-primary { + font-weight: bold; + padding-right: 0; +} + +table.sorted th.sort-primary:after { + + display: inline-block; + width: 1em; + height: 1em; + vertical-align: middle; + content: ' '; + + background-size: 1em 1em; + background-position: right center; + background-repeat: no-repeat; + background-image: url('images/arrows/down.png'); + +} + +table.sorted th.sort-primary.sort-descending:after { + background-image: url('images/arrows/up.png'); +} diff --git a/guacamole/src/main/webapp/app/list/directives/guacSortOrder.js b/guacamole/src/main/webapp/app/list/directives/guacSortOrder.js new file mode 100644 index 000000000..5bc131e2f --- /dev/null +++ b/guacamole/src/main/webapp/app/list/directives/guacSortOrder.js @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2015 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. + */ + +/** + * Updates the priority of the sorting property given by "guac-sort-property" + * within the StableSort object given by "guac-sort-order". The CSS classes + * "sort-primary" and "sort-descending" will be applied to the associated + * element depending on the priority and sort direction of the given property. + * + * The associated element will automatically be assigned the "sortable" CSS + * class. + */ +angular.module('list').directive('guacSortOrder', [function guacFocus() { + + return { + restrict: 'A', + + link: function linkGuacSortOrder($scope, $element, $attrs) { + + /** + * The object defining the sorting order. + * + * @type StableSort + */ + var sortOrder = $scope.$eval($attrs.guacSortOrder); + + /** + * The name of the property whose priority within the sort order + * is controlled by this directive. + * + * @type String + */ + var sortProperty = $scope.$eval($attrs.guacSortProperty); + + /** + * Returns whether the sort property defined via the + * "guac-sort-property" attribute is the primary sort property of + * the associated sort order. + * + * @returns {Boolean} + * true if the sort property defined via the + * "guac-sort-property" attribute is the primary sort property, + * false otherwise. + */ + var isPrimary = function isPrimary() { + return sortOrder.primary === sortProperty; + }; + + /** + * Returns whether the primary property of the sort order is + * sorted in descending order. + * + * @returns {Boolean} + * true if the primary property of the sort order is sorted in + * descending order, false otherwise. + */ + var isDescending = function isDescending() { + return sortOrder.descending; + }; + + // Assign "sortable" class to associated element + $element.addClass('sortable'); + + // Add/remove "sort-primary" class depending on sort order + $scope.$watch(isPrimary, function primaryChanged(primary) { + $element.toggleClass('sort-primary', primary); + }); + + // Add/remove "sort-descending" class depending on sort order + $scope.$watch(isDescending, function descendingChanged(descending) { + $element.toggleClass('sort-descending', descending); + }); + + // Update sort order when clicked + $element[0].addEventListener('click', function clicked() { + $scope.$evalAsync(function updateSortOrder() { + sortOrder.togglePrimary(sortProperty); + }); + }); + + } // end guacSortOrder link function + + }; + +}]); diff --git a/guacamole/src/main/webapp/app/manage/styles/sessions.css b/guacamole/src/main/webapp/app/manage/styles/sessions.css index 30b486828..ad8a7307e 100644 --- a/guacamole/src/main/webapp/app/manage/styles/sessions.css +++ b/guacamole/src/main/webapp/app/manage/styles/sessions.css @@ -22,57 +22,13 @@ .manage table.session-list { width: 100%; - border-collapse: collapse; } .manage table.session-list tr.session:hover { background: #CDA; } -.manage table.session-list th { - background: rgba(0, 0, 0, 0.125); - font-weight: normal; -} - -.manage table.session-list th, -.manage table.session-list td { - border: 1px solid #AAA; - padding: 0.5em 1em; -} - .manage table.session-list .select-session { min-width: 2em; text-align: center; } - -.manage table.session-list th { - cursor: pointer; -} - -.manage table.session-list th.select-session { - cursor: auto; -} - -.manage table.session-list th.sort-primary { - font-weight: bold; - padding-right: 0; -} - -.manage table.session-list th.sort-primary:after { - - display: inline-block; - width: 1em; - height: 1em; - vertical-align: middle; - content: ' '; - - background-size: 1em 1em; - background-position: right center; - background-repeat: no-repeat; - background-image: url('images/arrows/down.png'); - -} - -.manage table.session-list th.sort-primary.sort-descending:after { - background-image: url('images/arrows/up.png'); -} diff --git a/guacamole/src/main/webapp/app/manage/templates/manageSessions.html b/guacamole/src/main/webapp/app/manage/templates/manageSessions.html index b20d3e1e5..84d9fe6d2 100644 --- a/guacamole/src/main/webapp/app/manage/templates/manageSessions.html +++ b/guacamole/src/main/webapp/app/manage/templates/manageSessions.html @@ -41,24 +41,20 @@ THE SOFTWARE. placeholder="'MANAGE_SESSION.FIELD_PLACEHOLDER_FILTER' | translate"> -
+ {{'MANAGE_SESSION.TABLE_HEADER_SESSION_USERNAME' | translate}} + {{'MANAGE_SESSION.TABLE_HEADER_SESSION_STARTDATE' | translate}} + {{'MANAGE_SESSION.TABLE_HEADER_SESSION_REMOTEHOST' | translate}} + {{'MANAGE_SESSION.TABLE_HEADER_SESSION_CONNECTION_NAME' | translate}}
+
- - - - From fc0908f9f39000bd605799117cfbf22fea0ff6f6 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 26 Mar 2015 14:30:02 -0700 Subject: [PATCH 9/9] GUAC-1138: Rename StableSort to SortOrder. --- .../app/list/directives/guacSortOrder.js | 4 +-- .../types/{StableSort.js => SortOrder.js} | 32 +++++++++---------- .../controllers/manageSessionsController.js | 8 ++--- 3 files changed, 22 insertions(+), 22 deletions(-) rename guacamole/src/main/webapp/app/list/types/{StableSort.js => SortOrder.js} (84%) diff --git a/guacamole/src/main/webapp/app/list/directives/guacSortOrder.js b/guacamole/src/main/webapp/app/list/directives/guacSortOrder.js index 5bc131e2f..ea5a5c9fa 100644 --- a/guacamole/src/main/webapp/app/list/directives/guacSortOrder.js +++ b/guacamole/src/main/webapp/app/list/directives/guacSortOrder.js @@ -22,7 +22,7 @@ /** * Updates the priority of the sorting property given by "guac-sort-property" - * within the StableSort object given by "guac-sort-order". The CSS classes + * within the SortOrder object given by "guac-sort-order". The CSS classes * "sort-primary" and "sort-descending" will be applied to the associated * element depending on the priority and sort direction of the given property. * @@ -39,7 +39,7 @@ angular.module('list').directive('guacSortOrder', [function guacFocus() { /** * The object defining the sorting order. * - * @type StableSort + * @type SortOrder */ var sortOrder = $scope.$eval($attrs.guacSortOrder); diff --git a/guacamole/src/main/webapp/app/list/types/StableSort.js b/guacamole/src/main/webapp/app/list/types/SortOrder.js similarity index 84% rename from guacamole/src/main/webapp/app/list/types/StableSort.js rename to guacamole/src/main/webapp/app/list/types/SortOrder.js index 0dcdc84a8..86580b8ca 100644 --- a/guacamole/src/main/webapp/app/list/types/StableSort.js +++ b/guacamole/src/main/webapp/app/list/types/SortOrder.js @@ -21,10 +21,10 @@ */ /** - * A service for defining the StableSort class. + * A service for defining the SortOrder class. */ -angular.module('list').factory('StableSort', [ - function defineStableSort() { +angular.module('list').factory('SortOrder', [ + function defineSortOrder() { /** * Maintains a sorting predicate as required by the Angular orderBy filter. @@ -35,14 +35,14 @@ angular.module('list').factory('StableSort', [ * @param {String[]} predicate * The properties to sort by, in order of precidence. */ - var StableSort = function StableSort(predicate) { + var SortOrder = function SortOrder(predicate) { /** * Reference to this instance. * - * @type StableSort + * @type SortOrder */ - var stableSort = this; + var sortOrder = this; /** * The current sorting predicate. @@ -91,20 +91,20 @@ angular.module('list').factory('StableSort', [ var descendingName = '-' + name; // Remove requested property from current predicate - stableSort.predicate = stableSort.predicate.filter(function notRequestedProperty(current) { + sortOrder.predicate = sortOrder.predicate.filter(function notRequestedProperty(current) { return current !== ascendingName && current !== descendingName; }); // Add property to beginning of predicate if (descending) - stableSort.predicate.unshift(descendingName); + sortOrder.predicate.unshift(descendingName); else - stableSort.predicate.unshift(ascendingName); + sortOrder.predicate.unshift(ascendingName); // Update sorted state - stableSort.primary = name; - stableSort.descending = !!descending; + sortOrder.primary = name; + sortOrder.descending = !!descending; }; @@ -120,7 +120,7 @@ angular.module('list').factory('StableSort', [ * property, false otherwise. */ this.isSortedBy = function isSortedBy(property) { - return stableSort.primary === property; + return sortOrder.primary === property; }; /** @@ -133,17 +133,17 @@ angular.module('list').factory('StableSort', [ this.togglePrimary = function togglePrimary(property) { // Sort in ascending order by new property, if different - if (!stableSort.isSortedBy(property)) - stableSort.reorder(property, false); + if (!sortOrder.isSortedBy(property)) + sortOrder.reorder(property, false); // Otherwise, toggle sort order else - stableSort.reorder(property, !stableSort.descending); + sortOrder.reorder(property, !sortOrder.descending); }; }; - return StableSort; + return SortOrder; }]); \ No newline at end of file diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageSessionsController.js b/guacamole/src/main/webapp/app/manage/controllers/manageSessionsController.js index 479f0223c..ccd264072 100644 --- a/guacamole/src/main/webapp/app/manage/controllers/manageSessionsController.js +++ b/guacamole/src/main/webapp/app/manage/controllers/manageSessionsController.js @@ -29,7 +29,7 @@ angular.module('manage').controller('manageSessionsController', ['$scope', '$inj // Required types var ActiveConnectionWrapper = $injector.get('ActiveConnectionWrapper'); var ConnectionGroup = $injector.get('ConnectionGroup'); - var StableSort = $injector.get('StableSort'); + var SortOrder = $injector.get('SortOrder'); // Required services var activeConnectionService = $injector.get('activeConnectionService'); @@ -55,12 +55,12 @@ angular.module('manage').controller('manageSessionsController', ['$scope', '$inj $scope.wrappers = null; /** - * StableSort instance which maintains the sort order of the visible + * SortOrder instance which maintains the sort order of the visible * connection wrappers. * - * @type StableSort + * @type SortOrder */ - $scope.wrapperOrder = new StableSort([ + $scope.wrapperOrder = new SortOrder([ 'activeConnection.username', 'activeConnection.startDate', 'activeConnection.remoteHost',
+ {{'MANAGE_SESSION.TABLE_HEADER_SESSION_USERNAME' | translate}} + {{'MANAGE_SESSION.TABLE_HEADER_SESSION_STARTDATE' | translate}} + {{'MANAGE_SESSION.TABLE_HEADER_SESSION_REMOTEHOST' | translate}} + {{'MANAGE_SESSION.TABLE_HEADER_SESSION_CONNECTION_NAME' | translate}}