You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by vn...@apache.org on 2018/05/04 08:27:02 UTC

[08/21] guacamole-client git commit: GUACAMOLE-220: Migrate sharing profile management screen to common buttons and permission logic.

GUACAMOLE-220: Migrate sharing profile management screen to common buttons and permission logic.


Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/c1f5ad40
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/c1f5ad40
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/c1f5ad40

Branch: refs/heads/master
Commit: c1f5ad407504c42f42158ea38e9da04e3842f3c1
Parents: 7e1dbf7
Author: Michael Jumper <mj...@apache.org>
Authored: Tue May 1 12:24:33 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue May 1 20:58:28 2018 -0700

----------------------------------------------------------------------
 .../manageSharingProfileController.js           | 355 ++++++++-----------
 .../manage/templates/manageSharingProfile.html  |  15 +-
 2 files changed, 161 insertions(+), 209 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/c1f5ad40/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js b/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
index 7414e65..a0a683c 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
@@ -24,15 +24,16 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
         function manageSharingProfileController($scope, $injector) {
 
     // Required types
-    var SharingProfile = $injector.get('SharingProfile');
-    var PermissionSet  = $injector.get('PermissionSet');
+    var ManagementPermissions = $injector.get('ManagementPermissions');
+    var SharingProfile        = $injector.get('SharingProfile');
+    var PermissionSet         = $injector.get('PermissionSet');
 
     // Required services
     var $location                = $injector.get('$location');
+    var $q                       = $injector.get('$q');
     var $routeParams             = $injector.get('$routeParams');
     var authenticationService    = $injector.get('authenticationService');
     var connectionService        = $injector.get('connectionService');
-    var guacNotification         = $injector.get('guacNotification');
     var permissionService        = $injector.get('permissionService');
     var requestService           = $injector.get('requestService');
     var schemaService            = $injector.get('schemaService');
@@ -40,18 +41,6 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
     var translationStringService = $injector.get('translationStringService');
 
     /**
-     * An action to be provided along with the object sent to showStatus which
-     * closes the currently-shown status dialog, effectively canceling the
-     * operation which was pending user confirmation.
-     */
-    var CANCEL_ACTION = {
-        name        : "MANAGE_SHARING_PROFILE.ACTION_CANCEL",
-        callback    : function cancelCallback() {
-            guacNotification.showStatus(false);
-        }
-    };
-
-    /**
      * The unique identifier of the data source containing the sharing profile
      * being edited.
      *
@@ -98,34 +87,13 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
     $scope.parameters = null;
 
     /**
-     * Whether the user can save the sharing profile being edited. This could be
-     * updating an existing sharing profile, or creating a new sharing profile.
-     *
-     * @type Boolean
-     */
-    $scope.canSaveSharingProfile = null;
-
-    /**
-     * Whether the user can delete the sharing profile being edited.
-     *
-     * @type Boolean
-     */
-    $scope.canDeleteSharingProfile = null;
-
-    /**
-     * Whether the user can clone the sharing profile being edited.
-     *
-     * @type Boolean
-     */
-    $scope.canCloneSharingProfile = null;
-
-    /**
-     * All permissions associated with the current user, or null if the user's
-     * permissions have not yet been loaded.
+     * The managment-related actions that the current user may perform on the
+     * sharing profile currently being created/modified, or null if the current
+     * user's permissions have not yet been loaded.
      *
-     * @type PermissionSet
+     * @type ManagementPermissions
      */
-    $scope.permissions = null;
+    $scope.managementPermissions = null;
 
     /**
      * All available sharing profile attributes. This is only the set of
@@ -149,146 +117,157 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
             && $scope.sharingProfile          !== null
             && $scope.primaryConnection       !== null
             && $scope.parameters              !== null
-            && $scope.permissions             !== null
-            && $scope.attributes              !== null
-            && $scope.canSaveSharingProfile   !== null
-            && $scope.canDeleteSharingProfile !== null
-            && $scope.canCloneSharingProfile  !== null;
+            && $scope.managementPermissions   !== null
+            && $scope.attributes              !== null;
 
     };
 
-    // Pull sharing profile attribute schema
-    schemaService.getSharingProfileAttributes($scope.selectedDataSource)
-    .then(function attributesReceived(attributes) {
-        $scope.attributes = attributes;
-    }, requestService.WARN);
-
-    // Query the user's permissions for the current sharing profile
-    permissionService.getEffectivePermissions($scope.selectedDataSource, authenticationService.getCurrentUsername())
-    .then(function permissionsReceived(permissions) {
-
-        $scope.permissions = permissions;
-
-        // The sharing profile can be saved if it is new or if the user has
-        // UPDATE permission for that sharing profile (either explicitly or by
-        // virtue of being an administrator)
-        $scope.canSaveSharingProfile =
-               !identifier
-            || PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER)
-            || PermissionSet.hasSharingProfilePermission(permissions, PermissionSet.ObjectPermissionType.UPDATE, identifier);
-
-        // The sharing profile can be saved only if it exists and the user has
-        // DELETE permission (either explicitly or by virtue of being an
-        // administrator)
-        $scope.canDeleteSharingProfile =
-            !!identifier && (
-                   PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER)
-               ||  PermissionSet.hasSharingProfilePermission(permissions, PermissionSet.ObjectPermissionType.DELETE, identifier)
-            );
-
-        // The sharing profile can be cloned only if it exists, the user has
-        // UPDATE permission on the sharing profile being cloned (is able to
-        // read parameters), and the user can create new sharing profiles
-        $scope.canCloneSharingProfile =
-            !!identifier && (
-               PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.ADMINISTER) || (
-                       PermissionSet.hasSharingProfilePermission(permissions, PermissionSet.ObjectPermissionType.UPDATE, identifier)
-                   &&  PermissionSet.hasSystemPermission(permissions, PermissionSet.SystemPermissionType.CREATE_SHARING_PROFILE)
-               )
-            );
-
-    }, requestService.WARN);
-
-    // Get protocol metadata
-    schemaService.getProtocols($scope.selectedDataSource)
-    .then(function protocolsReceived(protocols) {
-        $scope.protocols = protocols;
-    }, requestService.WARN);
-
-    // If we are editing an existing sharing profile, pull its data
-    if (identifier) {
-
-        // Pull data from existing sharing profile
-        sharingProfileService.getSharingProfile($scope.selectedDataSource, identifier)
-        .then(function sharingProfileRetrieved(sharingProfile) {
-            $scope.sharingProfile = sharingProfile;
-        }, requestService.WARN);
-
-        // Pull sharing profile parameters
-        sharingProfileService.getSharingProfileParameters($scope.selectedDataSource, identifier)
-        .then(function parametersReceived(parameters) {
-            $scope.parameters = parameters;
-        }, requestService.WARN);
-
-    }
+    /**
+     * Loads the data associated with the sharing profile having the given
+     * identifier, preparing the interface for making modifications to that
+     * existing sharing profile.
+     *
+     * @param {String} dataSource
+     *     The unique identifier of the data source containing the sharing
+     *     profile to load.
+     *
+     * @param {String} identifier
+     *     The identifier of the sharing profile to load.
+     *
+     * @returns {Promise}
+     *     A promise which is resolved when the interface has been prepared for
+     *     editing the given sharing profile.
+     */
+    var loadExistingSharingProfile = function loadExistingSharingProfile(dataSource, identifier) {
+        return $q.all({
+            sharingProfile : sharingProfileService.getSharingProfile(dataSource, identifier),
+            parameters     : sharingProfileService.getSharingProfileParameters(dataSource, identifier)
+        })
+        .then(function sharingProfileDataRetrieved(values) {
+
+            $scope.sharingProfile = values.sharingProfile;
+            $scope.parameters = values.parameters;
+
+            // Load connection object for associated primary connection
+            return connectionService.getConnection(
+                dataSource,
+                values.sharingProfile.primaryConnectionIdentifier
+            )
+            .then(function connectionRetrieved(connection) {
+                $scope.primaryConnection = connection;
+            });
 
-    // If we are cloning an existing sharing profile, pull its data instead
-    else if (cloneSourceIdentifier) {
+        });
+    };
 
-        // Pull data from cloned sharing profile
-        sharingProfileService.getSharingProfile($scope.selectedDataSource, cloneSourceIdentifier)
-        .then(function sharingProfileRetrieved(sharingProfile) {
+    /**
+     * Loads the data associated with the sharing profile having the given
+     * identifier, preparing the interface for cloning that existing
+     * sharing profile.
+     *
+     * @param {String} dataSource
+     *     The unique identifier of the data source containing the sharing
+     *     profile to be cloned.
+     *
+     * @param {String} identifier
+     *     The identifier of the sharing profile being cloned.
+     *
+     * @returns {Promise}
+     *     A promise which is resolved when the interface has been prepared for
+     *     cloning the given sharing profile.
+     */
+    var loadClonedSharingProfile = function loadClonedSharingProfile(dataSource, identifier) {
+        return $q.all({
+            sharingProfile : sharingProfileService.getSharingProfile(dataSource, identifier),
+            parameters     : sharingProfileService.getSharingProfileParameters(dataSource, identifier)
+        })
+        .then(function sharingProfileDataRetrieved(values) {
 
-            // Store data of sharing profile being cloned
-            $scope.sharingProfile = sharingProfile;
+            $scope.sharingProfile = values.sharingProfile;
+            $scope.parameters = values.parameters;
 
             // Clear the identifier field because this sharing profile is new
             delete $scope.sharingProfile.identifier;
 
-        }, requestService.WARN);
-
-        // Pull sharing profile parameters from cloned sharing profile
-        sharingProfileService.getSharingProfileParameters($scope.selectedDataSource, cloneSourceIdentifier)
-        .then(function parametersReceived(parameters) {
-            $scope.parameters = parameters;
-        }, requestService.WARN);
+            // Load connection object for associated primary connection
+            return connectionService.getConnection(
+                dataSource,
+                values.sharingProfile.primaryConnectionIdentifier
+            )
+            .then(function connectionRetrieved(connection) {
+                $scope.primaryConnection = connection;
+            });
 
-    }
+        });
+    };
 
-    // If we are creating a new sharing profile, populate skeleton sharing
-    // profile data
-    else {
+    /**
+     * Loads skeleton sharing profile data, preparing the interface for
+     * creating a new sharing profile.
+     *
+     * @returns {Promise}
+     *     A promise which is resolved when the interface has been prepared for
+     *     creating a new sharing profile.
+     */
+    var loadSkeletonSharingProfile = function loadSkeletonSharingProfile() {
 
+        // Use skeleton sharing profile object with no associated parameters
         $scope.sharingProfile = new SharingProfile({
             primaryConnectionIdentifier : $location.search().parent
         });
-
         $scope.parameters = {};
 
-    }
-
-    // Populate primary connection once its identifier is known
-    $scope.$watch('sharingProfile.primaryConnectionIdentifier',
-        function retrievePrimaryConnection(identifier) {
-
-        if (identifier) {
-            connectionService.getConnection($scope.selectedDataSource, identifier)
-            .then(function connectionRetrieved(connection) {
-                $scope.primaryConnection = connection;
-            }, requestService.WARN);
-        }
+        return $q.resolve();
 
-    });
+    };
 
     /**
-     * Returns whether the current user can change/set all sharing profile
-     * attributes for the sharing profile being edited, regardless of whether
-     * those attributes are already explicitly associated with that sharing
-     * profile.
+     * Loads the data requred for performing the management task requested
+     * through the route parameters given at load time, automatically preparing
+     * the interface for editing an existing sharing profile, cloning an
+     * existing sharing profile, or creating an entirely new sharing profile.
      *
-     * @returns {Boolean}
-     *     true if the current user can change all attributes for the sharing
-     *     profile being edited, regardless of whether those attributes are
-     *     already explicitly associated with that sharing profile, false
-     *     otherwise.
+     * @returns {Promise}
+     *     A promise which is resolved when the interface has been prepared
+     *     for performing the requested management task.
      */
-    $scope.canChangeAllAttributes = function canChangeAllAttributes() {
+    var loadRequestedSharingProfile = function loadRequestedSharingProfile() {
+
+        // If we are editing an existing sharing profile, pull its data
+        if (identifier)
+            return loadExistingSharingProfile($scope.selectedDataSource, identifier);
 
-        // All attributes can be set if we are creating the sharing profile
-        return !identifier;
+        // If we are cloning an existing sharing profile, pull its data instead
+        if (cloneSourceIdentifier)
+            return loadClonedSharingProfile($scope.selectedDataSource, cloneSourceIdentifier);
+
+        // If we are creating a new sharing profile, populate skeleton sharing
+        // profile data
+        return loadSkeletonSharingProfile();
 
     };
 
+
+    // Query the user's permissions for the current sharing profile
+    $q.all({
+        sharingProfileData : loadRequestedSharingProfile(),
+        attributes  : schemaService.getSharingProfileAttributes($scope.selectedDataSource),
+        protocols   : schemaService.getProtocols($scope.selectedDataSource),
+        permissions : permissionService.getEffectivePermissions($scope.selectedDataSource, authenticationService.getCurrentUsername())
+    })
+    .then(function sharingProfileDataRetrieved(values) {
+
+        $scope.attributes = values.attributes;
+        $scope.protocols = values.protocols;
+
+        $scope.managementPermissions = ManagementPermissions.fromPermissionSet(
+                    values.permissions,
+                    PermissionSet.SystemPermissionType.CREATE_CONNECTION,
+                    PermissionSet.hasConnectionPermission,
+                    identifier);
+
+    }, requestService.WARN);
+
     /**
      * Returns the translation string namespace for the protocol having the
      * given name. The namespace will be of the form:
@@ -316,9 +295,10 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
     };
 
     /**
-     * Cancels all pending edits, returning to the management page.
+     * Cancels all pending edits, returning to the main list of connections
+     * within the selected data source.
      */
-    $scope.cancel = function cancel() {
+    $scope.returnToConnectionList = function returnToConnectionList() {
         $location.url('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
     };
 
@@ -332,64 +312,35 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
     };
 
     /**
-     * Saves the sharing profile, creating a new sharing profile or updating
-     * the existing sharing profile.
+     * Saves the current sharing profile, creating a new sharing profile or
+     * updating the existing sharing profile, returning a promise which is
+     * resolved if the save operation succeeds and rejected if the save
+     * operation fails.
+     *
+     * @returns {Promise}
+     *     A promise which is resolved if the save operation succeeds and is
+     *     rejected with an {@link Error} if the save operation fails.
      */
     $scope.saveSharingProfile = function saveSharingProfile() {
 
         $scope.sharingProfile.parameters = $scope.parameters;
 
         // Save the sharing profile
-        sharingProfileService.saveSharingProfile($scope.selectedDataSource, $scope.sharingProfile)
-        .then(function savedSharingProfile() {
-            $location.url('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
-        }, guacNotification.SHOW_REQUEST_ERROR);
+        return sharingProfileService.saveSharingProfile($scope.selectedDataSource, $scope.sharingProfile);
 
     };
 
     /**
-     * An action to be provided along with the object sent to showStatus which
-     * immediately deletes the current sharing profile.
-     */
-    var DELETE_ACTION = {
-        name        : "MANAGE_SHARING_PROFILE.ACTION_DELETE",
-        className   : "danger",
-        // Handle action
-        callback    : function deleteCallback() {
-            deleteSharingProfileImmediately();
-            guacNotification.showStatus(false);
-        }
-    };
-
-    /**
-     * Immediately deletes the current sharing profile, without prompting the
-     * user for confirmation.
-     */
-    var deleteSharingProfileImmediately = function deleteSharingProfileImmediately() {
-
-        // Delete the sharing profile
-        sharingProfileService.deleteSharingProfile($scope.selectedDataSource, $scope.sharingProfile)
-        .then(function deletedSharingProfile() {
-            $location.path('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
-        }, guacNotification.SHOW_REQUEST_ERROR);
-
-    };
-
-    /**
-     * Deletes the sharing profile, prompting the user first to confirm that
-     * deletion is desired.
+     * Deletes the current sharing profile, returning a promise which is
+     * resolved if the delete operation succeeds and rejected if the delete
+     * operation fails.
+     *
+     * @returns {Promise}
+     *     A promise which is resolved if the delete operation succeeds and is
+     *     rejected with an {@link Error} if the delete operation fails.
      */
     $scope.deleteSharingProfile = function deleteSharingProfile() {
-
-        // Confirm deletion request
-        guacNotification.showStatus({
-            'title'      : 'MANAGE_SHARING_PROFILE.DIALOG_HEADER_CONFIRM_DELETE',
-            'text'       : {
-                'key' : 'MANAGE_SHARING_PROFILE.TEXT_CONFIRM_DELETE'
-            },
-            'actions'    : [ DELETE_ACTION, CANCEL_ACTION]
-        });
-
+        return sharingProfileService.deleteSharingProfile($scope.selectedDataSource, $scope.sharingProfile);
     };
 
 }]);

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/c1f5ad40/guacamole/src/main/webapp/app/manage/templates/manageSharingProfile.html
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/templates/manageSharingProfile.html b/guacamole/src/main/webapp/app/manage/templates/manageSharingProfile.html
index d6c7043..ac52fa3 100644
--- a/guacamole/src/main/webapp/app/manage/templates/manageSharingProfile.html
+++ b/guacamole/src/main/webapp/app/manage/templates/manageSharingProfile.html
@@ -22,7 +22,7 @@
     <!-- Sharing profile attributes section -->
     <div class="attributes">
         <guac-form namespace="'SHARING_PROFILE_ATTRIBUTES'" content="attributes"
-                   model="sharingProfile.attributes" model-only="!canChangeAllAttributes()"></guac-form>
+                   model="sharingProfile.attributes" model-only="!managementPermissions.canChangeAllAttributes"></guac-form>
     </div>
 
     <!-- Sharing profile parameters -->
@@ -34,11 +34,12 @@
     </div>
 
     <!-- Form action buttons -->
-    <div class="action-buttons">
-        <button ng-show="canSaveSharingProfile" ng-click="saveSharingProfile()">{{'MANAGE_SHARING_PROFILE.ACTION_SAVE' | translate}}</button>
-        <button ng-show="canCloneSharingProfile" ng-click="cloneSharingProfile()">{{'MANAGE_SHARING_PROFILE.ACTION_CLONE' | translate}}</button>
-        <button ng-click="cancel()">{{'MANAGE_SHARING_PROFILE.ACTION_CANCEL' | translate}}</button>
-        <button ng-show="canDeleteSharingProfile" ng-click="deleteSharingProfile()" class="danger">{{'MANAGE_SHARING_PROFILE.ACTION_DELETE' | translate}}</button>
-    </div>
+    <management-buttons namespace="'MANAGE_SHARING_PROFILE'"
+          permissions="managementPermissions"
+          save="saveSharingProfile()"
+          delete="deleteSharingProfile()"
+          clone="cloneSharingProfile()"
+          return="returnToConnectionList()">
+    </management-buttons>
 
 </div>