You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by bb...@apache.org on 2018/01/08 18:13:54 UTC
[06/50] nifi git commit: NIFI-4436: - Adding support to save a
version of a flow based on a selected Process Group. - Adding support for
revert changes back to the most recent version. - Adding support to
disconnect from version control. - Moving the ver
http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-component-state.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-component-state.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-component-state.js
index 8fb73a8..8f8bb6d 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-component-state.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-component-state.js
@@ -230,7 +230,7 @@
applyFilter();
});
- // initialize the processor configuration dialog
+ // initialize the component state dialog
$('#component-state-dialog').modal({
scrollableContentStyle: 'scrollable',
headerText: 'Component State',
http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-component-version.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-component-version.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-component-version.js
index 3110e64..02abac1 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-component-version.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-component-version.js
@@ -18,7 +18,7 @@
/* global nf */
/**
- * Views state for a given component.
+ * Handles changing the version of a component bundle.
*/
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js
index a32a47f..f128086 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js
@@ -97,7 +97,7 @@
* @param {selection} selection The selection of currently selected components
*/
var canCreateTemplate = function (selection) {
- return nfCanvasUtils.canWrite() && (selection.empty() || nfCanvasUtils.canRead(selection));
+ return nfCanvasUtils.canWriteCurrentGroup() && (selection.empty() || nfCanvasUtils.canRead(selection));
};
/**
@@ -106,7 +106,7 @@
* @param {selection} selection The selection of currently selected components
*/
var canUploadTemplate = function (selection) {
- return nfCanvasUtils.canWrite() && selection.empty();
+ return nfCanvasUtils.canWriteCurrentGroup() && selection.empty();
};
/**
@@ -370,6 +370,89 @@
};
/**
+ * Determines whether the current selection supports flow versioning.
+ *
+ * @param selection
+ */
+ var supportsFlowVersioning = function (selection) {
+ if (nfCanvasUtils.supportsFlowVersioning() === false) {
+ return false;
+ }
+
+ if (selection.empty()) {
+ return nfCanvasUtils.canReadCurrentGroup() && nfCanvasUtils.canWriteCurrentGroup();
+ }
+
+ if (isProcessGroup(selection) === true) {
+ return nfCanvasUtils.canRead(selection) && nfCanvasUtils.canModify(selection);
+ }
+
+ return false;
+ };
+
+ /**
+ * Determines whether the current selection supports starting flow versioning.
+ *
+ * @param selection
+ */
+ var supportsStartFlowVersioning = function (selection) {
+ // ensure this selection supports flow versioning above
+ if (supportsFlowVersioning(selection) === false) {
+ return false;
+ }
+
+ if (selection.empty()) {
+ // check bread crumbs for version control information in the current group
+ var breadcrumbEntities = nfNgBridge.injector.get('breadcrumbsCtrl').getBreadcrumbs();
+ if (breadcrumbEntities.length > 0) {
+ var breadcrumbEntity = breadcrumbEntities[breadcrumbEntities.length - 1];
+ if (breadcrumbEntity.permissions.canRead) {
+ return nfCommon.isUndefinedOrNull(breadcrumbEntity.breadcrumb.versionControlInformation);
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ // check the selection for version control information
+ var processGroupData = selection.datum();
+ return nfCommon.isUndefinedOrNull(processGroupData.component.versionControlInformation);
+ };
+
+ /**
+ * Determines whether the current selection supports stopping flow versioning.
+ *
+ * @param selection
+ */
+ var supportsStopFlowVersioning = function (selection) {
+ // ensure this selection supports flow versioning above
+ if (supportsFlowVersioning(selection) === false) {
+ return false;
+ }
+
+ if (selection.empty()) {
+ // check bread crumbs for version control information in the current group
+ var breadcrumbEntities = nfNgBridge.injector.get('breadcrumbsCtrl').getBreadcrumbs();
+ if (breadcrumbEntities.length > 0) {
+ var breadcrumbEntity = breadcrumbEntities[breadcrumbEntities.length - 1];
+ if (breadcrumbEntity.permissions.canRead) {
+ return nfCommon.isDefinedAndNotNull(breadcrumbEntity.breadcrumb.versionControlInformation);
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ // check the selection for version control information
+ var processGroupData = selection.datum();
+ return nfCommon.isDefinedAndNotNull(processGroupData.component.versionControlInformation);
+ };
+
+ /**
* Determines whether the current selection could have provenance.
*
* @param {selection} selection
@@ -548,6 +631,16 @@
{id: 'show-details-menu-item', condition: hasDetails, menuItem: {clazz: 'fa fa-gear', text: 'View configuration', action: 'showDetails'}},
{id: 'variable-registry-menu-item', condition: hasVariables, menuItem: {clazz: 'fa', text: 'Variables', action: 'openVariableRegistry'}},
{separator: true},
+ {id: 'version-menu-item', groupMenuItem: {clazz: 'fa', text: 'Version'}, menuItems: [
+ {id: 'start-version-control-menu-item', condition: supportsStartFlowVersioning, menuItem: {clazz: 'fa fa-floppy-o', text: 'Start version control', action: 'saveFlowVersion'}},
+ {separator: true},
+ {id: 'commit-menu-item', condition: supportsStopFlowVersioning, menuItem: {clazz: 'fa fa-floppy-o', text: 'Commit local changes', action: 'saveFlowVersion'}},
+ {id: 'revert-menu-item', condition: supportsStopFlowVersioning, menuItem: {clazz: 'fa', text: 'Revert local changes', action: 'revertFlowChanges'}},
+ {id: 'change-version-menu-item', condition: supportsStopFlowVersioning, menuItem: {clazz: 'fa', text: 'Change version', action: 'changeFlowVersion'}},
+ {separator: true},
+ {id: 'stop-version-control-menu-item', condition: supportsStopFlowVersioning, menuItem: {clazz: 'fa', text: 'Stop version control', action: 'disconnectFlowVersioning'}}
+ ]},
+ {separator: true},
{id: 'enter-group-menu-item', condition: isProcessGroup, menuItem: {clazz: 'fa fa-sign-in', text: 'Enter group', action: 'enterGroup'}},
{separator: true},
{id: 'start-menu-item', condition: isRunnable, menuItem: {clazz: 'fa fa-play', text: 'Start', action: 'start'}},
http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-flow-version.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-flow-version.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-flow-version.js
new file mode 100644
index 0000000..6315d30
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-flow-version.js
@@ -0,0 +1,476 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* global define, module, require, exports */
+
+/**
+ * Handles versioning.
+ */
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery',
+ 'nf.ng.Bridge',
+ 'nf.ErrorHandler',
+ 'nf.Dialog',
+ 'nf.Common',
+ 'nf.Client',
+ 'nf.CanvasUtils',
+ 'nf.ProcessGroup',
+ 'nf.Graph'],
+ function ($, nfNgBridge, nfErrorHandler, nfDialog, nfCommon, nfClient, nfCanvasUtils, nfProcessGroup, nfGraph) {
+ return (nf.FlowVersion = factory($, nfNgBridge, nfErrorHandler, nfDialog, nfCommon, nfClient, nfCanvasUtils, nfProcessGroup, nfGraph));
+ });
+ } else if (typeof exports === 'object' && typeof module === 'object') {
+ module.exports = (nf.FlowVerison =
+ factory(require('jquery'),
+ require('nf.ng.Bridge'),
+ require('nf.ErrorHandler'),
+ require('nf.Dialog'),
+ require('nf.Common'),
+ require('nf.Client'),
+ require('nf.CanvasUtils'),
+ require('nf.ProcessGroup'),
+ require('nf.Graph')));
+ } else {
+ nf.FlowVersion = factory(root.$,
+ root.nf.ng.Bridge,
+ root.nf.ErrorHandler,
+ root.nf.Dialog,
+ root.nf.Common,
+ root.nf.Client,
+ root.nf.CanvasUtils,
+ root.nf.ProcessGroup,
+ root.nf.Graph);
+ }
+}(this, function ($, nfNgBridge, nfErrorHandler, nfDialog, nfCommon, nfClient, nfCanvasUtils, nfProcessGroup, nfGraph) {
+ 'use strict';
+
+ /**
+ * Reset the dialog.
+ */
+ var resetDialog = function () {
+ $('#flow-version-registry-combo').combo('destroy').hide();
+ $('#flow-version-bucket-combo').combo('destroy').hide();
+
+ $('#flow-version-registry').text('').hide();
+ $('#flow-version-bucket').text('').hide();
+
+ $('#flow-version-name').val('');
+ $('#flow-version-description').val('');
+ $('#flow-version-change-comments').val('');
+
+ $('#flow-version-process-group-id').removeData('versionControlInformation').removeData('revision').text('');
+ };
+
+ /**
+ * Loads the buckets for the specified registryIdentifier for the current user.
+ *
+ * @param registryIdentifier
+ * @returns {*}
+ */
+ var loadBuckets = function (registryIdentifier) {
+ return $.ajax({
+ type: 'GET',
+ url: '../nifi-api/flow/registries/' + encodeURIComponent(registryIdentifier) + '/buckets',
+ dataType: 'json'
+ }).done(function (response) {
+ var buckets = [];
+
+ if (nfCommon.isDefinedAndNotNull(response.buckets) && response.buckets.length > 0) {
+ response.buckets.sort(function (a, b) {
+ return a.bucket.name > b.bucket.name;
+ });
+
+ $.each(response.buckets, function (_, bucketEntity) {
+ var bucket = bucketEntity.bucket;
+ buckets.push({
+ text: bucket.name,
+ value: bucket.id,
+ description: nfCommon.escapeHtml(bucket.description)
+ });
+ });
+ } else {
+ buckets.push({
+ text: 'No available buckets',
+ value: null,
+ optionClass: 'unset',
+ disabled: true
+ });
+ }
+
+ // load the buckets
+ $('#flow-version-bucket-combo').combo('destroy').combo({
+ options: buckets,
+ select: selectBucket
+ });
+ }).fail(function () {
+ $('#save-flow-version-dialog').modal('refreshButtons');
+ }).fail(nfErrorHandler.handleAjaxError);
+ };
+
+ /**
+ * Select handler for the registries combo.
+ *
+ * @param selectedOption
+ */
+ var selectRegistry = function (selectedOption) {
+ if (selectedOption.disabled === true) {
+ $('#flow-version-bucket-combo').combo('destroy').combo({
+ options: [{
+ text: 'No available buckets',
+ value: null,
+ optionClass: 'unset',
+ disabled: true
+ }]
+ });
+
+ $('#save-flow-version-dialog').modal('refreshButtons');
+ } else {
+ loadBuckets(selectedOption.value);
+ }
+ };
+
+ /**
+ * Select handler for the buckets combo.
+ *
+ * @param selectedOption
+ */
+ var selectBucket = function (selectedOption) {
+ $('#save-flow-version-dialog').modal('refreshButtons');
+ };
+
+ /**
+ * Saves a flow version.
+ *
+ * @returns {*}
+ */
+ var saveFlowVersion = function () {
+ var processGroupId = $('#flow-version-process-group-id').text();
+ var processGroupRevision = $('#flow-version-process-group-id').data('revision');
+
+ var saveFlowVersionRequest = {
+ processGroupRevision: nfClient.getRevision({
+ revision: {
+ version: processGroupRevision.version
+ }
+ })
+ };
+
+ var versionControlInformation = $('#flow-version-process-group-id').data('versionControlInformation');
+ if (nfCommon.isDefinedAndNotNull(versionControlInformation)) {
+ saveFlowVersionRequest['versionedFlow'] = {
+ registryId: versionControlInformation.registryId,
+ bucketId: versionControlInformation.bucketId,
+ flowId: versionControlInformation.flowId,
+ flowName: $('#flow-version-name').val(),
+ description: $('#flow-version-description').val(),
+ comments: $('#flow-version-change-comments').val()
+ }
+ } else {
+ var selectedRegistry = $('#flow-version-registry-combo').combo('getSelectedOption');
+ var selectedBucket = $('#flow-version-bucket-combo').combo('getSelectedOption');
+
+ saveFlowVersionRequest['versionedFlow'] = {
+ registryId: selectedRegistry.value,
+ bucketId: selectedBucket.value,
+ flowName: $('#flow-version-name').val(),
+ description: $('#flow-version-description').val(),
+ comments: $('#flow-version-change-comments').val()
+ }
+ }
+
+ return $.ajax({
+ type: 'POST',
+ data: JSON.stringify(saveFlowVersionRequest),
+ url: '../nifi-api/versions/process-groups/' + encodeURIComponent(processGroupId),
+ dataType: 'json',
+ contentType: 'application/json'
+ }).fail(nfErrorHandler.handleAjaxError);
+ };
+
+ return {
+ init: function () {
+ // initialize the flow version dialog
+ $('#save-flow-version-dialog').modal({
+ scrollableContentStyle: 'scrollable',
+ headerText: 'Save Flow Version',
+ buttons: [{
+ buttonText: 'Save',
+ color: {
+ base: '#728E9B',
+ hover: '#004849',
+ text: '#ffffff'
+ },
+ disabled: function () {
+ if ($('#flow-version-registry-combo').is(':visible')) {
+ var selectedRegistry = $('#flow-version-registry-combo').combo('getSelectedOption');
+ var selectedBucket = $('#flow-version-bucket-combo').combo('getSelectedOption');
+
+ if (nfCommon.isDefinedAndNotNull(selectedRegistry) && nfCommon.isDefinedAndNotNull(selectedBucket)) {
+ return selectedRegistry.disabled === true || selectedBucket.disabled === true;
+ } else {
+ return true;
+ }
+ } else {
+ return false;
+ }
+ },
+ handler: {
+ click: function () {
+ var processGroupId = $('#flow-version-process-group-id').text();
+
+ saveFlowVersion().done(function (response) {
+ // refresh either selected PG or bread crumb to reflect connected/tracking status
+ if (nfCanvasUtils.getGroupId() === processGroupId) {
+ nfNgBridge.injector.get('breadcrumbsCtrl').updateVersionControlInformation(processGroupId, response.versionControlInformation);
+ nfNgBridge.digest();
+ } else {
+ nfProcessGroup.reload(processGroupId);
+ }
+
+ // close the dialog
+ $('#save-flow-version-dialog').modal('hide');
+ });
+ }
+ }
+ }, {
+ buttonText: 'Cancel',
+ color: {
+ base: '#E3E8EB',
+ hover: '#C7D2D7',
+ text: '#004849'
+ },
+ handler: {
+ click: function () {
+ $(this).modal('hide');
+ }
+ }
+ }],
+ handler: {
+ close: function () {
+ resetDialog();
+ }
+ }
+ });
+ },
+
+ /**
+ * Shows the flow version dialog.
+ *
+ * @param processGroupId
+ */
+ showFlowVersionDialog: function (processGroupId) {
+ return $.Deferred(function (deferred) {
+ $.ajax({
+ type: 'GET',
+ url: '../nifi-api/versions/process-groups/' + encodeURIComponent(processGroupId),
+ dataType: 'json'
+ }).done(function (response) {
+ // record the revision
+ $('#flow-version-process-group-id').data('revision', response.processGroupRevision).text(processGroupId);
+
+ if (nfCommon.isDefinedAndNotNull(response.versionControlInformation)) {
+ var versionControlInformation = response.versionControlInformation;
+
+ // update the registry and bucket visibility
+ $('#flow-version-registry').text(versionControlInformation.registryId).show();
+ $('#flow-version-bucket').text(versionControlInformation.bucketId).show();
+
+ $('#flow-version-name').val('');
+ $('#flow-version-description').val('');
+
+ // record the versionControlInformation
+ $('#flow-version-process-group-id').data('versionControlInformation', versionControlInformation)
+
+ deferred.resolve();
+ } else {
+ // update the registry and bucket visibility
+ $('#flow-version-registry-combo').show();
+ $('#flow-version-bucket-combo').show();
+
+ $.ajax({
+ type: 'GET',
+ url: '../nifi-api/flow/registries',
+ dataType: 'json'
+ }).done(function (registriesResponse) {
+ var registries = [];
+
+ if (nfCommon.isDefinedAndNotNull(registriesResponse.registries) && registriesResponse.registries.length > 0) {
+ registriesResponse.registries.sort(function (a, b) {
+ return a.component.name > b.component.name;
+ });
+
+ $.each(registriesResponse.registries, function (_, registryEntity) {
+ var registry = registryEntity.component;
+ registries.push({
+ text: registry.name,
+ value: registry.id,
+ description: nfCommon.escapeHtml(registry.description)
+ });
+ });
+ } else {
+ registries.push({
+ text: 'No available registries',
+ value: null,
+ optionClass: 'unset',
+ disabled: true
+ });
+ }
+
+ // load the registries
+ $('#flow-version-registry-combo').combo({
+ options: registries,
+ select: selectRegistry
+ });
+
+ deferred.resolve();
+ }).fail(function () {
+ deferred.reject();
+ }).fail(nfErrorHandler.handleAjaxError);
+ }
+ }).fail(nfErrorHandler.handleAjaxError);
+ }).done(function () {
+ $('#save-flow-version-dialog').modal('show');
+ }).fail(function () {
+ $('#save-flow-version-dialog').modal('refreshButtons');
+ }).promise();
+ },
+
+ /**
+ * Reverts changes for the specified Process Group.
+ *
+ * @param processGroupId
+ */
+ revertFlowChanges: function (processGroupId) {
+ // prompt the user before reverting
+ nfDialog.showYesNoDialog({
+ headerText: 'Revert Changes',
+ dialogContent: 'Are you sure you want to revert changes? All flow configuration changes will be reverted to the last version.',
+ noText: 'Cancel',
+ yesText: 'Revert',
+ yesHandler: function () {
+ $.ajax({
+ type: 'GET',
+ url: '../nifi-api/versions/process-groups/' + encodeURIComponent(processGroupId),
+ dataType: 'json'
+ }).done(function (response) {
+ if (nfCommon.isDefinedAndNotNull(response.versionControlInformation)) {
+ var revertFlowVersionRequest = {
+ processGroupRevision: nfClient.getRevision({
+ revision: {
+ version: response.processGroupRevision.version
+ }
+ }),
+ versionControlInformation: response.versionControlInformation
+ };
+
+ $.ajax({
+ type: 'POST',
+ data: JSON.stringify(revertFlowVersionRequest),
+ url: '../nifi-api/versions/revert-requests/process-groups/' + encodeURIComponent(processGroupId),
+ dataType: 'json',
+ contentType: 'application/json'
+ }).done(function (response) {
+ // TODO update multi step to show user the ramifications of reverting for confirmation
+
+ if (nfCanvasUtils.getGroupId() === processGroupId) {
+ // if reverting current PG... reload/refresh this group/canvas
+ // TODO consider implementing this differently
+ $.ajax({
+ type: 'GET',
+ url: '../nifi-api/flow/process-groups/' + encodeURIComponent(processGroupId),
+ dataType: 'json'
+ }).done(function (response) {
+ nfGraph.set(response.processGroupFlow.flow);
+ }).fail(nfErrorHandler.handleAjaxError);
+ } else {
+ // if reverting selected PG... reload selected PG to update counts, etc
+ nfProcessGroup.reload(processGroupId);
+ }
+
+ nfDialog.showOkDialog({
+ headerText: 'Revert Changes',
+ dialogContent: 'This Process Group has been reverted.'
+ });
+ }).fail(nfErrorHandler.handleAjaxError);
+ } else {
+ nfDialog.showOkDialog({
+ headerText: 'Revert Changes',
+ dialogContent: 'This Process Group is not currently under version control.'
+ });
+ }
+ }).fail(nfErrorHandler.handleAjaxError);
+ }
+ });
+ },
+
+ /**
+ * Disconnects the specified Process Group from flow versioning.
+ *
+ * @param processGroupId
+ */
+ disconnectFlowVersioning: function (processGroupId) {
+ // prompt the user before disconnecting
+ nfDialog.showYesNoDialog({
+ headerText: 'Disconnect',
+ dialogContent: 'Are you sure you want to disconnect?',
+ noText: 'Cancel',
+ yesText: 'Disconnect',
+ yesHandler: function () {
+ $.ajax({
+ type: 'GET',
+ url: '../nifi-api/versions/process-groups/' + encodeURIComponent(processGroupId),
+ dataType: 'json'
+ }).done(function (response) {
+ if (nfCommon.isDefinedAndNotNull(response.versionControlInformation)) {
+ var revision = nfClient.getRevision({
+ revision: {
+ version: response.processGroupRevision.version
+ }
+ });
+
+ $.ajax({
+ type: 'DELETE',
+ url: '../nifi-api/versions/process-groups/' + encodeURIComponent(processGroupId) + '?' + $.param(revision),
+ dataType: 'json',
+ contentType: 'application/json'
+ }).done(function (response) {
+ // refresh either selected PG or bread crumb to reflect disconnected status
+ if (nfCanvasUtils.getGroupId() === processGroupId) {
+ nfNgBridge.injector.get('breadcrumbsCtrl').updateVersionControlInformation(processGroupId, undefined);
+ nfNgBridge.digest();
+ } else {
+ nfProcessGroup.reload(processGroupId);
+ }
+
+ nfDialog.showOkDialog({
+ headerText: 'Disconnect',
+ dialogContent: 'This Process Group has been disconnected.'
+ });
+ }).fail(nfErrorHandler.handleAjaxError);
+ } else {
+ nfDialog.showOkDialog({
+ headerText: 'Disconnect',
+ dialogContent: 'This Process Group is not currently under version control.'
+ })
+ }
+ }).fail(nfErrorHandler.handleAjaxError);
+ }
+ });
+ }
+ };
+}));
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group-configuration.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group-configuration.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group-configuration.js
index 498fbd7..58402df 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group-configuration.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group-configuration.js
@@ -215,7 +215,7 @@
$('#process-group-configuration').data('process-group', {
'permissions': {
canRead: false,
- canWrite: nfCanvasUtils.canWrite()
+ canWrite: nfCanvasUtils.canWriteCurrentGroup()
}
});
} else {
http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group.js
index 13bbc70..17bb069 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-process-group.js
@@ -180,6 +180,15 @@
'class': 'process-group-name'
});
+ // process group name
+ processGroup.append('text')
+ .attr({
+ 'x': 3,
+ 'y': 17,
+ 'class': 'version-control'
+ })
+ .text('\uf00c');
+
// always support selecting and navigation
processGroup.on('dblclick', function (d) {
// enter this group on double click
@@ -868,12 +877,18 @@
}).append('title').text(function (d) {
return d.component.name;
});
+
+ // update version control information
+ processGroup.select('text.version-control').style('visibility', nfCommon.isDefinedAndNotNull(processGroupData.component.versionControlInformation) ? 'visible' : 'hidden');
} else {
// clear the process group comments
details.select('text.process-group-comments').text(null);
// clear the process group name
processGroup.select('text.process-group-name').text(null);
+
+ // update version control information
+ processGroup.select('text.version-control').style('visibility', false);
}
// populate the stats
http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/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 4da6fc6..0e5a2d7 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
@@ -81,7 +81,9 @@
controllerConfig: '../nifi-api/controller/config',
reportingTaskTypes: '../nifi-api/flow/reporting-task-types',
createReportingTask: '../nifi-api/controller/reporting-tasks',
- reportingTasks: '../nifi-api/flow/reporting-tasks'
+ reportingTasks: '../nifi-api/flow/reporting-tasks',
+ createRegistry: '../nifi-api/controller/registries',
+ registries: '../nifi-api/flow/registries'
}
};
@@ -465,6 +467,94 @@
};
/**
+ * Adds the specified entity.
+ */
+ var addRegistry = function () {
+ var registryEntity = {
+ 'revision': nfClient.getRevision({
+ 'revision': {
+ 'version': 0
+ }
+ }),
+ 'component': {
+ 'name': $('#registry-name').val(),
+ 'uri': $('#registry-location').val(),
+ 'description': $('#registry-description').val()
+ }
+ };
+
+ // add the new registry
+ var addRegistry = $.ajax({
+ type: 'POST',
+ url: config.urls.createRegistry,
+ data: JSON.stringify(registryEntity),
+ dataType: 'json',
+ contentType: 'application/json'
+ }).done(function (registryEntity) {
+ // add the item
+ var registriesGrid = $('#registries-table').data('gridInstance');
+ var registriesData = registriesGrid.getData();
+ registriesData.addItem($.extend({
+ type: 'Registry'
+ }, registryEntity));
+
+ // resort
+ registriesData.reSort();
+ registriesGrid.invalidate();
+
+ // select the new reporting task
+ var row = registriesData.getRowById(registryEntity.id);
+ nfFilteredDialogCommon.choseRow(registriesGrid, row);
+ registriesGrid.scrollRowIntoView(row);
+ }).fail(nfErrorHandler.handleAjaxError);
+
+ // hide the dialog
+ $('#registry-configuration-dialog').modal('hide');
+
+ return addRegistry;
+ };
+
+ /**
+ * Updates the registry with the specified id.
+ *
+ * @param registryId
+ */
+ var updateRegistry = function (registryId) {
+ var registriesGrid = $('#registries-table').data('gridInstance');
+ var registriesData = registriesGrid.getData();
+
+ var registryEntity = registriesData.getItemById(registryId);
+ var requestRegistryEntity = {
+ 'revision': nfClient.getRevision(registryEntity),
+ 'component': {
+ 'id': registryId,
+ 'name': $('#registry-name').val(),
+ 'uri': $('#registry-location').val(),
+ 'description': $('#registry-description').val()
+ }
+ };
+
+ // add the new reporting task
+ var updateRegistry = $.ajax({
+ type: 'PUT',
+ url: registryEntity.uri,
+ data: JSON.stringify(requestRegistryEntity),
+ dataType: 'json',
+ contentType: 'application/json'
+ }).done(function (registryEntity) {
+ // add the item
+ registriesData.updateItem(registryId, $.extend({
+ type: 'Registry'
+ }, registryEntity));
+ }).fail(nfErrorHandler.handleAjaxError);
+
+ // hide the dialog
+ $('#registry-configuration-dialog').modal('hide');
+
+ return updateRegistry;
+ };
+
+ /**
* Initializes the new reporting task dialog.
*/
var initNewReportingTaskDialog = function () {
@@ -783,6 +873,20 @@
}
}
});
+
+ // initialize the registry configuration dialog
+ $('#registry-configuration-dialog').modal({
+ scrollableContentStyle: 'scrollable',
+ headerText: 'Add Registry',
+ handler: {
+ close: function () {
+ $('#registry-id').text('');
+ $('#registry-name').val('');
+ $('#registry-location').val('');
+ $('#registry-description').val('');
+ }
+ }
+ });
};
/**
@@ -1090,6 +1194,228 @@
});
};
+ var initRegistriesTable = function () {
+
+ var locationFormatter = function (row, cell, value, columnDef, dataContext) {
+ if (!dataContext.permissions.canRead) {
+ return '<span class="blank">' + nfCommon.escapeHtml(dataContext.id) + '</span>';
+ }
+
+ return nfCommon.escapeHtml(dataContext.component.uri);
+ };
+
+ var descriptionFormatter = function (row, cell, value, columnDef, dataContext) {
+ if (!dataContext.permissions.canRead) {
+ return '<span class="blank">' + nfCommon.escapeHtml(dataContext.id) + '</span>';
+ }
+
+ return nfCommon.escapeHtml(dataContext.component.description);
+ };
+
+ var registriesActionFormatter = function (row, cell, value, columnDef, dataContext) {
+ var markup = '';
+
+ if (nfCommon.canModifyController()) {
+ // edit registry
+ markup += '<div title="Edit" class="pointer edit-registry fa fa-pencil" style="margin-top: 2px; margin-right: 3px;" ></div>';
+
+ // remove registry
+ markup += '<div title="Remove" class="pointer remove-registry fa fa-trash" style="margin-top: 2px; margin-right: 3px;" ></div>';
+ }
+
+ return markup;
+ };
+
+ // define the column model for the reporting tasks table
+ var registriesColumnModel = [
+ {
+ id: 'name',
+ name: 'Name',
+ field: 'name',
+ formatter: nameFormatter,
+ sortable: true,
+ resizable: true
+ },
+ {
+ id: 'uri',
+ name: 'Location',
+ field: 'uri',
+ formatter: locationFormatter,
+ sortable: true,
+ resizable: true
+ },
+ {
+ id: 'description',
+ name: 'Description',
+ field: 'description',
+ formatter: descriptionFormatter,
+ sortable: true,
+ resizable: true
+ }
+ ];
+
+ // action column should always be last
+ registriesColumnModel.push({
+ id: 'actions',
+ name: ' ',
+ resizable: false,
+ formatter: registriesActionFormatter,
+ sortable: false,
+ width: 90,
+ maxWidth: 90
+ });
+
+ // initialize the dataview
+ var registriesData = new Slick.Data.DataView({
+ inlineFilters: false
+ });
+ registriesData.setItems([]);
+
+ // initialize the sort
+ sort({
+ columnId: 'name',
+ sortAsc: true
+ }, registriesData);
+
+ // initialize the grid
+ var registriesGrid = new Slick.Grid('#registries-table', registriesData, registriesColumnModel, gridOptions);
+ registriesGrid.setSelectionModel(new Slick.RowSelectionModel());
+ registriesGrid.registerPlugin(new Slick.AutoTooltips());
+ registriesGrid.setSortColumn('name', true);
+ registriesGrid.onSort.subscribe(function (e, args) {
+ sort({
+ columnId: args.sortCol.id,
+ sortAsc: args.sortAsc
+ }, registriesData);
+ });
+
+ // configure a click listener
+ registriesGrid.onClick.subscribe(function (e, args) {
+ var target = $(e.target);
+
+ // get the service at this row
+ var registryEntity = registriesData.getItem(args.row);
+
+ // determine the desired action
+ if (registriesGrid.getColumns()[args.cell].id === 'actions') {
+ if (target.hasClass('edit-registry')) {
+ editRegistry(registryEntity);
+ } else if (target.hasClass('remove-registry')) {
+ promptToRemoveRegistry(registryEntity);
+ }
+ } else if (registriesGrid.getColumns()[args.cell].id === 'moreDetails') {
+ // if (target.hasClass('view-reporting-task')) {
+ // nfReportingTask.showDetails(reportingTaskEntity);
+ // } else if (target.hasClass('reporting-task-usage')) {
+ // // close the settings dialog
+ // $('#shell-close-button').click();
+ //
+ // // open the documentation for this reporting task
+ // nfShell.showPage('../nifi-docs/documentation?' + $.param({
+ // select: reportingTaskEntity.component.type,
+ // group: reportingTaskEntity.component.bundle.group,
+ // artifact: reportingTaskEntity.component.bundle.artifact,
+ // version: reportingTaskEntity.component.bundle.version
+ // })).done(function () {
+ // nfSettings.showSettings();
+ // });
+ // }
+ }
+ });
+
+ // wire up the dataview to the grid
+ registriesData.onRowCountChanged.subscribe(function (e, args) {
+ registriesGrid.updateRowCount();
+ registriesGrid.render();
+ });
+ registriesData.onRowsChanged.subscribe(function (e, args) {
+ registriesGrid.invalidateRows(args.rows);
+ registriesGrid.render();
+ });
+ registriesData.syncGridSelection(registriesGrid, true);
+
+ // hold onto an instance of the grid
+ $('#registries-table').data('gridInstance', registriesGrid);
+ };
+
+ /**
+ * Edits the specified registry entity.
+ *
+ * @param registryEntity
+ */
+ var editRegistry = function (registryEntity) {
+ // populate the dialog
+ $('#registry-id').text(registryEntity.id);
+ $('#registry-name').val(registryEntity.component.name);
+ $('#registry-location').val(registryEntity.component.uri);
+ $('#registry-description').val(registryEntity.component.description);
+
+ // show the dialog
+ $('#registry-configuration-dialog').modal('setButtonModel', [{
+ buttonText: 'Update',
+ color: {
+ base: '#728E9B',
+ hover: '#004849',
+ text: '#ffffff'
+ },
+ handler: {
+ click: function () {
+ updateRegistry(registryEntity.id);
+ }
+ }
+ }, {
+ buttonText: 'Cancel',
+ color: {
+ base: '#E3E8EB',
+ hover: '#C7D2D7',
+ text: '#004849'
+ },
+ handler: {
+ click: function () {
+ $(this).modal('hide');
+ }
+ }
+ }]).modal('show');
+ };
+
+ /**
+ * Prompts the user before attempting to delete the specified registry.
+ *
+ * @param {object} registryEntity
+ */
+ var promptToRemoveRegistry = function (registryEntity) {
+ // prompt for deletion
+ nfDialog.showYesNoDialog({
+ headerText: 'Delete Registry',
+ dialogContent: 'Delete registry \'' + nfCommon.escapeHtml(registryEntity.component.name) + '\'?',
+ yesHandler: function () {
+ removeRegistry(registryEntity);
+ }
+ });
+ };
+
+ /**
+ * Deletes the specified registry.
+ *
+ * @param {object} registryEntity
+ */
+ var removeRegistry = function (registryEntity) {
+ var revision = nfClient.getRevision(registryEntity);
+ $.ajax({
+ type: 'DELETE',
+ url: registryEntity.uri + '?' + $.param({
+ version: revision.version,
+ clientId: revision.clientId
+ }),
+ dataType: 'json'
+ }).done(function (response) {
+ // remove the task
+ var registryGrid = $('#registries-table').data('gridInstance');
+ var registryData = registryGrid.getData();
+ registryData.deleteItem(registryEntity.id);
+ }).fail(nfErrorHandler.handleAjaxError);
+ };
+
/**
* Loads the settings.
*/
@@ -1158,6 +1484,9 @@
// load the reporting tasks
var reportingTasks = loadReportingTasks();
+ // load the registries
+ var registries = loadRegistries();
+
// return a deferred for all parts of the settings
return $.when(settings, controllerServicesXhr, reportingTasks).done(function (settingsResult, controllerServicesResult) {
var controllerServicesResponse = controllerServicesResult[0];
@@ -1199,6 +1528,32 @@
};
/**
+ * Loads the registries.
+ */
+ var loadRegistries = function () {
+ return $.ajax({
+ type: 'GET',
+ url: config.urls.registries,
+ dataType: 'json'
+ }).done(function (response) {
+ var registries = [];
+ $.each(response.registries, function (_, registryEntity) {
+ registries.push($.extend({
+ type: 'Registry'
+ }, registryEntity));
+ });
+
+ var registriesGrid = $('#registries-table').data('gridInstance');
+ var registriesData = registriesGrid.getData();
+
+ // update the registries
+ registriesData.setItems(registries);
+ registriesData.reSort();
+ registriesGrid.invalidate();
+ });
+ };
+
+ /**
* Shows the process group configuration.
*/
var showSettings = function () {
@@ -1241,6 +1596,9 @@
}, {
name: 'Reporting Tasks',
tabContentId: 'reporting-tasks-tab-content'
+ }, {
+ name: 'Registries',
+ tabContentId: 'registries-tab-content'
}],
select: function () {
var tab = $(this).text();
@@ -1267,6 +1625,9 @@
} else if (tab === 'Reporting Tasks') {
$('#settings-save').hide();
return 'Create a new reporting task';
+ } else if (tab === 'Registries') {
+ $('#settings-save').hide();
+ return 'Register a new registry';
}
});
} else {
@@ -1276,7 +1637,7 @@
if (tab === 'Reporting Task Controller Services') {
$('#controller-cs-availability').show();
- } else if (tab === 'Reporting Tasks') {
+ } else if (tab === 'Reporting Tasks' || tab === 'Registries') {
$('#controller-cs-availability').hide();
}
@@ -1315,6 +1676,32 @@
// set the initial focus
$('#reporting-task-type-filter').focus();
+ } else if (selectedTab === 'Registries') {
+ $('#registry-configuration-dialog').modal('setButtonModel', [{
+ buttonText: 'Add',
+ color: {
+ base: '#728E9B',
+ hover: '#004849',
+ text: '#ffffff'
+ },
+ handler: {
+ click: function () {
+ addRegistry();
+ }
+ }
+ }, {
+ buttonText: 'Cancel',
+ color: {
+ base: '#E3E8EB',
+ hover: '#C7D2D7',
+ text: '#004849'
+ },
+ handler: {
+ click: function () {
+ $(this).modal('hide');
+ }
+ }
+ }]).modal('show');
}
});
@@ -1322,6 +1709,7 @@
initGeneral();
nfControllerServices.init(getControllerServicesTable(), nfSettings.showSettings);
initReportingTasks();
+ initRegistriesTable();
},
/**
http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/views/nf-ng-breadcrumbs-directive-view.html
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/views/nf-ng-breadcrumbs-directive-view.html b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/views/nf-ng-breadcrumbs-directive-view.html
index 10d36f1..a8b8579 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/views/nf-ng-breadcrumbs-directive-view.html
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/views/nf-ng-breadcrumbs-directive-view.html
@@ -22,6 +22,7 @@ limitations under the License.
<span ng-if="separatorFunc(crumb.parentBreadcrumb)" style="margin: 0 12px;">
»
</span>
+ <span ng-if="separatorFunc(crumb.breadcrumb.versionControlInformation)" class="breadcrumb-version-control fa fa-check" style="margin: 0 6px;"></span>
<span class="link"
ng-class="(highlightCrumbId === crumb.id) ? 'link-bold' : ''"
ng-click="clickFunc(crumb.id)">