diff --git a/client/galaxy/scripts/mvc/history/multi-panel.js b/client/galaxy/scripts/mvc/history/multi-panel.js index 8fca4adf47c..97117482be4 100644 --- a/client/galaxy/scripts/mvc/history/multi-panel.js +++ b/client/galaxy/scripts/mvc/history/multi-panel.js @@ -1,4 +1,5 @@ define([ + "utils/localization", "mvc/history/history-model", "mvc/history/history-view-edit", "mvc/history/copy-dialog", @@ -7,8 +8,7 @@ define([ "utils/ajax-queue", "ui/mode-button", "ui/search-input", - "utils/localization" -], function( HISTORY_MODEL, HISTORY_VIEW_EDIT, historyCopyDialog, ERROR_MODAL, baseMVC, ajaxQueue, _l){ +], function( _l, HISTORY_MODEL, HISTORY_VIEW_EDIT, historyCopyDialog, ERROR_MODAL, baseMVC, ajaxQueue){ 'use strict'; var logNamespace = 'history'; diff --git a/static/maps/mvc/history/multi-panel.js.map b/static/maps/mvc/history/multi-panel.js.map index 94f80423d62..1bb6a25b83c 100644 --- a/static/maps/mvc/history/multi-panel.js.map +++ b/static/maps/mvc/history/multi-panel.js.map @@ -1 +1 @@ -{"version":3,"sources":["mvc/history/multi-panel.js"],"names":["define","HISTORY_MODEL","HISTORY_VIEW_EDIT","historyCopyDialog","ERROR_MODAL","baseMVC","ajaxQueue","_l","_logNamespace","HistoryViewColumn","Backbone","View","extend","LoggableMixin","tagName","className","id","initialize","options","this","model","get","purgeAllowed","_","isUndefined","createPanel","panel","panelOptions","$scrollContainer","HistoryViewEdit","defaults","dragItems","$el","column","once","trigger","setUpPanelListeners","listenTo","rendered","view:expanded view:rendered","view","$","off","inView","viewLeft","viewRight","columnLeft","offset","left","width","$panel","render","speed","modelData","html","template","renderPanel","css","setUpBehaviors","data","isCurrentHistory","currentHistory","controlsRightTemplate","history","undefined","join","setElement","events","$list","before","_renderDropTargetHelp","setAsCurrent","click .delete-history","done","undelete","click .undelete-history","confirm","click .purge-history","purge","click .copy-history","copy","controlsLeftTemplate","variable","MultiPanelColumns","addClass","columnWidth","borderWidth","headerHeight","footerHeight","controlsHeight","perPage","toString","log","columnGap","setCollection","collection","hdaQueue","createColumns","NamedAjaxQueue","columnMap","columnOptions","historySearch","datasetSearch","models","histories","multipanel","setUpListeners","setUpCollectionListeners","fetchMore","stopListening","HistoryCollection","addModels","setCurrentHistory","scrollLeft","forEach","addColumn","oldCurrentColumn","error","add","all-fetched","_postFetchAll","new-current","addAsCurrentColumn","set-as-current","handleDeletedHistory","sort","fetchData","includeDeleted","findWhere","height","newCurrentColumn","currentHistoryId","errorHandler","_recalcFirstColumnHeight","isString","message","title","removeColumn","xhr","status","readyState","createColumn","errorModal","badGatewayErrorModal","ajaxErrorModal","_ajaxErrorHandler","queueHdaFetchDetails","apply","toArray","arguments","create","ev","current","renderColumns","each","i","newColumn","Galaxy","config","allow_user_dataset_purge","setUpColumnListeners","searchItems","queueHdaFetch","_dropData","currentColumnDropTargetOn","currentColumnDropTargetOff","remove","widthToRemove","toCopy","contents","queue","name","view:draggable:dragstart","start","JSON","parse","dataTransfer","getData","view:draggable:dragend","droptarget:drop","columnMapLength","filter","json","Object","keys","length","currentPage","sortedFilteredColumns","filters","fn","sortedColumns","fetchPage","reverse","content","filtered","sorted","fetch","index","every","map","call","$middle","self","_addColumns","sortedAndFiltered","fxSpeed","checkColumnsInView","mainTemplate","isNumber","_calcMiddleWidth","preventStackWidthAdj","empty","append","loadingIndicatorTemplate","columns","fetchOptions","details","ids","numExisting","children","fetchCurrentPage","renderItems","appendTo","numColumns","running","_renderEmptyMessage","contentsShown","silent","values","storage","allExpanded","renderInfo","haveDetails","progressivelyFetchDetails","location","toggleDeletedHistories","currentTarget","show","msg","window","text","_clickToggleDeletedDatasets","click .create-new.btn","click #include-deleted","click #toggle-deleted","close","root","_clickToggleDeletedHistories","toggleOptionsPopover","is","toggleHiddenDatasets","toggleShowHidden","_chooseOrder","toggleDeletedDatasets","currentHistoryModel","_scrollLeft","val","_moreOptionsPopover","orderKey","orderDescriptions","placeholder","onfirstsearch","slice","searchInput","clear","onclear","searchFor","onsearch","clearSearch","resize","viewport","_viewport","progress","checkForEndOfScroll","total","deferred","container","placement","optionsPopoverTemplate","$firstColumn","middleHeight","debouncedInView","debounce","$outerMiddle","parent","scroll","popover","columnsInView","first","controlHeight","find","scrollRight","right","currentColumn","dataDropped","vp","dropTargetOn","prototype","dataDrop","dropTarget","update_time","update_time-asc","name-dsc","size","size-asc"],"mappings":"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","file":"../../../scripts/mvc/history/multi-panel.js","sourcesContent":["define([\n \"mvc/history/history-model\",\n \"mvc/history/history-view-edit\",\n \"mvc/history/copy-dialog\",\n \"mvc/ui/error-modal\",\n \"mvc/base-mvc\",\n \"utils/ajax-queue\",\n \"ui/mode-button\",\n \"ui/search-input\",\n \"utils/localization\"\n], function( HISTORY_MODEL, HISTORY_VIEW_EDIT, historyCopyDialog, ERROR_MODAL, baseMVC, ajaxQueue, _l){\n'use strict';\n\nvar logNamespace = 'history';\n/* ==============================================================================\nTODO:\n\n============================================================================== */\n/** @class A container for a history panel that renders controls for that history (delete, copy, etc.) */\nvar HistoryViewColumn = Backbone.View.extend( baseMVC.LoggableMixin ).extend({\n\n _logNamespace : logNamespace,\n\n tagName : 'div',\n className : 'history-column flex-column flex-row-container',\n id : function id(){\n if( !this.model ){ return ''; }\n return 'history-column-' + this.model.get( 'id' );\n },\n\n // ------------------------------------------------------------------------ set up\n /** set up passed-in panel (if any) and listeners */\n initialize : function initialize( options ){\n options = options || {};\n this.purgeAllowed = !_.isUndefined( options.purgeAllowed )? options.purgeAllowed: false;\n this.panel = options.panel || this.createPanel( options );\n\n this.setUpListeners();\n },\n\n /** create a history panel for this column */\n createPanel : function createPanel( panelOptions ){\n return new HISTORY_VIEW_EDIT.HistoryViewEdit( _.defaults( panelOptions, {\n model : this.model,\n // non-current panels should set their hdas to draggable\n purgeAllowed : this.purgeAllowed,\n dragItems : true,\n $scrollContainer: function(){ return this.$el; },\n }));\n },\n\n /** set up reflexive listeners */\n setUpListeners : function setUpListeners(){\n var column = this;\n //this.log( 'setUpListeners', this );\n this.once( 'rendered', function(){\n column.trigger( 'rendered:initial', column );\n });\n this.setUpPanelListeners();\n },\n\n /** set listeners needed for panel */\n setUpPanelListeners : function setUpPanelListeners(){\n var column = this;\n this.listenTo( this.panel, {\n //'all': function(){ console.info( 'panel of ' + this, arguments ); },\n\n // assumes panel will take the longest to render\n 'rendered': function(){\n column.trigger( 'rendered', column );\n },\n // when a panel's view expands turn off the click handler on the rerun button so that it uses it's href\n // this allows the button to open the tool rerun form in a new tab (instead of erroring)\n // TODO: hack\n 'view:expanded view:rendered': function( view ){\n view.$( '.rerun-btn' ).off();\n }\n }, this );\n },\n\n /** do the dimensions of this column overlap the given (horizontal) browser coords? */\n inView : function( viewLeft, viewRight ){\n var columnLeft = this.$el.offset().left,\n columnRight = columnLeft + this.$el.width();\n if( columnRight < viewLeft ){ return false; }\n if( columnLeft > viewRight ){ return false; }\n return true;\n },\n\n /** shortcut to the panel */\n $panel : function $panel(){\n return this.$( '.history-panel' );\n },\n\n // ------------------------------------------------------------------------ render\n /** render ths column, its panel, and set up plugins */\n render : function render( speed ){\n speed = ( speed !== undefined )?( speed ):( 'fast' );\n //this.log( this + '.render', this.$el, this.el );\n //TODO: not needed\n var modelData = this.model? this.model.toJSON(): {};\n this.$el.html( this.template( modelData ) );\n this.renderPanel( speed );\n // jq 1.12 doesn't fade/show properly when display: flex, re-set here\n this.panel.$el.css( 'display', 'flex' );\n // if model and not children\n // template\n // render controls\n this.setUpBehaviors();\n // add panel\n return this;\n },\n\n /** set up plugins */\n setUpBehaviors : function setUpBehaviors(){\n //this.log( 'setUpBehaviors:', this );\n //var column = this;\n // on panel size change, ...\n },\n\n /** column body template with inner div for panel based on data (model json) */\n template : function template( data ){\n data = _.extend( data || {}, {\n isCurrentHistory : this.currentHistory\n });\n return $([\n '
',\n this.controlsLeftTemplate({ history: data, view: this }),\n //'',\n this.controlsRightTemplate({ history: data, view: this }),\n '
',\n '
',\n '
',\n '
'\n ].join( '' ));\n },\n\n /** render the panel contained in the column using speed for fx speed */\n renderPanel : function renderPanel( speed ){\n speed = ( speed !== undefined )?( speed ):( 'fast' );\n this.panel.setElement( this.$panel() ).render( speed );\n if( this.currentHistory ){\n this.panel.$list().before( this.panel._renderDropTargetHelp() );\n }\n return this;\n },\n\n // ------------------------------------------------------------------------ behaviors and events\n /** event map */\n events : {\n // will make this the current history\n 'click .switch-to.btn' : function(){ this.model.setAsCurrent(); },\n //TODO: remove boiler plate from next 3\n 'click .delete-history' : function(){\n var column = this;\n this.model._delete()\n .done( function( data ){ column.render(); });\n },\n 'click .undelete-history' : function(){\n var column = this;\n this.model.undelete()\n .done( function( data ){ column.render(); });\n },\n 'click .purge-history' : function(){\n if( confirm( _l( 'This will permanently remove the data. Are you sure?' ) ) ){\n var column = this;\n this.model.purge()\n .done( function( data ){ column.render(); });\n }\n },\n // will copy this history and make the copy the current history\n 'click .copy-history' : 'copy'\n },\n\n // ------------------------------------------------------------------------ non-current controls\n /** Open a modal to get a new history name, copy it (if not canceled), and makes the copy current */\n copy : function copy(){\n historyCopyDialog( this.model );\n },\n\n // ------------------------------------------------------------------------ templates\n /** controls template displaying controls above the panel based on this.currentHistory */\n controlsLeftTemplate : _.template([\n '
',\n '<% if( data.history.isCurrentHistory ){ %>',\n '', _l( 'Current History' ), '',\n '<% } else { %>',\n '',\n '<% } %>',\n '
'\n ].join( '' ), { variable : 'data' }),\n\n /** controls template displaying controls above the panel based on this.currentHistory */\n controlsRightTemplate : _.template([\n '
',\n '<% if( !data.history.purged ){ %>',\n '
',\n '',\n '',\n '
',\n '<% } %>',\n '
'\n ].join( '' ), { variable: 'data' }),\n\n // ------------------------------------------------------------------------ misc\n /** String rep */\n toString : function(){\n return 'HistoryViewColumn(' + ( this.panel? this.panel : '' ) + ')';\n }\n});\n\n\n//==============================================================================\n/** @class A view of a HistoryCollection and displays histories similarly to the current history panel.\n */\nvar MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({\n _logNamespace : logNamespace,\n\n className : 'multi-panel-history',\n\n // ------------------------------------------------------------------------ set up\n /** Set up internals, history collection, and columns to display the history */\n initialize : function initialize( options ){\n options = options || {};\n this.log( this + '.init', options );\n\n // add the className here (since we gen. pass the el in options)\n this.$el.addClass( this.className );\n\n // --- instance vars\n //TODO: move these to some defaults\n this.options = {\n columnWidth : 312,\n borderWidth : 1,\n columnGap : 8,\n headerHeight : 29,\n footerHeight : 0,\n controlsHeight : 20\n };\n\n /** how many histories to get when fetching a new batch/page */\n this.perPage = options.perPage || 10;\n\n /** named ajax queue for loading hdas */\n this.hdaQueue = new ajaxQueue.NamedAjaxQueue( [], false );\n\n // --- set up models, sub-views, and listeners\n /** the original unfiltered and unordered collection of histories */\n this.collection = null;\n /** model id to column map */\n this.columnMap = {};\n /** model id to column map */\n this.columnOptions = options.columnOptions || {};\n\n /** what to search for within all histories */\n this.historySearch = null;\n /** what to search for within all datasets */\n this.datasetSearch = null;\n\n this.setCollection( options.histories );\n this.setUpListeners();\n },\n\n /** Set up reflexive listeners */\n setUpListeners : function setUpListeners(){\n var multipanel = this;\n //multipanel.log( 'setUpListeners', multipanel );\n this.on( 'end-of-scroll', function(){\n multipanel.collection.fetchMore();\n });\n },\n\n // ------------------------------------------------------------------------ collection\n /** Set up a (new) history collection, sorting and adding listeners\n * @fires 'new-collection' when set with this view as the arg\n */\n setCollection : function setCollection( collection ){\n // console.log( 'setCollection:', collection );\n this.stopListening( this.collection );\n\n this.collection = collection || new HISTORY_MODEL.HistoryCollection();\n this.setUpCollectionListeners();\n\n this.createColumns();\n this.hdaQueue.clear();\n\n this.trigger( 'new-collection', this );\n return this;\n },\n\n /** Set up a (new) history collection, sorting and adding listeners\n * @fires 'new-collection' when set with this view as the arg\n */\n addModels : function addModels( models, collection, options ){\n // console.log( 'addModels:', models, collection, options );\n options = options || {};\n var multipanel = this;\n models = _.isArray( models )? models : [ models ];\n models.forEach( function( model ){\n multipanel.addColumn( model, false );\n // if this is from a fetch, sort will be called and it will call render\n });\n return this;\n },\n\n /** Set up listeners for the collection - handling: added histories, change of current, deletion, and sorting */\n setUpCollectionListeners : function(){\n var multipanel = this;\n multipanel.listenTo( multipanel.collection, {\n // handle ajax errors from the collection\n 'error' : multipanel.errorHandler,\n // add multiple models\n 'add' : multipanel.addModels,\n // when all the histories a user has have been fetched\n 'all-fetched' : multipanel._postFetchAll,\n // handle addition of histories, triggered by column copy and create new\n 'new-current' : multipanel.addAsCurrentColumn,\n // handle setting a history as current, triggered by history.setAsCurrent\n 'set-as-current' : multipanel.setCurrentHistory,\n // handle deleting a history (depends on whether panels is including deleted or not)\n 'change:deleted change:purged' : multipanel.handleDeletedHistory,\n // re-render columns after a sort\n 'sort' : function(){\n multipanel.renderColumns( 0 );\n },\n });\n },\n\n _postFetchAll : function( fetchData ){\n // console.log( '_postFetchAll' );\n this.$( '.histories-loading-indicator' ).remove();\n // when new histories is fetched and the indicator is not required,\n // the panel will jump slightly left - totally aesthetic but jarring\n // TODO: this probably would be best handled elsewhere during a refinement cycle (if any)\n if( !this.historySearch ){\n var $scrollContainer = this.$( '.outer-middle' );\n $scrollContainer.scrollLeft( $scrollContainer.scrollLeft() + 24 );\n }\n },\n\n /** Re-render and set currentHistoryId to reflect a new current history */\n setCurrentHistory : function setCurrentHistory( history ){\n this.log( 'setCurrentHistory:', history );\n var oldCurrentColumn = _.findWhere( this.columnMap, { currentHistory: true });\n if( oldCurrentColumn ){\n oldCurrentColumn.currentHistory = false;\n oldCurrentColumn.$el.height( '' );\n }\n\n var newCurrentColumn = this.columnMap[ this.collection.currentHistoryId ];\n newCurrentColumn.currentHistory = true;\n this.collection.sort();\n this._recalcFirstColumnHeight();\n return newCurrentColumn;\n },\n\n /** Either remove a deleted history or re-render it to show the deleted message\n * based on collection.includeDeleted\n */\n handleDeletedHistory : function handleDeletedHistory( history ){\n if( history.get( 'deleted' ) || history.get( 'purged' ) ){\n this.log( 'handleDeletedHistory', this.collection.includeDeleted, history );\n var multipanel = this,\n column = multipanel.columnMap[ history.id ];\n if( !column ){ return; }\n\n // if it's the current column, create a new, empty history as the new current\n if( column.model.id === this.collection.currentHistoryId ){\n //TODO: figuring out the order of async here is tricky\n // - for now let the user handle the two step process\n //multipanel.collection.create().done( function(){\n // if( !multipanel.collection.includeDeleted ){ multipanel.removeColumn( column, false ); }\n //});\n } else if( !multipanel.collection.includeDeleted ){\n multipanel.removeColumn( column );\n }\n }\n },\n\n // ........................................................................ error handling\n /** Event handler for errors (from the history collection mainly)\n * Alternately use two strings for model and xhr to use custom message and title (respectively)\n * (e.g. this.trigger( 'error', 'Heres a message', 'Heres a title' ))\n * @param {Model or View} model the (Backbone) source of the error\n * @param {XMLHTTPRequest} xhr any ajax obj. assoc. with the error\n * @param {Object} options the options map commonly used with bbone ajax\n */\n errorHandler : function( model, xhr, options ){\n // interrupted ajax or no connection\n if( xhr && xhr.status === 0 && xhr.readyState === 0 ){\n // return ERROR_MODAL.offlineErrorModal();\n // fail silently\n return;\n }\n // otherwise, leave something to report in the console\n this.error( model, xhr, options );\n // and feedback to a modal\n // if sent two strings (and possibly details as 'options'), use those as message and title\n if( _.isString( model ) && _.isString( xhr ) ){\n var message = model;\n var title = xhr;\n return ERROR_MODAL.errorModal( message, title, options );\n }\n // bad gateway\n // TODO: possibly to global handler\n if( xhr && xhr.status === 502 ){\n return ERROR_MODAL.badGatewayErrorModal();\n }\n return ERROR_MODAL.ajaxErrorModal( model, xhr, options );\n },\n\n /** If Galaxy object is available handle error there, otherwise, locally (and crudely) */\n _ajaxErrorHandler : function(){\n ERROR_MODAL.ajaxErrorModal.apply( null, _.toArray( arguments ) );\n },\n\n /** create a new history and set it to current */\n create : function( ev ){\n return this.collection.create({ current: true });\n },\n\n // ------------------------------------------------------------------------ columns\n /** create columns from collection */\n createColumns : function createColumns( models, columnOptions ){\n columnOptions = columnOptions || this.options.columnOptions;\n var multipanel = this;\n // clear column map\n // TODO: make cummulative\n multipanel.columnMap = {};\n multipanel.collection.each( function( model, i ){\n var column = multipanel.createColumn( model, columnOptions );\n multipanel.columnMap[ model.id ] = column;\n });\n },\n\n /** create a column and its panel and set up any listeners to them */\n createColumn : function createColumn( history, options ){\n // options passed can be re-used, so extend them before adding the model to prevent pollution for the next\n options = _.extend( {}, options, {\n model : history,\n purgeAllowed: Galaxy.config.allow_user_dataset_purge\n });\n var column = new HistoryViewColumn( options );\n if( history.id === this.collection.currentHistoryId ){ column.currentHistory = true; }\n this.setUpColumnListeners( column );\n if( this.datasetSearch ){\n column.panel.searchItems( this.datasetSearch );\n this.queueHdaFetchDetails( column );\n }\n return column;\n },\n\n /** add a new column for history and render all columns if render is true */\n addColumn : function add( history, render ){\n // console.debug( 'adding column for:', history, render );\n render = render !== undefined? render : true;\n var newColumn = this.createColumn( history );\n this.columnMap[ history.id ] = newColumn;\n if( render ){\n this.renderColumns();\n }\n return newColumn;\n },\n\n /** add a new column for history and make it the current history/column */\n addAsCurrentColumn : function add( history, collection, options ){\n //this.log( 'adding current column for:', history );\n var multipanel = this,\n newColumn = this.addColumn( history, false );\n this.setCurrentHistory( history );\n newColumn.once( 'rendered', function(){\n multipanel.queueHdaFetch( newColumn );\n });\n return newColumn;\n },\n\n /** remove the given column, it's listeners, and optionally render */\n removeColumn : function remove( column, render ){\n render = render !== undefined? render : true;\n this.log( 'removeColumn', column );\n if( !column ){ return; }\n var multipanel = this,\n widthToRemove = this.options.columnWidth + this.options.columnGap;\n column.$el.fadeOut( 'fast', function(){\n if( render ){\n $( this ).remove();\n multipanel.$( '.middle' ).width( multipanel.$( '.middle' ).width() - widthToRemove );\n multipanel.checkColumnsInView();\n multipanel._recalcFirstColumnHeight();\n }\n\n //TODO: to freeColumn (where Columns have freePanel)\n multipanel.stopListening( column.panel );\n multipanel.stopListening( column );\n delete multipanel.columnMap[ column.model.id ];\n column.remove();\n });\n },\n\n /** set up listeners for a column and it's panel - handling: hda lazy-loading, drag and drop */\n setUpColumnListeners : function setUpColumnListeners( column ){\n var multipanel = this;\n multipanel.listenTo( column, {\n //'all': function(){ console.info( 'column ' + column + ':', arguments ) },\n 'in-view': multipanel.queueHdaFetch\n });\n\n multipanel.listenTo( column.panel, {\n //'all': function(){ console.info( 'panel ' + column.panel + ':', arguments ) },\n\n 'view:draggable:dragstart': function( ev, view, panel, column ){\n multipanel._dropData = JSON.parse( ev.dataTransfer.getData( 'text' ) );\n multipanel.currentColumnDropTargetOn();\n },\n 'view:draggable:dragend': function( ev, view, panel, column ){\n multipanel._dropData = null;\n multipanel.currentColumnDropTargetOff();\n },\n 'droptarget:drop': function( ev, data, panel ){\n //note: bad copy sources fail silently\n var toCopy = multipanel._dropData.filter( function( json ){\n return panel.model.contents.isCopyable( json );\n });\n multipanel._dropData = null;\n\n var queue = new ajaxQueue.NamedAjaxQueue();\n if( panel.model.contents.currentPage !== 0 ){\n queue.add({\n name : 'fetch-front-page',\n fn : function(){\n return panel.model.contents.fetchPage( 0 );\n }\n });\n }\n // need to reverse to better match expected order\n // TODO: reconsider order in list-view._setUpItemViewListeners, dragstart (instead of here)\n toCopy.reverse().forEach( function( content ){\n queue.add({\n name : 'copy-' + content.id,\n fn : function(){\n return panel.model.contents.copy( content );\n }\n });\n });\n queue.start();\n queue.done( function( responses ){\n panel.model.fetch();\n });\n }\n });\n },\n\n /** conv. fn to count the columns in columnMap */\n columnMapLength : function(){\n return Object.keys( this.columnMap ).length;\n },\n\n /** return array of Columns filtered by filters and sorted to match the collection\n * @param: filters Function[] array of filter fns\n */\n sortedFilteredColumns : function( filters ){\n filters = filters || this.filters;\n if( !filters || !filters.length ){\n return this.sortedColumns();\n }\n var multipanel = this;\n return multipanel.sortedColumns().filter( function( column, index ){\n var filtered = column.currentHistory || _.every( filters.map( function( filter ){\n return filter.call( column );\n }));\n return filtered;\n });\n },\n\n /** return array of Columns sorted to match the collection */\n sortedColumns : function(){\n var multipanel = this;\n var sorted = this.collection.map( function( history, index ){\n return multipanel.columnMap[ history.id ];\n });\n return sorted;\n },\n\n // ------------------------------------------------------------------------ render\n /** Render this view, columns, and set up view plugins */\n render : function render( speed ){\n speed = speed !== undefined? speed: this.fxSpeed;\n var multipanel = this;\n\n multipanel.log( multipanel + '.render' );\n multipanel.$el.html( multipanel.mainTemplate( multipanel ) );\n multipanel.renderColumns( speed );\n\n // set the columns to full height allowed and set up behaviors for thie multipanel\n multipanel.setUpBehaviors();\n //TODO: wrong - has to wait for columns to render\n // - create a column listener that fires this when all columns are rendered\n multipanel.trigger( 'rendered', multipanel );\n return multipanel;\n },\n\n /** Render the columns and panels */\n renderColumns : function renderColumns( speed ){\n speed = _.isNumber( speed )? speed: this.fxSpeed;\n // console.log( 'renderColumns:', speed );\n // render columns and track the total number rendered, firing an event when all are rendered\n var self = this;\n var sortedAndFiltered = self.sortedFilteredColumns();\n // console.log( '\\t sortedAndFiltered:', sortedAndFiltered );\n var $middle = self.$( '.middle' ).empty();\n\n self._addColumns( sortedAndFiltered, speed );\n if( !self.collection.allFetched ){\n $middle.append( self.loadingIndicatorTemplate( self ) );\n }\n //TODO: sorta - at least their fx queue has started the re-rendering\n self.trigger( 'columns-rendered', sortedAndFiltered, self );\n\n if( self.datasetSearch && sortedAndFiltered.length <= 1 ){\n\n } else {\n // check for in-view, hda lazy-loading if so\n self.checkColumnsInView();\n // the first, current column has position: fixed and flex css will not apply - adjust height manually\n self._recalcFirstColumnHeight();\n }\n return sortedAndFiltered;\n },\n\n _addColumns : function( columns, speed ){\n speed = _.isNumber( speed )? speed: this.fxSpeed;\n var $middle = this.$( '.middle' );\n\n var numExisting = $middle.children( '.history-column' ).length;\n $middle.width( this._calcMiddleWidth( columns.length + numExisting ) );\n\n columns.forEach( function( column, i ){\n column.delegateEvents().render( speed ).$el.appendTo( $middle );\n });\n },\n\n _calcMiddleWidth : function( numColumns ){\n var preventStackWidthAdj = 16;\n return (\n numColumns * ( this.options.columnWidth + this.options.columnGap ) +\n // last column gap\n this.options.columnGap +\n // the amount that safely prevents stacking of columns when adding a new one\n preventStackWidthAdj\n );\n },\n\n //TODO: combine the following two more sensibly\n //TODO: could have HistoryContents.haveDetails return false\n // if column.model.contents.length === 0 && !column.model.get( 'empty' ) then just check that\n /** Get the *summary* contents of a column's history (and details on any expanded contents),\n * queueing the ajax call and using a named queue to prevent the call being sent twice\n */\n queueHdaFetch : function queueHdaFetch( column ){\n // console.log( column.model + '.contentsShown:', column.model.contentsShown() );\n var contents = column.model.contents;\n // console.log( 'queueHdaFetch:', column, column.model.get( 'contents_active' ) );\n // if the history model says it has hdas but none are present, queue an ajax req for them\n if( contents.length === 0 && column.model.contentsShown() ){\n var fetchOptions = { silent: true };\n var ids = _.values( contents.storage.allExpanded() ).join();\n if( ids ){ fetchOptions.details = ids; }\n // this uses a 'named' queue so that duplicate requests are ignored\n this.hdaQueue.add({\n name : column.model.id,\n fn : function(){\n return contents.fetchCurrentPage( fetchOptions )\n .done( function(){ column.panel.renderItems(); });\n }\n });\n // the queue is re-used, so if it's not processing requests - start it again\n if( !this.hdaQueue.running ){ this.hdaQueue.start(); }\n }\n },\n\n /** Get the *detailed* json for *all* of a column's history's contents - req'd for searching */\n queueHdaFetchDetails : function( column ){\n var contents = column.model.contents;\n var needsContentsLoaded = contents.length === 0 && column.model.contentsShown();\n if( needsContentsLoaded || !contents.haveDetails() ){\n // this uses a 'named' queue so that duplicate requests are ignored\n this.hdaQueue.add({\n name : column.model.id,\n fn : function(){\n return contents.progressivelyFetchDetails()\n .done( function(){ column.panel._renderEmptyMessage(); });\n }\n });\n // the queue is re-used, so if it's not processing requests - start it again\n if( !this.hdaQueue.running ){ this.hdaQueue.start(); }\n }\n },\n\n /** put a text msg in the header */\n renderInfo : function( msg ){\n return this.$( '.header .header-info' ).text( msg );\n },\n\n // ------------------------------------------------------------------------ events/behaviors\n events : {\n // will move to the server root (gen. Analyze data)\n 'click .done.btn' : 'close',\n // creates a new empty history and makes it current\n 'click .create-new.btn' : 'create',\n 'click #include-deleted' : '_clickToggleDeletedHistories',\n // these change the collection and column sort order\n 'click .order .set-order' : '_chooseOrder',\n 'click #toggle-deleted' : '_clickToggleDeletedDatasets',\n 'click #toggle-hidden' : '_clickToggleHiddenDatasets',\n //'dragstart .list-item .title-bar' : function( e ){ console.debug( 'ok' ); }\n },\n\n close : function( ev ){\n //TODO: switch to pushState/router\n window.location = Galaxy.root;\n },\n\n _clickToggleDeletedHistories : function( ev ){\n this.toggleDeletedHistories( $( ev.currentTarget ).is( ':checked' ) );\n this.toggleOptionsPopover();\n },\n /** Include deleted histories in the collection */\n toggleDeletedHistories : function( show ){\n if( show ){\n window.location = Galaxy.root + 'history/view_multiple?include_deleted_histories=True';\n } else {\n window.location = Galaxy.root + 'history/view_multiple';\n }\n },\n\n _clickToggleDeletedDatasets : function( ev ){\n this.toggleDeletedDatasets( $( ev.currentTarget ).is( ':checked' ) );\n this.toggleOptionsPopover();\n },\n toggleDeletedDatasets : function( show ){\n show = show !== undefined? show : false;\n var multipanel = this;\n multipanel.sortedFilteredColumns().forEach( function( column, i ){\n _.delay( function(){\n column.panel.toggleShowDeleted( show, false );\n }, i * 200 );\n });\n },\n\n _clickToggleHiddenDatasets : function( ev ){\n this.toggleHiddenDatasets( $( ev.currentTarget ).is( ':checked' ) );\n this.toggleOptionsPopover();\n },\n toggleHiddenDatasets : function( show ){\n show = show !== undefined? show : false;\n var multipanel = this;\n multipanel.sortedFilteredColumns().forEach( function( column, i ){\n _.delay( function(){\n column.panel.toggleShowHidden( show, false );\n }, i * 200 );\n });\n },\n\n /** change the collection order and re-fetch when the drop down in the options menu is changed */\n _chooseOrder : function( ev ){\n var multipanel = this,\n collection = multipanel.collection,\n orderKey = $( ev.currentTarget ).data( 'order' );\n // set the sort order text also\n multipanel.$( '.current-order' ).text( multipanel.orderDescriptions[ orderKey ] );\n multipanel.toggleOptionsPopover();\n // set the order and re-fetch using the new order, saving the current history as the first\n collection.setOrder( orderKey );\n var currentHistoryModel = collection.slice( 0, 1 );\n collection.fetchFirst().done( function(){\n collection.unshift( currentHistoryModel, { silent: true });\n multipanel.createColumns();\n // need to clear this or previously fetched contents won't refetch now (bc of named queue)\n multipanel.hdaQueue.clear();\n multipanel.render();\n });\n multipanel.once( 'columns-rendered', multipanel._scrollLeft );\n //TODO: check allFetched and do not reset if so - just sort instead\n },\n\n /** scroll the column container right or left */\n _scrollLeft : function( val ){\n val = _.isNumber( val )? val : 0;\n this.$( '.outer-middle' ).scrollLeft( val );\n },\n\n /** Set up any view plugins */\n setUpBehaviors : function(){\n var multipanel = this;\n multipanel._moreOptionsPopover();\n\n // input to search histories\n multipanel.$( '#search-histories' ).searchInput({\n name : 'search-histories',\n placeholder : _l( 'search histories' ),\n\n onfirstsearch : function( searchFor ){\n multipanel.$( '#search-histories' ).searchInput( 'toggle-loading' );\n multipanel.renderInfo( _l( 'loading all histories for search' ) );\n multipanel.collection.fetchAll()\n .done( function(){\n multipanel.$( '#search-histories' ).searchInput( 'toggle-loading' );\n multipanel.renderInfo( '' );\n });\n },\n onsearch : function( searchFor ){\n multipanel.historySearch = searchFor;\n multipanel.filters = [ function(){\n return this.model.matchesAll( multipanel.historySearch );\n }];\n multipanel.renderColumns( 0 );\n },\n onclear : function( searchFor ){\n multipanel.historySearch = null;\n //TODO: remove specifically not just reset\n multipanel.filters = [];\n multipanel.renderColumns( 0 );\n }\n });\n\n // input to search datasets\n multipanel.$( '#search-datasets' ).searchInput({\n name : 'search-datasets',\n placeholder : _l( 'search all datasets' ),\n\n onfirstsearch : function( searchFor ){\n multipanel.hdaQueue.clear();\n multipanel.$( '#search-datasets' ).searchInput( 'toggle-loading' );\n multipanel.datasetSearch = searchFor;\n multipanel.sortedFilteredColumns().forEach( function( column ){\n column.panel.searchItems( searchFor );\n // load details for them that need\n multipanel.queueHdaFetchDetails( column );\n });\n multipanel.hdaQueue.progress( function( progress ){\n multipanel.renderInfo([\n _l( 'searching' ), ( progress.curr + 1 ), _l( 'of' ), progress.total\n ].join( ' ' ));\n });\n multipanel.hdaQueue.deferred.done( function(){\n multipanel.renderInfo( '' );\n multipanel.$( '#search-datasets' ).searchInput( 'toggle-loading' );\n });\n },\n onsearch : function( searchFor ){\n multipanel.datasetSearch = searchFor;\n multipanel.sortedFilteredColumns().forEach( function( column ){\n column.panel.searchItems( searchFor );\n });\n },\n onclear : function( searchFor ){\n multipanel.datasetSearch = null;\n multipanel.sortedFilteredColumns().forEach( function( column ){\n column.panel.clearSearch();\n });\n }\n });\n\n // resize first (fixed position) column on page resize\n $( window ).resize( function(){\n multipanel._recalcFirstColumnHeight();\n });\n\n // when scrolling - check for histories now in view: they will fire 'in-view' and queueHdaLoading if necc.\n //TODO:?? might be able to simplify and not use pub-sub\n var debouncedInView = _.debounce( function _debouncedInner(){\n var viewport = multipanel._viewport();\n multipanel.checkColumnsInView( viewport );\n multipanel.checkForEndOfScroll( viewport );\n }, 100 );\n this.$( '.middle' ).parent().scroll( debouncedInView );\n },\n\n /** create the options popover */\n _moreOptionsPopover : function(){\n return this.$( '.open-more-options.btn' ).popover({\n container : '.header',\n placement : 'bottom',\n html : true,\n content : $( this.optionsPopoverTemplate( this ) )\n });\n },\n\n /** change the collection order and re-fetch when the drop down in the options menu is changed */\n toggleOptionsPopover : function( ev ){\n // hide seems broken in our version\n this.$( '.open-more-options.btn' ).popover( 'toggle' );\n },\n\n /** Adjust the height of the first, current column since flex-boxes won't work with fixed postiion elements */\n _recalcFirstColumnHeight : function(){\n var $firstColumn = this.$( '.history-column' ).first(),\n middleHeight = this.$( '.middle' ).height(),\n controlHeight = $firstColumn.find( '.panel-controls' ).height();\n $firstColumn.height( middleHeight )\n .find( '.inner' ).height( middleHeight - controlHeight );\n },\n\n /** Get the left and right pixel coords of the middle element */\n _viewport : function(){\n var $outerMiddle = this.$( '.middle' ).parent(),\n viewLeft = $outerMiddle.offset().left,\n width = $outerMiddle.width();\n return {\n left : viewLeft,\n right : viewLeft + width\n };\n },\n\n /** returns the columns currently in the viewport */\n columnsInView : function( viewport ){\n //TODO: uses offset which is render intensive\n //TODO: 2N - could use arg filter (sortedFilteredColumns( filter )) instead\n var vp = viewport || this._viewport();\n return this.sortedFilteredColumns().filter( function( column ){\n return column.currentHistory || column.inView( vp.left, vp.right );\n });\n },\n\n //TODO: sortByInView - return cols in view, then others\n /** trigger in-view from columns in-view */\n checkColumnsInView : function(){\n //TODO: assbackward - don't fire from the column, fire from here and listen from here\n this.columnsInView().forEach( function( column ){\n column.trigger( 'in-view', column );\n });\n },\n\n /** is the middle, horizontally scrolling section scrolled fully to the right? */\n checkForEndOfScroll : function( viewport ){\n viewport = viewport || this._viewport();\n var END_PADDING = 16,\n $middle = this.$( '.middle' ),\n scrollRight = $middle.parent().scrollLeft() + viewport.right;\n if( scrollRight >= ( $middle.width() - END_PADDING ) ){\n this.trigger( 'end-of-scroll' );\n }\n },\n\n /** Show and enable the current columns drop target */\n currentColumnDropTargetOn : function(){\n var currentColumn = this.columnMap[ this.collection.currentHistoryId ];\n if( !currentColumn ){ return; }\n //TODO: fix this - shouldn't need monkeypatch\n currentColumn.panel.dataDropped = function( data ){};\n currentColumn.panel.dropTargetOn();\n },\n\n /** Hide and disable the current columns drop target */\n currentColumnDropTargetOff : function(){\n var currentColumn = this.columnMap[ this.collection.currentHistoryId ];\n if( !currentColumn ){ return; }\n currentColumn.panel.dataDropped = HISTORY_VIEW_EDIT.HistoryViewEdit.prototype.dataDrop;\n // slight override of dropTargetOff to not erase drop-target-help\n currentColumn.panel.dropTarget = false;\n currentColumn.panel.$( '.history-drop-target' ).remove();\n },\n\n // ------------------------------------------------------------------------ misc\n /** String rep */\n toString : function(){\n return 'MultiPanelColumns(' + ( this.columns? this.columns.length : 0 ) + ')';\n },\n\n // ------------------------------------------------------------------------ templates\n mainTemplate : _.template([\n '
',\n '
',\n '',\n '
',\n '
',\n '',\n '',\n '',\n '
',\n // feedback\n '
',\n '
', '
',\n '
',\n '
',\n ' ',\n '
',\n '
',\n // middle - where the columns go\n '
',\n '
',\n '
',\n // footer\n '
'\n ].join(''), { variable: 'view' }),\n\n loadingIndicatorTemplate : _.template([\n '
',\n '', _l( 'Loading histories' ), '...',\n '
'\n ].join(''), { variable: 'view' }),\n\n orderDescriptions : {\n 'update_time' : _l( 'most recent first' ),\n 'update_time-asc' : _l( 'least recent first' ),\n 'name' : _l( 'name, a to z' ),\n 'name-dsc' : _l( 'name, z to a' ),\n 'size' : _l( 'size, large to small' ),\n 'size-asc' : _l( 'size, small to large' )\n },\n\n optionsPopoverTemplate : _.template([\n '
',\n '
',\n '',\n '',\n '
',\n\n '
',\n\n '
',\n\n '
',\n '
',\n '
'\n ].join(''), { variable: 'view' })\n\n});\n\n\n//==============================================================================\n return {\n MultiPanelColumns : MultiPanelColumns\n };\n});\n"]} \ No newline at end of file +{"version":3,"sources":["mvc/history/multi-panel.js"],"names":["define","_l","HISTORY_MODEL","HISTORY_VIEW_EDIT","historyCopyDialog","ERROR_MODAL","baseMVC","ajaxQueue","_logNamespace","HistoryViewColumn","Backbone","View","extend","LoggableMixin","tagName","className","id","initialize","options","this","model","get","purgeAllowed","_","isUndefined","createPanel","panel","panelOptions","$scrollContainer","HistoryViewEdit","defaults","dragItems","$el","column","once","trigger","setUpPanelListeners","listenTo","rendered","view:expanded view:rendered","view","$","off","inView","viewLeft","viewRight","columnLeft","offset","left","width","$panel","render","speed","modelData","html","template","renderPanel","css","setUpBehaviors","data","isCurrentHistory","currentHistory","controlsRightTemplate","history","undefined","join","setElement","events","$list","before","_renderDropTargetHelp","setAsCurrent","click .delete-history","done","undelete","click .undelete-history","confirm","click .purge-history","purge","click .copy-history","copy","controlsLeftTemplate","variable","MultiPanelColumns","addClass","columnWidth","borderWidth","headerHeight","footerHeight","controlsHeight","perPage","toString","log","columnGap","setCollection","collection","hdaQueue","createColumns","NamedAjaxQueue","columnMap","columnOptions","historySearch","datasetSearch","models","histories","multipanel","setUpListeners","setUpCollectionListeners","fetchMore","stopListening","HistoryCollection","addModels","setCurrentHistory","scrollLeft","forEach","addColumn","oldCurrentColumn","error","add","all-fetched","_postFetchAll","new-current","addAsCurrentColumn","set-as-current","handleDeletedHistory","sort","fetchData","includeDeleted","findWhere","height","newCurrentColumn","currentHistoryId","errorHandler","_recalcFirstColumnHeight","isString","message","title","removeColumn","xhr","status","readyState","createColumn","errorModal","badGatewayErrorModal","ajaxErrorModal","_ajaxErrorHandler","queueHdaFetchDetails","apply","toArray","arguments","create","ev","current","renderColumns","each","i","newColumn","Galaxy","config","allow_user_dataset_purge","setUpColumnListeners","searchItems","queueHdaFetch","_dropData","currentColumnDropTargetOn","currentColumnDropTargetOff","remove","widthToRemove","toCopy","contents","queue","name","view:draggable:dragstart","start","JSON","parse","dataTransfer","getData","view:draggable:dragend","droptarget:drop","columnMapLength","filter","json","Object","keys","length","currentPage","sortedFilteredColumns","filters","fn","sortedColumns","fetchPage","reverse","content","filtered","sorted","fetch","index","every","map","call","$middle","self","_addColumns","sortedAndFiltered","fxSpeed","checkColumnsInView","mainTemplate","isNumber","_calcMiddleWidth","preventStackWidthAdj","empty","append","loadingIndicatorTemplate","columns","fetchOptions","details","ids","numExisting","children","fetchCurrentPage","renderItems","appendTo","numColumns","running","_renderEmptyMessage","contentsShown","silent","values","storage","allExpanded","renderInfo","haveDetails","progressivelyFetchDetails","location","toggleDeletedHistories","currentTarget","show","msg","window","text","_clickToggleDeletedDatasets","click .create-new.btn","click #include-deleted","click #toggle-deleted","close","root","_clickToggleDeletedHistories","toggleOptionsPopover","is","toggleHiddenDatasets","toggleShowHidden","_chooseOrder","toggleDeletedDatasets","currentHistoryModel","_scrollLeft","val","_moreOptionsPopover","orderKey","orderDescriptions","placeholder","onfirstsearch","slice","searchInput","clear","onclear","searchFor","onsearch","clearSearch","resize","viewport","_viewport","progress","checkForEndOfScroll","total","deferred","container","placement","optionsPopoverTemplate","$firstColumn","middleHeight","debouncedInView","debounce","$outerMiddle","parent","scroll","popover","columnsInView","first","controlHeight","find","scrollRight","right","currentColumn","dataDropped","vp","dropTargetOn","prototype","dataDrop","dropTarget","update_time","update_time-asc","name-dsc","size","size-asc"],"mappings":"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","file":"../../../scripts/mvc/history/multi-panel.js","sourcesContent":["define([\n \"utils/localization\",\n \"mvc/history/history-model\",\n \"mvc/history/history-view-edit\",\n \"mvc/history/copy-dialog\",\n \"mvc/ui/error-modal\",\n \"mvc/base-mvc\",\n \"utils/ajax-queue\",\n \"ui/mode-button\",\n \"ui/search-input\",\n], function( _l, HISTORY_MODEL, HISTORY_VIEW_EDIT, historyCopyDialog, ERROR_MODAL, baseMVC, ajaxQueue){\n'use strict';\n\nvar logNamespace = 'history';\n/* ==============================================================================\nTODO:\n\n============================================================================== */\n/** @class A container for a history panel that renders controls for that history (delete, copy, etc.) */\nvar HistoryViewColumn = Backbone.View.extend( baseMVC.LoggableMixin ).extend({\n\n _logNamespace : logNamespace,\n\n tagName : 'div',\n className : 'history-column flex-column flex-row-container',\n id : function id(){\n if( !this.model ){ return ''; }\n return 'history-column-' + this.model.get( 'id' );\n },\n\n // ------------------------------------------------------------------------ set up\n /** set up passed-in panel (if any) and listeners */\n initialize : function initialize( options ){\n options = options || {};\n this.purgeAllowed = !_.isUndefined( options.purgeAllowed )? options.purgeAllowed: false;\n this.panel = options.panel || this.createPanel( options );\n\n this.setUpListeners();\n },\n\n /** create a history panel for this column */\n createPanel : function createPanel( panelOptions ){\n return new HISTORY_VIEW_EDIT.HistoryViewEdit( _.defaults( panelOptions, {\n model : this.model,\n // non-current panels should set their hdas to draggable\n purgeAllowed : this.purgeAllowed,\n dragItems : true,\n $scrollContainer: function(){ return this.$el; },\n }));\n },\n\n /** set up reflexive listeners */\n setUpListeners : function setUpListeners(){\n var column = this;\n //this.log( 'setUpListeners', this );\n this.once( 'rendered', function(){\n column.trigger( 'rendered:initial', column );\n });\n this.setUpPanelListeners();\n },\n\n /** set listeners needed for panel */\n setUpPanelListeners : function setUpPanelListeners(){\n var column = this;\n this.listenTo( this.panel, {\n //'all': function(){ console.info( 'panel of ' + this, arguments ); },\n\n // assumes panel will take the longest to render\n 'rendered': function(){\n column.trigger( 'rendered', column );\n },\n // when a panel's view expands turn off the click handler on the rerun button so that it uses it's href\n // this allows the button to open the tool rerun form in a new tab (instead of erroring)\n // TODO: hack\n 'view:expanded view:rendered': function( view ){\n view.$( '.rerun-btn' ).off();\n }\n }, this );\n },\n\n /** do the dimensions of this column overlap the given (horizontal) browser coords? */\n inView : function( viewLeft, viewRight ){\n var columnLeft = this.$el.offset().left,\n columnRight = columnLeft + this.$el.width();\n if( columnRight < viewLeft ){ return false; }\n if( columnLeft > viewRight ){ return false; }\n return true;\n },\n\n /** shortcut to the panel */\n $panel : function $panel(){\n return this.$( '.history-panel' );\n },\n\n // ------------------------------------------------------------------------ render\n /** render ths column, its panel, and set up plugins */\n render : function render( speed ){\n speed = ( speed !== undefined )?( speed ):( 'fast' );\n //this.log( this + '.render', this.$el, this.el );\n //TODO: not needed\n var modelData = this.model? this.model.toJSON(): {};\n this.$el.html( this.template( modelData ) );\n this.renderPanel( speed );\n // jq 1.12 doesn't fade/show properly when display: flex, re-set here\n this.panel.$el.css( 'display', 'flex' );\n // if model and not children\n // template\n // render controls\n this.setUpBehaviors();\n // add panel\n return this;\n },\n\n /** set up plugins */\n setUpBehaviors : function setUpBehaviors(){\n //this.log( 'setUpBehaviors:', this );\n //var column = this;\n // on panel size change, ...\n },\n\n /** column body template with inner div for panel based on data (model json) */\n template : function template( data ){\n data = _.extend( data || {}, {\n isCurrentHistory : this.currentHistory\n });\n return $([\n '
',\n this.controlsLeftTemplate({ history: data, view: this }),\n //'',\n this.controlsRightTemplate({ history: data, view: this }),\n '
',\n '
',\n '
',\n '
'\n ].join( '' ));\n },\n\n /** render the panel contained in the column using speed for fx speed */\n renderPanel : function renderPanel( speed ){\n speed = ( speed !== undefined )?( speed ):( 'fast' );\n this.panel.setElement( this.$panel() ).render( speed );\n if( this.currentHistory ){\n this.panel.$list().before( this.panel._renderDropTargetHelp() );\n }\n return this;\n },\n\n // ------------------------------------------------------------------------ behaviors and events\n /** event map */\n events : {\n // will make this the current history\n 'click .switch-to.btn' : function(){ this.model.setAsCurrent(); },\n //TODO: remove boiler plate from next 3\n 'click .delete-history' : function(){\n var column = this;\n this.model._delete()\n .done( function( data ){ column.render(); });\n },\n 'click .undelete-history' : function(){\n var column = this;\n this.model.undelete()\n .done( function( data ){ column.render(); });\n },\n 'click .purge-history' : function(){\n if( confirm( _l( 'This will permanently remove the data. Are you sure?' ) ) ){\n var column = this;\n this.model.purge()\n .done( function( data ){ column.render(); });\n }\n },\n // will copy this history and make the copy the current history\n 'click .copy-history' : 'copy'\n },\n\n // ------------------------------------------------------------------------ non-current controls\n /** Open a modal to get a new history name, copy it (if not canceled), and makes the copy current */\n copy : function copy(){\n historyCopyDialog( this.model );\n },\n\n // ------------------------------------------------------------------------ templates\n /** controls template displaying controls above the panel based on this.currentHistory */\n controlsLeftTemplate : _.template([\n '
',\n '<% if( data.history.isCurrentHistory ){ %>',\n '', _l( 'Current History' ), '',\n '<% } else { %>',\n '',\n '<% } %>',\n '
'\n ].join( '' ), { variable : 'data' }),\n\n /** controls template displaying controls above the panel based on this.currentHistory */\n controlsRightTemplate : _.template([\n '
',\n '<% if( !data.history.purged ){ %>',\n '
',\n '',\n '',\n '
',\n '<% } %>',\n '
'\n ].join( '' ), { variable: 'data' }),\n\n // ------------------------------------------------------------------------ misc\n /** String rep */\n toString : function(){\n return 'HistoryViewColumn(' + ( this.panel? this.panel : '' ) + ')';\n }\n});\n\n\n//==============================================================================\n/** @class A view of a HistoryCollection and displays histories similarly to the current history panel.\n */\nvar MultiPanelColumns = Backbone.View.extend( baseMVC.LoggableMixin ).extend({\n _logNamespace : logNamespace,\n\n className : 'multi-panel-history',\n\n // ------------------------------------------------------------------------ set up\n /** Set up internals, history collection, and columns to display the history */\n initialize : function initialize( options ){\n options = options || {};\n this.log( this + '.init', options );\n\n // add the className here (since we gen. pass the el in options)\n this.$el.addClass( this.className );\n\n // --- instance vars\n //TODO: move these to some defaults\n this.options = {\n columnWidth : 312,\n borderWidth : 1,\n columnGap : 8,\n headerHeight : 29,\n footerHeight : 0,\n controlsHeight : 20\n };\n\n /** how many histories to get when fetching a new batch/page */\n this.perPage = options.perPage || 10;\n\n /** named ajax queue for loading hdas */\n this.hdaQueue = new ajaxQueue.NamedAjaxQueue( [], false );\n\n // --- set up models, sub-views, and listeners\n /** the original unfiltered and unordered collection of histories */\n this.collection = null;\n /** model id to column map */\n this.columnMap = {};\n /** model id to column map */\n this.columnOptions = options.columnOptions || {};\n\n /** what to search for within all histories */\n this.historySearch = null;\n /** what to search for within all datasets */\n this.datasetSearch = null;\n\n this.setCollection( options.histories );\n this.setUpListeners();\n },\n\n /** Set up reflexive listeners */\n setUpListeners : function setUpListeners(){\n var multipanel = this;\n //multipanel.log( 'setUpListeners', multipanel );\n this.on( 'end-of-scroll', function(){\n multipanel.collection.fetchMore();\n });\n },\n\n // ------------------------------------------------------------------------ collection\n /** Set up a (new) history collection, sorting and adding listeners\n * @fires 'new-collection' when set with this view as the arg\n */\n setCollection : function setCollection( collection ){\n // console.log( 'setCollection:', collection );\n this.stopListening( this.collection );\n\n this.collection = collection || new HISTORY_MODEL.HistoryCollection();\n this.setUpCollectionListeners();\n\n this.createColumns();\n this.hdaQueue.clear();\n\n this.trigger( 'new-collection', this );\n return this;\n },\n\n /** Set up a (new) history collection, sorting and adding listeners\n * @fires 'new-collection' when set with this view as the arg\n */\n addModels : function addModels( models, collection, options ){\n // console.log( 'addModels:', models, collection, options );\n options = options || {};\n var multipanel = this;\n models = _.isArray( models )? models : [ models ];\n models.forEach( function( model ){\n multipanel.addColumn( model, false );\n // if this is from a fetch, sort will be called and it will call render\n });\n return this;\n },\n\n /** Set up listeners for the collection - handling: added histories, change of current, deletion, and sorting */\n setUpCollectionListeners : function(){\n var multipanel = this;\n multipanel.listenTo( multipanel.collection, {\n // handle ajax errors from the collection\n 'error' : multipanel.errorHandler,\n // add multiple models\n 'add' : multipanel.addModels,\n // when all the histories a user has have been fetched\n 'all-fetched' : multipanel._postFetchAll,\n // handle addition of histories, triggered by column copy and create new\n 'new-current' : multipanel.addAsCurrentColumn,\n // handle setting a history as current, triggered by history.setAsCurrent\n 'set-as-current' : multipanel.setCurrentHistory,\n // handle deleting a history (depends on whether panels is including deleted or not)\n 'change:deleted change:purged' : multipanel.handleDeletedHistory,\n // re-render columns after a sort\n 'sort' : function(){\n multipanel.renderColumns( 0 );\n },\n });\n },\n\n _postFetchAll : function( fetchData ){\n // console.log( '_postFetchAll' );\n this.$( '.histories-loading-indicator' ).remove();\n // when new histories is fetched and the indicator is not required,\n // the panel will jump slightly left - totally aesthetic but jarring\n // TODO: this probably would be best handled elsewhere during a refinement cycle (if any)\n if( !this.historySearch ){\n var $scrollContainer = this.$( '.outer-middle' );\n $scrollContainer.scrollLeft( $scrollContainer.scrollLeft() + 24 );\n }\n },\n\n /** Re-render and set currentHistoryId to reflect a new current history */\n setCurrentHistory : function setCurrentHistory( history ){\n this.log( 'setCurrentHistory:', history );\n var oldCurrentColumn = _.findWhere( this.columnMap, { currentHistory: true });\n if( oldCurrentColumn ){\n oldCurrentColumn.currentHistory = false;\n oldCurrentColumn.$el.height( '' );\n }\n\n var newCurrentColumn = this.columnMap[ this.collection.currentHistoryId ];\n newCurrentColumn.currentHistory = true;\n this.collection.sort();\n this._recalcFirstColumnHeight();\n return newCurrentColumn;\n },\n\n /** Either remove a deleted history or re-render it to show the deleted message\n * based on collection.includeDeleted\n */\n handleDeletedHistory : function handleDeletedHistory( history ){\n if( history.get( 'deleted' ) || history.get( 'purged' ) ){\n this.log( 'handleDeletedHistory', this.collection.includeDeleted, history );\n var multipanel = this,\n column = multipanel.columnMap[ history.id ];\n if( !column ){ return; }\n\n // if it's the current column, create a new, empty history as the new current\n if( column.model.id === this.collection.currentHistoryId ){\n //TODO: figuring out the order of async here is tricky\n // - for now let the user handle the two step process\n //multipanel.collection.create().done( function(){\n // if( !multipanel.collection.includeDeleted ){ multipanel.removeColumn( column, false ); }\n //});\n } else if( !multipanel.collection.includeDeleted ){\n multipanel.removeColumn( column );\n }\n }\n },\n\n // ........................................................................ error handling\n /** Event handler for errors (from the history collection mainly)\n * Alternately use two strings for model and xhr to use custom message and title (respectively)\n * (e.g. this.trigger( 'error', 'Heres a message', 'Heres a title' ))\n * @param {Model or View} model the (Backbone) source of the error\n * @param {XMLHTTPRequest} xhr any ajax obj. assoc. with the error\n * @param {Object} options the options map commonly used with bbone ajax\n */\n errorHandler : function( model, xhr, options ){\n // interrupted ajax or no connection\n if( xhr && xhr.status === 0 && xhr.readyState === 0 ){\n // return ERROR_MODAL.offlineErrorModal();\n // fail silently\n return;\n }\n // otherwise, leave something to report in the console\n this.error( model, xhr, options );\n // and feedback to a modal\n // if sent two strings (and possibly details as 'options'), use those as message and title\n if( _.isString( model ) && _.isString( xhr ) ){\n var message = model;\n var title = xhr;\n return ERROR_MODAL.errorModal( message, title, options );\n }\n // bad gateway\n // TODO: possibly to global handler\n if( xhr && xhr.status === 502 ){\n return ERROR_MODAL.badGatewayErrorModal();\n }\n return ERROR_MODAL.ajaxErrorModal( model, xhr, options );\n },\n\n /** If Galaxy object is available handle error there, otherwise, locally (and crudely) */\n _ajaxErrorHandler : function(){\n ERROR_MODAL.ajaxErrorModal.apply( null, _.toArray( arguments ) );\n },\n\n /** create a new history and set it to current */\n create : function( ev ){\n return this.collection.create({ current: true });\n },\n\n // ------------------------------------------------------------------------ columns\n /** create columns from collection */\n createColumns : function createColumns( models, columnOptions ){\n columnOptions = columnOptions || this.options.columnOptions;\n var multipanel = this;\n // clear column map\n // TODO: make cummulative\n multipanel.columnMap = {};\n multipanel.collection.each( function( model, i ){\n var column = multipanel.createColumn( model, columnOptions );\n multipanel.columnMap[ model.id ] = column;\n });\n },\n\n /** create a column and its panel and set up any listeners to them */\n createColumn : function createColumn( history, options ){\n // options passed can be re-used, so extend them before adding the model to prevent pollution for the next\n options = _.extend( {}, options, {\n model : history,\n purgeAllowed: Galaxy.config.allow_user_dataset_purge\n });\n var column = new HistoryViewColumn( options );\n if( history.id === this.collection.currentHistoryId ){ column.currentHistory = true; }\n this.setUpColumnListeners( column );\n if( this.datasetSearch ){\n column.panel.searchItems( this.datasetSearch );\n this.queueHdaFetchDetails( column );\n }\n return column;\n },\n\n /** add a new column for history and render all columns if render is true */\n addColumn : function add( history, render ){\n // console.debug( 'adding column for:', history, render );\n render = render !== undefined? render : true;\n var newColumn = this.createColumn( history );\n this.columnMap[ history.id ] = newColumn;\n if( render ){\n this.renderColumns();\n }\n return newColumn;\n },\n\n /** add a new column for history and make it the current history/column */\n addAsCurrentColumn : function add( history, collection, options ){\n //this.log( 'adding current column for:', history );\n var multipanel = this,\n newColumn = this.addColumn( history, false );\n this.setCurrentHistory( history );\n newColumn.once( 'rendered', function(){\n multipanel.queueHdaFetch( newColumn );\n });\n return newColumn;\n },\n\n /** remove the given column, it's listeners, and optionally render */\n removeColumn : function remove( column, render ){\n render = render !== undefined? render : true;\n this.log( 'removeColumn', column );\n if( !column ){ return; }\n var multipanel = this,\n widthToRemove = this.options.columnWidth + this.options.columnGap;\n column.$el.fadeOut( 'fast', function(){\n if( render ){\n $( this ).remove();\n multipanel.$( '.middle' ).width( multipanel.$( '.middle' ).width() - widthToRemove );\n multipanel.checkColumnsInView();\n multipanel._recalcFirstColumnHeight();\n }\n\n //TODO: to freeColumn (where Columns have freePanel)\n multipanel.stopListening( column.panel );\n multipanel.stopListening( column );\n delete multipanel.columnMap[ column.model.id ];\n column.remove();\n });\n },\n\n /** set up listeners for a column and it's panel - handling: hda lazy-loading, drag and drop */\n setUpColumnListeners : function setUpColumnListeners( column ){\n var multipanel = this;\n multipanel.listenTo( column, {\n //'all': function(){ console.info( 'column ' + column + ':', arguments ) },\n 'in-view': multipanel.queueHdaFetch\n });\n\n multipanel.listenTo( column.panel, {\n //'all': function(){ console.info( 'panel ' + column.panel + ':', arguments ) },\n\n 'view:draggable:dragstart': function( ev, view, panel, column ){\n multipanel._dropData = JSON.parse( ev.dataTransfer.getData( 'text' ) );\n multipanel.currentColumnDropTargetOn();\n },\n 'view:draggable:dragend': function( ev, view, panel, column ){\n multipanel._dropData = null;\n multipanel.currentColumnDropTargetOff();\n },\n 'droptarget:drop': function( ev, data, panel ){\n //note: bad copy sources fail silently\n var toCopy = multipanel._dropData.filter( function( json ){\n return panel.model.contents.isCopyable( json );\n });\n multipanel._dropData = null;\n\n var queue = new ajaxQueue.NamedAjaxQueue();\n if( panel.model.contents.currentPage !== 0 ){\n queue.add({\n name : 'fetch-front-page',\n fn : function(){\n return panel.model.contents.fetchPage( 0 );\n }\n });\n }\n // need to reverse to better match expected order\n // TODO: reconsider order in list-view._setUpItemViewListeners, dragstart (instead of here)\n toCopy.reverse().forEach( function( content ){\n queue.add({\n name : 'copy-' + content.id,\n fn : function(){\n return panel.model.contents.copy( content );\n }\n });\n });\n queue.start();\n queue.done( function( responses ){\n panel.model.fetch();\n });\n }\n });\n },\n\n /** conv. fn to count the columns in columnMap */\n columnMapLength : function(){\n return Object.keys( this.columnMap ).length;\n },\n\n /** return array of Columns filtered by filters and sorted to match the collection\n * @param: filters Function[] array of filter fns\n */\n sortedFilteredColumns : function( filters ){\n filters = filters || this.filters;\n if( !filters || !filters.length ){\n return this.sortedColumns();\n }\n var multipanel = this;\n return multipanel.sortedColumns().filter( function( column, index ){\n var filtered = column.currentHistory || _.every( filters.map( function( filter ){\n return filter.call( column );\n }));\n return filtered;\n });\n },\n\n /** return array of Columns sorted to match the collection */\n sortedColumns : function(){\n var multipanel = this;\n var sorted = this.collection.map( function( history, index ){\n return multipanel.columnMap[ history.id ];\n });\n return sorted;\n },\n\n // ------------------------------------------------------------------------ render\n /** Render this view, columns, and set up view plugins */\n render : function render( speed ){\n speed = speed !== undefined? speed: this.fxSpeed;\n var multipanel = this;\n\n multipanel.log( multipanel + '.render' );\n multipanel.$el.html( multipanel.mainTemplate( multipanel ) );\n multipanel.renderColumns( speed );\n\n // set the columns to full height allowed and set up behaviors for thie multipanel\n multipanel.setUpBehaviors();\n //TODO: wrong - has to wait for columns to render\n // - create a column listener that fires this when all columns are rendered\n multipanel.trigger( 'rendered', multipanel );\n return multipanel;\n },\n\n /** Render the columns and panels */\n renderColumns : function renderColumns( speed ){\n speed = _.isNumber( speed )? speed: this.fxSpeed;\n // console.log( 'renderColumns:', speed );\n // render columns and track the total number rendered, firing an event when all are rendered\n var self = this;\n var sortedAndFiltered = self.sortedFilteredColumns();\n // console.log( '\\t sortedAndFiltered:', sortedAndFiltered );\n var $middle = self.$( '.middle' ).empty();\n\n self._addColumns( sortedAndFiltered, speed );\n if( !self.collection.allFetched ){\n $middle.append( self.loadingIndicatorTemplate( self ) );\n }\n //TODO: sorta - at least their fx queue has started the re-rendering\n self.trigger( 'columns-rendered', sortedAndFiltered, self );\n\n if( self.datasetSearch && sortedAndFiltered.length <= 1 ){\n\n } else {\n // check for in-view, hda lazy-loading if so\n self.checkColumnsInView();\n // the first, current column has position: fixed and flex css will not apply - adjust height manually\n self._recalcFirstColumnHeight();\n }\n return sortedAndFiltered;\n },\n\n _addColumns : function( columns, speed ){\n speed = _.isNumber( speed )? speed: this.fxSpeed;\n var $middle = this.$( '.middle' );\n\n var numExisting = $middle.children( '.history-column' ).length;\n $middle.width( this._calcMiddleWidth( columns.length + numExisting ) );\n\n columns.forEach( function( column, i ){\n column.delegateEvents().render( speed ).$el.appendTo( $middle );\n });\n },\n\n _calcMiddleWidth : function( numColumns ){\n var preventStackWidthAdj = 16;\n return (\n numColumns * ( this.options.columnWidth + this.options.columnGap ) +\n // last column gap\n this.options.columnGap +\n // the amount that safely prevents stacking of columns when adding a new one\n preventStackWidthAdj\n );\n },\n\n //TODO: combine the following two more sensibly\n //TODO: could have HistoryContents.haveDetails return false\n // if column.model.contents.length === 0 && !column.model.get( 'empty' ) then just check that\n /** Get the *summary* contents of a column's history (and details on any expanded contents),\n * queueing the ajax call and using a named queue to prevent the call being sent twice\n */\n queueHdaFetch : function queueHdaFetch( column ){\n // console.log( column.model + '.contentsShown:', column.model.contentsShown() );\n var contents = column.model.contents;\n // console.log( 'queueHdaFetch:', column, column.model.get( 'contents_active' ) );\n // if the history model says it has hdas but none are present, queue an ajax req for them\n if( contents.length === 0 && column.model.contentsShown() ){\n var fetchOptions = { silent: true };\n var ids = _.values( contents.storage.allExpanded() ).join();\n if( ids ){ fetchOptions.details = ids; }\n // this uses a 'named' queue so that duplicate requests are ignored\n this.hdaQueue.add({\n name : column.model.id,\n fn : function(){\n return contents.fetchCurrentPage( fetchOptions )\n .done( function(){ column.panel.renderItems(); });\n }\n });\n // the queue is re-used, so if it's not processing requests - start it again\n if( !this.hdaQueue.running ){ this.hdaQueue.start(); }\n }\n },\n\n /** Get the *detailed* json for *all* of a column's history's contents - req'd for searching */\n queueHdaFetchDetails : function( column ){\n var contents = column.model.contents;\n var needsContentsLoaded = contents.length === 0 && column.model.contentsShown();\n if( needsContentsLoaded || !contents.haveDetails() ){\n // this uses a 'named' queue so that duplicate requests are ignored\n this.hdaQueue.add({\n name : column.model.id,\n fn : function(){\n return contents.progressivelyFetchDetails()\n .done( function(){ column.panel._renderEmptyMessage(); });\n }\n });\n // the queue is re-used, so if it's not processing requests - start it again\n if( !this.hdaQueue.running ){ this.hdaQueue.start(); }\n }\n },\n\n /** put a text msg in the header */\n renderInfo : function( msg ){\n return this.$( '.header .header-info' ).text( msg );\n },\n\n // ------------------------------------------------------------------------ events/behaviors\n events : {\n // will move to the server root (gen. Analyze data)\n 'click .done.btn' : 'close',\n // creates a new empty history and makes it current\n 'click .create-new.btn' : 'create',\n 'click #include-deleted' : '_clickToggleDeletedHistories',\n // these change the collection and column sort order\n 'click .order .set-order' : '_chooseOrder',\n 'click #toggle-deleted' : '_clickToggleDeletedDatasets',\n 'click #toggle-hidden' : '_clickToggleHiddenDatasets',\n //'dragstart .list-item .title-bar' : function( e ){ console.debug( 'ok' ); }\n },\n\n close : function( ev ){\n //TODO: switch to pushState/router\n window.location = Galaxy.root;\n },\n\n _clickToggleDeletedHistories : function( ev ){\n this.toggleDeletedHistories( $( ev.currentTarget ).is( ':checked' ) );\n this.toggleOptionsPopover();\n },\n /** Include deleted histories in the collection */\n toggleDeletedHistories : function( show ){\n if( show ){\n window.location = Galaxy.root + 'history/view_multiple?include_deleted_histories=True';\n } else {\n window.location = Galaxy.root + 'history/view_multiple';\n }\n },\n\n _clickToggleDeletedDatasets : function( ev ){\n this.toggleDeletedDatasets( $( ev.currentTarget ).is( ':checked' ) );\n this.toggleOptionsPopover();\n },\n toggleDeletedDatasets : function( show ){\n show = show !== undefined? show : false;\n var multipanel = this;\n multipanel.sortedFilteredColumns().forEach( function( column, i ){\n _.delay( function(){\n column.panel.toggleShowDeleted( show, false );\n }, i * 200 );\n });\n },\n\n _clickToggleHiddenDatasets : function( ev ){\n this.toggleHiddenDatasets( $( ev.currentTarget ).is( ':checked' ) );\n this.toggleOptionsPopover();\n },\n toggleHiddenDatasets : function( show ){\n show = show !== undefined? show : false;\n var multipanel = this;\n multipanel.sortedFilteredColumns().forEach( function( column, i ){\n _.delay( function(){\n column.panel.toggleShowHidden( show, false );\n }, i * 200 );\n });\n },\n\n /** change the collection order and re-fetch when the drop down in the options menu is changed */\n _chooseOrder : function( ev ){\n var multipanel = this,\n collection = multipanel.collection,\n orderKey = $( ev.currentTarget ).data( 'order' );\n // set the sort order text also\n multipanel.$( '.current-order' ).text( multipanel.orderDescriptions[ orderKey ] );\n multipanel.toggleOptionsPopover();\n // set the order and re-fetch using the new order, saving the current history as the first\n collection.setOrder( orderKey );\n var currentHistoryModel = collection.slice( 0, 1 );\n collection.fetchFirst().done( function(){\n collection.unshift( currentHistoryModel, { silent: true });\n multipanel.createColumns();\n // need to clear this or previously fetched contents won't refetch now (bc of named queue)\n multipanel.hdaQueue.clear();\n multipanel.render();\n });\n multipanel.once( 'columns-rendered', multipanel._scrollLeft );\n //TODO: check allFetched and do not reset if so - just sort instead\n },\n\n /** scroll the column container right or left */\n _scrollLeft : function( val ){\n val = _.isNumber( val )? val : 0;\n this.$( '.outer-middle' ).scrollLeft( val );\n },\n\n /** Set up any view plugins */\n setUpBehaviors : function(){\n var multipanel = this;\n multipanel._moreOptionsPopover();\n\n // input to search histories\n multipanel.$( '#search-histories' ).searchInput({\n name : 'search-histories',\n placeholder : _l( 'search histories' ),\n\n onfirstsearch : function( searchFor ){\n multipanel.$( '#search-histories' ).searchInput( 'toggle-loading' );\n multipanel.renderInfo( _l( 'loading all histories for search' ) );\n multipanel.collection.fetchAll()\n .done( function(){\n multipanel.$( '#search-histories' ).searchInput( 'toggle-loading' );\n multipanel.renderInfo( '' );\n });\n },\n onsearch : function( searchFor ){\n multipanel.historySearch = searchFor;\n multipanel.filters = [ function(){\n return this.model.matchesAll( multipanel.historySearch );\n }];\n multipanel.renderColumns( 0 );\n },\n onclear : function( searchFor ){\n multipanel.historySearch = null;\n //TODO: remove specifically not just reset\n multipanel.filters = [];\n multipanel.renderColumns( 0 );\n }\n });\n\n // input to search datasets\n multipanel.$( '#search-datasets' ).searchInput({\n name : 'search-datasets',\n placeholder : _l( 'search all datasets' ),\n\n onfirstsearch : function( searchFor ){\n multipanel.hdaQueue.clear();\n multipanel.$( '#search-datasets' ).searchInput( 'toggle-loading' );\n multipanel.datasetSearch = searchFor;\n multipanel.sortedFilteredColumns().forEach( function( column ){\n column.panel.searchItems( searchFor );\n // load details for them that need\n multipanel.queueHdaFetchDetails( column );\n });\n multipanel.hdaQueue.progress( function( progress ){\n multipanel.renderInfo([\n _l( 'searching' ), ( progress.curr + 1 ), _l( 'of' ), progress.total\n ].join( ' ' ));\n });\n multipanel.hdaQueue.deferred.done( function(){\n multipanel.renderInfo( '' );\n multipanel.$( '#search-datasets' ).searchInput( 'toggle-loading' );\n });\n },\n onsearch : function( searchFor ){\n multipanel.datasetSearch = searchFor;\n multipanel.sortedFilteredColumns().forEach( function( column ){\n column.panel.searchItems( searchFor );\n });\n },\n onclear : function( searchFor ){\n multipanel.datasetSearch = null;\n multipanel.sortedFilteredColumns().forEach( function( column ){\n column.panel.clearSearch();\n });\n }\n });\n\n // resize first (fixed position) column on page resize\n $( window ).resize( function(){\n multipanel._recalcFirstColumnHeight();\n });\n\n // when scrolling - check for histories now in view: they will fire 'in-view' and queueHdaLoading if necc.\n //TODO:?? might be able to simplify and not use pub-sub\n var debouncedInView = _.debounce( function _debouncedInner(){\n var viewport = multipanel._viewport();\n multipanel.checkColumnsInView( viewport );\n multipanel.checkForEndOfScroll( viewport );\n }, 100 );\n this.$( '.middle' ).parent().scroll( debouncedInView );\n },\n\n /** create the options popover */\n _moreOptionsPopover : function(){\n return this.$( '.open-more-options.btn' ).popover({\n container : '.header',\n placement : 'bottom',\n html : true,\n content : $( this.optionsPopoverTemplate( this ) )\n });\n },\n\n /** change the collection order and re-fetch when the drop down in the options menu is changed */\n toggleOptionsPopover : function( ev ){\n // hide seems broken in our version\n this.$( '.open-more-options.btn' ).popover( 'toggle' );\n },\n\n /** Adjust the height of the first, current column since flex-boxes won't work with fixed postiion elements */\n _recalcFirstColumnHeight : function(){\n var $firstColumn = this.$( '.history-column' ).first(),\n middleHeight = this.$( '.middle' ).height(),\n controlHeight = $firstColumn.find( '.panel-controls' ).height();\n $firstColumn.height( middleHeight )\n .find( '.inner' ).height( middleHeight - controlHeight );\n },\n\n /** Get the left and right pixel coords of the middle element */\n _viewport : function(){\n var $outerMiddle = this.$( '.middle' ).parent(),\n viewLeft = $outerMiddle.offset().left,\n width = $outerMiddle.width();\n return {\n left : viewLeft,\n right : viewLeft + width\n };\n },\n\n /** returns the columns currently in the viewport */\n columnsInView : function( viewport ){\n //TODO: uses offset which is render intensive\n //TODO: 2N - could use arg filter (sortedFilteredColumns( filter )) instead\n var vp = viewport || this._viewport();\n return this.sortedFilteredColumns().filter( function( column ){\n return column.currentHistory || column.inView( vp.left, vp.right );\n });\n },\n\n //TODO: sortByInView - return cols in view, then others\n /** trigger in-view from columns in-view */\n checkColumnsInView : function(){\n //TODO: assbackward - don't fire from the column, fire from here and listen from here\n this.columnsInView().forEach( function( column ){\n column.trigger( 'in-view', column );\n });\n },\n\n /** is the middle, horizontally scrolling section scrolled fully to the right? */\n checkForEndOfScroll : function( viewport ){\n viewport = viewport || this._viewport();\n var END_PADDING = 16,\n $middle = this.$( '.middle' ),\n scrollRight = $middle.parent().scrollLeft() + viewport.right;\n if( scrollRight >= ( $middle.width() - END_PADDING ) ){\n this.trigger( 'end-of-scroll' );\n }\n },\n\n /** Show and enable the current columns drop target */\n currentColumnDropTargetOn : function(){\n var currentColumn = this.columnMap[ this.collection.currentHistoryId ];\n if( !currentColumn ){ return; }\n //TODO: fix this - shouldn't need monkeypatch\n currentColumn.panel.dataDropped = function( data ){};\n currentColumn.panel.dropTargetOn();\n },\n\n /** Hide and disable the current columns drop target */\n currentColumnDropTargetOff : function(){\n var currentColumn = this.columnMap[ this.collection.currentHistoryId ];\n if( !currentColumn ){ return; }\n currentColumn.panel.dataDropped = HISTORY_VIEW_EDIT.HistoryViewEdit.prototype.dataDrop;\n // slight override of dropTargetOff to not erase drop-target-help\n currentColumn.panel.dropTarget = false;\n currentColumn.panel.$( '.history-drop-target' ).remove();\n },\n\n // ------------------------------------------------------------------------ misc\n /** String rep */\n toString : function(){\n return 'MultiPanelColumns(' + ( this.columns? this.columns.length : 0 ) + ')';\n },\n\n // ------------------------------------------------------------------------ templates\n mainTemplate : _.template([\n '
',\n '
',\n '',\n '
',\n '
',\n '',\n '',\n '',\n '
',\n // feedback\n '
',\n '
', '
',\n '
',\n '
',\n ' ',\n '
',\n '
',\n // middle - where the columns go\n '
',\n '
',\n '
',\n // footer\n '
'\n ].join(''), { variable: 'view' }),\n\n loadingIndicatorTemplate : _.template([\n '
',\n '', _l( 'Loading histories' ), '...',\n '
'\n ].join(''), { variable: 'view' }),\n\n orderDescriptions : {\n 'update_time' : _l( 'most recent first' ),\n 'update_time-asc' : _l( 'least recent first' ),\n 'name' : _l( 'name, a to z' ),\n 'name-dsc' : _l( 'name, z to a' ),\n 'size' : _l( 'size, large to small' ),\n 'size-asc' : _l( 'size, small to large' )\n },\n\n optionsPopoverTemplate : _.template([\n '
',\n '
',\n '',\n '',\n '
',\n\n '
',\n\n '
',\n\n '
',\n '
',\n '
'\n ].join(''), { variable: 'view' })\n\n});\n\n\n//==============================================================================\n return {\n MultiPanelColumns : MultiPanelColumns\n };\n});\n"]} \ No newline at end of file diff --git a/static/scripts/mvc/history/multi-panel.js b/static/scripts/mvc/history/multi-panel.js index fb1c5663b20..b5def50e260 100644 --- a/static/scripts/mvc/history/multi-panel.js +++ b/static/scripts/mvc/history/multi-panel.js @@ -1,2 +1,2 @@ -"use strict";define(["mvc/history/history-model","mvc/history/history-view-edit","mvc/history/copy-dialog","mvc/ui/error-modal","mvc/base-mvc","utils/ajax-queue","ui/mode-button","ui/search-input","utils/localization"],function(e,t,n,i,o,r,s){var l=Backbone.View.extend(o.LoggableMixin).extend({_logNamespace:"history",tagName:"div",className:"history-column flex-column flex-row-container",id:function(){return this.model?"history-column-"+this.model.get("id"):""},initialize:function(e){e=e||{},this.purgeAllowed=!_.isUndefined(e.purgeAllowed)&&e.purgeAllowed,this.panel=e.panel||this.createPanel(e),this.setUpListeners()},createPanel:function(e){return new t.HistoryViewEdit(_.defaults(e,{model:this.model,purgeAllowed:this.purgeAllowed,dragItems:!0,$scrollContainer:function(){return this.$el}}))},setUpListeners:function(){var e=this;this.once("rendered",function(){e.trigger("rendered:initial",e)}),this.setUpPanelListeners()},setUpPanelListeners:function(){var e=this;this.listenTo(this.panel,{rendered:function(){e.trigger("rendered",e)},"view:expanded view:rendered":function(e){e.$(".rerun-btn").off()}},this)},inView:function(e,t){var n=this.$el.offset().left;return!(n+this.$el.width()t)},$panel:function(){return this.$(".history-panel")},render:function(e){e=void 0!==e?e:"fast";var t=this.model?this.model.toJSON():{};return this.$el.html(this.template(t)),this.renderPanel(e),this.panel.$el.css("display","flex"),this.setUpBehaviors(),this},setUpBehaviors:function(){},template:function(e){return e=_.extend(e||{},{isCurrentHistory:this.currentHistory}),$(['
',this.controlsLeftTemplate({history:e,view:this}),this.controlsRightTemplate({history:e,view:this}),"
",'
','
',"
"].join(""))},renderPanel:function(e){return e=void 0!==e?e:"fast",this.panel.setElement(this.$panel()).render(e),this.currentHistory&&this.panel.$list().before(this.panel._renderDropTargetHelp()),this},events:{"click .switch-to.btn":function(){this.model.setAsCurrent()},"click .delete-history":function(){var e=this;this.model._delete().done(function(t){e.render()})},"click .undelete-history":function(){var e=this;this.model.undelete().done(function(t){e.render()})},"click .purge-history":function(){if(confirm(s("This will permanently remove the data. Are you sure?"))){var e=this;this.model.purge().done(function(t){e.render()})}},"click .copy-history":"copy"},copy:function(){n(this.model)},controlsLeftTemplate:_.template(['
',"<% if( data.history.isCurrentHistory ){ %>",'',s("Current History"),"","<% } else { %>",'","<% } %>","
"].join(""),{variable:"data"}),controlsRightTemplate:_.template(['
',"<% if( !data.history.purged ){ %>",'
','",'","
","<% } %>","
"].join(""),{variable:"data"}),toString:function(){return"HistoryViewColumn("+(this.panel?this.panel:"")+")"}});return{MultiPanelColumns:Backbone.View.extend(o.LoggableMixin).extend({_logNamespace:"history",className:"multi-panel-history",initialize:function(e){e=e||{},this.log(this+".init",e),this.$el.addClass(this.className),this.options={columnWidth:312,borderWidth:1,columnGap:8,headerHeight:29,footerHeight:0,controlsHeight:20},this.perPage=e.perPage||10,this.hdaQueue=new r.NamedAjaxQueue([],!1),this.collection=null,this.columnMap={},this.columnOptions=e.columnOptions||{},this.historySearch=null,this.datasetSearch=null,this.setCollection(e.histories),this.setUpListeners()},setUpListeners:function(){var e=this;this.on("end-of-scroll",function(){e.collection.fetchMore()})},setCollection:function(t){return this.stopListening(this.collection),this.collection=t||new e.HistoryCollection,this.setUpCollectionListeners(),this.createColumns(),this.hdaQueue.clear(),this.trigger("new-collection",this),this},addModels:function(e,t,n){n=n||{};var i=this;return(e=_.isArray(e)?e:[e]).forEach(function(e){i.addColumn(e,!1)}),this},setUpCollectionListeners:function(){var e=this;e.listenTo(e.collection,{error:e.errorHandler,add:e.addModels,"all-fetched":e._postFetchAll,"new-current":e.addAsCurrentColumn,"set-as-current":e.setCurrentHistory,"change:deleted change:purged":e.handleDeletedHistory,sort:function(){e.renderColumns(0)}})},_postFetchAll:function(e){if(this.$(".histories-loading-indicator").remove(),!this.historySearch){var t=this.$(".outer-middle");t.scrollLeft(t.scrollLeft()+24)}},setCurrentHistory:function(e){this.log("setCurrentHistory:",e);var t=_.findWhere(this.columnMap,{currentHistory:!0});t&&(t.currentHistory=!1,t.$el.height(""));var n=this.columnMap[this.collection.currentHistoryId];return n.currentHistory=!0,this.collection.sort(),this._recalcFirstColumnHeight(),n},handleDeletedHistory:function(e){if(e.get("deleted")||e.get("purged")){this.log("handleDeletedHistory",this.collection.includeDeleted,e);var t=this,n=t.columnMap[e.id];if(!n)return;n.model.id===this.collection.currentHistoryId||t.collection.includeDeleted||t.removeColumn(n)}},errorHandler:function(e,t,n){if(!t||0!==t.status||0!==t.readyState){if(this.error(e,t,n),_.isString(e)&&_.isString(t)){var o=e,r=t;return i.errorModal(o,r,n)}return t&&502===t.status?i.badGatewayErrorModal():i.ajaxErrorModal(e,t,n)}},_ajaxErrorHandler:function(){i.ajaxErrorModal.apply(null,_.toArray(arguments))},create:function(e){return this.collection.create({current:!0})},createColumns:function(e,t){t=t||this.options.columnOptions;var n=this;n.columnMap={},n.collection.each(function(e,i){var o=n.createColumn(e,t);n.columnMap[e.id]=o})},createColumn:function(e,t){t=_.extend({},t,{model:e,purgeAllowed:Galaxy.config.allow_user_dataset_purge});var n=new l(t);return e.id===this.collection.currentHistoryId&&(n.currentHistory=!0),this.setUpColumnListeners(n),this.datasetSearch&&(n.panel.searchItems(this.datasetSearch),this.queueHdaFetchDetails(n)),n},addColumn:function(e,t){t=void 0===t||t;var n=this.createColumn(e);return this.columnMap[e.id]=n,t&&this.renderColumns(),n},addAsCurrentColumn:function(e,t,n){var i=this,o=this.addColumn(e,!1);return this.setCurrentHistory(e),o.once("rendered",function(){i.queueHdaFetch(o)}),o},removeColumn:function(e,t){if(t=void 0===t||t,this.log("removeColumn",e),e){var n=this,i=this.options.columnWidth+this.options.columnGap;e.$el.fadeOut("fast",function(){t&&($(this).remove(),n.$(".middle").width(n.$(".middle").width()-i),n.checkColumnsInView(),n._recalcFirstColumnHeight()),n.stopListening(e.panel),n.stopListening(e),delete n.columnMap[e.model.id],e.remove()})}},setUpColumnListeners:function(e){var t=this;t.listenTo(e,{"in-view":t.queueHdaFetch}),t.listenTo(e.panel,{"view:draggable:dragstart":function(e,n,i,o){t._dropData=JSON.parse(e.dataTransfer.getData("text")),t.currentColumnDropTargetOn()},"view:draggable:dragend":function(e,n,i,o){t._dropData=null,t.currentColumnDropTargetOff()},"droptarget:drop":function(e,n,i){var o=t._dropData.filter(function(e){return i.model.contents.isCopyable(e)});t._dropData=null;var s=new r.NamedAjaxQueue;0!==i.model.contents.currentPage&&s.add({name:"fetch-front-page",fn:function(){return i.model.contents.fetchPage(0)}}),o.reverse().forEach(function(e){s.add({name:"copy-"+e.id,fn:function(){return i.model.contents.copy(e)}})}),s.start(),s.done(function(e){i.model.fetch()})}})},columnMapLength:function(){return Object.keys(this.columnMap).length},sortedFilteredColumns:function(e){return(e=e||this.filters)&&e.length?this.sortedColumns().filter(function(t,n){return t.currentHistory||_.every(e.map(function(e){return e.call(t)}))}):this.sortedColumns()},sortedColumns:function(){var e=this;return this.collection.map(function(t,n){return e.columnMap[t.id]})},render:function(e){e=void 0!==e?e:this.fxSpeed;var t=this;return t.log(t+".render"),t.$el.html(t.mainTemplate(t)),t.renderColumns(e),t.setUpBehaviors(),t.trigger("rendered",t),t},renderColumns:function(e){e=_.isNumber(e)?e:this.fxSpeed;var t=this,n=t.sortedFilteredColumns(),i=t.$(".middle").empty();return t._addColumns(n,e),t.collection.allFetched||i.append(t.loadingIndicatorTemplate(t)),t.trigger("columns-rendered",n,t),t.datasetSearch&&n.length<=1||(t.checkColumnsInView(),t._recalcFirstColumnHeight()),n},_addColumns:function(e,t){t=_.isNumber(t)?t:this.fxSpeed;var n=this.$(".middle"),i=n.children(".history-column").length;n.width(this._calcMiddleWidth(e.length+i)),e.forEach(function(e,i){e.delegateEvents().render(t).$el.appendTo(n)})},_calcMiddleWidth:function(e){return e*(this.options.columnWidth+this.options.columnGap)+this.options.columnGap+16},queueHdaFetch:function(e){var t=e.model.contents;if(0===t.length&&e.model.contentsShown()){var n={silent:!0},i=_.values(t.storage.allExpanded()).join();i&&(n.details=i),this.hdaQueue.add({name:e.model.id,fn:function(){return t.fetchCurrentPage(n).done(function(){e.panel.renderItems()})}}),this.hdaQueue.running||this.hdaQueue.start()}},queueHdaFetchDetails:function(e){var t=e.model.contents;!(0===t.length&&e.model.contentsShown())&&t.haveDetails()||(this.hdaQueue.add({name:e.model.id,fn:function(){return t.progressivelyFetchDetails().done(function(){e.panel._renderEmptyMessage()})}}),this.hdaQueue.running||this.hdaQueue.start())},renderInfo:function(e){return this.$(".header .header-info").text(e)},events:{"click .done.btn":"close","click .create-new.btn":"create","click #include-deleted":"_clickToggleDeletedHistories","click .order .set-order":"_chooseOrder","click #toggle-deleted":"_clickToggleDeletedDatasets","click #toggle-hidden":"_clickToggleHiddenDatasets"},close:function(e){window.location=Galaxy.root},_clickToggleDeletedHistories:function(e){this.toggleDeletedHistories($(e.currentTarget).is(":checked")),this.toggleOptionsPopover()},toggleDeletedHistories:function(e){window.location=e?Galaxy.root+"history/view_multiple?include_deleted_histories=True":Galaxy.root+"history/view_multiple"},_clickToggleDeletedDatasets:function(e){this.toggleDeletedDatasets($(e.currentTarget).is(":checked")),this.toggleOptionsPopover()},toggleDeletedDatasets:function(e){e=void 0!==e&&e,this.sortedFilteredColumns().forEach(function(t,n){_.delay(function(){t.panel.toggleShowDeleted(e,!1)},200*n)})},_clickToggleHiddenDatasets:function(e){this.toggleHiddenDatasets($(e.currentTarget).is(":checked")),this.toggleOptionsPopover()},toggleHiddenDatasets:function(e){e=void 0!==e&&e,this.sortedFilteredColumns().forEach(function(t,n){_.delay(function(){t.panel.toggleShowHidden(e,!1)},200*n)})},_chooseOrder:function(e){var t=this,n=t.collection,i=$(e.currentTarget).data("order");t.$(".current-order").text(t.orderDescriptions[i]),t.toggleOptionsPopover(),n.setOrder(i);var o=n.slice(0,1);n.fetchFirst().done(function(){n.unshift(o,{silent:!0}),t.createColumns(),t.hdaQueue.clear(),t.render()}),t.once("columns-rendered",t._scrollLeft)},_scrollLeft:function(e){e=_.isNumber(e)?e:0,this.$(".outer-middle").scrollLeft(e)},setUpBehaviors:function(){var e=this;e._moreOptionsPopover(),e.$("#search-histories").searchInput({name:"search-histories",placeholder:s("search histories"),onfirstsearch:function(t){e.$("#search-histories").searchInput("toggle-loading"),e.renderInfo(s("loading all histories for search")),e.collection.fetchAll().done(function(){e.$("#search-histories").searchInput("toggle-loading"),e.renderInfo("")})},onsearch:function(t){e.historySearch=t,e.filters=[function(){return this.model.matchesAll(e.historySearch)}],e.renderColumns(0)},onclear:function(t){e.historySearch=null,e.filters=[],e.renderColumns(0)}}),e.$("#search-datasets").searchInput({name:"search-datasets",placeholder:s("search all datasets"),onfirstsearch:function(t){e.hdaQueue.clear(),e.$("#search-datasets").searchInput("toggle-loading"),e.datasetSearch=t,e.sortedFilteredColumns().forEach(function(n){n.panel.searchItems(t),e.queueHdaFetchDetails(n)}),e.hdaQueue.progress(function(t){e.renderInfo([s("searching"),t.curr+1,s("of"),t.total].join(" "))}),e.hdaQueue.deferred.done(function(){e.renderInfo(""),e.$("#search-datasets").searchInput("toggle-loading")})},onsearch:function(t){e.datasetSearch=t,e.sortedFilteredColumns().forEach(function(e){e.panel.searchItems(t)})},onclear:function(t){e.datasetSearch=null,e.sortedFilteredColumns().forEach(function(e){e.panel.clearSearch()})}}),$(window).resize(function(){e._recalcFirstColumnHeight()});var t=_.debounce(function(){var t=e._viewport();e.checkColumnsInView(t),e.checkForEndOfScroll(t)},100);this.$(".middle").parent().scroll(t)},_moreOptionsPopover:function(){return this.$(".open-more-options.btn").popover({container:".header",placement:"bottom",html:!0,content:$(this.optionsPopoverTemplate(this))})},toggleOptionsPopover:function(e){this.$(".open-more-options.btn").popover("toggle")},_recalcFirstColumnHeight:function(){var e=this.$(".history-column").first(),t=this.$(".middle").height(),n=e.find(".panel-controls").height();e.height(t).find(".inner").height(t-n)},_viewport:function(){var e=this.$(".middle").parent(),t=e.offset().left;return{left:t,right:t+e.width()}},columnsInView:function(e){var t=e||this._viewport();return this.sortedFilteredColumns().filter(function(e){return e.currentHistory||e.inView(t.left,t.right)})},checkColumnsInView:function(){this.columnsInView().forEach(function(e){e.trigger("in-view",e)})},checkForEndOfScroll:function(e){e=e||this._viewport();var t=this.$(".middle");t.parent().scrollLeft()+e.right>=t.width()-16&&this.trigger("end-of-scroll")},currentColumnDropTargetOn:function(){var e=this.columnMap[this.collection.currentHistoryId];e&&(e.panel.dataDropped=function(e){},e.panel.dropTargetOn())},currentColumnDropTargetOff:function(){var e=this.columnMap[this.collection.currentHistoryId];e&&(e.panel.dataDropped=t.HistoryViewEdit.prototype.dataDrop,e.panel.dropTarget=!1,e.panel.$(".history-drop-target").remove())},toString:function(){return"MultiPanelColumns("+(this.columns?this.columns.length:0)+")"},mainTemplate:_.template(['
','
','",'
','
','','',"","
",'
','
',"
","
",'
',' ","
","
",'
','
',"
",''].join(""),{variable:"view"}),loadingIndicatorTemplate:_.template(['
','',s("Loading histories"),"...","
"].join(""),{variable:"view"}),orderDescriptions:{update_time:s("most recent first"),"update_time-asc":s("least recent first"),name:s("name, a to z"),"name-dsc":s("name, z to a"),size:s("size, large to small"),"size-asc":s("size, small to large")},optionsPopoverTemplate:_.template(['
','
','",'","
",'
","
",'
",'
","
"].join(""),{variable:"view"})})}}); +"use strict";define(["utils/localization","mvc/history/history-model","mvc/history/history-view-edit","mvc/history/copy-dialog","mvc/ui/error-modal","mvc/base-mvc","utils/ajax-queue","ui/mode-button","ui/search-input"],function(e,t,n,i,o,r,s){var l=Backbone.View.extend(r.LoggableMixin).extend({_logNamespace:"history",tagName:"div",className:"history-column flex-column flex-row-container",id:function(){return this.model?"history-column-"+this.model.get("id"):""},initialize:function(e){e=e||{},this.purgeAllowed=!_.isUndefined(e.purgeAllowed)&&e.purgeAllowed,this.panel=e.panel||this.createPanel(e),this.setUpListeners()},createPanel:function(e){return new n.HistoryViewEdit(_.defaults(e,{model:this.model,purgeAllowed:this.purgeAllowed,dragItems:!0,$scrollContainer:function(){return this.$el}}))},setUpListeners:function(){var e=this;this.once("rendered",function(){e.trigger("rendered:initial",e)}),this.setUpPanelListeners()},setUpPanelListeners:function(){var e=this;this.listenTo(this.panel,{rendered:function(){e.trigger("rendered",e)},"view:expanded view:rendered":function(e){e.$(".rerun-btn").off()}},this)},inView:function(e,t){var n=this.$el.offset().left;return!(n+this.$el.width()t)},$panel:function(){return this.$(".history-panel")},render:function(e){e=void 0!==e?e:"fast";var t=this.model?this.model.toJSON():{};return this.$el.html(this.template(t)),this.renderPanel(e),this.panel.$el.css("display","flex"),this.setUpBehaviors(),this},setUpBehaviors:function(){},template:function(e){return e=_.extend(e||{},{isCurrentHistory:this.currentHistory}),$(['
',this.controlsLeftTemplate({history:e,view:this}),this.controlsRightTemplate({history:e,view:this}),"
",'
','
',"
"].join(""))},renderPanel:function(e){return e=void 0!==e?e:"fast",this.panel.setElement(this.$panel()).render(e),this.currentHistory&&this.panel.$list().before(this.panel._renderDropTargetHelp()),this},events:{"click .switch-to.btn":function(){this.model.setAsCurrent()},"click .delete-history":function(){var e=this;this.model._delete().done(function(t){e.render()})},"click .undelete-history":function(){var e=this;this.model.undelete().done(function(t){e.render()})},"click .purge-history":function(){if(confirm(e("This will permanently remove the data. Are you sure?"))){var t=this;this.model.purge().done(function(e){t.render()})}},"click .copy-history":"copy"},copy:function(){i(this.model)},controlsLeftTemplate:_.template(['
',"<% if( data.history.isCurrentHistory ){ %>",'',e("Current History"),"","<% } else { %>",'","<% } %>","
"].join(""),{variable:"data"}),controlsRightTemplate:_.template(['
',"<% if( !data.history.purged ){ %>",'
','",'","
","<% } %>","
"].join(""),{variable:"data"}),toString:function(){return"HistoryViewColumn("+(this.panel?this.panel:"")+")"}});return{MultiPanelColumns:Backbone.View.extend(r.LoggableMixin).extend({_logNamespace:"history",className:"multi-panel-history",initialize:function(e){e=e||{},this.log(this+".init",e),this.$el.addClass(this.className),this.options={columnWidth:312,borderWidth:1,columnGap:8,headerHeight:29,footerHeight:0,controlsHeight:20},this.perPage=e.perPage||10,this.hdaQueue=new s.NamedAjaxQueue([],!1),this.collection=null,this.columnMap={},this.columnOptions=e.columnOptions||{},this.historySearch=null,this.datasetSearch=null,this.setCollection(e.histories),this.setUpListeners()},setUpListeners:function(){var e=this;this.on("end-of-scroll",function(){e.collection.fetchMore()})},setCollection:function(e){return this.stopListening(this.collection),this.collection=e||new t.HistoryCollection,this.setUpCollectionListeners(),this.createColumns(),this.hdaQueue.clear(),this.trigger("new-collection",this),this},addModels:function(e,t,n){n=n||{};var i=this;return(e=_.isArray(e)?e:[e]).forEach(function(e){i.addColumn(e,!1)}),this},setUpCollectionListeners:function(){var e=this;e.listenTo(e.collection,{error:e.errorHandler,add:e.addModels,"all-fetched":e._postFetchAll,"new-current":e.addAsCurrentColumn,"set-as-current":e.setCurrentHistory,"change:deleted change:purged":e.handleDeletedHistory,sort:function(){e.renderColumns(0)}})},_postFetchAll:function(e){if(this.$(".histories-loading-indicator").remove(),!this.historySearch){var t=this.$(".outer-middle");t.scrollLeft(t.scrollLeft()+24)}},setCurrentHistory:function(e){this.log("setCurrentHistory:",e);var t=_.findWhere(this.columnMap,{currentHistory:!0});t&&(t.currentHistory=!1,t.$el.height(""));var n=this.columnMap[this.collection.currentHistoryId];return n.currentHistory=!0,this.collection.sort(),this._recalcFirstColumnHeight(),n},handleDeletedHistory:function(e){if(e.get("deleted")||e.get("purged")){this.log("handleDeletedHistory",this.collection.includeDeleted,e);var t=this,n=t.columnMap[e.id];if(!n)return;n.model.id===this.collection.currentHistoryId||t.collection.includeDeleted||t.removeColumn(n)}},errorHandler:function(e,t,n){if(!t||0!==t.status||0!==t.readyState){if(this.error(e,t,n),_.isString(e)&&_.isString(t)){var i=e,r=t;return o.errorModal(i,r,n)}return t&&502===t.status?o.badGatewayErrorModal():o.ajaxErrorModal(e,t,n)}},_ajaxErrorHandler:function(){o.ajaxErrorModal.apply(null,_.toArray(arguments))},create:function(e){return this.collection.create({current:!0})},createColumns:function(e,t){t=t||this.options.columnOptions;var n=this;n.columnMap={},n.collection.each(function(e,i){var o=n.createColumn(e,t);n.columnMap[e.id]=o})},createColumn:function(e,t){t=_.extend({},t,{model:e,purgeAllowed:Galaxy.config.allow_user_dataset_purge});var n=new l(t);return e.id===this.collection.currentHistoryId&&(n.currentHistory=!0),this.setUpColumnListeners(n),this.datasetSearch&&(n.panel.searchItems(this.datasetSearch),this.queueHdaFetchDetails(n)),n},addColumn:function(e,t){t=void 0===t||t;var n=this.createColumn(e);return this.columnMap[e.id]=n,t&&this.renderColumns(),n},addAsCurrentColumn:function(e,t,n){var i=this,o=this.addColumn(e,!1);return this.setCurrentHistory(e),o.once("rendered",function(){i.queueHdaFetch(o)}),o},removeColumn:function(e,t){if(t=void 0===t||t,this.log("removeColumn",e),e){var n=this,i=this.options.columnWidth+this.options.columnGap;e.$el.fadeOut("fast",function(){t&&($(this).remove(),n.$(".middle").width(n.$(".middle").width()-i),n.checkColumnsInView(),n._recalcFirstColumnHeight()),n.stopListening(e.panel),n.stopListening(e),delete n.columnMap[e.model.id],e.remove()})}},setUpColumnListeners:function(e){var t=this;t.listenTo(e,{"in-view":t.queueHdaFetch}),t.listenTo(e.panel,{"view:draggable:dragstart":function(e,n,i,o){t._dropData=JSON.parse(e.dataTransfer.getData("text")),t.currentColumnDropTargetOn()},"view:draggable:dragend":function(e,n,i,o){t._dropData=null,t.currentColumnDropTargetOff()},"droptarget:drop":function(e,n,i){var o=t._dropData.filter(function(e){return i.model.contents.isCopyable(e)});t._dropData=null;var r=new s.NamedAjaxQueue;0!==i.model.contents.currentPage&&r.add({name:"fetch-front-page",fn:function(){return i.model.contents.fetchPage(0)}}),o.reverse().forEach(function(e){r.add({name:"copy-"+e.id,fn:function(){return i.model.contents.copy(e)}})}),r.start(),r.done(function(e){i.model.fetch()})}})},columnMapLength:function(){return Object.keys(this.columnMap).length},sortedFilteredColumns:function(e){return(e=e||this.filters)&&e.length?this.sortedColumns().filter(function(t,n){return t.currentHistory||_.every(e.map(function(e){return e.call(t)}))}):this.sortedColumns()},sortedColumns:function(){var e=this;return this.collection.map(function(t,n){return e.columnMap[t.id]})},render:function(e){e=void 0!==e?e:this.fxSpeed;var t=this;return t.log(t+".render"),t.$el.html(t.mainTemplate(t)),t.renderColumns(e),t.setUpBehaviors(),t.trigger("rendered",t),t},renderColumns:function(e){e=_.isNumber(e)?e:this.fxSpeed;var t=this,n=t.sortedFilteredColumns(),i=t.$(".middle").empty();return t._addColumns(n,e),t.collection.allFetched||i.append(t.loadingIndicatorTemplate(t)),t.trigger("columns-rendered",n,t),t.datasetSearch&&n.length<=1||(t.checkColumnsInView(),t._recalcFirstColumnHeight()),n},_addColumns:function(e,t){t=_.isNumber(t)?t:this.fxSpeed;var n=this.$(".middle"),i=n.children(".history-column").length;n.width(this._calcMiddleWidth(e.length+i)),e.forEach(function(e,i){e.delegateEvents().render(t).$el.appendTo(n)})},_calcMiddleWidth:function(e){return e*(this.options.columnWidth+this.options.columnGap)+this.options.columnGap+16},queueHdaFetch:function(e){var t=e.model.contents;if(0===t.length&&e.model.contentsShown()){var n={silent:!0},i=_.values(t.storage.allExpanded()).join();i&&(n.details=i),this.hdaQueue.add({name:e.model.id,fn:function(){return t.fetchCurrentPage(n).done(function(){e.panel.renderItems()})}}),this.hdaQueue.running||this.hdaQueue.start()}},queueHdaFetchDetails:function(e){var t=e.model.contents;!(0===t.length&&e.model.contentsShown())&&t.haveDetails()||(this.hdaQueue.add({name:e.model.id,fn:function(){return t.progressivelyFetchDetails().done(function(){e.panel._renderEmptyMessage()})}}),this.hdaQueue.running||this.hdaQueue.start())},renderInfo:function(e){return this.$(".header .header-info").text(e)},events:{"click .done.btn":"close","click .create-new.btn":"create","click #include-deleted":"_clickToggleDeletedHistories","click .order .set-order":"_chooseOrder","click #toggle-deleted":"_clickToggleDeletedDatasets","click #toggle-hidden":"_clickToggleHiddenDatasets"},close:function(e){window.location=Galaxy.root},_clickToggleDeletedHistories:function(e){this.toggleDeletedHistories($(e.currentTarget).is(":checked")),this.toggleOptionsPopover()},toggleDeletedHistories:function(e){window.location=e?Galaxy.root+"history/view_multiple?include_deleted_histories=True":Galaxy.root+"history/view_multiple"},_clickToggleDeletedDatasets:function(e){this.toggleDeletedDatasets($(e.currentTarget).is(":checked")),this.toggleOptionsPopover()},toggleDeletedDatasets:function(e){e=void 0!==e&&e,this.sortedFilteredColumns().forEach(function(t,n){_.delay(function(){t.panel.toggleShowDeleted(e,!1)},200*n)})},_clickToggleHiddenDatasets:function(e){this.toggleHiddenDatasets($(e.currentTarget).is(":checked")),this.toggleOptionsPopover()},toggleHiddenDatasets:function(e){e=void 0!==e&&e,this.sortedFilteredColumns().forEach(function(t,n){_.delay(function(){t.panel.toggleShowHidden(e,!1)},200*n)})},_chooseOrder:function(e){var t=this,n=t.collection,i=$(e.currentTarget).data("order");t.$(".current-order").text(t.orderDescriptions[i]),t.toggleOptionsPopover(),n.setOrder(i);var o=n.slice(0,1);n.fetchFirst().done(function(){n.unshift(o,{silent:!0}),t.createColumns(),t.hdaQueue.clear(),t.render()}),t.once("columns-rendered",t._scrollLeft)},_scrollLeft:function(e){e=_.isNumber(e)?e:0,this.$(".outer-middle").scrollLeft(e)},setUpBehaviors:function(){var t=this;t._moreOptionsPopover(),t.$("#search-histories").searchInput({name:"search-histories",placeholder:e("search histories"),onfirstsearch:function(n){t.$("#search-histories").searchInput("toggle-loading"),t.renderInfo(e("loading all histories for search")),t.collection.fetchAll().done(function(){t.$("#search-histories").searchInput("toggle-loading"),t.renderInfo("")})},onsearch:function(e){t.historySearch=e,t.filters=[function(){return this.model.matchesAll(t.historySearch)}],t.renderColumns(0)},onclear:function(e){t.historySearch=null,t.filters=[],t.renderColumns(0)}}),t.$("#search-datasets").searchInput({name:"search-datasets",placeholder:e("search all datasets"),onfirstsearch:function(n){t.hdaQueue.clear(),t.$("#search-datasets").searchInput("toggle-loading"),t.datasetSearch=n,t.sortedFilteredColumns().forEach(function(e){e.panel.searchItems(n),t.queueHdaFetchDetails(e)}),t.hdaQueue.progress(function(n){t.renderInfo([e("searching"),n.curr+1,e("of"),n.total].join(" "))}),t.hdaQueue.deferred.done(function(){t.renderInfo(""),t.$("#search-datasets").searchInput("toggle-loading")})},onsearch:function(e){t.datasetSearch=e,t.sortedFilteredColumns().forEach(function(t){t.panel.searchItems(e)})},onclear:function(e){t.datasetSearch=null,t.sortedFilteredColumns().forEach(function(e){e.panel.clearSearch()})}}),$(window).resize(function(){t._recalcFirstColumnHeight()});var n=_.debounce(function(){var e=t._viewport();t.checkColumnsInView(e),t.checkForEndOfScroll(e)},100);this.$(".middle").parent().scroll(n)},_moreOptionsPopover:function(){return this.$(".open-more-options.btn").popover({container:".header",placement:"bottom",html:!0,content:$(this.optionsPopoverTemplate(this))})},toggleOptionsPopover:function(e){this.$(".open-more-options.btn").popover("toggle")},_recalcFirstColumnHeight:function(){var e=this.$(".history-column").first(),t=this.$(".middle").height(),n=e.find(".panel-controls").height();e.height(t).find(".inner").height(t-n)},_viewport:function(){var e=this.$(".middle").parent(),t=e.offset().left;return{left:t,right:t+e.width()}},columnsInView:function(e){var t=e||this._viewport();return this.sortedFilteredColumns().filter(function(e){return e.currentHistory||e.inView(t.left,t.right)})},checkColumnsInView:function(){this.columnsInView().forEach(function(e){e.trigger("in-view",e)})},checkForEndOfScroll:function(e){e=e||this._viewport();var t=this.$(".middle");t.parent().scrollLeft()+e.right>=t.width()-16&&this.trigger("end-of-scroll")},currentColumnDropTargetOn:function(){var e=this.columnMap[this.collection.currentHistoryId];e&&(e.panel.dataDropped=function(e){},e.panel.dropTargetOn())},currentColumnDropTargetOff:function(){var e=this.columnMap[this.collection.currentHistoryId];e&&(e.panel.dataDropped=n.HistoryViewEdit.prototype.dataDrop,e.panel.dropTarget=!1,e.panel.$(".history-drop-target").remove())},toString:function(){return"MultiPanelColumns("+(this.columns?this.columns.length:0)+")"},mainTemplate:_.template(['
','
','",'
','
','','',"","
",'
','
',"
","
",'
',' ","
","
",'
','
',"
",''].join(""),{variable:"view"}),loadingIndicatorTemplate:_.template(['
','',e("Loading histories"),"...","
"].join(""),{variable:"view"}),orderDescriptions:{update_time:e("most recent first"),"update_time-asc":e("least recent first"),name:e("name, a to z"),"name-dsc":e("name, z to a"),size:e("size, large to small"),"size-asc":e("size, small to large")},optionsPopoverTemplate:_.template(['
','
','",'","
",'
","
",'
",'
","
"].join(""),{variable:"view"})})}}); //# sourceMappingURL=../../../maps/mvc/history/multi-panel.js.map