GUAC-933 Fixed connection history formatting, connection parameter saving, and create new connection view.

This commit is contained in:
James Muehlner
2014-12-09 23:30:14 -08:00
parent b76324667e
commit 3c55e97abe
7 changed files with 179 additions and 24 deletions

View File

@@ -29,12 +29,14 @@ angular.module('manage').controller('connectionEditModalController', ['$scope',
var connectionEditModal = $injector.get('connectionEditModal'); var connectionEditModal = $injector.get('connectionEditModal');
var connectionService = $injector.get('connectionService'); var connectionService = $injector.get('connectionService');
var displayObjectPreparationService = $injector.get('displayObjectPreparationService'); var displayObjectPreparationService = $injector.get('displayObjectPreparationService');
var Connection = $injector.get('Connection');
var HistoryEntryWrapper = $injector.get('HistoryEntryWrapper');
// Make a copy of the old connection so that we can copy over the changes when done // Make a copy of the old connection so that we can copy over the changes when done
var oldConnection = $scope.connection; var oldConnection = $scope.connection;
// Copy data into a new conection object in case the user doesn't want to save // Copy data into a new conection object in case the user doesn't want to save
$scope.connection = angular.copy($scope.connection); $scope.connection = new Connection($scope.connection);
var newConnection = !$scope.connection.identifier; var newConnection = !$scope.connection.identifier;
if(newConnection) if(newConnection)
@@ -45,6 +47,13 @@ angular.module('manage').controller('connectionEditModalController', ['$scope',
if(!$scope.connection.protocol) if(!$scope.connection.protocol)
$scope.connection.protocol = "vnc"; $scope.connection.protocol = "vnc";
$scope.historyEntryWrappers = [];
// Wrap all the history entries
$scope.connection.history.forEach(function wrapHistoryEntry(historyEntry) {
$scope.historyEntryWrappers.push(new HistoryEntryWrapper(historyEntry));
});
/** /**
* Close the modal. * Close the modal.
*/ */
@@ -103,7 +112,8 @@ angular.module('manage').controller('connectionEditModalController', ['$scope',
// Close the modal // Close the modal
connectionEditModal.deactivate(); connectionEditModal.deactivate();
}); });
} };
}]); }]);

View File

