You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by mc...@apache.org on 2015/04/07 16:52:30 UTC

[4/5] incubator-nifi git commit: NIFI-475: - Adding support to create controller services inline when editing a components properties.

NIFI-475:
- Adding support to create controller services inline when editing a components properties.

NIFI-475:
- Adding support to create controller services inline when editing a components properties.

NIFI-475:
- Prompting the user to save changes before navigating to the controller service definition.


Project: http://git-wip-us.apache.org/repos/asf/incubator-nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-nifi/commit/9963057f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-nifi/tree/9963057f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-nifi/diff/9963057f

Branch: refs/heads/NIFI-475
Commit: 9963057fdb23dceb2fa6f22aac30f39e74e41619
Parents: 7369730
Author: Matt Gilman <ma...@gmail.com>
Authored: Mon Apr 6 16:29:07 2015 -0400
Committer: Matt Gilman <ma...@gmail.com>
Committed: Tue Apr 7 10:50:21 2015 -0400

----------------------------------------------------------------------
 .../nifi/web/api/dto/PropertyDescriptorDTO.java |   9 +-
 .../org/apache/nifi/web/NiFiServiceFacade.java  |   3 +-
 .../nifi/web/StandardNiFiServiceFacade.java     |   4 +-
 .../apache/nifi/web/api/ControllerResource.java |   7 +-
 .../org/apache/nifi/web/api/dto/DtoFactory.java |   6 +-
 .../nifi/web/controller/ControllerFacade.java   |  43 ++-
 .../org/apache/nifi/web/util/SnippetUtils.java  |   6 +-
 .../propertytable/jquery.propertytable.css      |  43 +++
 .../propertytable/jquery.propertytable.js       | 285 +++++++++++++++++--
 .../js/nf/canvas/nf-controller-service.js       | 182 ++++++------
 .../js/nf/canvas/nf-processor-configuration.js  |   2 +-
 .../webapp/js/nf/canvas/nf-reporting-task.js    |   4 +-
 .../src/main/webapp/js/nf/canvas/nf-settings.js |   2 +
 13 files changed, 467 insertions(+), 129 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/9963057f/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/PropertyDescriptorDTO.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/PropertyDescriptorDTO.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/PropertyDescriptorDTO.java
