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 connectionService = $injector.get('connectionService');
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
var oldConnection = $scope.connection;
// 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;
if(newConnection)
@@ -45,6 +47,13 @@ angular.module('manage').controller('connectionEditModalController', ['$scope',
if(!$scope.connection.protocol)
$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.
*/
@@ -103,7 +112,8 @@ angular.module('manage').controller('connectionEditModalController', ['$scope',
// Close the modal
connectionEditModal.deactivate();
});
}
};
}]);

View File

@@ -24,7 +24,7 @@
/**
* A directive that allows editing of a connection parameter.
*/
angular.module('manage').directive('guacConnectionParameter', [function locationChooser() {
angular.module('manage').directive('guacConnectionParameter', [function connectionParameter() {
return {
// Element only
@@ -41,14 +41,44 @@ angular.module('manage').directive('guacConnectionParameter', [function location
$scope.parameterName = $scope.parameter.name;
// Coerce numeric strings to numbers
if($scope.parameterType === 'NUMERIC') {
$scope.connectionParameters[$scope.parameterName] =
Number($scope.connectionParameters[$scope.parameterName]) || 0;
// Coerce boolean strings to boolean values
} else if($scope.parameterType === 'BOOLEAN') {
$scope.connectionParameters[$scope.parameterName] =
$scope.connectionParameters[$scope.parameterName] === 'true';
if ($scope.parameterType === 'NUMERIC') {
// If a value exists, coerce it to a number
if ($scope.connectionParameters[$scope.parameterName])
$scope.parameterValue = Number($scope.connectionParameters[$scope.parameterName]);
else
$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.
*/
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
THE SOFTWARE.
-->
<input ng-show="parameterType === 'TEXT'" type="text" ng-model="connectionParameters[parameterName]"/>
<input ng-show="parameterType === 'NUMERIC'" type="number" ng-model="connectionParameters[parameterName]"/>
<input ng-show="parameterType === 'USERNAME'" type="text" ng-model="connectionParameters[parameterName]"/>
<input ng-show="parameterType === 'PASSWORD'" type="password" ng-model="connectionParameters[parameterName]"/>
<input ng-show="parameterType === 'BOOLEAN'" type="checkbox" ng-model="connectionParameters[parameterName]"/>
<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>
<input ng-show="parameterType === 'TEXT'" type="text" ng-model="parameterValue"/>
<input ng-show="parameterType === 'NUMERIC'" type="number" ng-model="parameterValue"/>
<input ng-show="parameterType === 'USERNAME'" type="text" ng-model="parameterValue"/>
<input ng-show="parameterType === 'PASSWORD'" type="password" ng-model="parameterValue"/>
<input ng-show="parameterType === 'BOOLEAN'" type="checkbox" ng-model="parameterValue"/>
<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>

View File

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