@@ -24,7 +24,7 @@
/** /**
* A directive that allows editing of a connection parameter. * A directive that allows editing of a connection parameter.
*/ */
angular.module('manage').directive('guacConnectionParameter', [function locationChooser() { angular.module('manage').directive('guacConnectionParameter', [function connectionParameter() {
return { return {
// Element only // Element only
@@ -41,14 +41,44 @@ angular.module('manage').directive('guacConnectionParameter', [function location
$scope.parameterName = $scope.parameter.name; $scope.parameterName = $scope.parameter.name;
// Coerce numeric strings to numbers // Coerce numeric strings to numbers
if($scope.parameterType === 'NUMERIC') { if ($scope.parameterType === 'NUMERIC') {
$scope.connectionParameters[$scope.parameterName] =
Number($scope.connectionParameters[$scope.parameterName]) || 0; // If a value exists, coerce it to a number
// Coerce boolean strings to boolean values if ($scope.connectionParameters[$scope.parameterName])
} else if($scope.parameterType === 'BOOLEAN') { $scope.parameterValue = Number($scope.connectionParameters[$scope.parameterName]);
$scope.connectionParameters[$scope.parameterName] = else
$scope.connectionParameters[$scope.parameterName] === 'true'; $scope.parameterValue = null;
} }
// Coerce boolean strings to boolean values
else if ($scope.parameterType === 'BOOLEAN') {
// TODO: Use defined checked value from protocol description
$scope.parameterValue = $scope.connectionParameters[$scope.parameterName] === 'true';
}
// All other parameter types are represented internally as strings
else
$scope.parameterValue = $scope.connectionParameters[$scope.parameterName];
// Update internal representation as model is changed
$scope.$watch('parameterValue', function parameterValueChanges(value) {
// Convert numeric values back into strings
if ($scope.parameterType === 'NUMERIC') {
if (value === null || typeof value === 'undefined')
$scope.connectionParameters[$scope.parameterName] = '';
else
$scope.connectionParameters[$scope.parameterName] = value.toString();
}
// TODO: Transform BOOLEAN input fields back into strings based on protocol description
// All other parameter types are already strings
else
$scope.connectionParameters[$scope.parameterName] = value;
});
}] }]
}; };

View File

@@ -23,5 +23,5 @@
/** /**
* The module for the administration functionality. * The module for the administration functionality.
*/ */
angular.module('manage', ['btford.modal', 'protocol', 'connectionGroup', 'util']); angular.module('manage', ['btford.modal', 'protocol', 'connection', 'connectionGroup', 'util']);

View File

@@ -20,10 +20,10 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
--> -->
<input ng-show="parameterType === 'TEXT'" type="text" ng-model="connectionParameters[parameterName]"/> <input ng-show="parameterType === 'TEXT'" type="text" ng-model="parameterValue"/>
<input ng-show="parameterType === 'NUMERIC'" type="number" ng-model="connectionParameters[parameterName]"/> <input ng-show="parameterType === 'NUMERIC'" type="number" ng-model="parameterValue"/>
<input ng-show="parameterType === 'USERNAME'" type="text" ng-model="connectionParameters[parameterName]"/> <input ng-show="parameterType === 'USERNAME'" type="text" ng-model="parameterValue"/>
<input ng-show="parameterType === 'PASSWORD'" type="password" ng-model="connectionParameters[parameterName]"/> <input ng-show="parameterType === 'PASSWORD'" type="password" ng-model="parameterValue"/>
<input ng-show="parameterType === 'BOOLEAN'" type="checkbox" ng-model="connectionParameters[parameterName]"/> <input ng-show="parameterType === 'BOOLEAN'" type="checkbox" ng-model="parameterValue"/>
<select ng-show="parameterType === 'ENUM'" ng-model="connectionParameters[parameterName]" ng-options="option.value as 'protocol.' + connection.protocol + '.parameters.' + parameter.name + '.options.' + (option.value || 'empty') | translate for option in parameter.options | orderBy: value"></select> <select ng-show="parameterType === 'ENUM'" ng-model="parameterValue" ng-options="option.value as 'protocol.' + connection.protocol + '.parameters.' + parameter.name + '.options.' + (option.value || 'empty') | translate for option in parameter.options | orderBy: value"></select>
</span> </span>

View File

@@ -94,12 +94,12 @@ THE SOFTWARE.
<th>{{'manage.edit.connection.history.duration' | translate}}</th> <th>{{'manage.edit.connection.history.duration' | translate}}</th>
</tr> </tr>
<tbody> <tbody>
<tr ng-repeat="record in connection.history"> <tr ng-repeat="wrapper in historyEntryWrappers">
<td class="username">{{record.username}}</td> <td class="username">{{wrapper.entry.username}}</td>
<td class="start">{{record.startDate | date:'short'}}</td> <td class="start">{{wrapper.entry.startDate | date:'short'}}</td>
<td ng-show="record.endDate && !record.active" class="duration">{{record.endDate - record.startDate}}</td> <td ng-show="wrapper.entry.endDate && !wrapper.entry.active" class="duration">{{'manage.edit.connection.history.formattedDuration' | translate:"{VALUE: wrapper.duration.value, UNIT: wrapper.duration.unit}"}}</td>
<td ng-show="!record.endDate && !record.active" class="duration">{{'manage.edit.connection.history.unknownEnd' | translate}}</td> <td ng-show="!wrapper.entry.endDate && !wrapper.entry.active" class="duration">{{'manage.edit.connection.history.unknownEnd' | translate}}</td>
<td ng-show="record.active" class="duration">{{'manage.edit.connection.history.activeNow' | translate}}</td> <td ng-show="wrapper.entry.active" class="duration">{{'manage.edit.connection.history.activeNow' | translate}}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@@ -0,0 +1,114 @@
/*
* 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 generating new guacClient properties objects.
*/
angular.module('manage').factory('HistoryEntryWrapper', [function defineHistoryEntryWrapper() {
/**
* Given a number of milliseconds, returns an object containing a unit and value
* for that history entry duration.
*
* @param {Number} milliseconds The number of milliseconds.
* @return {Object} A unit and value pair representing a history entry duration.
*/
var formatMilliseconds = function formatMilliseconds(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;
};
// Seconds
if (seconds < 60) {
return {
value : round(seconds),
unit : "second"
};
}
// Minutes
if (seconds < 3600) {
return {
value : round(seconds / 60 ),
unit : "minute"
};
}
// Hours
if (seconds < 86400) {
return {
value : round(seconds / 3600),
unit : "hour"
};
}
// Days
return {
value : round(seconds / 86400),
unit : "day"
};
};
/**
* Wrapper for ConnectionHistoryEntry which adds display-specific
* properties, such as the connection duration.
*
* @constructor
* @param {ConnectionHistoryEntry} historyEntry
* The history entry to wrap.
*/
var HistoryEntryWrapper = function HistoryEntryWrapper(historyEntry) {
/**
* The wrapped ConnectionHistoryEntry.
*
* @type ConnectionHistoryEntry
*/
this.entry = historyEntry;
/**
* An object providing value and unit properties, denoting the duration
* and its corresponding units.
*
* @type Object
*/
this.duration = null;
// Set the duration if the necessary information is present
if (historyEntry.endDate && historyEntry.startDate)
this.duration = formatMilliseconds(historyEntry.endDate - historyEntry.startDate);
};
return HistoryEntryWrapper;
}]);

View File

@@ -53,7 +53,8 @@
"startTime" : "Start Time", "startTime" : "Start Time",
"duration" : "Duration", "duration" : "Duration",
"activeNow" : "Active Now", "activeNow" : "Active Now",
"unknownEnd" : "--" "unknownEnd" : "--",
"formattedDuration" : "{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{}}"
} }
}, },
"connectionGroup": { "connectionGroup": {