##// END OF EJS Templates
Backport PR #5527: Don't remove upload items from nav tree unless explicitly requested....
MinRK -
Show More
@@ -1,412 +1,422 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2011 The IPython Development Team
2 // Copyright (C) 2011 The IPython Development Team
3 //
3 //
4 // Distributed under the terms of the BSD License. The full license is in
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7
7
8 //============================================================================
8 //============================================================================
9 // NotebookList
9 // NotebookList
10 //============================================================================
10 //============================================================================
11
11
12 var IPython = (function (IPython) {
12 var IPython = (function (IPython) {
13 "use strict";
13 "use strict";
14
14
15 var utils = IPython.utils;
15 var utils = IPython.utils;
16
16
17 var NotebookList = function (selector, options, element_name) {
17 var NotebookList = function (selector, options, element_name) {
18 var that = this
18 var that = this
19 // allow code re-use by just changing element_name in kernellist.js
19 // allow code re-use by just changing element_name in kernellist.js
20 this.element_name = element_name || 'notebook';
20 this.element_name = element_name || 'notebook';
21 this.selector = selector;
21 this.selector = selector;
22 if (this.selector !== undefined) {
22 if (this.selector !== undefined) {
23 this.element = $(selector);
23 this.element = $(selector);
24 this.style();
24 this.style();
25 this.bind_events();
25 this.bind_events();
26 }
26 }
27 this.notebooks_list = [];
27 this.notebooks_list = [];
28 this.sessions = {};
28 this.sessions = {};
29 this.base_url = options.base_url || utils.get_body_data("baseUrl");
29 this.base_url = options.base_url || utils.get_body_data("baseUrl");
30 this.notebook_path = options.notebook_path || utils.get_body_data("notebookPath");
30 this.notebook_path = options.notebook_path || utils.get_body_data("notebookPath");
31 $([IPython.events]).on('sessions_loaded.Dashboard',
31 $([IPython.events]).on('sessions_loaded.Dashboard',
32 function(e, d) { that.sessions_loaded(d); });
32 function(e, d) { that.sessions_loaded(d); });
33 };
33 };
34
34
35 NotebookList.prototype.style = function () {
35 NotebookList.prototype.style = function () {
36 var prefix = '#' + this.element_name
36 var prefix = '#' + this.element_name
37 $(prefix + '_toolbar').addClass('list_toolbar');
37 $(prefix + '_toolbar').addClass('list_toolbar');
38 $(prefix + '_list_info').addClass('toolbar_info');
38 $(prefix + '_list_info').addClass('toolbar_info');
39 $(prefix + '_buttons').addClass('toolbar_buttons');
39 $(prefix + '_buttons').addClass('toolbar_buttons');
40 $(prefix + '_list_header').addClass('list_header');
40 $(prefix + '_list_header').addClass('list_header');
41 this.element.addClass("list_container");
41 this.element.addClass("list_container");
42 };
42 };
43
43
44
44
45 NotebookList.prototype.bind_events = function () {
45 NotebookList.prototype.bind_events = function () {
46 var that = this;
46 var that = this;
47 $('#refresh_' + this.element_name + '_list').click(function () {
47 $('#refresh_' + this.element_name + '_list').click(function () {
48 that.load_sessions();
48 that.load_sessions();
49 });
49 });
50 this.element.bind('dragover', function () {
50 this.element.bind('dragover', function () {
51 return false;
51 return false;
52 });
52 });
53 this.element.bind('drop', function(event){
53 this.element.bind('drop', function(event){
54 that.handleFilesUpload(event,'drop');
54 that.handleFilesUpload(event,'drop');
55 return false;
55 return false;
56 });
56 });
57 };
57 };
58
58
59 NotebookList.prototype.handleFilesUpload = function(event, dropOrForm) {
59 NotebookList.prototype.handleFilesUpload = function(event, dropOrForm) {
60 var that = this;
60 var that = this;
61 var files;
61 var files;
62 if(dropOrForm =='drop'){
62 if(dropOrForm =='drop'){
63 files = event.originalEvent.dataTransfer.files;
63 files = event.originalEvent.dataTransfer.files;
64 } else
64 } else
65 {
65 {
66 files = event.originalEvent.target.files;
66 files = event.originalEvent.target.files;
67 }
67 }
68 for (var i = 0; i < files.length; i++) {
68 for (var i = 0; i < files.length; i++) {
69 var f = files[i];
69 var f = files[i];
70 var reader = new FileReader();
70 var reader = new FileReader();
71 reader.readAsText(f);
71 reader.readAsText(f);
72 var name_and_ext = utils.splitext(f.name);
72 var name_and_ext = utils.splitext(f.name);
73 var file_ext = name_and_ext[1];
73 var file_ext = name_and_ext[1];
74 if (file_ext === '.ipynb') {
74 if (file_ext === '.ipynb') {
75 var item = that.new_notebook_item(0);
75 var item = that.new_notebook_item(0);
76 item.addClass('new-file');
76 that.add_name_input(f.name, item);
77 that.add_name_input(f.name, item);
77 // Store the notebook item in the reader so we can use it later
78 // Store the notebook item in the reader so we can use it later
78 // to know which item it belongs to.
79 // to know which item it belongs to.
79 $(reader).data('item', item);
80 $(reader).data('item', item);
80 reader.onload = function (event) {
81 reader.onload = function (event) {
81 var nbitem = $(event.target).data('item');
82 var nbitem = $(event.target).data('item');
82 that.add_notebook_data(event.target.result, nbitem);
83 that.add_notebook_data(event.target.result, nbitem);
83 that.add_upload_button(nbitem);
84 that.add_upload_button(nbitem);
84 };
85 };
85 } else {
86 } else {
86 var dialog = 'Uploaded notebooks must be .ipynb files';
87 var dialog = 'Uploaded notebooks must be .ipynb files';
87 IPython.dialog.modal({
88 IPython.dialog.modal({
88 title : 'Invalid file type',
89 title : 'Invalid file type',
89 body : dialog,
90 body : dialog,
90 buttons : {'OK' : {'class' : 'btn-primary'}}
91 buttons : {'OK' : {'class' : 'btn-primary'}}
91 });
92 });
92 }
93 }
93 }
94 }
94 // Replace the file input form wth a clone of itself. This is required to
95 // Replace the file input form wth a clone of itself. This is required to
95 // reset the form. Otherwise, if you upload a file, delete it and try to
96 // reset the form. Otherwise, if you upload a file, delete it and try to
96 // upload it again, the changed event won't fire.
97 // upload it again, the changed event won't fire.
97 var form = $('input.fileinput');
98 var form = $('input.fileinput');
98 form.replaceWith(form.clone(true));
99 form.replaceWith(form.clone(true));
99 return false;
100 return false;
100 };
101 };
101
102
102 NotebookList.prototype.clear_list = function () {
103 NotebookList.prototype.clear_list = function (remove_uploads) {
103 this.element.children('.list_item').remove();
104 // Clears the navigation tree.
105 //
106 // Parameters
107 // remove_uploads: bool=False
108 // Should upload prompts also be removed from the tree.
109 if (remove_uploads) {
110 this.element.children('.list_item').remove();
111 } else {
112 this.element.children('.list_item:not(.new-file)').remove();
113 }
104 };
114 };
105
115
106 NotebookList.prototype.load_sessions = function(){
116 NotebookList.prototype.load_sessions = function(){
107 IPython.session_list.load_sessions();
117 IPython.session_list.load_sessions();
108 };
118 };
109
119
110
120
111 NotebookList.prototype.sessions_loaded = function(data){
121 NotebookList.prototype.sessions_loaded = function(data){
112 this.sessions = data;
122 this.sessions = data;
113 this.load_list();
123 this.load_list();
114 };
124 };
115
125
116 NotebookList.prototype.load_list = function () {
126 NotebookList.prototype.load_list = function () {
117 var that = this;
127 var that = this;
118 var settings = {
128 var settings = {
119 processData : false,
129 processData : false,
120 cache : false,
130 cache : false,
121 type : "GET",
131 type : "GET",
122 dataType : "json",
132 dataType : "json",
123 success : $.proxy(this.list_loaded, this),
133 success : $.proxy(this.list_loaded, this),
124 error : $.proxy( function(){
134 error : $.proxy( function(){
125 that.list_loaded([], null, null, {msg:"Error connecting to server."});
135 that.list_loaded([], null, null, {msg:"Error connecting to server."});
126 },this)
136 },this)
127 };
137 };
128
138
129 var url = utils.url_join_encode(
139 var url = utils.url_join_encode(
130 this.base_url,
140 this.base_url,
131 'api',
141 'api',
132 'notebooks',
142 'notebooks',
133 this.notebook_path
143 this.notebook_path
134 );
144 );
135 $.ajax(url, settings);
145 $.ajax(url, settings);
136 };
146 };
137
147
138
148
139 NotebookList.prototype.list_loaded = function (data, status, xhr, param) {
149 NotebookList.prototype.list_loaded = function (data, status, xhr, param) {
140 var message = 'Notebook list empty.';
150 var message = 'Notebook list empty.';
141 if (param !== undefined && param.msg) {
151 if (param !== undefined && param.msg) {
142 message = param.msg;
152 message = param.msg;
143 }
153 }
144 var item = null;
154 var item = null;
145 var len = data.length;
155 var len = data.length;
146 this.clear_list();
156 this.clear_list();
147 if (len === 0) {
157 if (len === 0) {
148 item = this.new_notebook_item(0);
158 item = this.new_notebook_item(0);
149 var span12 = item.children().first();
159 var span12 = item.children().first();
150 span12.empty();
160 span12.empty();
151 span12.append($('<div style="margin:auto;text-align:center;color:grey"/>').text(message));
161 span12.append($('<div style="margin:auto;text-align:center;color:grey"/>').text(message));
152 }
162 }
153 var path = this.notebook_path;
163 var path = this.notebook_path;
154 var offset = 0;
164 var offset = 0;
155 if (path !== '') {
165 if (path !== '') {
156 item = this.new_notebook_item(0);
166 item = this.new_notebook_item(0);
157 this.add_dir(path, '..', item);
167 this.add_dir(path, '..', item);
158 offset = 1;
168 offset = 1;
159 }
169 }
160 for (var i=0; i<len; i++) {
170 for (var i=0; i<len; i++) {
161 if (data[i].type === 'directory') {
171 if (data[i].type === 'directory') {
162 var name = data[i].name;
172 var name = data[i].name;
163 item = this.new_notebook_item(i+offset);
173 item = this.new_notebook_item(i+offset);
164 this.add_dir(path, name, item);
174 this.add_dir(path, name, item);
165 } else {
175 } else {
166 var name = data[i].name;
176 var name = data[i].name;
167 item = this.new_notebook_item(i+offset);
177 item = this.new_notebook_item(i+offset);
168 this.add_link(path, name, item);
178 this.add_link(path, name, item);
169 name = utils.url_path_join(path, name);
179 name = utils.url_path_join(path, name);
170 if(this.sessions[name] === undefined){
180 if(this.sessions[name] === undefined){
171 this.add_delete_button(item);
181 this.add_delete_button(item);
172 } else {
182 } else {
173 this.add_shutdown_button(item,this.sessions[name]);
183 this.add_shutdown_button(item,this.sessions[name]);
174 }
184 }
175 }
185 }
176 }
186 }
177 };
187 };
178
188
179
189
180 NotebookList.prototype.new_notebook_item = function (index) {
190 NotebookList.prototype.new_notebook_item = function (index) {
181 var item = $('<div/>').addClass("list_item").addClass("row-fluid");
191 var item = $('<div/>').addClass("list_item").addClass("row-fluid");
182 // item.addClass('list_item ui-widget ui-widget-content ui-helper-clearfix');
192 // item.addClass('list_item ui-widget ui-widget-content ui-helper-clearfix');
183 // item.css('border-top-style','none');
193 // item.css('border-top-style','none');
184 item.append($("<div/>").addClass("span12").append(
194 item.append($("<div/>").addClass("span12").append(
185 $('<i/>').addClass('item_icon')
195 $('<i/>').addClass('item_icon')
186 ).append(
196 ).append(
187 $("<a/>").addClass("item_link").append(
197 $("<a/>").addClass("item_link").append(
188 $("<span/>").addClass("item_name")
198 $("<span/>").addClass("item_name")
189 )
199 )
190 ).append(
200 ).append(
191 $('<div/>').addClass("item_buttons btn-group pull-right")
201 $('<div/>').addClass("item_buttons btn-group pull-right")
192 ));
202 ));
193
203
194 if (index === -1) {
204 if (index === -1) {
195 this.element.append(item);
205 this.element.append(item);
196 } else {
206 } else {
197 this.element.children().eq(index).after(item);
207 this.element.children().eq(index).after(item);
198 }
208 }
199 return item;
209 return item;
200 };
210 };
201
211
202
212
203 NotebookList.prototype.add_dir = function (path, name, item) {
213 NotebookList.prototype.add_dir = function (path, name, item) {
204 item.data('name', name);
214 item.data('name', name);
205 item.data('path', path);
215 item.data('path', path);
206 item.find(".item_name").text(name);
216 item.find(".item_name").text(name);
207 item.find(".item_icon").addClass('icon-folder-open');
217 item.find(".item_icon").addClass('icon-folder-open');
208 item.find("a.item_link")
218 item.find("a.item_link")
209 .attr('href',
219 .attr('href',
210 utils.url_join_encode(
220 utils.url_join_encode(
211 this.base_url,
221 this.base_url,
212 "tree",
222 "tree",
213 path,
223 path,
214 name
224 name
215 )
225 )
216 );
226 );
217 };
227 };
218
228
219
229
220 NotebookList.prototype.add_link = function (path, nbname, item) {
230 NotebookList.prototype.add_link = function (path, nbname, item) {
221 item.data('nbname', nbname);
231 item.data('nbname', nbname);
222 item.data('path', path);
232 item.data('path', path);
223 item.find(".item_name").text(nbname);
233 item.find(".item_name").text(nbname);
224 item.find(".item_icon").addClass('icon-book');
234 item.find(".item_icon").addClass('icon-book');
225 item.find("a.item_link")
235 item.find("a.item_link")
226 .attr('href',
236 .attr('href',
227 utils.url_join_encode(
237 utils.url_join_encode(
228 this.base_url,
238 this.base_url,
229 "notebooks",
239 "notebooks",
230 path,
240 path,
231 nbname
241 nbname
232 )
242 )
233 ).attr('target','_blank');
243 ).attr('target','_blank');
234 };
244 };
235
245
236
246
237 NotebookList.prototype.add_name_input = function (nbname, item) {
247 NotebookList.prototype.add_name_input = function (nbname, item) {
238 item.data('nbname', nbname);
248 item.data('nbname', nbname);
239 item.find(".item_icon").addClass('icon-book');
249 item.find(".item_icon").addClass('icon-book');
240 item.find(".item_name").empty().append(
250 item.find(".item_name").empty().append(
241 $('<input/>')
251 $('<input/>')
242 .addClass("nbname_input")
252 .addClass("nbname_input")
243 .attr('value', utils.splitext(nbname)[0])
253 .attr('value', utils.splitext(nbname)[0])
244 .attr('size', '30')
254 .attr('size', '30')
245 .attr('type', 'text')
255 .attr('type', 'text')
246 );
256 );
247 };
257 };
248
258
249
259
250 NotebookList.prototype.add_notebook_data = function (data, item) {
260 NotebookList.prototype.add_notebook_data = function (data, item) {
251 item.data('nbdata', data);
261 item.data('nbdata', data);
252 };
262 };
253
263
254
264
255 NotebookList.prototype.add_shutdown_button = function (item, session) {
265 NotebookList.prototype.add_shutdown_button = function (item, session) {
256 var that = this;
266 var that = this;
257 var shutdown_button = $("<button/>").text("Shutdown").addClass("btn btn-mini btn-danger").
267 var shutdown_button = $("<button/>").text("Shutdown").addClass("btn btn-mini btn-danger").
258 click(function (e) {
268 click(function (e) {
259 var settings = {
269 var settings = {
260 processData : false,
270 processData : false,
261 cache : false,
271 cache : false,
262 type : "DELETE",
272 type : "DELETE",
263 dataType : "json",
273 dataType : "json",
264 success : function () {
274 success : function () {
265 that.load_sessions();
275 that.load_sessions();
266 }
276 }
267 };
277 };
268 var url = utils.url_join_encode(
278 var url = utils.url_join_encode(
269 that.base_url,
279 that.base_url,
270 'api/sessions',
280 'api/sessions',
271 session
281 session
272 );
282 );
273 $.ajax(url, settings);
283 $.ajax(url, settings);
274 return false;
284 return false;
275 });
285 });
276 // var new_buttons = item.find('a'); // shutdown_button;
286 // var new_buttons = item.find('a'); // shutdown_button;
277 item.find(".item_buttons").text("").append(shutdown_button);
287 item.find(".item_buttons").text("").append(shutdown_button);
278 };
288 };
279
289
280 NotebookList.prototype.add_delete_button = function (item) {
290 NotebookList.prototype.add_delete_button = function (item) {
281 var new_buttons = $('<span/>').addClass("btn-group pull-right");
291 var new_buttons = $('<span/>').addClass("btn-group pull-right");
282 var notebooklist = this;
292 var notebooklist = this;
283 var delete_button = $("<button/>").text("Delete").addClass("btn btn-mini").
293 var delete_button = $("<button/>").text("Delete").addClass("btn btn-mini").
284 click(function (e) {
294 click(function (e) {
285 // $(this) is the button that was clicked.
295 // $(this) is the button that was clicked.
286 var that = $(this);
296 var that = $(this);
287 // We use the nbname and notebook_id from the parent notebook_item element's
297 // We use the nbname and notebook_id from the parent notebook_item element's
288 // data because the outer scopes values change as we iterate through the loop.
298 // data because the outer scopes values change as we iterate through the loop.
289 var parent_item = that.parents('div.list_item');
299 var parent_item = that.parents('div.list_item');
290 var nbname = parent_item.data('nbname');
300 var nbname = parent_item.data('nbname');
291 var message = 'Are you sure you want to permanently delete the notebook: ' + nbname + '?';
301 var message = 'Are you sure you want to permanently delete the notebook: ' + nbname + '?';
292 IPython.dialog.modal({
302 IPython.dialog.modal({
293 title : "Delete notebook",
303 title : "Delete notebook",
294 body : message,
304 body : message,
295 buttons : {
305 buttons : {
296 Delete : {
306 Delete : {
297 class: "btn-danger",
307 class: "btn-danger",
298 click: function() {
308 click: function() {
299 var settings = {
309 var settings = {
300 processData : false,
310 processData : false,
301 cache : false,
311 cache : false,
302 type : "DELETE",
312 type : "DELETE",
303 dataType : "json",
313 dataType : "json",
304 success : function (data, status, xhr) {
314 success : function (data, status, xhr) {
305 parent_item.remove();
315 parent_item.remove();
306 }
316 }
307 };
317 };
308 var url = utils.url_join_encode(
318 var url = utils.url_join_encode(
309 notebooklist.base_url,
319 notebooklist.base_url,
310 'api/notebooks',
320 'api/notebooks',
311 notebooklist.notebook_path,
321 notebooklist.notebook_path,
312 nbname
322 nbname
313 );
323 );
314 $.ajax(url, settings);
324 $.ajax(url, settings);
315 }
325 }
316 },
326 },
317 Cancel : {}
327 Cancel : {}
318 }
328 }
319 });
329 });
320 return false;
330 return false;
321 });
331 });
322 item.find(".item_buttons").text("").append(delete_button);
332 item.find(".item_buttons").text("").append(delete_button);
323 };
333 };
324
334
325
335
326 NotebookList.prototype.add_upload_button = function (item) {
336 NotebookList.prototype.add_upload_button = function (item) {
327 var that = this;
337 var that = this;
328 var upload_button = $('<button/>').text("Upload")
338 var upload_button = $('<button/>').text("Upload")
329 .addClass('btn btn-primary btn-mini upload_button')
339 .addClass('btn btn-primary btn-mini upload_button')
330 .click(function (e) {
340 .click(function (e) {
331 var nbname = item.find('.item_name > input').val();
341 var nbname = item.find('.item_name > input').val();
332 if (nbname.slice(nbname.length-6, nbname.length) != ".ipynb") {
342 if (nbname.slice(nbname.length-6, nbname.length) != ".ipynb") {
333 nbname = nbname + ".ipynb";
343 nbname = nbname + ".ipynb";
334 }
344 }
335 var path = that.notebook_path;
345 var path = that.notebook_path;
336 var nbdata = item.data('nbdata');
346 var nbdata = item.data('nbdata');
337 var content_type = 'application/json';
347 var content_type = 'application/json';
338 var model = {
348 var model = {
339 content : JSON.parse(nbdata),
349 content : JSON.parse(nbdata),
340 };
350 };
341 var settings = {
351 var settings = {
342 processData : false,
352 processData : false,
343 cache : false,
353 cache : false,
344 type : 'PUT',
354 type : 'PUT',
345 dataType : 'json',
355 dataType : 'json',
346 data : JSON.stringify(model),
356 data : JSON.stringify(model),
347 headers : {'Content-Type': content_type},
357 headers : {'Content-Type': content_type},
348 success : function (data, status, xhr) {
358 success : function (data, status, xhr) {
349 that.add_link(path, nbname, item);
359 that.add_link(path, nbname, item);
350 that.add_delete_button(item);
360 that.add_delete_button(item);
351 },
361 },
352 error : function (data, status, xhr) {
362 error : function (data, status, xhr) {
353 console.log(data, status);
363 console.log(data, status);
354 }
364 }
355 };
365 };
356
366
357 var url = utils.url_join_encode(
367 var url = utils.url_join_encode(
358 that.base_url,
368 that.base_url,
359 'api/notebooks',
369 'api/notebooks',
360 that.notebook_path,
370 that.notebook_path,
361 nbname
371 nbname
362 );
372 );
363 $.ajax(url, settings);
373 $.ajax(url, settings);
364 return false;
374 return false;
365 });
375 });
366 var cancel_button = $('<button/>').text("Cancel")
376 var cancel_button = $('<button/>').text("Cancel")
367 .addClass("btn btn-mini")
377 .addClass("btn btn-mini")
368 .click(function (e) {
378 .click(function (e) {
369 console.log('cancel click');
379 console.log('cancel click');
370 item.remove();
380 item.remove();
371 return false;
381 return false;
372 });
382 });
373 item.find(".item_buttons").empty()
383 item.find(".item_buttons").empty()
374 .append(upload_button)
384 .append(upload_button)
375 .append(cancel_button);
385 .append(cancel_button);
376 };
386 };
377
387
378
388
379 NotebookList.prototype.new_notebook = function(){
389 NotebookList.prototype.new_notebook = function(){
380 var path = this.notebook_path;
390 var path = this.notebook_path;
381 var base_url = this.base_url;
391 var base_url = this.base_url;
382 var settings = {
392 var settings = {
383 processData : false,
393 processData : false,
384 cache : false,
394 cache : false,
385 type : "POST",
395 type : "POST",
386 dataType : "json",
396 dataType : "json",
387 async : false,
397 async : false,
388 success : function (data, status, xhr) {
398 success : function (data, status, xhr) {
389 var notebook_name = data.name;
399 var notebook_name = data.name;
390 window.open(
400 window.open(
391 utils.url_join_encode(
401 utils.url_join_encode(
392 base_url,
402 base_url,
393 'notebooks',
403 'notebooks',
394 path,
404 path,
395 notebook_name),
405 notebook_name),
396 '_blank'
406 '_blank'
397 );
407 );
398 }
408 }
399 };
409 };
400 var url = utils.url_join_encode(
410 var url = utils.url_join_encode(
401 base_url,
411 base_url,
402 'api/notebooks',
412 'api/notebooks',
403 path
413 path
404 );
414 );
405 $.ajax(url, settings);
415 $.ajax(url, settings);
406 };
416 };
407
417
408 IPython.NotebookList = NotebookList;
418 IPython.NotebookList = NotebookList;
409
419
410 return IPython;
420 return IPython;
411
421
412 }(IPython));
422 }(IPython));
General Comments 0
You need to be logged in to leave comments. Login now