define([ 'mvc/list/list-item', 'mvc/dataset/dataset-list', "mvc/base-mvc", "utils/localization" ], function( LIST_ITEM, DATASET_LIST, BASE_MVC, _l ){ //============================================================================== var _super = LIST_ITEM.FoldoutListItemView; /** @class A job view used from within a larger list of jobs. * Each job itself is a foldout panel of history contents displaying the outputs of this job. */ var JobListItemView = _super.extend(/** @lends JobListItemView.prototype */{ /** logger used to record this.log messages, commonly set to console */ //logger : console, className : _super.prototype.className + " job", id : function(){ return [ 'job', this.model.get( 'id' ) ].join( '-' ); }, foldoutPanelClass : DATASET_LIST.DatasetList, /** Set up: instance vars, options, and event handlers */ initialize : function( attributes ){ if( attributes.logger ){ this.logger = this.model.logger = attributes.logger; } this.log( this + '.initialize:', attributes ); _super.prototype.initialize.call( this, attributes ); this.tool = attributes.tool || {}; this.jobData = attributes.jobData || {}; /** where should pages from links be displayed? (default to new tab/window) */ this.linkTarget = attributes.linkTarget || '_blank'; }, /** In this override, add the state as a class for use with state-based CSS */ _swapNewRender : function( $newRender ){ _super.prototype._swapNewRender.call( this, $newRender ); if( this.model.has( 'state' ) ){ this.$el.addClass( 'state-' + this.model.get( 'state' ) ); } return this.$el; }, /** Stub to return proper foldout panel options */ _getFoldoutPanelOptions : function(){ var options = _super.prototype._getFoldoutPanelOptions.call( this ); return _.extend( options, { collection : this.model.outputCollection, selecting : false }); }, // ........................................................................ template helpers // all of these are ADAPTERs - in other words, it might be better if the API returned the final form // or something similar in order to remove some of the complexity here /** Return tool.inputs that should/can be safely displayed */ _labelParamMap : function(){ //ADAPTER var params = this.model.get( 'params' ), labelParamMap = {}; _.each( this.tool.inputs, function( i ){ //console.debug( i.label, i.model_class ); if( i.label && i.model_class !== 'DataToolParameter' ){ labelParamMap[ i.label ] = params[ i.name ]; } }); return labelParamMap; }, _labelInputMap : function(){ //ADAPTER var view = this, labelInputMap = {}; _.each( this.jobData.inputs, function( input ){ var toolInput = view._findToolInput( input.name ); if( toolInput ){ labelInputMap[ toolInput.label ] = input; } }); return labelInputMap; }, /** Return a tool.inputs object that matches (or partially matches) the given (job input) name */ _findToolInput : function( name ){ //ADAPTER var toolInputs = this.tool.inputs, exactMatch = _.findWhere( toolInputs, { name : name }); if( exactMatch ){ return exactMatch; } return this._findRepeatToolInput( name, toolInputs ); }, /** Return a tool.inputs object that partially matches the given (job input) name (for repeat dataset inputs)*/ _findRepeatToolInput : function( name, toolInputs ){ //ADAPTER toolInputs = toolInputs || this.tool.inputs; var partialMatch = _.find( toolInputs, function( i ){ return name.indexOf( i.name ) === 0; }); if( !partialMatch ){ return undefined; } var subMatch = _.find( partialMatch.inputs, function( i ){ return name.indexOf( i.name ) !== -1; }); return subMatch; }, // ........................................................................ misc /** String representation */ toString : function(){ return 'JobListItemView(' + this.model + ')'; } }); // ............................................................................ TEMPLATES /** underscore templates */ JobListItemView.prototype.templates = (function(){ //TODO: move to require text! plugin var elTemplate = BASE_MVC.wrapTemplate([ '
', '
<%= model.id %>
', // errors, messages, etc. '
', // multi-select checkbox '
', '', '
', // space for title bar buttons - gen. floated to the right '
', '
', // expandable area for more details '
', '
' ]); var titleBarTemplate = BASE_MVC.wrapTemplate([ // adding a tabindex here allows focusing the title bar and the use of keydown to expand the dataset display '
', //'', '
', '<%- view.tool.name %>', '
', '
', '<%- view.tool.description %>', ' ', _l( 'Created' ), ': <%= new Date( job.create_time ).toString() %>, ', '', '
' ], 'job' ); var subtitleTemplate = BASE_MVC.wrapTemplate([ '
', '<%- view.tool.description %>', // ' ', _l( 'Created' ), ': <%= new Date( job.create_time ).toString() %>, ', //'', // ' (', _l( 'version' ), ': <%= view.tool.version %>)', //'' ], 'job' ); var detailsTemplate = BASE_MVC.wrapTemplate([ '
', //'
', // '', // '<%= view.tool.version %>', //'
', '
', '<% _.each( view._labelInputMap(), function( input, label ){ %>', '
', '', //TODO: input dataset name '<%= input.content.name %>', '
', '<% }) %>', '<% _.each( view._labelParamMap(), function( param, label ){ %>', '
', '', '<%= param %>', '
', '<% }) %>', '
', '
' ], 'job' ); return _.extend( {}, _super.prototype.templates, { //el : elTemplate, titleBar : titleBarTemplate, subtitle : subtitleTemplate, details : detailsTemplate }); }()); //============================================================================= return { JobListItemView : JobListItemView }; });