diff --git a/IPython/html/static/tree/js/notebooklist.js b/IPython/html/static/tree/js/notebooklist.js index f8026cc..429e046 100644 --- a/IPython/html/static/tree/js/notebooklist.js +++ b/IPython/html/static/tree/js/notebooklist.js @@ -87,6 +87,11 @@ define([ that.load_list(); }); }); + + $('.rename-button').click($.proxy(this.rename_selected, this)); + $('.shutdown-button').click($.proxy(this.shutdown_selected, this)); + $('.duplicate-button').click($.proxy(this.duplicate_selected, this)); + $('.delete-button').click($.proxy(this.delete_selected, this)); } }; @@ -111,7 +116,7 @@ define([ // read non-notebook files as binary reader.readAsArrayBuffer(f); } - var item = that.new_item(0); + var item = that.new_item(0, true); item.addClass('new-file'); that.add_name_input(f.name, item, file_ext == '.ipynb' ? 'notebook' : 'file'); // Store the list item in the reader so we can use it later @@ -218,7 +223,7 @@ define([ var path = this.notebook_path; var offset = n_uploads; if (path !== '') { - item = this.new_item(offset); + item = this.new_item(offset, false); model = { type: 'directory', name: '..', @@ -229,34 +234,84 @@ define([ } for (var i=0; i').addClass("list_item").addClass("row"); - // item.addClass('list_item ui-widget ui-widget-content ui-helper-clearfix'); - // item.css('border-top-style','none'); - item.append($("
").addClass("col-md-12").append( - $('').addClass('item_icon') - ).append( - $("").addClass("item_link").append( - $("").addClass("item_name") - ) - ).append( - $('
').addClass("item_buttons pull-right") - )); + /** + * Creates a new item. + * @param {integer} index + * @param {boolean} [selectable] - tristate, undefined: don't draw checkbox, + * false: don't draw checkbox but pad + * where it should be, true: draw checkbox. + * @return {JQuery} row + */ + NotebookList.prototype.new_item = function (index, selectable) { + var row = $('
') + .addClass("list_item") + .addClass("row"); + + var item = $("
") + .addClass("col-md-12") + .appendTo(row); + + var checkbox; + if (selectable !== undefined) { + checkbox = $('') + .attr('type', 'checkbox') + .appendTo(item); + } + + $('') + .addClass('item_icon') + .appendTo(item); + + var link = $("") + .addClass("item_link") + .appendTo(item); + + $("") + .addClass("item_name") + .appendTo(link); + + if (selectable === false) { + checkbox.css('visibility', 'hidden'); + } else if (selectable === true) { + var that = this; + link.click(function(e) { + e.stopPropagation(); + }); + checkbox.click(function(e) { + e.stopPropagation(); + that._selection_changed(); + }); + row.click(function(e) { + e.stopPropagation(); + checkbox.prop('checked', !checkbox.prop('checked')); + that._selection_changed(); + }); + } + + var buttons = $('
') + .addClass("item_buttons pull-right") + .appendTo(item); + + $('') + .addClass('fa fa-power-off running-indicator') + .css('visible', 'hidden') + .appendTo(buttons); if (index === -1) { - this.element.append(item); + this.element.append(row); } else { - this.element.children().eq(index).after(item); + this.element.children().eq(index).after(row); } - return item; + return row; }; @@ -272,12 +327,58 @@ define([ file: 'edit', }; + NotebookList.prototype._selection_changed = function() { + var selected = []; + var has_notebook = false; + var has_directory = false; + $('.list_item :checked').each(function(index, item) { + var parent = $(item).parent().parent(); + selected.push({ + name: parent.data('name'), + path: parent.data('path'), + type: parent.data('type') + }); + + has_notebook = has_notebook || parent.data('type') == 'notebook'; + has_directory = has_directory || parent.data('type') == 'directory'; + }); + this.selected = selected; + + // Rename is only visible when one item is selected. + if (selected.length==1) { + $('.rename-button').css('display', 'inline-block'); + } else { + $('.rename-button').css('display', 'none'); + } + + // Shutdown is only visible when one or more notebooks are visible. + if (has_notebook) { + $('.shutdown-button').css('display', 'inline-block'); + } else { + $('.shutdown-button').css('display', 'none'); + } + + // Duplicate isn't visible if a directory is selected. + if (selected.length > 0 && !has_directory) { + $('.duplicate-button').css('display', 'inline-block'); + } else { + $('.duplicate-button').css('display', 'none'); + } + + // Delete is visible if one or more items are selected. + if (selected.length > 0) { + $('.delete-button').css('display', 'inline-block'); + } else { + $('.delete-button').css('display', 'none'); + } + }; NotebookList.prototype.add_link = function (model, item) { var path = model.path, name = model.name; item.data('name', name); item.data('path', path); + item.data('type', model.type); item.find(".item_name").text(name); var icon = NotebookList.icons[model.type]; var uri_prefix = NotebookList.uri_prefixes[model.type]; @@ -291,13 +392,8 @@ define([ ) ); - var can_duplicate = (model.type != 'directory'); - var can_rename = (model.type == 'directory'); - var can_delete = (model.type != 'notebook' || this.sessions[path] === undefined); - if (!can_delete) { - this.add_shutdown_button(item, this.sessions[path]); - } - this.add_actions_button(item, can_delete, can_duplicate, can_rename); + var running = (model.type == 'notebook' && this.sessions[path] !== undefined); + item.find(".item_buttons i.running-indicator").css('visibility', running ? '' : 'hidden'); // directory nav doesn't open new tabs // files, notebooks do @@ -329,188 +425,156 @@ define([ }; - NotebookList.prototype.add_shutdown_button = function (item, session) { + NotebookList.prototype.shutdown_selected = function() { var that = this; - var shutdown_button = $(" + + + +