diff --git a/rundeckapp/grails-app/assets/javascripts/filterStepPluginsKO.js b/rundeckapp/grails-app/assets/javascripts/filterStepPluginsKO.js new file mode 100644 index 00000000000..5c54fcebb4b --- /dev/null +++ b/rundeckapp/grails-app/assets/javascripts/filterStepPluginsKO.js @@ -0,0 +1,56 @@ +/* + * Copyright 2016 SimplifyOps, Inc. (http://simplifyops.com) + * + * Licensed 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. + */ + +//= require knockout.min +//= require knockout-mapping + + +function StepPluginsFilter(data) { + var self = this; + self.stepDescriptions = ko.observableArray(data.stepDescriptions); + self.stepFilterValue = ko.observable(""); + self.currentFilter = ko.observable(); + self.currentPropertyFilter = ko.observable(""); + self.filterStepDescriptions = function () { + var filterValue = self.stepFilterValue() ? self.stepFilterValue().split("=") : ""; + var prop = filterValue.length > 1 ? filterValue[0] : "title"; + var value = filterValue.length > 1 ? filterValue[1] : filterValue[0]; + self.currentPropertyFilter(prop); + self.currentFilter(value); + }; + + self.isVisible = function(typedesc){ + var arrayFiltered = ko.utils.arrayFilter(self.stepDescriptions(), function (descr) { + var propertyFilterValue = self.currentPropertyFilter() ? + self.currentPropertyFilter().split(":") : undefined; + + var filterByProps = propertyFilterValue && propertyFilterValue.length == 2; + + if(!filterByProps) { + return descr[self.currentPropertyFilter() || "title"].toLowerCase() + .indexOf(self.currentFilter() ? self.currentFilter().toLowerCase() : undefined) >= 0 + && typedesc == descr.name; + } else if(filterByProps) { + return descr.properties.any(function(t){ + return t[propertyFilterValue[1]].toLowerCase() + .indexOf(self.currentFilter() ? self.currentFilter().toLowerCase() : undefined) >= 0; + }) && typedesc == descr.name; + } + }); + + return arrayFiltered.length > 0 || (!self.currentFilter() || self.currentFilter() === ""); + }; +} diff --git a/rundeckapp/grails-app/assets/javascripts/jobEditPage_bundle.js b/rundeckapp/grails-app/assets/javascripts/jobEditPage_bundle.js index 500178b8f2c..f045d6b80d1 100644 --- a/rundeckapp/grails-app/assets/javascripts/jobEditPage_bundle.js +++ b/rundeckapp/grails-app/assets/javascripts/jobEditPage_bundle.js @@ -22,12 +22,13 @@ //= require workflowStepEditorKO //= require nodeFiltersKO //= require optionEditKO +//= require filterStepPluginsKO //= require storageBrowseKO //= require prototype-bundle //= require ace-bundle /* - Manifest: include jobedit.js, workflowStepEditorKO, nodeFiltersKO, optionEditKO + Manifest: include jobedit.js, workflowStepEditorKO, nodeFiltersKO, optionEditKO, filterStepPluginsKO */ diff --git a/rundeckapp/grails-app/i18n/messages.properties b/rundeckapp/grails-app/i18n/messages.properties index 4ca0d195f47..c44853db38e 100644 --- a/rundeckapp/grails-app/i18n/messages.properties +++ b/rundeckapp/grails-app/i18n/messages.properties @@ -786,11 +786,13 @@ JobExec.property.nodeKeepgoing.null.description=Maintain the behavior defined fo JobExec.property.nodeThreadcount.null.description=If blank, use the Thread Count defined for the triggered Job. node.filter=Node Filter node.filter.prompt=Node Filter +step.plugins.filter.prompt=Search step matched.nodes.prompt=Matched Nodes refresh=refresh nodes.matched=Nodes Matched enter.a.node.filter=Enter a node filter, or .* for all nodes enter.a.node.filter.override=Enter a filter string. Leave blank to use the filter defined for the triggered job. +enter.a.step.filter.override=Enter a step filter string. JobExec.property.nodeFilter.help.description=Enter a node filter to override the triggered Job's target nodes. If you enter a new filter string, you can also change the Thread Count, and behavior if the Job fails for a node. JobExec.property.nodeRankOrder.null.description=Maintain the ordering defined in the triggered Job html=HTML diff --git a/rundeckapp/grails-app/views/common/_stepPluginsfilterStringHelp.gsp b/rundeckapp/grails-app/views/common/_stepPluginsfilterStringHelp.gsp new file mode 100644 index 00000000000..5c0b3350b17 --- /dev/null +++ b/rundeckapp/grails-app/views/common/_stepPluginsfilterStringHelp.gsp @@ -0,0 +1,41 @@ +%{-- + Copyright 2014 SimplifyOps Inc, + + Licensed 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. + --}% + +Select plugins by title: +

+ mystep1 +

+

+ This will show plugins that contains "mystep1" on title. +

+ +Filter plugins by attribute value: + + +Filter plugins by property value: + \ No newline at end of file diff --git a/rundeckapp/grails-app/views/execution/_wfAddStep.gsp b/rundeckapp/grails-app/views/execution/_wfAddStep.gsp index e5a53956861..4bdaaa1f23d 100644 --- a/rundeckapp/grails-app/views/execution/_wfAddStep.gsp +++ b/rundeckapp/grails-app/views/execution/_wfAddStep.gsp @@ -13,6 +13,7 @@ - See the License for the specific language governing permissions and - limitations under the License. --}% +<%@ page import="grails.converters.JSON" %>
@@ -27,8 +28,38 @@
-
+ +
+
+ + + +
+ + + + + + +
+
+ +
+
+ +
+
- +
- +
+ + fireWhenReady('addStep_${enc(js: rkey)}',function(){ + + function parseJSONString(jsonString){ + jsonString = jsonString.replace(/\"/g,'"'); + return JSON.parse(jsonString); + }; + + function findEncName(name) { + var arrayDescrtions = parseJSONString("${stepDescriptions.collect{enc(attr: it.name)} as JSON}"); + return arrayDescrtions.find(function(ad){return ad === name}) + }; + + function parseModelToJS(jsonString) { + var jsonObject=parseJSONString(jsonString); + // jsonObject.forEach(function(item){item.encName = findEncName(item.name)}); + return jsonObject + }; + + var nodeStepDescriptionsArray = parseModelToJS("${nodeStepDescriptions as JSON}"); + var stepDescriptionsArray = parseModelToJS("${stepDescriptions as JSON}"); + var pluginsDescriptions = nodeStepDescriptionsArray.concat(stepDescriptionsArray); + + var filter = new StepPluginsFilter({stepDescriptions:pluginsDescriptions}); + + ko.applyBindings(filter,jQuery('#addStep_${enc(js:rkey)}')[0]); + }); +