From 4a4c87fa15efa7adbb08b414bc5a5a280a41803d Mon Sep 17 00:00:00 2001 From: Matt Gilman Date: Tue, 4 Oct 2016 15:30:41 -0400 Subject: [PATCH] NIFI-2849: - Showing process group name when possible. - Providing a link to jump to the process group defined in the effective policy. - Preventing editing an inherited policy. - When overriding a policy, allowing the user to indicate if the policy should be empty or should copy the user/groups of the inherited policy. This closes #1090. Signed-off-by: Andy LoPresto --- .../nifi/web/api/entity/ComponentEntity.java | 2 +- .../src/main/webapp/WEB-INF/pages/canvas.jsp | 1 + .../canvas/override-policy-dialog.jsp | 26 ++++ .../src/main/webapp/css/policy-management.css | 9 ++ .../components/nf-ng-template-component.js | 3 +- .../js/nf/canvas/nf-policy-management.js | 146 +++++++++++++----- .../src/main/webapp/js/nf/nf-dialog.js | 1 - 7 files changed, 149 insertions(+), 39 deletions(-) create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/override-policy-dialog.jsp diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ComponentEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ComponentEntity.java index 5a2f64351f..0d818733e4 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ComponentEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/ComponentEntity.java @@ -28,7 +28,7 @@ import java.util.Objects; /** * A base type for request/response entities. */ -@XmlRootElement(name = "entity") +@XmlRootElement(name = "componentEntity") public class ComponentEntity extends Entity { private RevisionDTO revision; diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp index 6bd1b8c928..130284b5ba 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp @@ -125,6 +125,7 @@ + diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/override-policy-dialog.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/override-policy-dialog.jsp new file mode 100644 index 0000000000..b369c481b5 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/override-policy-dialog.jsp @@ -0,0 +1,26 @@ +<%-- + 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. +--%> +<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %> + \ No newline at end of file diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/policy-management.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/policy-management.css index 2fa956bf13..21cdc1ff48 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/policy-management.css +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/policy-management.css @@ -222,3 +222,12 @@ div.policy-selected-component-type { font-family: Roboto; font-size: 13px; } + +/* + override policy dialog +*/ + +#override-policy-dialog label { + font-family: inherit; + letter-spacing: inherit; +} diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-template-component.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-template-component.js index a029e79b9b..61b9c03b9b 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-template-component.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-template-component.js @@ -81,8 +81,7 @@ nf.ng.TemplateComponent = function (serviceProvider) { // configure the instantiate template dialog this.getElement().modal({ scrollableContentStyle: 'scrollable', - headerText: 'Add Template', - overlayBackgroud: false + headerText: 'Add Template' }); }, diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-policy-management.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-policy-management.js index cfae290c85..c8e87f3049 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-policy-management.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-policy-management.js @@ -229,9 +229,52 @@ nf.PolicyManagement = (function () { }; var initPolicyTable = function () { - // create/override a policy - $('#create-policy-link, #override-policy-link, #add-local-admin-link').on('click', function () { - createPolicy(); + $('#override-policy-dialog').modal({ + headerText: 'Override Policy', + buttons: [{ + buttonText: 'Override', + color: { + base: '#728E9B', + hover: '#004849', + text: '#ffffff' + }, + handler: { + click: function () { + // create the policy, copying if appropriate + createPolicy($('#copy-policy-radio-button').is(':checked')); + + $(this).modal('hide'); + } + } + }, { + buttonText: 'Cancel', + color: { + base: '#E3E8EB', + hover: '#C7D2D7', + text: '#004849' + }, + handler: { + click: function () { + $(this).modal('hide'); + } + } + }], + handler: { + close: function () { + // reset the radio button + $('#copy-policy-radio-button').prop('checked', true); + } + } + }); + + // create/add a policy + $('#create-policy-link, #add-local-admin-link').on('click', function () { + createPolicy(false); + }); + + // override a policy + $('#override-policy-link').on('click', function () { + $('#override-policy-dialog').modal('show'); }); // policy type listing @@ -413,7 +456,9 @@ nf.PolicyManagement = (function () { // see if the user has permissions for the current policy var currentEntity = $('#policy-table').data('policy'); - if (currentEntity.permissions.canWrite === true) { + var resourceComponentId = nf.Common.substringAfterLast(currentEntity.component.resource, '/'); + var selectedComponentId = $('#selected-policy-component-id').text(); + if (currentEntity.permissions.canWrite === true && resourceComponentId === selectedComponentId) { markup += '
'; } @@ -659,13 +704,30 @@ nf.PolicyManagement = (function () { * * @param resource */ - var convertToHumanReadableResource = function (resource) { + var getResourceMessage = function (resource) { if (resource === '/policies') { - return 'all policies'; + return $('Showing effective policy inherited from all policies.'); } else if (resource === '/controller') { - return 'the controller'; + return $('Showing effective policy inherited from the controller.'); } else { - return 'Process Group ' + nf.Common.substringAfterLast(resource, '/'); + // extract the group id + var processGroupId = nf.Common.substringAfterLast(resource, '/'); + var processGroupName = processGroupId; + + // attempt to resolve the group name + var breadcrumbs = nf.ng.Bridge.injector.get('breadcrumbsCtrl').getBreadcrumbs(); + $.each(breadcrumbs, function (_, breadcrumbEntity) { + if (breadcrumbEntity.id === processGroupId) { + processGroupName = breadcrumbEntity.label; + return false; + } + }); + + // build the mark up + return $('Showing effective policy inherited from Process Group ').append($('').text(processGroupName).on('click', function () { + $('#shell-close-button').click(); + nf.CanvasUtils.enterGroup(processGroupId); + })).append('.'); } }; @@ -686,21 +748,22 @@ nf.PolicyManagement = (function () { // store the current policy version $('#policy-table').data('policy', policyEntity); - // allow modification if allowed - $('#new-policy-user-button').prop('disabled', policyEntity.permissions.canWrite === false); - // see if the policy is for this resource if (resourceAndAction.resource === policy.resource) { // allow remove when policy is not inherited $('#delete-policy-button').prop('disabled', policyEntity.permissions.canWrite === false); + + // allow modification if allowed + $('#new-policy-user-button').prop('disabled', policyEntity.permissions.canWrite === false); } else { - $('#policy-message').text('Showing effective policy inherited from ' + convertToHumanReadableResource(policy.resource) + '. '); + $('#policy-message').append(getResourceMessage(policy.resource)); // policy is inherited, we do not know if the user has permissions to modify the desired policy... show button and let server decide $('#override-policy-message').show(); - // to not support policy deletion + // do not support policy deletion/modification $('#delete-policy-button').prop('disabled', true); + $('#new-policy-user-button').prop('disabled', true); } // populate the table @@ -732,8 +795,6 @@ nf.PolicyManagement = (function () { // if the return policy is for the desired policy (not inherited, show it) if (resourceAndAction.resource === policy.resource) { - $('#policy-message').text(policy.resource); - // populate the policy details populatePolicy(policyEntity); } else { @@ -803,10 +864,6 @@ nf.PolicyManagement = (function () { // ensure appropriate actions for the loaded policy if (policyEntity.permissions.canRead === true) { - var policy = policyEntity.component; - - $('#policy-message').text(policy.resource); - // populate the policy details populatePolicy(policyEntity); } else { @@ -856,10 +913,33 @@ nf.PolicyManagement = (function () { /** * Creates a new policy for the current selection. + * + * @param copyInheritedPolicy Whether or not to copy the inherited policy */ - var createPolicy = function () { + var createPolicy = function (copyInheritedPolicy) { var resourceAndAction = getSelectedResourceAndAction(); + var users = []; + var userGroups = []; + if (copyInheritedPolicy === true) { + var policyGrid = $('#policy-table').data('gridInstance'); + var policyData = policyGrid.getData(); + + var items = policyData.getItems(); + $.each(items, function (_, item) { + var itemCopy = $.extend({}, item); + + if (itemCopy.type === 'user') { + users.push(itemCopy); + } else { + userGroups.push(itemCopy); + } + + // remove the type as it was added client side to render differently and is not part of the actual schema + delete itemCopy.type; + }); + } + var entity = { 'revision': nf.Client.getRevision({ 'revision': { @@ -868,7 +948,9 @@ nf.PolicyManagement = (function () { }), 'component': { 'action': resourceAndAction.action, - 'resource': resourceAndAction.resource + 'resource': resourceAndAction.resource, + 'users': users, + 'userGroups': userGroups } }; @@ -881,10 +963,6 @@ nf.PolicyManagement = (function () { }).done(function (policyEntity) { // ensure appropriate actions for the loaded policy if (policyEntity.permissions.canRead === true) { - var policy = policyEntity.component; - - $('#policy-message').text(policy.resource); - // populate the policy details populatePolicy(policyEntity); } else { @@ -907,14 +985,16 @@ nf.PolicyManagement = (function () { var items = policyData.getItems(); $.each(items, function (_, item) { - if (item.type === 'user') { - users.push(item); + var itemCopy = $.extend({}, item); + + if (itemCopy.type === 'user') { + users.push(itemCopy); } else { - userGroups.push(item); + userGroups.push(itemCopy); } - // remove the type as it was added client side to render differently - delete item.type; + // remove the type as it was added client side to render differently and is not part of the actual schema + delete itemCopy.type; }); var currentEntity = $('#policy-table').data('policy'); @@ -937,10 +1017,6 @@ nf.PolicyManagement = (function () { }).done(function (policyEntity) { // ensure appropriate actions for the loaded policy if (policyEntity.permissions.canRead === true) { - var policy = policyEntity.component; - - $('#policy-message').text(policy.resource); - // populate the policy details populatePolicy(policyEntity); } else { @@ -982,7 +1058,7 @@ nf.PolicyManagement = (function () { * Reset the policy message. */ var resetPolicyMessage = function () { - $('#policy-message').text(''); + $('#policy-message').text('').empty(); $('#new-policy-message').hide(); $('#override-policy-message').hide(); $('#add-local-admin-message').hide(); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-dialog.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-dialog.js index 26d0f300f1..50aa70402b 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-dialog.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-dialog.js @@ -94,7 +94,6 @@ nf.Dialog = (function () { options = $.extend({ headerText: '', dialogContent: '', - overlayBackgrond: true, yesText: 'Yes', noText: 'No' }, options);