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