From 9507f2f8d2ec616f01f5ee8825106300b95e8ddc Mon Sep 17 00:00:00 2001 From: Andrew Gauld Date: Fri, 7 Feb 2020 15:00:39 +0000 Subject: Add DCAE MOD design tool project Change-Id: I660b28ebfaa7e4b5f03a1df5fd17d126f58b7c14 Issue-ID: DCAEGEN2-1860 Signed-off-by: Andrew Gauld --- .../header/components/nf-ng-processor-component.js | 1150 ++++++++++++++++++++ 1 file changed, 1150 insertions(+) create mode 100644 mod/designtool/designtool-web/src/main/webapp/js/nf/canvas/header/components/nf-ng-processor-component.js (limited to 'mod/designtool/designtool-web/src/main/webapp/js/nf/canvas/header/components/nf-ng-processor-component.js') diff --git a/mod/designtool/designtool-web/src/main/webapp/js/nf/canvas/header/components/nf-ng-processor-component.js b/mod/designtool/designtool-web/src/main/webapp/js/nf/canvas/header/components/nf-ng-processor-component.js new file mode 100644 index 0000000..0f4b953 --- /dev/null +++ b/mod/designtool/designtool-web/src/main/webapp/js/nf/canvas/header/components/nf-ng-processor-component.js @@ -0,0 +1,1150 @@ +/* + * 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. + * + * Modifications to the original nifi code for the ONAP project are made + * available under the Apache License, Version 2.0 + */ + +/* global define, module, require, exports */ + +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery', + 'Slick', + 'nf.Client', + 'nf.Birdseye', + 'nf.Storage', + 'nf.Graph', + 'nf.CanvasUtils', + 'nf.ErrorHandler', + 'nf.FilteredDialogCommon', + 'nf.Dialog', + 'nf.Common'], + function ($, Slick, nfClient, nfBirdseye, nfStorage, nfGraph, nfCanvasUtils, nfErrorHandler, nfFilteredDialogCommon, nfDialog, nfCommon) { + return (nf.ng.ProcessorComponent = factory($, Slick, nfClient, nfBirdseye, nfStorage, nfGraph, nfCanvasUtils, nfErrorHandler, nfFilteredDialogCommon, nfDialog, nfCommon)); + }); + } else if (typeof exports === 'object' && typeof module === 'object') { + module.exports = (nf.ng.ProcessorComponent = + factory(require('jquery'), + require('Slick'), + require('nf.Client'), + require('nf.Birdseye'), + require('nf.Storage'), + require('nf.Graph'), + require('nf.CanvasUtils'), + require('nf.ErrorHandler'), + require('nf.FilteredDialogCommon'), + require('nf.Dialog'), + require('nf.Common'))); + } else { + nf.ng.ProcessorComponent = factory(root.$, + root.Slick, + root.nf.Client, + root.nf.Birdseye, + root.nf.Storage, + root.nf.Graph, + root.nf.CanvasUtils, + root.nf.ErrorHandler, + root.nf.FilteredDialogCommon, + root.nf.Dialog, + root.nf.Common); + } +}(this, function ($, Slick, nfClient, nfBirdseye, nfStorage, nfGraph, nfCanvasUtils, nfErrorHandler, nfFilteredDialogCommon, nfDialog, nfCommon) { + 'use strict'; + + return function (serviceProvider) { + 'use strict'; + + + var latestResponse; + + var processorTypesData; + + + /** + * 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 (nfCommon.isDefinedAndNotNull(processorTypesGrid)) { + var processorTypesDataForFilter = processorTypesGrid.getData(); + + // update the search criteria + processorTypesDataForFilter.setFilterArgs({ + searchString: getFilterText() + }); + processorTypesDataForFilter.refresh(); + + // update the buttons to possibly trigger the disabled state + $('#new-processor-dialog').modal('refreshButtons'); + + // update the selection if possible + if (processorTypesDataForFilter.getLength() > 0) { + nfFilteredDialogCommon.choseFirstRow(processorTypesGrid); + // make the first row visible + processorTypesGrid.scrollRowToTop(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 the row matches the selected source group + var matchesGroup = true; + if (matchesFilter && matchesTags) { + var bundleGroup = $('#processor-bundle-group-combo').combo('getSelectedOption'); + if (nfCommon.isDefinedAndNotNull(bundleGroup) && bundleGroup.value !== '') { + matchesGroup = (item.bundle.group === bundleGroup.value); + } + } + + // determine if this row should be visible + var matches = matchesFilter && matchesTags && matchesGroup; + + // 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').attr('title', '').text(''); + $('#processor-type-name').attr('title', '').text(''); + $('#processor-type-bundle').attr('title', '').text(''); + $('#selected-processor-name').text(''); + $('#selected-processor-type').text('').removeData('bundle'); + + // 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; + }; + + /** + * 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 () { + return $('#processor-type-filter').val(); + }; + + /** + * Resets the filtered processor types. + */ + var resetProcessorDialog = function () { + + //********* REPLICATED A BLOCK OF CODE to get logic of autoloading processor ---STARTING FROM HERE----******************** + + // initialize the processor type table + var processorTypesColumns = [ + { + id: 'type', + name: 'Type', + field: 'label', + formatter: nfCommon.typeFormatter, + sortable: true, + resizable: true + }, + { + id: 'version', + name: 'Version', + field: 'version', + formatter: nfCommon.typeVersionFormatter, + sortable: true, + resizable: true + }, + { + id: 'tags', + name: 'Tags', + field: 'tags', + sortable: true, + resizable: true, + formatter: nfCommon.genericValueFormatter + } + ]; + + var processorTypesOptions = { + forceFitColumns: true, + enableTextSelectionOnCells: true, + enableCellNavigation: true, + enableColumnReorder: false, + autoEdit: false, + multiSelect: false, + rowHeight: 24 + }; + + // initialize the dataview + processorTypesData = new Slick.Data.DataView({ + inlineFilters: false + }); + processorTypesData.setItems([]); + processorTypesData.setFilterArgs({ + searchString: getFilterText() + }); + processorTypesData.setFilter(filter); + + // initialize the sort + nfCommon.sortType({ + 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) { + nfCommon.sortType({ + 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 (nfCommon.isDefinedAndNotNull(processorType)) { + if (nfCommon.isBlank(processorType.description)) { + $('#processor-type-description') + .attr('title', '') + .html('No description specified'); + } else { + $('#processor-type-description') + .width($('#processor-description-container').innerWidth() - 1) + .html(processorType.description) + .ellipsis(); + } + + var bundle = nfCommon.formatBundle(processorType.bundle); + var type = nfCommon.formatType(processorType); + + // populate the dom + $('#processor-type-name').text(type).attr('title', type); + $('#processor-type-bundle').text(bundle).attr('title', bundle); + $('#selected-processor-name').text(processorType.label); + $('#selected-processor-type').text(processorType.type).data('bundle', processorType.bundle); + + // refresh the buttons based on the current selection + $('#new-processor-dialog').modal('refreshButtons'); + } + } + }); + processorTypesGrid.onViewportChanged.subscribe(function (e, args) { + nfCommon.cleanUpTooltips($('#processor-types-table'), 'div.view-usage-restriction'); + }); + + // 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).on('mouseenter', 'div.slick-cell', function (e) { + var usageRestriction = $(this).find('div.view-usage-restriction'); + if (usageRestriction.length && !usageRestriction.data('qtip')) { + var rowId = $(this).find('span.row-id').text(); + + // get the status item + var item = processorTypesData.getItemById(rowId); + + // show the tooltip + if (item.restricted === true) { + var restrictionTip = $('
'); + + if (nfCommon.isBlank(item.usageRestriction)) { + restrictionTip.append($('

