diff --git a/notebook/static/notebook/js/menubar.js b/notebook/static/notebook/js/menubar.js index 450ce310c..0e45c4707 100644 --- a/notebook/static/notebook/js/menubar.js +++ b/notebook/static/notebook/js/menubar.js @@ -170,6 +170,10 @@ define([ that.notebook.copy_notebook(); return false; }); + this.element.find('#save_notebook_as').click(function() { + that.notebook.save_notebook_as(); + return false; + }); this.element.find('#download_ipynb').click(function () { var base_url = that.notebook.base_url; var notebook_path = utils.encode_uri_components(that.notebook.notebook_path); diff --git a/notebook/static/notebook/js/notebook.js b/notebook/static/notebook/js/notebook.js index a9ec36cac..c6acbe6e2 100644 --- a/notebook/static/notebook/js/notebook.js +++ b/notebook/static/notebook/js/notebook.js @@ -2846,7 +2846,82 @@ define([ this._checkpoint_after_save = false; } }; - + + Notebook.prototype.save_notebook_as = function() { + // If current notebook has some changes, save them, or the copied notebook won't have them. + if (this.writable && this.dirty) { + this.save_notebook(); + } + var that = this; + var dialog_body = $('
').append( + $("

").addClass("save-message") + .text(i18n.msg._('Enter a notebook path relative to notebook dir')) + ).append( + $("
") + ).append( + $('').attr('type','text').attr('size','25') + .addClass('form-control').attr('placeholder', that.notebook_name) + ); + + var d = dialog.modal({ + title: 'Save As', + body: dialog_body, + keyboard_manager: this.keyboard_manager, + notebook: this, + buttons: { + Cancel: {}, + Save: { + class: 'btn-primary', + click: function() { + var nb_path = d.find('input').val(); + var nb_name = nb_path.split('/').slice(-1).pop(); + // If notebook name does not contain extension '.ipynb' add it + var ext = utils.splitext(nb_name)[1]; + if (ext === '') { + nb_name = nb_name + '.ipynb'; + nb_path = nb_path + '.ipynb'; + } + var save_thunk = function() { + var model = { + 'type': 'notebook', + 'content': that.toJSON(), + 'name': nb_name + }; + return that.contents.save(nb_path, model) + .then(function(data) { + window.open(data.path, '_self'); + },function(error) { + console.error(i18n.msg._(error.message || 'Unknown error saving notebook')); + }); + } + that.contents.get(nb_path, {type: 'notebook'}).then(function(data) { + var warning_body = $('

').append( + $("

").text(i18n.msg._('Notebook with that name exists.'))); + dialog.modal({ + title: 'Save As', + body: warning_body, + buttons: {Cancel: {}, + Overwrite: { + class: 'btn-warning', + click: function() { + return save_thunk(); + } + } + } + }); + }, function(err) { + return save_thunk(); + }) + return false; + } + }, + }, + open : function () { + d.find('input[type="text"]').focus().select(); + } + }); + } + /** * Update the autosave interval based on the duration of the last save. * diff --git a/notebook/templates/notebook.html b/notebook/templates/notebook.html index 7e627b1f9..701516ce6 100644 --- a/notebook/templates/notebook.html +++ b/notebook/templates/notebook.html @@ -89,6 +89,9 @@ data-notebook-path="{{notebook_path | urlencode}}"

  • {% trans %}Make a Copy...{% endtrans %}
  • +
  • + {% trans %}Save as{% endtrans %}
  • {% trans %}Rename...{% endtrans %}
  • {% trans %}Save and Checkpoint{% endtrans %}