1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/commits/93215e7e74d0/ Changeset: 93215e7e74d0 User: guerler Date: 2013-09-20 04:53:34 Summary: Drag&drop multiple file upload: updates and fixes Affected #: 9 files diff -r 6f77298e8d1628fb55d8ba72a69ab62b7864bb7a -r 93215e7e74d020b478803ce2755f76c7e5236f16 lib/galaxy/webapps/galaxy/api/history_contents.py --- a/lib/galaxy/webapps/galaxy/api/history_contents.py +++ b/lib/galaxy/webapps/galaxy/api/history_contents.py @@ -235,8 +235,15 @@ # get file destination file_destination = dataset.get_file_name() + # check if the directory exists + dn = os.path.dirname(file_destination) + if not os.path.exists(dn): + os.makedirs(dn) + + # get file and directory names + fn = os.path.basename(content.filename) + # save file locally - fn = os.path.basename(content.filename) open(file_destination, 'wb').write(content.file.read()) # log diff -r 6f77298e8d1628fb55d8ba72a69ab62b7864bb7a -r 93215e7e74d020b478803ce2755f76c7e5236f16 static/scripts/galaxy.modal.js --- a/static/scripts/galaxy.modal.js +++ b/static/scripts/galaxy.modal.js @@ -77,13 +77,25 @@ // link functions $.each(options.buttons, function(name, value) { - footer.append($('<button></button>').text(name).click(value)).append(" "); + footer.append($('<button id="' + String(name).toLowerCase() + '"></button>').text(name).click(value)).append(" "); }); } else // default close button footer.append($('<button></button>').text('Close').click(function() { self.hide() })).append(" "); }, + // enable buttons + enable: function(name) + { + $(this.el).find('#' + String(name).toLowerCase()).prop('disabled', false); + }, + + // disable buttons + disable: function(name) + { + $(this.el).find('#' + String(name).toLowerCase()).prop('disabled', true); + }, + /* HTML TEMPLATES */ diff -r 6f77298e8d1628fb55d8ba72a69ab62b7864bb7a -r 93215e7e74d020b478803ce2755f76c7e5236f16 static/scripts/galaxy.upload.js --- a/static/scripts/galaxy.upload.js +++ b/static/scripts/galaxy.upload.js @@ -1,5 +1,5 @@ /* - galaxy upload v1.0 + galaxy upload */ // dependencies @@ -14,12 +14,20 @@ // button button_show : null, - // file counter - file_counter: 0, + // upload mod + uploadbox: null, // initialize initialize : function() { + // wait for galaxy history panel (workaround due to the use of iframes) + if (!Galaxy.currHistoryPanel) + { + var self = this; + window.setTimeout(function() { self.initialize() }, 500) + return; + } + // add activate icon var self = this; this.button_show = new mod_master.GalaxyMasterIcon ( @@ -37,87 +45,252 @@ // events events : { - 'mouseover' : 'event_mouseover', - 'mouseleave' : 'event_mouseleave' + 'mouseover' : 'event_mouseover', + 'mouseleave' : 'event_mouseleave' }, // mouse over event_mouseover : function (e) { - $('#galaxy-upload-box').addClass('highlight'); }, // mouse left event_mouseleave : function (e) { - $('#galaxy-upload-box').removeClass('highlight'); }, // start - event_start : function(index, file, message) + event_announce : function(index, file, message) { + // hide info + this.uploadbox.info().hide(); + // make id - var id = '#galaxy-upload-file-' + index; + var id = '#upload-' + index; - // add tag - $('#galaxy-upload-box').append(this.template_file(id)); + // add upload item + $(this.el).append(this.template_file(id)); + + // scroll to bottom + $(this.el).scrollTop($(this.el).prop('scrollHeight')); + + // access upload item + var it = this.get_upload_item(index); + + // fade in + it.fadeIn(); // update title - $('#galaxy-upload-file-' + index).find('.title').html(file.name); + it.find('.title').html(file.name); + // configure select field + it.find('#extension').select2( + { + placeholder: 'Auto-detect', + width: 'copy', + ajax: { + url: "http://www.weighttraining.com/sm/search", + dataType: 'jsonp', + quietMillis: 100, + data: function(term, page) + { + return { + types: ["exercise"], + limit: -1, + term: term + }; + }, + results: function(data, page) + { + return { results: data.results.exercise } + } + }, + formatResult: function(exercise) + { + return "<div class='select2-user-result'>" + exercise.term + "</div>"; + }, + formatSelection: function(exercise) + { + return exercise.term; + }, + initSelection : function (element, callback) + { + var elementText = $(element).attr('data-init-text'); + callback({"term":elementText}); + } + }); + + // add functionality to remove button + var self = this; + it.find('.remove').on('click', function() { self.event_remove (index) }); + // initialize progress this.event_progress(index, file, 0); - // update counter - this.file_counter++; - this.refresh(); + // update button status + this.modal.enable('Upload'); + this.modal.enable('Reset'); + }, + + // start + event_initialize : function(index, file, message) + { + // update on screen counter + this.button_show.number(message); + + // get element + var it = this.get_upload_item(index); + + // read in configuration + var data = { + source : "upload", + space_to_tabs : it.find('#space_to_tabs').is(':checked'), + extension : it.find('#extension').val() + } + + // return additional data to be send with file + return data; }, // progress event_progress : function(index, file, message) { - // get progress bar - var el = $('#galaxy-upload-file-' + index); + // get element + var it = this.get_upload_item(index); // get value var percentage = parseInt(message); // update progress - el.find('.progress').css({ width : percentage + '%' }); + it.find('.progress-bar').css({ width : percentage + '%' }); // update info - el.find('.info').html(percentage + '% of ' + this.size_to_string (file.size)); + it.find('.info').html(percentage + '% of ' + this.size_to_string (file.size)); }, // end event_success : function(index, file, message) - { + { + // get element + var it = this.get_upload_item(index); + + // update progress frame + it.addClass('panel-success'); + it.removeClass('panel-default'); + // update galaxy history Galaxy.currHistoryPanel.refresh(); - // update counter - this.file_counter--; - this.refresh(); + // make sure progress is shown correctly + this.event_progress(index, file, 100); + + // update on screen counter + this.button_show.number(''); }, // end event_error : function(index, file, message) { - // get file box - var el = $('#galaxy-upload-file-' + index); + // get element + var it = this.get_upload_item(index); // update progress frame - el.find('.progress-frame').addClass('failed'); + it.addClass('panel-danger'); + it.removeClass('panel-default'); - // update error message - el.find('.error').html("<strong>Failed:</strong> " + message); - - // update progress + // remove progress bar + it.find('.progress').remove(); + + // write error message + it.find('.error').html('<strong>Failed:</strong> ' + message); + + // make sure progress is shown correctly this.event_progress(index, file, 0); - // update counter - this.file_counter--; - this.refresh(); + // update on screen counter + this.button_show.number(''); + }, + + // start upload process + event_upload : function() + { + // hide configuration + $(this.el).find('.panel-body').hide(); + + // switch icon + $(this.el).find('.remove').each(function() + { + $(this).removeClass('fa-icon-trash'); + $(this).addClass('fa-icon-caret-down'); + }); + + // update button status + this.modal.disable('Upload'); + + // configure url + var current_history = Galaxy.currHistoryPanel.model.get('id'); + this.uploadbox.configure({url : galaxy_config.root + "api/histories/" + current_history + "/contents"}); + + // initiate upload procedure in plugin + this.uploadbox.upload(); + }, + + // remove all + event_reset : function() + { + // remove from screen + var panels = $(this.el).find('.panel'); + var self = this; + panels.fadeOut({complete: function() + { + // remove panels + panels.remove(); + + // show on screen info + self.uploadbox.info().fadeIn(); + }}); + + // update button status + this.modal.disable('Upload'); + this.modal.disable('Reset'); + + // remove from queue + this.uploadbox.reset(); + }, + + // remove item from upload list + event_remove : function(index) + { + // remove + var self = this; + var it = this.get_upload_item(index); + + // fade out and update button status + it.fadeOut({complete: function() + { + // remove from screen + it.remove(); + + // remove from queue + self.uploadbox.remove(index); + + // update reset button + if ($(self.el).find('.panel').length > 0) + self.modal.enable('Reset'); + else { + // disable reset button + self.modal.disable('Reset'); + + // show on screen info + self.uploadbox.info().fadeIn(); + } + + // update upload button + if (self.uploadbox.length() > 0) + self.modal.enable('Upload'); + else + self.modal.disable('Upload'); + }}); }, // show/hide upload frame @@ -126,14 +299,6 @@ // prevent default e.preventDefault(); - // wait for galaxy history panel (workaround due to the use of iframes) - if (!Galaxy.currHistoryPanel) - { - var self = this; - window.setTimeout(function() { self.event_show(e) }, 200) - return; - } - // create modal if (!this.modal) { @@ -142,44 +307,45 @@ this.modal = new mod_modal.GalaxyModal( { title : 'Upload files from your local drive', - body : this.template(), + body : this.template('upload-box'), buttons : { - 'Close' : function() {self.modal.hide()} + 'Select' : function() {self.uploadbox.select()}, + 'Upload' : function() {self.event_upload()}, + 'Reset' : function() {self.event_reset()}, + 'Close' : function() {self.modal.hide()} } }); - // get current history - var current_history = Galaxy.currHistoryPanel.model.get('id'); - + // set element + this.setElement('#upload-box'); + // file upload var self = this; - $('#galaxy-upload-box').uploadbox( + this.uploadbox = this.$el.uploadbox( { - url : galaxy_config.root + "api/histories/" + current_history + "/contents", dragover : self.event_mouseover, dragleave : self.event_mouseleave, - start : function(index, file, message) { self.event_start(index, file, message) }, + announce : function(index, file, message) { self.event_announce(index, file, message) }, + initialize : function(index, file, message) { return self.event_initialize(index, file, message) }, success : function(index, file, message) { self.event_success(index, file, message) }, progress : function(index, file, message) { self.event_progress(index, file, message) }, error : function(index, file, message) { self.event_error(index, file, message) }, - data : {source : "upload"} }); - // set element - this.setElement('#galaxy-upload-box'); + // update button status + this.modal.disable('Upload'); + this.modal.disable('Reset'); } - + // show modal this.modal.show(); }, - // update counter - refresh: function () + // get upload item + get_upload_item: function(index) { - if (this.file_counter > 0) - this.button_show.number(this.file_counter); - else - this.button_show.number(''); + // get element + return $(this.el).find('#upload-' + index); }, // to string @@ -197,21 +363,32 @@ }, // load html template - template: function() + template: function(id) { - return '<form id="galaxy-upload-box" class="galaxy-upload-box"></form>'; + return '<div id="' + id + '" class="upload-box"></div>'; }, // load html template template_file: function(id) { - return '<div id="' + id.substr(1) + '" class="file corner-soft shadow">' + - '<div class="title"></div>' + - '<div class="error"></div>' + - '<div class="progress-frame corner-soft">' + - '<div class="progress"></div>' + + return '<div id="' + id.substr(1) + '" class="panel panel-default">' + + '<div class="panel-heading">' + + '<h5 class="title"></h5>' + + '<h5 class="info"></h5>' + + '<div class="remove fa-icon-trash"></div>' + '</div>' + - '<div class="info"></div>' + + '<div class="panel-body">' + + '<div class="menu">' + + //'<input id="extension" type="hidden" width="10px"/> ' + + '<span><input id="space_to_tabs" type="checkbox">Convert spaces to tabs</input></span>' + + '</div>' + + '</div>' + + '<div class="panel-footer">' + + '<div class="progress">' + + '<div class="progress-bar progress-bar-success"></div>' + + '</div>' + + '<h6 class="error"></h6>' + + '</div>' + '</div>'; } }); diff -r 6f77298e8d1628fb55d8ba72a69ab62b7864bb7a -r 93215e7e74d020b478803ce2755f76c7e5236f16 static/scripts/utils/galaxy.uploadbox.js --- a/static/scripts/utils/galaxy.uploadbox.js +++ b/static/scripts/utils/galaxy.uploadbox.js @@ -1,5 +1,5 @@ /* - galaxy upload lib v1.0 - uses FileReader, FormData and XMLHttpRequest + galaxy upload lib - uses FileReader, FormData and XMLHttpRequest */ ;(function($) { @@ -11,67 +11,71 @@ { url : '', paramname : 'content', - maxfilesize : 2048, - data : {}, + maxfilesize : 250, dragover : function() {}, dragleave : function() {}, + announce : function() {}, initialize : function() {}, - start : function() {}, progress : function() {}, success : function() {}, error : function(index, file, message) { alert(message); }, error_browser : "Your browser does not support drag-and-drop file uploads.", - error_filesize : "This file is too large. Please use an FTP client to upload it.", - error_default : "The upload failed. Please make sure the file is available and accessible.", - text_default : "Drag&drop files here or click to browse your local drive.", - text_degrade : "Click here to browse your local drive. <br><br>Unfortunately, your browser does not support multiple file uploads or drag&drop.<br>Please upgrade to i.e. Firefox 4+, Chrome 7+, IE 10+, Opera 12+ or Safari 6+." + error_filesize : "This file is too large (>250MB). Please use an FTP client to upload it.", + error_default : "Please make sure the file is available.", + text_default : "Drag&drop files into this box or click 'Select' to select files!", + text_degrade : "Unfortunately, your browser does not support multiple file uploads or drag&drop.<br>Please upgrade to i.e. Firefox 4+, Chrome 7+, IE 10+, Opera 12+ or Safari 6+." } - // global file queue - var queue = []; + // options + var opts = {}; + + // file queue + var queue = {}; - // global counter for file being currently processed - var queue_index = -1; + // counter for file being currently processed + var queue_index = 0; - // global queue status + // queue length + var queue_length = 0; + + // indicates if queue is currently running var queue_status = false; + // element + var el = null; + // attach to element $.fn.uploadbox = function(options) { // parse options - var opts = $.extend({}, default_opts, options); + opts = $.extend({}, default_opts, options); // compatibility var mode = window.File && window.FileReader && window.FormData && window.XMLHttpRequest; + // element + el = this; + // append upload button - this.append('<input id="uploadbox_input" type="file" style="display: none" multiple>'); - this.append('<div id="uploadbox_info"></div>'); + el.append('<input id="uploadbox_input" type="file" style="display: none" multiple>'); + el.append('<div id="uploadbox_info"></div>'); // set info text if (mode) - this.find('#uploadbox_info').html(opts.text_default); + el.find('#uploadbox_info').html(opts.text_default); else - this.find('#uploadbox_info').html(opts.text_degrade); + el.find('#uploadbox_info').html(opts.text_degrade); // attach events - this.on('drop', drop); - this.on('dragover', dragover); - this.on('dragleave', dragleave); - - // attach click event - this.on('click', function(e) - { - e.stopPropagation(); - $('#uploadbox_input').trigger(e); - }); + el.on('drop', drop); + el.on('dragover', dragover); + el.on('dragleave', dragleave); // attach change event $('#uploadbox_input').change(function(e) { - var files = e.target.files; - upload(files); + // add files to queue + add(e.target.files); }); // drop event @@ -81,11 +85,8 @@ if(!e.dataTransfer) return; - // get files from event - var files = e.dataTransfer.files; - - // start upload - upload(files); + // add files to queue + add(e.dataTransfer.files); // prevent default e.preventDefault(); @@ -98,14 +99,14 @@ function dragover(e) { e.preventDefault(); - opts.dragover.call(this, e); + opts.dragover.call(e); } // drag leave function dragleave(e) { e.stopPropagation(); - opts.dragleave.call(this, e); + opts.dragleave.call(e); } // progress @@ -117,39 +118,61 @@ } // respond to an upload request - function upload(files) + function add(files) { - // get current queue size - var queue_sofar = queue.length; + // add new files to queue + for (var i = 0; i < files.length; i++) + { + // new identifier + var index = String(++queue_index); - // add new files to queue - for (var index = 0; index < files.length; index++) - queue.push(files[index]); + // add to queue + queue[index] = files[i]; - // tell client about new uploads - for (var index = queue_sofar; index < queue.length; index++) - opts.start(index, queue[index], ""); + // increase counter + queue_length++; - // initiate processing loop if process loop is not running already - if (!queue_status) - process(); + // announce + opts.announce(index, queue[index], ""); + } } + // remove entry from queue + function remove(index) + { + if (queue[index]) + { + // remove from queue + delete queue[index]; + + // update counter + queue_length--; + } + } + // process an upload, recursive function process() { - // check if for files - if (queue_index + 1 == queue.length) + // get an identifier from the queue + var index = -1; + for (var key in queue) { - queue_status = false; - return; + index = key; + break; } - // set status - queue_status = true; + // validate + if (queue_length == 0) + return; - // identify current index - var index = ++queue_index; + // get current file from queue + var file = queue[index]; + + // remove from queue + remove(index) + + // start + var data = opts.initialize(index, file, length); // add file to queue try @@ -158,50 +181,45 @@ var reader = new FileReader(); // identify maximum file size - var file = queue[index]; var filesize = file.size; var maxfilesize = 1048576 * opts.maxfilesize; - + // set index reader.index = index; if (filesize < maxfilesize) { - // link loadend is always called at the end - reader.onloadend = function(e) + // link load + reader.onload = function(e) { - send(index, file) + send(index, file, data) }; // link error reader.onerror = function(e) { - opts.error(index, file, opts.error_default); - queue_status = false; + error(index, file, opts.error_default); }; // read data reader.readAsDataURL(file); } else { // skip file - opts.error(index, file, opts.error_filesize); - - // restart process - process(); + error(index, file, opts.error_filesize); } } catch (err) { // parse error - opts.error(index, file, err); + error(index, file, err); } } // send file - function send (index, file) + function send (index, file, data) { // construct form data var formData = new FormData(); - for (var key in opts.data) - formData.append(key, opts.data[key]); + for (var key in data) + formData.append(key, data[key]); formData.append(opts.paramname, file, file.name); // prepare request @@ -237,22 +255,94 @@ // pass any error to the error option if (xhr.status < 200 || xhr.status > 299) { + // format error + var text = xhr.statusText; + if (!xhr.statusText) + text = opts.error_default; + // request error - opts.error(index, file, xhr.statusText + " (Server Code " + xhr.status + ")"); - - // reset status - queue_status = false; - } else { + error(index, file, text + " (Server Code " + xhr.status + ")"); + } else // parse response - opts.success(index, file, response); - - // upload next file - process(); - } + success(index, file, response); } } - // return - return this; + // success + function success (index, file, msg) + { + // parse message + opts.success(index, file, msg); + + // restart process after success + process(); + } + + // error + function error (index, file, err) + { + // parse error + opts.error(index, file, err); + + // restart process after error + process(); + } + + /* + public interface + */ + + // open file browser for selection + function select() + { + $('#uploadbox_input').trigger('click'); + } + + // remove all entries from queue + function reset(index) + { + for (index in queue) + remove(index); + } + + // initiate upload process + function upload() + { + if (!queue_status) + process(); + } + + // current queue length + function length() + { + return queue_length; + } + + // set options + function configure(options) + { + // update current configuration + opts = $.extend({}, opts, options); + + // return new configuration + return opts; + } + + // visibility of on screen information + function info() + { + return el.find('#uploadbox_info'); + } + + // export functions + return { + 'select' : select, + 'remove' : remove, + 'upload' : upload, + 'reset' : reset, + 'length' : length, + 'configure' : configure, + 'info' : info + }; } })(jQuery); \ No newline at end of file diff -r 6f77298e8d1628fb55d8ba72a69ab62b7864bb7a -r 93215e7e74d020b478803ce2755f76c7e5236f16 static/style/blue/base.css --- a/static/style/blue/base.css +++ b/static/style/blue/base.css @@ -1122,15 +1122,12 @@ .galaxy-frame .frame .f-close{right:5px;top:1px} .galaxy-frame .frame .f-pin{left:6px;top:1px} .galaxy-frame .frame .f-resize{background:#fff;width:16px;height:16px;color:#2c3143;right:0px;bottom:0px;text-align:center;line-height:16px;border:0px} -.galaxy-upload-box{width:100%;height:200px;max-height:200px;padding:10px 0px 0px 0px;text-align:center;cursor:pointer;overflow:scroll;font-size:12px;line-height:1.428571429;-moz-border-radius:5px;border-radius:5px;border:1px dashed #bfbfbf}.galaxy-upload-box .corner-soft{-moz-border-radius:3px;border-radius:3px} -.galaxy-upload-box .shadow{-webkit-box-shadow:0 0 2px rgba(0,0,0,0.3)} -.galaxy-upload-box .highlight{border:1px dashed #333} -.galaxy-upload-box .file{position:relative;margin:5px 20px 5px 20px;border:1px solid #bfbfbf;color:#333}.galaxy-upload-box .file .title{margin:3px 130px 0px 5px;text-align:left;overflow:hidden;border:0px} -.galaxy-upload-box .file .progress-frame{border:0px;margin:0px 5px 3px 5px;height:7px;background:#bfbfbf} -.galaxy-upload-box .file .progress{background:#5cb85c;height:100%;width:0%} -.galaxy-upload-box .file .failed{background:#d9534f} -.galaxy-upload-box .file .error{font-size:11px;text-align:left;overflow:hidden;margin:0px 5px 0px 5px} -.galaxy-upload-box .file .info{position:absolute;top:4px;right:5px;font-size:11px;text-align:right;overflow:hidden;max-width:100px;max-height:12px} +.upload-box{width:100%;height:250px;max-height:250px;text-align:center;overflow:scroll;font-size:12px;line-height:1.33;-moz-border-radius:5px;border-radius:5px;border:1px dashed #bfbfbf;padding:20px}.upload-box .panel{display:none}.upload-box .panel .panel-heading{position:relative;height:19px;padding:5px}.upload-box .panel .panel-heading .title{position:absolute;top:2px;font-weight:normal;text-align:left;margin:0px;max-width:300px;overflow:hidden} +.upload-box .panel .panel-heading .info{position:absolute;top:3px;font-weight:normal;right:20px;text-align:right;margin:0px} +.upload-box .panel .panel-heading .remove{position:absolute;cursor:pointer;top:0px;right:3px} +.upload-box .panel .panel-body{position:relative;padding:5px} +.upload-box .panel .panel-footer{position:relative;height:20px;padding:0px}.upload-box .panel .panel-footer .progress{height:10px;margin:5px} +.upload-box .panel .panel-footer .error{font-weight:normal;margin:2px} .unselectable{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none} .parent-width{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:100%;*width:90%} .clear:before,.clear:after{content:" ";display:table;} diff -r 6f77298e8d1628fb55d8ba72a69ab62b7864bb7a -r 93215e7e74d020b478803ce2755f76c7e5236f16 static/style/blue/sprite-fugue.png Binary file static/style/blue/sprite-fugue.png has changed diff -r 6f77298e8d1628fb55d8ba72a69ab62b7864bb7a -r 93215e7e74d020b478803ce2755f76c7e5236f16 static/style/blue/sprite-history-buttons.png Binary file static/style/blue/sprite-history-buttons.png has changed diff -r 6f77298e8d1628fb55d8ba72a69ab62b7864bb7a -r 93215e7e74d020b478803ce2755f76c7e5236f16 static/style/blue/sprite-history-states.png Binary file static/style/blue/sprite-history-states.png has changed diff -r 6f77298e8d1628fb55d8ba72a69ab62b7864bb7a -r 93215e7e74d020b478803ce2755f76c7e5236f16 static/style/src/less/upload.less --- a/static/style/src/less/upload.less +++ b/static/style/src/less/upload.less @@ -1,87 +1,80 @@ -.galaxy-upload-box +.upload-box { width : 100%; - height : 200px; - max-height : 200px; - padding : 10px 0px 0px 0px; + height : 250px; + max-height : 250px; text-align : center; - cursor : pointer; overflow : scroll; font-size : @font-size-base; - line-height : @line-height-base; + line-height : @line-height-large; -moz-border-radius: @border-radius-large; - border-radius: @border-radius-large; + border-radius : @border-radius-large; border : 1px dashed @btn-default-border; + padding : 20px; - .corner-soft + .panel { - -moz-border-radius: @border-radius-base; - border-radius: @border-radius-base; - } + display: none; - .shadow - { - -webkit-box-shadow: 0 0 2px rgba(0,0,0,0.3); - } + .panel-heading + { + position: relative; + height: 19px; + padding: 5px; - .highlight - { - border : 1px dashed @btn-default-color; - } + .title + { + position: absolute; + top: 2px; + font-weight: normal; + text-align: left; + margin: 0px; + max-width: 300px; + overflow: hidden; + } - .file - { - position : relative; - margin : 5px 20px 5px 20px; - border : 1px solid @btn-default-border; - color : @btn-default-color; + .info + { + position: absolute; + top: 3px; + font-weight: normal; + right: 20px; + text-align: right; + margin: 0px; + } - .title - { - margin : 3px 130px 0px 5px; - text-align : left; - overflow : hidden; - border : 0px; + .remove + { + position: absolute; + cursor: pointer; + top: 0px; + right: 3px; + } } - .progress-frame + .panel-body { - border : 0px; - margin : 0px 5px 3px 5px; - height : 7px; - background : @btn-default-border; + position: relative; + padding: 5px; } - .progress + .panel-footer { - background : @bs-success; - height : 100%; - width : 0%; - } - - .failed - { - background : @bs-danger; - } - - .error - { - font-size : @font-size-small; - text-align : left; - overflow : hidden; - margin : 0px 5px 0px 5px; - } - - .info - { - position : absolute; - top : 4px; - right : 5px; - font-size : @font-size-small; - text-align : right; - overflow : hidden; - max-width : 100px; - max-height : 12px; + position:relative; + height: 20px; + padding: 0px; + + .progress + { + height: 10px; + margin: 5px; + } + + .error + { + font-weight: normal; + margin: 2px; + } } } } \ No newline at end of file Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.