diff --git a/IPython/html/static/tree/js/main.js b/IPython/html/static/tree/js/main.js index 2b1f151..2858dd6 100644 --- a/IPython/html/static/tree/js/main.js +++ b/IPython/html/static/tree/js/main.js @@ -71,7 +71,7 @@ require([ var login_widget = new loginwidget.LoginWidget('#login_widget', common_options); - var nnw = new newnotebook.NewNotebookWidget("#new-notebook-buttons", + var new_buttons = new newnotebook.NewNotebookWidget("#new-buttons", $.extend( {contents: contents}, common_options @@ -130,7 +130,7 @@ require([ IPython.session_list = session_list; IPython.kernel_list = kernel_list; IPython.login_widget = login_widget; - IPython.new_notebook_widget = nnw; + IPython.new_notebook_widget = new_buttons; events.trigger('app_initialized.DashboardApp'); diff --git a/IPython/html/static/tree/js/newnotebook.js b/IPython/html/static/tree/js/newnotebook.js index f93ef14..4ab23bf 100644 --- a/IPython/html/static/tree/js/newnotebook.js +++ b/IPython/html/static/tree/js/newnotebook.js @@ -15,7 +15,6 @@ define([ this.notebook_path = options.notebook_path; this.contents = options.contents; this.default_kernel = null; - this.config = options.config; this.kernelspecs = {}; if (this.selector !== undefined) { this.element = $(selector); @@ -41,7 +40,7 @@ define([ /** load kernelspec list */ var that = this; this.kernelspecs = data.kernelspecs; - var menu = this.element.find("#new-notebook-menu"); + var menu = this.element.find("#notebook-kernels"); var keys = Object.keys(data.kernelspecs).sort(function (a, b) { var da = data.kernelspecs[a].display_name; var db = data.kernelspecs[b].display_name; @@ -64,45 +63,8 @@ define([ .text(ks.display_name) .attr('title', 'Create a new notebook with ' + ks.display_name) ); - menu.append(li); + menu.after(li); } - this.config.loaded.then(function () { - that._load_default_kernelspec(data['default']); - }); - }; - - NewNotebookWidget.prototype._load_default_kernelspec = function (default_name) { - /** load default kernelspec name from config, if defined */ - if (this.config.data.NewNotebookWidget && - this.config.data.NewNotebookWidget.default_kernel && - this.kernelspecs[this.config.data.NewNotebookWidget.default_kernel] !== undefined - ) { - default_name = this.config.data.NewNotebookWidget.default_kernel; - } - this.set_default_kernel(default_name); - }; - - NewNotebookWidget.prototype.set_default_kernel = function (kernel_name) { - /** select the current default kernel */ - this.default_kernel = kernel_name; - this.config.update({ - NewNotebookWidget: { - default_kernel: kernel_name - } - }); - var spec = this.kernelspecs[kernel_name]; - var display_name; - if (spec) { - display_name = spec.display_name; - this.element.find("#current-kernel") - .text(display_name) - .attr('title', display_name + " is the default kernel for new notebooks"); - } else { - display_name = 'default kernel'; - } - this.element.find("#new_notebook").attr('title', - 'Create a new notebook with ' + display_name - ); }; NewNotebookWidget.prototype.new_notebook = function (kernel_name) { diff --git a/IPython/html/static/tree/js/notebooklist.js b/IPython/html/static/tree/js/notebooklist.js index 330a895..862db6b 100644 --- a/IPython/html/static/tree/js/notebooklist.js +++ b/IPython/html/static/tree/js/notebooklist.js @@ -7,7 +7,8 @@ define([ 'base/js/utils', 'base/js/dialog', 'base/js/events', -], function(IPython, $, utils, dialog, events) { + 'base/js/keyboard', +], function(IPython, $, utils, dialog, events, keyboard) { "use strict"; var NotebookList = function (selector, options) { @@ -54,7 +55,6 @@ define([ this.element.addClass("list_container"); }; - NotebookList.prototype.bind_events = function () { var that = this; $('#refresh_' + this.element_name + '_list').click(function () { @@ -67,6 +67,25 @@ define([ that.handleFilesUpload(event,'drop'); return false; }); + + // Bind events for singleton controls. + if (!NotebookList._bound_singletons) { + NotebookList._bound_singletons = true; + $('#new-file').click(function(e) { + that._prompt_name('File').then(function(name) { + that._create('file', name).then(function() { + that.load_sessions(); + }); + }); + }); + $('#new-folder').click(function(e) { + that._prompt_name('Folder').then(function(name) { + that._create('directory', name).then(function() { + that.load_sessions(); + }); + }); + }); + } }; NotebookList.prototype.handleFilesUpload = function(event, dropOrForm) { @@ -519,6 +538,90 @@ define([ .append(cancel_button); }; + /** + * Prompt the user for a name. + * @param {string} what - What you want a name for. + * @return {Promise} Promise that resolve with a string name + */ + NotebookList.prototype._prompt_name = function(what) { + var that = this; + var dialog_body = $('
').append( + $("

").addClass("rename-message") + .text(what + ' name:') + ).append( + $("
") + ).append( + $('').attr('type','text').attr('size','25').addClass('form-control') + .val('') // Default to empty + ); + + return new Promise(function(resolve, reject) { + var dialog_inst = dialog.modal({ + title: "Rename Notebook", + body: dialog_body, + buttons: { + "OK": { + class: "btn-primary", + click: function () { + resolve(dialog_inst.find('input').val()); + } + }, + "Cancel": { + click: function () { + reject(); + } + } + }, open: function () { + /** + * Upon ENTER, click the OK button. + */ + dialog_inst.find('input[type="text"]').keydown(function (event) { + if (event.which === keyboard.keycodes.enter) { + dialog_inst.find('.btn-primary').first().click(); + return false; + } + }); + dialog_inst.find('input[type="text"]').focus().select(); + } + }); + }); + }; + + /** + * Creates a `file` or `directory` + * @param {string} type - "file" or "directory" + * @param {string} name - name of the thing to create + * @return {Promise} success + */ + NotebookList.prototype._create = function(type, name) { + var that = this; + return new Promise(function(resolve, reject) { + var settings = { + processData : false, + cache : false, + type : "PUT", + data: JSON.stringify({ + type: type, + format: 'text', + content: '', + }), + dataType: "json", + success: function () { + resolve(); + }, + error: function() { + reject(); + utils.log_ajax_error.apply(this, arguments); + }, + }; + var url = utils.url_join_encode( + that.base_url, + 'api/contents/' + name + ); + $.ajax(url, settings); + }); + }; + // Backwards compatability. IPython.NotebookList = NotebookList; diff --git a/IPython/html/static/tree/less/tree.less b/IPython/html/static/tree/less/tree.less index 84c64a4..19ebeeb 100644 --- a/IPython/html/static/tree/less/tree.less +++ b/IPython/html/static/tree/less/tree.less @@ -156,7 +156,7 @@ input.engine_num_input { .icon(@fa-var-file-o) } -ul#new-notebook-menu { +ul#new-menu { // align right instead of left left: auto; right: 0; diff --git a/IPython/html/templates/tree.html b/IPython/html/templates/tree.html index cd80351..860a68d 100644 --- a/IPython/html/templates/tree.html +++ b/IPython/html/templates/tree.html @@ -42,16 +42,22 @@ data-terminals-available="{{terminals_available}}" -

-
- +
+
- +