index d10a324..ecde255 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/PropertyDescriptorDTO.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/PropertyDescriptorDTO.java
@@ -34,7 +34,7 @@ public class PropertyDescriptorDTO {
     private boolean sensitive;
     private boolean dynamic;
     private boolean supportsEl;
-    private boolean identifiesControllerService;
+    private String identifiesControllerService;
 
     /**
      * The set of allowable values for this property. If empty then the
@@ -158,15 +158,16 @@ public class PropertyDescriptorDTO {
     }
 
     /**
-     * Whether this descriptor represents a controller service.
+     * If this property identifies a controller service, this returns the 
+     * fully qualified type, null otherwise.
      * 
      * @return 
      */
-    public boolean isIdentifiesControllerService() {
+    public String getIdentifiesControllerService() {
         return identifiesControllerService;
     }
 
-    public void setIdentifiesControllerService(boolean identifiesControllerService) {
+    public void setIdentifiesControllerService(String identifiesControllerService) {
         this.identifiesControllerService = identifiesControllerService;
     }
     

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/9963057f/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
index e3afbf9..8d9dade 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
@@ -252,9 +252,10 @@ public interface NiFiServiceFacade {
     /**
      * Returns the list of controller service types.
      * 
+     * @param serviceType Filters only service types that implement this type
      * @return The list of available controller types
      */
-    Set<DocumentedTypeDTO> getControllerServiceTypes();
+    Set<DocumentedTypeDTO> getControllerServiceTypes(String serviceType);
     
     /**
      * Returns the list of reporting task types.

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/9963057f/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
index 086c46b..88637b4 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
@@ -1718,8 +1718,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
     }
 
     @Override
-    public Set<DocumentedTypeDTO> getControllerServiceTypes() {
-        return controllerFacade.getControllerServiceTypes();
+    public Set<DocumentedTypeDTO> getControllerServiceTypes(final String serviceType) {
+        return controllerFacade.getControllerServiceTypes(serviceType);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/9963057f/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
index 98f17d5..c0b4cd7 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java
@@ -737,6 +737,7 @@ public class ControllerResource extends ApplicationResource {
      * @param clientId Optional client id. If the client id is not specified, a
      * new one will be generated. This value (whether specified or generated) is
      * included in the response.
+     * @param serviceType Returns only services that implement this type
      * @return A controllerServicesTypesEntity.
      */
     @GET
@@ -744,7 +745,9 @@ public class ControllerResource extends ApplicationResource {
     @Path("/controller-service-types")
     @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
     @TypeHint(ControllerServiceTypesEntity.class)
-    public Response getControllerServiceTypes(@QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId) {
+    public Response getControllerServiceTypes(
+            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId,
+            @QueryParam("serviceType") String serviceType) {
 
         // replicate if cluster manager
         if (properties.isClusterManager()) {
@@ -758,7 +761,7 @@ public class ControllerResource extends ApplicationResource {
         // create response entity
         final ControllerServiceTypesEntity entity = new ControllerServiceTypesEntity();
         entity.setRevision(revision);
-        entity.setControllerServiceTypes(serviceFacade.getControllerServiceTypes());
+        entity.setControllerServiceTypes(serviceFacade.getControllerServiceTypes(serviceType));
 
         // generate the response
         return clusterContext(generateOkResponse(entity)).build();

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/9963057f/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
index 7fe76ad..f3678d1 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
@@ -1958,7 +1958,11 @@ public final class DtoFactory {
         dto.setDescription(propertyDescriptor.getDescription());
         dto.setDefaultValue(propertyDescriptor.getDefaultValue());
         dto.setSupportsEl(propertyDescriptor.isExpressionLanguageSupported());
-        dto.setIdentifiesControllerService(propertyDescriptor.getControllerServiceDefinition() != null);
+        
+        // set the identifies controller service is applicable
+        if (propertyDescriptor.getControllerServiceDefinition() != null) {
+            dto.setIdentifiesControllerService(propertyDescriptor.getControllerServiceDefinition().getName());
+        }
 
         final Class<? extends ControllerService> serviceDefinition = propertyDescriptor.getControllerServiceDefinition();
         if (propertyDescriptor.getAllowableValues() == null) {

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/9963057f/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
index a373f05..b5e6f7e 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
@@ -108,6 +108,7 @@ import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO;
 import org.apache.nifi.web.api.dto.status.StatusHistoryDTO;
 import org.apache.nifi.web.DownloadableContent;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.ClassUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.admin.service.UserService;
 import org.apache.nifi.authorization.DownloadAuthorization;
@@ -348,12 +349,48 @@ public class ControllerFacade {
     }
     
     /**
+     * Returns whether the specified type implements the specified serviceType.
+     * 
+     * @param baseType
+     * @param type
+     * @return
+     */
+    private boolean implementsServiceType(final String serviceType, final Class type) {
+        final List<Class<?>> interfaces = ClassUtils.getAllInterfaces(type);
+        for (final Class i : interfaces) {
+            if (ControllerService.class.isAssignableFrom(i) && i.getName().equals(serviceType)) {
+                return true;
+            }
+        }
+        
+        return false;
+    }
+    
+    /**
      * Gets the ControllerService types that this controller supports.
      * 
+     * @param serviceType
      * @return 
      */
-    public Set<DocumentedTypeDTO> getControllerServiceTypes() {
-        return dtoFactory.fromDocumentedTypes(ControllerService.class, ExtensionManager.getExtensions(ControllerService.class));
+    public Set<DocumentedTypeDTO> getControllerServiceTypes(final String serviceType) { 
+        final Set<Class> serviceImplementations = ExtensionManager.getExtensions(ControllerService.class);
+        
+        // identify the controller services that implement the specified serviceType if applicable
+        final Set<Class> matchingServiceImplementions;
+        if (serviceType != null) {
+            matchingServiceImplementions = new HashSet<>();
+            
+            // check each type and remove those that aren't in the specified ancestry
+            for (final Class type : serviceImplementations) {
+                if (implementsServiceType(serviceType, type)) {
+                    matchingServiceImplementions.add(type);
+                }
+            }
+        } else {
+            matchingServiceImplementions = serviceImplementations;
+        }
+        
+        return dtoFactory.fromDocumentedTypes(matchingServiceImplementions);
     }
     
     /**
@@ -362,7 +399,7 @@ public class ControllerFacade {
      * @return 
      */
     public Set<DocumentedTypeDTO> getReportingTaskTypes() {
-        return dtoFactory.fromDocumentedTypes(ReportingTask.class, ExtensionManager.getExtensions(ReportingTask.class));
+        return dtoFactory.fromDocumentedTypes(ExtensionManager.getExtensions(ReportingTask.class));
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/9963057f/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/util/SnippetUtils.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/util/SnippetUtils.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/util/SnippetUtils.java
index fa9bc41..40e5730 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/util/SnippetUtils.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/util/SnippetUtils.java
@@ -222,7 +222,7 @@ public final class SnippetUtils {
                 }
                 
                 final PropertyDescriptorDTO propertyDescriptorDto = descriptors.get(propName);
-                if ( propertyDescriptorDto != null && propertyDescriptorDto.isIdentifiesControllerService() ) {
+                if ( propertyDescriptorDto != null && propertyDescriptorDto.getIdentifiesControllerService() != null ) {
                     final ControllerServiceNode serviceNode = flowController.getControllerServiceNode(propValue);
                     if ( serviceNode != null ) {
                         addControllerServicesToSnippet(snippet, serviceNode);
@@ -363,7 +363,7 @@ public final class SnippetUtils {
                 final Map<String, PropertyDescriptorDTO> descriptors = serviceDTO.getDescriptors();
                 if ( properties != null && descriptors != null ) {
                     for ( final PropertyDescriptorDTO descriptor : descriptors.values() ) {
-                        if ( descriptor.isIdentifiesControllerService() ) {
+                        if ( descriptor.getIdentifiesControllerService() != null ) {
                             final String currentServiceId = properties.get(descriptor.getName());
                             if ( currentServiceId == null ) {
                                 continue;
@@ -558,7 +558,7 @@ public final class SnippetUtils {
         final Map<String, PropertyDescriptorDTO> descriptors = configDto.getDescriptors();
         if ( properties != null && descriptors != null ) {
             for ( final PropertyDescriptorDTO descriptor : descriptors.values() ) {
-                if ( descriptor.isIdentifiesControllerService() ) {
+                if ( descriptor.getIdentifiesControllerService() != null ) {
                     final String currentServiceId = properties.get(descriptor.getName());
                     if ( currentServiceId == null ) {
                         continue;

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/9963057f/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.css
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.css b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.css
index 74b6f4c..d1f22b2 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.css
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.css
@@ -104,6 +104,49 @@ div.new-property-button-container {
 }
 
 /*
+    New inline controller service dialog
+*/
+
+div.new-inline-controller-service-dialog {
+    z-index: 1301;
+    display: none;
+    padding: 10px;
+    border: 3px solid #365C6A;
+    box-shadow: 4px 4px 6px rgba(0, 0, 0, 0.9);
+    cursor: move;
+    width: 350px;
+    height: 250px;
+}
+
+div.new-inline-controller-service-combo {
+    height: 18px;
+    width: 340px;
+    margin-bottom: 10px;
+}
+
+div.new-inline-controller-service-tags {
+    height: 18px;
+    width: 340px;
+    margin-bottom: 10px;
+    overflow: hidden;
+    white-space: nowrap;
+}
+
+div.new-inline-controller-service-description {
+    height: 115px;
+    width: 340px;
+    overflow: auto;
+}
+
+div.new-inline-controller-service-button-container {
+    position: absolute;
+    left: 0;
+    bottom: 0;
+    right: 0;
+    padding: 0 8px 10px;
+}
+
+/*
     Styles for the property editor.
 */
 

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/9963057f/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.js
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.js b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.js
index bbafc60..c2b947d 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.js
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/propertytable/jquery.propertytable.js
@@ -23,7 +23,17 @@
  *
  * {
  *   readOnly: true,
- *   newPropertyDialogContainer: 'body'
+ *   dialogContainer: 'body',
+ *   descriptorDeferred: function () {
+ *      return $.Deferred(function (deferred) {
+ *          deferred.resolve();
+ *      }).promise;
+ *   },
+ *   goToServiceDeferred: function () {
+ *      return $.Deferred(function (deferred) {
+ *          deferred.resolve();
+ *      }).promise;
+ *   }
  * }
  */
 
@@ -443,6 +453,10 @@
             var gridContainer = $(args.grid.getContainerNode());
             var descriptors = gridContainer.data('descriptors');
             propertyDescriptor = descriptors[args.item.property];
+            
+            // get the options
+            var propertyContainer = gridContainer.closest('.property-container');
+            var configurationOptions = propertyContainer.data('options');
 
             // create the wrapper
             wrapper = $('<div></div>').css({
@@ -490,6 +504,15 @@
                     disabled: true
                 });
             }
+            
+            // if this descriptor identifies a controller service, provide a way to create one
+            if (nf.Common.isDefinedAndNotNull(propertyDescriptor.identifiesControllerService)) {
+                options.push({
+                    text: 'Create new service...',
+                    value: undefined,
+                    optionClass: 'unset'
+                });
+            }
 
             // determine the max height
             var position = args.position;
@@ -499,7 +522,16 @@
             // build the combo field
             combo = $('<div class="value-combo combo"></div>').combo({
                 options: options,
-                maxHeight: maxHeight
+                maxHeight: maxHeight,
+                select: function (option) {
+                    if (typeof option.value === 'undefined') {
+                        // cancel the current edit
+                        scope.cancel();
+                        
+                        // prompt for the new service type
+                        promptForNewControllerService(gridContainer, args.grid, args.item, propertyDescriptor.identifiesControllerService, configurationOptions);
+                    }
+                }
             }).width(position.width - 16).appendTo(wrapper);
 
             // add buttons for handling user input
@@ -744,6 +776,153 @@
             }
         }
     };
+    
+    /**
+     * Gets the available controller services that implement the specified type and
+     * prompts the user to create one.
+     * 
+     * @param {jQuery} gridContainer The grid container
+     * @param {slickgrid} grid The grid
+     * @param {object} item The item
+     * @param {type} serviceType The type of service to create
+     * @param {object} configurationOptions The configuration options
+     */
+    var promptForNewControllerService = function (gridContainer, grid, item, serviceType, configurationOptions) {
+        $.ajax({
+            type: 'GET',
+            url: '../nifi-api/controller/controller-service-types',
+            data: {
+                serviceType: serviceType
+            },
+            dataType: 'json'
+        }).done(function (response) {
+            var options = [];
+            $.each(response.controllerServiceTypes, function (i, controllerServiceType) {
+                options.push({
+                    text: nf.Common.substringAfterLast(controllerServiceType.type, '.'),
+                    value: controllerServiceType.type
+                });
+            });
+            
+            // ensure there are some applicable controller services
+            if (options.length === 0) {
+                nf.Dialog.showOkDialog({
+                    dialogContent: 'No controller service types found that are applicable for this property.',
+                    overlayBackground: false
+                });
+            } else {
+                var newControllerServiceDialogMarkup = 
+                        '<div class="new-inline-controller-service-dialog dialog cancellable">' +
+                            '<div>' +
+                                '<div class="setting-name">Controller Service</div>' +
+                                '<div class="setting-field">' +
+                                    '<div class="new-inline-controller-service-combo"></div>' +
+                                '</div>' +
+                            '</div>' +
+                            '<div>' +
+                                '<div class="setting-name">Tags</div>' +
+                                '<div class="setting-field">' +
+                                    '<div class="new-inline-controller-service-tags"></div>' +
+                                '</div>' +
+                            '</div>' +
+                            '<div>' +
+                                '<div class="setting-name">Description</div>' +
+                                '<div class="setting-field">' +
+                                    '<div class="new-inline-controller-service-description"></div>' +
+                                '</div>' +
+                            '</div>' +
+                            '<div class="new-inline-controller-service-button-container">' +
+                                '<div class="new-inline-controller-service-create button button-normal">Create</div>' +
+                                '<div class="new-inline-controller-service-cancel button button-normal">Cancel</div>' +
+                                '<div class="clear"></div>' +
+                            '</div>' +
+                        '</div>';
+
+                var newControllerServiceDialog = $(newControllerServiceDialogMarkup).appendTo(configurationOptions.dialogContainer);
+                var newControllerServiceCombo = newControllerServiceDialog.find('div.new-inline-controller-service-combo');
+                var newControllerServiceTags = newControllerServiceDialog.find('div.new-inline-controller-service-tags');
+                var newControllerServiceDescription = newControllerServiceDialog.find('div.new-inline-controller-service-description');
+                
+                // build the combo field
+                newControllerServiceCombo.combo({
+                    options: options,
+                    select: function (option) {
+                        var service;
+                        $.each(response.controllerServiceTypes, function (i, controllerServiceType) {
+                            if (controllerServiceType.type === option.value) {
+                                service = controllerServiceType;
+                                return false;
+                            }
+                        });
+                        
+                        // set the service details
+                        newControllerServiceTags.text(service.tags.join(', ')).ellipsis();
+                        newControllerServiceDescription.text(service.description);
+                    }
+                });
+                
+                var create = function () {
+                    var newControllerServiceType = newControllerServiceCombo.combo('getSelectedOption').value;
+
+                    // create service of the specified type
+                    var revision = nf.Client.getRevision();
+
+                    // add the new controller service
+                    $.ajax({
+                        type: 'POST',
+                        url: '../nifi-api/controller/controller-services/node',
+                        data: {
+                            version: revision.version,
+                            clientId: revision.clientId,
+                            type: newControllerServiceType
+                        },
+                        dataType: 'json'
+                    }).done(function (response) {
+                        // update the revision
+                        nf.Client.setRevision(response.revision);
+
+                        $.Deferred(function (deferred) {
+                            // load the property descriptor if possible
+                            if (typeof configurationOptions.descriptorDeferred === 'function') {
+                                configurationOptions.descriptorDeferred(item.property).done(function(response) {
+                                    var descriptor = response.propertyDescriptor;
+
+                                    // store the descriptor for use later
+                                    var descriptors = gridContainer.data('descriptors');
+                                    if (!nf.Common.isUndefined(descriptors)) {
+                                        descriptors[descriptor.name] = descriptor;
+                                    }
+
+                                    deferred.resolve();
+                                });
+                            } else {
+                                deferred.resolve();
+                            }
+                        }).done(function() {
+                            // add a row for the new property
+                            var data = grid.getData();
+                            data.updateItem(item.id, $.extend(item, {
+                                value: response.controllerService.id
+                            }));
+
+                            // close the dialog
+                            newControllerServiceDialog.hide();
+                        });
+                    }).fail(nf.Common.handleAjaxError);
+                };
+
+                var cancel = function () {
+                    newControllerServiceDialog.hide();
+                };
+
+                // make the new property dialog draggable
+                newControllerServiceDialog.draggable({
+                    cancel: 'input, textarea, pre, .button, .' + editorClass,
+                    containment: 'body'
+                }).on('click', 'div.new-inline-controller-service-create', create).on('click', 'div.new-inline-controller-service-cancel', cancel).modal('show');
+            }
+        }).fail(nf.Common.handleAjaxError);
+    };
 
     var initPropertiesTable = function (table, options) {
         // function for formatting the property name
@@ -826,20 +1005,36 @@
             {id: 'value', field: 'value', name: 'Value', sortable: false, resizable: true, cssClass: 'pointer', rerenderOnResize: true, formatter: valueFormatter}
         ];
 
-        if (options.readOnly !== true) {
-            // custom formatter for the actions column
-            var actionFormatter = function (row, cell, value, columnDef, dataContext) {
-                var markup = '';
+        // custom formatter for the actions column
+        var actionFormatter = function (row, cell, value, columnDef, dataContext) {
+            var markup = '';
 
-                // allow user defined properties to be removed
-                if (dataContext.type === 'userDefined') {
-                    markup = '<img src="images/iconDelete.png" title="Delete" class="delete-property pointer" style="margin-top: 2px" />';
-                }
+            // get the property descriptor
+            var descriptors = table.data('descriptors');
+            var propertyDescriptor = descriptors[dataContext.property];
+            
+            var identifiesControllerService = nf.Common.isDefinedAndNotNull(propertyDescriptor.identifiesControllerService);
+            var isConfigured = nf.Common.isDefinedAndNotNull(dataContext.value);
+            
+            // check for allowable values which will drive which editor to use
+            if (identifiesControllerService && isConfigured) {
+                // ensure the configured value is referencing a valid service
+                $.each(propertyDescriptor.allowableValues, function (_, allowableValue) {
+                    if (allowableValue.value === dataContext.value) {
+                        markup = '<img src="images/iconGoTo.png" title="Go To" class="go-to-service pointer" style="margin-top: 2px" />';
+                        return false;
+                    }
+                });
+            }
 
-                return markup;
-            };
-            propertyColumns.push({id: "actions", name: "&nbsp;", minWidth: 20, width: 20, formatter: actionFormatter});
-        }
+            // allow user defined properties to be removed
+            if (options.readOnly !== true && dataContext.type === 'userDefined') {
+                markup = '<img src="images/iconDelete.png" title="Delete" class="delete-property pointer" style="margin-top: 2px" />';
+            }
+
+            return markup;
+        };
+        propertyColumns.push({id: "actions", name: "&nbsp;", minWidth: 20, width: 20, formatter: actionFormatter});
 
         var propertyConfigurationOptions = {
             forceFitColumns: true,
@@ -899,6 +1094,39 @@
                 }
             }
         };
+        
+        var goToControllerService = function (property) {
+            // close the dialog
+            var dialog = table.closest('.dialog');
+            if (dialog.hasClass('modal')) {
+                dialog.modal('hide');
+            } else {
+                dialog.hide();
+            }
+
+            $.Deferred(function (deferred) {
+                if ($('#settings').is(':visible')) {
+                    deferred.resolve();
+                } else {
+                    // reload the settings and show
+                    nf.Settings.loadSettings().done(function () {
+                        nf.Settings.showSettings();
+                        deferred.resolve();
+                    });
+                }
+            }).done(function () {
+                var controllerServiceGrid = $('#controller-services-table').data('gridInstance');
+                var controllerServiceData = controllerServiceGrid.getData();
+
+                // select the desired service
+                var row = controllerServiceData.getRowById(property.value);
+                controllerServiceGrid.setSelectedRows([row]);
+                controllerServiceGrid.scrollRowIntoView(row);
+
+                // select the controller services tab
+                $('#settings-tabs').find('li:eq(1)').click();
+            });
+        };
 
         // initialize the grid
         var propertyGrid = new Slick.Grid(table, propertyData, propertyColumns, propertyConfigurationOptions);
@@ -916,10 +1144,11 @@
                 // prevents standard edit logic
                 e.stopImmediatePropagation();
             } else if (propertyGrid.getColumns()[args.cell].id === 'actions') {
+                var property = propertyData.getItem(args.row);
+                
                 var target = $(e.target);
                 if (target.hasClass('delete-property')) {
                     // mark the property in question for removal
-                    var property = propertyData.getItem(args.row);
                     property.hidden = true;
 
                     // refresh the table
@@ -927,6 +1156,17 @@
 
                     // prevents standard edit logic
                     e.stopImmediatePropagation();
+                } else if (target.hasClass('go-to-service')) {
+                    if (options.readOnly === true) {
+                        goToControllerService(property);
+                    } else {
+                        // load the property descriptor if possible
+                        if (typeof options.goToServiceDeferred === 'function') {
+                            options.goToServiceDeferred().done(function() {
+                                goToControllerService(property);
+                            });
+                        }
+                    }
                 }
             }
         });
@@ -1076,8 +1316,8 @@
             nf.Common.removeAllPropertyDetailDialogs();
         } else {
             // clear any existing new property dialogs
-            if (nf.Common.isDefinedAndNotNull(options.newPropertyDialogContainer)) {
-                $(options.newPropertyDialogContainer).children('div.new-property-dialog').hide();
+            if (nf.Common.isDefinedAndNotNull(options.dialogContainer)) {
+                $(options.dialogContainer).children('div.new-property-dialog').hide();
             }
         }
 
@@ -1108,7 +1348,7 @@
                     var propertyTableContainer = $(this);
 
                     // clear any current contents, remote events, and store options
-                    propertyTableContainer.empty().unbind().data('options', options);
+                    propertyTableContainer.empty().unbind().addClass('property-container').data('options', options);
 
                     // build the component
                     var header = $('<div class="properties-header"></div>').appendTo(propertyTableContainer);
@@ -1118,7 +1358,7 @@
                     var table = $('<div class="property-table"></div>').appendTo(propertyTableContainer);
 
                     // optionally add a add new property button
-                    if (options.readOnly !== true && nf.Common.isDefinedAndNotNull(options.newPropertyDialogContainer)) {
+                    if (options.readOnly !== true && nf.Common.isDefinedAndNotNull(options.dialogContainer)) {
                         // build the new property dialog
                         var newPropertyDialogMarkup = 
                                 '<div class="new-property-dialog dialog cancellable">' +
@@ -1135,7 +1375,7 @@
                                     '</div>' +
                                 '</div>';
 
-                        var newPropertyDialog = $(newPropertyDialogMarkup).appendTo(options.newPropertyDialogContainer);
+                        var newPropertyDialog = $(newPropertyDialogMarkup).appendTo(options.dialogContainer);
                         var newPropertyNameField = newPropertyDialog.find('input.new-property-name');
 
                         var add = function () {
@@ -1295,8 +1535,9 @@
                 clear(propertyTableContainer);
                 
                 // clear any existing new property dialogs
-                if (nf.Common.isDefinedAndNotNull(options.newPropertyDialogContainer)) {
-                    $(options.newPropertyDialogContainer).children('div.new-property-dialog').remove();
+                if (nf.Common.isDefinedAndNotNull(options.dialogContainer)) {
+                    $(options.dialogContainer).children('div.new-property-dialog').remove();
+                    $(options.dialogContainer).children('div.new-inline-controller-service-dialog').remove();
                 }
             });
         },

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/9963057f/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service.js
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service.js b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service.js
index 26b7253..2584bc2 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service.js
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service.js
@@ -374,6 +374,7 @@ nf.ControllerService = (function () {
                     // select the selected row
                     var row = controllerServiceData.getRowById(referencingComponent.id);
                     controllerServiceGrid.setSelectedRows([row]);
+                    controllerServiceGrid.scrollRowIntoView(row);
                     
                     // close the dialog and shell
                     referenceContainer.closest('.dialog').modal('hide');
@@ -419,6 +420,7 @@ nf.ControllerService = (function () {
                     // select the selected row
                     var row = reportingTaskData.getRowById(referencingComponent.id);
                     reportingTaskGrid.setSelectedRows([row]);
+                    reportingTaskGrid.scrollRowIntoView(row);
                     
                     // select the reporting task tab
                     $('#settings-tabs').find('li:last').click();
@@ -1070,6 +1072,79 @@ nf.ControllerService = (function () {
     };
     
     /**
+     * Goes to a service configuration from the property table.
+     */
+    var goToServiceFromProperty = function () {
+        return $.Deferred(function (deferred) {
+            // close all fields currently being edited
+            $('#controller-service-properties').propertytable('saveRow');
+
+            // determine if changes have been made
+            if (isSaveRequired()) {
+                // see if those changes should be saved
+                nf.Dialog.showYesNoDialog({
+                    dialogContent: 'Save changes before going to this Controller Service?',
+                    overlayBackground: false,
+                    noHandler: function () {
+                        deferred.resolve();
+                    },
+                    yesHandler: function () {
+                        var controllerService = $('#controller-service-configuration').data('controllerServiceDetails');
+                        saveControllerService(controllerService).done(function () {
+                            deferred.resolve();
+                        }).fail(function () {
+                            deferred.reject();
+                        });
+                    }
+                });
+            } else {
+                deferred.resolve();
+            }
+        }).promise();
+    };
+    
+    var saveControllerService = function (controllerService) {
+        // marshal the settings and properties and update the controller service
+        var updatedControllerService = marshalDetails();
+
+        // ensure details are valid as far as we can tell
+        if (validateDetails(updatedControllerService)) {
+            var previouslyReferencedServiceIds = [];
+            $.each(identifyReferencedServiceDescriptors(controllerService), function (_, descriptor) {
+                var modifyingService = !nf.Common.isUndefined(updatedControllerService.controllerService.properties) && !nf.Common.isUndefined(updatedControllerService.controllerService.properties[descriptor.name]);
+                var isCurrentlyConfigured = nf.Common.isDefinedAndNotNull(controllerService.properties[descriptor.name]);
+
+                // if we are attempting to update a controller service reference
+                if (modifyingService && isCurrentlyConfigured) {
+
+                    // record the current value if set
+                    previouslyReferencedServiceIds.push(controllerService.properties[descriptor.name]);
+                }
+            });
+
+            // update the selected component
+            return $.ajax({
+                type: 'PUT',
+                data: JSON.stringify(updatedControllerService),
+                url: controllerService.uri,
+                dataType: 'json',
+                processData: false,
+                contentType: 'application/json'
+            }).done(function (response) {
+                if (nf.Common.isDefinedAndNotNull(response.controllerService)) {
+                    // update the revision
+                    nf.Client.setRevision(response.revision);
+
+                    // reload all previously referenced controller services
+                    $.each(previouslyReferencedServiceIds, function(_, oldServiceReferenceId) {
+                        reloadControllerService(oldServiceReferenceId);
+                    });
+                }
+            }).fail(handleControllerServiceConfigurationError);
+        }
+    };
+    
+    /**
      * Identifies the descriptors that identify controller services.
      * 
      * @param {object} component
@@ -1078,7 +1153,7 @@ nf.ControllerService = (function () {
         var referencedServiceDescriptors = [];
         
         $.each(component.descriptors, function(_, descriptor) {
-            if (descriptor.identifiesControllerService === true) {
+            if (nf.Common.isDefinedAndNotNull(descriptor.identifiesControllerService)) {
                 referencedServiceDescriptors.push(descriptor);
             }
         });
@@ -1180,8 +1255,9 @@ nf.ControllerService = (function () {
             // initialize the property table
             $('#controller-service-properties').propertytable({
                 readOnly: false,
-                newPropertyDialogContainer: '#new-controller-service-property-container',
-                descriptorDeferred: getControllerServicePropertyDescriptor
+                dialogContainer: '#new-controller-service-property-container',
+                descriptorDeferred: getControllerServicePropertyDescriptor,
+                goToServiceDeferred: goToServiceFromProperty
             });
             
             // initialize the disable service dialog
@@ -1324,8 +1400,9 @@ nf.ControllerService = (function () {
                 // initialize the property table
                 $('#controller-service-properties').propertytable('destroy').propertytable({
                     readOnly: false,
-                    newPropertyDialogContainer: '#new-controller-service-property-container',
-                    descriptorDeferred: getControllerServicePropertyDescriptor
+                    dialogContainer: '#new-controller-service-property-container',
+                    descriptorDeferred: getControllerServicePropertyDescriptor,
+                    goToServiceDeferred: goToServiceFromProperty
                 });
                 
                 // update the mode
@@ -1392,49 +1469,15 @@ nf.ControllerService = (function () {
                                 // close all fields currently being edited
                                 $('#controller-service-properties').propertytable('saveRow');
 
-                                // marshal the settings and properties and update the controller service
-                                var updatedControllerService = marshalDetails();
-
-                                // ensure details are valid as far as we can tell
-                                if (validateDetails(updatedControllerService)) {
-                                    var previouslyReferencedServiceIds = [];
-                                    $.each(identifyReferencedServiceDescriptors(controllerService), function (_, descriptor) {
-                                        var modifyingService = !nf.Common.isUndefined(updatedControllerService.controllerService.properties) && !nf.Common.isUndefined(updatedControllerService.controllerService.properties[descriptor.name]);
-                                        var isCurrentlyConfigured = nf.Common.isDefinedAndNotNull(controllerService.properties[descriptor.name]);
-                                        
-                                        // if we are attempting to update a controller service reference
-                                        if (modifyingService && isCurrentlyConfigured) {
-                                            // record the current value if set
-                                            previouslyReferencedServiceIds.push(controllerService.properties[descriptor.name]);
-                                        }
-                                    });
+                                // save the controller service
+                                saveControllerService(controllerService).done(function (response) {
+                                    // reload the controller service
+                                    renderControllerService(response.controllerService);
+                                    reloadControllerServiceReferences(response.controllerService);
                                     
-                                    // update the selected component
-                                    $.ajax({
-                                        type: 'PUT',
-                                        data: JSON.stringify(updatedControllerService),
-                                        url: controllerService.uri,
-                                        dataType: 'json',
-                                        processData: false,
-                                        contentType: 'application/json'
-                                    }).done(function (response) {
-                                        if (nf.Common.isDefinedAndNotNull(response.controllerService)) {
-                                            nf.Client.setRevision(response.revision);
-
-                                            // reload the controller service
-                                            renderControllerService(response.controllerService);
-                                            reloadControllerServiceReferences(response.controllerService);
-                                            
-                                            // reload all previously referenced controller services
-                                            $.each(previouslyReferencedServiceIds, function(_, oldServiceReferenceId) {
-                                                reloadControllerService(oldServiceReferenceId);
-                                            });
-
-                                            // close the details panel
-                                            controllerServiceDialog.modal('hide');
-                                        }
-                                    }).fail(handleControllerServiceConfigurationError);
-                                }
+                                    // close the details panel
+                                    controllerServiceDialog.modal('hide');
+                                });
                             }
                         }
                     }, {
@@ -1480,47 +1523,10 @@ nf.ControllerService = (function () {
                                         overlayBackground: false,
                                         noHandler: openCustomUi,
                                         yesHandler: function () {
-                                            // marshal the settings and properties and update the controller service
-                                            var updatedControllerService = marshalDetails();
-
-                                            // ensure details are valid as far as we can tell
-                                            if (validateDetails(updatedControllerService)) {
-                                                var previouslyReferencedServiceIds = [];
-                                                $.each(identifyReferencedServiceDescriptors(controllerService), function (_, descriptor) {
-                                                    var modifyingService = !nf.Common.isUndefined(updatedControllerService.controllerService.properties) && !nf.Common.isUndefined(updatedControllerService.controllerService.properties[descriptor.name]);
-                                                    var isCurrentlyConfigured = nf.Common.isDefinedAndNotNull(controllerService.properties[descriptor.name]);
-
-                                                    // if we are attempting to update a controller service reference
-                                                    if (modifyingService && isCurrentlyConfigured) {
-                                                        
-                                                        // record the current value if set
-                                                        previouslyReferencedServiceIds.push(controllerService.properties[descriptor.name]);
-                                                    }
-                                                });
-
-                                                // update the selected component
-                                                $.ajax({
-                                                    type: 'PUT',
-                                                    data: JSON.stringify(updatedControllerService),
-                                                    url: controllerService.uri,
-                                                    dataType: 'json',
-                                                    processData: false,
-                                                    contentType: 'application/json'
-                                                }).done(function (response) {
-                                                    if (nf.Common.isDefinedAndNotNull(response.controllerService)) {
-                                                        // update the revision
-                                                        nf.Client.setRevision(response.revision);
-
-                                                        // reload all previously referenced controller services
-                                                        $.each(previouslyReferencedServiceIds, function(_, oldServiceReferenceId) {
-                                                            reloadControllerService(oldServiceReferenceId);
-                                                        });
-
-                                                        // open the custom ui
-                                                        openCustomUi();
-                                                    }
-                                                }).fail(handleControllerServiceConfigurationError);
-                                            }
+                                            saveControllerService(controllerService).done(function () {
+                                                // open the custom ui
+                                                openCustomUi();
+                                            });
                                         }
                                     });
                                 } else {

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/9963057f/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-processor-configuration.js
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-processor-configuration.js b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-processor-configuration.js
index 4e828df..be3e4c1 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-processor-configuration.js
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-processor-configuration.js
@@ -470,7 +470,7 @@ nf.ProcessorConfiguration = (function () {
             // initialize the property table
             $('#processor-properties').propertytable({
                 readOnly: false,
-                newPropertyDialogContainer: '#new-processor-property-container',
+                dialogContainer: '#new-processor-property-container',
                 descriptorDeferred: function(propertyName) {
                     var processor = $('#processor-configuration').data('processorDetails');
                     return $.ajax({

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/9963057f/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-reporting-task.js
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-reporting-task.js b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-reporting-task.js
index ed13f10..960251e 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-reporting-task.js
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-reporting-task.js
@@ -288,7 +288,7 @@ nf.ReportingTask = (function () {
             // initialize the property table
             $('#reporting-task-properties').propertytable({
                 readOnly: false,
-                newPropertyDialogContainer: '#new-reporting-task-property-container',
+                dialogContainer: '#new-reporting-task-property-container',
                 deferredDescriptor: getReportingTaskPropertyDescriptor
             });
         },
@@ -308,7 +308,7 @@ nf.ReportingTask = (function () {
                 // initialize the property table
                 $('#reporting-task-properties').propertytable('destroy').propertytable({
                     readOnly: false,
-                    newPropertyDialogContainer: '#new-reporting-task-property-container',
+                    dialogContainer: '#new-reporting-task-property-container',
                     deferredDescriptor: getReportingTaskPropertyDescriptor
                 });
                 

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/9963057f/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
index 0e60b2c..6e8c94e 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
@@ -431,6 +431,7 @@ nf.Settings = (function () {
             // select the new controller service
             var row = controllerServicesData.getRowById(controllerService.id);
             controllerServicesGrid.setSelectedRows([row]);
+            controllerServicesGrid.scrollRowIntoView(row);
         }).fail(nf.Common.handleAjaxError);
 
         // hide the dialog
@@ -1147,6 +1148,7 @@ nf.Settings = (function () {
             // select the new reporting task
             var row = reportingTaskData.getRowById(reportingTask.id);
             reportingTaskGrid.setSelectedRows([row]);
+            reportingTaskGrid.scrollRowIntoView(row);
         }).fail(nf.Common.handleAjaxError);
 
         // hide the dialog