http://git-wip-us.apache.org/repos/asf/nifi/blob/1df8fe44/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-output-port-component.js ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-output-port-component.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-output-port-component.js new file mode 100644 index 0000000..5a27d48 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-output-port-component.js @@ -0,0 +1,205 @@ +/* + * 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 nf, d3 */ + +nf.ng.OutputPortComponent = (function () { + + function OutputPortComponent(serviceProvider) { + + /** + * Create the input port and add to the graph. + * + * @argument {string} portName The output port name. + * @argument {object} pt The point that the output port was dropped. + */ + var createOutputPort = function (portName, pt) { + var outputPortEntity = { + 'revision': nf.Client.getRevision(), + 'component': { + 'name': portName, + 'position': { + 'x': pt.x, + 'y': pt.y + } + } + }; + + // create a new processor of the defined type + $.ajax({ + type: 'POST', + url: serviceProvider.headerCtrl.toolboxCtrl.config.urls.api + '/process-groups/' + encodeURIComponent(nf.Canvas.getGroupId()) + '/output-ports', + data: JSON.stringify(outputPortEntity), + dataType: 'json', + contentType: 'application/json' + }).done(function (response) { + if (nf.Common.isDefinedAndNotNull(response.component)) { + // update the revision + nf.Client.setRevision(response.revision); + + // add the port to the graph + nf.Graph.add({ + 'outputPorts': [response] + }, true); + + // update component visibility + nf.Canvas.View.updateVisibility(); + + // update the birdseye + nf.Birdseye.refresh(); + } + }).fail(nf.Common.handleAjaxError); + }; + + function OutputPortComponent() { + }; + OutputPortComponent.prototype = { + constructor: OutputPortComponent, + + /** + * The output port component's modal. + */ + modal: { + + /** + * Gets the modal element. + * + * @returns {*|jQuery|HTMLElement} + */ + getElement: function () { + return $('#new-port-dialog'); //Reuse the input port dialog.... + }, + + /** + * Initialize the modal. + */ + init: function () { + //Reuse the input port dialog.... + }, + + /** + * Updates the modal config. + * + * @param {string} name The name of the property to update. + * @param {object|array} config The config for the `name`. + */ + update: function (name, config) { + this.getElement().modal(name, config); + }, + + /** + * Show the modal. + */ + show: function () { + this.getElement().modal('show'); + }, + + /** + * Hide the modal. + */ + hide: function () { + this.getElement().modal('hide'); + } + }, + + /** + * Gets the component. + * + * @returns {*|jQuery|HTMLElement} + */ + getElement: function () { + return $('#port-out-component'); + }, + + /** + * Enable the component. + */ + enabled: function () { + this.getElement().attr('disabled', false); + }, + + /** + * Disable the component. + */ + disabled: function () { + this.getElement().attr('disabled', true); + }, + + /** + * Handler function for when component is dropped on the canvas. + * + * @argument {object} pt The point that the component was dropped. + */ + dropHandler: function (pt) { + this.promptForOutputPortName(pt); + }, + + /** + * Prompts the user to enter the name for the output port. + * + * @argument {object} pt The point that the output port was dropped. + */ + promptForOutputPortName: function (pt) { + var self = this; + var addOutputPort = function () { + // get the name of the output port and clear the textfield + var portName = $('#new-port-name').val(); + + // hide the dialog + self.modal.hide(); + + // create the output port + createOutputPort(portName, pt); + }; + + this.modal.update('setButtonModel', [{ + buttonText: 'Add', + handler: { + click: addOutputPort + } + }, { + buttonText: 'Cancel', + handler: { + click: function () { + self.modal.hide(); + } + } + }]); + + // update the port type + $('#new-port-type').text('Output'); + + // set the focus and show the dialog + this.modal.show(); + + // set up the focus and key handlers + $('#new-port-name').focus().off('keyup').on('keyup', function (e) { + var code = e.keyCode ? e.keyCode : e.which; + if (code === $.ui.keyCode.ENTER) { + addOutputPort(); + } + }); + } + }; + var outputPortComponent = new OutputPortComponent(); + return outputPortComponent; + } + + OutputPortComponent.$inject = ['serviceProvider']; + + return OutputPortComponent; +}()); \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/1df8fe44/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-processor-component.js ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-processor-component.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-processor-component.js new file mode 100644 index 0000000..7451c75 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-processor-component.js @@ -0,0 +1,573 @@ +/* + * 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 nf, d3 */ + +nf.ng.ProcessorComponent = (function () { + + function ProcessorComponent(serviceProvider) { + + /** + * Filters the processor type table. + */ + var applyFilter = function () { + // get the dataview + var processorTypesGrid = $('#processor-types-table').data('gridInstance'); + + // ensure the grid has been initialized + if (nf.Common.isDefinedAndNotNull(processorTypesGrid)) { + var processorTypesData = processorTypesGrid.getData(); + + // update the search criteria + processorTypesData.setFilterArgs({ + searchString: getFilterText() + }); + processorTypesData.refresh(); + + // update the selection if possible + if (processorTypesData.getLength() > 0) { + processorTypesGrid.setSelectedRows([0]); + } + } + }; + + /** + * Determines if the item matches the filter. + * + * @param {object} item The item to filter. + * @param {object} args The filter criteria. + * @returns {boolean} Whether the item matches the filter. + */ + var matchesRegex = 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 matchesLabel = item['label'].search(filterExp) >= 0; + var matchesTags = item['tags'].search(filterExp) >= 0; + return matchesLabel || matchesTags; + }; + + /** + * Performs the filtering. + * + * @param {object} item The item subject to filtering. + * @param {object} args Filter arguments. + * @returns {Boolean} Whether or not to include the item. + */ + var filter = function (item, args) { + // determine if the item matches the filter + var matchesFilter = matchesRegex(item, args); + + // determine if the row matches the selected tags + var matchesTags = true; + if (matchesFilter) { + var tagFilters = $('#processor-tag-cloud').tagcloud('getSelectedTags'); + var hasSelectedTags = tagFilters.length > 0; + if (hasSelectedTags) { + matchesTags = matchesSelectedTags(tagFilters, item['tags']); + } + } + + // determine if this row should be visible + var matches = matchesFilter && matchesTags; + + // if this row is currently selected and its being filtered + if (matches === false && $('#selected-processor-type').text() === item['type']) { + // clear the selected row + $('#processor-type-description').text(''); + $('#processor-type-name').text(''); + $('#selected-processor-name').text(''); + $('#selected-processor-type').text(''); + + // clear the active cell the it can be reselected when its included + var processTypesGrid = $('#processor-types-table').data('gridInstance'); + processTypesGrid.resetActiveCell(); + } + + return matches; + }; + + /** + * Determines if the specified tags match all the tags selected by the user. + * + * @argument {string[]} tagFilters The tag filters. + * @argument {string} tags The tags to test. + */ + var matchesSelectedTags = function (tagFilters, tags) { + var selectedTags = []; + $.each(tagFilters, function (_, filter) { + selectedTags.push(filter); + }); + + // normalize the tags + var normalizedTags = tags.toLowerCase(); + + var matches = true; + $.each(selectedTags, function (i, selectedTag) { + if (normalizedTags.indexOf(selectedTag) === -1) { + matches = false; + return false; + } + }); + + return matches; + }; + + /** + * 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 aString = nf.Common.isDefinedAndNotNull(a[sortDetails.columnId]) ? a[sortDetails.columnId] : ''; + var bString = nf.Common.isDefinedAndNotNull(b[sortDetails.columnId]) ? b[sortDetails.columnId] : ''; + return aString === bString ? 0 : aString > bString ? 1 : -1; + }; + + // perform the sort + data.sort(comparer, sortDetails.sortAsc); + }; + + /** + * Get the text out of the filter field. If the filter field doesn't + * have any text it will contain the text 'filter list' so this method + * accounts for that. + */ + var getFilterText = function () { + var filterText = ''; + var filterField = $('#processor-type-filter'); + if (!filterField.hasClass(serviceProvider.headerCtrl.toolboxCtrl.config.styles.filterList)) { + filterText = filterField.val(); + } + return filterText; + }; + + /** + * Resets the filtered processor types. + */ + var resetProcessorDialog = function () { + // clear the selected tag cloud + $('#processor-tag-cloud').tagcloud('clearSelectedTags'); + + // clear any filter strings + $('#processor-type-filter').addClass(serviceProvider.headerCtrl.toolboxCtrl.config.styles.filterList).val(serviceProvider.headerCtrl.toolboxCtrl.config.filterText); + + // reapply the filter + applyFilter(); + + // clear the selected row + $('#processor-type-description').text(''); + $('#processor-type-name').text(''); + $('#selected-processor-name').text(''); + $('#selected-processor-type').text(''); + + // unselect any current selection + var processTypesGrid = $('#processor-types-table').data('gridInstance'); + processTypesGrid.setSelectedRows([]); + processTypesGrid.resetActiveCell(); + }; + + /** + * Create the processor and add to the graph. + * + * @argument {string} name The processor name. + * @argument {string} processorType The processor type. + * @argument {object} pt The point that the processor was dropped. + */ + var createProcessor = function (name, processorType, pt) { + var processorEntity = { + 'revision': nf.Client.getRevision(), + 'component': { + 'type': processorType, + 'name': name, + 'position': { + 'x': pt.x, + 'y': pt.y + } + } + }; + + // create a new processor of the defined type + $.ajax({ + type: 'POST', + url: serviceProvider.headerCtrl.toolboxCtrl.config.urls.api + '/process-groups/' + encodeURIComponent(nf.Canvas.getGroupId()) + '/processors', + data: JSON.stringify(processorEntity), + dataType: 'json', + contentType: 'application/json' + }).done(function (response) { + if (nf.Common.isDefinedAndNotNull(response.component)) { + // update the revision + nf.Client.setRevision(response.revision); + + // add the processor to the graph + nf.Graph.add({ + 'processors': [response] + }, true); + + // update component visibility + nf.Canvas.View.updateVisibility(); + + // update the birdseye + nf.Birdseye.refresh(); + } + }).fail(nf.Common.handleAjaxError); + }; + + function ProcessorComponent() { + }; + ProcessorComponent.prototype = { + constructor: ProcessorComponent, + + /** + * The processor component's modal. + */ + modal: { + + /** + * The processor component modal's filter. + */ + filter: { + + /** + * Initialize the filter. + */ + init: function () { + // define the function for filtering the list + $('#processor-type-filter').focus(function () { + if ($(this).hasClass(serviceProvider.headerCtrl.toolboxCtrl.config.styles.filterList)) { + $(this).removeClass(serviceProvider.headerCtrl.toolboxCtrl.config.styles.filterList).val(''); + } + }).blur(function () { + if ($(this).val() === '') { + $(this).addClass(serviceProvider.headerCtrl.toolboxCtrl.config.styles.filterList).val(serviceProvider.headerCtrl.toolboxCtrl.config.filterText); + } + }).addClass(serviceProvider.headerCtrl.toolboxCtrl.config.styles.filterList).val(serviceProvider.headerCtrl.toolboxCtrl.config.filterText); + + // initialize the processor type table + var processorTypesColumns = [ + {id: 'type', name: 'Type', field: 'label', sortable: true, resizable: true}, + {id: 'tags', name: 'Tags', field: 'tags', sortable: true, resizable: true} + ]; + var processorTypesOptions = { + forceFitColumns: true, + enableTextSelectionOnCells: true, + enableCellNavigation: true, + enableColumnReorder: false, + autoEdit: false, + multiSelect: false + }; + + // initialize the dataview + var processorTypesData = new Slick.Data.DataView({ + inlineFilters: false + }); + processorTypesData.setItems([]); + processorTypesData.setFilterArgs({ + searchString: getFilterText() + }); + processorTypesData.setFilter(filter); + + // initialize the sort + sort({ + columnId: 'type', + sortAsc: true + }, processorTypesData); + + // initialize the grid + var processorTypesGrid = new Slick.Grid('#processor-types-table', processorTypesData, processorTypesColumns, processorTypesOptions); + processorTypesGrid.setSelectionModel(new Slick.RowSelectionModel()); + processorTypesGrid.registerPlugin(new Slick.AutoTooltips()); + processorTypesGrid.setSortColumn('type', true); + processorTypesGrid.onSort.subscribe(function (e, args) { + sort({ + columnId: args.sortCol.field, + sortAsc: args.sortAsc + }, processorTypesData); + }); + processorTypesGrid.onSelectedRowsChanged.subscribe(function (e, args) { + if ($.isArray(args.rows) && args.rows.length === 1) { + var processorTypeIndex = args.rows[0]; + var processorType = processorTypesGrid.getDataItem(processorTypeIndex); + + // set the processor type description + if (nf.Common.isDefinedAndNotNull(processorType)) { + if (nf.Common.isBlank(processorType.description)) { + $('#processor-type-description').attr('title', '').html('<span class="unset">No description specified</span>'); + } else { + $('#processor-type-description').html(processorType.description).ellipsis(); + } + + // populate the dom + $('#processor-type-name').text(processorType.label).ellipsis(); + $('#selected-processor-name').text(processorType.label); + $('#selected-processor-type').text(processorType.type); + } + } + }); + + // wire up the dataview to the grid + processorTypesData.onRowCountChanged.subscribe(function (e, args) { + processorTypesGrid.updateRowCount(); + processorTypesGrid.render(); + + // update the total number of displayed processors + $('#displayed-processor-types').text(args.current); + }); + processorTypesData.onRowsChanged.subscribe(function (e, args) { + processorTypesGrid.invalidateRows(args.rows); + processorTypesGrid.render(); + }); + processorTypesData.syncGridSelection(processorTypesGrid, false); + + // hold onto an instance of the grid + $('#processor-types-table').data('gridInstance', processorTypesGrid); + + // load the available processor types, this select is shown in the + // new processor dialog when a processor is dragged onto the screen + $.ajax({ + type: 'GET', + url: serviceProvider.headerCtrl.toolboxCtrl.config.urls.processorTypes, + dataType: 'json' + }).done(function (response) { + var tags = []; + + // begin the update + processorTypesData.beginUpdate(); + + // go through each processor type + $.each(response.processorTypes, function (i, documentedType) { + var type = documentedType.type; + + // create the row for the processor type + processorTypesData.addItem({ + id: i, + label: nf.Common.substringAfterLast(type, '.'), + type: type, + description: nf.Common.escapeHtml(documentedType.description), + tags: documentedType.tags.join(', ') + }); + + // count the frequency of each tag for this type + $.each(documentedType.tags, function (i, tag) { + tags.push(tag.toLowerCase()); + }); + }); + + // end the udpate + processorTypesData.endUpdate(); + + // set the total number of processors + $('#total-processor-types, #displayed-processor-types').text(response.processorTypes.length); + + // create the tag cloud + $('#processor-tag-cloud').tagcloud({ + tags: tags, + select: applyFilter, + remove: applyFilter + }); + }).fail(nf.Common.handleAjaxError); + } + }, + + /** + * Gets the modal element. + * + * @returns {*|jQuery|HTMLElement} + */ + getElement: function () { + return $('#new-processor-dialog'); + }, + + /** + * Initialize the modal. + */ + init: function () { + this.filter.init(); + + // configure the new processor dialog + this.getElement().modal({ + headerText: 'Add Processor', + overlayBackground: false + }); + }, + + /** + * Updates the modal config. + * + * @param {string} name The name of the property to update. + * @param {object|array} config The config for the `name`. + */ + update: function (name, config) { + this.getElement().modal(name, config); + }, + + /** + * Show the modal + */ + show: function () { + this.getElement().modal('show'); + }, + + /** + * Hide the modal + */ + hide: function () { + this.getElement().modal('hide'); + } + }, + + /** + * Gets the component. + * + * @returns {*|jQuery|HTMLElement} + */ + getElement: function () { + return $('#processor-component'); + }, + + /** + * Enable the component. + */ + enabled: function () { + this.getElement().attr('disabled', false); + }, + + /** + * Disable the component. + */ + disabled: function () { + this.getElement().attr('disabled', true); + }, + + /** + * Handler function for when component is dropped on the canvas. + * + * @argument {object} pt The point that the component was dropped + */ + dropHandler: function (pt) { + this.promptForProcessorType(pt); + }, + + /** + * Prompts the user to select the type of new processor to create. + * + * @argument {object} pt The point that the processor was dropped + */ + promptForProcessorType: function (pt) { + var self = this; + // handles adding the selected processor at the specified point + var addProcessor = function () { + // get the type of processor currently selected + var name = $('#selected-processor-name').text(); + var processorType = $('#selected-processor-type').text(); + + // ensure something was selected + if (name === '' || processorType === '') { + nf.Dialog.showOkDialog({ + dialogContent: 'The type of processor to create must be selected.', + overlayBackground: false + }); + } else { + // create the new processor + createProcessor(name, processorType, pt); + } + + // hide the dialog + self.modal.hide(); + }; + + // get the grid reference + var grid = $('#processor-types-table').data('gridInstance'); + + // add the processor when its double clicked in the table + var gridDoubleClick = function (e, args) { + var processorType = grid.getDataItem(args.row); + + $('#selected-processor-name').text(processorType.label); + $('#selected-processor-type').text(processorType.type); + + addProcessor(); + }; + + // register a handler for double click events + grid.onDblClick.subscribe(gridDoubleClick); + + // update the button model + this.modal.update('setButtonModel', [{ + buttonText: 'Add', + handler: { + click: addProcessor + } + }, { + buttonText: 'Cancel', + handler: { + click: function () { + $('#new-processor-dialog').modal('hide'); + } + } + }]); + + // set a new handler for closing the the dialog + this.modal.update('setHandler', { + close: function () { + // remove the handler + grid.onDblClick.unsubscribe(gridDoubleClick); + + // clear the current filters + resetProcessorDialog(); + } + }); + + // show the dialog + this.modal.show(); + + // setup the filter + $('#processor-type-filter').focus().off('keyup').on('keyup', function (e) { + var code = e.keyCode ? e.keyCode : e.which; + if (code === $.ui.keyCode.ENTER) { + addProcessor(); + } else { + applyFilter(); + } + }); + + // adjust the grid canvas now that its been rendered + grid.resizeCanvas(); + grid.setSelectedRows([0]); + } + }; + var processorComponent = new ProcessorComponent(); + return processorComponent; + } + + ProcessorComponent.$inject = ['serviceProvider']; + + return ProcessorComponent; +}()); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi/blob/1df8fe44/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-remote-process-group-component.js ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-remote-process-group-component.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-remote-process-group-component.js new file mode 100644 index 0000000..3588e85 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-remote-process-group-component.js @@ -0,0 +1,212 @@ +/* + * 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 nf, d3 */ + +nf.ng.RemoteProcessGroupComponent = (function () { + + function RemoteProcessGroupComponent(serviceProvider) { + + /** + * Create the controller and add to the graph. + * + * @argument {string} remoteProcessGroupUri The remote group uri. + * @argument {object} pt The point that the remote group was dropped. + */ + var createRemoteProcessGroup = function (remoteProcessGroupUri, pt) { + var remoteProcessGroupEntity = { + 'revision': nf.Client.getRevision(), + 'component': { + 'targetUri': remoteProcessGroupUri, + 'position': { + 'x': pt.x, + 'y': pt.y + } + } + }; + + // create a new processor of the defined type + $.ajax({ + type: 'POST', + url: serviceProvider.headerCtrl.toolboxCtrl.config.urls.api + '/process-groups/' + encodeURIComponent(nf.Canvas.getGroupId()) + '/remote-process-groups', + data: JSON.stringify(remoteProcessGroupEntity), + dataType: 'json', + contentType: 'application/json' + }).done(function (response) { + if (nf.Common.isDefinedAndNotNull(response.component)) { + // update the revision + nf.Client.setRevision(response.revision); + + // add the processor to the graph + nf.Graph.add({ + 'remoteProcessGroups': [response] + }, true); + + // update component visibility + nf.Canvas.View.updateVisibility(); + + // update the birdseye + nf.Birdseye.refresh(); + } + }).fail(nf.Common.handleAjaxError); + }; + + function RemoteProcessGroupComponent() { + }; + RemoteProcessGroupComponent.prototype = { + constructor: RemoteProcessGroupComponent, + + /** + * The remote group component's modal. + */ + modal: { + + /** + * Gets the modal element. + * + * @returns {*|jQuery|HTMLElement} + */ + getElement: function () { + return $('#new-remote-process-group-dialog'); + }, + + /** + * Initialize the modal. + */ + init: function () { + // configure the new remote process group dialog + this.getElement().modal({ + headerText: 'Add Remote Process Group', + overlayBackground: false, + handler: { + close: function () { + $('#new-remote-process-group-uri').val(''); + } + } + }); + }, + + /** + * Updates the modal config. + * + * @param {string} name The name of the property to update. + * @param {object|array} config The config for the `name`. + */ + update: function (name, config) { + this.getElement().modal(name, config); + }, + + /** + * Show the modal. + */ + show: function () { + this.getElement().modal('show'); + }, + + /** + * Hide the modal. + */ + hide: function () { + this.getElement().modal('hide'); + } + }, + + /** + * Gets the component. + * + * @returns {*|jQuery|HTMLElement} + */ + getElement: function () { + return $('#group-remote-component'); + }, + + /** + * Enable the component. + */ + enabled: function () { + this.getElement().attr('disabled', false); + }, + + /** + * Disable the component. + */ + disabled: function () { + this.getElement().attr('disabled', true); + }, + + /** + * Handler function for when component is dropped on the canvas. + * + * @argument {object} pt The point that the component was dropped. + */ + dropHandler: function (pt) { + this.promptForRemoteProcessGroupUri(pt); + }, + + /** + * Prompts the user to enter the URI for the remote process group. + * + * @argument {object} pt The point that the remote group was dropped. + */ + promptForRemoteProcessGroupUri: function (pt) { + var self = this; + var addRemoteProcessGroup = function () { + // get the uri of the controller and clear the textfield + var remoteProcessGroupUri = $('#new-remote-process-group-uri').val(); + + // hide the dialog + self.modal.hide(); + + // create the remote process group + createRemoteProcessGroup(remoteProcessGroupUri, pt); + }; + + this.modal.update('setButtonModel', [{ + buttonText: 'Add', + handler: { + click: addRemoteProcessGroup + } + }, { + buttonText: 'Cancel', + handler: { + click: function () { + self.modal.hide(); + ; + } + } + }]); + + // show the dialog + this.modal.show(); + + // set the focus and key handlers + $('#new-remote-process-group-uri').focus().off('keyup').on('keyup', function (e) { + var code = e.keyCode ? e.keyCode : e.which; + if (code === $.ui.keyCode.ENTER) { + addRemoteProcessGroup(); + } + }); + } + }; + var remoteProcessGroupComponent = new RemoteProcessGroupComponent(); + return remoteProcessGroupComponent; + } + + RemoteProcessGroupComponent.$inject = ['serviceProvider']; + + return RemoteProcessGroupComponent; +}()); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi/blob/1df8fe44/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-template-component.js ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-template-component.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-template-component.js new file mode 100644 index 0000000..96523df --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/header/components/nf-ng-template-component.js @@ -0,0 +1,221 @@ +/* + * 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 nf, d3 */ + +nf.ng.TemplateComponent = (function () { + + function TemplateComponent(serviceProvider) { + + /** + * Instantiates the specified template. + * + * @argument {string} templateId The template id. + * @argument {object} pt The point that the template was dropped. + */ + var createTemplate = function (templateId, pt) { + var instantiateTemplateInstance = { + 'revision': nf.Client.getRevision(), + 'templateId': templateId, + 'originX': pt.x, + 'originY': pt.y + }; + + // create a new instance of the new template + $.ajax({ + type: 'POST', + url: serviceProvider.headerCtrl.toolboxCtrl.config.urls.api + '/process-groups/' + encodeURIComponent(nf.Canvas.getGroupId()) + '/template-instance', + data: JSON.stringify(instantiateTemplateInstance), + dataType: 'json', + contentType: 'application/json' + }).done(function (response) { + // update the revision + nf.Client.setRevision(response.revision); + + // populate the graph accordingly + nf.Graph.add(response.flow, true); + + // update component visibility + nf.Canvas.View.updateVisibility(); + + // update the birdseye + nf.Birdseye.refresh(); + }).fail(nf.Common.handleAjaxError); + }; + + function TemplateComponent() { + }; + TemplateComponent.prototype = { + constructor: TemplateComponent, + + /** + * The template component's modal. + */ + modal: { + + /** + * Gets the modal element. + * + * @returns {*|jQuery|HTMLElement} + */ + getElement: function () { + return $('#instantiate-template-dialog'); + }, + + /** + * Initialize the modal. + */ + init: function () { + // configure the instantiate template dialog + this.getElement().modal({ + headerText: 'Instantiate Template', + overlayBackgroud: false + }); + }, + + /** + * Updates the modal config. + * + * @param {string} name The name of the property to update. + * @param {object|array} config The config for the `name`. + */ + update: function (name, config) { + this.getElement().modal(name, config); + }, + + /** + * Show the modal. + */ + show: function () { + this.getElement().modal('show'); + }, + + /** + * Hide the modal. + */ + hide: function () { + this.getElement().modal('hide'); + } + }, + + /** + * Gets the component. + * + * @returns {*|jQuery|HTMLElement} + */ + getElement: function () { + return $('#template-component'); + }, + + /** + * Enable the component. + */ + enabled: function () { + this.getElement().attr('disabled', false); + }, + + /** + * Disable the component. + */ + disabled: function () { + this.getElement().attr('disabled', true); + }, + + /** + * Handler function for when component is dropped on the canvas. + * + * @argument {object} pt The point that the component was dropped. + */ + dropHandler: function (pt) { + this.promptForTemplate(pt); + }, + + /** + * Prompts the user to select a template. + * + * @argument {object} pt The point that the template was dropped. + */ + promptForTemplate: function (pt) { + var self = this; + $.ajax({ + type: 'GET', + url: serviceProvider.headerCtrl.toolboxCtrl.config.urls.api + '/process-groups/' + encodeURIComponent(nf.Canvas.getGroupId()) + '/templates', + dataType: 'json' + }).done(function (response) { + var templates = response.templates; + if (nf.Common.isDefinedAndNotNull(templates) && templates.length > 0) { + var options = []; + $.each(templates, function (_, template) { + options.push({ + text: template.name, + value: template.id, + description: nf.Common.escapeHtml(template.description) + }); + }); + + // configure the templates combo + $('#available-templates').combo({ + maxHeight: 300, + options: options + }); + + // update the button model + self.modal.update('setButtonModel', [{ + buttonText: 'Add', + handler: { + click: function () { + // get the type of processor currently selected + var selectedOption = $('#available-templates').combo('getSelectedOption'); + var templateId = selectedOption.value; + + // hide the dialog + self.modal.hide(); + + // instantiate the specified template + createTemplate(templateId, pt); + } + } + }, { + buttonText: 'Cancel', + handler: { + click: function () { + self.modal.hide(); + } + } + }]); + + // show the dialog + self.modal.show(); + } else { + nf.Dialog.showOkDialog({ + headerText: 'Instantiate Template', + dialogContent: 'No templates have been loaded into this NiFi.', + overlayBackground: false + }); + } + + }).fail(nf.Common.handleAjaxError); + } + }; + var templateComponent = new TemplateComponent(); + return templateComponent; + } + + TemplateComponent.$inject = ['serviceProvider']; + + return TemplateComponent; +}()); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi/blob/1df8fe44/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js index 59f56fc..9d90a61 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js @@ -49,9 +49,6 @@ nf.Actions = (function () { $('#drop-request-status-dialog').modal('setButtonModel', []); } } - }).draggable({ - containment: 'parent', - handle: '.dialog-header' }); }; @@ -418,10 +415,10 @@ nf.Actions = (function () { })); }); - // refresh the toolbar once the updates have completed + // inform Angular app once the updates have completed if (enableRequests.length > 0) { $.when.apply(window, enableRequests).always(function () { - nf.CanvasToolbar.refresh(); + nf.ng.Bridge.digest(); }); } } @@ -460,10 +457,10 @@ nf.Actions = (function () { })); }); - // refresh the toolbar once the updates have completed + // inform Angular app once the updates have completed if (disableRequests.length > 0) { $.when.apply(window, disableRequests).always(function () { - nf.CanvasToolbar.refresh(); + nf.ng.Bridge.digest(); }); } } @@ -549,10 +546,10 @@ nf.Actions = (function () { })); }); - // refresh the toolbar once the updates have completed + // inform Angular app once the updates have completed if (startRequests.length > 0) { $.when.apply(window, startRequests).always(function () { - nf.CanvasToolbar.refresh(); + nf.ng.Bridge.digest(); }); } } @@ -623,10 +620,10 @@ nf.Actions = (function () { })); }); - // refresh the toolbar once the updates have completed + // inform Angular app once the updates have completed if (stopRequests.length > 0) { $.when.apply(window, stopRequests).always(function () { - nf.CanvasToolbar.refresh(); + nf.ng.Bridge.digest(); }); } } @@ -823,9 +820,10 @@ nf.Actions = (function () { } } - // refresh the birdseye/toolbar + // refresh the birdseye nf.Birdseye.refresh(); - nf.CanvasToolbar.refresh(); + // inform Angular app values have changed + nf.ng.Bridge.digest(); }).fail(nf.Common.handleAjaxError); } else { // create a snippet for the specified component and link to the data flow @@ -873,9 +871,10 @@ nf.Actions = (function () { nf.Connection.remove(components.get('Connection')); } - // refresh the birdseye/toolbar + // refresh the birdseye nf.Birdseye.refresh(); - nf.CanvasToolbar.refresh(); + // inform Angular app values have changed + nf.ng.Bridge.digest(); }).fail(function (xhr, status, error) { // unable to acutally remove the components so attempt to // unlink and remove just the snippet - if unlinking fails @@ -1158,7 +1157,7 @@ nf.Actions = (function () { var origin = nf.CanvasUtils.getOrigin(selection); var pt = {'x': origin.x, 'y': origin.y}; - $.when(nf.CanvasToolbox.promptForGroupName(pt)).done(function (processGroup) { + $.when(nf.ng.Bridge.get('appCtrl.serviceProvider.headerCtrl.toolboxCtrl.groupComponent').promptForGroupName(pt)).done(function (processGroup) { var group = d3.select('#id-' + processGroup.id); nf.CanvasUtils.moveComponents(selection, group); }); http://git-wip-us.apache.org/repos/asf/nifi/blob/1df8fe44/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-birdseye.js ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-birdseye.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-birdseye.js index 1b23262..9cbe228 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-birdseye.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-birdseye.js @@ -119,17 +119,17 @@ nf.Birdseye = (function () { // update the brush d3.select('rect.birdseye-brush') - .attr({ - 'width': screenWidth, - 'height': screenHeight, - 'stroke-width': (2 / birdseyeScale), - 'transform': function (d) { - d.x = brushTranslate[0]; - d.y = brushTranslate[1]; - - return 'translate(' + brushTranslate + ')'; - } - }); + .attr({ + 'width': screenWidth, + 'height': screenHeight, + 'stroke-width': (2 / birdseyeScale), + 'transform': function (d) { + d.x = brushTranslate[0]; + d.y = brushTranslate[1]; + + return 'translate(' + brushTranslate + ')'; + } + }); // redraw the canvas var canvasElement = d3.select('#birdseye-canvas').node(); @@ -183,7 +183,7 @@ nf.Birdseye = (function () { // process groups context.fillStyle = '#294c58'; $.each(components.processGroups, function (_, d) { - context.fillRect(d.x, d.y, d.dimensions.width, d.dimensions.height); + context.fillRect(d.position.x, d.position.y, d.dimensions.width, d.dimensions.height); }); // processors @@ -198,7 +198,7 @@ nf.Birdseye = (function () { } context.fillStyle = color; - context.fillRect(d.x, d.y, d.dimensions.width, d.dimensions.height); + context.fillRect(d.position.x, d.position.y, d.dimensions.width, d.dimensions.height); }); context.restore(); @@ -210,131 +210,89 @@ nf.Birdseye = (function () { return { init: function () { var birdseye = $('#birdseye'); - var birdseyeContainer = $('#birdseye-container'); - $('#birdseye-collapse').click(function () { - // update the outline collapse icon - if (birdseye.is(':visible')) { - $(this).removeClass('birdseye-expanded-hover').addClass('birdseye-collapsed-hover'); - - // hide the outline - birdseye.hide(); - birdseyeContainer.hide(); - visible = false; - - // shift the counts position - $('#controller-counts').css('margin-right', '-13px'); - } else { - $(this).removeClass('birdseye-collapsed-hover').addClass('birdseye-expanded-hover'); - - // shift the counts position - $('#controller-counts').css('margin-right', '195px'); - - // show the outline - birdseye.show(); - birdseyeContainer.show(); - visible = true; - - // refresh the birdseye as it may have changed - refresh(nf.Graph.get()); - } - }).mouseover(function () { - // update the outline collapse icon - if (birdseye.is(':visible')) { - $(this).removeClass('birdseye-expanded').addClass('birdseye-expanded-hover'); - } else { - $(this).removeClass('birdseye-collapsed').addClass('birdseye-collapsed-hover'); - } - }).mouseout(function () { - // update the outline collapse icon - if (birdseye.is(':visible')) { - $(this).removeClass('birdseye-expanded-hover').addClass('birdseye-expanded'); - } else { - $(this).removeClass('birdseye-collapsed-hover').addClass('birdseye-collapsed'); - } - }); d3.select('#birdseye').append('canvas') - .attr('id', 'birdseye-canvas') - .attr('width', birdseye.width()) - .attr('height', birdseye.height()); + .attr('id', 'birdseye-canvas') + .attr('width', birdseye.width()) + .attr('height', birdseye.height()); // build the birdseye svg var svg = d3.select('#birdseye').append('svg') - .attr('width', birdseye.width()) - .attr('height', birdseye.height()); + .attr('width', birdseye.width()) + .attr('height', birdseye.height()); // group birdseye components together birdseyeGroup = svg.append('g') - .attr('class', 'birdseye'); + .attr('class', 'birdseye'); // processor in the birdseye componentGroup = birdseyeGroup.append('g') - .attr('pointer-events', 'none'); + .attr('pointer-events', 'none'); // define the brush drag behavior var brush = d3.behavior.drag() - .origin(function (d) { - return { - x: d.x, - y: d.y - }; - }) - .on('dragstart', function () { - // hide the context menu - nf.ContextMenu.hide(); - }) - .on('drag', function (d) { - d.x += d3.event.dx; - d.y += d3.event.dy; - - // update the location of the brush - d3.select(this).attr('transform', function () { - return 'translate(' + d.x + ', ' + d.y + ')'; - }); - // get the current transformation - var scale = nf.Canvas.View.scale(); - var translate = nf.Canvas.View.translate(); - - // update the translation according to the delta - translate = [(-d3.event.dx * scale) + translate[0], (-d3.event.dy * scale) + translate[1]]; - - // record the current transforms - nf.Canvas.View.translate(translate); - - // refresh the canvas - nf.Canvas.View.refresh({ - persist: false, - transition: false, - refreshComponents: false, - refreshBirdseye: false - }); - }) - .on('dragend', function () { - // update component visibility - nf.Canvas.View.updateVisibility(); - - // persist the users view - nf.CanvasUtils.persistUserView(); - - // refresh the birdseye - nf.Birdseye.refresh(); + .origin(function (d) { + return { + x: d.x, + y: d.y + }; + }) + .on('dragstart', function () { + // hide the context menu + nf.ContextMenu.hide(); + }) + .on('drag', function (d) { + d.x += d3.event.dx; + d.y += d3.event.dy; + + // update the location of the brush + d3.select(this).attr('transform', function () { + return 'translate(' + d.x + ', ' + d.y + ')'; }); + // get the current transformation + var scale = nf.Canvas.View.scale(); + var translate = nf.Canvas.View.translate(); + + // update the translation according to the delta + translate = [(-d3.event.dx * scale) + translate[0], (-d3.event.dy * scale) + translate[1]]; + + // record the current transforms + nf.Canvas.View.translate(translate); + + // refresh the canvas + nf.Canvas.View.refresh({ + persist: false, + transition: false, + refreshComponents: false, + refreshBirdseye: false + }); + }) + .on('dragend', function () { + // update component visibility + nf.Canvas.View.updateVisibility(); + + // persist the users view + nf.CanvasUtils.persistUserView(); + + // refresh the birdseye + nf.Birdseye.refresh(); + }); // context area birdseyeGroup.append('g') - .attr({ - 'pointer-events': 'all', - 'class': 'birdseye-brush-container' - }) - .append('rect') - .attr('class', 'birdseye-brush moveable') - .datum({ - x: 0, - y: 0 - }) - .call(brush); + .attr({ + 'pointer-events': 'all', + 'class': 'birdseye-brush-container' + }) + .append('rect') + .attr('class', 'birdseye-brush moveable') + .datum({ + x: 0, + y: 0 + }) + .call(brush); }, - + /** * Handles rendering of the birdseye tool. */ @@ -342,6 +300,29 @@ nf.Birdseye = (function () { if (visible) { refresh(nf.Graph.get()); } + }, + + /** + * Function that needs to be call when the birdseye visibility changes. + * + * @param {boolean} isVisible + */ + updateBirdseyeVisibility: function (isVisible) { + var birdseye = $('#birdseye'); + + // update the outline collapse icon + if (isVisible) { + // show the outline + birdseye.show(); + visible = true; + + // refresh the birdseye as it may have changed + refresh(nf.Graph.get()); + } else { + // hide the outline + birdseye.hide(); + visible = false; + } } }; }()); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi/blob/1df8fe44/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-header.js ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-header.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-header.js deleted file mode 100644 index fbe4b7d..0000000 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-header.js +++ /dev/null @@ -1,303 +0,0 @@ -/* - * 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 nf, d3 */ - -nf.CanvasHeader = (function () { - - var MIN_TOOLBAR_WIDTH = 640; - - var config = { - urls: { - helpDocument: '../nifi-docs/documentation' - } - }; - - return { - /** - * Initialize the canvas header. - * - * @argument {boolean} supportsLogin Whether login is supported - */ - init: function (supportsLogin) { - // mouse over for the reporting link - nf.Common.addHoverEffect('#reporting-link', 'reporting-link', 'reporting-link-hover').click(function () { - nf.Shell.showPage('summary'); - }); - - // mouse over for the counters link - nf.Common.addHoverEffect('#counters-link', 'counters-link', 'counters-link-hover').click(function () { - nf.Shell.showPage('counters'); - }); - - // mouse over for the history link - nf.Common.addHoverEffect('#history-link', 'history-link', 'history-link-hover').click(function () { - nf.Shell.showPage('history'); - }); - - // mouse over for the provenance link - if (nf.Common.canAccessProvenance()) { - nf.Common.addHoverEffect('#provenance-link', 'provenance-link', 'provenance-link-hover').click(function () { - nf.Shell.showPage('provenance'); - }); - } else { - $('#provenance-link').addClass('provenance-link-disabled'); - } - - // mouse over for the templates link - nf.Common.addHoverEffect('#templates-link', 'templates-link', 'templates-link-hover').click(function () { - nf.Shell.showPage('templates?' + $.param({ - groupId: nf.Canvas.getGroupId() - })); - }); - - // mouse over for the flow settings link - nf.Common.addHoverEffect('#flow-settings-link', 'flow-settings-link', 'flow-settings-link-hover').click(function () { - nf.Settings.loadSettings().done(function () { - nf.Settings.showSettings(); - }); - }); - - // mouse over for the cluster link - if (nf.Canvas.isClustered()) { - nf.Common.addHoverEffect('#cluster-link', 'cluster-link', 'cluster-link-hover').click(function () { - nf.Shell.showPage('cluster'); - }); - - // show the connected nodes - $('#connected-nodes-element').show(); - } else { - $('#cluster-link').hide(); - } - - // mouse over for the reporting link - nf.Common.addHoverEffect('#bulletin-board-link', 'bulletin-board-link', 'bulletin-board-hover').click(function () { - nf.Shell.showPage('bulletin-board'); - }); - - // setup the refresh link actions - $('#refresh-required-link').click(function () { - nf.CanvasHeader.reloadAndClearWarnings(); - }); - - // configure the about dialog - $('#nf-about').modal({ - overlayBackground: true, - buttons: [{ - buttonText: 'Ok', - handler: { - click: function () { - $('#nf-about').modal('hide'); - } - } - }] - }); - - // show about dialog - $('#about-link').click(function () { - $('#nf-about').modal('show'); - }); - - // download the help documentation - $('#help-link').click(function () { - nf.Shell.showPage(config.urls.helpDocument); - }); - - // login link - $('#login-link').click(function () { - nf.Shell.showPage('login', false); - }); - - // logout link - $('#logout-link').click(function () { - nf.Storage.removeItem("jwt"); - window.location = '/nifi'; - }); - - // if the user is not anonymous or accessing via http - if ($('#current-user').text() !== nf.Common.ANONYMOUS_USER_TEXT || location.protocol === 'http:') { - $('#login-link-container').css('display', 'none'); - } - - // if accessing via http, don't show the current user - if (location.protocol === 'http:') { - $('#current-user-container').css('display', 'none'); - } - - // initialize the new template dialog - $('#new-template-dialog').modal({ - headerText: 'Create Template', - overlayBackground: false - }); - - // configure the fill color dialog - $('#fill-color-dialog').modal({ - headerText: 'Fill', - overlayBackground: false, - buttons: [{ - buttonText: 'Apply', - handler: { - click: function () { - var selection = nf.CanvasUtils.getSelection(); - - // color the selected components - selection.each(function (d) { - var selected = d3.select(this); - var selectedData = selected.datum(); - - // get the color and update the styles - var color = $('#fill-color').minicolors('value'); - - // ensure the color actually changed - if (color !== selectedData.component.style['background-color']) { - // build the request entity - var entity = { - 'revision': nf.Client.getRevision(), - 'component': { - 'id': selectedData.id, - 'style': { - 'background-color': color - } - } - }; - - // update the style for the specified component - $.ajax({ - type: 'PUT', - url: selectedData.component.uri, - data: JSON.stringify(entity), - dataType: 'json', - contentType: 'application/json' - }).done(function (response) { - // update the revision - nf.Client.setRevision(response.revision); - - // update the component - nf[selectedData.type].set(response); - }).fail(function (xhr, status, error) { - if (xhr.status === 400 || xhr.status === 404 || xhr.status === 409) { - nf.Dialog.showOkDialog({ - dialogContent: nf.Common.escapeHtml(xhr.responseText), - overlayBackground: true - }); - } - }); - } - }); - - // close the dialog - $('#fill-color-dialog').modal('hide'); - } - } - }, { - buttonText: 'Cancel', - handler: { - click: function () { - // close the dialog - $('#fill-color-dialog').modal('hide'); - } - } - }], - handler: { - close: function () { - // clear the current color - $('#fill-color-value').val(''); - $('#fill-color').minicolors('value', ''); - } - } - }).draggable({ - containment: 'parent', - handle: '.dialog-header' - }); - - // initialize the fill color picker - $('#fill-color').minicolors({ - inline: true, - change: function (hex, opacity) { - // update the value - $('#fill-color-value').val(hex); - - // always update the preview - $('#fill-color-processor-preview, #fill-color-label-preview').css({ - 'border-color': hex, - 'background': 'linear-gradient(to bottom, #ffffff, ' + hex + ')', - 'filter': 'progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr=#ffffff, endColorstr=' + hex + ')' - }); - } - }); - - // updates the color if its a valid hex color string - var updateColor = function () { - var hex = $('#fill-color-value').val(); - - // only update the fill color when its a valid hex color string - // #[six hex characters|three hex characters] case insensitive - if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(hex)) { - $('#fill-color').minicolors('value', hex); - } - }; - - // apply fill color from field on blur and enter press - $('#fill-color-value').on('blur', updateColor).on('keyup', function (e) { - var code = e.keyCode ? e.keyCode : e.which; - if (code === $.ui.keyCode.ENTER) { - updateColor(); - } - }); - - var toolbar = $('#toolbar'); - var groupButton = $('#action-group'); - $(window).on('resize', function () { - if (toolbar.width() < MIN_TOOLBAR_WIDTH && groupButton.is(':visible')) { - toolbar.find('.secondary').hide(); - } else if (toolbar.width() > MIN_TOOLBAR_WIDTH && groupButton.is(':hidden')) { - toolbar.find('.secondary').show(); - } - }); - - // set up the initial visibility - if (toolbar.width() < MIN_TOOLBAR_WIDTH) { - toolbar.find('.secondary').hide(); - } - }, - /** - * Reloads and clears any warnings. - */ - reloadAndClearWarnings: function () { - nf.Canvas.reload().done(function () { - // update component visibility - nf.Canvas.View.updateVisibility(); - - // refresh the birdseye - nf.Birdseye.refresh(); - - // hide the refresh link on the canvas - $('#stats-last-refreshed').removeClass('alert'); - $('#refresh-required-container').hide(); - - // hide the refresh link on the settings - $('#settings-last-refreshed').removeClass('alert'); - $('#settings-refresh-required-icon').hide(); - }).fail(function () { - nf.Dialog.showOkDialog({ - dialogContent: 'Unable to refresh the current group.', - overlayBackground: true - }); - }); - } - }; -}()); \ No newline at end of file