From 6ca076f7fcc59e4d499fa6b15277907f9a88bf8a Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 1 May 2018 17:18:48 -0700 Subject: [PATCH] GUACAMOLE-220: Move data source tabs to separate directive. --- .../controllers/manageUserController.js | 70 ++++------- .../app/manage/directives/dataSourceTabs.js | 111 ++++++++++++++++++ .../app/manage/templates/dataSourceTabs.html | 3 + .../app/manage/templates/manageUser.html | 22 ++-- 4 files changed, 152 insertions(+), 54 deletions(-) create mode 100644 guacamole/src/main/webapp/app/manage/directives/dataSourceTabs.js create mode 100644 guacamole/src/main/webapp/app/manage/templates/dataSourceTabs.html diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js index dcb87e156..27cb9337f 100644 --- a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js +++ b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js @@ -26,7 +26,6 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto // Required types var Error = $injector.get('Error'); var ManagementPermissions = $injector.get('ManagementPermissions'); - var PageDefinition = $injector.get('PageDefinition'); var PermissionFlagSet = $injector.get('PermissionFlagSet'); var PermissionSet = $injector.get('PermissionSet'); var User = $injector.get('User'); @@ -40,7 +39,6 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto var permissionService = $injector.get('permissionService'); var requestService = $injector.get('requestService'); var schemaService = $injector.get('schemaService'); - var translationStringService = $injector.get('translationStringService'); var userService = $injector.get('userService'); /** @@ -136,11 +134,14 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto $scope.permissionsRemoved = new PermissionSet(); /** - * The management-related actions that the current user may perform on the - * user currently being created/modified, or null if the current user's - * permissions have not yet been loaded. + * For each applicable data source, the management-related actions that the + * current user may perform on the user account currently being created + * or modified, as a map of data source identifier to the + * {@link ManagementPermissions} object describing the actions available + * within that data source, or null if the current user's permissions have + * not yet been loaded. * - * @type ManagementPermissions + * @type Object. */ $scope.managementPermissions = null; @@ -153,14 +154,6 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto */ $scope.attributes = null; - /** - * The pages associated with each user account having the given username. - * Each user account will be associated with a particular data source. - * - * @type PageDefinition[] - */ - $scope.accountPages = []; - /** * Returns whether critical data has completed being loaded. * @@ -349,53 +342,42 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto }) .then(function dataReceived(values) { - var managementPermissions = {}; - $scope.attributes = values.attributes; - // Generate pages for each applicable data source - $scope.accountPages = []; + $scope.managementPermissions = {}; angular.forEach(dataSources, function addAccountPage(dataSource) { // Determine whether data source contains this user var exists = (dataSource in $scope.users); // Calculate management actions available for this specific account - managementPermissions[dataSource] = ManagementPermissions.fromPermissionSet( + $scope.managementPermissions[dataSource] = ManagementPermissions.fromPermissionSet( values.permissions[dataSource], PermissionSet.SystemPermissionType.CREATE_USER, PermissionSet.hasUserPermission, exists ? username : null); - // Account is not relevant if it does not exist and cannot be - // created - var readOnly = !managementPermissions[dataSource].canSaveObject; - if (!exists && readOnly) - return; - - // Only the selected data source is relevant when cloning - if (cloneSourceUsername && dataSource !== $scope.dataSource) - return; - - // Determine class name based on read-only / linked status - var className; - if (readOnly) className = 'read-only'; - else if (exists) className = 'linked'; - else className = 'unlinked'; - - // Add page entry - $scope.accountPages.push(new PageDefinition({ - name : translationStringService.canonicalize('DATA_SOURCE_' + dataSource) + '.NAME', - url : '/manage/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(username || ''), - className : className - })); - }); - $scope.managementPermissions = managementPermissions[$scope.dataSource]; - }, requestService.WARN); + /** + * Returns the URL for the page which manages the user account currently + * being edited under the given data source. The given data source need not + * be the same as the data source currently selected. + * + * @param {String} dataSource + * The unique identifier of the data source that the URL is being + * generated for. + * + * @returns {String} + * The URL for the page which manages the user account currently being + * edited under the given data source. + */ + $scope.getUserURL = function getUserURL(dataSource) { + return '/manage/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(username || ''); + }; + /** * Cancels all pending edits, returning to the main list of users. */ diff --git a/guacamole/src/main/webapp/app/manage/directives/dataSourceTabs.js b/guacamole/src/main/webapp/app/manage/directives/dataSourceTabs.js new file mode 100644 index 000000000..cf7068f27 --- /dev/null +++ b/guacamole/src/main/webapp/app/manage/directives/dataSourceTabs.js @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Directive which displays a set of tabs pointing to the same object within + * different data sources, such as user accounts which span multiple data + * sources. + */ +angular.module('manage').directive('dataSourceTabs', ['$injector', + function dataSourceTabs($injector) { + + // Required types + var PageDefinition = $injector.get('PageDefinition'); + + // Required services + var translationStringService = $injector.get('translationStringService'); + + var directive = { + + restrict : 'E', + replace : true, + templateUrl : 'app/manage/templates/dataSourceTabs.html', + + scope : { + + /** + * The permissions which dictate the management actions available + * to the current user. + * + * @type Object. + */ + permissions : '=', + + /** + * A function which returns the URL of the object within a given + * data source. The relevant data source will be made available to + * the Angular expression defining this function as the + * "dataSource" variable. No other values will be made available, + * including values from the scope. + * + * @type Function + */ + url : '&' + + } + + }; + + directive.controller = ['$scope', function dataSourceTabsController($scope) { + + /** + * The set of pages which each manage the same object within different + * data sources. + * + * @type PageDefinition[] + */ + $scope.pages = null; + + // Keep pages synchronized with permissions + $scope.$watch('permissions', function permissionsChanged(permissions) { + + $scope.pages = []; + angular.forEach(permissions, function addDataSourcePage(managementPermissions, dataSource) { + + // Determine whether data source contains this object + var exists = !!managementPermissions.identifier; + + // Data source is not relevant if the associated object does not + // exist and cannot be created + var readOnly = !managementPermissions.canSaveObject; + if (!exists && readOnly) + return; + + // Determine class name based on read-only / linked status + var className; + if (readOnly) className = 'read-only'; + else if (exists) className = 'linked'; + else className = 'unlinked'; + + // Add page entry + $scope.pages.push(new PageDefinition({ + name : translationStringService.canonicalize('DATA_SOURCE_' + dataSource) + '.NAME', + url : $scope.url({ dataSource : dataSource }), + className : className + })); + + }); + + }); + + }]; + + return directive; + +}]); diff --git a/guacamole/src/main/webapp/app/manage/templates/dataSourceTabs.html b/guacamole/src/main/webapp/app/manage/templates/dataSourceTabs.html new file mode 100644 index 000000000..a8a08431b --- /dev/null +++ b/guacamole/src/main/webapp/app/manage/templates/dataSourceTabs.html @@ -0,0 +1,3 @@ +
+ +
\ No newline at end of file diff --git a/guacamole/src/main/webapp/app/manage/templates/manageUser.html b/guacamole/src/main/webapp/app/manage/templates/manageUser.html index 02b3ddce5..6770d3103 100644 --- a/guacamole/src/main/webapp/app/manage/templates/manageUser.html +++ b/guacamole/src/main/webapp/app/manage/templates/manageUser.html @@ -6,17 +6,18 @@

{{'MANAGE_USER.SECTION_HEADER_EDIT_USER' | translate}}

-
- -
+ + -
+

{{'MANAGE_USER.INFO_READ_ONLY' | translate}}

-
+
@@ -40,13 +41,14 @@
-
+
+ model="user.attributes" + model-only="!managementPermissions[dataSource].canChangeAllAttributes">
- -