##// END OF EJS Templates
Draft of the cluster list UI....
Brian Granger -
Show More
@@ -0,0 +1,128 b''
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2008-2011 The IPython Development Team
3 //
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
7
8 //============================================================================
9 // NotebookList
10 //============================================================================
11
12 var IPython = (function (IPython) {
13
14 var ClusterList = function (selector) {
15 this.selector = selector;
16 if (this.selector !== undefined) {
17 this.element = $(selector);
18 this.style();
19 this.bind_events();
20 }
21 };
22
23 ClusterList.prototype.style = function () {
24 $('#cluster_toolbar').addClass('list_toolbar');
25 $('#cluster_list_info').addClass('toolbar_info');
26 $('#cluster_buttons').addClass('toolbar_buttons');
27 $('div#cluster_header').addClass('list_header ui-widget ui-widget-header');
28 $('#refresh_cluster_list').button({
29 icons : {primary: 'ui-icon-arrowrefresh-1-s'},
30 text : false
31 });
32 };
33
34
35 ClusterList.prototype.bind_events = function () {
36 var that = this;
37 $('#refresh_cluster_list').click(function () {
38 that.load_list();
39 });
40 };
41
42
43 ClusterList.prototype.load_list = function () {
44 var settings = {
45 processData : false,
46 cache : false,
47 type : "GET",
48 dataType : "json",
49 success : $.proxy(this.load_list_success, this)
50 };
51 var url = $('body').data('baseProjectUrl') + 'clusters';
52 $.ajax(url, settings);
53 };
54
55
56 ClusterList.prototype.clear_list = function () {
57 this.element.children('.list_item').remove();
58 }
59
60 ClusterList.prototype.load_list_success = function (data, status, xhr) {
61 console.log(data);
62 this.clear_list();
63 var len = data.length;
64 for (var i=0; i<len; i++) {
65 var item_div = $('<div/>');
66 item_div.addClass('list_item ui-widget ui-widget-content ui-helper-clearfix');
67 item_div.css('border-top-style','none');
68 var item = new ClusterItem(item_div);
69 item.update_state(data[i]);
70 item_div.data('item', item);
71 console.log('appending item', item);
72 this.element.append(item_div);
73 };
74 };
75
76
77 var ClusterItem = function (element) {
78 this.element = $(element);
79 this.data = null;
80 };
81
82
83 ClusterItem.prototype.update_state = function (data) {
84 this.data = data;
85 if (data.status === 'running') {
86 this.state_running();
87 } else if (data.status === 'stopped') {
88 this.state_stopped();
89 };
90
91 }
92
93
94 ClusterItem.prototype.state_stopped = function () {
95 var item_name = $('<span/>').addClass('item_name').text(this.data.profile);
96 var item_buttons = $('<span/>').addClass('item_buttons');
97 var start_button = $('<button>Start</button>').button();
98 item_buttons.append(start_button);
99 this.element.append(item_name).append(item_buttons);
100 start_button.click(function (e) {
101 console.log('start');
102 });
103 }
104
105
106 ClusterItem.prototype.start_success = function () {
107
108 };
109
110 ClusterItem.prototype.state_running = function () {
111 var item_name = $('<span/>').addClass('item_name').text(this.data.profile);
112 var item_buttons = $('<span/>').addClass('item_buttons');
113 var stop_button = $('<button>Stop</button>').button();
114 item_buttons.append(start_button);
115 this.element.append(item_name).append(item_buttons);
116 start_button.click(function (e) {
117 console.log('stop');
118 });
119 };
120
121
122 IPython.ClusterList = ClusterList;
123 IPython.ClusterItem = ClusterItem;
124
125 return IPython;
126
127 }(IPython));
128
@@ -1,57 +1,57 b''
1 1
2 2 /**
3 3 * Primary styles
4 4 *
5 5 * Author: IPython Development Team
6 6 */
7 7
8 8 #main_app {
9 9 width: 920px;
10 10 margin: 30px auto 0px auto;
11 11 }
12 12
13 #notebooks_toolbar {
13 .list_toolbar {
14 14 padding: 5px;
15 15 height: 25px;
16 16 line-height: 25px;
17 17 }
18 18
19 #drag_info {
19 .toolbar_info {
20 20 float: left;
21 21 }
22 22
23 #notebooks_buttons {
23 .toolbar_buttons {
24 24 float: right;
25 25 }
26 26
27 #project_name {
27 .list_header {
28 28 height: 25px;
29 29 line-height: 25px;
30 padding: 3px;
30 padding: 3px 5px;
31 31 }
32 32
33 .notebook_item {
33 .list_item {
34 34 height: 25px;
35 35 line-height: 25px;
36 padding: 3px;
36 padding: 3px 5px;
37 37 }
38 38
39 39 .notebook_item a {
40 40 text-decoration: none;
41 41 }
42 42
43 43 .item_buttons {
44 44 float: right;
45 45 }
46 46
47 47 .item_buttons .upload_button {
48 48 color: darkred;
49 49 }
50 50
51 51 .highlight_text {
52 52 color: blue;
53 53 }
54 54
55 55 .ui-tabs .ui-tabs-nav li a {
56 56 padding: .3em .5em;
57 57 }
@@ -1,251 +1,267 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2008-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
14 14 var NotebookList = function (selector) {
15 15 this.selector = selector;
16 16 if (this.selector !== undefined) {
17 17 this.element = $(selector);
18 18 this.style();
19 19 this.bind_events();
20 20 }
21 21 };
22 22
23 23 NotebookList.prototype.style = function () {
24 $('div#project_name').addClass('ui-widget ui-widget-header');
24 $('#notebook_toolbar').addClass('list_toolbar');
25 $('#drag_info').addClass('toolbar_info');
26 $('#notebook_buttons').addClass('toolbar_buttons');
27 $('div#project_name').addClass('list_header ui-widget ui-widget-header');
28 $('#refresh_notebook_list').button({
29 icons : {primary: 'ui-icon-arrowrefresh-1-s'},
30 text : false
31 });
25 32 };
26 33
27 34
28 35 NotebookList.prototype.bind_events = function () {
29 36 if (IPython.read_only){
30 37 return;
31 38 }
32 39 var that = this;
40 $('#refresh_notebook_list').click(function () {
41 that.load_list();
42 });
33 43 this.element.bind('dragover', function () {
34 44 return false;
35 45 });
36 46 this.element.bind('drop', function (event) {
37 47 var files = event.originalEvent.dataTransfer.files;
38 48 for (var i = 0, f; f = files[i]; i++) {
39 49 var reader = new FileReader();
40 50 reader.readAsText(f);
41 51 var fname = f.name.split('.');
42 52 var nbname = fname.slice(0,-1).join('.');
43 53 var nbformat = fname.slice(-1)[0];
44 54 if (nbformat === 'ipynb') {nbformat = 'json';};
45 55 if (nbformat === 'py' || nbformat === 'json') {
46 56 var item = that.new_notebook_item(0);
47 57 that.add_name_input(nbname, item);
48 58 item.data('nbformat', nbformat);
49 59 // Store the notebook item in the reader so we can use it later
50 60 // to know which item it belongs to.
51 61 $(reader).data('item', item);
52 62 reader.onload = function (event) {
53 63 var nbitem = $(event.target).data('item');
54 64 that.add_notebook_data(event.target.result, nbitem);
55 65 that.add_upload_button(nbitem);
56 66 };
57 67 };
58 68 }
59 69 return false;
60 70 });
61 71 };
62 72
63 73
74 NotebookList.prototype.clear_list = function () {
75 this.element.children('.list_item').remove();
76 }
77
78
64 79 NotebookList.prototype.load_list = function () {
80 this.clear_list();
65 81 var settings = {
66 82 processData : false,
67 83 cache : false,
68 84 type : "GET",
69 85 dataType : "json",
70 86 success : $.proxy(this.list_loaded, this)
71 87 };
72 88 var url = $('body').data('baseProjectUrl') + 'notebooks';
73 89 $.ajax(url, settings);
74 90 };
75 91
76 92
77 93 NotebookList.prototype.list_loaded = function (data, status, xhr) {
78 94 var len = data.length;
79 95 // Todo: remove old children
80 96 for (var i=0; i<len; i++) {
81 97 var notebook_id = data[i].notebook_id;
82 98 var nbname = data[i].name;
83 99 var item = this.new_notebook_item(i);
84 100 this.add_link(notebook_id, nbname, item);
85 101 if (!IPython.read_only){
86 102 // hide delete buttons when readonly
87 103 this.add_delete_button(item);
88 104 }
89 105 };
90 106 };
91 107
92 108
93 109 NotebookList.prototype.new_notebook_item = function (index) {
94 110 var item = $('<div/>');
95 item.addClass('notebook_item ui-widget ui-widget-content ui-helper-clearfix');
111 item.addClass('list_item ui-widget ui-widget-content ui-helper-clearfix');
96 112 item.css('border-top-style','none');
97 113 var item_name = $('<span/>').addClass('item_name');
98 114
99 115 item.append(item_name);
100 116 if (index === -1) {
101 117 this.element.append(item);
102 118 } else {
103 119 this.element.children().eq(index).after(item);
104 120 }
105 121 return item;
106 122 };
107 123
108 124
109 125 NotebookList.prototype.add_link = function (notebook_id, nbname, item) {
110 126 item.data('nbname', nbname);
111 127 item.data('notebook_id', notebook_id);
112 128 var new_item_name = $('<span/>').addClass('item_name');
113 129 new_item_name.append(
114 130 $('<a/>').
115 131 attr('href', $('body').data('baseProjectUrl')+notebook_id).
116 132 attr('target','_blank').
117 133 text(nbname)
118 134 );
119 135 var e = item.find('.item_name');
120 136 if (e.length === 0) {
121 137 item.append(new_item_name);
122 138 } else {
123 139 e.replaceWith(new_item_name);
124 140 };
125 141 };
126 142
127 143
128 144 NotebookList.prototype.add_name_input = function (nbname, item) {
129 145 item.data('nbname', nbname);
130 146 var new_item_name = $('<span/>').addClass('item_name');
131 147 new_item_name.append(
132 148 $('<input/>').addClass('ui-widget ui-widget-content').
133 149 attr('value', nbname).
134 150 attr('size', '30').
135 151 attr('type', 'text')
136 152 );
137 153 var e = item.find('.item_name');
138 154 if (e.length === 0) {
139 155 item.append(new_item_name);
140 156 } else {
141 157 e.replaceWith(new_item_name);
142 158 };
143 159 };
144 160
145 161
146 162 NotebookList.prototype.add_notebook_data = function (data, item) {
147 163 item.data('nbdata',data);
148 164 };
149 165
150 166
151 167 NotebookList.prototype.add_delete_button = function (item) {
152 168 var new_buttons = $('<span/>').addClass('item_buttons');
153 169 var delete_button = $('<button>Delete</button>').button().
154 170 click(function (e) {
155 171 // $(this) is the button that was clicked.
156 172 var that = $(this);
157 173 // We use the nbname and notebook_id from the parent notebook_item element's
158 174 // data because the outer scopes values change as we iterate through the loop.
159 var parent_item = that.parents('div.notebook_item');
175 var parent_item = that.parents('div.list_item');
160 176 var nbname = parent_item.data('nbname');
161 177 var notebook_id = parent_item.data('notebook_id');
162 178 var dialog = $('<div/>');
163 179 dialog.html('Are you sure you want to permanently delete the notebook: ' + nbname + '?');
164 180 parent_item.append(dialog);
165 181 dialog.dialog({
166 182 resizable: false,
167 183 modal: true,
168 184 title: "Delete notebook",
169 185 buttons : {
170 186 "Delete": function () {
171 187 var settings = {
172 188 processData : false,
173 189 cache : false,
174 190 type : "DELETE",
175 191 dataType : "json",
176 192 success : function (data, status, xhr) {
177 193 parent_item.remove();
178 194 }
179 195 };
180 196 var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id;
181 197 $.ajax(url, settings);
182 198 $(this).dialog('close');
183 199 },
184 200 "Cancel": function () {
185 201 $(this).dialog('close');
186 202 }
187 203 }
188 204 });
189 205 });
190 206 new_buttons.append(delete_button);
191 207 var e = item.find('.item_buttons');
192 208 if (e.length === 0) {
193 209 item.append(new_buttons);
194 210 } else {
195 211 e.replaceWith(new_buttons);
196 212 };
197 213 };
198 214
199 215
200 216 NotebookList.prototype.add_upload_button = function (item) {
201 217 var that = this;
202 218 var new_buttons = $('<span/>').addClass('item_buttons');
203 219 var upload_button = $('<button>Upload</button>').button().
204 220 click(function (e) {
205 221 var nbname = item.find('.item_name > input').attr('value');
206 222 var nbformat = item.data('nbformat');
207 223 var nbdata = item.data('nbdata');
208 224 var content_type = 'text/plain';
209 225 if (nbformat === 'json') {
210 226 content_type = 'application/json';
211 227 } else if (nbformat === 'py') {
212 228 content_type = 'application/x-python';
213 229 };
214 230 var settings = {
215 231 processData : false,
216 232 cache : false,
217 233 type : 'POST',
218 234 dataType : 'json',
219 235 data : nbdata,
220 236 headers : {'Content-Type': content_type},
221 237 success : function (data, status, xhr) {
222 238 that.add_link(data, nbname, item);
223 239 that.add_delete_button(item);
224 240 }
225 241 };
226 242
227 243 var qs = $.param({name:nbname, format:nbformat});
228 244 var url = $('body').data('baseProjectUrl') + 'notebooks?' + qs;
229 245 $.ajax(url, settings);
230 246 });
231 247 var cancel_button = $('<button>Cancel</button>').button().
232 248 click(function (e) {
233 249 item.remove();
234 250 });
235 251 upload_button.addClass('upload_button');
236 252 new_buttons.append(upload_button).append(cancel_button);
237 253 var e = item.find('.item_buttons');
238 254 if (e.length === 0) {
239 255 item.append(new_buttons);
240 256 } else {
241 257 e.replaceWith(new_buttons);
242 258 };
243 259 };
244 260
245 261
246 262 IPython.NotebookList = NotebookList;
247 263
248 264 return IPython;
249 265
250 266 }(IPython));
251 267
@@ -1,33 +1,35 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2008-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 // On document ready
10 10 //============================================================================
11 11
12 12
13 13 $(document).ready(function () {
14 14
15 15 IPython.page = new IPython.Page();
16 16
17 17 $('div#tabs').tabs();
18 18 $('div#main_app').addClass('border-box-sizing ui-widget');
19 19 $('div#notebooks_toolbar').addClass('ui-widget ui-helper-clearfix');
20 20 $('#new_notebook').button().click(function (e) {
21 21 window.open($('body').data('baseProjectUrl')+'new');
22 22 });
23 23
24 24 IPython.read_only = $('body').data('readOnly') === 'True';
25 25 IPython.notebook_list = new IPython.NotebookList('div#notebook_list');
26 IPython.cluster_list = new IPython.ClusterList('div#cluster_list');
26 27 IPython.login_widget = new IPython.LoginWidget('span#login_widget');
27 28
28 29 IPython.notebook_list.load_list();
30 IPython.cluster_list.load_list();
29 31
30 32 IPython.page.show();
31 33
32 34 });
33 35
@@ -1,57 +1,72 b''
1 1 {% extends page.html %}
2 2
3 3 {% block title %}IPython Dashboard{% end %}
4 4
5 5 {% block stylesheet %}
6 6 <link rel="stylesheet" href="{{static_url("css/projectdashboard.css") }}" type="text/css" />
7 7 {% end %}
8 8
9 9
10 10 {% block params %}
11 11
12 12 data-project={{project}}
13 13 data-base-project-url={{base_project_url}}
14 14 data-base-kernel-url={{base_kernel_url}}
15 15 data-read-only={{read_only}}
16 16
17 17 {% end %}
18 18
19 19
20 20 {% block site %}
21 21
22 22 <div id="main_app">
23 23
24 24 <div id="tabs">
25 25 <ul>
26 26 <li><a href="#tab1">Notebooks</a></li>
27 27 <li><a href="#tab2">Clusters</a></li>
28 28 </ul>
29 29
30 30 <div id="tab1">
31 31 {% if logged_in or not read_only %}
32 <div id="notebooks_toolbar">
32 <div id="notebook_toolbar">
33 33 <span id="drag_info">Drag files onto the list to import
34 34 notebooks.</span>
35 35
36 <span id="notebooks_buttons">
37 <button id="new_notebook">New Notebook</button>
36 <span id="notebook_buttons">
37 <button id="refresh_notebook_list" title="Refresh notebook list">Refresh</button>
38 <button id="new_notebook" title="Create new notebook">New Notebook</button>
38 39 </span>
39 40 </div>
40 41 {% end %}
41 42
42 43 <div id="notebook_list">
43 44 <div id="project_name"><h2>{{project}}</h2></div>
44 45 </div>
45 46 </div>
46 47 <div id="tab2">
48
49 <div id="cluster_toolbar">
50 <span id="cluster_list_info">IPython parallel computing clusters</span>
51
52 <span id="cluster_buttons">
53 <button id="refresh_cluster_list" title="Refresh cluster list">Refresh</button>
54 </span>
55 </div>
56
57 <div id="cluster_list">
58 <div id="cluster_header"><h2>Clusters</h2></div>
59 </div>
60
47 61 </div>
48 62 </div>
49 63
50 64 </div>
51 65
52 66 {% end %}
53 67
54 68 {% block script %}
55 69 <script src="{{static_url("js/notebooklist.js") }}" type="text/javascript" charset="utf-8"></script>
70 <script src="{{static_url("js/clusterlist.js") }}" type="text/javascript" charset="utf-8"></script>
56 71 <script src="{{static_url("js/projectdashboardmain.js") }}" type="text/javascript" charset="utf-8"></script>
57 72 {% end %}
General Comments 0
You need to be logged in to leave comments. Login now