| /* |
| * 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.Storage', |
| 'nf.Common', |
| 'nf.Client', |
| 'nf.CanvasUtils', |
| 'nf.ProcessGroup', |
| 'nf.ProcessGroupConfiguration', |
| 'nf.Graph', |
| 'nf.Birdseye'], |
| function ($, nfNgBridge, nfErrorHandler, nfDialog, nfStorage, nfCommon, nfClient, nfCanvasUtils, nfProcessGroup, nfProcessGroupConfiguration, nfGraph, nfBirdseye) { |
| return (nf.FlowVersion = factory($, nfNgBridge, nfErrorHandler, nfDialog, nfStorage, nfCommon, nfClient, nfCanvasUtils, nfProcessGroup, nfProcessGroupConfiguration, nfGraph, nfBirdseye)); |
| }); |
| } 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.Storage'), |
| require('nf.Common'), |
| require('nf.Client'), |
| require('nf.CanvasUtils'), |
| require('nf.ProcessGroup'), |
| require('nf.ProcessGroupConfiguration'), |
| require('nf.Graph'), |
| require('nf.Birdseye'))); |
| } else { |
| nf.FlowVersion = factory(root.$, |
| root.nf.ng.Bridge, |
| root.nf.ErrorHandler, |
| root.nf.Dialog, |
| root.nf.Storage, |
| root.nf.Common, |
| root.nf.Client, |
| root.nf.CanvasUtils, |
| root.nf.ProcessGroup, |
| root.nf.ProcessGroupConfiguration, |
| root.nf.Graph, |
| root.nf.Birdseye); |
| } |
| }(this, function ($, nfNgBridge, nfErrorHandler, nfDialog, nfStorage, nfCommon, nfClient, nfCanvasUtils, nfProcessGroup, nfProcessGroupConfiguration, nfGraph, nfBirdseye) { |
| 'use strict'; |
| |
| var serverTimeOffset = null; |
| |
| var gridOptions = { |
| forceFitColumns: true, |
| enableTextSelectionOnCells: true, |
| enableCellNavigation: true, |
| enableColumnReorder: false, |
| autoEdit: false, |
| multiSelect: false, |
| rowHeight: 24 |
| }; |
| |
| /** |
| * Reset the save flow version dialog. |
| */ |
| var resetSaveFlowVersionDialog = function () { |
| $('#save-flow-version-registry-combo').combo('destroy').hide(); |
| $('#save-flow-version-bucket-combo').combo('destroy').hide(); |
| |
| $('#save-flow-version-label').text(''); |
| |
| $('#save-flow-version-registry').text('').hide(); |
| $('#save-flow-version-bucket').text('').hide(); |
| |
| $('#save-flow-version-name').text('').hide(); |
| $('#save-flow-version-description').removeClass('unset blank').text('').hide(); |
| |
| $('#save-flow-version-name-field').val('').hide(); |
| $('#save-flow-version-description-field').val('').hide(); |
| $('#save-flow-version-change-comments').val(''); |
| |
| $('#save-flow-version-process-group-id').removeData('versionControlInformation').removeData('revision').text(''); |
| $('#save-flow-version-action').text(''); |
| }; |
| |
| /** |
| * Reset the revert local changes dialog. |
| */ |
| var resetRevertLocalChangesDialog = function () { |
| $('#revert-local-changes-process-group-id').text(''); |
| |
| clearLocalChangesGrid($('#revert-local-changes-table'), $('#revert-local-changes-filter'), $('#displayed-revert-local-changes-entries'), $('#total-revert-local-changes-entries')); |
| }; |
| |
| /** |
| * Reset the show local changes dialog. |
| */ |
| var resetShowLocalChangesDialog = function () { |
| clearLocalChangesGrid($('#show-local-changes-table'), $('#show-local-changes-filter'), $('#displayed-show-local-changes-entries'), $('#total-show-local-changes-entries')); |
| }; |
| |
| /** |
| * Clears the local changes grid. |
| */ |
| var clearLocalChangesGrid = function (localChangesTable, filterInput, displayedLabel, totalLabel) { |
| var localChangesGrid = localChangesTable.data('gridInstance'); |
| if (nfCommon.isDefinedAndNotNull(localChangesGrid)) { |
| localChangesGrid.setSelectedRows([]); |
| localChangesGrid.resetActiveCell(); |
| |
| var localChangesData = localChangesGrid.getData(); |
| localChangesData.setItems([]); |
| localChangesData.setFilterArgs({ |
| searchString: '' |
| }); |
| } |
| |
| filterInput.val(''); |
| |
| displayedLabel.text('0'); |
| totalLabel.text('0'); |
| }; |
| |
| /** |
| * Clears the version grid |
| */ |
| var clearFlowVersionsGrid = function () { |
| var importFlowVersionGrid = $('#import-flow-version-table').data('gridInstance'); |
| if (nfCommon.isDefinedAndNotNull(importFlowVersionGrid)) { |
| importFlowVersionGrid.setSelectedRows([]); |
| importFlowVersionGrid.resetActiveCell(); |
| |
| var importFlowVersionData = importFlowVersionGrid.getData(); |
| importFlowVersionData.setItems([]); |
| } |
| }; |
| |
| /** |
| * Reset the import flow version dialog. |
| */ |
| var resetImportFlowVersionDialog = function () { |
| $('#import-flow-version-dialog').removeData('pt'); |
| |
| $('#import-flow-version-registry-combo').combo('destroy').hide(); |
| $('#import-flow-version-bucket-combo').combo('destroy').hide(); |
| $('#import-flow-version-name-combo').combo('destroy').hide(); |
| |
| $('#import-flow-version-registry').text('').hide(); |
| $('#import-flow-version-bucket').text('').hide(); |
| $('#import-flow-version-name').text('').hide(); |
| |
| clearFlowVersionsGrid(); |
| |
| $('#import-flow-version-process-group-id').removeData('versionControlInformation').removeData('revision').text(''); |
| |
| $('#import-flow-version-container').hide(); |
| $('#import-flow-version-label').text(''); |
| }; |
| |
| /** |
| * Loads the registries into the specified registry combo. |
| * |
| * @param dialog |
| * @param registryCombo |
| * @param bucketCombo |
| * @param flowCombo |
| * @param selectBucket |
| * @param bucketCheck |
| * @returns {deferred} |
| */ |
| var loadRegistries = function (dialog, registryCombo, bucketCombo, flowCombo, selectBucket, bucketCheck) { |
| return $.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.registry.name > b.registry.name; |
| }); |
| |
| $.each(registriesResponse.registries, function (_, registryEntity) { |
| var registry = registryEntity.registry; |
| 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 |
| registryCombo.combo({ |
| options: registries, |
| select: function (selectedOption) { |
| selectRegistry(dialog, selectedOption, bucketCombo, flowCombo, selectBucket, bucketCheck) |
| } |
| }); |
| }).fail(nfErrorHandler.handleAjaxError); |
| }; |
| |
| /** |
| * Loads the buckets for the specified registryIdentifier for the current user. |
| * |
| * @param registryIdentifier |
| * @param bucketCombo |
| * @param flowCombo |
| * @param selectBucket |
| * @param bucketCheck |
| * @returns {*} |
| */ |
| var loadBuckets = function (registryIdentifier, bucketCombo, flowCombo, selectBucket, bucketCheck) { |
| 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) { |
| if (a.permissions.canRead === false && b.permissions.canRead === false) { |
| return 0; |
| } else if (a.permissions.canRead === false) { |
| return -1; |
| } else if (b.permissions.canRead === false) { |
| return 1; |
| } |
| |
| return a.bucket.name > b.bucket.name; |
| }); |
| |
| $.each(response.buckets, function (_, bucketEntity) { |
| if (bucketEntity.permissions.canRead === true) { |
| var bucket = bucketEntity.bucket; |
| |
| if (bucketCheck(bucketEntity)) { |
| buckets.push({ |
| text: bucket.name, |
| value: bucket.id, |
| description: nfCommon.escapeHtml(bucket.description) |
| }); |
| } |
| } |
| }); |
| } |
| |
| if (buckets.length === 0) { |
| buckets.push({ |
| text: 'No available buckets', |
| value: null, |
| optionClass: 'unset', |
| disabled: true |
| }); |
| |
| if (nfCommon.isDefinedAndNotNull(flowCombo)) { |
| flowCombo.combo('destroy').combo({ |
| options: [{ |
| text: 'No available flows', |
| value: null, |
| optionClass: 'unset', |
| disabled: true |
| }] |
| }); |
| } |
| } |
| |
| // load the buckets |
| bucketCombo.combo('destroy').combo({ |
| options: buckets, |
| select: selectBucket |
| }); |
| }).fail(nfErrorHandler.handleAjaxError); |
| }; |
| |
| /** |
| * Select handler for the registries combo. |
| * |
| * @param dialog |
| * @param selectedOption |
| * @param bucketCombo |
| * @param flowCombo |
| * @param selectBucket |
| * @param bucketCheck |
| */ |
| var selectRegistry = function (dialog, selectedOption, bucketCombo, flowCombo, selectBucket, bucketCheck) { |
| var showNoBucketsAvailable = function () { |
| bucketCombo.combo('destroy').combo({ |
| options: [{ |
| text: 'No available buckets', |
| value: null, |
| optionClass: 'unset', |
| disabled: true |
| }] |
| }); |
| |
| if (nfCommon.isDefinedAndNotNull(flowCombo)) { |
| flowCombo.combo('destroy').combo({ |
| options: [{ |
| text: 'No available flows', |
| value: null, |
| optionClass: 'unset', |
| disabled: true |
| }] |
| }); |
| } |
| |
| dialog.modal('refreshButtons'); |
| }; |
| |
| if (selectedOption.disabled === true) { |
| showNoBucketsAvailable(); |
| } else { |
| bucketCombo.combo('destroy').combo({ |
| options: [{ |
| text: 'Loading buckets...', |
| value: null, |
| optionClass: 'unset', |
| disabled: true |
| }] |
| }); |
| |
| if (nfCommon.isDefinedAndNotNull(flowCombo)) { |
| flowCombo.combo('destroy').combo({ |
| options: [{ |
| text: 'Loading flows...', |
| value: null, |
| optionClass: 'unset', |
| disabled: true |
| }] |
| }); |
| |
| clearFlowVersionsGrid(); |
| } |
| |
| loadBuckets(selectedOption.value, bucketCombo, flowCombo, selectBucket, bucketCheck).fail(function () { |
| showNoBucketsAvailable(); |
| }); |
| } |
| }; |
| |
| /** |
| * Select handler for the buckets combo. |
| * |
| * @param selectedOption |
| */ |
| var selectBucketSaveFlowVersion = function (selectedOption) { |
| $('#save-flow-version-dialog').modal('refreshButtons'); |
| }; |
| |
| /** |
| * Saves a flow version. |
| * |
| * @returns {*} |
| */ |
| var saveFlowVersion = function () { |
| var processGroupId = $('#save-flow-version-process-group-id').text(); |
| var processGroupRevision = $('#save-flow-version-process-group-id').data('revision'); |
| |
| var saveFlowVersionRequest = { |
| processGroupRevision: nfClient.getRevision({ |
| revision: { |
| version: processGroupRevision.version |
| } |
| }), |
| 'disconnectedNodeAcknowledged': nfStorage.isDisconnectionAcknowledged() |
| }; |
| |
| var versionControlInformation = $('#save-flow-version-process-group-id').data('versionControlInformation'); |
| if (nfCommon.isDefinedAndNotNull(versionControlInformation)) { |
| saveFlowVersionRequest['versionedFlow'] = { |
| registryId: versionControlInformation.registryId, |
| bucketId: versionControlInformation.bucketId, |
| flowId: versionControlInformation.flowId, |
| comments: $('#save-flow-version-change-comments').val(), |
| action: $('#save-flow-version-action').text() |
| } |
| } else { |
| var selectedRegistry = $('#save-flow-version-registry-combo').combo('getSelectedOption'); |
| var selectedBucket = $('#save-flow-version-bucket-combo').combo('getSelectedOption'); |
| |
| saveFlowVersionRequest['versionedFlow'] = { |
| registryId: selectedRegistry.value, |
| bucketId: selectedBucket.value, |
| flowName: $('#save-flow-version-name-field').val(), |
| description: $('#save-flow-version-description-field').val(), |
| comments: $('#save-flow-version-change-comments').val(), |
| action: $('#save-flow-version-action').text() |
| }; |
| } |
| |
| return $.ajax({ |
| type: 'POST', |
| data: JSON.stringify(saveFlowVersionRequest), |
| url: '../nifi-api/versions/process-groups/' + encodeURIComponent(processGroupId), |
| dataType: 'json', |
| contentType: 'application/json' |
| }).done(function (response) { |
| if ('SYNC_FAILURE' === response.versionControlInformation.state) { |
| nfDialog.showOkDialog({ |
| headerText: 'Error', |
| dialogContent: response.versionControlInformation.stateExplanation |
| }); |
| } |
| }).fail(nfErrorHandler.handleAjaxError); |
| }; |
| |
| /** |
| * Sorts the specified data using the specified sort details. |
| * |
| * @param {object} sortDetails |
| * @param {object} data |
| */ |
| var sort = function (sortDetails, data) { |
| // defines a function for sorting |
| var comparer = function (a, b) { |
| var aIsBlank = nfCommon.isBlank(a[sortDetails.columnId]); |
| var bIsBlank = nfCommon.isBlank(b[sortDetails.columnId]); |
| |
| if (aIsBlank && bIsBlank) { |
| return 0; |
| } else if (aIsBlank) { |
| return 1; |
| } else if (bIsBlank) { |
| return -1; |
| } |
| |
| return a[sortDetails.columnId] === b[sortDetails.columnId] ? 0 : a[sortDetails.columnId] > b[sortDetails.columnId] ? 1 : -1; |
| }; |
| |
| // perform the sort |
| data.sort(comparer, sortDetails.sortAsc); |
| }; |
| |
| var initImportFlowVersionTable = function () { |
| var importFlowVersionTable = $('#import-flow-version-table'); |
| |
| var valueFormatter = function (row, cell, value, columnDef, dataContext) { |
| return nfCommon.escapeHtml(value); |
| }; |
| |
| var timestampFormatter = function (row, cell, value, columnDef, dataContext) { |
| // get the current user time to properly convert the server time |
| var now = new Date(); |
| |
| // convert the user offset to millis |
| var userTimeOffset = now.getTimezoneOffset() * 60 * 1000; |
| |
| // create the proper date by adjusting by the offsets |
| var date = new Date(dataContext.timestamp + userTimeOffset + serverTimeOffset); |
| return nfCommon.formatDateTime(date); |
| }; |
| |
| // define the column model for flow versions |
| var importFlowVersionColumns = [ |
| { |
| id: 'version', |
| name: 'Version', |
| field: 'version', |
| formatter: valueFormatter, |
| sortable: true, |
| resizable: true, |
| width: 75, |
| maxWidth: 75 |
| }, |
| { |
| id: 'timestamp', |
| name: 'Created', |
| field: 'timestamp', |
| formatter: timestampFormatter, |
| sortable: true, |
| resizable: true, |
| width: 175, |
| maxWidth: 175 |
| }, |
| { |
| id: 'changeComments', |
| name: 'Comments', |
| field: 'comments', |
| sortable: true, |
| resizable: true, |
| formatter: valueFormatter |
| } |
| ]; |
| |
| // initialize the dataview |
| var importFlowVersionData = new Slick.Data.DataView({ |
| inlineFilters: false |
| }); |
| |
| // initialize the sort |
| sort({ |
| columnId: 'version', |
| sortAsc: false |
| }, importFlowVersionData); |
| |
| // initialize the grid |
| var importFlowVersionGrid = new Slick.Grid(importFlowVersionTable, importFlowVersionData, importFlowVersionColumns, gridOptions); |
| importFlowVersionGrid.setSelectionModel(new Slick.RowSelectionModel()); |
| importFlowVersionGrid.registerPlugin(new Slick.AutoTooltips()); |
| importFlowVersionGrid.setSortColumn('version', false); |
| importFlowVersionGrid.onSort.subscribe(function (e, args) { |
| sort({ |
| columnId: args.sortCol.id, |
| sortAsc: args.sortAsc |
| }, importFlowVersionData); |
| }); |
| importFlowVersionGrid.onSelectedRowsChanged.subscribe(function (e, args) { |
| $('#import-flow-version-dialog').modal('refreshButtons'); |
| }); |
| importFlowVersionGrid.onDblClick.subscribe(function (e, args) { |
| if ($('#import-flow-version-label').is(':visible')) { |
| changeFlowVersion(); |
| } else { |
| importFlowVersion().always(function () { |
| $('#import-flow-version-dialog').modal('hide'); |
| }); |
| } |
| }); |
| |
| // wire up the dataview to the grid |
| importFlowVersionData.onRowCountChanged.subscribe(function (e, args) { |
| importFlowVersionGrid.updateRowCount(); |
| importFlowVersionGrid.render(); |
| }); |
| importFlowVersionData.onRowsChanged.subscribe(function (e, args) { |
| importFlowVersionGrid.invalidateRows(args.rows); |
| importFlowVersionGrid.render(); |
| }); |
| importFlowVersionData.syncGridSelection(importFlowVersionGrid, true); |
| |
| // hold onto an instance of the grid |
| importFlowVersionTable.data('gridInstance', importFlowVersionGrid); |
| }; |
| |
| /** |
| * Initializes the specified local changes table. |
| * |
| * @param localChangesTable |
| * @param filterInput |
| * @param displayedLabel |
| * @param totalLabel |
| */ |
| var initLocalChangesTable = function (localChangesTable, filterInput, displayedLabel, totalLabel) { |
| |
| var getFilterText = function () { |
| return filterInput.val(); |
| }; |
| |
| var applyFilter = function () { |
| // get the dataview |
| var localChangesGrid = localChangesTable.data('gridInstance'); |
| |
| // ensure the grid has been initialized |
| if (nfCommon.isDefinedAndNotNull(localChangesGrid)) { |
| var localChangesData = localChangesGrid.getData(); |
| |
| // update the search criteria |
| localChangesData.setFilterArgs({ |
| searchString: getFilterText() |
| }); |
| localChangesData.refresh(); |
| } |
| }; |
| |
| var filter = function (item, args) { |
| if (args.searchString === '') { |
| return true; |
| } |
| |
| try { |
| // perform the row filtering |
| var filterExp = new RegExp(args.searchString, 'i'); |
| } catch (e) { |
| // invalid regex |
| return false; |
| } |
| |
| // determine if the item matches the filter |
| var matchesId = item['componentId'].search(filterExp) >= 0; |
| var matchesDifferenceType = item['differenceType'].search(filterExp) >= 0; |
| var matchesDifference = item['difference'].search(filterExp) >= 0; |
| |
| // conditionally consider the component name |
| var matchesComponentName = false; |
| if (nfCommon.isDefinedAndNotNull(item['componentName'])) { |
| matchesComponentName = item['componentName'].search(filterExp) >= 0; |
| } |
| |
| return matchesId || matchesComponentName || matchesDifferenceType || matchesDifference; |
| }; |
| |
| // initialize the component state filter |
| filterInput.on('keyup', function () { |
| applyFilter(); |
| }); |
| |
| var valueFormatter = function (row, cell, value, columnDef, dataContext) { |
| return nfCommon.escapeHtml(value); |
| }; |
| |
| var actionsFormatter = function (row, cell, value, columnDef, dataContext) { |
| var markup = ''; |
| |
| if (dataContext.differenceType !== 'Component Removed' && nfCommon.isDefinedAndNotNull(dataContext.processGroupId)) { |
| markup += '<div class="pointer go-to-component fa fa-long-arrow-right" title="Go To"></div>'; |
| } |
| |
| return markup; |
| }; |
| |
| // define the column model for local changes |
| var localChangesColumns = [ |
| { |
| id: 'componentName', |
| name: 'Component Name', |
| field: 'componentName', |
| formatter: valueFormatter, |
| sortable: true, |
| resizable: true |
| }, |
| { |
| id: 'differenceType', |
| name: 'Change Type', |
| field: 'differenceType', |
| formatter: valueFormatter, |
| sortable: true, |
| resizable: true |
| }, |
| { |
| id: 'difference', |
| name: 'Difference', |
| field: 'difference', |
| formatter: valueFormatter, |
| sortable: true, |
| resizable: true |
| }, |
| { |
| id: 'actions', |
| name: ' ', |
| formatter: actionsFormatter, |
| sortable: false, |
| resizable: false, |
| width: 25 |
| } |
| ]; |
| |
| // initialize the dataview |
| var localChangesData = new Slick.Data.DataView({ |
| inlineFilters: false |
| }); |
| localChangesData.setFilterArgs({ |
| searchString: getFilterText() |
| }); |
| localChangesData.setFilter(filter); |
| |
| // initialize the sort |
| sort({ |
| columnId: 'componentName', |
| sortAsc: true |
| }, localChangesData); |
| |
| // initialize the grid |
| var localChangesGrid = new Slick.Grid(localChangesTable, localChangesData, localChangesColumns, gridOptions); |
| localChangesGrid.setSelectionModel(new Slick.RowSelectionModel()); |
| localChangesGrid.registerPlugin(new Slick.AutoTooltips()); |
| localChangesGrid.setSortColumn('componentName', true); |
| localChangesGrid.onSort.subscribe(function (e, args) { |
| sort({ |
| columnId: args.sortCol.id, |
| sortAsc: args.sortAsc |
| }, localChangesData); |
| }); |
| |
| // configure a click listener |
| localChangesGrid.onClick.subscribe(function (e, args) { |
| var target = $(e.target); |
| |
| // get the node at this row |
| var componentDifference = localChangesData.getItem(args.row); |
| |
| // determine the desired action |
| if (localChangesGrid.getColumns()[args.cell].id === 'actions') { |
| if (target.hasClass('go-to-component')) { |
| if (componentDifference.componentType === 'Controller Service') { |
| nfProcessGroupConfiguration.showConfiguration(componentDifference.processGroupId).done(function () { |
| nfProcessGroupConfiguration.selectControllerService(componentDifference.componentId); |
| |
| localChangesTable.closest('.large-dialog').modal('hide'); |
| }); |
| } else { |
| nfCanvasUtils.showComponent(componentDifference.processGroupId, componentDifference.componentId).done(function () { |
| localChangesTable.closest('.large-dialog').modal('hide'); |
| }); |
| } |
| } |
| } |
| }); |
| |
| // wire up the dataview to the grid |
| localChangesData.onRowCountChanged.subscribe(function (e, args) { |
| localChangesGrid.updateRowCount(); |
| localChangesGrid.render(); |
| |
| // update the total number of displayed items |
| displayedLabel.text(nfCommon.formatInteger(args.current)); |
| }); |
| localChangesData.onRowsChanged.subscribe(function (e, args) { |
| localChangesGrid.invalidateRows(args.rows); |
| localChangesGrid.render(); |
| }); |
| localChangesData.syncGridSelection(localChangesGrid, true); |
| |
| // hold onto an instance of the grid |
| localChangesTable.data('gridInstance', localChangesGrid); |
| |
| // initialize the number of display items |
| displayedLabel.text('0'); |
| totalLabel.text('0'); |
| }; |
| |
| /** |
| * Shows the import flow version dialog. |
| */ |
| var showImportFlowVersionDialog = function () { |
| var pt = $('#new-process-group-dialog').data('pt'); |
| $('#import-flow-version-dialog').data('pt', pt); |
| |
| // update the registry and bucket visibility |
| var registryCombo = $('#import-flow-version-registry-combo').combo('destroy').combo({ |
| options: [{ |
| text: 'Loading registries...', |
| value: null, |
| optionClass: 'unset', |
| disabled: true |
| }] |
| }).show(); |
| var bucketCombo = $('#import-flow-version-bucket-combo').combo('destroy').combo({ |
| options: [{ |
| text: 'Loading buckets...', |
| value: null, |
| optionClass: 'unset', |
| disabled: true |
| }] |
| }).show(); |
| var flowCombo = $('#import-flow-version-name-combo').combo('destroy').combo({ |
| options: [{ |
| text: 'Loading flows...', |
| value: null, |
| optionClass: 'unset', |
| disabled: true |
| }] |
| }).show(); |
| |
| loadRegistries($('#import-flow-version-dialog'), registryCombo, bucketCombo, flowCombo, selectBucketImportVersion, function (bucketEntity) { |
| return true; |
| }).done(function () { |
| // show the import dialog |
| $('#import-flow-version-dialog').modal('setHeaderText', 'Import Version').modal('setButtonModel', [{ |
| buttonText: 'Import', |
| color: { |
| base: '#728E9B', |
| hover: '#004849', |
| text: '#ffffff' |
| }, |
| disabled: disableImportOrChangeButton, |
| handler: { |
| click: function () { |
| importFlowVersion().always(function () { |
| $('#import-flow-version-dialog').modal('hide'); |
| }); |
| } |
| } |
| }, { |
| buttonText: 'Cancel', |
| color: { |
| base: '#E3E8EB', |
| hover: '#C7D2D7', |
| text: '#004849' |
| }, |
| handler: { |
| click: function () { |
| $(this).modal('hide'); |
| } |
| } |
| }]).modal('show'); |
| |
| // hide the new process group dialog |
| $('#new-process-group-dialog').modal('hide'); |
| }); |
| }; |
| |
| /** |
| * Loads the flow versions for the specified registry, bucket, and flow. |
| * |
| * @param registryIdentifier |
| * @param bucketIdentifier |
| * @param flowIdentifier |
| * @returns deferred |
| */ |
| var loadFlowVersions = function (registryIdentifier, bucketIdentifier, flowIdentifier) { |
| var importFlowVersionGrid = $('#import-flow-version-table').data('gridInstance'); |
| var importFlowVersionData = importFlowVersionGrid.getData(); |
| |
| // begin the update |
| importFlowVersionData.beginUpdate(); |
| |
| // remove the current versions |
| importFlowVersionGrid.setSelectedRows([]); |
| importFlowVersionGrid.resetActiveCell(); |
| importFlowVersionData.setItems([]); |
| |
| return $.ajax({ |
| type: 'GET', |
| url: '../nifi-api/flow/registries/' + encodeURIComponent(registryIdentifier) + '/buckets/' + encodeURIComponent(bucketIdentifier) + '/flows/' + encodeURIComponent(flowIdentifier) + '/versions', |
| dataType: 'json' |
| }).done(function (response) { |
| if (nfCommon.isDefinedAndNotNull(response.versionedFlowSnapshotMetadataSet) && response.versionedFlowSnapshotMetadataSet.length > 0) { |
| $.each(response.versionedFlowSnapshotMetadataSet, function (_, entity) { |
| importFlowVersionData.addItem($.extend({ |
| id: entity.versionedFlowSnapshotMetadata.version |
| }, entity.versionedFlowSnapshotMetadata)); |
| }); |
| } else { |
| nfDialog.showOkDialog({ |
| headerText: 'Flow Versions', |
| dialogContent: 'This flow does not have any versions available.' |
| }); |
| } |
| }).fail(nfErrorHandler.handleAjaxError).always(function () { |
| // end the update |
| importFlowVersionData.endUpdate(); |
| |
| // resort |
| importFlowVersionData.reSort(); |
| importFlowVersionGrid.invalidate(); |
| }); |
| }; |
| |
| /** |
| * Loads the versioned flows from the specified registry and bucket. |
| * |
| * @param registryIdentifier |
| * @param bucketIdentifier |
| * @param selectFlow |
| * @returns deferred |
| */ |
| var loadFlows = function (registryIdentifier, bucketIdentifier, selectFlow) { |
| return $.ajax({ |
| type: 'GET', |
| url: '../nifi-api/flow/registries/' + encodeURIComponent(registryIdentifier) + '/buckets/' + encodeURIComponent(bucketIdentifier) + '/flows', |
| dataType: 'json' |
| }).done(function (response) { |
| var versionedFlows = []; |
| |
| if (nfCommon.isDefinedAndNotNull(response.versionedFlows) && response.versionedFlows.length > 0) { |
| response.versionedFlows.sort(function (a, b) { |
| return a.versionedFlow.flowName > b.versionedFlow.flowName; |
| }); |
| |
| $.each(response.versionedFlows, function (_, versionedFlowEntity) { |
| var versionedFlow = versionedFlowEntity.versionedFlow; |
| versionedFlows.push({ |
| text: versionedFlow.flowName, |
| value: versionedFlow.flowId, |
| description: nfCommon.escapeHtml(versionedFlow.description) |
| }); |
| }); |
| } else { |
| versionedFlows.push({ |
| text: 'No available flows', |
| value: null, |
| optionClass: 'unset', |
| disabled: true |
| }); |
| } |
| |
| // load the buckets |
| $('#import-flow-version-name-combo').combo('destroy').combo({ |
| options: versionedFlows, |
| select: function (selectedFlow) { |
| if (nfCommon.isDefinedAndNotNull(selectedFlow.value)) { |
| selectFlow(registryIdentifier, bucketIdentifier, selectedFlow.value) |
| } else { |
| var importFlowVersionGrid = $('#import-flow-version-table').data('gridInstance'); |
| var importFlowVersionData = importFlowVersionGrid.getData(); |
| |
| // clear the current values |
| importFlowVersionData.beginUpdate(); |
| importFlowVersionData.setItems([]); |
| importFlowVersionData.endUpdate(); |
| } |
| } |
| }); |
| }).fail(nfErrorHandler.handleAjaxError); |
| }; |
| |
| /** |
| * Handler when a versioned flow is selected. |
| * |
| * @param registryIdentifier |
| * @param bucketIdentifier |
| * @param flowIdentifier |
| */ |
| var selectVersionedFlow = function (registryIdentifier, bucketIdentifier, flowIdentifier) { |
| loadFlowVersions(registryIdentifier, bucketIdentifier, flowIdentifier).done(function () { |
| $('#import-flow-version-dialog').modal('refreshButtons'); |
| }); |
| }; |
| |
| /** |
| * Handler when a bucket is selected. |
| * |
| * @param selectedBucket |
| */ |
| var selectBucketImportVersion = function (selectedBucket) { |
| // clear the flow versions grid |
| clearFlowVersionsGrid(); |
| |
| if (nfCommon.isDefinedAndNotNull(selectedBucket.value)) { |
| // mark the flows as loading |
| $('#import-flow-version-name-combo').combo('destroy').combo({ |
| options: [{ |
| text: 'Loading flows...', |
| value: null, |
| optionClass: 'unset', |
| disabled: true |
| }] |
| }); |
| |
| var selectedRegistry = $('#import-flow-version-registry-combo').combo('getSelectedOption'); |
| |
| // load the flows for the currently selected registry and bucket |
| loadFlows(selectedRegistry.value, selectedBucket.value, selectVersionedFlow); |
| } else { |
| // mark no flows available |
| $('#import-flow-version-name-combo').combo('destroy').combo({ |
| options: [{ |
| text: 'No available flows', |
| value: null, |
| optionClass: 'unset', |
| disabled: true |
| }] |
| }); |
| } |
| }; |
| |
| /** |
| * Imports the selected flow version. |
| */ |
| var importFlowVersion = function () { |
| var pt = $('#import-flow-version-dialog').data('pt'); |
| |
| var selectedRegistry = $('#import-flow-version-registry-combo').combo('getSelectedOption'); |
| var selectedBucket = $('#import-flow-version-bucket-combo').combo('getSelectedOption'); |
| var selectedFlow = $('#import-flow-version-name-combo').combo('getSelectedOption'); |
| |
| var importFlowVersionGrid = $('#import-flow-version-table').data('gridInstance'); |
| var selectedVersionIndex = importFlowVersionGrid.getSelectedRows(); |
| var selectedVersion = importFlowVersionGrid.getDataItem(selectedVersionIndex[0]); |
| |
| var processGroupEntity = { |
| 'revision': nfClient.getRevision({ |
| 'revision': { |
| 'version': 0 |
| } |
| }), |
| 'disconnectedNodeAcknowledged': nfStorage.isDisconnectionAcknowledged(), |
| 'component': { |
| 'position': { |
| 'x': pt.x, |
| 'y': pt.y |
| }, |
| 'versionControlInformation': { |
| 'registryId': selectedRegistry.value, |
| 'bucketId': selectedBucket.value, |
| 'flowId': selectedFlow.value, |
| 'version': selectedVersion.version |
| } |
| } |
| }; |
| |
| return $.ajax({ |
| type: 'POST', |
| data: JSON.stringify(processGroupEntity), |
| url: '../nifi-api/process-groups/' + encodeURIComponent(nfCanvasUtils.getGroupId()) + '/process-groups', |
| dataType: 'json', |
| contentType: 'application/json' |
| }).done(function (response) { |
| // add the process group to the graph |
| nfGraph.add({ |
| 'processGroups': [response] |
| }, { |
| 'selectAll': true |
| }); |
| |
| // update component visibility |
| nfGraph.updateVisibility(); |
| |
| // update the birdseye |
| nfBirdseye.refresh(); |
| }).fail(nfErrorHandler.handleAjaxError); |
| }; |
| |
| /** |
| * Determines whether the import/change button is disabled. |
| * |
| * @returns {boolean} |
| */ |
| var disableImportOrChangeButton = function () { |
| var importFlowVersionGrid = $('#import-flow-version-table').data('gridInstance'); |
| if (nfCommon.isDefinedAndNotNull(importFlowVersionGrid)) { |
| var selected = importFlowVersionGrid.getSelectedRows(); |
| |
| // if the version label is visible, this is a change version request so disable when |
| // the version that represents the current version is selected |
| if ($('#import-flow-version-label').is(':visible')) { |
| if (selected.length === 1) { |
| var selectedFlow = importFlowVersionGrid.getDataItem(selected[0]); |
| |
| var currentVersion = parseInt($('#import-flow-version-label').text(), 10); |
| return currentVersion === selectedFlow.version; |
| } else { |
| return true; |
| } |
| } else { |
| // if importing, enable when a single row is selecting |
| return selected.length !== 1; |
| } |
| } else { |
| return true; |
| } |
| }; |
| |
| /** |
| * Changes the flow version for the currently selected Process Group. |
| * |
| * @returns {deferred} |
| */ |
| var changeFlowVersion = function () { |
| var changeTimer = null; |
| var changeRequest = null; |
| var cancelled = false; |
| |
| var processGroupId = $('#import-flow-version-process-group-id').text(); |
| var processGroupRevision = $('#import-flow-version-process-group-id').data('revision'); |
| var versionControlInformation = $('#import-flow-version-process-group-id').data('versionControlInformation'); |
| |
| var importFlowVersionGrid = $('#import-flow-version-table').data('gridInstance'); |
| var selectedVersionIndex = importFlowVersionGrid.getSelectedRows(); |
| var selectedVersion = importFlowVersionGrid.getDataItem(selectedVersionIndex[0]); |
| |
| // update the button model of the change version status dialog |
| $('#change-version-status-dialog').modal('setButtonModel', [{ |
| buttonText: 'Stop', |
| color: { |
| base: '#728E9B', |
| hover: '#004849', |
| text: '#ffffff' |
| }, |
| handler: { |
| click: function () { |
| cancelled = true; |
| |
| $('#change-version-status-dialog').modal('setButtonModel', []); |
| |
| // we are waiting for the next poll attempt |
| if (changeTimer !== null) { |
| // cancel it |
| clearTimeout(changeTimer); |
| |
| // cancel the change request |
| completeChangeRequest(); |
| } |
| } |
| } |
| }]); |
| |
| // hide the import dialog immediately |
| $('#import-flow-version-dialog').modal('hide'); |
| |
| var submitChangeRequest = function () { |
| var changeVersionRequest = { |
| 'processGroupRevision': nfClient.getRevision({ |
| 'revision': { |
| 'version': processGroupRevision.version |
| } |
| }), |
| 'disconnectedNodeAcknowledged': nfStorage.isDisconnectionAcknowledged(), |
| 'versionControlInformation': { |
| 'groupId': processGroupId, |
| 'registryId': versionControlInformation.registryId, |
| 'bucketId': versionControlInformation.bucketId, |
| 'flowId': versionControlInformation.flowId, |
| 'version': selectedVersion.version |
| } |
| }; |
| |
| return $.ajax({ |
| type: 'POST', |
| data: JSON.stringify(changeVersionRequest), |
| url: '../nifi-api/versions/update-requests/process-groups/' + encodeURIComponent(processGroupId), |
| dataType: 'json', |
| contentType: 'application/json' |
| }).done(function () { |
| // initialize the progress bar value |
| updateProgress(0); |
| |
| // show the progress dialog |
| $('#change-version-status-dialog').modal('show'); |
| }).fail(nfErrorHandler.handleAjaxError); |
| }; |
| |
| var pollChangeRequest = function () { |
| getChangeRequest().done(processChangeResponse); |
| }; |
| |
| var getChangeRequest = function () { |
| return $.ajax({ |
| type: 'GET', |
| url: changeRequest.uri, |
| dataType: 'json' |
| }).fail(completeChangeRequest).fail(nfErrorHandler.handleAjaxError); |
| }; |
| |
| var completeChangeRequest = function () { |
| if (cancelled === true) { |
| // update the message to indicate successful completion |
| $('#change-version-status-message').text('The change version request has been cancelled.'); |
| |
| // update the button model |
| $('#change-version-status-dialog').modal('setButtonModel', [{ |
| buttonText: 'Close', |
| color: { |
| base: '#728E9B', |
| hover: '#004849', |
| text: '#ffffff' |
| }, |
| handler: { |
| click: function () { |
| $(this).modal('hide'); |
| } |
| } |
| }]); |
| } |
| |
| if (nfCommon.isDefinedAndNotNull(changeRequest)) { |
| $.ajax({ |
| type: 'DELETE', |
| url: changeRequest.uri + '?' + $.param({ |
| 'disconnectedNodeAcknowledged': nfStorage.isDisconnectionAcknowledged() |
| }), |
| dataType: 'json' |
| }).done(function (response) { |
| changeRequest = response.request; |
| |
| // update the component that was changing |
| updateProcessGroup(processGroupId); |
| |
| if (nfCommon.isDefinedAndNotNull(changeRequest.failureReason)) { |
| // hide the progress dialog |
| $('#change-version-status-dialog').modal('hide'); |
| |
| nfDialog.showOkDialog({ |
| headerText: 'Change Version', |
| dialogContent: nfCommon.escapeHtml(changeRequest.failureReason) |
| }); |
| } else { |
| // update the percent complete |
| updateProgress(changeRequest.percentCompleted); |
| |
| // update the message to indicate successful completion |
| $('#change-version-status-message').text('This Process Group version has changed.'); |
| |
| // update the button model |
| $('#change-version-status-dialog').modal('setButtonModel', [{ |
| buttonText: 'Close', |
| color: { |
| base: '#728E9B', |
| hover: '#004849', |
| text: '#ffffff' |
| }, |
| handler: { |
| click: function () { |
| $(this).modal('hide'); |
| } |
| } |
| }]); |
| } |
| }); |
| } |
| }; |
| |
| var processChangeResponse = function (response) { |
| changeRequest = response.request; |
| |
| if (changeRequest.complete === true || cancelled === true) { |
| completeChangeRequest(); |
| } else { |
| // update the percent complete |
| updateProgress(changeRequest.percentCompleted); |
| |
| // update the status of the listing request |
| $('#change-version-status-message').text(changeRequest.state); |
| |
| changeTimer = setTimeout(function () { |
| // clear the timer since we've been invoked |
| changeTimer = null; |
| |
| // poll revert request |
| pollChangeRequest(); |
| }, 2000); |
| } |
| }; |
| |
| submitChangeRequest().done(processChangeResponse); |
| }; |
| |
| /** |
| * Gets the version control information for the specified process group id. |
| * |
| * @param processGroupId |
| * @return {deferred} |
| */ |
| var getVersionControlInformation = function (processGroupId) { |
| return $.Deferred(function (deferred) { |
| if (processGroupId === nfCanvasUtils.getGroupId()) { |
| $.ajax({ |
| type: 'GET', |
| url: '../nifi-api/versions/process-groups/' + encodeURIComponent(processGroupId), |
| dataType: 'json' |
| }).done(function (response) { |
| deferred.resolve(response); |
| }).fail(function () { |
| deferred.reject(); |
| }); |
| } else { |
| var processGroup = nfProcessGroup.get(processGroupId); |
| if (processGroup.permissions.canRead === true && processGroup.permissions.canWrite === true) { |
| deferred.resolve({ |
| 'processGroupRevision': processGroup.revision, |
| 'versionControlInformation': processGroup.component.versionControlInformation |
| }); |
| } else { |
| deferred.reject(); |
| } |
| } |
| }).promise(); |
| }; |
| |
| /** |
| * Updates the specified process group with the specified version control information. |
| * |
| * @param processGroupId |
| * @param versionControlInformation |
| */ |
| var updateVersionControlInformation = function (processGroupId, versionControlInformation) { |
| // refresh either selected PG or bread crumb to reflect connected/tracking status |
| if (nfCanvasUtils.getGroupId() === processGroupId) { |
| nfNgBridge.injector.get('breadcrumbsCtrl').updateVersionControlInformation(processGroupId, versionControlInformation); |
| nfNgBridge.digest(); |
| } else { |
| nfProcessGroup.reload(processGroupId); |
| } |
| }; |
| |
| /** |
| * Updates the specified process group following an operation that may change it's contents. |
| * |
| * @param processGroupId |
| */ |
| var updateProcessGroup = function (processGroupId) { |
| if (nfCanvasUtils.getGroupId() === processGroupId) { |
| // if reverting/changing current PG... reload/refresh this group/canvas |
| |
| $.ajax({ |
| type: 'GET', |
| url: '../nifi-api/flow/process-groups/' + encodeURIComponent(processGroupId), |
| dataType: 'json' |
| }).done(function (response) { |
| // update the graph components |
| nfGraph.set(response.processGroupFlow.flow); |
| |
| // update the component visibility |
| nfGraph.updateVisibility(); |
| |
| // update the breadcrumbs |
| var breadcrumbsCtrl = nfNgBridge.injector.get('breadcrumbsCtrl'); |
| breadcrumbsCtrl.resetBreadcrumbs(); |
| breadcrumbsCtrl.generateBreadcrumbs(response.processGroupFlow.breadcrumb); |
| |
| // inform Angular app values have changed |
| nfNgBridge.digest(); |
| }).fail(nfErrorHandler.handleAjaxError); |
| } else { |
| // if reverting selected PG... reload selected PG to update counts, etc |
| nfProcessGroup.reload(processGroupId); |
| } |
| }; |
| |
| /** |
| * Updates the progress bar to the specified percent complete. |
| * |
| * @param percentComplete |
| */ |
| var updateProgress = function (percentComplete) { |
| // remove existing labels |
| var progressBar = $('#change-version-percent-complete'); |
| progressBar.find('div.progress-label').remove(); |
| progressBar.find('md-progress-linear').remove(); |
| |
| // update the progress |
| var label = $('<div class="progress-label"></div>').text(percentComplete + '%'); |
| (nfNgBridge.injector.get('$compile')($('<md-progress-linear ng-cloak ng-value="' + percentComplete + '" class="md-hue-2" md-mode="determinate" aria-label="Searching Queue"></md-progress-linear>'))(nfNgBridge.rootScope)).appendTo(progressBar); |
| progressBar.append(label); |
| }; |
| |
| /** |
| * Shows local changes for the specified process group. |
| * |
| * @param processGroupId |
| * @param localChangesMessage |
| * @param localChangesTable |
| * @param totalLabel |
| */ |
| var loadLocalChanges = function (processGroupId, localChangesMessage, localChangesTable, totalLabel) { |
| var localChangesGrid = localChangesTable.data('gridInstance'); |
| var localChangesData = localChangesGrid.getData(); |
| |
| // begin the update |
| localChangesData.beginUpdate(); |
| |
| // remove the current versions |
| localChangesGrid.setSelectedRows([]); |
| localChangesGrid.resetActiveCell(); |
| localChangesData.setItems([]); |
| |
| // load the necessary details |
| var loadMessage = getVersionControlInformation(processGroupId).done(function (response) { |
| if (nfCommon.isDefinedAndNotNull(response.versionControlInformation)) { |
| var vci = response.versionControlInformation; |
| localChangesMessage.text('The following changes have been made to ' + vci.flowName + ' (Version ' + vci.version + ').'); |
| } else { |
| nfDialog.showOkDialog({ |
| headerText: 'Change Version', |
| dialogContent: 'This Process Group is not currently under version control.' |
| }); |
| } |
| }); |
| var loadChanges = $.ajax({ |
| type: 'GET', |
| url: '../nifi-api/process-groups/' + encodeURIComponent(processGroupId) + '/local-modifications', |
| dataType: 'json' |
| }).done(function (response) { |
| if (nfCommon.isDefinedAndNotNull(response.componentDifferences) && response.componentDifferences.length > 0) { |
| var totalDifferences = 0; |
| $.each(response.componentDifferences, function (_, componentDifference) { |
| $.each(componentDifference.differences, function (_, difference) { |
| localChangesData.addItem({ |
| id: totalDifferences++, |
| componentId: componentDifference.componentId, |
| componentName: componentDifference.componentName, |
| componentType: componentDifference.componentType, |
| processGroupId: componentDifference.processGroupId, |
| differenceType: difference.differenceType, |
| difference: difference.difference |
| }); |
| }); |
| }); |
| |
| // end the update |
| localChangesData.endUpdate(); |
| |
| // resort |
| localChangesData.reSort(); |
| localChangesGrid.invalidate(); |
| |
| // update the total displayed |
| totalLabel.text(nfCommon.formatInteger(totalDifferences)); |
| } else { |
| nfDialog.showOkDialog({ |
| headerText: 'Local Changes', |
| dialogContent: 'This Process Group does not have any local changes.' |
| }); |
| } |
| }).fail(nfErrorHandler.handleAjaxError); |
| |
| return $.when(loadMessage, loadChanges); |
| }; |
| |
| /** |
| * Revert local changes for the specified process group. |
| * |
| * @param processGroupId |
| */ |
| var revertLocalChanges = function (processGroupId) { |
| getVersionControlInformation(processGroupId).done(function (response) { |
| if (nfCommon.isDefinedAndNotNull(response.versionControlInformation)) { |
| var revertTimer = null; |
| var revertRequest = null; |
| var cancelled = false; |
| |
| // update the button model of the revert status dialog |
| $('#change-version-status-dialog').modal('setButtonModel', [{ |
| buttonText: 'Stop', |
| color: { |
| base: '#728E9B', |
| hover: '#004849', |
| text: '#ffffff' |
| }, |
| handler: { |
| click: function () { |
| cancelled = true; |
| |
| $('#change-version-status-dialog').modal('setButtonModel', []); |
| |
| // we are waiting for the next poll attempt |
| if (revertTimer !== null) { |
| // cancel it |
| clearTimeout(revertTimer); |
| |
| // cancel the revert request |
| completeRevertRequest(); |
| } |
| } |
| } |
| }]); |
| |
| // hide the import dialog immediately |
| $('#import-flow-version-dialog').modal('hide'); |
| |
| var submitRevertRequest = function () { |
| var revertFlowVersionRequest = { |
| 'processGroupRevision': nfClient.getRevision({ |
| 'revision': { |
| 'version': response.processGroupRevision.version |
| } |
| }), |
| 'disconnectedNodeAcknowledged': nfStorage.isDisconnectionAcknowledged(), |
| 'versionControlInformation': response.versionControlInformation |
| }; |
| |
| return $.ajax({ |
| type: 'POST', |
| data: JSON.stringify(revertFlowVersionRequest), |
| url: '../nifi-api/versions/revert-requests/process-groups/' + encodeURIComponent(processGroupId), |
| dataType: 'json', |
| contentType: 'application/json' |
| }).done(function () { |
| // initialize the progress bar value |
| updateProgress(0); |
| |
| // show the progress dialog |
| $('#change-version-status-dialog').modal('show'); |
| }).fail(nfErrorHandler.handleAjaxError); |
| }; |
| |
| var pollRevertRequest = function () { |
| getRevertRequest().done(processRevertResponse); |
| }; |
| |
| var getRevertRequest = function () { |
| return $.ajax({ |
| type: 'GET', |
| url: revertRequest.uri, |
| dataType: 'json' |
| }).fail(completeRevertRequest).fail(nfErrorHandler.handleAjaxError); |
| }; |
| |
| var completeRevertRequest = function () { |
| if (cancelled === true) { |
| // update the message to indicate successful completion |
| $('#change-version-status-message').text('The revert request has been cancelled.'); |
| |
| // update the button model |
| $('#change-version-status-dialog').modal('setButtonModel', [{ |
| buttonText: 'Close', |
| color: { |
| base: '#728E9B', |
| hover: '#004849', |
| text: '#ffffff' |
| }, |
| handler: { |
| click: function () { |
| $(this).modal('hide'); |
| } |
| } |
| }]); |
| } |
| |
| if (nfCommon.isDefinedAndNotNull(revertRequest)) { |
| $.ajax({ |
| type: 'DELETE', |
| url: revertRequest.uri + '?' + $.param({ |
| 'disconnectedNodeAcknowledged': nfStorage.isDisconnectionAcknowledged() |
| }), |
| dataType: 'json' |
| }).done(function (response) { |
| revertRequest = response.request; |
| |
| // update the component that was changing |
| updateProcessGroup(processGroupId); |
| |
| if (nfCommon.isDefinedAndNotNull(revertRequest.failureReason)) { |
| // hide the progress dialog |
| $('#change-version-status-dialog').modal('hide'); |
| |
| nfDialog.showOkDialog({ |
| headerText: 'Revert Local Changes', |
| dialogContent: nfCommon.escapeHtml(revertRequest.failureReason) |
| }); |
| } else { |
| // update the percent complete |
| updateProgress(revertRequest.percentCompleted); |
| |
| // update the message to indicate successful completion |
| $('#change-version-status-message').text('This Process Group version has changed.'); |
| |
| // update the button model |
| $('#change-version-status-dialog').modal('setButtonModel', [{ |
| buttonText: 'Close', |
| color: { |
| base: '#728E9B', |
| hover: '#004849', |
| text: '#ffffff' |
| }, |
| handler: { |
| click: function () { |
| $(this).modal('hide'); |
| } |
| } |
| }]); |
| } |
| }); |
| } |
| }; |
| |
| var processRevertResponse = function (response) { |
| revertRequest = response.request; |
| |
| if (revertRequest.complete === true || cancelled === true) { |
| completeRevertRequest(); |
| } else { |
| // update the percent complete |
| updateProgress(revertRequest.percentCompleted); |
| |
| // update the status of the revert request |
| $('#change-version-status-message').text(revertRequest.state); |
| |
| revertTimer = setTimeout(function () { |
| // clear the timer since we've been invoked |
| revertTimer = null; |
| |
| // poll revert request |
| pollRevertRequest(); |
| }, 2000); |
| } |
| }; |
| |
| submitRevertRequest().done(processRevertResponse); |
| } else { |
| nfDialog.showOkDialog({ |
| headerText: 'Revert Changes', |
| dialogContent: 'This Process Group is not currently under version control.' |
| }); |
| } |
| }).fail(nfErrorHandler.handleAjaxError); |
| }; |
| |
| return { |
| init: function (timeOffset) { |
| serverTimeOffset = timeOffset; |
| |
| // 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 ($('#save-flow-version-registry-combo').is(':visible')) { |
| var selectedRegistry = $('#save-flow-version-registry-combo').combo('getSelectedOption'); |
| var selectedBucket = $('#save-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 = $('#save-flow-version-process-group-id').text(); |
| saveFlowVersion().done(function (response) { |
| updateVersionControlInformation(processGroupId, response.versionControlInformation); |
| }); |
| |
| $(this).modal('hide'); |
| } |
| } |
| }, { |
| buttonText: 'Cancel', |
| color: { |
| base: '#E3E8EB', |
| hover: '#C7D2D7', |
| text: '#004849' |
| }, |
| handler: { |
| click: function () { |
| $(this).modal('hide'); |
| } |
| } |
| }], |
| handler: { |
| close: function () { |
| resetSaveFlowVersionDialog(); |
| } |
| } |
| }); |
| |
| // initialize the import flow version dialog |
| $('#import-flow-version-dialog').modal({ |
| scrollableContentStyle: 'scrollable', |
| handler: { |
| close: function () { |
| resetImportFlowVersionDialog(); |
| } |
| } |
| }); |
| |
| // configure the drop request status dialog |
| $('#change-version-status-dialog').modal({ |
| scrollableContentStyle: 'scrollable', |
| headerText: 'Change Flow Version', |
| handler: { |
| close: function () { |
| // clear the current button model |
| $('#change-version-status-dialog').modal('setButtonModel', []); |
| } |
| } |
| }); |
| |
| // init the revert local changes dialog |
| $('#revert-local-changes-dialog').modal({ |
| scrollableContentStyle: 'scrollable', |
| headerText: 'Revert Local Changes', |
| buttons: [{ |
| buttonText: 'Revert', |
| color: { |
| base: '#728E9B', |
| hover: '#004849', |
| text: '#ffffff' |
| }, |
| handler: { |
| click: function () { |
| var processGroupId = $('#revert-local-changes-process-group-id').text(); |
| revertLocalChanges(processGroupId); |
| |
| $(this).modal('hide'); |
| } |
| } |
| }, { |
| buttonText: 'Cancel', |
| color: { |
| base: '#E3E8EB', |
| hover: '#C7D2D7', |
| text: '#004849' |
| }, |
| handler: { |
| click: function () { |
| $(this).modal('hide'); |
| } |
| } |
| }], |
| handler: { |
| close: function () { |
| resetRevertLocalChangesDialog(); |
| } |
| } |
| }); |
| |
| // init the show local changes dialog |
| $('#show-local-changes-dialog').modal({ |
| scrollableContentStyle: 'scrollable', |
| headerText: 'Show Local Changes', |
| buttons: [{ |
| buttonText: 'Close', |
| color: { |
| base: '#728E9B', |
| hover: '#004849', |
| text: '#ffffff' |
| }, |
| handler: { |
| click: function () { |
| $(this).modal('hide'); |
| } |
| } |
| }], |
| handler: { |
| close: function () { |
| resetShowLocalChangesDialog(); |
| } |
| } |
| }); |
| |
| // handle the click for the process group import |
| $('#import-process-group-link').on('click', function() { |
| showImportFlowVersionDialog(); |
| }); |
| |
| // initialize the import flow version table |
| initImportFlowVersionTable(); |
| initLocalChangesTable($('#revert-local-changes-table'), $('#revert-local-changes-filter'), $('#displayed-revert-local-changes-entries'), $('#total-revert-local-changes-entries')); |
| initLocalChangesTable($('#show-local-changes-table'), $('#show-local-changes-filter'), $('#displayed-show-local-changes-entries'), $('#total-show-local-changes-entries')); |
| }, |
| |
| /** |
| * Shows the flow version dialog. |
| * |
| * @param processGroupId |
| */ |
| showFlowVersionDialog: function (processGroupId, action) { |
| var focusName = true; |
| |
| return $.Deferred(function (deferred) { |
| getVersionControlInformation(processGroupId).done(function (groupVersionControlInformation) { |
| if (nfCommon.isDefinedAndNotNull(groupVersionControlInformation.versionControlInformation)) { |
| var versionControlInformation = groupVersionControlInformation.versionControlInformation; |
| |
| // update the registry and bucket visibility |
| $('#save-flow-version-registry').text(versionControlInformation.registryName).show(); |
| $('#save-flow-version-bucket').text(versionControlInformation.bucketName).show(); |
| |
| if (action == 'COMMIT') { |
| $('#save-flow-version-label').text(versionControlInformation.version + 1).show(); |
| } else { |
| $('#save-flow-version-label').hide(); |
| } |
| |
| $('#save-flow-version-name').text(versionControlInformation.flowName).show(); |
| nfCommon.populateField('save-flow-version-description', versionControlInformation.flowDescription); |
| $('#save-flow-version-description').show(); |
| |
| // record the versionControlInformation |
| $('#save-flow-version-process-group-id').data('versionControlInformation', versionControlInformation); |
| |
| // record the type of action (i.e. commit vs force-commit) |
| $('#save-flow-version-action').text(action); |
| |
| // reposition the version label |
| $('#save-flow-version-label').css('margin-top', '-15px'); |
| |
| focusName = false; |
| deferred.resolve(); |
| } else { |
| // update the registry and bucket visibility |
| var registryCombo = $('#save-flow-version-registry-combo').combo('destroy').combo({ |
| options: [{ |
| text: 'Loading registries...', |
| value: null, |
| optionClass: 'unset', |
| disabled: true |
| }] |
| }).show(); |
| var bucketCombo = $('#save-flow-version-bucket-combo').combo('destroy').combo({ |
| options: [{ |
| text: 'Loading buckets...', |
| value: null, |
| optionClass: 'unset', |
| disabled: true |
| }] |
| }).show(); |
| |
| // set the initial version |
| $('#save-flow-version-label').text(1).show(); |
| |
| $('#save-flow-version-name-field').show(); |
| $('#save-flow-version-description-field').show(); |
| $('#save-flow-version-action').text(action); |
| |
| // reposition the version label |
| $('#save-flow-version-label').css('margin-top', '0'); |
| |
| loadRegistries($('#save-flow-version-dialog'), registryCombo, bucketCombo, null, selectBucketSaveFlowVersion, function (bucketEntity) { |
| return bucketEntity.permissions.canWrite === true; |
| }).done(function () { |
| deferred.resolve(); |
| }).fail(function () { |
| deferred.reject(); |
| }); |
| } |
| |
| // record the revision |
| $('#save-flow-version-process-group-id').data('revision', groupVersionControlInformation.processGroupRevision).text(processGroupId); |
| }).fail(nfErrorHandler.handleAjaxError); |
| }).done(function () { |
| $('#save-flow-version-dialog').modal('show'); |
| |
| if (focusName) { |
| $('#save-flow-version-name-field').focus(); |
| } else { |
| $('#save-flow-version-change-comments').focus(); |
| } |
| }).fail(function () { |
| $('#save-flow-version-dialog').modal('refreshButtons'); |
| }).promise(); |
| }, |
| |
| /** |
| * Reverts local changes for the specified Process Group. |
| * |
| * @param processGroupId |
| */ |
| revertLocalChanges: function (processGroupId) { |
| loadLocalChanges(processGroupId, $('#revert-local-changes-message'), $('#revert-local-changes-table'), $('#total-revert-local-changes-entries')).done(function () { |
| $('#revert-local-changes-process-group-id').text(processGroupId); |
| $('#revert-local-changes-dialog').modal('show'); |
| }); |
| }, |
| |
| /** |
| * Shows local changes for the specified process group. |
| * |
| * @param processGroupId |
| */ |
| showLocalChanges: function (processGroupId) { |
| loadLocalChanges(processGroupId, $('#show-local-changes-message'), $('#show-local-changes-table'), $('#total-show-local-changes-entries')).done(function () { |
| $('#show-local-changes-dialog').modal('show'); |
| }); |
| }, |
| |
| /** |
| * Shows the change flow version dialog. |
| * |
| * @param processGroupId |
| */ |
| showChangeFlowVersionDialog: function (processGroupId) { |
| return $.Deferred(function (deferred) { |
| getVersionControlInformation(processGroupId).done(function (groupVersionControlInformation) { |
| if (nfCommon.isDefinedAndNotNull(groupVersionControlInformation.versionControlInformation)) { |
| var versionControlInformation = groupVersionControlInformation.versionControlInformation; |
| |
| // update the registry and bucket visibility |
| $('#import-flow-version-registry').text(versionControlInformation.registryName).show(); |
| $('#import-flow-version-bucket').text(versionControlInformation.bucketName).show(); |
| $('#import-flow-version-name').text(versionControlInformation.flowName).show(); |
| |
| // show the current version information |
| $('#import-flow-version-container').show(); |
| $('#import-flow-version-label').text(versionControlInformation.version); |
| |
| // record the versionControlInformation |
| $('#import-flow-version-process-group-id').data('versionControlInformation', versionControlInformation).data('revision', groupVersionControlInformation.processGroupRevision).text(processGroupId); |
| |
| // load the flow versions |
| loadFlowVersions(versionControlInformation.registryId, versionControlInformation.bucketId, versionControlInformation.flowId).done(function () { |
| deferred.resolve(); |
| }).fail(function () { |
| nfDialog.showOkDialog({ |
| headerText: 'Change Version', |
| dialogContent: 'Unable to load available versions for this Process Group.' |
| }); |
| |
| deferred.reject(); |
| }); |
| } else { |
| nfDialog.showOkDialog({ |
| headerText: 'Change Version', |
| dialogContent: 'This Process Group is not currently under version control.' |
| }); |
| |
| deferred.reject(); |
| } |
| }).fail(nfErrorHandler.handleAjaxError); |
| }).done(function () { |
| // show the dialog |
| $('#import-flow-version-dialog').modal('setHeaderText', 'Change Version').modal('setButtonModel', [{ |
| buttonText: 'Change', |
| color: { |
| base: '#728E9B', |
| hover: '#004849', |
| text: '#ffffff' |
| }, |
| disabled: disableImportOrChangeButton, |
| handler: { |
| click: function () { |
| changeFlowVersion(); |
| } |
| } |
| }, { |
| buttonText: 'Cancel', |
| color: { |
| base: '#E3E8EB', |
| hover: '#C7D2D7', |
| text: '#004849' |
| }, |
| handler: { |
| click: function () { |
| $(this).modal('hide'); |
| } |
| } |
| }]).modal('show'); |
| }).promise(); |
| }, |
| |
| /** |
| * Stops version control for the specified Process Group. |
| * |
| * @param processGroupId |
| */ |
| stopVersionControl: function (processGroupId) { |
| // prompt the user before disconnecting |
| nfDialog.showYesNoDialog({ |
| headerText: 'Stop Version Control', |
| dialogContent: 'Are you sure you want to stop version control?', |
| 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($.extend({ |
| 'disconnectedNodeAcknowledged': nfStorage.isDisconnectionAcknowledged() |
| }, revision)), |
| dataType: 'json', |
| contentType: 'application/json' |
| }).done(function (response) { |
| updateVersionControlInformation(processGroupId, undefined); |
| |
| nfDialog.showOkDialog({ |
| headerText: 'Disconnect', |
| dialogContent: 'This Process Group is no longer under version control.' |
| }); |
| }).fail(nfErrorHandler.handleAjaxError); |
| } else { |
| nfDialog.showOkDialog({ |
| headerText: 'Disconnect', |
| dialogContent: 'This Process Group is not currently under version control.' |
| }) |
| } |
| }).fail(nfErrorHandler.handleAjaxError); |
| } |
| }); |
| } |
| }; |
| })); |