diff --git a/IPython/html/static/tree/js/notebooklist.js b/IPython/html/static/tree/js/notebooklist.js index aa05f44..4a3044b 100644 --- a/IPython/html/static/tree/js/notebooklist.js +++ b/IPython/html/static/tree/js/notebooklist.js @@ -114,10 +114,20 @@ define([ that.load_sessions(); }); + // Bind events for action buttons. $('.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)); + + // Bind events for selection menu buttons. + $('#tree-selector .select-all').click($.proxy(this.select_all, this)); + $('#tree-selector .select-notebooks').click($.proxy(this.select_notebooks, this)); + $('#tree-selector .select-running-notebooks').click($.proxy(this.select_running_notebooks, this)); + $('#tree-selector .select-files').click($.proxy(this.select_files, this)); + $('#tree-selector .select-directories').click($.proxy(this.select_directories, this)); + $('#tree-selector .select-inverse').click($.proxy(this.select_inverse, this)); + $('#tree-selector .unselect-all').click($.proxy(this.unselect_all, this)); } }; @@ -356,10 +366,93 @@ define([ }; /** + * Select all of the items in the tree. + */ + NotebookList.prototype.select_all = function() { + $('.list_item input[type=checkbox]').each(function(index, item) { + $(item).prop('checked', true); + }); + this._selection_changed(); + }; + + /** + * Select all of the notebooks in the tree. + */ + NotebookList.prototype.select_notebooks = function() { + this.unselect_all(); + $('.list_item').each(function(index, item) { + if ($(item).data('type') === 'notebook') { + $(item).find('input[type=checkbox]').prop('checked', true); + } + }); + this._selection_changed(); + }; + + /** + * Select all of the running notebooks in the tree. + */ + NotebookList.prototype.select_running_notebooks = function() { + this.unselect_all(); + var that = this; + $('.list_item').each(function(index, item) { + if ($(item).data('type') === 'notebook' && that.sessions[$(item).data('path')] !== undefined) { + $(item).find('input[type=checkbox]').prop('checked', true); + } + }); + this._selection_changed(); + }; + + /** + * Select all of the files in the tree. + */ + NotebookList.prototype.select_files = function() { + this.unselect_all(); + $('.list_item').each(function(index, item) { + if ($(item).data('type') === 'file') { + $(item).find('input[type=checkbox]').prop('checked', true); + } + }); + this._selection_changed(); + }; + + /** + * Select all of the directories in the tree. + */ + NotebookList.prototype.select_directories = function() { + this.unselect_all(); + $('.list_item').each(function(index, item) { + if ($(item).data('type') === 'directory') { + $(item).find('input[type=checkbox]').prop('checked', true); + } + }); + this._selection_changed(); + }; + + /** + * Select the inverse of the current selection. + */ + NotebookList.prototype.select_inverse = function() { + $('.list_item input[type=checkbox]').each(function(index, item) { + $(item).prop('checked', !$(item).prop('checked')); + }); + this._selection_changed(); + }; + + /** + * Unselect everything selected in the tree. + */ + NotebookList.prototype.unselect_all = function() { + $('.list_item input[type=checkbox]').each(function(index, item) { + $(item).prop('checked', false); + }); + this._selection_changed(); + }; + + + /** * Handles when any row selector checkbox is toggled. */ NotebookList.prototype._selection_changed = function() { - // Use a JQuery selector to find each row with a checked checkbox. If // we decide to add more checkboxes in the future, this code will need // to be changed to distinguish which checkbox is the row selector. @@ -368,11 +461,14 @@ define([ var has_directory = false; var has_file = false; var that = this; + var checked = 0; $('.list_item :checked').each(function(index, item) { var parent = $(item).parent().parent(); - // If the item doesn't have an upload button, it can be selected. - if (parent.find('.upload_button').length === 0) { + // If the item doesn't have an upload button and it's not the + // breadcrumbs, it can be selected. Breadcrumbs path == ''. + if (parent.find('.upload_button').length === 0 && parent.data('path') !== '') { + checked++; selected.push({ name: parent.data('name'), path: parent.data('path'), @@ -417,6 +513,15 @@ define([ } else { $('.delete-button').css('display', 'none'); } + + // If all of the items are selected, show the selector as checked. If + // some of the items are selected, show it as checked. Otherwise, + // uncheck it. + if (checked === 0) { + $('#tree-selector input[type=checkbox]').prop('checked', false); + } else { + $('#tree-selector input[type=checkbox]').prop('checked', true); + } }; NotebookList.prototype.add_link = function (model, item) { diff --git a/IPython/html/static/tree/less/tree.less b/IPython/html/static/tree/less/tree.less index 1a657ec..1fe3190 100644 --- a/IPython/html/static/tree/less/tree.less +++ b/IPython/html/static/tree/less/tree.less @@ -14,6 +14,9 @@ @dark_dashboard_color: @breadcrumb-color; @list_stripe_color: lighten(@page-backdrop-color,3%); +// The left padding of the selector button's contents. +@dashboard-selectorbtn-lpad: 7px; + ul#tabs { margin-bottom: @dashboard_tb_pad; } @@ -100,6 +103,11 @@ ul.breadcrumb { input { margin-right: @dashboard_lr_pad; + margin-left: @dashboard_lr_pad + @dashboard-selectorbtn-lpad; + } + + .item_link { + margin-left: 14px; } } @@ -152,12 +160,23 @@ input.engine_num_input { color: blue; } -#project_name > .breadcrumb { - padding: 0px; - margin-bottom: 0px; - background-color: transparent; - font-weight: bold; - +#project_name { + display: inline-block; + + > .breadcrumb { + padding: 0px; + margin-bottom: 0px; + background-color: transparent; + font-weight: bold; + } +} + +#tree-selector { + display: inline-block; + + input[type=checkbox] { + margin-left: @dashboard_lr_pad; + } } .tab-content .row { diff --git a/IPython/html/templates/tree.html b/IPython/html/templates/tree.html index 05d32df..ee37433 100644 --- a/IPython/html/templates/tree.html +++ b/IPython/html/templates/tree.html @@ -76,6 +76,24 @@ data-terminals-available="{{terminals_available}}"
+ + +