ToolForm: Match and sort datasets and collections through API, add single selection as default option

This commit is contained in:
Aysam Guerler
2014-11-11 21:46:38 -05:00
parent 62918c0ff3
commit b9a13cdf2f
21 changed files with 370 additions and 444 deletions
+11 -111
View File
@@ -1,96 +1,23 @@
define(['utils/utils'], function(Utils){
return Backbone.Model.extend({
// initialize
initialize: function(options) {
// backup basic url
this.base_url = galaxy_config.root + 'api/histories/' + options.history_id + '/contents';
// prepare content obects
this.datatypes = {};
initialize: function(app) {
this.summary = {};
// link this
var self = this;
// request datatypes
Utils.get({
url : galaxy_config.root + 'api/datatypes/mapping',
cache : true,
success : function(response) {
// backup datatype dictionary
self.datatypes = response;
// get history summary
Utils.get({
url : self.base_url + '?deleted=false',
success : function(response) {
// backup summary
self.summary = response;
// sort by id
self.summary.sort(function(a, b) {
return a.hid > b.hid ? -1 : (a.hid < b.hid ? 1 : 0);
});
// log
console.debug('tools-content::initialize() - Completed.');
// callback
options.success && options.success();
},
error : function(response) {
// log request failure
console.debug('tools-content::initialize() - Ajax request for summary failed.');
console.debug(response);
}
});
},
error : function(response) {
// log request failure
console.debug('tools-content::initialize() - Ajax request for datatypes failed.');
console.debug(response);
}
});
},
/**
* Filters contents by data type.
/** Add new content elements
*/
filterType: function(options) {
// initialize parameters
options = options || {};
var result = [];
// identify content type
var history_content_type = 'dataset';
if (options.src== 'hdca') {
history_content_type = 'dataset_collection';
}
// search in summary
for (var i in this.summary) {
var content = this.summary[i];
// check ok state (TODO: should be implemented in the api)
if (content.history_content_type === 'dataset' && content.state !== 'ok') {
continue;
}
// match datatypes
var found = false;
for (var i in options.extensions) {
if (this._matchType(options.extensions[i], content.extension)) {
found = true;
break;
}
}
// final match result
if ((content.history_content_type === history_content_type) && (found || !options.extensions)) {
result.push(content);
add: function(content_list) {
// add/update content in summary list
for (var i in content_list) {
for (var j in content_list[i]) {
var c = content_list[i][j];
this.summary[c.id + '_' + c.src] = c;
}
}
return result;
// log
console.debug('tools-content::initialize() - Completed.');
},
/** Returns matched content from summary.
@@ -126,33 +53,6 @@ define(['utils/utils'], function(Utils){
console.debug(response);
}
});
},
/** Check if datatypes match
*/
_matchType: function(target, reference) {
// check if target class is available
var target_class = this.datatypes.ext_to_class_name[target];
if (!target_class) {
console.debug('tools-content::_matchType() - Specific target class unavailable. Accepting all formats.');
return true;
}
// check if reference class is available
var reference_class = this.datatypes.ext_to_class_name[reference];
if (!reference_class) {
console.debug('tools-content::_matchType() - Specific reference class unavailable. Accepting all formats.');
return true;
}
// check reference group
var reference_group = this.datatypes.class_to_classes[reference_class];
if (reference_group[target_class]) {
return true;
}
// classes do not match
return false;
}
});
});
+32 -20
View File
@@ -21,11 +21,19 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc',
var self = this;
// link galaxy modal or create one
if (parent.Galaxy && parent.Galaxy.modal) {
this.modal = parent.Galaxy.modal;
var galaxy = parent.Galaxy;
if (galaxy && galaxy.modal) {
this.modal = galaxy.modal;
} else {
this.modal = new Ui.Modal.View();
}
// check if the user is an admin
if (galaxy && galaxy.currUser) {
this.is_admin = galaxy.currUser.get('is_admin')
} else {
this.is_admin = false;
}
// link options
this.options = options;
@@ -47,12 +55,10 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc',
this.job_handler = new ToolJobs(this);
// request history content and build form
this.content = new ToolContent({
history_id : self.options.history_id,
success : function() {
self._buildForm(self.options);
}
});
this.content = new ToolContent(this);
// build this form
this._buildForm(options);
},
// message
@@ -72,7 +78,7 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc',
// this happens i.e. when repeat blocks are added or removed and on initialization
rebuild: function() {
this.tree.refresh();
console.debug('tools-form::refresh() - Refreshed form structure.');
console.debug('tools-form::rebuild() - Rebuilding data structures.');
},
// refreshes input states i.e. for dynamic parameters
@@ -142,7 +148,7 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc',
var current_state = this.tree.finalize({
data : function(dict) {
if (dict.values.length > 0 && dict.values[0] && dict.values[0].src === 'hda') {
return self.content.get({id: dict.values[0].id}).dataset_id;
return self.content.get({id: dict.values[0].id, src: 'hda'}).dataset_id;
}
return null;
}
@@ -215,16 +221,22 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc',
// get/update field
var field = self.field_list[input_id];
if (field.update && input.type != 'data') {
if (field.update) {
var new_options = [];
for (var i in node.options) {
var opt = node.options[i];
if (opt.length > 2) {
new_options.push({
'label': opt[0],
'value': opt[1]
});
}
switch (input.type) {
case 'data':
new_options = input.options;
break;
default:
for (var i in node.options) {
var opt = node.options[i];
if (opt.length > 2) {
new_options.push({
'label': opt[0],
'value': opt[1]
});
}
}
}
field.update(new_options);
console.debug('Updating options for ' + input_id);
@@ -292,7 +304,7 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc',
});
// add admin operations
if (Galaxy.currUser.get('is_admin')) {
if (this.is_admin) {
// create download button
menu.addMenu({
icon : 'fa-download',
@@ -142,8 +142,8 @@ return Backbone.Model.extend({
if (batch_n === -1) {
batch_n = n;
} else {
if (batch_n !== n && n != 1) {
this._foundError(input_id, 'Please make sure that you select a single input or the same number of inputs for all batch mode fields. This field contains <b>' + n + '</b> selection(s) while a previous field contains <b>' + batch_n + '</b>.');
if (batch_n !== n) {
this._foundError(input_id, 'Please make sure that you select the same number of inputs for all batch mode fields. This field contains <b>' + n + '</b> selection(s) while a previous field contains <b>' + batch_n + '</b>.');
return false;
}
}
@@ -372,6 +372,7 @@ define(['utils/utils', 'mvc/ui/ui-table', 'mvc/ui/ui-misc', 'mvc/tools/tools-rep
id : 'field-' + input_def.id,
extensions : input_def.extensions,
multiple : input_def.multiple,
data : input_def.options,
onchange : function() {
self.app.refresh();
}
@@ -4,7 +4,8 @@ define(['utils/utils', 'mvc/ui/ui-misc', 'mvc/ui/ui-tabs', 'mvc/tools/tools-temp
var View = Backbone.View.extend({
// initialize
initialize : function(app, options) {
// configure options
// link app and options
this.app = app;
this.options = options;
// link this
@@ -14,13 +15,14 @@ var View = Backbone.View.extend({
this.setElement('<div/>');
// current selection
this.current = 'hda';
this.current = 'single';
// create button
this.button_new = new Ui.RadioButton.View({
this.button_type = new Ui.RadioButton.View({
value : this.current,
data : [ { icon: 'fa-file-o', label : 'Select datasets', value : 'hda' },
{ icon: 'fa-files-o', label : 'Select a collection', value : 'hdca' }],
data : [ { icon: 'fa-file-o', label : 'Single dataset', value : 'single' },
{ icon: 'fa-files-o', label : 'Multiple datasets', value : 'multiple' },
{ icon: 'fa-folder-o', label : 'List of datasets', value : 'collection' }],
onchange: function(value) {
self.current = value;
self.refresh();
@@ -28,68 +30,56 @@ var View = Backbone.View.extend({
}
});
//
// datasets
//
var datasets = app.content.filterType({
src : 'hda',
extensions : options.extensions
// single dataset select field
this.select_single = new Ui.Select.View({
onchange : function() {
self.trigger('change');
}
});
// configure options fields
var dataset_options = [];
for (var i in datasets) {
dataset_options.push({
label: datasets[i].hid + ': ' + datasets[i].name,
value: datasets[i].id
});
}
// select field
this.select_datasets = new Ui.Select.View({
// multiple datasets select field
this.select_multiple = new Ui.Select.View({
multiple : true,
data : dataset_options,
value : dataset_options[0] && dataset_options[0].value,
onchange : function() {
self.trigger('change');
}
});
//
// collections
//
var collections = app.content.filterType({
src : 'hdca',
extensions : options.extensions
});
// configure options fields
var collection_options = [];
for (var i in collections) {
collection_options.push({
label: collections[i].hid + ': ' + collections[i].name,
value: collections[i].id
});
}
// create select field for collections
// collection select field
this.select_collection = new Ui.Select.View({
data : collection_options,
value : collection_options[0] && collection_options[0].value,
onchange : function() {
self.trigger('change');
}
});
// list of all select fields
this.list = {
'single' : {
field: this.select_single,
type : 'hda'
},
'multiple' : {
field: this.select_multiple,
type : 'hda'
},
'collection' : {
field: this.select_collection,
type : 'hdca'
}
};
// add batch mode information
this.$batch = $(ToolTemplate.batchMode());
// add elements to dom
this.$el.append(Utils.wrap(this.button_new.$el));
this.$el.append(this.select_datasets.$el);
this.$el.append(this.select_collection.$el);
// check for batch mode
if (!this.options.multiple) {
this.$el.append(ToolTemplate.batchMode());
this.$el.append(Utils.wrap(this.button_type.$el));
for (var i in this.list) {
this.$el.append(this.list[i].field.$el);
}
this.$el.append(this.$batch);
// update options
this.update(options.data);
// refresh view
this.refresh();
@@ -102,31 +92,77 @@ var View = Backbone.View.extend({
});
},
/** Indicate that select fields are being updated */
wait: function() {
for (var i in this.list) {
this.list[i].field.wait();
}
},
/** Indicate that the options update has been completed */
unwait: function() {
for (var i in this.list) {
this.list[i].field.unwait();
}
},
/** Update content selector */
update: function(options) {
// identify dataset options
var dataset_options = [];
for (var i in options.hda) {
var hda = options.hda[i];
dataset_options.push({
label: hda.hid + ': ' + hda.name,
value: hda.id
});
}
// identify collection options
var collection_options = [];
for (var i in options.hdca) {
var hdca = options.hdca[i];
collection_options.push({
label: hdca.hid + ': ' + hdca.name,
value: hdca.id
});
}
// update selection fields
this.select_single.update(dataset_options);
this.select_multiple.update(dataset_options);
this.select_collection.update(collection_options);
// add to content list
this.app.content.add(options);
},
/** Return the currently selected dataset values */
value : function (dict) {
// update current value
if (dict !== undefined) {
try {
// set source
this.current = dict.values[0].src;
this.refresh();
// create list
var list = [];
for (var i in dict.values) {
list.push(dict.values[i].id);
}
// identify select element
switch(this.current) {
case 'hda':
this.select_datasets.value(list);
break;
case 'hdca':
this.select_collection.value(list[0]);
break;
// identify suitable select field
if (dict && dict.values.length > 0 && dict.values[0].src == 'hcda') {
this.current = 'collection';
this.select_collection.value(list[0]);
} else {
if (list.length > 1) {
this.current = 'multiple';
this.select_multiple.value(list);
} else {
this.current = 'single';
this.select_single.value(list[0]);
}
}
this.refresh();
// check if value has been set
var select = this._select();
if (!select.validate()) {
@@ -153,7 +189,7 @@ var View = Backbone.View.extend({
for (var i in id_list) {
result.values.push({
id : id_list[i],
src : this.current
src : this.list[this.current].type
});
}
@@ -169,26 +205,24 @@ var View = Backbone.View.extend({
/** Refreshes data selection view */
refresh: function() {
switch (this.current) {
case 'hda':
this.select_datasets.$el.fadeIn();
this.select_collection.$el.hide();
break;
case 'hdca':
this.select_datasets.$el.hide();
this.select_collection.$el.fadeIn();
break;
for (var i in this.list) {
var $el = this.list[i].field.$el;
if (this.current == i) {
$el.show();
} else {
$el.hide();
}
}
if (this.current != 'single' && !this.options.multiple) {
this.$batch.show();
} else {
this.$batch.hide();
}
},
/** Assists in selecting the current field */
_select: function() {
switch(this.current) {
case 'hdca':
return this.select_collection;
default:
return this.select_datasets;
}
return this.list[this.current].field;
}
});
@@ -56,7 +56,7 @@ return {
batchMode: function() {
return '<div class="ui-table-form-info">' +
'<i class="fa fa-sitemap" style="font-size: 1.2em; padding: 2px 5px;"/>' +
'This is a batch mode input field. A separate job will be triggered for each dataset.'
'This is a batch mode input field. A separate job will be triggered for each dataset.' +
'</div>';
}
};