GUAC-997 Added active user count to REST API and UI.

This commit is contained in:
James Muehlner
2015-01-27 22:20:03 -08:00
parent 4573677880
commit f7e1f3a303
9 changed files with 86 additions and 2 deletions

View File

@@ -22,10 +22,12 @@
package org.glyptodon.guacamole.net.basic.rest.connection; package org.glyptodon.guacamole.net.basic.rest.connection;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.codehaus.jackson.annotate.JsonIgnoreProperties; import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.net.auth.Connection; import org.glyptodon.guacamole.net.auth.Connection;
import org.glyptodon.guacamole.net.auth.ConnectionRecord;
import org.glyptodon.guacamole.net.basic.rest.connectiongroup.APIConnectionGroup; import org.glyptodon.guacamole.net.basic.rest.connectiongroup.APIConnectionGroup;
import org.glyptodon.guacamole.protocol.GuacamoleConfiguration; import org.glyptodon.guacamole.protocol.GuacamoleConfiguration;
@@ -62,6 +64,11 @@ public class APIConnection {
*/ */
private Map<String, String> parameters; private Map<String, String> parameters;
/**
* The count of currently active users for this connection.
*/
private int activeUsers;
/** /**
* Create an empty APIConnection. * Create an empty APIConnection.
*/ */
@@ -86,6 +93,14 @@ public class APIConnection {
this.parentIdentifier = connection.getParentIdentifier(); this.parentIdentifier = connection.getParentIdentifier();
if (this.parentIdentifier == null) if (this.parentIdentifier == null)
this.parentIdentifier = APIConnectionGroup.ROOT_IDENTIFIER; this.parentIdentifier = APIConnectionGroup.ROOT_IDENTIFIER;
// Set the number of currently active users
this.activeUsers = 0;
for (ConnectionRecord history : connection.getHistory()) {
if (history.isActive())
this.activeUsers++;
}
// Set protocol from configuration // Set protocol from configuration
GuacamoleConfiguration configuration = connection.getConfiguration(); GuacamoleConfiguration configuration = connection.getConfiguration();
@@ -173,5 +188,21 @@ public class APIConnection {
public void setProtocol(String protocol) { public void setProtocol(String protocol) {
this.protocol = protocol; this.protocol = protocol;
} }
/**
* Returns the number of currently active users for this connection.
* @return The number of currently active users for this connection.
*/
public int getActiveUsers() {
return activeUsers;
}
/**
* Set the number of currently active users for this connection.
* @param activeUsers The number of currently active users for this connection.
*/
public void setActiveUsers(int activeUsers) {
this.activeUsers = activeUsers;
}
} }

View File

@@ -100,6 +100,14 @@ angular.module('groupList').factory('GroupListItem', ['ConnectionGroup', functio
* @type Boolean * @type Boolean
*/ */
this.isExpanded = template.isExpanded; this.isExpanded = template.isExpanded;
/**
* The number of currently active users for this connection. This field
* has no meaning for a connection group, and may be null or undefined.
*
* @type Number
*/
this.activeUsers = template.activeUsers;
/** /**
* The connection or connection group whose data is exposed within * The connection or connection group whose data is exposed within
@@ -134,6 +142,9 @@ angular.module('groupList').factory('GroupListItem', ['ConnectionGroup', functio
// Type information // Type information
isConnection : true, isConnection : true,
isConnectionGroup : false, isConnectionGroup : false,
// Count of currently active users
activeUsers : connection.activeUsers,
// Wrapped item // Wrapped item
wrappedItem : connection wrappedItem : connection

View File

@@ -21,7 +21,7 @@
THE SOFTWARE. THE SOFTWARE.
--> -->
<div class="caption"> <div class="caption" ng-class="{active: item.activeUsers}">
<!-- Connection icon --> <!-- Connection icon -->
<div class="protocol"> <div class="protocol">
@@ -30,6 +30,11 @@
<!-- Connection name --> <!-- Connection name -->
<span class="name">{{item.name}}</span> <span class="name">{{item.name}}</span>
<!-- Active user count -->
<span class="activeUserCount" ng-show="item.activeUsers">
{{'HOME.INFO_ACTIVE_USER_COUNT' | translate:'{USERS: item.activeUsers}'}}
</span>
</div> </div>
</a> </a>

View File

@@ -41,3 +41,10 @@
font-style: normal; font-style: normal;
src: url('fonts/carlito/Carlito-Bold.woff') format('woff'); src: url('fonts/carlito/Carlito-Bold.woff') format('woff');
} }
@font-face {
font-family: 'Carlito';
font-weight: normal;
font-style: italic;
src: url('fonts/carlito/Carlito-Italic.woff') format('woff');
}

View File

@@ -140,6 +140,16 @@ div.section {
background: #DEB; background: #DEB;
} }
.caption.active * {
opacity: 0.5;
}
.caption .activeUserCount {
font-style: italic;
position: absolute;
right: 1em;
}
.list-item:not(.selected) .caption:hover { .list-item:not(.selected) .caption:hover {
background: #CDA; background: #CDA;
} }

View File

@@ -21,7 +21,7 @@
THE SOFTWARE. THE SOFTWARE.
--> -->
<div class="caption"> <div class="caption" ng-class="{active: item.activeUsers}">
<!-- Connection icon --> <!-- Connection icon -->
<div class="protocol"> <div class="protocol">
@@ -31,5 +31,10 @@
<!-- Connection name --> <!-- Connection name -->
<span class="name">{{item.name}}</span> <span class="name">{{item.name}}</span>
<!-- Active user count -->
<span class="activeUserCount" ng-show="item.activeUsers">
{{'MANAGE.INFO_ACTIVE_USER_COUNT' | translate:'{USERS: item.activeUsers}'}}
</span>
</div> </div>
</a> </a>

View File

@@ -79,6 +79,15 @@ angular.module('rest').factory('Connection', [function defineConnection() {
* @type Object.<String, String> * @type Object.<String, String>
*/ */
this.parameters = template.parameters; this.parameters = template.parameters;
/**
* The count of currently active users for this connection. This field
* will be returned from the REST API during a get operation,
* but may not be set when doing an update or create operation.
*
* @type Number
*/
this.activeUsers = template.activeUsers;
}; };

View File

@@ -11,6 +11,8 @@
"ACTION_NAVIGATE_BACK" : "Back", "ACTION_NAVIGATE_BACK" : "Back",
"ACTION_NAVIGATE_HOME" : "Home", "ACTION_NAVIGATE_HOME" : "Home",
"ACTION_SAVE" : "Save", "ACTION_SAVE" : "Save",
"INFO_ACTIVE_USER_COUNT" : "Currently in use by {USERS} {USERS, plural, one{user} other{users}}.",
"NAME" : "Guacamole ${project.version}" "NAME" : "Guacamole ${project.version}"
@@ -105,6 +107,8 @@
"ACTION_LOGOUT" : "@:APP.ACTION_LOGOUT", "ACTION_LOGOUT" : "@:APP.ACTION_LOGOUT",
"ACTION_MANAGE" : "@:APP.ACTION_MANAGE", "ACTION_MANAGE" : "@:APP.ACTION_MANAGE",
"INFO_ACTIVE_USER_COUNT" : "@:APP.INFO_ACTIVE_USER_COUNT",
"INFO_NO_RECENT_CONNECTIONS" : "No recent connections.", "INFO_NO_RECENT_CONNECTIONS" : "No recent connections.",
@@ -139,6 +143,8 @@
"HELP_SHOW_PASSWORD" : "Click to show password", "HELP_SHOW_PASSWORD" : "Click to show password",
"HELP_HIDE_PASSWORD" : "Click to hide password", "HELP_HIDE_PASSWORD" : "Click to hide password",
"HELP_USERS" : "Click or tap on a user below to manage that user. Depending on your access level, users can be added and deleted, and their passwords can be changed.", "HELP_USERS" : "Click or tap on a user below to manage that user. Depending on your access level, users can be added and deleted, and their passwords can be changed.",
"INFO_ACTIVE_USER_COUNT" : "@:APP.INFO_ACTIVE_USER_COUNT",
"SECTION_HEADER_ADMINISTRATION" : "Administration", "SECTION_HEADER_ADMINISTRATION" : "Administration",
"SECTION_HEADER_CONNECTIONS" : "Connections", "SECTION_HEADER_CONNECTIONS" : "Connections",