diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/upgrade/upgrade-pre-0.9.9.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/upgrade/upgrade-pre-0.9.9.sql
index 60915f3da..d26684b16 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/upgrade/upgrade-pre-0.9.9.sql
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/upgrade/upgrade-pre-0.9.9.sql
@@ -26,3 +26,4 @@
ALTER TABLE guacamole_connection_history ADD KEY (start_date);
ALTER TABLE guacamole_connection_history ADD KEY (end_date);
+ALTER TABLE guacamole_connection_history ADD KEY search_index (start_date, connection_id, user_id);
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/glyptodon/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/glyptodon/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml
index f6b6698a9..91eec1430 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/glyptodon/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/glyptodon/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml
@@ -86,8 +86,8 @@
guacamole_connection_history.start_date,
guacamole_connection_history.end_date
FROM guacamole_connection_history
- JOIN guacamole_connection ON guacamole_connection_history.connection_id = guacamole_connection.connection_id
- JOIN guacamole_user ON guacamole_connection_history.user_id = guacamole_user.user_id
+ LEFT JOIN guacamole_connection ON guacamole_connection_history.connection_id = guacamole_connection.connection_id
+ LEFT JOIN guacamole_user ON guacamole_connection_history.user_id = guacamole_user.user_id
- OR (
- (start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP})
- AND (end_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP})
- )
+ OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
)
-
-
-
- guacamole_connection.connection_name
- guacamole_user.username
guacamole_connection_history.start_date
- guacamole_connection_history.end_date
1
DESC
@@ -150,8 +141,8 @@
guacamole_connection_history.start_date,
guacamole_connection_history.end_date
FROM guacamole_connection_history
- JOIN guacamole_connection ON guacamole_connection_history.connection_id = guacamole_connection.connection_id
- JOIN guacamole_user ON guacamole_connection_history.user_id = guacamole_user.user_id
+ LEFT JOIN guacamole_connection ON guacamole_connection_history.connection_id = guacamole_connection.connection_id
+ LEFT JOIN guacamole_user ON guacamole_connection_history.user_id = guacamole_user.user_id
JOIN guacamole_connection_permission ON
@@ -183,29 +174,20 @@
)
- OR (
- (start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP})
- AND (end_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP})
- )
+ OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
)
-
-
-
- guacamole_connection.connection_name
- guacamole_user.username
guacamole_connection_history.start_date
- guacamole_connection_history.end_date
1
DESC
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-0.9.9.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-0.9.9.sql
index 3ff710617..f4f58b52f 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-0.9.9.sql
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-0.9.9.sql
@@ -26,3 +26,4 @@
CREATE INDEX ON guacamole_connection_history(start_date);
CREATE INDEX ON guacamole_connection_history(end_date);
+CREATE INDEX guacamole_connection_history_search_index ON guacamole_connection_history(start_date, connection_id, user_id);
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/glyptodon/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/glyptodon/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml
index b3a23eadc..87dbee47c 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/glyptodon/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/glyptodon/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml
@@ -86,8 +86,8 @@
guacamole_connection_history.start_date,
guacamole_connection_history.end_date
FROM guacamole_connection_history
- JOIN guacamole_connection ON guacamole_connection_history.connection_id = guacamole_connection.connection_id
- JOIN guacamole_user ON guacamole_connection_history.user_id = guacamole_user.user_id
+ LEFT JOIN guacamole_connection ON guacamole_connection_history.connection_id = guacamole_connection.connection_id
+ LEFT JOIN guacamole_user ON guacamole_connection_history.user_id = guacamole_user.user_id
- OR (
- (start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP})
- AND (end_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP})
- )
+ OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
)
-
-
-
- guacamole_connection.connection_name
- guacamole_user.username
guacamole_connection_history.start_date
- guacamole_connection_history.end_date
1
DESC
@@ -150,8 +141,8 @@
guacamole_connection_history.start_date,
guacamole_connection_history.end_date
FROM guacamole_connection_history
- JOIN guacamole_connection ON guacamole_connection_history.connection_id = guacamole_connection.connection_id
- JOIN guacamole_user ON guacamole_connection_history.user_id = guacamole_user.user_id
+ LEFT JOIN guacamole_connection ON guacamole_connection_history.connection_id = guacamole_connection.connection_id
+ LEFT JOIN guacamole_user ON guacamole_connection_history.user_id = guacamole_user.user_id
JOIN guacamole_connection_permission ON
@@ -183,29 +174,20 @@
)
- OR (
- (start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP})
- AND (end_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP})
- )
+ OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
)
-
-
-
- guacamole_connection.connection_name
- guacamole_user.username
guacamole_connection_history.start_date
- guacamole_connection_history.end_date
1
DESC
diff --git a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/ConnectionRecordSet.java b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/ConnectionRecordSet.java
index ef6f9c336..691764485 100644
--- a/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/ConnectionRecordSet.java
+++ b/guacamole-ext/src/main/java/org/glyptodon/guacamole/net/auth/ConnectionRecordSet.java
@@ -39,29 +39,11 @@ public interface ConnectionRecordSet {
*/
enum SortableProperty {
- /**
- * The name (not identifier) of the connection associated with the
- * connection record.
- */
- CONNECTION_NAME,
-
- /**
- * The identifier (username) of the user that used the connection
- * associated with the connection record.
- */
- USER_IDENTIFIER,
-
/**
* The date and time when the connection associated with the
* connection record began.
*/
- START_DATE,
-
- /**
- * The date and time when the connection associated with the
- * connection record ended.
- */
- END_DATE
+ START_DATE
};
diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/history/APIConnectionRecordSortPredicate.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/history/APIConnectionRecordSortPredicate.java
index 17872d77d..df3dec58c 100644
--- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/history/APIConnectionRecordSortPredicate.java
+++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/history/APIConnectionRecordSortPredicate.java
@@ -46,29 +46,11 @@ public class APIConnectionRecordSortPredicate {
*/
public enum SortableProperty {
- /**
- * The name (not identifier) of the connection associated with the
- * connection record.
- */
- connectionName(ConnectionRecordSet.SortableProperty.CONNECTION_NAME),
-
- /**
- * The username (identifier) of the user associated with the connection
- * record.
- */
- username(ConnectionRecordSet.SortableProperty.USER_IDENTIFIER),
-
/**
* The date that the connection associated with the connection record
* began (connected).
*/
- startDate(ConnectionRecordSet.SortableProperty.START_DATE),
-
- /**
- * The date that the connection associated with the connection record
- * ended (disconnected).
- */
- endDate(ConnectionRecordSet.SortableProperty.END_DATE);
+ startDate(ConnectionRecordSet.SortableProperty.START_DATE);
/**
* The ConnectionRecordSet.SortableProperty that this property name
diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/history/HistoryRESTService.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/history/HistoryRESTService.java
index a99a5ec9c..1f9f4c8b8 100644
--- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/history/HistoryRESTService.java
+++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/history/HistoryRESTService.java
@@ -61,7 +61,7 @@ public class HistoryRESTService {
/**
* The maximum number of history records to return in any one response.
*/
- private static final int MAXIMUM_HISTORY_SIZE = 10000;
+ private static final int MAXIMUM_HISTORY_SIZE = 1000;
/**
* A service for authenticating users from auth tokens.
diff --git a/guacamole/src/main/webapp/app/manage/types/HistoryEntryDuration.js b/guacamole/src/main/webapp/app/manage/types/HistoryEntryDuration.js
deleted file mode 100644
index 86995baa2..000000000
--- a/guacamole/src/main/webapp/app/manage/types/HistoryEntryDuration.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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 service for defining the HistoryEntryDuration class.
- */
-angular.module('manage').factory('HistoryEntryDuration', [function defineHistoryEntryDuration() {
-
- /**
- * Value/unit pair representing the length of time that a connection was
- * used.
- *
- * @constructor
- * @param {Number} milliseconds
- * The number of milliseconds that the associated connection was used.
- */
- var HistoryEntryDuration = function HistoryEntryDuration(milliseconds) {
-
- var seconds = milliseconds / 1000;
-
- /**
- * Rounds the given value to the nearest tenth.
- *
- * @param {Number} value The value to round.
- * @returns {Number} The given value, rounded to the nearest tenth.
- */
- var round = function round(value) {
- return Math.round(value * 10) / 10;
- };
-
- // Days
- if (seconds >= 86400) {
- this.value = round(seconds / 86400);
- this.unit = 'day';
- }
-
- // Hours
- else if (seconds >= 3600) {
- this.value = round(seconds / 3600);
- this.unit = 'hour';
- }
-
- // Minutes
- else if (seconds >= 60) {
- this.value = round(seconds / 60);
- this.unit = 'minute';
- }
-
- // Seconds
- else {
-
- /**
- * The number of seconds (or minutes, or hours, etc.) that the
- * connection was used. The units associated with this value are
- * represented by the unit property.
- *
- * @type Number
- */
- this.value = round(seconds);
-
- /**
- * The units associated with the value of this duration. Valid
- * units are 'second', 'minute', 'hour', and 'day'.
- *
- * @type String
- */
- this.unit = 'second';
-
- }
-
- };
-
- return HistoryEntryDuration;
-
-}]);
\ No newline at end of file
diff --git a/guacamole/src/main/webapp/app/manage/types/HistoryEntryWrapper.js b/guacamole/src/main/webapp/app/manage/types/HistoryEntryWrapper.js
index f8ad26e1d..f8f8aaec4 100644
--- a/guacamole/src/main/webapp/app/manage/types/HistoryEntryWrapper.js
+++ b/guacamole/src/main/webapp/app/manage/types/HistoryEntryWrapper.js
@@ -23,8 +23,11 @@
/**
* A service for defining the HistoryEntryWrapper class.
*/
-angular.module('manage').factory('HistoryEntryWrapper', ['HistoryEntryDuration',
- function defineHistoryEntryWrapper(HistoryEntryDuration) {
+angular.module('manage').factory('HistoryEntryWrapper', ['$injector',
+ function defineHistoryEntryWrapper($injector) {
+
+ // Required types
+ var ConnectionHistoryEntry = $injector.get('ConnectionHistoryEntry');
/**
* Wrapper for ConnectionHistoryEntry which adds display-specific
@@ -47,7 +50,7 @@ angular.module('manage').factory('HistoryEntryWrapper', ['HistoryEntryDuration',
* An object providing value and unit properties, denoting the duration
* and its corresponding units.
*
- * @type HistoryEntryDuration
+ * @type ConnectionHistoryEntry.Duration
*/
this.duration = null;
@@ -65,13 +68,13 @@ angular.module('manage').factory('HistoryEntryWrapper', ['HistoryEntryDuration',
if (historyEntry.active)
this.durationText = 'MANAGE_CONNECTION.INFO_CONNECTION_ACTIVE_NOW';
- // If connection is not active, inform use if end date is not known
+ // If connection is not active, inform user if end date is not known
else if (!historyEntry.endDate)
this.durationText = 'MANAGE_CONNECTION.INFO_CONNECTION_DURATION_UNKNOWN';
// Set the duration if the necessary information is present
if (historyEntry.endDate && historyEntry.startDate)
- this.duration = new HistoryEntryDuration(historyEntry.endDate - historyEntry.startDate);
+ this.duration = new ConnectionHistoryEntry.Duration(historyEntry.endDate - historyEntry.startDate);
};
diff --git a/guacamole/src/main/webapp/app/rest/types/ConnectionHistoryEntry.js b/guacamole/src/main/webapp/app/rest/types/ConnectionHistoryEntry.js
index 7e892538c..355f8084a 100644
--- a/guacamole/src/main/webapp/app/rest/types/ConnectionHistoryEntry.js
+++ b/guacamole/src/main/webapp/app/rest/types/ConnectionHistoryEntry.js
@@ -110,29 +110,80 @@ angular.module('rest').factory('ConnectionHistoryEntry', [function defineConnect
*/
ConnectionHistoryEntry.SortPredicate = {
- /**
- * The name of the connection associated with the history entry (not
- * the connection identifier).
- */
- CONNECTION_NAME : 'connectionName',
-
- /**
- * The username of the user associated with the history entry (the user
- * identifier).
- */
- USER_IDENTIFIER : 'username',
-
/**
* The date and time that the connection associated with the history
* entry began (connected).
*/
- START_DATE : 'startDate',
+ START_DATE : 'startDate'
+
+ };
+
+ /**
+ * Value/unit pair representing the length of time that a connection was
+ * used.
+ *
+ * @constructor
+ * @param {Number} milliseconds
+ * The number of milliseconds that the associated connection was used.
+ */
+ ConnectionHistoryEntry.Duration = function Duration(milliseconds) {
/**
- * The date and time that the connection associated with the history
- * entry ended (disconnected).
+ * The provided duration in seconds.
+ *
+ * @type Number
*/
- END_DATE : 'endDate'
+ var seconds = milliseconds / 1000;
+
+ /**
+ * Rounds the given value to the nearest tenth.
+ *
+ * @param {Number} value The value to round.
+ * @returns {Number} The given value, rounded to the nearest tenth.
+ */
+ var round = function round(value) {
+ return Math.round(value * 10) / 10;
+ };
+
+ // Days
+ if (seconds >= 86400) {
+ this.value = round(seconds / 86400);
+ this.unit = 'day';
+ }
+
+ // Hours
+ else if (seconds >= 3600) {
+ this.value = round(seconds / 3600);
+ this.unit = 'hour';
+ }
+
+ // Minutes
+ else if (seconds >= 60) {
+ this.value = round(seconds / 60);
+ this.unit = 'minute';
+ }
+
+ // Seconds
+ else {
+
+ /**
+ * The number of seconds (or minutes, or hours, etc.) that the
+ * connection was used. The units associated with this value are
+ * represented by the unit property.
+ *
+ * @type Number
+ */
+ this.value = round(seconds);
+
+ /**
+ * The units associated with the value of this duration. Valid
+ * units are 'second', 'minute', 'hour', and 'day'.
+ *
+ * @type String
+ */
+ this.unit = 'second';
+
+ }
};
diff --git a/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnectionHistory.js b/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnectionHistory.js
index 3e6dbd298..0e1bd9d0a 100644
--- a/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnectionHistory.js
+++ b/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnectionHistory.js
@@ -37,8 +37,9 @@ angular.module('settings').directive('guacSettingsConnectionHistory', [function
controller: ['$scope', '$injector', function settingsConnectionHistoryController($scope, $injector) {
// Get required types
- var FilterToken = $injector.get('FilterToken');
- var SortOrder = $injector.get('SortOrder');
+ var ConnectionHistoryEntryWrapper = $injector.get('ConnectionHistoryEntryWrapper');
+ var FilterToken = $injector.get('FilterToken');
+ var SortOrder = $injector.get('SortOrder');
// Get required services
var $routeParams = $injector.get('$routeParams');
@@ -53,12 +54,12 @@ angular.module('settings').directive('guacSettingsConnectionHistory', [function
$scope.dataSource = $routeParams.dataSource;
/**
- * All matching connection history records, or null if these
- * records have not yet been retrieved.
+ * All wrapped matching connection history entries, or null if these
+ * entries have not yet been retrieved.
*
- * @type ConnectionHistoryEntry[]
+ * @type ConnectionHistoryEntryWrapper[]
*/
- $scope.historyRecords = null;
+ $scope.historyEntryWrappers = null;
/**
* The search terms to use when filtering the history records.
@@ -82,7 +83,7 @@ angular.module('settings').directive('guacSettingsConnectionHistory', [function
*/
$scope.order = new SortOrder([
'-startDate',
- '-endDate',
+ '-duration',
'username',
'connectionName'
]);
@@ -107,8 +108,8 @@ angular.module('settings').directive('guacSettingsConnectionHistory', [function
*
*/
$scope.isLoaded = function isLoaded() {
- return $scope.historyRecords !== null
- && $scope.dateFormat !== null;
+ return $scope.historyEntryWrappers !== null
+ && $scope.dateFormat !== null;
};
/**
@@ -121,7 +122,7 @@ angular.module('settings').directive('guacSettingsConnectionHistory', [function
* records are present, false otherwise.
*/
$scope.isHistoryEmpty = function isHistoryEmpty() {
- return $scope.isLoaded() && $scope.historyRecords.length === 0;
+ return $scope.isLoaded() && $scope.historyEntryWrappers.length === 0;
};
/**
@@ -131,7 +132,7 @@ angular.module('settings').directive('guacSettingsConnectionHistory', [function
$scope.search = function search() {
// Clear current results
- $scope.historyRecords = null;
+ $scope.historyEntryWrappers = null;
// Tokenize search string
var tokens = FilterToken.tokenize($scope.searchString);
@@ -164,12 +165,17 @@ angular.module('settings').directive('guacSettingsConnectionHistory', [function
historyService.getConnectionHistory(
$scope.dataSource,
requiredContents,
- $scope.order.predicate
+ $scope.order.predicate.filter(function isSupportedPredicate(predicate) {
+ return predicate === 'startDate' || predicate === '-startDate';
+ })
)
- .success(function historyRetrieved(historyRecords) {
+ .success(function historyRetrieved(historyEntries) {
- // Store retrieved permissions
- $scope.historyRecords = historyRecords;
+ // Wrap all history entries for sake of display
+ $scope.historyEntryWrappers = [];
+ angular.forEach(historyEntries, function wrapHistoryEntry(historyEntry) {
+ $scope.historyEntryWrappers.push(new ConnectionHistoryEntryWrapper(historyEntry));
+ });
});
diff --git a/guacamole/src/main/webapp/app/settings/templates/settingsConnectionHistory.html b/guacamole/src/main/webapp/app/settings/templates/settingsConnectionHistory.html
index 718bb004b..c22560e00 100644
--- a/guacamole/src/main/webapp/app/settings/templates/settingsConnectionHistory.html
+++ b/guacamole/src/main/webapp/app/settings/templates/settingsConnectionHistory.html
@@ -43,8 +43,8 @@
{{'SETTINGS_CONNECTION_HISTORY.TABLE_HEADER_SESSION_STARTDATE' | translate}}
|
-
- {{'SETTINGS_CONNECTION_HISTORY.TABLE_HEADER_SESSION_ENDDATE' | translate}}
+ |
+ {{'SETTINGS_CONNECTION_HISTORY.TABLE_HEADER_SESSION_DURATION' | translate}}
|
{{'SETTINGS_CONNECTION_HISTORY.TABLE_HEADER_SESSION_CONNECTION_NAME' | translate}}
@@ -52,11 +52,12 @@
|
-
- {{historyRecord.username}} |
- {{historyRecord.startDate | date : dateFormat}} |
- {{historyRecord.endDate | date : dateFormat}} |
- {{historyRecord.connectionName}} |
+
+ {{historyEntryWrapper.username}} |
+ {{historyEntryWrapper.startDate | date : dateFormat}} |
+ |
+ {{historyEntryWrapper.connectionName}} |
@@ -67,8 +68,8 @@
-
+
diff --git a/guacamole/src/main/webapp/app/settings/types/ConnectionHistoryEntryWrapper.js b/guacamole/src/main/webapp/app/settings/types/ConnectionHistoryEntryWrapper.js
new file mode 100644
index 000000000..e2e372631
--- /dev/null
+++ b/guacamole/src/main/webapp/app/settings/types/ConnectionHistoryEntryWrapper.js
@@ -0,0 +1,121 @@
+/*
+ * 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 service for defining the ConnectionHistoryEntryWrapper class.
+ */
+angular.module('settings').factory('ConnectionHistoryEntryWrapper', ['$injector',
+ function defineConnectionHistoryEntryWrapper($injector) {
+
+ // Required types
+ var ConnectionHistoryEntry = $injector.get('ConnectionHistoryEntry');
+
+ /**
+ * Wrapper for ConnectionHistoryEntry which adds display-specific
+ * properties, such as a duration.
+ *
+ * @constructor
+ * @param {ConnectionHistoryEntry} historyEntry
+ * The ConnectionHistoryEntry that should be wrapped.
+ */
+ var ConnectionHistoryEntryWrapper = function ConnectionHistoryEntryWrapper(historyEntry) {
+
+ /**
+ * The identifier of the connection associated with this history entry.
+ *
+ * @type String
+ */
+ this.connectionIdentifier = historyEntry.connectionIdentifier;
+
+ /**
+ * The name of the connection associated with this history entry.
+ *
+ * @type String
+ */
+ this.connectionName = historyEntry.connectionName;
+
+ /**
+ * The username of the user associated with this particular usage of
+ * the connection.
+ *
+ * @type String
+ */
+ this.username = historyEntry.username;
+
+ /**
+ * The time that usage began, in seconds since 1970-01-01 00:00:00 UTC.
+ *
+ * @type Number
+ */
+ this.startDate = historyEntry.startDate;
+
+ /**
+ * The time that usage ended, in seconds since 1970-01-01 00:00:00 UTC.
+ * The absence of an endDate does NOT necessarily indicate that the
+ * connection is still in use, particularly if the server was shutdown
+ * or restarted before the history entry could be updated. To determine
+ * whether a connection is still active, check the active property of
+ * this history entry.
+ *
+ * @type Number
+ */
+ this.endDate = historyEntry.endDate;
+
+ /**
+ * The total amount of time the connection associated with the wrapped
+ * history record was open, in seconds.
+ *
+ * @type Number
+ */
+ this.duration = this.endDate - this.startDate;
+
+ /**
+ * An object providing value and unit properties, denoting the duration
+ * and its corresponding units.
+ *
+ * @type ConnectionHistoryEntry.Duration
+ */
+ this.readableDuration = null;
+
+ // Set the duration if the necessary information is present
+ if (this.endDate && this.startDate)
+ this.readableDuration = new ConnectionHistoryEntry.Duration(this.duration);
+
+ /**
+ * The string to display as the duration of this history entry. If a
+ * duration is available, its value and unit will be exposed to any
+ * given translation string as the VALUE and UNIT substitution
+ * variables respectively.
+ *
+ * @type String
+ */
+ this.readableDurationText = 'SETTINGS_CONNECTION_HISTORY.TEXT_HISTORY_DURATION';
+
+ // Inform user if end date is not known
+ if (!this.endDate)
+ this.readableDurationText = 'SETTINGS_CONNECTION_HISTORY.INFO_CONNECTION_DURATION_UNKNOWN';
+
+ };
+
+ return ConnectionHistoryEntryWrapper;
+
+}]);
diff --git a/guacamole/src/main/webapp/translations/de.json b/guacamole/src/main/webapp/translations/de.json
index cdb78e8af..dfc61b132 100644
--- a/guacamole/src/main/webapp/translations/de.json
+++ b/guacamole/src/main/webapp/translations/de.json
@@ -38,7 +38,9 @@
"INFO_ACTIVE_USER_COUNT" : "In Benutzung durch {USERS} Benutzer.",
- "NAME" : "Guacamole ${project.version}"
+ "NAME" : "Guacamole ${project.version}",
+
+ "TEXT_HISTORY_DURATION" : "{VALUE} {UNIT, select, second{{VALUE, plural, one{Sekunde} other{Sekunden}}} minute{{VALUE, plural, one{Minute} other{Minuten}}} hour{{VALUE, plural, one{Stunde} other{Stunden}}} day{{VALUE, plural, one{Tag} other{Tage}}} other{}}"
},
@@ -202,7 +204,7 @@
"TABLE_HEADER_HISTORY_DURATION" : "Dauer",
"TEXT_CONFIRM_DELETE" : "Dieser Löschvorgang ist unumkehrbar. Soll diese Verbindung wirklich gelöscht werden?",
- "TEXT_HISTORY_DURATION" : "{VALUE} {UNIT, select, second{{VALUE, plural, one{Sekunde} other{Sekunden}}} minute{{VALUE, plural, one{Minute} other{Minuten}}} hour{{VALUE, plural, one{Stunde} other{Stunden}}} day{{VALUE, plural, one{Tag} other{Tage}}} other{}}"
+ "TEXT_HISTORY_DURATION" : "@:APP.TEXT_HISTORY_DURATION"
},
@@ -480,25 +482,6 @@
},
- "SETTINGS_CONNECTION_HISTORY" : {
-
- "ACTION_SEARCH" : "@:APP.ACTION_SEARCH",
-
- "FIELD_PLACEHOLDER_FILTER" : "@:APP.FIELD_PLACEHOLDER_FILTER",
-
- "FORMAT_DATE" : "@:APP.FORMAT_DATE_TIME_PRECISE",
-
- "HELP_CONNECTION_HISTORY" : "Die letzten Verbindungen werden hier historisch aufgelistet und können durch Klicken auf die Spaltenüberschriften sortiert werden. Zum Aufsuchen von bestimmten Datensätzen, geben Sie eine Filterzeichenfolge ein und klicken Sie auf \"Suchen\". Nur Datensätze, die die vorgesehenen Filterzeichenfolge entsprechen, werden aufgelistet.",
-
- "INFO_NO_HISTORY" : "Keine passenden Datensätze",
-
- "TABLE_HEADER_SESSION_CONNECTION_NAME" : "Verbindungsname",
- "TABLE_HEADER_SESSION_ENDDATE" : "Endzeit",
- "TABLE_HEADER_SESSION_STARTDATE" : "Startzeit",
- "TABLE_HEADER_SESSION_USERNAME" : "Benutzername"
-
- },
-
"SETTINGS_CONNECTIONS" : {
"ACTION_ACKNOWLEDGE" : "@:APP.ACTION_ACKNOWLEDGE",
@@ -517,7 +500,23 @@
"SETTINGS_CONNECTION_HISTORY" : {
- "FIELD_PLACEHOLDER_FILTER" : "@:APP.FIELD_PLACEHOLDER_FILTER"
+ "ACTION_SEARCH" : "@:APP.ACTION_SEARCH",
+
+ "FIELD_PLACEHOLDER_FILTER" : "@:APP.FIELD_PLACEHOLDER_FILTER",
+
+ "FORMAT_DATE" : "@:APP.FORMAT_DATE_TIME_PRECISE",
+
+ "HELP_CONNECTION_HISTORY" : "Die letzten Verbindungen werden hier historisch aufgelistet und können durch Klicken auf die Spaltenüberschriften sortiert werden. Zum Aufsuchen von bestimmten Datensätzen, geben Sie eine Filterzeichenfolge ein und klicken Sie auf \"Suchen\". Nur Datensätze, die die vorgesehenen Filterzeichenfolge entsprechen, werden aufgelistet.",
+
+ "INFO_CONNECTION_DURATION_UNKNOWN" : "--",
+ "INFO_NO_HISTORY" : "Keine passenden Datensätze",
+
+ "TABLE_HEADER_SESSION_CONNECTION_NAME" : "Verbindungsname",
+ "TABLE_HEADER_SESSION_DURATION" : "Dauer",
+ "TABLE_HEADER_SESSION_STARTDATE" : "Startzeit",
+ "TABLE_HEADER_SESSION_USERNAME" : "Benutzername",
+
+ "TEXT_HISTORY_DURATION" : "@:APP.TEXT_HISTORY_DURATION"
},
diff --git a/guacamole/src/main/webapp/translations/en.json b/guacamole/src/main/webapp/translations/en.json
index d35f8355d..b774d0376 100644
--- a/guacamole/src/main/webapp/translations/en.json
+++ b/guacamole/src/main/webapp/translations/en.json
@@ -38,7 +38,9 @@
"INFO_ACTIVE_USER_COUNT" : "Currently in use by {USERS} {USERS, plural, one{user} other{users}}.",
- "NAME" : "Guacamole ${project.version}"
+ "NAME" : "Guacamole ${project.version}",
+
+ "TEXT_HISTORY_DURATION" : "{VALUE} {UNIT, select, second{{VALUE, plural, one{second} other{seconds}}} minute{{VALUE, plural, one{minute} other{minutes}}} hour{{VALUE, plural, one{hour} other{hours}}} day{{VALUE, plural, one{day} other{days}}} other{}}"
},
@@ -202,7 +204,7 @@
"TABLE_HEADER_HISTORY_DURATION" : "Duration",
"TEXT_CONFIRM_DELETE" : "Connections cannot be restored after they have been deleted. Are you sure you want to delete this connection?",
- "TEXT_HISTORY_DURATION" : "{VALUE} {UNIT, select, second{{VALUE, plural, one{second} other{seconds}}} minute{{VALUE, plural, one{minute} other{minutes}}} hour{{VALUE, plural, one{hour} other{hours}}} day{{VALUE, plural, one{day} other{days}}} other{}}"
+ "TEXT_HISTORY_DURATION" : "@:APP.TEXT_HISTORY_DURATION"
},
@@ -493,12 +495,15 @@
"HELP_CONNECTION_HISTORY" : "History records for past connections are listed here and can be sorted by clicking the column headers. To search for specific records, enter a filter string and click \"Search\". Only records which match the provided filter string will be listed.",
- "INFO_NO_HISTORY" : "No matching records",
+ "INFO_CONNECTION_DURATION_UNKNOWN" : "--",
+ "INFO_NO_HISTORY" : "No matching records",
"TABLE_HEADER_SESSION_CONNECTION_NAME" : "Connection name",
- "TABLE_HEADER_SESSION_ENDDATE" : "End time",
+ "TABLE_HEADER_SESSION_DURATION" : "Duration",
"TABLE_HEADER_SESSION_STARTDATE" : "Start time",
- "TABLE_HEADER_SESSION_USERNAME" : "Username"
+ "TABLE_HEADER_SESSION_USERNAME" : "Username",
+
+ "TEXT_HISTORY_DURATION" : "@:APP.TEXT_HISTORY_DURATION"
},
diff --git a/guacamole/src/main/webapp/translations/fr.json b/guacamole/src/main/webapp/translations/fr.json
index 6839339b2..00c88b4e1 100644
--- a/guacamole/src/main/webapp/translations/fr.json
+++ b/guacamole/src/main/webapp/translations/fr.json
@@ -36,7 +36,9 @@
"INFO_ACTIVE_USER_COUNT" : "Actuellement utilisé par {USERS} {USERS, plural, one{utilisateur} other{utilisateurs}}.",
- "NAME" : "Guacamole ${project.version}"
+ "NAME" : "Guacamole ${project.version}",
+
+ "TEXT_HISTORY_DURATION" : "{VALUE} {UNIT, select, second{{VALUE, plural, one{seconde} other{secondes}}} minute{{VALUE, plural, one{minute} other{minutes}}} hour{{VALUE, plural, one{heure} other{heures}}} day{{VALUE, plural, one{jour} other{jours}}} other{}}"
},
@@ -193,7 +195,7 @@
"TABLE_HEADER_HISTORY_DURATION" : "Durée",
"TEXT_CONFIRM_DELETE" : "Les connexions ne pourront être restaurées une fois supprimées. Êtes-vous certains de vouloir supprimer cette connexion ?",
- "TEXT_HISTORY_DURATION" : "{VALUE} {UNIT, select, second{{VALUE, plural, one{seconde} other{secondes}}} minute{{VALUE, plural, one{minute} other{minutes}}} hour{{VALUE, plural, one{heure} other{heures}}} day{{VALUE, plural, one{jour} other{jours}}} other{}}"
+ "TEXT_HISTORY_DURATION" : "@:APP.TEXT_HISTORY_DURATION"
},
@@ -461,7 +463,18 @@
"SETTINGS_CONNECTION_HISTORY" : {
- "FIELD_PLACEHOLDER_FILTER" : "@:APP.FIELD_PLACEHOLDER_FILTER"
+ "FIELD_PLACEHOLDER_FILTER" : "@:APP.FIELD_PLACEHOLDER_FILTER",
+
+ "FORMAT_DATE" : "@:APP.FORMAT_DATE_TIME_PRECISE",
+
+ "INFO_CONNECTION_DURATION_UNKNOWN" : "--",
+
+ "TABLE_HEADER_SESSION_CONNECTION_NAME" : "Nom de connexion",
+ "TABLE_HEADER_SESSION_DURATION" : "Durée",
+ "TABLE_HEADER_SESSION_STARTDATE" : "Ouvert depuis",
+ "TABLE_HEADER_SESSION_USERNAME" : "Identifiant",
+
+ "TEXT_HISTORY_DURATION" : "@:APP.TEXT_HISTORY_DURATION"
},
diff --git a/guacamole/src/main/webapp/translations/it.json b/guacamole/src/main/webapp/translations/it.json
index 40282016e..d778e8376 100644
--- a/guacamole/src/main/webapp/translations/it.json
+++ b/guacamole/src/main/webapp/translations/it.json
@@ -192,8 +192,7 @@
"TABLE_HEADER_HISTORY_START" : "Start Time",
"TABLE_HEADER_HISTORY_DURATION" : "Durata",
- "TEXT_CONFIRM_DELETE" : "Le Connessioni non possono essere ripristinate dopo la loro eliminazione. Sei sicuro di volere eliminare questa connessione?",
- "TEXT_HISTORY_DURATION" : "{VALUE} {UNIT, select, second{{VALUE, plural, one{second} other{seconds}}} minute{{VALUE, plural, one{minute} other{minutes}}} hour{{VALUE, plural, one{hour} other{hours}}} day{{VALUE, plural, one{day} other{days}}} other{}}"
+ "TEXT_CONFIRM_DELETE" : "Le Connessioni non possono essere ripristinate dopo la loro eliminazione. Sei sicuro di volere eliminare questa connessione?"
},
@@ -461,7 +460,16 @@
"SETTINGS_CONNECTION_HISTORY" : {
- "FIELD_PLACEHOLDER_FILTER" : "@:APP.FIELD_PLACEHOLDER_FILTER"
+ "FIELD_PLACEHOLDER_FILTER" : "@:APP.FIELD_PLACEHOLDER_FILTER",
+
+ "FORMAT_DATE" : "@:APP.FORMAT_DATE_TIME_PRECISE",
+
+ "INFO_CONNECTION_DURATION_UNKNOWN" : "--",
+
+ "TABLE_HEADER_SESSION_CONNECTION_NAME" : "Nome della connessione",
+ "TABLE_HEADER_SESSION_STARTDATE" : "Start Time",
+ "TABLE_HEADER_SESSION_DURATION" : "Durata",
+ "TABLE_HEADER_SESSION_USERNAME" : "Username"
},
diff --git a/guacamole/src/main/webapp/translations/nl.json b/guacamole/src/main/webapp/translations/nl.json
index d5945a94a..8c0cfd94f 100644
--- a/guacamole/src/main/webapp/translations/nl.json
+++ b/guacamole/src/main/webapp/translations/nl.json
@@ -38,7 +38,9 @@
"INFO_ACTIVE_USER_COUNT" : "Op dit moment in gebruik door {USERS} {USERS, plural, one{gebruiker} other{gebruikers}}.",
- "NAME" : "Guacamole ${project.version}"
+ "NAME" : "Guacamole ${project.version}",
+
+ "TEXT_HISTORY_DURATION" : "{VALUE} {UNIT, select, second{{VALUE, plural, one{seconde} other{seconden}}} minute{{VALUE, plural, one{minuut} other{minuten}}} hour{{VALUE, plural, one{uur} other{uren}}} day{{VALUE, plural, one{dag} other{dagen}}} other{}}"
},
@@ -202,7 +204,7 @@
"TABLE_HEADER_HISTORY_DURATION" : "Tijdsduur",
"TEXT_CONFIRM_DELETE" : "Verbindingen kunnen niet worden hersteld nadat ze zijn verwijderd. Weet u zeker dat u deze verbinding wilt verwijderen?",
- "TEXT_HISTORY_DURATION" : "{VALUE} {UNIT, select, second{{VALUE, plural, one{seconde} other{seconden}}} minute{{VALUE, plural, one{minuut} other{minuten}}} hour{{VALUE, plural, one{uur} other{uren}}} day{{VALUE, plural, one{dag} other{dagen}}} other{}}"
+ "TEXT_HISTORY_DURATION" : "@:APP.TEXT_HISTORY_DURATION"
},
@@ -490,12 +492,15 @@
"HELP_CONNECTION_HISTORY" : "De gebruikgeschiedenis van verbindingen wordt hier onder getoond en kan gesorteerd worden door op de titel van de kolom te klikken. Voer een zoekterm in en klik op \"Zoeken\", om op specifieke resultaten te zoeken. Alleen de resultaten die voldoen aan de zoekterm zullen dan getoond worden.",
- "INFO_NO_HISTORY" : "Geen resultaten gevonden",
+ "INFO_CONNECTION_DURATION_UNKNOWN" : "--",
+ "INFO_NO_HISTORY" : "Geen resultaten gevonden",
"TABLE_HEADER_SESSION_CONNECTION_NAME" : "Verbindingsnaam",
- "TABLE_HEADER_SESSION_ENDDATE" : "Eindtijd",
+ "TABLE_HEADER_SESSION_DURATION" : "Tijdsduur",
"TABLE_HEADER_SESSION_STARTDATE" : "Starttijd",
- "TABLE_HEADER_SESSION_USERNAME" : "Gebruikersnaam"
+ "TABLE_HEADER_SESSION_USERNAME" : "Gebruikersnaam",
+
+ "TEXT_HISTORY_DURATION" : "@:APP.TEXT_HISTORY_DURATION"
},
diff --git a/guacamole/src/main/webapp/translations/ru.json b/guacamole/src/main/webapp/translations/ru.json
index ecef5f39a..c5add3744 100644
--- a/guacamole/src/main/webapp/translations/ru.json
+++ b/guacamole/src/main/webapp/translations/ru.json
@@ -35,7 +35,9 @@
"INFO_ACTIVE_USER_COUNT" : "Подключено пользователей {USERS}.",
- "NAME" : "Guacamole ${project.version}"
+ "NAME" : "Guacamole ${project.version}",
+
+ "TEXT_HISTORY_DURATION" : "{VALUE} {UNIT, select, second{{VALUE, plural, one{секунда} other{сек}}} minute{{VALUE, plural, one{минута} other{мин}}} hour{{VALUE, plural, one{час} other{ч}}} day{{VALUE, plural, one{день} other{дн}}} other{}}"
},
@@ -190,7 +192,7 @@
"TABLE_HEADER_HISTORY_DURATION" : "Продолжительность",
"TEXT_CONFIRM_DELETE" : "Подключения не могут быть восстановлены после удаления. Вы уверены, что хотите удалить подключение?",
- "TEXT_HISTORY_DURATION" : "{VALUE} {UNIT, select, second{{VALUE, plural, one{секунда} other{сек}}} minute{{VALUE, plural, one{минута} other{мин}}} hour{{VALUE, plural, one{час} other{ч}}} day{{VALUE, plural, one{день} other{дн}}} other{}}"
+ "TEXT_HISTORY_DURATION" : "@:APP.TEXT_HISTORY_DURATION"
},
@@ -429,7 +431,18 @@
"SETTINGS_CONNECTION_HISTORY" : {
- "FIELD_PLACEHOLDER_FILTER" : "@:APP.FIELD_PLACEHOLDER_FILTER"
+ "FIELD_PLACEHOLDER_FILTER" : "@:APP.FIELD_PLACEHOLDER_FILTER",
+
+ "FORMAT_DATE" : "@:APP.FORMAT_DATE_TIME_PRECISE",
+
+ "INFO_CONNECTION_DURATION_UNKNOWN" : "--",
+
+ "TABLE_HEADER_SESSION_CONNECTION_NAME" : "Название подключения",
+ "TABLE_HEADER_SESSION_DURATION" : "Продолжительность",
+ "TABLE_HEADER_SESSION_STARTDATE" : "Время начала",
+ "TABLE_HEADER_SESSION_USERNAME" : "Имя пользователя",
+
+ "TEXT_HISTORY_DURATION" : "@:APP.TEXT_HISTORY_DURATION"
},