').text('Requires the following permissions:')); + } else { + restrictionTip.append($('

').text(item.usageRestriction + ' Requires the following permissions:')); + } + + var restrictions = []; + if (nfCommon.isDefinedAndNotNull(item.explicitRestrictions)) { + $.each(item.explicitRestrictions, function (_, explicitRestriction) { + var requiredPermission = explicitRestriction.requiredPermission; + restrictions.push("'" + requiredPermission.label + "' - " + nfCommon.escapeHtml(explicitRestriction.explanation)); + }); + } else { + restrictions.push('Access to restricted components regardless of restrictions.'); + } + restrictionTip.append(nfCommon.formatUnorderedList(restrictions)); + + usageRestriction.qtip($.extend({}, nfCommon.config.tooltipConfig, { + content: restrictionTip, + position: { + container: $('#summary'), + at: 'bottom right', + my: 'top left', + adjust: { + x: 4, + y: 4 + } + } + })); + } + } + }); + + var generalRestriction = nfCommon.getPolicyTypeListing('restricted-components'); + + // 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:'../nifi-api/flow/processor-types', + // url: serviceProvider.headerCtrl.toolboxCtrl.config.urls.processorTypes, + dataType: 'json' + }).done(function (response) { + console.log(response); + var tags = []; + var groups = d3.set(); + var restrictedUsage = d3.map(); + var requiredPermissions = d3.map(); + + // begin the update + processorTypesData.beginUpdate(); + + // go through each processor type + $.each(response.processorTypes, function (i, documentedType) { + var type = documentedType.type; + + if (documentedType.restricted === true) { + if (nfCommon.isDefinedAndNotNull(documentedType.explicitRestrictions)) { + $.each(documentedType.explicitRestrictions, function (_, explicitRestriction) { + var requiredPermission = explicitRestriction.requiredPermission; + + // update required permissions + if (!requiredPermissions.has(requiredPermission.id)) { + requiredPermissions.set(requiredPermission.id, requiredPermission.label); + } + + // update component restrictions + if (!restrictedUsage.has(requiredPermission.id)) { + restrictedUsage.set(requiredPermission.id, []); + } + + restrictedUsage.get(requiredPermission.id).push({ + type: nfCommon.formatType(documentedType), + bundle: nfCommon.formatBundle(documentedType.bundle), + explanation: nfCommon.escapeHtml(explicitRestriction.explanation) + }) + }); + } else { + // update required permissions + if (!requiredPermissions.has(generalRestriction.value)) { + requiredPermissions.set(generalRestriction.value, generalRestriction.text); + } + + // update component restrictions + if (!restrictedUsage.has(generalRestriction.value)) { + restrictedUsage.set(generalRestriction.value, []); + } + + restrictedUsage.get(generalRestriction.value).push({ + type: nfCommon.formatType(documentedType), + bundle: nfCommon.formatBundle(documentedType.bundle), + explanation: nfCommon.escapeHtml(documentedType.usageRestriction) + }); + } + } + + // record the group + groups.add(documentedType.bundle.group); + + // create the row for the processor type + processorTypesData.addItem({ + id: i, + label: nfCommon.substringAfterLast(type, '.'), + type: type, + bundle: documentedType.bundle, + description: nfCommon.escapeHtml(documentedType.description), + restricted: documentedType.restricted, + usageRestriction: nfCommon.escapeHtml(documentedType.usageRestriction), + explicitRestrictions: documentedType.explicitRestrictions, + 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 update + processorTypesData.endUpdate(); + + // resort + processorTypesData.reSort(); + processorTypesGrid.invalidate(); + + // set the component restrictions and the corresponding required permissions + nfCanvasUtils.addComponentRestrictions(restrictedUsage, requiredPermissions); + + // 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 + }); + + // build the combo options + var options = [{ + text: 'all groups', + value: '' + }]; + groups.each(function (group) { + options.push({ + text: group, + value: group + }); + }); + + // initialize the bundle group combo + $('#processor-bundle-group-combo').combo({ + options: options, + select: applyFilter + }); + }).fail(nfErrorHandler.handleAjaxError); + +//************* REPLICATED CODE---ENDS HERE------****************** + + + + // clear the selected tag cloud + $('#processor-tag-cloud').tagcloud('clearSelectedTags'); + + // reset the group combo + $('#processor-bundle-group-combo').combo('setSelectedOption', { + value: '' + }); + + // clear any filter strings + $('#processor-type-filter').val(''); + + // reapply the filter + applyFilter(); + + // clear the selected row + $('#processor-type-description').attr('title', '').text(''); + $('#processor-type-name').attr('title', '').text(''); + $('#processor-type-bundle').attr('title', '').text(''); + $('#selected-processor-name').text(''); + $('#selected-processor-type').text('').removeData('bundle'); + + // 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} bundle The processor bundle. + * @argument {object} pt The point that the processor was dropped. + */ + var createProcessor = function (name, processorType, bundle, pt) { + var processorEntity = { + 'revision': nfClient.getRevision({ + 'revision': { + 'version': 0 + } + }), + 'disconnectedNodeAcknowledged': nfStorage.isDisconnectionAcknowledged(), + 'component': { + 'type': processorType, + 'bundle': bundle, + '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(nfCanvasUtils.getGroupId()) + '/processors', + data: JSON.stringify(processorEntity), + dataType: 'json', + contentType: 'application/json' + }).done(function (response) { + // add the processor to the graph + nfGraph.add({ + 'processors': [response] + }, { + 'selectAll': true + }); + + // update component visibility + nfGraph.updateVisibility(); + + // update the birdseye + nfBirdseye.refresh(); + }).fail(nfErrorHandler.handleAjaxError); + }; + + /** + * Whether the specified item is selectable. + * + * @param item process type + */ + var isSelectable = function (item) { + return item.restricted === false || nfCommon.canAccessComponentRestrictions(item.explicitRestrictions); + }; + + function ProcessorComponent() { + + this.icon = 'icon icon-processor'; + + this.hoverIcon = 'icon icon-processor-add'; + + /** + * The processor component's modal. + */ + this.modal = { + + /** + * The processor component modal's filter. + */ + filter: { + + /** + * Initialize the filter. + */ + init: function () { + // initialize the processor type table + var processorTypesColumns = [ + { + id: 'type', + name: 'Type', + field: 'label', + formatter: nfCommon.typeFormatter, + sortable: true, + resizable: true + }, + { + id: 'version', + name: 'Version', + field: 'version', + formatter: nfCommon.typeVersionFormatter, + sortable: true, + resizable: true + }, + { + id: 'tags', + name: 'Tags', + field: 'tags', + sortable: true, + resizable: true, + formatter: nfCommon.genericValueFormatter + } + ]; + + var processorTypesOptions = { + forceFitColumns: true, + enableTextSelectionOnCells: true, + enableCellNavigation: true, + enableColumnReorder: false, + autoEdit: false, + multiSelect: false, + rowHeight: 24 + }; + + // initialize the dataview + processorTypesData = new Slick.Data.DataView({ + inlineFilters: false + }); + processorTypesData.setItems([]); + processorTypesData.setFilterArgs({ + searchString: getFilterText() + }); + processorTypesData.setFilter(filter); + + // initialize the sort + nfCommon.sortType({ + 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) { + nfCommon.sortType({ + 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 (nfCommon.isDefinedAndNotNull(processorType)) { + if (nfCommon.isBlank(processorType.description)) { + $('#processor-type-description') + .attr('title', '') + .html('No description specified'); + } else { + $('#processor-type-description') + .width($('#processor-description-container').innerWidth() - 1) + .html(processorType.description) + .ellipsis(); + } + + var bundle = nfCommon.formatBundle(processorType.bundle); + var type = nfCommon.formatType(processorType); + + // populate the dom + $('#processor-type-name').text(type).attr('title', type); + $('#processor-type-bundle').text(bundle).attr('title', bundle); + $('#selected-processor-name').text(processorType.label); + $('#selected-processor-type').text(processorType.type).data('bundle', processorType.bundle); + + // refresh the buttons based on the current selection + $('#new-processor-dialog').modal('refreshButtons'); + } + } + }); + processorTypesGrid.onViewportChanged.subscribe(function (e, args) { + nfCommon.cleanUpTooltips($('#processor-types-table'), 'div.view-usage-restriction'); + }); + + // 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).on('mouseenter', 'div.slick-cell', function (e) { + var usageRestriction = $(this).find('div.view-usage-restriction'); + if (usageRestriction.length && !usageRestriction.data('qtip')) { + var rowId = $(this).find('span.row-id').text(); + + // get the status item + var item = processorTypesData.getItemById(rowId); + + // show the tooltip + if (item.restricted === true) { + var restrictionTip = $('
'); + + if (nfCommon.isBlank(item.usageRestriction)) { + restrictionTip.append($('

