mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
Merge pull request #93 from glyptodon/paginate-lists
GUAC-1099: Paginate list output in Guacamole UI
This commit is contained in:
@@ -21,7 +21,8 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* A directive which displays the contents of a connection group.
|
||||
* A directive which displays the contents of a connection group within an
|
||||
* automatically-paginated view.
|
||||
*/
|
||||
angular.module('groupList').directive('guacGroupList', [function guacGroupList() {
|
||||
|
||||
@@ -75,7 +76,14 @@ angular.module('groupList').directive('guacGroupList', [function guacGroupList()
|
||||
*
|
||||
* @type Boolean
|
||||
*/
|
||||
showRootGroup : '='
|
||||
showRootGroup : '=',
|
||||
|
||||
/**
|
||||
* The maximum number of connections or groups to show per page.
|
||||
*
|
||||
* @type Number
|
||||
*/
|
||||
pageSize : '='
|
||||
|
||||
},
|
||||
|
||||
|
@@ -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', ['rest']);
|
||||
angular.module('groupList', ['pager', 'rest']);
|
||||
|
@@ -51,6 +51,13 @@
|
||||
|
||||
</script>
|
||||
|
||||
<div class="list-item" ng-repeat="item in rootItem.children | orderBy : 'name'" ng-include="'nestedGroup.html'"></div>
|
||||
<!-- Root-level connections / groups -->
|
||||
<div class="group-list-page">
|
||||
<div class="list-item" ng-repeat="item in childrenPage" ng-include="'nestedGroup.html'"></div>
|
||||
</div>
|
||||
|
||||
<!-- Pager for connections / groups -->
|
||||
<guac-pager page="childrenPage" items="rootItem.children | orderBy : 'name'"
|
||||
page-size="pageSize"></guac-pager>
|
||||
|
||||
</div>
|
||||
|
@@ -41,7 +41,8 @@
|
||||
<guac-group-list
|
||||
connection-group="rootConnectionGroup"
|
||||
connection-template="'app/home/templates/connection.html'"
|
||||
connection-group-template="'app/home/templates/connectionGroup.html'"></guac-group-list>
|
||||
connection-group-template="'app/home/templates/connectionGroup.html'"
|
||||
page-size="20"></guac-group-list>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@@ -289,51 +289,6 @@ div.section {
|
||||
background-image: url('images/group-icons/guac-open.png');
|
||||
}
|
||||
|
||||
/*
|
||||
* Settings formatting
|
||||
*/
|
||||
|
||||
.form dt,
|
||||
.settings dt {
|
||||
border-bottom: 1px dotted #AAA;
|
||||
padding-bottom: 0.25em;
|
||||
}
|
||||
|
||||
.form dd,
|
||||
.settings dd {
|
||||
margin: 1.5em;
|
||||
margin-left: 2.5em;
|
||||
font-size: 0.75em;
|
||||
}
|
||||
|
||||
.connections input.name,
|
||||
.users input.name {
|
||||
max-width: 80%;
|
||||
width: 20em;
|
||||
}
|
||||
|
||||
.connection-list,
|
||||
.user-list {
|
||||
border: 1px solid rgba(0, 0, 0, 0.25);
|
||||
height: 20em;
|
||||
-moz-border-radius: 0.2em;
|
||||
-webkit-border-radius: 0.2em;
|
||||
-khtml-border-radius: 0.2em;
|
||||
border-radius: 0.2em;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.connections .add-connection,
|
||||
.connections .add-connection-group,
|
||||
.users .add-user {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.connection-add-form,
|
||||
.user-add-form {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
div.logout-panel {
|
||||
padding: 0.45em;
|
||||
text-align: right;
|
||||
@@ -346,66 +301,7 @@ div.logout-panel {
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
.first-page,
|
||||
.prev-page,
|
||||
.set-page,
|
||||
.next-page,
|
||||
.last-page {
|
||||
cursor: pointer;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.first-page.disabled,
|
||||
.prev-page.disabled,
|
||||
.set-page.disabled,
|
||||
.next-page.disabled,
|
||||
.last-page.disabled {
|
||||
cursor: auto;
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
.set-page,
|
||||
.more-pages {
|
||||
display: inline-block;
|
||||
padding: 0.25em;
|
||||
text-align: center;
|
||||
min-width: 1.25em;
|
||||
}
|
||||
|
||||
.set-page {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.set-page.current {
|
||||
cursor: auto;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
-moz-border-radius: 0.2em;
|
||||
-webkit-border-radius: 0.2em;
|
||||
-khtml-border-radius: 0.2em;
|
||||
border-radius: 0.2em;
|
||||
}
|
||||
|
||||
.icon.first-page {
|
||||
background-image: url('images/action-icons/guac-first-page.png');
|
||||
}
|
||||
|
||||
.icon.prev-page {
|
||||
background-image: url('images/action-icons/guac-prev-page.png');
|
||||
}
|
||||
|
||||
.icon.next-page {
|
||||
background-image: url('images/action-icons/guac-next-page.png');
|
||||
}
|
||||
|
||||
.icon.last-page {
|
||||
background-image: url('images/action-icons/guac-last-page.png');
|
||||
}
|
||||
|
||||
.buttons,
|
||||
.list-pager-buttons {
|
||||
.buttons {
|
||||
text-align: center;
|
||||
margin: 1em;
|
||||
}
|
||||
|
@@ -23,5 +23,5 @@
|
||||
/**
|
||||
* The module for the administration functionality.
|
||||
*/
|
||||
angular.module('manage', ['groupList', 'locale', 'rest']);
|
||||
angular.module('manage', ['groupList', 'locale', 'pager', 'rest']);
|
||||
|
||||
|
@@ -20,6 +20,12 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
button.add-user,
|
||||
a.button.add-connection,
|
||||
a.button.add-connection-group {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
button.add-user {
|
||||
|
||||
background-image: url('images/action-icons/guac-user-add.png');
|
||||
|
@@ -30,3 +30,12 @@
|
||||
text-align: center;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.manage .user-add-form {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.manage .user-add-form input.name {
|
||||
max-width: 80%;
|
||||
width: 20em;
|
||||
}
|
||||
|
31
guacamole/src/main/webapp/app/manage/styles/lists.css
Normal file
31
guacamole/src/main/webapp/app/manage/styles/lists.css
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
.manage .connection-list .group-list-page,
|
||||
.manage .user-list {
|
||||
border: 1px solid rgba(0, 0, 0, 0.25);
|
||||
min-height: 15em;
|
||||
-moz-border-radius: 0.2em;
|
||||
-webkit-border-radius: 0.2em;
|
||||
-khtml-border-radius: 0.2em;
|
||||
border-radius: 0.2em;
|
||||
}
|
@@ -44,7 +44,7 @@ THE SOFTWARE.
|
||||
|
||||
<!-- List of users this user has access to -->
|
||||
<div class="user-list">
|
||||
<div ng-repeat="user in users | orderBy : 'username'" class="user list-item">
|
||||
<div ng-repeat="user in userPage" class="user list-item">
|
||||
<a ng-href="#/manage/users/{{user.username}}">
|
||||
<div class="caption">
|
||||
<div class="icon user"></div>
|
||||
@@ -53,6 +53,10 @@ THE SOFTWARE.
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pager controls for user list -->
|
||||
<guac-pager page="userPage" items="users | orderBy : 'username'"></guac-pager>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@@ -68,7 +68,8 @@ THE SOFTWARE.
|
||||
context="groupListContext"
|
||||
connection-group="rootGroup"
|
||||
connection-template="'app/manage/templates/connectionPermission.html'"
|
||||
connection-group-template="'app/manage/templates/connectionGroupPermission.html'"/>
|
||||
connection-group-template="'app/manage/templates/connectionGroupPermission.html'"
|
||||
page-size="20"/>
|
||||
</div>
|
||||
|
||||
<!-- Form action buttons -->
|
||||
|
303
guacamole/src/main/webapp/app/pager/directives/guacPager.js
Normal file
303
guacamole/src/main/webapp/app/pager/directives/guacPager.js
Normal file
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
* 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 pagination controls, along with a paginated
|
||||
* subset of the elements of some given array.
|
||||
*/
|
||||
angular.module('pager').directive('guacPager', [function guacPager() {
|
||||
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
scope: {
|
||||
|
||||
/**
|
||||
* The property to which a subset of the provided array will be
|
||||
* assigned.
|
||||
*
|
||||
* @type Array
|
||||
*/
|
||||
page : '=',
|
||||
|
||||
/**
|
||||
* The maximum number of items per page.
|
||||
*
|
||||
* @type Number
|
||||
*/
|
||||
pageSize : '&',
|
||||
|
||||
/**
|
||||
* The maximum number of page choices to provide, regardless of the
|
||||
* total number of pages.
|
||||
*
|
||||
* @type Number
|
||||
*/
|
||||
pageCount : '&',
|
||||
|
||||
/**
|
||||
* An array objects to paginate. Subsets of this array will be
|
||||
* exposed as pages.
|
||||
*
|
||||
* @type Array
|
||||
*/
|
||||
items : '&'
|
||||
|
||||
},
|
||||
|
||||
templateUrl: 'app/pager/templates/guacPager.html',
|
||||
controller: ['$scope', function guacPagerController($scope) {
|
||||
|
||||
/**
|
||||
* The default size of a page, if not provided via the pageSize
|
||||
* attribute.
|
||||
*
|
||||
* @type Number
|
||||
*/
|
||||
var DEFAULT_PAGE_SIZE = 10;
|
||||
|
||||
/**
|
||||
* The default maximum number of page choices to provide, if a
|
||||
* value is not providede via the pageCount attribute.
|
||||
*
|
||||
* @type Number
|
||||
*/
|
||||
var DEFAULT_PAGE_COUNT = 11;
|
||||
|
||||
/**
|
||||
* An array of arrays, where the Nth array contains the contents of
|
||||
* the Nth page.
|
||||
*
|
||||
* @type Array[]
|
||||
*/
|
||||
var pages = [];
|
||||
|
||||
/**
|
||||
* The number of the first selectable page.
|
||||
*
|
||||
* @type Number;
|
||||
*/
|
||||
$scope.firstPage = 1;
|
||||
|
||||
/**
|
||||
* The number of the page immediately before the currently-selected
|
||||
* page.
|
||||
*
|
||||
* @type Number;
|
||||
*/
|
||||
$scope.previousPage = 1;
|
||||
|
||||
/**
|
||||
* The number of the currently-selected page.
|
||||
*
|
||||
* @type Number;
|
||||
*/
|
||||
$scope.currentPage = 1;
|
||||
|
||||
/**
|
||||
* The number of the page immediately after the currently-selected
|
||||
* page.
|
||||
*
|
||||
* @type Number;
|
||||
*/
|
||||
$scope.nextPage = 1;
|
||||
|
||||
/**
|
||||
* The number of the last selectable page.
|
||||
*
|
||||
* @type Number;
|
||||
*/
|
||||
$scope.lastPage = 1;
|
||||
|
||||
/**
|
||||
* An array of relevant page numbers that the user may want to jump
|
||||
* to directly.
|
||||
*
|
||||
* @type Number[]
|
||||
*/
|
||||
$scope.pageNumbers = [];
|
||||
|
||||
/**
|
||||
* Updates the displayed page number choices.
|
||||
*/
|
||||
var updatePageNumbers = function updatePageNumbers() {
|
||||
|
||||
// Get page count
|
||||
var pageCount = $scope.pageCount() || DEFAULT_PAGE_COUNT;
|
||||
|
||||
// Determine start/end of page window
|
||||
var windowStart = $scope.currentPage - (pageCount - 1) / 2;
|
||||
var windowEnd = windowStart + pageCount - 1;
|
||||
|
||||
// Shift window as necessary if it extends beyond the first page
|
||||
if (windowStart < $scope.firstPage) {
|
||||
windowEnd = Math.min($scope.lastPage, windowEnd - windowStart + $scope.firstPage);
|
||||
windowStart = $scope.firstPage;
|
||||
}
|
||||
|
||||
// Shift window as necessary if it extends beyond the last page
|
||||
else if (windowEnd > $scope.lastPage) {
|
||||
windowStart = Math.max(1, windowStart - windowEnd + $scope.lastPage);
|
||||
windowEnd = $scope.lastPage;
|
||||
}
|
||||
|
||||
// Generate list of relevant page numbers
|
||||
$scope.pageNumbers = [];
|
||||
for (var pageNumber = windowStart; pageNumber <= windowEnd; pageNumber++)
|
||||
$scope.pageNumbers.push(pageNumber);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Iterates through the bound items array, splitting it into pages
|
||||
* based on the current page size.
|
||||
*/
|
||||
var updatePages = function updatePages() {
|
||||
|
||||
// Get current items and page size
|
||||
var items = $scope.items();
|
||||
var pageSize = $scope.pageSize() || DEFAULT_PAGE_SIZE;
|
||||
|
||||
// Clear current pages
|
||||
pages = [];
|
||||
|
||||
// Only split into pages if items actually exist
|
||||
if (items) {
|
||||
|
||||
// Split into pages of pageSize items each
|
||||
for (var i = 0; i < items.length; i += pageSize)
|
||||
pages.push(items.slice(i, i + pageSize));
|
||||
|
||||
}
|
||||
|
||||
// Update minimum and maximum values
|
||||
$scope.firstPage = 1;
|
||||
$scope.lastPage = pages.length;
|
||||
|
||||
// Select an appropriate page
|
||||
var adjustedCurrentPage = Math.min($scope.lastPage, Math.max($scope.firstPage, $scope.currentPage));
|
||||
$scope.selectPage(adjustedCurrentPage);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Selects the page having the given number, assigning that page to
|
||||
* the property bound to the page attribute. If no such page
|
||||
* exists, the property will be set to undefined instead. Valid
|
||||
* page numbers begin at 1.
|
||||
*
|
||||
* @param {Number} page
|
||||
* The number of the page to select. Valid page numbers begin
|
||||
* at 1.
|
||||
*/
|
||||
$scope.selectPage = function selectPage(page) {
|
||||
|
||||
// Select the chosen page
|
||||
$scope.currentPage = page;
|
||||
$scope.page = pages[page-1];
|
||||
|
||||
// Update next/previous page numbers
|
||||
$scope.nextPage = Math.min($scope.lastPage, $scope.currentPage + 1);
|
||||
$scope.previousPage = Math.max($scope.firstPage, $scope.currentPage - 1);
|
||||
|
||||
// Update which page numbers are shown
|
||||
updatePageNumbers();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether the given page number can be legally selected
|
||||
* via selectPage(), resulting in a different page being shown.
|
||||
*
|
||||
* @param {Number} page
|
||||
* The page number to check.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
* true if the page having the given number can be selected,
|
||||
* false otherwise.
|
||||
*/
|
||||
$scope.canSelectPage = function canSelectPage(page) {
|
||||
return page !== $scope.currentPage
|
||||
&& page >= $scope.firstPage
|
||||
&& page <= $scope.lastPage;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether the page having the given number is currently
|
||||
* selected.
|
||||
*
|
||||
* @param {Number} page
|
||||
* The page number to check.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
* true if the page having the given number is currently
|
||||
* selected, false otherwise.
|
||||
*/
|
||||
$scope.isSelected = function isSelected(page) {
|
||||
return page === $scope.currentPage;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether pages exist before the first page listed in the
|
||||
* pageNumbers array.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
* true if pages exist before the first page listed in the
|
||||
* pageNumbers array, false otherwise.
|
||||
*/
|
||||
$scope.hasMorePagesBefore = function hasMorePagesBefore() {
|
||||
var firstPageNumber = $scope.pageNumbers[0]
|
||||
return firstPageNumber !== $scope.firstPage;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether pages exist after the last page listed in the
|
||||
* pageNumbers array.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
* true if pages exist after the last page listed in the
|
||||
* pageNumbers array, false otherwise.
|
||||
*/
|
||||
$scope.hasMorePagesAfter = function hasMorePagesAfter() {
|
||||
var lastPageNumber = $scope.pageNumbers[$scope.pageNumbers.length - 1];
|
||||
return lastPageNumber !== $scope.lastPage;
|
||||
};
|
||||
|
||||
// Update available pages when available items are changed
|
||||
$scope.$watchCollection($scope.items, function itemsChanged() {
|
||||
updatePages();
|
||||
});
|
||||
|
||||
// Update available pages when page size is changed
|
||||
$scope.$watch($scope.pageSize, function pageSizeChanged() {
|
||||
updatePages();
|
||||
});
|
||||
|
||||
// Update available page numbers when page count is changed
|
||||
$scope.$watch($scope.pageCount, function pageCountChanged() {
|
||||
updatePageNumbers();
|
||||
});
|
||||
|
||||
}]
|
||||
|
||||
};
|
||||
}]);
|
26
guacamole/src/main/webapp/app/pager/pagerModule.js
Normal file
26
guacamole/src/main/webapp/app/pager/pagerModule.js
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module for displaying the contents of a list, split into multiple pages.
|
||||
*/
|
||||
angular.module('pager', []);
|
90
guacamole/src/main/webapp/app/pager/styles/pager.css
Normal file
90
guacamole/src/main/webapp/app/pager/styles/pager.css
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
.pager {
|
||||
text-align: center;
|
||||
margin: 1em;
|
||||
}
|
||||
|
||||
.pager .page-numbers {
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.pager .first-page,
|
||||
.pager .prev-page,
|
||||
.pager .set-page,
|
||||
.pager .next-page,
|
||||
.pager .last-page {
|
||||
cursor: pointer;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.pager .first-page.disabled,
|
||||
.pager .prev-page.disabled,
|
||||
.pager .set-page.disabled,
|
||||
.pager .next-page.disabled,
|
||||
.pager .last-page.disabled {
|
||||
cursor: auto;
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
.pager .set-page,
|
||||
.pager .more-pages {
|
||||
display: inline-block;
|
||||
padding: 0.25em;
|
||||
text-align: center;
|
||||
min-width: 1.25em;
|
||||
}
|
||||
|
||||
.pager .set-page {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.pager .set-page.current {
|
||||
cursor: auto;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
-moz-border-radius: 0.2em;
|
||||
-webkit-border-radius: 0.2em;
|
||||
-khtml-border-radius: 0.2em;
|
||||
border-radius: 0.2em;
|
||||
}
|
||||
|
||||
.pager .icon.first-page {
|
||||
background-image: url('images/action-icons/guac-first-page.png');
|
||||
}
|
||||
|
||||
.pager .icon.prev-page {
|
||||
background-image: url('images/action-icons/guac-prev-page.png');
|
||||
}
|
||||
|
||||
.pager .icon.next-page {
|
||||
background-image: url('images/action-icons/guac-next-page.png');
|
||||
}
|
||||
|
||||
.pager .icon.last-page {
|
||||
background-image: url('images/action-icons/guac-last-page.png');
|
||||
}
|
46
guacamole/src/main/webapp/app/pager/templates/guacPager.html
Normal file
46
guacamole/src/main/webapp/app/pager/templates/guacPager.html
Normal file
@@ -0,0 +1,46 @@
|
||||
<div class="pager" ng-show="pageNumbers.length > 1">
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<!-- First / Previous -->
|
||||
<div class="first-page icon" ng-class="{disabled: !canSelectPage(firstPage)}" ng-click="selectPage(firstPage)"/>
|
||||
<div class="prev-page icon" ng-class="{disabled: !canSelectPage(previousPage)}" ng-click="selectPage(previousPage)"/>
|
||||
|
||||
<!-- Indicator of the existence of pages before the first page number shown -->
|
||||
<div class="more-pages" ng-show="hasMorePagesBefore()">...</div>
|
||||
|
||||
<!-- Page numbers -->
|
||||
<ul class="page-numbers">
|
||||
<li class="set-page"
|
||||
ng-class="{current: isSelected(pageNumber)}"
|
||||
ng-repeat="pageNumber in pageNumbers"
|
||||
ng-click="selectPage(pageNumber)">{{pageNumber}}</li>
|
||||
</ul>
|
||||
|
||||
<!-- Indicator of the existence of pages beyond the last page number shown -->
|
||||
<div class="more-pages" ng-show="hasMorePagesAfter()">...</div>
|
||||
|
||||
<!-- Next / Last -->
|
||||
<div class="next-page icon" ng-class="{disabled: !canSelectPage(nextPage)}" ng-click="selectPage(nextPage)"/>
|
||||
<div class="last-page icon" ng-class="{disabled: !canSelectPage(lastPage)}" ng-click="selectPage(lastPage)"/>
|
||||
|
||||
</div>
|
Reference in New Issue
Block a user