Repository: nifi
Updated Branches:
  refs/heads/master ae3012a99 -> 9152a9fdb


http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/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-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
index e2e5eb0..a47cea7 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
@@ -28,9 +28,9 @@ nf.Settings = (function () {
             api: '../nifi-api',
             controllerConfig: '../nifi-api/controller/config',
             controllerArchive: '../nifi-api/controller/archive',
-            controllerServiceTypes: 
'../nifi-api/flow/controller-service-types',
             reportingTaskTypes: '../nifi-api/flow/reporting-task-types',
-            reportingTasks: '../nifi-api/controller/reporting-tasks'
+            createReportingTask: '../nifi-api/controller/reporting-tasks',
+            reportingTasks: '../nifi-api/flow/reporting-tasks'
         }
     };
 
@@ -44,66 +44,56 @@ nf.Settings = (function () {
     };
 
     /**
-     * Initializes the general tab.
+     * Gets the controller services table.
+     *
+     * @returns {*|jQuery|HTMLElement}
      */
-    var initGeneral = function () {
-        // update the visibility of the controls
-        if (nf.Common.isDFM()) {
-            $('#general-settings div.editable').show();
-            $('#general-settings div.read-only').hide();
-
-            // register the click listener for the archive link
-            $('#archive-flow-link').click(function () {
-                $.ajax({
-                    type: 'POST',
-                    url: config.urls.controllerArchive,
-                    dataType: 'json',
-                    contentType: 'application/json'
-                }).done(function (response) {
-                    // show the result dialog
-                    nf.Dialog.showOkDialog({
-                        dialogContent: 'A new flow archive was successfully 
created.',
-                        overlayBackground: false
-                    });
-                }).fail(nf.Common.handleAjaxError);
+    var getControllerServicesTable = function () {
+        return $('#controller-services-table');
+    };
+
+    /**
+     * Saves the settings for the controller.
+     *
+     * @param version
+     */
+    var saveSettings = function (version) {
+        // marshal the configuration details
+        var configuration = marshalConfiguration();
+        var entity = {
+            'revision': nf.Client.getRevision({
+                'revision': {
+                    'version': version
+                }
+            }),
+            'config': configuration
+        };
+
+        // save the new configuration details
+        $.ajax({
+            type: 'PUT',
+            url: config.urls.controllerConfig,
+            data: JSON.stringify(entity),
+            dataType: 'json',
+            contentType: 'application/json'
+        }).done(function (response) {
+            // close the settings dialog
+            nf.Dialog.showOkDialog({
+                dialogContent: 'Settings successfully applied.',
+                overlayBackground: false
             });
 
             // register the click listener for the save button
-            $('#settings-save').click(function () {
-                // marshal the configuration details
-                var configuration = marshalConfiguration();
-                var entity = {
-                    'revision': nf.Client.getRevision({
-                        'version': 0
-                    }),
-                    'config': configuration
-                };
-
-                // save the new configuration details
-                $.ajax({
-                    type: 'PUT',
-                    url: config.urls.controllerConfig,
-                    data: JSON.stringify(entity),
-                    dataType: 'json',
-                    contentType: 'application/json'
-                }).done(function (response) {
-                    // TODO - update the revision
-                    // nf.Client.setRevision(response.revision);
-
-                    // update the displayed name
-                    document.title = response.config.name;
-
-                    // close the settings dialog
-                    nf.Dialog.showOkDialog({
-                        dialogContent: 'Settings successfully applied.',
-                        overlayBackground: false
-                    });
-                }).fail(nf.Common.handleAjaxError);
+            $('#settings-save').off('click').on('click', function () {
+                saveSettings(response.revision.version);
             });
-        } else {
-            $('#general-settings div.editable').hide();
-            $('#general-settings div.read-only').show();
-        }
+        }).fail(nf.Common.handleAjaxError);
+    }
+
+    /**
+     * Initializes the general tab.
+     */
+    var initGeneral = function () {
     };
 
     /**
@@ -112,107 +102,12 @@ nf.Settings = (function () {
     var marshalConfiguration = function () {
         // create the configuration
         var configuration = {};
-        configuration['name'] = $('#data-flow-title-field').val();
-        configuration['comments'] = $('#data-flow-comments-field').val();
         configuration['maxTimerDrivenThreadCount'] = 
$('#maximum-timer-driven-thread-count-field').val();
         configuration['maxEventDrivenThreadCount'] = 
$('#maximum-event-driven-thread-count-field').val();
         return configuration;
     };
 
     /**
-     * Get the text out of the filter field. If the filter field doesn't
-     * have any text it will contain the text 'filter list' so this method
-     * accounts for that.
-     */
-    var getControllerServiceTypeFilterText = function () {
-        var filterText = '';
-        var filterField = $('#controller-service-type-filter');
-        if (!filterField.hasClass(config.styles.filterList)) {
-            filterText = filterField.val();
-        }
-        return filterText;
-    };
-
-    /**
-     * Filters the processor type table.
-     */
-    var applyControllerServiceTypeFilter = function () {
-        // get the dataview
-        var controllerServiceTypesGrid = 
$('#controller-service-types-table').data('gridInstance');
-
-        // ensure the grid has been initialized
-        if (nf.Common.isDefinedAndNotNull(controllerServiceTypesGrid)) {
-            var controllerServiceTypesData = 
controllerServiceTypesGrid.getData();
-
-            // update the search criteria
-            controllerServiceTypesData.setFilterArgs({
-                searchString: getControllerServiceTypeFilterText()
-            });
-            controllerServiceTypesData.refresh();
-
-            // update the selection if possible
-            if (controllerServiceTypesData.getLength() > 0) {
-                controllerServiceTypesGrid.setSelectedRows([0]);
-            }
-        }
-    };
-
-    /**
-     * Hides the selected controller service.
-     */
-    var clearSelectedControllerService = function () {
-        $('#controller-service-type-description').text('');
-        $('#controller-service-type-name').text('');
-        $('#selected-controller-service-name').text('');
-        $('#selected-controller-service-type').text('');
-        $('#controller-service-description-container').hide();
-    };
-
-    /**
-     * Clears the selected controller service type.
-     */
-    var clearControllerServiceSelection = function () {
-        // clear the selected row
-        clearSelectedControllerService();
-
-        // clear the active cell the it can be reselected when its included
-        var controllerServiceTypesGrid = 
$('#controller-service-types-table').data('gridInstance');
-        controllerServiceTypesGrid.resetActiveCell();
-    };
-
-    /**
-     * Performs the filtering.
-     *
-     * @param {object} item     The item subject to filtering
-     * @param {object} args     Filter arguments
-     * @returns {Boolean}       Whether or not to include the item
-     */
-    var filterControllerServiceTypes = function (item, args) {
-        // determine if the item matches the filter
-        var matchesFilter = matchesRegex(item, args);
-
-        // determine if the row matches the selected tags
-        var matchesTags = true;
-        if (matchesFilter) {
-            var tagFilters = 
$('#controller-service-tag-cloud').tagcloud('getSelectedTags');
-            var hasSelectedTags = tagFilters.length > 0;
-            if (hasSelectedTags) {
-                matchesTags = matchesSelectedTags(tagFilters, item['tags']);
-            }
-        }
-
-        // determine if this row should be visible
-        var matches = matchesFilter && matchesTags;
-
-        // if this row is currently selected and its being filtered
-        if (matches === false && $('#selected-controller-service-type').text() 
=== item['type']) {
-            clearControllerServiceSelection();
-        }
-
-        return matches;
-    };
-
-    /**
      * Determines if the item matches the filter.
      *
      * @param {object} item     The item to filter
@@ -265,238 +160,6 @@ nf.Settings = (function () {
     };
 
     /**
-     * Adds the currently selected controller service.
-     */
-    var addSelectedControllerService = function () {
-        var selectedServiceType = 
$('#selected-controller-service-type').text();
-
-        // ensure something was selected
-        if (selectedServiceType === '') {
-            nf.Dialog.showOkDialog({
-                dialogContent: 'The type of controller service to create must 
be selected.',
-                overlayBackground: false
-            });
-        } else {
-            addControllerService(selectedServiceType);
-        }
-    };
-
-    /**
-     * Adds a new controller service of the specified type.
-     *
-     * @param {string} controllerServiceType
-     */
-    var addControllerService = function (controllerServiceType) {
-        // build the controller service entity
-        var controllerServiceEntity = {
-            'component': {
-                'type': controllerServiceType
-            }
-        };
-
-        // add the new controller service
-        var addService = $.ajax({
-            type: 'POST',
-            url: config.urls.api + '/process-groups/' + 
encodeURIComponent(nf.Canvas.getGroupId()) + '/controller-services',
-            data: JSON.stringify(controllerServiceEntity),
-            dataType: 'json',
-            contentType: 'application/json'
-        }).done(function (controllerServiceEntity) {
-            // add the item
-            var controllerServicesGrid = 
$('#controller-services-table').data('gridInstance');
-            var controllerServicesData = controllerServicesGrid.getData();
-            controllerServicesData.addItem(controllerServiceEntity);
-
-            // resort
-            controllerServicesData.reSort();
-            controllerServicesGrid.invalidate();
-
-            // select the new controller service
-            var row = 
controllerServicesData.getRowById(controllerServiceEntity.id);
-            controllerServicesGrid.setSelectedRows([row]);
-            controllerServicesGrid.scrollRowIntoView(row);
-        }).fail(nf.Common.handleAjaxError);
-
-        // hide the dialog
-        $('#new-controller-service-dialog').modal('hide');
-
-        return addService;
-    };
-
-    /**
-     * Initializes the new controller service dialog.
-     */
-    var initNewControllerServiceDialog = function () {
-        // define the function for filtering the list
-        $('#controller-service-type-filter').on('keyup', function (e) {
-            var code = e.keyCode ? e.keyCode : e.which;
-            if (code === $.ui.keyCode.ENTER) {
-                addSelectedControllerService();
-            } else {
-                applyControllerServiceTypeFilter();
-            }
-        }).focus(function () {
-            if ($(this).hasClass(config.styles.filterList)) {
-                $(this).removeClass(config.styles.filterList).val('');
-            }
-        }).blur(function () {
-            if ($(this).val() === '') {
-                
$(this).addClass(config.styles.filterList).val(config.filterText);
-            }
-        }).addClass(config.styles.filterList).val(config.filterText);
-
-        // initialize the processor type table
-        var controllerServiceTypesColumns = [
-            {id: 'type', name: 'Type', field: 'label', sortable: false, 
resizable: true},
-            {id: 'tags', name: 'Tags', field: 'tags', sortable: false, 
resizable: true}
-        ];
-
-        // initialize the dataview
-        var controllerServiceTypesData = new Slick.Data.DataView({
-            inlineFilters: false
-        });
-        controllerServiceTypesData.setItems([]);
-        controllerServiceTypesData.setFilterArgs({
-            searchString: getControllerServiceTypeFilterText()
-        });
-        controllerServiceTypesData.setFilter(filterControllerServiceTypes);
-
-        // initialize the grid
-        var controllerServiceTypesGrid = new 
Slick.Grid('#controller-service-types-table', controllerServiceTypesData, 
controllerServiceTypesColumns, gridOptions);
-        controllerServiceTypesGrid.setSelectionModel(new 
Slick.RowSelectionModel());
-        controllerServiceTypesGrid.registerPlugin(new Slick.AutoTooltips());
-        controllerServiceTypesGrid.setSortColumn('type', true);
-        controllerServiceTypesGrid.onSelectedRowsChanged.subscribe(function 
(e, args) {
-            if ($.isArray(args.rows) && args.rows.length === 1) {
-                var controllerServiceTypeIndex = args.rows[0];
-                var controllerServiceType = 
controllerServiceTypesGrid.getDataItem(controllerServiceTypeIndex);
-
-                // set the controller service type description
-                if (nf.Common.isDefinedAndNotNull(controllerServiceType)) {
-                    if (nf.Common.isBlank(controllerServiceType.description)) {
-                        
$('#controller-service-type-description').attr('title', '').html('<span 
class="unset">No description specified</span>');
-                    } else {
-                        
$('#controller-service-type-description').html(controllerServiceType.description).ellipsis();
-                    }
-
-                    // populate the dom
-                    
$('#controller-service-type-name').text(controllerServiceType.label).ellipsis();
-                    
$('#selected-controller-service-name').text(controllerServiceType.label);
-                    
$('#selected-controller-service-type').text(controllerServiceType.type);
-
-                    // show the selected controller service
-                    $('#controller-service-description-container').show();
-                }
-            }
-        });
-        controllerServiceTypesGrid.onDblClick.subscribe(function (e, args) {
-            var controllerServiceType = 
controllerServiceTypesGrid.getDataItem(args.row);
-            addControllerService(controllerServiceType.type);
-        });
-
-        // wire up the dataview to the grid
-        controllerServiceTypesData.onRowCountChanged.subscribe(function (e, 
args) {
-            controllerServiceTypesGrid.updateRowCount();
-            controllerServiceTypesGrid.render();
-
-            // update the total number of displayed processors
-            $('#displayed-controller-service-types').text(args.current);
-        });
-        controllerServiceTypesData.onRowsChanged.subscribe(function (e, args) {
-            controllerServiceTypesGrid.invalidateRows(args.rows);
-            controllerServiceTypesGrid.render();
-        });
-        
controllerServiceTypesData.syncGridSelection(controllerServiceTypesGrid, true);
-
-        // hold onto an instance of the grid
-        $('#controller-service-types-table').data('gridInstance', 
controllerServiceTypesGrid);
-
-        // load the available controller services
-        $.ajax({
-            type: 'GET',
-            url: config.urls.controllerServiceTypes,
-            dataType: 'json'
-        }).done(function (response) {
-            var id = 0;
-            var tags = [];
-
-            // begin the update
-            controllerServiceTypesData.beginUpdate();
-
-            // go through each controller service type
-            $.each(response.controllerServiceTypes, function (i, 
documentedType) {
-                // add the documented type
-                controllerServiceTypesData.addItem({
-                    id: id++,
-                    label: nf.Common.substringAfterLast(documentedType.type, 
'.'),
-                    type: documentedType.type,
-                    description: 
nf.Common.escapeHtml(documentedType.description),
-                    tags: documentedType.tags.join(', ')
-                });
-
-                // count the frequency of each tag for this type
-                $.each(documentedType.tags, function (i, tag) {
-                    tags.push(tag.toLowerCase());
-                });
-            });
-
-            // end the udpate
-            controllerServiceTypesData.endUpdate();
-
-            // set the total number of processors
-            $('#total-controller-service-types, 
#displayed-controller-service-types').text(response.controllerServiceTypes.length);
-
-            // create the tag cloud
-            $('#controller-service-tag-cloud').tagcloud({
-                tags: tags,
-                select: applyControllerServiceTypeFilter,
-                remove: applyControllerServiceTypeFilter
-            });
-        }).fail(nf.Common.handleAjaxError);
-
-        // initialize the controller service dialog
-        $('#new-controller-service-dialog').modal({
-            headerText: 'Add Controller Service',
-            overlayBackground: false,
-            buttons: [{
-                buttonText: 'Add',
-                handler: {
-                    click: function () {
-                        addSelectedControllerService();
-                    }
-                }
-            }, {
-                buttonText: 'Cancel',
-                handler: {
-                    click: function () {
-                        $(this).modal('hide');
-                    }
-                }
-            }],
-            handler: {
-                close: function () {
-                    // clear the selected row
-                    clearSelectedControllerService();
-
-                    // clear any filter strings
-                    
$('#controller-service-type-filter').addClass(config.styles.filterList).val(config.filterText);
-
-                    // clear the tagcloud
-                    
$('#controller-service-tag-cloud').tagcloud('clearSelectedTags');
-
-                    // reset the filter
-                    applyControllerServiceTypeFilter();
-
-                    // unselect any current selection
-                    var processTypesGrid = 
$('#controller-service-types-table').data('gridInstance');
-                    processTypesGrid.setSelectedRows([]);
-                    processTypesGrid.resetActiveCell();
-                }
-            }
-        });
-    };
-
-    /**
      * Formatter for the name column.
      *
      * @param {type} row
@@ -577,270 +240,6 @@ nf.Settings = (function () {
     };
 
     /**
-     * Initializes the controller services tab.
-     */
-    var initControllerServices = function () {
-        // initialize the new controller service dialog
-        initNewControllerServiceDialog();
-
-        // more details formatter
-        var moreControllerServiceDetails = function (row, cell, value, 
columnDef, dataContext) {
-            if (!dataContext.accessPolicy.canRead) {
-                return '';
-            }
-            
-            var markup = '<img src="images/iconDetails.png" title="View 
Details" class="pointer view-controller-service" style="margin-top: 5px; float: 
left;" />';
-
-            // always include a button to view the usage
-            markup += '<img src="images/iconUsage.png" title="Usage" 
class="pointer controller-service-usage" style="margin-left: 6px; margin-top: 
3px; float: left;" />';
-
-            var hasErrors = 
!nf.Common.isEmpty(dataContext.component.validationErrors);
-            var hasBulletins = 
!nf.Common.isEmpty(dataContext.component.bulletins);
-
-            if (hasErrors) {
-                markup += '<img src="images/iconAlert.png" class="has-errors" 
style="margin-top: 4px; margin-left: 3px; float: left;" />';
-            }
-
-            if (hasBulletins) {
-                markup += '<img src="images/iconBulletin.png" 
class="has-bulletins" style="margin-top: 5px; margin-left: 5px; float: 
left;"/>';
-            }
-
-            if (hasErrors || hasBulletins) {
-                markup += '<span class="hidden row-id">' + 
nf.Common.escapeHtml(dataContext.id) + '</span>';
-            }
-
-            return markup;
-        };
-
-        var controllerServiceStateFormatter = function (row, cell, value, 
columnDef, dataContext) {
-            if (!dataContext.accessPolicy.canRead) {
-                return '';
-            }
-            
-            // determine the appropriate label
-            var icon = '', label = '';
-            if (!nf.Common.isEmpty(dataContext.component.validationErrors)) {
-                icon = 'invalid';
-                label = 'Invalid';
-            } else {
-                if (dataContext.component.state === 'DISABLED') {
-                    icon = 'disabled';
-                    label = 'Disabled';
-                } else if (dataContext.component.state === 'DISABLING') {
-                    icon = 'disabled';
-                    label = 'Disabling';
-                } else if (dataContext.component.state === 'ENABLED') {
-                    icon = 'enabled';
-                    label = 'Enabled';
-                } else if (dataContext.component.state === 'ENABLING') {
-                    icon = 'enabled';
-                    label = 'Enabling';
-                }
-            }
-
-            // format the markup
-            var formattedValue = '<div class="' + icon + '" style="margin-top: 
3px;"></div>';
-            return formattedValue + '<div class="status-text" 
style="margin-top: 2px; margin-left: 4px; float: left;">' + label + '</div>';
-        };
-
-        var controllerServiceActionFormatter = function (row, cell, value, 
columnDef, dataContext) {
-            var markup = '';
-
-            if (dataContext.accessPolicy.canRead && 
dataContext.accessPolicy.canWrite) {
-                if (dataContext.component.state === 'ENABLED' || 
dataContext.component.state === 'ENABLING') {
-                    markup += '<img src="images/iconDisable.png" 
title="Disable" class="pointer disable-controller-service" style="margin-top: 
2px;" />';
-                } else if (dataContext.component.state === 'DISABLED') {
-                    markup += '<img src="images/iconEdit.png" title="Edit" 
class="pointer edit-controller-service" style="margin-top: 2px;" />';
-
-                    // if there are no validation errors allow enabling
-                    if 
(nf.Common.isEmpty(dataContext.component.validationErrors)) {
-                        markup += '<img src="images/iconEnable.png" 
title="Enable" class="pointer enable-controller-service" style="margin-top: 
2px; margin-left: 3px;"/>';
-                    }
-
-                    markup += '<img src="images/iconDelete.png" title="Remove" 
class="pointer delete-controller-service" style="margin-top: 2px; margin-left: 
3px;" />';
-                }
-
-                if (dataContext.component.persistsState === true) {
-                    markup += '<img src="images/iconViewState.png" title="View 
State" class="pointer view-state-controller-service" style="margin-top: 2px; 
margin-left: 3px;" />';
-                }
-            }
-
-            return markup;
-        };
-
-        // define the column model for the controller services table
-        var controllerServicesColumns = [
-            {id: 'moreDetails', name: '&nbsp;', resizable: false, formatter: 
moreControllerServiceDetails, sortable: true, width: 90, maxWidth: 90, toolTip: 
'Sorts based on presence of bulletins'},
-            {id: 'name', name: 'Name', formatter: nameFormatter, sortable: 
true, resizable: true},
-            {id: 'type', name: 'Type', formatter: typeFormatter, sortable: 
true, resizable: true},
-            {id: 'state', name: 'State', formatter: 
controllerServiceStateFormatter, sortable: true, resizeable: true}
-        ];
-
-        // action column should always be last
-        controllerServicesColumns.push({id: 'actions', name: '&nbsp;', 
resizable: false, formatter: controllerServiceActionFormatter, sortable: false, 
width: 90, maxWidth: 90});
-
-        // initialize the dataview
-        var controllerServicesData = new Slick.Data.DataView({
-            inlineFilters: false
-        });
-        controllerServicesData.setItems([]);
-
-        // initialize the sort
-        sort({
-            columnId: 'name',
-            sortAsc: true
-        }, controllerServicesData);
-
-        // initialize the grid
-        var controllerServicesGrid = new 
Slick.Grid('#controller-services-table', controllerServicesData, 
controllerServicesColumns, gridOptions);
-        controllerServicesGrid.setSelectionModel(new 
Slick.RowSelectionModel());
-        controllerServicesGrid.registerPlugin(new Slick.AutoTooltips());
-        controllerServicesGrid.setSortColumn('name', true);
-        controllerServicesGrid.onSort.subscribe(function (e, args) {
-            sort({
-                columnId: args.sortCol.field,
-                sortAsc: args.sortAsc
-            }, controllerServicesData);
-        });
-
-        // configure a click listener
-        controllerServicesGrid.onClick.subscribe(function (e, args) {
-            var target = $(e.target);
-
-            // get the service at this row
-            var controllerServiceEntity = 
controllerServicesData.getItem(args.row);
-
-            // determine the desired action
-            if (controllerServicesGrid.getColumns()[args.cell].id === 
'actions') {
-                if (target.hasClass('edit-controller-service')) {
-                    
nf.ControllerService.showConfiguration(controllerServiceEntity);
-                } else if (target.hasClass('enable-controller-service')) {
-                    nf.ControllerService.enable(controllerServiceEntity);
-                } else if (target.hasClass('disable-controller-service')) {
-                    nf.ControllerService.disable(controllerServiceEntity);
-                } else if (target.hasClass('delete-controller-service')) {
-                    nf.ControllerService.remove(controllerServiceEntity);
-                } else if (target.hasClass('view-state-controller-service')) {
-                    
nf.ComponentState.showState(controllerServiceEntity.component, 
controllerServiceEntity.state === 'DISABLED');
-                }
-            } else if (controllerServicesGrid.getColumns()[args.cell].id === 
'moreDetails') {
-                if (target.hasClass('view-controller-service')) {
-                    nf.ControllerService.showDetails(controllerServiceEntity);
-                } else if (target.hasClass('controller-service-usage')) {
-                     // close the settings dialog
-                     $('#shell-close-button').click();
-
-                     // open the documentation for this controller service
-                     nf.Shell.showPage('../nifi-docs/documentation?' + 
$.param({
-                         select: 
nf.Common.substringAfterLast(controllerServiceEntity.component.type, '.')
-                     })).done(function() {
-                         nf.Settings.showSettings();
-                     });
-                 }
-            }
-        });
-
-        // wire up the dataview to the grid
-        controllerServicesData.onRowCountChanged.subscribe(function (e, args) {
-            controllerServicesGrid.updateRowCount();
-            controllerServicesGrid.render();
-        });
-        controllerServicesData.onRowsChanged.subscribe(function (e, args) {
-            controllerServicesGrid.invalidateRows(args.rows);
-            controllerServicesGrid.render();
-        });
-        controllerServicesData.syncGridSelection(controllerServicesGrid, true);
-
-        // hold onto an instance of the grid
-        $('#controller-services-table').data('gridInstance', 
controllerServicesGrid).on('mouseenter', 'div.slick-cell', function (e) {
-            var errorIcon = $(this).find('img.has-errors');
-            if (errorIcon.length && !errorIcon.data('qtip')) {
-                var serviceId = $(this).find('span.row-id').text();
-
-                // get the service item
-                var controllerServiceEntity = 
controllerServicesData.getItemById(serviceId);
-
-                // format the errors
-                var tooltip = 
nf.Common.formatUnorderedList(controllerServiceEntity.component.validationErrors);
-
-                // show the tooltip
-                if (nf.Common.isDefinedAndNotNull(tooltip)) {
-                    errorIcon.qtip($.extend({
-                        content: tooltip,
-                        position: {
-                            target: 'mouse',
-                            viewport: $(window),
-                            adjust: {
-                                x: 8,
-                                y: 8,
-                                method: 'flipinvert flipinvert'
-                            }
-                        }
-                    }, nf.Common.config.tooltipConfig));
-                }
-            }
-
-            var bulletinIcon = $(this).find('img.has-bulletins');
-            if (bulletinIcon.length && !bulletinIcon.data('qtip')) {
-                var taskId = $(this).find('span.row-id').text();
-
-                // get the task item
-                var controllerServiceEntity = 
controllerServicesData.getItemById(taskId);
-
-                // format the tooltip
-                var bulletins = 
nf.Common.getFormattedBulletins(controllerServiceEntity.component.bulletins);
-                var tooltip = nf.Common.formatUnorderedList(bulletins);
-
-                // show the tooltip
-                if (nf.Common.isDefinedAndNotNull(tooltip)) {
-                    bulletinIcon.qtip($.extend({}, 
nf.Common.config.tooltipConfig, {
-                        content: tooltip,
-                        position: {
-                            target: 'mouse',
-                            viewport: $(window),
-                            adjust: {
-                                x: 8,
-                                y: 8,
-                                method: 'flipinvert flipinvert'
-                            }
-                        }
-                    }));
-                }
-            }
-        });
-    };
-
-    /**
-     * Loads the controller services.
-     */
-    var loadControllerServices = function () {
-        return $.ajax({
-            type: 'GET',
-            url: config.urls.api + '/flow/process-groups/' + 
encodeURIComponent(nf.Canvas.getGroupId()) + '/controller-services',
-            dataType: 'json'
-        }).done(function (response) {
-            var services = [];
-            $.each(response.controllerServices, function (_, service) {
-                services.push($.extend({
-                    bulletins: []
-                }, service));
-            });
-
-            var controllerServicesElement = $('#controller-services-table');
-            nf.Common.cleanUpTooltips(controllerServicesElement, 
'img.has-errors');
-            nf.Common.cleanUpTooltips(controllerServicesElement, 
'img.has-bulletins');
-
-            var controllerServicesGrid = 
controllerServicesElement.data('gridInstance');
-            var controllerServicesData = controllerServicesGrid.getData();
-
-            // update the controller services
-            controllerServicesData.setItems(services);
-            controllerServicesData.reSort();
-            controllerServicesGrid.invalidate();
-        });
-    };
-
-    /**
      * Get the text out of the filter field. If the filter field doesn't
      * have any text it will contain the text 'filter list' so this method
      * accounts for that.
@@ -966,7 +365,7 @@ nf.Settings = (function () {
         // add the new reporting task
         var addTask = $.ajax({
             type: 'POST',
-            url: config.urls.reportingTasks,
+            url: config.urls.createReportingTask,
             data: JSON.stringify(reportingTaskEntity),
             dataType: 'json',
             contentType: 'application/json'
@@ -1399,6 +798,81 @@ nf.Settings = (function () {
     };
 
     /**
+     * Loads the settings.
+     */
+    var loadSettings = function () {
+        var setUnauthorizedText = function () {
+            
$('#read-only-maximum-timer-driven-thread-count-field').addClass('unset').text('Unauthorized');
+            
$('#read-only-maximum-event-driven-thread-count-field').addClass('unset').text('Unauthorized');
+        };
+        
+        var setEditable = function (editable) {
+            if (editable) {
+                $('#general-settings div.editable').show();
+                $('#general-settings div.read-only').hide();
+                $('#settings-save').show();
+            } else {
+                $('#general-settings div.editable').hide();
+                $('#general-settings div.read-only').show();
+                $('#settings-save').hide();
+            }
+        };
+        
+        var settings = $.Deferred(function (deferred) {
+            $.ajax({
+                type: 'GET',
+                url: config.urls.controllerConfig,
+                dataType: 'json'
+            }).done(function (response) {
+                // update the current time
+                
$('#settings-last-refreshed').text(response.config.currentTime);
+
+                if (response.accessPolicy.canWrite) {
+                    // populate the settings
+                    
$('#maximum-timer-driven-thread-count-field').removeClass('unset').val(response.config.maxTimerDrivenThreadCount);
+                    
$('#maximum-event-driven-thread-count-field').removeClass('unset').val(response.config.maxEventDrivenThreadCount);
+
+                    setEditable(true);
+
+                    // register the click listener for the save button
+                    $('#settings-save').off('click').on('click', function () {
+                        saveSettings(response.revision.version);
+                    });
+                } else {
+                    if (response.accessPolicy.canRead) {
+                        // populate the settings
+                        
$('#read-only-maximum-timer-driven-thread-count-field').removeClass('unset').text(response.config.maxTimerDrivenThreadCount);
+                        
$('#read-only-maximum-event-driven-thread-count-field').removeClass('unset').text(response.config.maxEventDrivenThreadCount);
+                    } else {
+                        setUnauthorizedText();
+                    }
+
+                    setEditable(false);
+                }
+                deferred.resolve();
+            }).fail(function (xhr, status, error) {
+                if (xhr.status === 403) {
+                    setUnauthorizedText();
+                    setEditable(false);
+                    deferred.resolve();
+                } else {
+                    deferred.reject(xhr, status, error);
+                }
+            });
+        }).promise();
+            
+        // load the controller services
+        var controllerServicesUri = config.urls.api + 
'/flow/controller/controller-services';
+        var controllerServices = 
nf.ControllerServices.loadControllerServices(controllerServicesUri, 
getControllerServicesTable());
+
+        // load the reporting tasks
+        var reportingTasks = loadReportingTasks();
+
+        // return a deferred for all parts of the settings
+        return $.when(settings, controllerServices, 
reportingTasks).fail(nf.Common.handleAjaxError);
+    };
+
+    /**
      * Loads the reporting tasks.
      */
     var loadReportingTasks = function () {
@@ -1428,9 +902,30 @@ nf.Settings = (function () {
         });
     };
 
+    /**
+     * Shows the process group configuration.
+     */
+    var showSettings = function () {
+        // show the settings dialog
+        nf.Shell.showContent('#settings').done(function () {
+            reset();
+        });
+
+        // adjust the table size
+        nf.Settings.resetTableSize();
+    };
+
+    /**
+     * Reset state of this dialog.
+     */
+    var reset = function () {
+        // reset button state
+        $('#settings-save').mouseout();
+    };
+
     return {
         /**
-         * Initializes the status page.
+         * Initializes the settings page.
          */
         init: function () {
             // initialize the settings tabs
@@ -1469,35 +964,17 @@ nf.Settings = (function () {
                 }
             });
 
-            // setup the tooltip for the refresh icon
-            $('#settings-refresh-required-icon').qtip($.extend({
-                content: 'This flow has been modified by another user. Please 
refresh.'
-            }, nf.CanvasUtils.config.systemTooltipConfig));
-
-            // settings refresh button... TODO?
+            // settings refresh button
             nf.Common.addHoverEffect('#settings-refresh-button', 
'button-refresh', 'button-refresh-hover').click(function () {
-                if ($('#settings-refresh-required-icon').is(':visible')) {
-                    
nf.ng.Bridge.get('appCtrl.serviceProvider.headerCtrl').reloadAndClearWarnings();
-                } else {
-                    nf.Settings.loadSettings();
-                }
+                loadSettings();
             });
 
             // create a new controller service or reporting task
             $('#new-service-or-task').on('click', function () {
-                var selectedTab = $('li.settings-selected-tab').text();
+                var selectedTab = $('#settings-tabs 
li.settings-selected-tab').text();
                 if (selectedTab === 'Controller Services') {
-                    $('#new-controller-service-dialog').modal('show');
-
-                    // reset the canvas size after the dialog is shown
-                    var controllerServiceTypesGrid = 
$('#controller-service-types-table').data('gridInstance');
-                    if 
(nf.Common.isDefinedAndNotNull(controllerServiceTypesGrid)) {
-                        controllerServiceTypesGrid.setSelectedRows([0]);
-                        controllerServiceTypesGrid.resizeCanvas();
-                    }
-
-                    // set the initial focus
-                    $('#controller-service-type-filter').focus();
+                    var controllerServicesUri = config.urls.api + 
'/controller/controller-services';
+                    
nf.ControllerServices.promptNewControllerService(controllerServicesUri, 
getControllerServicesTable());
                 } else if (selectedTab === 'Reporting Tasks') {
                     $('#new-reporting-task-dialog').modal('show');
 
@@ -1512,10 +989,15 @@ nf.Settings = (function () {
                     $('#reporting-task-type-filter').focus();
                 }
             });
+            
+            // handle window resizing
+            $(window).on('resize', function (e) {
+                nf.Settings.resetTableSize();
+            });
 
             // initialize each tab
             initGeneral();
-            initControllerServices();
+            nf.ControllerServices.init(getControllerServicesTable());
             initReportingTasks();
         },
 
@@ -1523,10 +1005,7 @@ nf.Settings = (function () {
          * Update the size of the grid based on its container's current size.
          */
         resetTableSize: function () {
-            var controllerServicesGrid = 
$('#controller-services-table').data('gridInstance');
-            if (nf.Common.isDefinedAndNotNull(controllerServicesGrid)) {
-                controllerServicesGrid.resizeCanvas();
-            }
+            nf.ControllerServices.resetTableSize(getControllerServicesTable());
 
             var reportingTasksGrid = 
$('#reporting-tasks-table').data('gridInstance');
             if (nf.Common.isDefinedAndNotNull(reportingTasksGrid)) {
@@ -1538,54 +1017,25 @@ nf.Settings = (function () {
          * Shows the settings dialog.
          */
         showSettings: function () {
-            // show the settings dialog
-            nf.Shell.showContent('#settings').done(function () {
-                // reset button state
-                $('#settings-save').mouseout();
-            });
-
-            // adjust the table size
-            nf.Settings.resetTableSize();
+            return loadSettings().done(showSettings);
         },
 
         /**
-         * Loads the settings.
+         * Selects the specified controller service.
+         * 
+         * @param {string} controllerServiceId
          */
-        loadSettings: function () {
-            var settings = $.ajax({
-                type: 'GET',
-                url: config.urls.controllerConfig,
-                dataType: 'json'
-            }).done(function (response) {
-                // ensure the config is present
-                if (nf.Common.isDefinedAndNotNull(response.config)) {
-                    // set the header
-                    $('#settings-header-text').text(response.config.name + ' 
Settings');
-                    
$('#settings-last-refreshed').text(response.config.currentTime);
-
-                    // populate the controller settings
-                    if (nf.Common.isDFM()) {
-                        $('#data-flow-title-field').val(response.config.name);
-                        
$('#data-flow-comments-field').val(response.config.comments);
-                        
$('#maximum-timer-driven-thread-count-field').val(response.config.maxTimerDrivenThreadCount);
-                        
$('#maximum-event-driven-thread-count-field').val(response.config.maxEventDrivenThreadCount);
-                    } else {
-                        
$('#read-only-data-flow-title-field').html(nf.Common.formatValue(response.config.name));
-                        
$('#read-only-data-flow-comments-field').html(nf.Common.formatValue(response.config.comments));
-                        
$('#read-only-maximum-timer-driven-thread-count-field').text(response.config.maxTimerDrivenThreadCount);
-                        
$('#read-only-maximum-event-driven-thread-count-field').text(response.config.maxEventDrivenThreadCount);
-                    }
-                }
-            });
+        selectControllerService: function (controllerServiceId) {
+            var controllerServiceGrid = 
getControllerServicesTable().data('gridInstance');
+            var controllerServiceData = controllerServiceGrid.getData();
 
-            // load the controller services
-            var controllerServices = loadControllerServices();
+            // select the desired service
+            var row = controllerServiceData.getRowById(controllerServiceId);
+            controllerServiceGrid.setSelectedRows([row]);
+            controllerServiceGrid.scrollRowIntoView(row);
 
-            // load the reporting tasks
-            var reportingTasks = loadReportingTasks();
-
-            // return a deferred for all parts of the settings
-            return $.when(settings, controllerServices, 
reportingTasks).fail(nf.Common.handleAjaxError);
+            // select the controller services tab
+            $('#settings-tabs').find('li:eq(1)').click();  
         },
 
         /**
@@ -1595,35 +1045,9 @@ nf.Settings = (function () {
          * @param {object} reportingTaskBulletins
          */
         setBulletins: function(controllerServiceBulletins, 
reportingTaskBulletins) {
-            // controller services
-            var controllerServicesGrid = 
$('#controller-services-table').data('gridInstance');
-            var controllerServicesData = controllerServicesGrid.getData();
-            controllerServicesData.beginUpdate();
-
-            // if there are some bulletins process them
-            if (!nf.Common.isEmpty(controllerServiceBulletins)) {
-                var controllerServiceBulletinsBySource = d3.nest()
-                    .key(function(d) { return d.sourceId; })
-                    .map(controllerServiceBulletins, d3.map);
-
-                controllerServiceBulletinsBySource.forEach(function(sourceId, 
sourceBulletins) {
-                    var controllerService = 
controllerServicesData.getItemById(sourceId);
-                    if (nf.Common.isDefinedAndNotNull(controllerService)) {
-                        controllerServicesData.updateItem(sourceId, 
$.extend(controllerService, {
-                            bulletins: sourceBulletins
-                        }));
-                    }
-                });
-            } else {
-                // if there are no bulletins clear all
-                var controllerServices = controllerServicesData.getItems();
-                $.each(controllerServices, function(_, controllerService) {
-                    controllerServicesData.updateItem(controllerService.id, 
$.extend(controllerService, {
-                        bulletins: []
-                    }));
-                });
+            if ($('#controller-services-table').data('gridInstance')) {
+                
nf.ControllerServices.setBulletins(getControllerServicesTable(), 
controllerServiceBulletins);
             }
-            controllerServicesData.endUpdate();
 
             // reporting tasks
             var reportingTasksGrid = 
$('#reporting-tasks-table').data('gridInstance');

http://git-wip-us.apache.org/repos/asf/nifi/blob/9152a9fd/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
index 305775a..2bef094 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
@@ -337,8 +337,8 @@ nf.Common = (function () {
                 return;
             }
 
-            // status code 400, 404, and 409 are expected response codes for 
common errors.
-            if (xhr.status === 400 || xhr.status === 404 || xhr.status === 
409) {
+            // status code 400, 403, 404, and 409 are expected response codes 
for common errors.
+            if (xhr.status === 400 || xhr.status === 403 || xhr.status === 404 
|| xhr.status === 409) {
                 nf.Dialog.showOkDialog({
                     dialogContent: nf.Common.escapeHtml(xhr.responseText),
                     overlayBackground: false
@@ -360,14 +360,7 @@ nf.Common = (function () {
                 } else if (xhr.status === 401) {
                     $('#message-title').text('Unauthorized');
                     if ($.trim(xhr.responseText) === '') {
-                        $('#message-content').text('Authorization is required 
to use this NiFi.');
-                    } else {
-                        $('#message-content').text(xhr.responseText);
-                    }
-                } else if (xhr.status === 403) {
-                    $('#message-title').text('Access Denied');
-                    if ($.trim(xhr.responseText) === '') {
-                        $('#message-content').text('Unable to authorize you to 
use this NiFi.');
+                        $('#message-content').text('Authentication is required 
to use this NiFi.');
                     } else {
                         $('#message-content').text(xhr.responseText);
                     }

Reply via email to