').text('Requires the following permissions:')); + } else { + restrictionTip.append($('

').text(item.usageRestriction + ' Requires the following permissions:')); + } + + var restrictions = []; + if (nfCommon.isDefinedAndNotNull(item.explicitRestrictions)) { + $.each(item.explicitRestrictions, function (_, explicitRestriction) { + var requiredPermission = explicitRestriction.requiredPermission; + restrictions.push("'" + requiredPermission.label + "' - " + nfCommon.escapeHtml(explicitRestriction.explanation)); + }); + } else { + restrictions.push('Access to restricted components regardless of restrictions.'); + } + restrictionTip.append(nfCommon.formatUnorderedList(restrictions)); + + usageRestriction.qtip($.extend({}, nfCommon.config.tooltipConfig, { + content: restrictionTip, + position: { + container: $('#summary'), + at: 'bottom right', + my: 'top left', + adjust: { + x: 4, + y: 4 + } + } + })); + } + } + }); + + var generalRestriction = nfCommon.getPolicyTypeListing('restricted-components'); + + // 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:'../nifi-api/flow/processor-types', +// url: serviceProvider.headerCtrl.toolboxCtrl.config.urls.processorTypes, + dataType: 'json' + }).done(function (response) { + console.log(response); + var tags = []; + var groups = d3.set(); + var restrictedUsage = d3.map(); + var requiredPermissions = d3.map(); + + // begin the update + processorTypesData.beginUpdate(); + + // go through each processor type + $.each(response.processorTypes, function (i, documentedType) { + var type = documentedType.type; + + if (documentedType.restricted === true) { + if (nfCommon.isDefinedAndNotNull(documentedType.explicitRestrictions)) { + $.each(documentedType.explicitRestrictions, function (_, explicitRestriction) { + var requiredPermission = explicitRestriction.requiredPermission; + + // update required permissions + if (!requiredPermissions.has(requiredPermission.id)) { + requiredPermissions.set(requiredPermission.id, requiredPermission.label); + } + + // update component restrictions + if (!restrictedUsage.has(requiredPermission.id)) { + restrictedUsage.set(requiredPermission.id, []); + } + + restrictedUsage.get(requiredPermission.id).push({ + type: nfCommon.formatType(documentedType), + bundle: nfCommon.formatBundle(documentedType.bundle), + explanation: nfCommon.escapeHtml(explicitRestriction.explanation) + }) + }); + } else { + // update required permissions + if (!requiredPermissions.has(generalRestriction.value)) { + requiredPermissions.set(generalRestriction.value, generalRestriction.text); + } + + // update component restrictions + if (!restrictedUsage.has(generalRestriction.value)) { + restrictedUsage.set(generalRestriction.value, []); + } + + restrictedUsage.get(generalRestriction.value).push({ + type: nfCommon.formatType(documentedType), + bundle: nfCommon.formatBundle(documentedType.bundle), + explanation: nfCommon.escapeHtml(documentedType.usageRestriction) + }); + } + } + + // record the group + groups.add(documentedType.bundle.group); + + // create the row for the processor type + processorTypesData.addItem({ + id: i, + label: nfCommon.substringAfterLast(type, '.'), + type: type, + bundle: documentedType.bundle, + description: nfCommon.escapeHtml(documentedType.description), + restricted: documentedType.restricted, + usageRestriction: nfCommon.escapeHtml(documentedType.usageRestriction), + explicitRestrictions: documentedType.explicitRestrictions, + 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 update + processorTypesData.endUpdate(); + + // resort + processorTypesData.reSort(); + processorTypesGrid.invalidate(); + + // set the component restrictions and the corresponding required permissions + nfCanvasUtils.addComponentRestrictions(restrictedUsage, requiredPermissions); + + // 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 + }); + + // build the combo options + var options = [{ + text: 'all groups', + value: '' + }]; + groups.each(function (group) { + options.push({ + text: group, + value: group + }); + }); + + // initialize the bundle group combo + $('#processor-bundle-group-combo').combo({ + options: options, + select: applyFilter + }); + }).fail(nfErrorHandler.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({ + scrollableContentStyle: 'scrollable', + headerText: 'Add Processor', + handler: { + resize: function () { + $('#processor-type-description') + .width($('#processor-description-container').innerWidth() - 1) + .text($('#processor-type-description').attr('title')) + .ellipsis(); + } + } + }); + }, + + /** + * 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'); + } + }; + } + + ProcessorComponent.prototype = { + constructor: ProcessorComponent, + + /** + * 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); + }, + + /** + * The drag icon for the toolbox component. + * + * @param event + * @returns {*|jQuery|HTMLElement} + */ + dragIcon: function (event) { + return $('
'); + }, + + /** + * 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 processorComponent = 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(); + var bundle = $('#selected-processor-type').data('bundle'); + + // ensure something was selected + if (name === '' || processorType === '') { + nfDialog.showOkDialog({ + headerText: 'Add Processor', + dialogContent: 'The type of processor to create must be selected.' + }); + } else { + // create the new processor + createProcessor(name, processorType, bundle, pt); + } + + // hide the dialog + processorComponent.modal.hide(); + }; + + // get the grid reference + var grid = $('#processor-types-table').data('gridInstance'); + var dataview = grid.getData(); + + // add the processor when its double clicked in the table + var gridDoubleClick = function (e, args) { + var processorType = grid.getDataItem(args.row); + + if (isSelectable(processorType)) { + $('#selected-processor-name').text(processorType.label); + $('#selected-processor-type').text(processorType.type).data('bundle', processorType.bundle); + + addProcessor(); + } + }; + + // register a handler for double click events + grid.onDblClick.subscribe(gridDoubleClick); + + // update the button model + this.modal.update('setButtonModel', [{ + buttonText: 'Add', + color: { + base: '#728E9B', + hover: '#004849', + text: '#ffffff' + }, + disabled: function () { + var selected = grid.getSelectedRows(); + + if (selected.length > 0) { + // grid configured with multi-select = false + var item = grid.getDataItem(selected[0]); + return isSelectable(item) === false; + } else { + return dataview.getLength() === 0; + } + }, + handler: { + click: addProcessor + } + }, + { + buttonText: 'Cancel', + color: { + base: '#E3E8EB', + hover: '#C7D2D7', + text: '#004849' + }, + handler: { + click: function () { + $('#new-processor-dialog').modal('hide'); + } + } + }]); + + // set a new handler for closing the the dialog + this.modal.update('setCloseHandler', function () { + // remove the handler + grid.onDblClick.unsubscribe(gridDoubleClick); + + // clear the current filters + resetProcessorDialog(); + }); + + // show the dialog + this.modal.show(); + + var navigationKeys = [$.ui.keyCode.UP, $.ui.keyCode.PAGE_UP, $.ui.keyCode.DOWN, $.ui.keyCode.PAGE_DOWN]; + + // setup the filter + $('#processor-type-filter').off('keyup').on('keyup', function (e) { + var code = e.keyCode ? e.keyCode : e.which; + + // ignore navigation keys + if ($.inArray(code, navigationKeys) !== -1) { + return; + } + + if (code === $.ui.keyCode.ENTER) { + var selected = grid.getSelectedRows(); + + if (selected.length > 0) { + // grid configured with multi-select = false + var item = grid.getDataItem(selected[0]); + if (isSelectable(item)) { + addProcessor(); + } + } + } else { + applyFilter(); + } + }); + + // setup row navigation + nfFilteredDialogCommon.addKeydownListener('#processor-type-filter', grid, dataview); + + // adjust the grid canvas now that its been rendered + grid.resizeCanvas(); + + // auto select the first row if possible + if (dataview.getLength() > 0) { + nfFilteredDialogCommon.choseFirstRow(grid); + } + + // set the initial focus + $('#processor-type-filter').focus() + } + }; + + var processorComponent = new ProcessorComponent(); + return processorComponent; + }; +})); -- cgit 1.2.3-korg