Skip to content

Commit fd25ae1

Browse files
committed
Add 'Save As' option to the menu
1 parent dc73f9a commit fd25ae1

File tree

3 files changed

+83
-1
lines changed

3 files changed

+83
-1
lines changed

notebook/static/notebook/js/menubar.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@ define([
170170
that.notebook.copy_notebook();
171171
return false;
172172
});
173+
this.element.find('#save_notebook_as').click(function() {
174+
that.notebook.save_notebook_as();
175+
return false;
176+
});
173177
this.element.find('#download_ipynb').click(function () {
174178
var base_url = that.notebook.base_url;
175179
var notebook_path = utils.encode_uri_components(that.notebook.notebook_path);

notebook/static/notebook/js/notebook.js

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2846,7 +2846,82 @@ define([
28462846
this._checkpoint_after_save = false;
28472847
}
28482848
};
2849-
2849+
2850+
Notebook.prototype.save_notebook_as = function() {
2851+
// If current notebook has some changes, save them, or the copied notebook won't have them.
2852+
if (this.writable && this.dirty) {
2853+
this.save_notebook();
2854+
}
2855+
var that = this;
2856+
var dialog_body = $('<div/>').append(
2857+
$("<p/>").addClass("save-message")
2858+
.text(i18n.msg._('Enter a notebook path relative to notebook dir'))
2859+
).append(
2860+
$("<br/>")
2861+
).append(
2862+
$('<input/>').attr('type','text').attr('size','25')
2863+
.addClass('form-control').attr('placeholder', that.notebook_name)
2864+
);
2865+
2866+
var d = dialog.modal({
2867+
title: 'Save As',
2868+
body: dialog_body,
2869+
keyboard_manager: this.keyboard_manager,
2870+
notebook: this,
2871+
buttons: {
2872+
Cancel: {},
2873+
Save: {
2874+
class: 'btn-primary',
2875+
click: function() {
2876+
var nb_path = d.find('input').val();
2877+
var nb_name = nb_path.split('/').slice(-1).pop();
2878+
// If notebook name does not contain extension '.ipynb' add it
2879+
var ext = utils.splitext(nb_name)[1];
2880+
if (ext === '') {
2881+
nb_name = nb_name + '.ipynb';
2882+
nb_path = nb_path + '.ipynb';
2883+
}
2884+
var save_thunk = function() {
2885+
var model = {
2886+
'type': 'notebook',
2887+
'content': that.toJSON(),
2888+
'name': nb_name
2889+
};
2890+
return that.contents.save(nb_path, model)
2891+
.then(function(data) {
2892+
window.open(data.path, '_self');
2893+
},function(error) {
2894+
console.error(i18n.msg._(error.message || 'Unknown error saving notebook'));
2895+
});
2896+
}
2897+
that.contents.get(nb_path, {type: 'notebook'}).then(function(data) {
2898+
var warning_body = $('<div/>').append(
2899+
$("<p/>").text(i18n.msg._('Notebook with that name exists.')));
2900+
dialog.modal({
2901+
title: 'Save As',
2902+
body: warning_body,
2903+
buttons: {Cancel: {},
2904+
Overwrite: {
2905+
class: 'btn-warning',
2906+
click: function() {
2907+
return save_thunk();
2908+
}
2909+
}
2910+
}
2911+
});
2912+
}, function(err) {
2913+
return save_thunk();
2914+
})
2915+
return false;
2916+
}
2917+
},
2918+
},
2919+
open : function () {
2920+
d.find('input[type="text"]').focus().select();
2921+
}
2922+
});
2923+
}
2924+
28502925
/**
28512926
* Update the autosave interval based on the duration of the last save.
28522927
*

notebook/templates/notebook.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@
8989
<li id="copy_notebook"
9090
title="{% trans %}Open a copy of this notebook's contents and start a new kernel{% endtrans %}">
9191
<a href="#">{% trans %}Make a Copy...{% endtrans %}</a></li>
92+
<li id="save_notebook_as"
93+
title="{% trans %}Save a copy of the notebook's contents and start a new kernel{% endtrans %}">
94+
<a href="#">{% trans %}Save as{% endtrans %}</a></li>
9295
<li id="rename_notebook"><a href="#">{% trans %}Rename...{% endtrans %}</a></li>
9396
<li id="save_checkpoint"><a href="#">{% trans %}Save and Checkpoint{% endtrans %}</a></li>
9497
<!-- <hr/> -->

0 commit comments

Comments
 (0)