diff --git a/guacamole/src/main/webapp/app/index/config/indexRouteConfig.js b/guacamole/src/main/webapp/app/index/config/indexRouteConfig.js
index c980705ea..cf2434586 100644
--- a/guacamole/src/main/webapp/app/index/config/indexRouteConfig.js
+++ b/guacamole/src/main/webapp/app/index/config/indexRouteConfig.js
@@ -44,10 +44,22 @@ angular.module('index').config(['$routeProvider', '$locationProvider',
})
.when('/manage/connections/:id?', {
title: 'application.title',
- bodyClassName: 'manage-connection',
+ bodyClassName: 'manage',
templateUrl: 'app/manage/templates/manageConnection.html',
controller: 'manageConnectionController'
})
+ .when('/manage/connectionGroups/:id?', {
+ title: 'application.title',
+ bodyClassName: 'manage',
+ templateUrl: 'app/manage/templates/manageConnectionGroup.html',
+ controller: 'manageConnectionGroupController'
+ })
+ .when('/manage/users/:id', {
+ title: 'application.title',
+ bodyClassName: 'manage',
+ templateUrl: 'app/manage/templates/manageUser.html',
+ controller: 'manageUserController'
+ })
.when('/login/', {
title: 'application.title',
bodyClassName: 'login',
diff --git a/guacamole/src/main/webapp/app/home/styles/connection.css b/guacamole/src/main/webapp/app/index/styles/lists.css
similarity index 97%
rename from guacamole/src/main/webapp/app/home/styles/connection.css
rename to guacamole/src/main/webapp/app/index/styles/lists.css
index 9d659d20f..ad0a1d542 100644
--- a/guacamole/src/main/webapp/app/home/styles/connection.css
+++ b/guacamole/src/main/webapp/app/index/styles/lists.css
@@ -20,33 +20,33 @@
* THE SOFTWARE.
*/
+.user,
.group,
.connection {
cursor: pointer;
}
+.user a,
.connection a,
.group a {
text-decoration:none;
color: black;
}
+.user a:hover,
.connection a:hover,
.group a:hover {
text-decoration:none;
color: black;
}
+.user a:visited,
.connection a:visited,
.group a:visited {
text-decoration:none;
color: black;
}
-.group .connection .bears {
- display: none;
-}
-
.connection:hover {
background: #CDA;
}
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
index eca91e8a7..e6396c631 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
@@ -26,115 +26,181 @@
angular.module('manage').controller('manageConnectionController', ['$scope', '$injector',
function manageConnectionController($scope, $injector) {
- var $routeParams = $injector.get('$routeParams');
- var connectionService = $injector.get('connectionService');
- var connectionGroupService = $injector.get('connectionGroupService');
- var protocolService = $injector.get('protocolService');
- var Connection = $injector.get('Connection');
- var ConnectionGroup = $injector.get('ConnectionGroup');
- var PermissionSet = $injector.get('PermissionSet');
- var HistoryEntryWrapper = $injector.get('HistoryEntryWrapper');
-
+ // Required types
+ var Connection = $injector.get('Connection');
+ var ConnectionGroup = $injector.get('ConnectionGroup');
+ var HistoryEntryWrapper = $injector.get('HistoryEntryWrapper');
+ var PermissionSet = $injector.get('PermissionSet');
+
+ // Required services
+ var $location = $injector.get('$location');
+ var $routeParams = $injector.get('$routeParams');
+ var connectionService = $injector.get('connectionService');
+ var connectionGroupService = $injector.get('connectionGroupService');
+ var protocolService = $injector.get('protocolService');
+
+ /**
+ * An action to be provided along with the object sent to showStatus which
+ * closes the currently-shown status dialog.
+ */
+ var ACKNOWLEDGE_ACTION = {
+ name : "manage.error.action.acknowledge",
+ // Handle action
+ callback : function acknowledgeCallback() {
+ $scope.showStatus(false);
+ }
+ };
+
+ /**
+ * The identifier of the connection being edited. If a new connection is
+ * being created, this will not be defined.
+ *
+ * @type String
+ */
var identifier = $routeParams.id;
- // Make a copy of the old connection so that we can copy over the changes when done
- var oldConnection = $scope.connection;
-
+ // Pull connection group hierarchy
connectionGroupService.getConnectionGroupTree(ConnectionGroup.ROOT_IDENTIFIER, PermissionSet.ObjectPermissionType.UPDATE)
.success(function connectionGroupReceived(rootGroup) {
$scope.rootGroup = rootGroup;
$scope.loadingConnections = false;
});
- // Get the protocol information from the server and copy it into the scope
- protocolService.getProtocols().success(function fetchProtocols(protocols) {
+ // Get protocol metadata
+ protocolService.getProtocols().success(function protocolsReceived(protocols) {
$scope.protocols = protocols;
});
- // Wrap all the history entries
+ // If we are editing an existing connection, pull its data
if (identifier) {
- // Copy data into a new conection object in case the user doesn't want to save
+ // Pull data from existing connection
connectionService.getConnection(identifier).success(function connectionRetrieved(connection) {
$scope.connection = connection;
});
-
- connectionService.getConnectionHistory(identifier).success(function wrapHistoryEntries(historyEntries) {
+
+ // Pull connection history
+ connectionService.getConnectionHistory(identifier).success(function historyReceived(historyEntries) {
+
+ // Wrap all history entries for sake of display
$scope.historyEntryWrappers = [];
historyEntries.forEach(function wrapHistoryEntry(historyEntry) {
$scope.historyEntryWrappers.push(new HistoryEntryWrapper(historyEntry));
});
+
});
- connectionService.getConnectionParameters(identifier).success(function setParameters(parameters) {
+ // Pull connection parameters
+ connectionService.getConnectionParameters(identifier).success(function parametersReceived(parameters) {
$scope.parameters = parameters;
});
}
+
+ // If we are creating a new connection, populate skeleton connection data
else {
$scope.connection = new Connection({ protocol: 'vnc' });
$scope.historyEntryWrappers = [];
$scope.parameters = {};
}
-
+
/**
- * Close the modal.
+ * Cancels all pending edits, returning to the management page.
*/
- $scope.close = function close() {
- //connectionEditModal.deactivate();
+ $scope.cancel = function cancel() {
+ $location.path('/manage/');
};
-
+
/**
- * Save the connection and close the modal.
+ * Saves the connection, creating a new connection or updating the existing
+ * connection.
*/
- $scope.save = function save() {
- connectionService.saveConnection($scope.connection).success(function successfullyUpdatedConnection() {
-
- var oldParentID = oldConnection.parentIdentifier;
- var newParentID = $scope.connection.parentIdentifier;
-
- // Copy the data back to the original model
- angular.extend(oldConnection, $scope.connection);
-
- // We have to move this connection
- if(oldParentID !== newParentID)
-
- // New connections are created by default in root - don't try to move it if it's already there.
- if(newConnection && newParentID === $scope.rootGroup.identifier) {
- $scope.moveItem($scope.connection, oldParentID, newParentID);
- } else {
- connectionService.moveConnection($scope.connection).then(function moveConnection() {
- $scope.moveItem($scope.connection, oldParentID, newParentID);
- });
- }
-
- // Close the modal
- //connectionEditModal.deactivate();
+ $scope.saveConnection = function saveConnection() {
+
+ $scope.connection.parameters = $scope.parameters;
+
+ // Save the connection
+ connectionService.saveConnection($scope.connection)
+ .success(function savedConnection() {
+ $location.path('/manage/');
+ })
+
+ // Notify of any errors
+ .error(function connectionSaveFailed(error) {
+ $scope.showStatus({
+ 'className' : 'error',
+ 'title' : 'manage.error.title',
+ 'text' : error.message,
+ 'actions' : [ ACKNOWLEDGE_ACTION ]
+ });
});
+
+
};
/**
- * Delete the connection and close the modal.
+ * An action to be provided along with the object sent to showStatus which
+ * closes the currently-shown status dialog.
*/
- $scope['delete'] = function deleteConnection() {
-
- // Nothing to delete if the connection is new
- var newConnection = !$scope.connection.identifier;
- if(newConnection) {
- // Close the modal
- //connectionEditModal.deactivate();
- return;
+ var DELETE_ACTION = {
+ name : "manage.edit.connection.delete",
+ className : "danger",
+ // Handle action
+ callback : function deleteCallback() {
+ deleteConnectionImmediately();
+ $scope.showStatus(false);
}
-
- connectionService.deleteConnection($scope.connection).success(function successfullyDeletedConnection() {
- var oldParentID = oldConnection.parentIdentifier;
-
- // We have to remove this connection from the heirarchy
- $scope.moveItem($scope.connection, oldParentID);
-
- // Close the modal
- //connectionEditModal.deactivate();
+ };
+
+ /**
+ * An action to be provided along with the object sent to showStatus which
+ * closes the currently-shown status dialog.
+ */
+ var CANCEL_ACTION = {
+ name : "manage.edit.connection.cancel",
+ // Handle action
+ callback : function cancelCallback() {
+ $scope.showStatus(false);
+ }
+ };
+
+ /**
+ * Immediately deletes the current connection, without prompting the user
+ * for confirmation.
+ */
+ var deleteConnectionImmediately = function deleteConnectionImmediately() {
+
+ // Delete the connection
+ connectionService.deleteConnection($scope.connection)
+ .success(function deletedConnection() {
+ $location.path('/manage/');
+ })
+
+ // Notify of any errors
+ .error(function connectionDeletionFailed(error) {
+ $scope.showStatus({
+ 'className' : 'error',
+ 'title' : 'manage.error.title',
+ 'text' : error.message,
+ 'actions' : [ ACKNOWLEDGE_ACTION ]
+ });
});
+
+ };
+
+ /**
+ * Deletes the connection, prompting the user first to confirm that
+ * deletion is desired.
+ */
+ $scope.deleteConnection = function deleteConnection() {
+
+ // Confirm deletion request
+ $scope.showStatus({
+ 'title' : 'manage.edit.connection.confirmDelete.title',
+ 'text' : 'manage.edit.connection.confirmDelete.text',
+ 'actions' : [ DELETE_ACTION, CANCEL_ACTION]
+ });
+
};
}]);
diff --git a/guacamole/src/main/webapp/app/manage/controllers/connectionGroupEditModalController.js b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
similarity index 73%
rename from guacamole/src/main/webapp/app/manage/controllers/connectionGroupEditModalController.js
rename to guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
index 68ba74f51..87520c03d 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/connectionGroupEditModalController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
@@ -23,35 +23,47 @@
/**
* The controller for the connection group edit modal.
*/
-angular.module('manage').controller('connectionGroupEditModalController', ['$scope', '$injector',
- function connectionEditModalController($scope, $injector) {
+angular.module('manage').controller('manageConnectionGroupController', ['$scope', '$injector',
+ function manageConnectionGroupController($scope, $injector) {
- var connectionGroupEditModal = $injector.get('connectionGroupEditModal');
- var connectionGroupService = $injector.get('connectionGroupService');
-
- // Make a copy of the old connection group so that we can copy over the changes when done
- var oldConnectionGroup = $scope.connectionGroup;
+ // Required types
+ var ConnectionGroup = $injector.get('ConnectionGroup');
+ var PermissionSet = $injector.get('PermissionSet');
+
+ // Required services
+ var connectionGroupService = $injector.get('connectionGroupService');
+ var $routeParams = $injector.get('$routeParams');
// Copy data into a new conection group object in case the user doesn't want to save
- $scope.connectionGroup = angular.copy($scope.connectionGroup);
-
- var newConnectionGroup = !$scope.connectionGroup.identifier;
-
+ var identifier = $routeParams.id;
+
+ // Pull connection group data
+ if (identifier) {
+ connectionGroupService.getConnectionGroup(identifier).success(function connectionGroupReceived(connectionGroup) {
+ $scope.connectionGroup = connectionGroup;
+ });
+ }
+
+ else
+ $scope.connectionGroup = new ConnectionGroup();
+
+ connectionGroupService.getConnectionGroupTree(ConnectionGroup.ROOT_IDENTIFIER, PermissionSet.ObjectPermissionType.UPDATE)
+ .success(function connectionGroupReceived(rootGroup) {
+ $scope.rootGroup = rootGroup;
+ $scope.loadingConnections = false;
+ });
+
$scope.types = [
{
label: "organizational",
- value: "ORGANIZATIONAL"
+ value: ConnectionGroup.Type.ORGANIZATIONAL
},
{
- label: "balancing",
- value: "BALANCING"
+ label : "balancing",
+ value : ConnectionGroup.Type.BALANCING
}
];
- // Set it to organizational by default
- if(!$scope.connectionGroup.type)
- $scope.connectionGroup.type = $scope.types[0].value;
-
/**
* Close the modal.
*/
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageController.js b/guacamole/src/main/webapp/app/manage/controllers/manageController.js
index 7fc5e0a08..80af55931 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageController.js
@@ -27,146 +27,78 @@ angular.module('manage').controller('manageController', ['$scope', '$injector',
function manageController($scope, $injector) {
// Required types
- var PermissionSet = $injector.get('PermissionSet');
var ConnectionGroup = $injector.get('ConnectionGroup');
+ var PermissionSet = $injector.get('PermissionSet');
+ var User = $injector.get('User');
// Required services
- var connectionGroupService = $injector.get('connectionGroupService');
- var connectionGroupEditModal = $injector.get('connectionGroupEditModal');
- var userEditModal = $injector.get('userEditModal');
- var protocolService = $injector.get('protocolService');
- var userService = $injector.get('userService');
-
- // Set status to loading until we have all the connections, groups, and users have loaded
- $scope.loadingUsers = true;
- $scope.loadingConnections = true;
-
- $scope.basicPermissionsLoaded.then(function basicPermissionsHaveBeenLoaded() {
+ var connectionGroupService = $injector.get('connectionGroupService');
+ var userService = $injector.get('userService');
- // Retrieve all users for whom we have UPDATE permission
- connectionGroupService.getConnectionGroupTree(ConnectionGroup.ROOT_IDENTIFIER, PermissionSet.ObjectPermissionType.UPDATE)
- .success(function connectionGroupReceived(rootGroup) {
- $scope.rootGroup = rootGroup;
- $scope.loadingConnections = false;
- });
-
- // Retrieve all users for whom we have UPDATE permission
- userService.getUsers(PermissionSet.ObjectPermissionType.UPDATE)
- .success(function usersReceived(users) {
- $scope.users = users;
- $scope.loadingUsers = false;
- });
-
- });
-
- $scope.protocols = {};
-
- // Get the protocol information from the server and copy it into the scope
- protocolService.getProtocols().success(function fetchProtocols(protocols) {
- $scope.protocols = protocols;
- });
-
- // Expose object edit functions to group list template
- $scope.groupListContext = {
-
- /**
- * Open a modal to edit the given connection.
- *
- * @param {Connection} connection
- * The connection to edit.
- */
- editConnection : function editConnection(connection) {
- connectionEditModal.activate({
- connection : connection,
- protocols : $scope.protocols,
- rootGroup : $scope.rootGroup
- });
- },
-
- /**
- * Open a modal to edit the given connection group.
- *
- * @param {ConnectionGroup} connectionGroup
- * The connection group to edit.
- */
- editConnectionGroup : function editConnectionGroup(connectionGroup) {
- connectionGroupEditModal.activate({
- connectionGroup : connectionGroup,
- rootGroup : $scope.rootGroup
- });
+ /**
+ * An action to be provided along with the object sent to showStatus which
+ * closes the currently-shown status dialog.
+ */
+ var ACKNOWLEDGE_ACTION = {
+ name : "manage.error.action.acknowledge",
+ // Handle action
+ callback : function acknowledgeCallback() {
+ $scope.showStatus(false);
}
+ };
- };
-
/**
- * Open a modal to create a new connection.
+ * The name of the new user to create, if any, when user creation is
+ * requested via newUser().
+ *
+ * @type String
*/
- $scope.newConnection = function newConnection() {
- connectionEditModal.activate(
- {
- connection : {},
- protocols : $scope.protocols,
- rootGroup : $scope.rootGroup
- });
- };
-
- /**
- * Open a modal to create a new connection group.
- */
- $scope.newConnectionGroup = function newConnectionGroup() {
- connectionGroupEditModal.activate(
- {
- connectionGroup : {},
- rootGroup : $scope.rootGroup
- });
- };
-
- // Remove the user from the current list of users
- function removeUser(user) {
- for(var i = 0; i < $scope.users.length; i++) {
- if($scope.users[i].username === user.username) {
- $scope.users.splice(i, 1);
- break;
- }
- }
- }
-
- /**
- * Open a modal to edit the user.
- *
- * @param {object} user The user to edit.
- */
- $scope.editUser = function editUser(user) {
- userEditModal.activate(
- {
- user : user,
- rootGroup : $scope.rootGroup,
- removeUser : removeUser
- });
- };
-
$scope.newUsername = "";
+ // Retrieve all users for whom we have UPDATE permission
+ connectionGroupService.getConnectionGroupTree(ConnectionGroup.ROOT_IDENTIFIER, PermissionSet.ObjectPermissionType.UPDATE)
+ .success(function connectionGroupReceived(rootGroup) {
+ $scope.rootGroup = rootGroup;
+ });
+
+ // Retrieve all users for whom we have UPDATE permission
+ userService.getUsers(PermissionSet.ObjectPermissionType.UPDATE)
+ .success(function usersReceived(users) {
+ $scope.users = users;
+ });
+
/**
- * Open a modal to edit the user.
- *
- * @param {object} user The user to edit.
+ * Creates a new user having the username specified in the user creation
+ * interface.
*/
$scope.newUser = function newUser() {
- if($scope.newUsername) {
- var newUser = {
- username: $scope.newUsername
- };
-
- userService.createUser(newUser).success(function addUserToList() {
- $scope.users.push(newUser);
+
+ // Create user skeleton
+ var user = new User({
+ username: $scope.newUsername || ''
+ });
+
+ // Create specified user
+ userService.createUser(user)
+
+ // Add user to visible list upon success
+ .success(function userCreated() {
+ $scope.users.push(user);
+ })
+
+ // Notify of any errors
+ .error(function userCreationFailed(error) {
+ $scope.showStatus({
+ 'className' : 'error',
+ 'title' : 'manage.error.title',
+ 'text' : error.message,
+ 'actions' : [ ACKNOWLEDGE_ACTION ]
});
-
- $scope.newUsername = "";
- }
+ });
+
+ // Reset username
+ $scope.newUsername = "";
+
};
}]);
-
-
-
diff --git a/guacamole/src/main/webapp/app/manage/controllers/userEditModalController.js b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
similarity index 91%
rename from guacamole/src/main/webapp/app/manage/controllers/userEditModalController.js
rename to guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
index 3d7cadd6c..c62cb38fe 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/userEditModalController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
@@ -23,18 +23,20 @@
/**
* The controller for the connection edit modal.
*/
-angular.module('manage').controller('userEditModalController', ['$scope', '$injector',
- function userEditModalController($scope, $injector) {
+angular.module('manage').controller('manageUserController', ['$scope', '$injector',
+ function manageUserController($scope, $injector) {
- var userEditModal = $injector.get('userEditModal');
+ // Required services
+ var $routeParams = $injector.get('$routeParams');
var userService = $injector.get('userService');
var permissionService = $injector.get('permissionService');
- // Make a copy of the old user so that we can copy over the changes when done
- var oldUser = $scope.user;
-
- // Copy data into a new conection object in case the user doesn't want to save
- $scope.user = angular.copy($scope.user);
+ var identifier = $routeParams.id;
+
+ // Pull user data
+ userService.getUser(identifier).success(function userReceived(user) {
+ $scope.user = user;
+ });
/**
* Close the modal.
@@ -205,7 +207,7 @@ angular.module('manage').controller('userEditModalController', ['$scope', '$inje
originalSystemPermissions;
// Get the permissions for the user we are editing
- permissionService.getPermissions($scope.user.username).success(function gotPermissions(permissions) {
+ permissionService.getPermissions(identifier).success(function gotPermissions(permissions) {
$scope.permissions = permissions;
// Figure out if the user has any system level permissions
@@ -247,16 +249,8 @@ angular.module('manage').controller('userEditModalController', ['$scope', '$inje
// Close the modal
userEditModal.deactivate();
});
- }
-
- /**
- * Toggle the open/closed status of the connectionGroup.
- *
- * @param {object} connectionGroup The connection group to toggle.
- */
- $scope.toggleExpanded = function toggleExpanded(connectionGroup) {
- connectionGroup.expanded = !connectionGroup.expanded;
};
+
}]);
diff --git a/guacamole/src/main/webapp/app/manage/styles/buttons.css b/guacamole/src/main/webapp/app/manage/styles/buttons.css
index ca5c5665a..0e4925855 100644
--- a/guacamole/src/main/webapp/app/manage/styles/buttons.css
+++ b/guacamole/src/main/webapp/app/manage/styles/buttons.css
@@ -42,7 +42,7 @@ a.button.add-connection {
}
-button.add-connection-group {
+a.button.add-connection-group {
background-image: url('images/action-icons/guac-group-add.png');
background-repeat: no-repeat;
diff --git a/guacamole/src/main/webapp/app/manage/styles/manageConnection.css b/guacamole/src/main/webapp/app/manage/styles/forms.css
similarity index 87%
rename from guacamole/src/main/webapp/app/manage/styles/manageConnection.css
rename to guacamole/src/main/webapp/app/manage/styles/forms.css
index 8df3ede5c..656d86a20 100644
--- a/guacamole/src/main/webapp/app/manage/styles/manageConnection.css
+++ b/guacamole/src/main/webapp/app/manage/styles/forms.css
@@ -20,19 +20,17 @@
* THE SOFTWARE.
*/
-.manage-connection .info table,
-.manage-connection .parameters table {
+.manage .properties table {
margin: 1em;
}
-.manage-connection .info table th,
-.manage-connection .parameters table th {
+.manage .properties table th {
text-align: left;
font-weight: normal;
padding-right: 1em;
}
-.manage-connection .action-buttons {
+.manage .action-buttons {
text-align: center;
margin-bottom: 1em;
}
diff --git a/guacamole/src/main/webapp/app/manage/templates/connectionGroup.html b/guacamole/src/main/webapp/app/manage/templates/connectionGroup.html
index 93acc8148..499c53daa 100644
--- a/guacamole/src/main/webapp/app/manage/templates/connectionGroup.html
+++ b/guacamole/src/main/webapp/app/manage/templates/connectionGroup.html
@@ -1,4 +1,4 @@
-
+
{{item.name}}
-
+
diff --git a/guacamole/src/main/webapp/app/manage/templates/editableConnectionGroup.html b/guacamole/src/main/webapp/app/manage/templates/editableConnectionGroup.html
deleted file mode 100644
index f10a348db..000000000
--- a/guacamole/src/main/webapp/app/manage/templates/editableConnectionGroup.html
+++ /dev/null
@@ -1,79 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/guacamole/src/main/webapp/app/manage/templates/manage.html b/guacamole/src/main/webapp/app/manage/templates/manage.html
index 231b02dda..55b6abed5 100644
--- a/guacamole/src/main/webapp/app/manage/templates/manage.html
+++ b/guacamole/src/main/webapp/app/manage/templates/manage.html
@@ -40,11 +40,11 @@ THE SOFTWARE.
-
\ No newline at end of file
diff --git a/guacamole/src/main/webapp/app/notification/templates/guacNotification.html b/guacamole/src/main/webapp/app/notification/templates/guacNotification.html
index 50d484fb2..a31cff250 100644
--- a/guacamole/src/main/webapp/app/notification/templates/guacNotification.html
+++ b/guacamole/src/main/webapp/app/notification/templates/guacNotification.html
@@ -41,7 +41,7 @@
-
+
diff --git a/guacamole/src/main/webapp/app/notification/types/NotificationAction.js b/guacamole/src/main/webapp/app/notification/types/NotificationAction.js
index d0e75cb6d..8a49adc52 100644
--- a/guacamole/src/main/webapp/app/notification/types/NotificationAction.js
+++ b/guacamole/src/main/webapp/app/notification/types/NotificationAction.js
@@ -35,8 +35,11 @@ angular.module('notification').factory('NotificationAction', [function defineNot
*
* @param {Function} callback
* The callback to call when the user elects to perform this action.
+ *
+ * @param {String} className
+ * The CSS class to associate with this action, if any.
*/
- var NotificationAction = function NotificationAction(name, callback) {
+ var NotificationAction = function NotificationAction(name, callback, className) {
/**
* Reference to this NotificationAction.
@@ -45,6 +48,13 @@ angular.module('notification').factory('NotificationAction', [function defineNot
*/
var action = this;
+ /**
+ * The CSS class associated with this action.
+ *
+ * @type String
+ */
+ this.className = className;
+
/**
* The name of this action.
*
diff --git a/guacamole/src/main/webapp/translations/en_US.json b/guacamole/src/main/webapp/translations/en_US.json
index 9fa497063..84637ccf2 100644
--- a/guacamole/src/main/webapp/translations/en_US.json
+++ b/guacamole/src/main/webapp/translations/en_US.json
@@ -43,6 +43,10 @@
"cancel" : "Cancel",
"save" : "Save",
"delete" : "Delete",
+ "confirmDelete" : {
+ "title" : "Delete Connection",
+ "text" : "Connections cannot be restored after they have been deleted. Are you sure you want to delete this connection?"
+ },
"protocol" : "Protocol:",
"root" : "ROOT",
"location" : "Location:",
@@ -87,6 +91,12 @@
"createConnectionGroup" : "Create new connection groups:",
"connections" : "Connections:"
}
+ },
+ "error": {
+ "title" : "Error",
+ "action": {
+ "acknowledge" : "OK"
+ }
}
},
"protocol": {