mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-31 00:53:21 +00:00 
			
		
		
		
	Paginate main UI connection list, improve pager styles, begin proper style separation.
This commit is contained in:
		| @@ -24,6 +24,7 @@ | ||||
|     <head> | ||||
|         <link rel="icon" type="image/png" href="images/guacamole-logo-64.png"/> | ||||
|         <link rel="apple-touch-icon" type="image/png" href="images/guacamole-logo-144.png"/> | ||||
|         <link rel="stylesheet" type="text/css" href="styles/ui.css"/> | ||||
|         <link rel="stylesheet" type="text/css" href="styles/login.css"/> | ||||
|         <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, target-densitydpi=medium-dpi"/> | ||||
|         <title>Guacamole ${project.version}</title> | ||||
| @@ -82,6 +83,9 @@ | ||||
|             <div id="all-connections"> | ||||
|             </div> | ||||
|  | ||||
|             <div id="all-connections-buttons"> | ||||
|             </div> | ||||
|  | ||||
|             <h2>Clipboard</h2> | ||||
|             <div id="clipboardDiv"> | ||||
|                 <p> | ||||
|   | ||||
| @@ -257,167 +257,6 @@ GuacAdmin.ListItem = function(type, title) { | ||||
|  | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * A paging component. Elements can be added via the addElement() function, | ||||
|  * and will only be shown if they are on the current page, set via setPage(). | ||||
|  *  | ||||
|  * Beware that all elements will be added to the given container element, and | ||||
|  * all children of the container element will be removed when the page is | ||||
|  * changed. | ||||
|  */ | ||||
| GuacAdmin.Pager = function(container) { | ||||
|  | ||||
|     var guac_pager = this; | ||||
|  | ||||
|     /** | ||||
|      * A container for all pager control buttons. | ||||
|      */ | ||||
|     var element = GuacUI.createElement("div", "pager"); | ||||
|  | ||||
|     /** | ||||
|      * All displayable elements. | ||||
|      */ | ||||
|     var elements = []; | ||||
|  | ||||
|     /** | ||||
|      * The number of elements to display per page. | ||||
|      */ | ||||
|     this.page_capacity = 10; | ||||
|  | ||||
|     /** | ||||
|      * The number of pages to generate a window for. | ||||
|      */ | ||||
|     this.window_size = 11; | ||||
|  | ||||
|     /** | ||||
|      * The current page, where 0 is the first page. | ||||
|      */ | ||||
|     this.current_page = 0; | ||||
|  | ||||
|     /** | ||||
|      * The last existing page. | ||||
|      */ | ||||
|     this.last_page = 0; | ||||
|  | ||||
|     function update_display() { | ||||
|  | ||||
|         var i; | ||||
|  | ||||
|         // Calculate first and last elements of page (where the last element | ||||
|         // is actually the first element of the next page) | ||||
|         var first_element = guac_pager.current_page * guac_pager.page_capacity; | ||||
|         var last_element  = Math.min(elements.length, | ||||
|                 first_element + guac_pager.page_capacity); | ||||
|  | ||||
|         // Clear contents, add elements | ||||
|         container.innerHTML = ""; | ||||
|         for (i=first_element; i < last_element; i++) | ||||
|             container.appendChild(elements[i]); | ||||
|  | ||||
|         // Update buttons | ||||
|         element.innerHTML = ""; | ||||
|  | ||||
|         // Create first and prev buttons | ||||
|         var first = GuacUI.createChildElement(element, "div", "first-page icon"); | ||||
|         var prev = GuacUI.createChildElement(element, "div", "prev-page icon"); | ||||
|  | ||||
|         // Handle prev/first | ||||
|         if (guac_pager.current_page > 0) { | ||||
|             first.onclick = function() { | ||||
|                 guac_pager.setPage(0); | ||||
|             }; | ||||
|  | ||||
|             prev.onclick = function() { | ||||
|                 guac_pager.setPage(guac_pager.current_page - 1); | ||||
|             }; | ||||
|         } | ||||
|         else { | ||||
|             GuacUI.addClass(first, "disabled"); | ||||
|             GuacUI.addClass(prev, "disabled"); | ||||
|         } | ||||
|  | ||||
|         // Calculate page jump window start/end | ||||
|         var window_start = guac_pager.current_page - (guac_pager.window_size - 1) / 2; | ||||
|         var window_end = window_start + guac_pager.window_size - 1; | ||||
|  | ||||
|         // Shift window as necessary | ||||
|         if (window_start < 0) { | ||||
|             window_end = Math.min(guac_pager.last_page, window_end - window_start); | ||||
|             window_start = 0; | ||||
|         } | ||||
|         else if (window_end > guac_pager.last_page) { | ||||
|             window_start = Math.max(0, window_start - window_end + guac_pager.last_page); | ||||
|             window_end = guac_pager.last_page; | ||||
|         } | ||||
|          | ||||
|         // Add page jumps | ||||
|         for (i=window_start; i<=window_end; i++) { | ||||
|  | ||||
|             // Create clickable element containing page number | ||||
|             var jump = GuacUI.createChildElement(element, "div", "set-page"); | ||||
|             jump.textContent = i+1; | ||||
|              | ||||
|             // Mark current page | ||||
|             if (i == guac_pager.current_page) | ||||
|                 GuacUI.addClass(jump, "current"); | ||||
|  | ||||
|             // If not current, add click event | ||||
|             else | ||||
|                 (function(page_number) { | ||||
|                     jump.onclick = function() { | ||||
|                         guac_pager.setPage(page_number); | ||||
|                     }; | ||||
|                 })(i); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         // Create next and last buttons | ||||
|         var next = GuacUI.createChildElement(element, "div", "next-page icon"); | ||||
|         var last = GuacUI.createChildElement(element, "div", "last-page icon"); | ||||
|  | ||||
|         // Handle next/last | ||||
|         if (guac_pager.current_page < guac_pager.last_page) { | ||||
|             next.onclick = function() { | ||||
|                 guac_pager.setPage(guac_pager.current_page + 1); | ||||
|             }; | ||||
|              | ||||
|             last.onclick = function() { | ||||
|                 guac_pager.setPage(guac_pager.last_page); | ||||
|             }; | ||||
|         } | ||||
|         else { | ||||
|             GuacUI.addClass(next, "disabled"); | ||||
|             GuacUI.addClass(last, "disabled"); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Adds the given element to the set of displayable elements. | ||||
|      */ | ||||
|     this.addElement = function(element) { | ||||
|         elements.push(element); | ||||
|         guac_pager.last_page = Math.max(0, | ||||
|             Math.floor((elements.length - 1) / guac_pager.page_capacity)); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Sets the current page, where 0 is the first page. | ||||
|      */ | ||||
|     this.setPage = function(number) { | ||||
|         guac_pager.current_page = number; | ||||
|         update_display(); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Returns the element representing the buttons of this pager. | ||||
|      */ | ||||
|     this.getElement = function() { | ||||
|         return element; | ||||
|     }; | ||||
|  | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * Set handler for logout | ||||
|  */ | ||||
| @@ -963,9 +802,7 @@ GuacAdmin.reset = function() { | ||||
|     GuacAdmin.cached_connections = GuacamoleService.Connections.list(); | ||||
|  | ||||
|     // Sort connections by ID | ||||
|     GuacAdmin.cached_connections.sort(function(a, b) { | ||||
|         return a.id.localeCompare(b.id); | ||||
|     }); | ||||
|     GuacAdmin.cached_connections.sort(GuacamoleService.Connections.comparator); | ||||
|  | ||||
|     // Connection management | ||||
|     if (GuacAdmin.cached_permissions.create_connection | ||||
| @@ -1044,7 +881,7 @@ GuacAdmin.reset = function() { | ||||
|  | ||||
|     // Add new pager | ||||
|     GuacAdmin.containers.user_list.innerHTML = ""; | ||||
|     GuacAdmin.userPager = new GuacAdmin.Pager(GuacAdmin.containers.user_list); | ||||
|     GuacAdmin.userPager = new GuacUI.Pager(GuacAdmin.containers.user_list); | ||||
|  | ||||
|     // Add users to pager | ||||
|     var usernames = Object.keys(GuacAdmin.cached_permissions.read_user).sort(); | ||||
| @@ -1071,7 +908,7 @@ GuacAdmin.reset = function() { | ||||
|  | ||||
|     // Add new pager | ||||
|     GuacAdmin.containers.connection_list.innerHTML = ""; | ||||
|     GuacAdmin.connectionPager = new GuacAdmin.Pager(GuacAdmin.containers.connection_list); | ||||
|     GuacAdmin.connectionPager = new GuacUI.Pager(GuacAdmin.containers.connection_list); | ||||
|  | ||||
|     // Add connections to pager | ||||
|     for (i=0; i<GuacAdmin.cached_connections.length; i++) | ||||
|   | ||||
| @@ -512,3 +512,173 @@ GuacUI.Connection = function(connection) { | ||||
|     }; | ||||
|  | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * A paging component. Elements can be added via the addElement() function, | ||||
|  * and will only be shown if they are on the current page, set via setPage(). | ||||
|  *  | ||||
|  * Beware that all elements will be added to the given container element, and | ||||
|  * all children of the container element will be removed when the page is | ||||
|  * changed. | ||||
|  */ | ||||
| GuacUI.Pager = function(container) { | ||||
|  | ||||
|     var guac_pager = this; | ||||
|  | ||||
|     /** | ||||
|      * A container for all pager control buttons. | ||||
|      */ | ||||
|     var element = GuacUI.createElement("div", "pager"); | ||||
|  | ||||
|     /** | ||||
|      * All displayable elements. | ||||
|      */ | ||||
|     var elements = []; | ||||
|  | ||||
|     /** | ||||
|      * The number of elements to display per page. | ||||
|      */ | ||||
|     this.page_capacity = 10; | ||||
|  | ||||
|     /** | ||||
|      * The number of pages to generate a window for. | ||||
|      */ | ||||
|     this.window_size = 11; | ||||
|  | ||||
|     /** | ||||
|      * The current page, where 0 is the first page. | ||||
|      */ | ||||
|     this.current_page = 0; | ||||
|  | ||||
|     /** | ||||
|      * The last existing page. | ||||
|      */ | ||||
|     this.last_page = 0; | ||||
|  | ||||
|     function update_display() { | ||||
|  | ||||
|         var i; | ||||
|  | ||||
|         // Calculate first and last elements of page (where the last element | ||||
|         // is actually the first element of the next page) | ||||
|         var first_element = guac_pager.current_page * guac_pager.page_capacity; | ||||
|         var last_element  = Math.min(elements.length, | ||||
|                 first_element + guac_pager.page_capacity); | ||||
|  | ||||
|         // Clear contents, add elements | ||||
|         container.innerHTML = ""; | ||||
|         for (i=first_element; i < last_element; i++) | ||||
|             container.appendChild(elements[i]); | ||||
|  | ||||
|         // Update buttons | ||||
|         element.innerHTML = ""; | ||||
|  | ||||
|         // Create first and prev buttons | ||||
|         var first = GuacUI.createChildElement(element, "div", "first-page icon"); | ||||
|         var prev = GuacUI.createChildElement(element, "div", "prev-page icon"); | ||||
|  | ||||
|         // Handle prev/first | ||||
|         if (guac_pager.current_page > 0) { | ||||
|             first.onclick = function() { | ||||
|                 guac_pager.setPage(0); | ||||
|             }; | ||||
|  | ||||
|             prev.onclick = function() { | ||||
|                 guac_pager.setPage(guac_pager.current_page - 1); | ||||
|             }; | ||||
|         } | ||||
|         else { | ||||
|             GuacUI.addClass(first, "disabled"); | ||||
|             GuacUI.addClass(prev, "disabled"); | ||||
|         } | ||||
|  | ||||
|         // Calculate page jump window start/end | ||||
|         var window_start = guac_pager.current_page - (guac_pager.window_size - 1) / 2; | ||||
|         var window_end = window_start + guac_pager.window_size - 1; | ||||
|  | ||||
|         // Shift window as necessary | ||||
|         if (window_start < 0) { | ||||
|             window_end = Math.min(guac_pager.last_page, window_end - window_start); | ||||
|             window_start = 0; | ||||
|         } | ||||
|         else if (window_end > guac_pager.last_page) { | ||||
|             window_start = Math.max(0, window_start - window_end + guac_pager.last_page); | ||||
|             window_end = guac_pager.last_page; | ||||
|         } | ||||
|          | ||||
|         // Add ellipsis if window after beginning | ||||
|         if (window_start != 0) | ||||
|             GuacUI.createChildElement(element, "div", "more-pages").textContent = "..."; | ||||
|          | ||||
|         // Add page jumps | ||||
|         for (i=window_start; i<=window_end; i++) { | ||||
|  | ||||
|             // Create clickable element containing page number | ||||
|             var jump = GuacUI.createChildElement(element, "div", "set-page"); | ||||
|             jump.textContent = i+1; | ||||
|              | ||||
|             // Mark current page | ||||
|             if (i == guac_pager.current_page) | ||||
|                 GuacUI.addClass(jump, "current"); | ||||
|  | ||||
|             // If not current, add click event | ||||
|             else | ||||
|                 (function(page_number) { | ||||
|                     jump.onclick = function() { | ||||
|                         guac_pager.setPage(page_number); | ||||
|                     }; | ||||
|                 })(i); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         // Add ellipsis if window before end | ||||
|         if (window_end != guac_pager.last_page) | ||||
|             GuacUI.createChildElement(element, "div", "more-pages").textContent = "..."; | ||||
|          | ||||
|         // Create next and last buttons | ||||
|         var next = GuacUI.createChildElement(element, "div", "next-page icon"); | ||||
|         var last = GuacUI.createChildElement(element, "div", "last-page icon"); | ||||
|  | ||||
|         // Handle next/last | ||||
|         if (guac_pager.current_page < guac_pager.last_page) { | ||||
|             next.onclick = function() { | ||||
|                 guac_pager.setPage(guac_pager.current_page + 1); | ||||
|             }; | ||||
|              | ||||
|             last.onclick = function() { | ||||
|                 guac_pager.setPage(guac_pager.last_page); | ||||
|             }; | ||||
|         } | ||||
|         else { | ||||
|             GuacUI.addClass(next, "disabled"); | ||||
|             GuacUI.addClass(last, "disabled"); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Adds the given element to the set of displayable elements. | ||||
|      */ | ||||
|     this.addElement = function(element) { | ||||
|         elements.push(element); | ||||
|         guac_pager.last_page = Math.max(0, | ||||
|             Math.floor((elements.length - 1) / guac_pager.page_capacity)); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Sets the current page, where 0 is the first page. | ||||
|      */ | ||||
|     this.setPage = function(number) { | ||||
|         guac_pager.current_page = number; | ||||
|         update_display(); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Returns the element representing the buttons of this pager. | ||||
|      */ | ||||
|     this.getElement = function() { | ||||
|         return element; | ||||
|     }; | ||||
|  | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -26,7 +26,8 @@ var GuacamoleRootUI = { | ||||
|     "sections": { | ||||
|         "login_form"         : document.getElementById("login-form"), | ||||
|         "recent_connections" : document.getElementById("recent-connections"), | ||||
|         "all_connections"  : document.getElementById("all-connections") | ||||
|         "all_connections"    : document.getElementById("all-connections"), | ||||
|         "all_connections_buttons" : document.getElementById("all-connections-buttons") | ||||
|     }, | ||||
|  | ||||
|     "messages": { | ||||
| @@ -144,6 +145,9 @@ GuacamoleRootUI.reset = function() { | ||||
|     try { | ||||
|         connections = GuacamoleService.Connections.list(parameters); | ||||
|  | ||||
|         // Sort connections by ID | ||||
|         connections.sort(GuacamoleService.Connections.comparator); | ||||
|  | ||||
|         // Show admin elements if admin permissions available | ||||
|         var permissions = GuacamoleService.Permissions.list(); | ||||
|         if (permissions.create_connection | ||||
| @@ -169,6 +173,10 @@ GuacamoleRootUI.reset = function() { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     // Create pager for connections | ||||
|     var connection_pager = new GuacUI.Pager(GuacamoleRootUI.sections.all_connections); | ||||
|     connection_pager.page_capacity = 20; | ||||
|  | ||||
|     // Add connection icons | ||||
|     for (var i=0; i<connections.length; i++) { | ||||
|  | ||||
| @@ -183,11 +191,19 @@ GuacamoleRootUI.reset = function() { | ||||
|             GuacamoleRootUI.addRecentConnection(connection); | ||||
|  | ||||
|         // Add connection to connection list | ||||
|         GuacamoleRootUI.sections.all_connections.appendChild( | ||||
|         connection_pager.addElement( | ||||
|             new GuacUI.Connection(connections[i]).getElement()); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     // Add buttons if more than one page | ||||
|     if (connection_pager.last_page != 0) | ||||
|         GuacamoleRootUI.sections.all_connections_buttons.appendChild( | ||||
|             connection_pager.getElement()); | ||||
|  | ||||
|     // Start at page 0 | ||||
|     connection_pager.setPage(0); | ||||
|  | ||||
|     // If connections could be retrieved, display list | ||||
|     GuacamoleRootUI.views.login.style.display = "none"; | ||||
|     GuacamoleRootUI.views.connections.style.display = ""; | ||||
|   | ||||
| @@ -165,6 +165,13 @@ GuacamoleService.PermissionSet = function() { | ||||
|  */ | ||||
| GuacamoleService.Connections = { | ||||
|  | ||||
|     /** | ||||
|      * Comparator which compares two GuacamoleService.Connection objects. | ||||
|      */ | ||||
|     "comparator" : function(a, b) { | ||||
|         return a.id.localeCompare(b.id); | ||||
|     }, | ||||
|  | ||||
|      /** | ||||
|       * Returns an array of Connections for which the current user has access. | ||||
|       *  | ||||
|   | ||||
| @@ -242,8 +242,14 @@ div#recent-connections, | ||||
| div#clipboardDiv, | ||||
| div#settings, | ||||
| div#all-connections { | ||||
|     margin: 0; | ||||
|     padding: 1em; | ||||
|     margin: 1em; | ||||
|     padding: 0; | ||||
| } | ||||
|  | ||||
| #all-connections-buttons { | ||||
|     text-align: center; | ||||
|     margin: 1em; | ||||
|     padding: 0; | ||||
| } | ||||
|  | ||||
| div#recent-connections { | ||||
| @@ -366,4 +372,4 @@ div#recent-connections .protocol { | ||||
|     margin: 1.5em; | ||||
|     margin-left: 2.5em; | ||||
|     font-size: 0.75em; | ||||
| } | ||||
| } | ||||
| @@ -388,16 +388,28 @@ div#logout-panel { | ||||
|     opacity: 0.25; | ||||
| } | ||||
|  | ||||
| .set-page { | ||||
|     text-decoration: underline; | ||||
| .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 { | ||||
| @@ -419,4 +431,5 @@ div#logout-panel { | ||||
| #user-list-buttons, | ||||
| #connection-list-buttons { | ||||
|     text-align: center; | ||||
|     margin: 1em; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user