Skip to content

Commit

Permalink
Merge pull request #806 from martenson/data-lib-work
Browse files Browse the repository at this point in the history
UI and API for data library folders management
  • Loading branch information
blankenberg committed Sep 29, 2015
2 parents 5318757 + e9f12d3 commit 6406276
Show file tree
Hide file tree
Showing 18 changed files with 255 additions and 77 deletions.
5 changes: 5 additions & 0 deletions client/galaxy/scripts/mvc/library/library-folderlist-view.js
Expand Up @@ -263,6 +263,11 @@ var FolderListView = Backbone.View.extend({
* Currently supports only sorting by name.
*/
sortFolder: function(sort_by, order){
console.log('sorting');
// default to asc sort by name
if (sort_by === 'undefined' && order === 'undefined'){
return this.collection.sortByNameAsc();
}
if (sort_by === 'name'){
if (order === 'asc'){
return this.collection.sortByNameAsc();
Expand Down
66 changes: 61 additions & 5 deletions client/galaxy/scripts/mvc/library/library-folderrow-view.js
Expand Up @@ -15,7 +15,8 @@ var FolderRowView = Backbone.View.extend({
lastSelectedHistory: '',

events: {
'click .undelete_dataset_btn' : 'undelete_dataset'
'click .undelete_dataset_btn' : 'undeleteDataset',
'click .undelete_folder_btn' : 'undeleteFolder'
},

options: {
Expand All @@ -29,16 +30,23 @@ var FolderRowView = Backbone.View.extend({

render: function(folder_item){
var template = null;
if (folder_item.get('type') === 'folder'){
if (folder_item.get('type') === 'folder' || folder_item.get('model_class') === 'LibraryFolder'){
this.options.type = 'folder';
template = this.templateRowFolder();
} else {
if (folder_item.get('deleted')){
template = this.templateRowDeletedFolder();
} else{
template = this.templateRowFolder();
}
} else if (folder_item.get('type') === 'file' || folder_item.get('model_class') === 'LibraryDataset'){
this.options.type = 'file';
if (folder_item.get('deleted')){
template = this.templateRowDeletedFile();
} else {
template = this.templateRowFile();
}
} else {
console.error('Unknown library item type found.');
console.error(folder_item.get('type') || folder_item.get('model_class'));
}
this.setElement(template({content_item:folder_item}));
this.$el.show();
Expand All @@ -52,7 +60,7 @@ var FolderRowView = Backbone.View.extend({
/**
* Undeletes the dataset on server and renders the row again.
*/
undelete_dataset : function(event){
undeleteDataset : function(event){
$(".tooltip").hide();
var that = this;
var dataset_id = $(event.target).closest('tr')[0].id;
Expand All @@ -63,6 +71,7 @@ var FolderRowView = Backbone.View.extend({
Galaxy.libraries.folderListView.collection.remove(dataset_id);
var updated_dataset = new mod_library_model.Item(response);
Galaxy.libraries.folderListView.collection.add(updated_dataset);
Galaxy.libraries.folderListView.collection.sortByNameAsc();
mod_toastr.success('Dataset undeleted. Click this to see it.', '', {onclick: function() {
var folder_id = that.model.get('folder_id');
window.location='#folders/' + folder_id + '/datasets/' + that.id;
Expand All @@ -78,6 +87,33 @@ var FolderRowView = Backbone.View.extend({
});
},

/**
* Undeletes the folder on server and renders the row again.
*/
undeleteFolder : function(event){
$(".tooltip").hide();
var that = this;
var folder_id = $(event.target).closest('tr')[0].id;
var folder = Galaxy.libraries.folderListView.collection.get(folder_id);
folder.url = folder.urlRoot + folder.id + '?undelete=true';
folder.destroy({
success : function(model, response){
Galaxy.libraries.folderListView.collection.remove(folder_id);
var updated_folder = new mod_library_model.FolderAsModel(response);
Galaxy.libraries.folderListView.collection.add(updated_folder);
Galaxy.libraries.folderListView.collection.sortByNameAsc();
mod_toastr.success('Folder undeleted.');
},
error : function(model, response){
if (typeof response.responseJSON !== "undefined"){
mod_toastr.error('Folder was not undeleted. ' + response.responseJSON.err_msg);
} else {
mod_toastr.error('An error occured! Folder was not undeleted. Please try again.');
}
}
});
},

templateRowFolder: function() {
tmpl_array = [];

Expand Down Expand Up @@ -138,6 +174,26 @@ var FolderRowView = Backbone.View.extend({
tmpl_array.push(' <td><span data-toggle="tooltip" data-placement="top" title="Marked deleted" style="color:grey;" class="fa fa-ban fa-lg"> </span><button data-toggle="tooltip" data-placement="top" title="Undelete <%- content_item.get("name") %>" class="primary-button btn-xs undelete_dataset_btn show_on_hover" type="button" style="display:none; margin-left:1em;"><span class="fa fa-unlock"> Undelete</span></button></td>');
tmpl_array.push('</tr>');

return _.template(tmpl_array.join(''));
},

templateRowDeletedFolder: function(){
tmpl_array = [];

tmpl_array.push('<tr class="active folder_row light library-row" id="<%- content_item.id %>">');
tmpl_array.push(' <td>');
tmpl_array.push(' <span title="Folder" class="fa fa-folder-o"></span>');
tmpl_array.push(' </td>');
tmpl_array.push(' <td></td>');
tmpl_array.push(' <td style="color:grey;">');
tmpl_array.push(' <%- content_item.get("name") %>');
tmpl_array.push(' </td>');
tmpl_array.push(' <td>folder</td>');
tmpl_array.push(' <td></td>');
tmpl_array.push(' <td><%= _.escape(content_item.get("update_time")) %></td>'); // time updated
tmpl_array.push(' <td><span data-toggle="tooltip" data-placement="top" title="Marked deleted" style="color:grey;" class="fa fa-ban fa-lg"> </span><button data-toggle="tooltip" data-placement="top" title="Undelete <%- content_item.get("name") %>" class="primary-button btn-xs undelete_folder_btn show_on_hover" type="button" style="display:none; margin-left:1em;"><span class="fa fa-unlock"> Undelete</span></button></td>');
tmpl_array.push('</tr>');

return _.template(tmpl_array.join(''));
}

Expand Down
57 changes: 38 additions & 19 deletions client/galaxy/scripts/mvc/library/library-foldertoolbar-view.js
Expand Up @@ -863,37 +863,45 @@ var FolderToolbarView = Backbone.View.extend({
* call them in chain. Update progress bar in between each.
* @param {array} lddas_set array of lddas to delete
*/
chainCallDeletingHdas: function( lddas_set ){
chainCallDeletingItems: function( items_to_delete ){
var self = this;
this.deleted_lddas = new mod_library_model.Folder();
var popped_item = lddas_set.pop();
this.deleted_items = new mod_library_model.Folder();
var popped_item = items_to_delete.pop();
if ( typeof popped_item === "undefined" ) {
if ( this.options.chain_call_control.failed_number === 0 ){
mod_toastr.success( 'Selected datasets were deleted.' );
mod_toastr.success( 'Selected items were deleted.' );
} else if ( this.options.chain_call_control.failed_number === this.options.chain_call_control.total_number ){
mod_toastr.error( 'There was an error and no datasets were deleted. Please make sure you have sufficient permissions.' );
mod_toastr.error( 'There was an error and no items were deleted. Please make sure you have sufficient permissions.' );
} else if ( this.options.chain_call_control.failed_number < this.options.chain_call_control.total_number ){
mod_toastr.warning( 'Some of the datasets could not be deleted. Please make sure you have sufficient permissions.' );
mod_toastr.warning( 'Some of the items could not be deleted. Please make sure you have sufficient permissions.' );
}
Galaxy.modal.hide();
return this.deleted_lddas;
return this.deleted_items;
}
var promise = $.when( popped_item.destroy() );

promise.done( function( dataset ){
promise.done( function( item ){
Galaxy.libraries.folderListView.collection.remove( popped_item.id );
self.updateProgress();
// add the deleted dataset to collection, triggers rendering
// add the deleted item to collection, triggers rendering
if ( Galaxy.libraries.folderListView.options.include_deleted ){
var updated_dataset = new mod_library_model.Item( dataset );
Galaxy.libraries.folderListView.collection.add( updated_dataset );
var updated_item = null;
if (item.type === 'folder' || item.model_class === 'LibraryFolder'){
updated_item = new mod_library_model.FolderAsModel( item );
} else if (item.type === 'file' || item.model_class === 'LibraryDataset'){
updated_item = new mod_library_model.Item( item );
} else {
console.error('Unknown library item type found.');
console.error(item.type || item.model_class);
}
Galaxy.libraries.folderListView.collection.add( updated_item );
}
self.chainCallDeletingHdas( lddas_set );
self.chainCallDeletingItems( items_to_delete );
})
.fail( function(){
self.options.chain_call_control.failed_number += 1;
self.updateProgress();
self.chainCallDeletingHdas( lddas_set );
self.chainCallDeletingItems( items_to_delete );
});
},

Expand Down Expand Up @@ -931,25 +939,35 @@ var FolderToolbarView = Backbone.View.extend({
this.options.chain_call_control.failed_number = 0;

var dataset_ids = [];
var folder_ids = [];
checkedValues.each(function(){
if (this.parentElement.parentElement.id !== '') {
dataset_ids.push(this.parentElement.parentElement.id);
if (this.parentElement.parentElement.id.substring(0,1) == 'F'){
folder_ids.push(this.parentElement.parentElement.id);
} else {
dataset_ids.push(this.parentElement.parentElement.id);
}
}
});
// init the progress bar
this.progressStep = 100 / dataset_ids.length;
var items_total = dataset_ids.length + folder_ids.length
this.progressStep = 100 / items_total;
this.progress = 0;

// prepare the dataset items to be added
var lddas_to_delete = [];
var items_to_delete = [];
for (var i = dataset_ids.length - 1; i >= 0; i--) {
var dataset = new mod_library_model.Item({id:dataset_ids[i]});
lddas_to_delete.push(dataset);
items_to_delete.push(dataset);
}
for (var i = folder_ids.length - 1; i >= 0; i--) {
var folder = new mod_library_model.FolderAsModel({id:folder_ids[i]});
items_to_delete.push(folder);
}

this.options.chain_call_control.total_number = dataset_ids.length;
this.options.chain_call_control.total_number = items_total.length;
// call the recursive function to call ajax one after each other (request FIFO queue)
this.chainCallDeletingHdas(lddas_to_delete);
this.chainCallDeletingItems(items_to_delete);
}
},

Expand Down Expand Up @@ -1099,6 +1117,7 @@ var FolderToolbarView = Backbone.View.extend({
tmpl_array.push('<p><%- library.get("description") %></p>');
tmpl_array.push('<h3>Library synopsis:</h3>');
tmpl_array.push('<p><%- library.get("synopsis") %></p>');
tmpl_array.push('<p data-toggle="tooltip" data-placement="top" title="<%- library.get("create_time") %>">created <%- library.get("create_time_pretty") %></p>');

tmpl_array.push('</div>');

Expand Down
47 changes: 29 additions & 18 deletions client/galaxy/scripts/mvc/library/library-model.js
Expand Up @@ -83,20 +83,19 @@ define([], function() {
// ============================================================================
// FOLDER RELATED MODELS

var Item = Backbone.Model.extend({
urlRoot : ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/libraries/datasets/'
var LibraryItem = Backbone.Model.extend({
});

var Ldda = Backbone.Model.extend({
var Ldda = LibraryItem.extend({
urlRoot : ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/libraries/datasets/'
});

var FolderAsModel = Backbone.Model.extend({
urlRoot: ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/folders'
var FolderAsModel = LibraryItem.extend({
urlRoot: ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/folders/'
});

var Folder = Backbone.Collection.extend({
model: Item,
model: LibraryItem,

/** Sort collection by item name (ascending) and return the sorted
* collection. Folders go before datasets.
Expand Down Expand Up @@ -150,16 +149,28 @@ define([], function() {
});

var FolderContainer = Backbone.Model.extend({
defaults : {
folder : new Folder(),
urlRoot : ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/folders/',
id : "unknown"
},
parse : function(obj) {
// response is not a simple array, it contains metadata
// this will update the inner collection
this.get("folder").reset(obj.folder_contents);
return obj;
defaults : {
folder : new Folder(),
urlRoot : ( window.galaxy_config ? galaxy_config.root : '/' ) + 'api/folders/',
id : "unknown"
},
parse : function(obj) {
// empty the collection
this.get("folder").reset();
// response is not a simple array, it contains metadata
// this will update the inner collection
for (var i = 0; i < obj.folder_contents.length; i++) {
if (obj.folder_contents[i].type === 'folder'){
var folder_item = new FolderAsModel(obj.folder_contents[i])
this.get("folder").add(folder_item);
} else if(obj.folder_contents[i].type === 'file'){
var file_item = new Ldda(obj.folder_contents[i])
this.get("folder").add(file_item);
} else{
console.error('Unknown folder item type encountered while parsing response.');
}
};
return obj;
}
});

Expand Down Expand Up @@ -204,10 +215,10 @@ define([], function() {

return {
Library: Library,
FolderAsModel : FolderAsModel,
Libraries : Libraries,
Item : Item,
Item : Ldda,
Ldda : Ldda,
FolderAsModel : FolderAsModel,
Folder : Folder,
FolderContainer : FolderContainer,
HistoryItem : HistoryItem,
Expand Down

0 comments on commit 6406276

Please sign in to comment.