Skip to content

Commit

Permalink
Separate input augmentation helpers from form views, augment inputs f…
Browse files Browse the repository at this point in the history
…or regular form
  • Loading branch information
guerler committed Aug 16, 2017
1 parent abe8117 commit 338abee
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 159 deletions.
295 changes: 145 additions & 150 deletions client/galaxy/scripts/mvc/workflow/workflow-forms.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,80 @@
define( [ 'utils/utils', 'mvc/form/form-view', 'mvc/tool/tool-form-base' ], function( Utils, Form, ToolFormBase ) {

/** Default form wrapper for non-tool modules in the workflow editor. */
var Default = Backbone.View.extend({
initialize: function( options ) {
this.form = new Form( options );
_addLabelAnnotation( this.form );
this.form.render();
}
});

/** Tool form wrapper for the workflow editor. */
var Tool = Backbone.View.extend({
initialize: function( options ) {
var self = this;
var node = options.node;
this.form = new ToolFormBase( Utils.merge( options, {
text_enable : 'Set in Advance',
text_disable : 'Set at Runtime',
narrow : true,
initial_errors : true,
cls : 'ui-portlet-narrow',
customize : function( form ) {
var options = form.model.attributes;
Utils.deepeach( options.inputs, function( input ) {
if ( input.type ) {
if ( [ 'data', 'data_collection' ].indexOf( input.type ) != -1 ) {
input.type = 'hidden';
input.info = 'Data input \'' + input.name + '\' (' + Utils.textify( input.extensions ) + ')';
input.value = { '__class__': 'RuntimeValue' };
} else if ( !input.fixed ) {
input.collapsible_value = { '__class__': 'RuntimeValue' };
input.is_workflow = ( input.options && input.options.length == 0 ) ||
( [ 'integer', 'float' ].indexOf( input.type ) != -1 );
}
}
});
Utils.deepeach( options.inputs, function( input ) {
input.type == 'conditional' && ( input.test_param.collapsible_value = undefined );
});
_addSections( form );
_addLabelAnnotation( form );
},
postchange : function( process, form ) {
var options = form.model.attributes;
var current_state = {
tool_id : options.id,
tool_version : options.version,
type : 'tool',
inputs : $.extend( true, {}, form.data.create() )
}
Galaxy.emit.debug( 'tool-form-workflow::postchange()', 'Sending current state.', current_state );
Utils.request({
type : 'POST',
url : Galaxy.root + 'api/workflows/build_module',
data : current_state,
success : function( data ) {
form.update( data.config_form );
form.errors( data.config_form );
// This hasn't modified the workflow, just returned
// module information for the tool to update the workflow
// state stored on the client with. User needs to save
// for this to take effect.
node.update_field_data( data );
Galaxy.emit.debug( 'tool-form-workflow::postchange()', 'Received new model.', data );
process.resolve();
},
error : function( response ) {
Galaxy.emit.debug( 'tool-form-workflow::postchange()', 'Refresh request failed.', response );
process.reject();
}
});
}
}));
}
});

/** Augments the module form definition by adding label and annotation fields */
function _addLabelAnnotation ( form ) {
var options = form.model.attributes;
Expand All @@ -23,7 +98,7 @@ define( [ 'utils/utils', 'mvc/form/form-view', 'mvc/tool/tool-form-base' ], func
fixed : true,
onchange: function( new_label ) {
var duplicate = false;
for ( var i in self.workflow.nodes ) {
for ( var i in workflow.nodes ) {
var n = workflow.nodes[ i ];
if ( n.label && n.label == new_label && n.id != node.id ) {
duplicate = true;
Expand Down Expand Up @@ -53,130 +128,60 @@ define( [ 'utils/utils', 'mvc/form/form-view', 'mvc/tool/tool-form-base' ], func
};
}

/** Default form wrapper for non-tool modules in the workflow editor. */
var Default = Backbone.View.extend({
initialize: function( options ) {
options.customize = function( form ) { _addLabelAnnotation( form ) };
this.form = new Form( options );
}
});
/** Builds all sub sections */
function _addSections( form ) {
var options = form.model.attributes;
var inputs = options.inputs;
var datatypes = options.datatypes;
var node = options.node;
var workflow = options.workflow;
var post_job_actions = node.post_job_actions;
var output_id = node.output_terminals && Object.keys( node.output_terminals )[ 0 ];

/** Tool form wrapper for the workflow editor. */
var Tool = Backbone.View.extend({
initialize: function( options ) {
var self = this;
this.workflow = options.workflow;
this.node = options.node;
if ( this.node ) {
this.post_job_actions = this.node.post_job_actions || {};
this.form = new ToolFormBase( Utils.merge( options, {
text_enable : 'Set in Advance',
text_disable : 'Set at Runtime',
narrow : true,
initial_errors : true,
cls : 'ui-portlet-narrow',
customize : function( form ) {
var options = form.model.attributes;
Utils.deepeach( options.inputs, function( input ) {
if ( input.type ) {
if ( [ 'data', 'data_collection' ].indexOf( input.type ) != -1 ) {
input.type = 'hidden';
input.info = 'Data input \'' + input.name + '\' (' + Utils.textify( input.extensions ) + ')';
input.value = { '__class__': 'RuntimeValue' };
} else if ( !input.fixed ) {
input.collapsible_value = { '__class__': 'RuntimeValue' };
input.is_workflow = ( input.options && input.options.length == 0 ) ||
( [ 'integer', 'float' ].indexOf( input.type ) != -1 );
}
}
});
Utils.deepeach( options.inputs, function( input ) {
input.type == 'conditional' && ( input.test_param.collapsible_value = undefined );
});

// build sections
self._makeSections( options );

// add label and annotation fields
_addLabelAnnotation( form );
},
postchange : function( process, form ) {
var options = form.model.attributes;
var current_state = {
tool_id : options.id,
tool_version : options.version,
type : 'tool',
inputs : $.extend( true, {}, form.data.create() )
/** Visit input nodes and enrich by name/value pairs from server data */
function visit( head, head_list ) {
head_list = head_list || [];
head_list.push( head );
for ( var i in head.inputs ) {
var input = head.inputs[ i ];
var action = input.action;
if ( action ) {
input.name = 'pja__' + output_id + '__' + input.action;
if ( input.pja_arg ) {
input.name += '__' + input.pja_arg;
}
if ( input.payload ) {
for ( var p_id in input.payload ) {
var p = input.payload[ p_id ];
input.payload[ input.name + '__' + p_id ] = p;
delete p;
}
}
var d = post_job_actions[ input.action + output_id ];
if ( d ) {
for ( var j in head_list ) {
head_list[ j ].expanded = true;
}
if ( input.pja_arg ) {
input.value = d.action_arguments && d.action_arguments[ input.pja_arg ] || input.value;
} else {
input.value = 'true';
}
Galaxy.emit.debug( 'tool-form-workflow::postchange()', 'Sending current state.', current_state );
Utils.request({
type : 'POST',
url : Galaxy.root + 'api/workflows/build_module',
data : current_state,
success : function( data ) {
form.update( data.config_form );
form.errors( data.config_form );
// This hasn't modified the workflow, just returned
// module information for the tool to update the workflow
// state stored on the client with. User needs to save
// for this to take effect.
self.node.update_field_data( data );
Galaxy.emit.debug( 'tool-form-workflow::postchange()', 'Received new model.', data );
process.resolve();
},
error : function( response ) {
Galaxy.emit.debug( 'tool-form-workflow::postchange()', 'Refresh request failed.', response );
process.reject();
}
});
},
}));
} else {
Galaxy.emit.debug('tool-form-workflow::initialize()', 'Node not found in workflow.');
}
},

/** Builds all sub sections */
_makeSections: function( options ){
var inputs = options.inputs;
var datatypes = options.datatypes;
var output_id = this.node.output_terminals && Object.keys( this.node.output_terminals )[ 0 ];
if ( output_id ) {
inputs.push({
name : 'pja__' + output_id + '__EmailAction',
label : 'Email notification',
type : 'boolean',
value : String( Boolean( this.post_job_actions[ 'EmailAction' + output_id ] ) ),
ignore : 'false',
help : 'An email notification will be sent when the job has completed.',
payload : {
'host' : window.location.host
}
});
inputs.push({
name : 'pja__' + output_id + '__DeleteIntermediatesAction',
label : 'Output cleanup',
type : 'boolean',
value : String( Boolean( this.post_job_actions[ 'DeleteIntermediatesAction' + output_id ] ) ),
ignore : 'false',
help : 'Upon completion of this step, delete non-starred outputs from completed workflow steps if they are no longer required as inputs.'
});
for ( var i in this.node.output_terminals ) {
inputs.push( this._makeSection( i, datatypes ) );
}
input.inputs && visit( input, head_list.slice( 0 ) );
}
},
}

/** Builds sub section with step actions/annotation */
_makeSection: function( output_id, datatypes ){
var self = this;
function _makeSection( output_id, datatypes ) {
var extensions = [];
var input_terminal_names = [];
for ( key in datatypes ) {
extensions.push( { 0 : datatypes[ key ], 1 : datatypes[ key ] } );
}
for ( key in this.node.input_terminals ){
input_terminal_names.push( this.node.input_terminals[ key ].name );
for ( key in node.input_terminals ){
input_terminal_names.push( node.input_terminals[ key ].name );
}
extensions.sort( function( a, b ) {
return a.label > b.label ? 1 : a.label < b.label ? -1 : 0;
Expand All @@ -200,10 +205,10 @@ define( [ 'utils/utils', 'mvc/form/form-view', 'mvc/tool/tool-form-base' ], func
inputs : [{
label : 'Label',
type : 'text',
value : ( output = this.node.getWorkflowOutput( output_id ) ) && output.label || '',
value : ( output = node.getWorkflowOutput( output_id ) ) && output.label || '',
help : 'This will provide a short name to describe the output - this must be unique across workflows.',
onchange : function( new_value ) {
self.workflow.attemptUpdateOutputLabel( self.node, output_id, new_value );
workflow.attemptUpdateOutputLabel( node, output_id, new_value );
}
},{
action : 'RenameDatasetAction',
Expand Down Expand Up @@ -281,45 +286,35 @@ define( [ 'utils/utils', 'mvc/form/form-view', 'mvc/tool/tool-form-base' ], func
help : 'This action will set column assignments in the output dataset. Blank fields are ignored.'
}]
};
visit( input_config );
return input_config;
}

// visit input nodes and enrich by name/value pairs from server data
function visit ( head, head_list ) {
head_list = head_list || [];
head_list.push( head );
for ( var i in head.inputs ) {
var input = head.inputs[ i ];
var action = input.action;
if ( action ) {
input.name = 'pja__' + output_id + '__' + input.action;
if ( input.pja_arg ) {
input.name += '__' + input.pja_arg;
}
if ( input.payload ) {
for ( var p_id in input.payload ) {
var p = input.payload[ p_id ];
input.payload[ input.name + '__' + p_id ] = p;
delete p;
}
}
var d = self.post_job_actions[ input.action + output_id ];
if ( d ) {
for ( var j in head_list ) {
head_list[ j ].expanded = true;
}
if ( input.pja_arg ) {
input.value = d.action_arguments && d.action_arguments[ input.pja_arg ] || input.value;
} else {
input.value = 'true';
}
}
}
input.inputs && visit( input, head_list.slice( 0 ) );
if ( output_id ) {
inputs.push({
name : 'pja__' + output_id + '__EmailAction',
label : 'Email notification',
type : 'boolean',
value : String( Boolean( post_job_actions[ 'EmailAction' + output_id ] ) ),
ignore : 'false',
help : 'An email notification will be sent when the job has completed.',
payload : {
'host' : window.location.host
}
});
inputs.push({
name : 'pja__' + output_id + '__DeleteIntermediatesAction',
label : 'Output cleanup',
type : 'boolean',
value : String( Boolean( post_job_actions[ 'DeleteIntermediatesAction' + output_id ] ) ),
ignore : 'false',
help : 'Upon completion of this step, delete non-starred outputs from completed workflow steps if they are no longer required as inputs.'
});
for ( var i in node.output_terminals ) {
inputs.push( _makeSection( i, datatypes ) );
}
visit( input_config );
return input_config;
}
});
}

return {
Default: Default,
Expand Down
14 changes: 9 additions & 5 deletions client/galaxy/scripts/mvc/workflow/workflow-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -670,13 +670,17 @@ define([
content.datatypes = this.datatypes;
content.icon = WorkflowIcons[ node.type ];
content.cls = 'ui-portlet-narrow';
if ( node.type == 'tool' ) {
form_wrapper = new FormWrappers.Tool( content );
if ( node ) {
if ( node.type == 'tool' ) {
form_wrapper = new FormWrappers.Tool( content );
} else {
form_wrapper = new FormWrappers.Default( content );
}
$el.append( form_wrapper.form.$el );
$container.append( $el );
} else {
form_wrapper = new FormWrappers.Default( content );
Galaxy.emit.debug('workflow-view::initialize()', 'Node not found in workflow.');
}
$el.append( form_wrapper.form.$el );
$container.append( $el );
}
$( '.' + cls ).hide();
$container.find( '#' + id ).show();
Expand Down
Loading

0 comments on commit 338abee

Please sign in to comment.