Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions rundeckapp/grails-app/assets/javascripts/filterStepPluginsKO.js
Original file line number Diff line number Diff line change
@@ -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() === "");
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/


2 changes: 2 additions & 0 deletions rundeckapp/grails-app/i18n/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
%{--
Copyright 2014 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.
--}%

<strong>Select plugins by title:</strong>
<p>
<code>mystep1</code>
</p>
<p>
This will show plugins that contains "mystep1" on title.
</p>

<strong>Filter plugins by attribute value:</strong>
<ul>
<li>description: <code>description=value</code></li>

<li>name: <code>name=value</code></li>

<li>title: <code>title=value</code></li>
</ul>

<strong>Filter plugins by property value:</strong>
<ul>
<li>property description: <code>property:description=value</code></li>

<li>property title: <code>property:title=value</code></li>

<li>property name: <code>property:name=value</code></li>
</ul>
70 changes: 66 additions & 4 deletions rundeckapp/grails-app/views/execution/_wfAddStep.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- See the License for the specific language governing permissions and
- limitations under the License.
--}%
<%@ page import="grails.converters.JSON" %>
<div class="panel-heading">
<span class="h3 ">
<g:message code="${addMessage}"/>
Expand All @@ -27,8 +28,38 @@
<div class="h4"><g:message code="${chooseMessage}"/></div>
</div>
</div>
<div class="row row-space">
<g:set var="rkey" value="${g.rkey()}"/>
<div id="addStep_${rkey}" class="row row-space">
<div class="col-sm-12">
<div class="form-group">

<label class="col-sm-2 control-label" for="stepFilter${enc(attr: rkey)}">
<g:message code="step.plugins.filter.prompt"/>
</label>

<div class="col-sm-10">
<g:set var="filtvalue" value="${item?.nodeFilter}"/>

<span class="input-group nodefilters">
<g:render template="/framework/stepPluginFilterInputGroup"
model="[filterFieldName: 'nodeFilter',
filterFieldId:'nodeFilterField'+rkey,
queryFieldHelpId:'nodeFilterQueryFieldHelp'+rkey,
queryFieldPlaceholderText: g.message(code:'enter.a.step.filter.override'),
filterset: '',
filtvalue: filtvalue,
nodeStepDescriptions: nodeStepDescriptions,
filterName: null]"/>
</span>

<div class=" collapse" id="nodeFilterQueryFieldHelp${enc(attr: rkey)}">
<div class="help-block">
<g:render template="/common/stepPluginsfilterStringHelp"/>
</div>
</div>

</div>
</div>
<ul class="nav nav-tabs" >
<li class="active node_step_section">
<a href="#addnodestep" data-toggle="tab">
Expand Down Expand Up @@ -75,8 +106,9 @@
</div>
<g:each in="${nodeStepDescriptions.sort{a,b->a.name<=>b.name}}" var="typedesc">

<a class="list-group-item textbtn add_node_step_type" data-node-step-type="${enc(attr:typedesc.name)}"
href="#">
<a data-bind="visible: isVisible('${(typedesc.name)}')"
class="list-group-item textbtn add_node_step_type"
data-node-step-type="${enc(attr:typedesc.name)}" href="#">
<stepplugin:pluginIcon service="WorkflowNodeStep"
name="${typedesc.name}"
width="16px"
Expand Down Expand Up @@ -120,7 +152,9 @@
<g:plural for="${stepDescriptions}" code="workflow.step.plugin" />
</div>
<g:each in="${stepDescriptions.sort{a,b->a.name<=>b.name}}" var="typedesc">
<a class="list-group-item textbtn add_step_type" data-step-type="${enc(attr:typedesc.name)}" href="#">
<a data-bind="visible: isVisible('${(typedesc.name)}')" class="list-group-item textbtn add_step_type"
data-step-type="${enc(attr: typedesc.name)}"
href="#">
<stepplugin:pluginIcon service="WorkflowStep"
name="${typedesc.name}"
width="16px"
Expand Down Expand Up @@ -153,6 +187,34 @@
</div>
</div>
</div>
<g:javascript>
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]);
});
</g:javascript>
</div>

<div class="panel-footer">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
%{--
Copyright 2014 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.
--}%

<input type='search' name="${filterFieldName?enc(attr:filterFieldName):'filter'}" class="schedJobNodeFilter form-control"
data-bind="textInput: stepFilterValue, executeOnEnter: filterStepDescriptions"
placeholder="${queryFieldPlaceholderText?:g.message(code:'enter.a.node.filter')}"
data-toggle='popover'
data-popover-content-ref="#${queryFieldHelpId?enc(attr:queryFieldHelpId):'queryFilterHelp'}"
data-placement="bottom"
data-trigger="manual"
data-container="body"
value="${enc(attr:filtvalue)}" id="${filterFieldId ? enc(attr: filterFieldId) : 'schedJobNodeFilter'}"/>


<span class="input-group-btn">
<a class="btn btn-default" data-toggle='popover-for' data-target="#${filterFieldId ? enc(attr: filterFieldId) : 'schedJobNodeFilter'}" onclick="jQuery('#${filterFieldId ? enc(attr: filterFieldId) : 'schedJobNodeFilter'}').popover('toggle')">
<i class="glyphicon glyphicon-question-sign"></i>
</a>
<a class="btn btn-default" data-bind="click: filterStepDescriptions" href="#">
<g:message code="search" />
</a>
</span>