root / ui / templates / machines.html @ e246ea1a
History | View | Annotate | Download (31.4 kB)
1 |
{% load i18n %} |
---|---|
2 |
|
3 |
<div id="machines" class="separator"></div> |
4 |
|
5 |
<!-- the create button -->
|
6 |
<div id="createcontainer"> |
7 |
<span id="createbody">{% trans "Start by creating a new Virtual Machine:" %}</span><br /> |
8 |
<a id="create" rel="#wizard" href="#">{% trans "Create New +" %}</a> |
9 |
</div>
|
10 |
|
11 |
<!-- changing between standard/list view -->
|
12 |
<div id="view-select"> |
13 |
<a id="standard" href="/machines/standard"></a> |
14 |
<a id="list" href="/machines/list"></a> |
15 |
<a id="single" href="#"></a> |
16 |
</div>
|
17 |
|
18 |
<div id="emptymachineslist"> |
19 |
<h1 id="welcomeheader">{% trans "Welcome to the ocean!" %}</h1> |
20 |
<br /> |
21 |
<span class="welcomebody">{% trans "From this panel you will be able to manage your Virtual Machines (VMs). If you don't know what a VM is: take the " %}<a href="#">{% trans "tour" %}</a>.</span> |
22 |
<br /> |
23 |
<br /> |
24 |
<span class="welcomebody">{% trans "The panel is currently empty, because you don't have any VMs yet. You can start by creating your new VM by clicking the blue button on the right. The wizard will guide you through the whole process." %}</span> |
25 |
<br /> |
26 |
<br /> |
27 |
<span class="welcomefooter">{% trans "For more information or help, click " %}<a href="#">{% trans "here" %}</a>.</span> |
28 |
</div>
|
29 |
|
30 |
<!-- the form -->
|
31 |
<form action="#"> |
32 |
<!-- scrollable root element -->
|
33 |
<div class="modal" id="wizard"> |
34 |
<!-- status bar -->
|
35 |
<ul id="status"> |
36 |
<li class="active"> |
37 |
<span class="headernumber" class="first">1</span> |
38 |
<div class="headerbody first">{% trans "Image" %}</div> |
39 |
</li>
|
40 |
<li>
|
41 |
<span class="headernumber">2</span> |
42 |
<div class="headerbody">{% trans "Flavor" %}</div> |
43 |
</li>
|
44 |
<li class="third"> |
45 |
<span class="headernumber">3</span> |
46 |
<div class="headerbody">{% trans "Name" %}</div> |
47 |
</li>
|
48 |
</ul>
|
49 |
<!-- scrollable items -->
|
50 |
<div class="items"> |
51 |
<!-- pages -->
|
52 |
<div class="page"> |
53 |
<h2>{% trans "Select an OS" %}</h2> |
54 |
<hr class="topruler" /> |
55 |
<ul class="tabs"> |
56 |
<li><a href="#">{% trans "system images" %}</a></li> |
57 |
<li><a href="#">{% trans "custom images" %}</a></li> |
58 |
</ul>
|
59 |
<div class="panes"> |
60 |
<li id="image-template" style="display:none"> |
61 |
<label for="image.id"> |
62 |
<a>
|
63 |
<div class="image-container"> |
64 |
<div class="image"> |
65 |
<input class="radio" type="radio" name="image-id" id="image-id" /> |
66 |
<img src="" class="image-logo"/> |
67 |
<strong class="image-title">image.title</strong> |
68 |
<br /> |
69 |
<span class="description">image.description</span> |
70 |
<span id="size" class="size">?? MB</span><span class="size"> MB</span> |
71 |
</div>
|
72 |
</div>
|
73 |
</a>
|
74 |
</label>
|
75 |
</li>
|
76 |
<ul class="pane" id="standard-images"> |
77 |
<!-- standard images -->
|
78 |
</ul>
|
79 |
<ul class="pane" id="custom-images"> |
80 |
<!-- custom images -->
|
81 |
</ul>
|
82 |
</div>
|
83 |
<hr class="bottomruler" /> |
84 |
<button type="button" class="prev" id="cancel">{% trans "Cancel" %}</button> |
85 |
<button type="button" class="next right">{% trans "Next" %}</button> |
86 |
</div>
|
87 |
<div class="page"> |
88 |
<h2>{% trans "Select CPUs, RAM and Disk Size" %}</h2> |
89 |
<hr class="topruler" /> |
90 |
<ul>
|
91 |
<li id="machinetype"> |
92 |
<div class="machine-type"> |
93 |
<label for="small" id="small"> |
94 |
<input type="radio" id="small" name="machine-type" value="small" checked="true" /> |
95 |
<span class="typebody" id="small-body">{% trans "small" %}</span> |
96 |
</label>
|
97 |
</div>
|
98 |
<div class="machine-type"> |
99 |
<label for="medium" id="medium"> |
100 |
<input type="radio" id="medium" name="machine-type" value="medium" /> |
101 |
<span class="typebody" id="medium-body">{% trans "medium" %}</span> |
102 |
</label>
|
103 |
</div>
|
104 |
<div class="machine-type"> |
105 |
<label for="large" id="large"> |
106 |
<input type="radio" id="large" name="machine-type" value="large" /> |
107 |
<span class="typebody" id="large-body">{% trans "large" %}</span> |
108 |
</label>
|
109 |
</div>
|
110 |
<div class="machine-type"> |
111 |
<label for="custom" id="custom"> |
112 |
<input type="radio" name="machine-type" id="custom" value="large" /> |
113 |
<span class="typebody" id="custom-body">{% trans "custom" %}</span> |
114 |
</label>
|
115 |
</div>
|
116 |
</li>
|
117 |
<div id="page2-container"> |
118 |
<li class="slider-container"> |
119 |
<label><strong class="sliders">CPUs</strong></label> |
120 |
<input type="range" id="cpu" style="display:none" /> |
121 |
<input type="text" class="range" id="cpu-indicator" /> |
122 |
<span class="units">cores</span> |
123 |
</li>
|
124 |
<li class="slider-container"> |
125 |
<label><strong class="sliders">RAM</strong></label> |
126 |
<input type="range" id="ram" style="display:none" /> |
127 |
<input type="text" class="range" id="ram-indicator" /> |
128 |
<span class="units">MB</span> |
129 |
</li>
|
130 |
<li class="slider-container"> |
131 |
<label><strong class="sliders">Size</strong></label> |
132 |
<input type="range" id="storage" style="display:none" /> |
133 |
<input type="text" class="range" id="storage-indicator" /> |
134 |
<span class="units">GB</span> |
135 |
</li>
|
136 |
<li>
|
137 |
<div class="cost"> |
138 |
<span> {% trans "Your wallet:" %} 10,000 Credits </span> | <span>{% trans "This setup will cost you:" %}<input type="text" id="credits-indicator" value="20" class="range" disabled="disabled" /> {% trans "C/hour" %}</span> |
139 |
</div>
|
140 |
</li>
|
141 |
</div>
|
142 |
</ul>
|
143 |
<hr class="bottomruler" /> |
144 |
<button type="button" class="prev">{% trans "Back" %}</button> |
145 |
<button type="button" class="next right">{% trans "Next" %}</button> |
146 |
</div>
|
147 |
<div class="page"> |
148 |
<h2>{% trans "Confirm your settings" %}</h2> |
149 |
<hr class="topruler" /> |
150 |
<ul id="page3-container"> |
151 |
<li class="required" id="label-name"> |
152 |
<label>
|
153 |
<strong>Name:</strong> |
154 |
<input type="text" class="text" name="machine_name" id="name" value="My Ubuntu 10.04 x86_64 server"/> |
155 |
</label>
|
156 |
</li>
|
157 |
<li>
|
158 |
<span>{% trans "Image:" %}</span> <span id="machine_image-label">Ubuntu 10.04 x86_64 server</span> |
159 |
</li>
|
160 |
<li>
|
161 |
<span>{% trans "CPUs:" %}</span> <span id="machine_cpu-label">2</span> <span>{% trans "cores" %}</span> |
162 |
</li>
|
163 |
<li>
|
164 |
<span>{% trans "RAM:" %}</span> <span id="machine_ram-label">1024</span><span>MB</span> |
165 |
</li>
|
166 |
<li>
|
167 |
<span>{% trans "System Disk:" %}</span> <span id="machine_storage-label">10</span><span>GB</span> |
168 |
</li>
|
169 |
<li>
|
170 |
<span>{% trans "Cost per Hour:" %}</span> <span>40 {% trans "credits" %}</span> |
171 |
</li>
|
172 |
<li>
|
173 |
<span>{% trans "Credits in Wallet:" %}</span> <span>10.000</span> |
174 |
</li>
|
175 |
</ul>
|
176 |
<hr class="bottomruler" /> |
177 |
<button type="button" class="prev">{% trans "Back" %}</button> |
178 |
<button type="button" class="next right" id="start">{% trans "Create VM" %}</button> |
179 |
</div>
|
180 |
</div>
|
181 |
</div>
|
182 |
</form>
|
183 |
|
184 |
<!-- base notification for error/success reporting -->
|
185 |
<a id="notification" rel="#error-success" href="#"></a> |
186 |
|
187 |
<div class="modal" id="error-success"> |
188 |
<h3>{% trans "Error!/Success!" %}</h3> |
189 |
<div><p>{% trans "More details about the result"%}</p></div> |
190 |
</div>
|
191 |
|
192 |
<!-- metadata scrollable -->
|
193 |
<div>
|
194 |
<!-- root element for scrollable -->
|
195 |
<div id="metadata-wizard"> |
196 |
|
197 |
<!-- root element for the items -->
|
198 |
<div class="items"> |
199 |
<div class="page" id="edit-dialog"> |
200 |
<div class='container'> |
201 |
<h3>
|
202 |
<label>{% trans "Tags for machine:" %}</label> |
203 |
<span>Server name</span> |
204 |
<p style='display:none;'>hidden server id</p> |
205 |
</h3>
|
206 |
<hr class="topruler" /> |
207 |
<hr class="fatruler" /> |
208 |
<div class="content"> |
209 |
<ul class="meta-template" style="display:none"> |
210 |
<li>
|
211 |
<label>{% trans "Key" %}</label> |
212 |
<button type="button" class="remove">{% trans "remove x" %}</button> |
213 |
<hr class="meta-separator"> |
214 |
<p>{% trans "Value" %}</p> |
215 |
<button type="button" class="edit">{% trans "edit" %}</button> |
216 |
<button type="button" class="cancel">{% trans "cancel" %}</button> |
217 |
<button type="button" class="save">{% trans "save" %}</button> |
218 |
</li>
|
219 |
</ul>
|
220 |
<ul class="meta-list"> |
221 |
</ul>
|
222 |
</div>
|
223 |
</div>
|
224 |
<button type="button" class="close">{% trans "Close" %}</button> |
225 |
<button type="button" class="create next browse right">{% trans "Create New+" %}</button> |
226 |
<div class="bottomruler"></div> |
227 |
</div>
|
228 |
<div class="page" id="add-dialog"> |
229 |
<div class='container'> |
230 |
<h3>
|
231 |
<label>{% trans "Tags for machine:" %}</label> |
232 |
<span>Server name</span> |
233 |
<p style='display:none;'>hidden server id</p> |
234 |
</h3>
|
235 |
<hr class="topruler" /> |
236 |
<hr class="fatruler" /> |
237 |
<div class="content"> |
238 |
<label class="meta-key">{% trans "Key:" %}</label> |
239 |
<input type="text" maxlength="15" class="key" value="{% trans 'max 15 characters' %}"/> |
240 |
<hr class="meta-separator"> |
241 |
<label class="meta-value">{% trans "Value:" %}</label> |
242 |
<textarea class="value">{% trans "max 150 characters" %}</textarea> |
243 |
</div>
|
244 |
</div>
|
245 |
<button type="button" class="cancel prev browse left">{% trans "Cancel" %}</button> |
246 |
<button type="button" class="save">{% trans "Save" %}</button> |
247 |
<div class="bottomruler"></div> |
248 |
</div>
|
249 |
</div>
|
250 |
</div>
|
251 |
</div>
|
252 |
|
253 |
<a id="metadata-scrollable" href="#" rel="#metadata-wizard"></a> |
254 |
|
255 |
<div id="machinesview"></div> |
256 |
|
257 |
<div class="confirm_multiple"> |
258 |
<p>{% trans "Your actions will affect" %} <span class="actionLen">XX</span> {% trans "machines" %}</p> |
259 |
<button class="yes">{% trans "Confirm All" %}</button> |
260 |
<button class="no">{% trans "Cancel All" %}</button> |
261 |
</div>
|
262 |
|
263 |
<div id="machines" class="separator"></div> |
264 |
|
265 |
<script>
|
266 |
|
267 |
//add hover to labels
|
268 |
$('span.typebody').mouseover(function() {
|
269 |
$(this).addClass('typehover');
|
270 |
});
|
271 |
$('span.typebody').mouseout(function() {
|
272 |
$(this).removeClass('typehover');
|
273 |
});
|
274 |
|
275 |
// return value from metadata key "OS", if it exists
|
276 |
function os_icon(metadata) {
|
277 |
if (!metadata) {
|
278 |
return 'unknown';
|
279 |
}
|
280 |
|
281 |
if (metadata.values.OS == undefined || metadata.values.OS == '') {
|
282 |
return 'unknown';
|
283 |
} else {
|
284 |
if (UrlExists("static/machines/" + metadata.values.OS + '-on.png')) {
|
285 |
return metadata.values.OS;
|
286 |
} else {
|
287 |
return 'unknown';
|
288 |
}
|
289 |
}
|
290 |
}
|
291 |
|
292 |
//helper function to check file existance
|
293 |
function UrlExists(url)
|
294 |
{
|
295 |
var http = new XMLHttpRequest();
|
296 |
http.open('HEAD', url, false);
|
297 |
http.send();
|
298 |
return http.status!=404;
|
299 |
}
|
300 |
|
301 |
// switch to list view
|
302 |
$("a#list").click(function(){
|
303 |
list_view();
|
304 |
return false;
|
305 |
});
|
306 |
|
307 |
// switch to standard view
|
308 |
$("a#standard").click(function(){
|
309 |
standard_view();
|
310 |
return false;
|
311 |
});
|
312 |
|
313 |
// launch VM creation wizard
|
314 |
$("a#create").click(function(){
|
315 |
// launch wizard only if images and flavors are found
|
316 |
if (images.length > 0 && flavors.length > 0) {
|
317 |
$("#wizard").scrollable().begin();
|
318 |
$("#wizard").show();
|
319 |
$('a#create').data('overlay').load()
|
320 |
} else if (images.length == 0 ) {
|
321 |
ajax_error('NO_IMAGES');
|
322 |
return false;
|
323 |
} else if (flavors.length == 0) {
|
324 |
ajax_error('NO_FLAVORS');
|
325 |
return false;
|
326 |
}
|
327 |
});
|
328 |
|
329 |
// create wizard overlay
|
330 |
$(function() {
|
331 |
$("a#create").overlay({
|
332 |
mask: '#000',
|
333 |
effect: 'default',
|
334 |
top: '5%',
|
335 |
oneInstance: false,
|
336 |
closeOnClick: false
|
337 |
});
|
338 |
});
|
339 |
|
340 |
// wizard
|
341 |
$(function() {
|
342 |
var root = $("#wizard").scrollable();
|
343 |
var api = root.scrollable();
|
344 |
// rangeinput with default configuration
|
345 |
// validation logic is done inside the onBeforeSeek callback
|
346 |
api.onBeforeSeek(function(event, i) {
|
347 |
// we are going 1 step backwards so no need for validation
|
348 |
if (api.getIndex() < i) {
|
349 |
// 1. get current page
|
350 |
var page = root.find(".page").eq(api.getIndex()),
|
351 |
// 2. .. and all required fields inside the page
|
352 |
inputs = page.find(".required :input").removeClass("error"),
|
353 |
// 3. .. which are empty
|
354 |
empty = inputs.filter(function() {
|
355 |
return $(this).val().replace(/\s*/g, '') == '';
|
356 |
});
|
357 |
// if there are empty fields, then
|
358 |
if (empty.length) {
|
359 |
// add a CSS class name "error" for empty & required fields
|
360 |
empty.addClass("error");
|
361 |
// cancel seeking of the scrollable by returning false
|
362 |
return false;
|
363 |
// everything is good
|
364 |
}
|
365 |
}
|
366 |
// update confirm step
|
367 |
if (api.getIndex()==0) {
|
368 |
var image = $("input[type=radio][name=image-id]:checked");
|
369 |
var imageRef = image.length ? image[0].id : false
|
370 |
if (imageRef) {
|
371 |
var imageName = $("label[for=" + imageRef + "] .image-title").text();
|
372 |
$("#machine_image-label")[0].textContent = imageName;
|
373 |
$("input[type=text][name=machine_name]")[0].value = "My " + imageName + " server";
|
374 |
}
|
375 |
} else if (api.getIndex()==1) {
|
376 |
$("#machine_cpu-label")[0].textContent = $("#cpu-indicator")[0].value;
|
377 |
$("#machine_ram-label")[0].textContent = $("#ram-indicator")[0].value;
|
378 |
$("#machine_storage-label")[0].textContent = $("#storage-indicator")[0].value;
|
379 |
}
|
380 |
});
|
381 |
api.onSeek(function(event, i) {
|
382 |
// update status bar
|
383 |
$("#status li").removeClass("active").eq(i).addClass("active");
|
384 |
});
|
385 |
// if tab is pressed on the next button seek to next page
|
386 |
$(root).live('keydown', function (e) {
|
387 |
if ( e.keyCode == 9 ){
|
388 |
if(e.preventDefault) {
|
389 |
e.preventDefault();
|
390 |
}
|
391 |
api.next();
|
392 |
}
|
393 |
});
|
394 |
//submit wizard by pressing enter on the name textbox
|
395 |
$("#name").keypress(function (e) {
|
396 |
if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
|
397 |
$('#start').click();
|
398 |
return false;
|
399 |
} else {
|
400 |
return true;
|
401 |
}
|
402 |
});
|
403 |
});
|
404 |
|
405 |
// disable sliders in flavor selection
|
406 |
function disableSliders() {
|
407 |
$("#cpu").attr('disabled',true);
|
408 |
$("#ram").attr('disabled',true);
|
409 |
$("#storage").attr('disabled',true);
|
410 |
}
|
411 |
|
412 |
//update radio button when clicking on text
|
413 |
$("#small-body").live('click' ,function() {
|
414 |
$(this).parent().find("#small").click();
|
415 |
});
|
416 |
$("#medium-body").live('click' ,function() {
|
417 |
$(this).parent().find("#medium").click();
|
418 |
});
|
419 |
$("#large-body").live('click' ,function() {
|
420 |
$(this).parent().find("#large").click();
|
421 |
});
|
422 |
$("#custom-body").live('click' ,function() {
|
423 |
$(this).parent().find("#custom").click();
|
424 |
});
|
425 |
|
426 |
//select image div on radio button select
|
427 |
$('.radio').live('click' ,function() {
|
428 |
$(this).parents("div").find(".image").removeClass('selecteddiv');
|
429 |
if($(this).is(':checked')) {
|
430 |
$(this).parent().addClass('selecteddiv');
|
431 |
}
|
432 |
|
433 |
});
|
434 |
|
435 |
// validate cpu input box
|
436 |
$("#cpu-indicator").live('change',function(){
|
437 |
var v = Number(this.value);
|
438 |
var i = cpus.indexOf(v);
|
439 |
if (isNaN(v)) {
|
440 |
$(this).value = cpus[0];
|
441 |
$("#cpu").data('rangeinput').setValue(0);
|
442 |
} else if (i == -1) {
|
443 |
for (var j=0; j < cpus.length; j++)
|
444 |
if (v<cpus[j])
|
445 |
break;
|
446 |
$("#cpu").data('rangeinput').setValue(j);
|
447 |
} else {
|
448 |
$("#cpu").data('rangeinput').setValue(i);
|
449 |
}
|
450 |
return false;
|
451 |
});
|
452 |
|
453 |
// validate ram input box
|
454 |
$("#ram-indicator").live('change',function(){
|
455 |
var v = Number(this.value);
|
456 |
var i = ram.indexOf(v);
|
457 |
if (isNaN(v)) {
|
458 |
$(this).value = cpus[0];
|
459 |
$("#ram").data('rangeinput').setValue(0);
|
460 |
} else if (i == -1) {
|
461 |
for (var j=0; j < ram.length; j++)
|
462 |
if (v<ram[j])
|
463 |
break;
|
464 |
$("#ram").data('rangeinput').setValue(j);
|
465 |
} else {
|
466 |
$("#ram").data('rangeinput').setValue(i);
|
467 |
}
|
468 |
return false;
|
469 |
});
|
470 |
|
471 |
// validate storage input box
|
472 |
$("#storage-indicator").live('change',function(){
|
473 |
var v = Number(this.value);
|
474 |
var i = disks.indexOf(v);
|
475 |
if (isNaN(v)) {
|
476 |
$(this).value = disks[0];
|
477 |
$("#storage").data('rangeinput').setValue(0);
|
478 |
} else if (i == -1) {
|
479 |
for (var j=0; j < disks.length; j++)
|
480 |
if (v<disks[j])
|
481 |
break;
|
482 |
$("#storage").data('rangeinput').setValue(j);
|
483 |
} else {
|
484 |
$("#storage").data('rangeinput').setValue(i);
|
485 |
}
|
486 |
return false;
|
487 |
});
|
488 |
|
489 |
// selecting the small size
|
490 |
$("#small").click(function(){
|
491 |
$("#cpu").data('rangeinput').setValue(0);
|
492 |
$("#ram").data('rangeinput').setValue(0);
|
493 |
$("#storage").data('rangeinput').setValue(0);
|
494 |
$("#cpu-indicator")[0].value = cpus[0];
|
495 |
$("#ram-indicator")[0].value = ram[0];
|
496 |
$("#storage-indicator")[0].value = disks[0];
|
497 |
$("#small").addClass("active");
|
498 |
$("#medium").removeClass("active");
|
499 |
$("#large").removeClass("active");
|
500 |
$("#custom").removeClass("active");
|
501 |
});
|
502 |
|
503 |
// selecting the medium size
|
504 |
$("#medium").click(function(){
|
505 |
$("#cpu").data('rangeinput').setValue(1);
|
506 |
$("#ram").data('rangeinput').setValue(1);
|
507 |
$("#storage").data('rangeinput').setValue(1);
|
508 |
$("#cpu-indicator")[0].value = cpus[1];
|
509 |
$("#ram-indicator")[0].value = ram[1];
|
510 |
$("#storage-indicator")[0].value = disks[1];
|
511 |
$("#medium").addClass("active");
|
512 |
$("#small").removeClass("active");
|
513 |
$("#large").removeClass("active");
|
514 |
$("#custom").removeClass("active");
|
515 |
});
|
516 |
|
517 |
// selecting the large size
|
518 |
$("#large").click(function(){
|
519 |
$("#cpu").data('rangeinput').setValue(2);
|
520 |
$("#ram").data('rangeinput').setValue(2);
|
521 |
$("#storage").data('rangeinput').setValue(2);
|
522 |
$("#cpu-indicator")[0].value = cpus[2];
|
523 |
$("#ram-indicator")[0].value = ram[2];
|
524 |
$("#storage-indicator")[0].value = disks[2];
|
525 |
$("#large").addClass("active");
|
526 |
$("#medium").removeClass("active");
|
527 |
$("#small").removeClass("active");
|
528 |
$("#custom").removeClass("active");
|
529 |
});
|
530 |
|
531 |
// selecting the custom flavor enables the sliders
|
532 |
$("#custom").click(function(){
|
533 |
$("#cpu").attr('disabled',false);
|
534 |
$("#ram").attr('disabled',false);
|
535 |
$("#storage").attr('disabled',false);
|
536 |
$("strong.sliders").style = 'color: #778899;';
|
537 |
$("#custom input").attr('checked', 'checked');
|
538 |
$("#custom").addClass("active");
|
539 |
$("#medium").removeClass("active");
|
540 |
$("#large").removeClass("active");
|
541 |
$("#small").removeClass("active");
|
542 |
});
|
543 |
|
544 |
//when textbox gains focus, add selection in css
|
545 |
$('#cpu-indicator').focus(function() {
|
546 |
$(this).addClass('selectedrange');
|
547 |
});
|
548 |
$('#ram-indicator').focus(function() {
|
549 |
$(this).addClass('selectedrange');
|
550 |
});
|
551 |
$('#storage-indicator').focus(function() {
|
552 |
$(this).addClass('selectedrange');
|
553 |
});
|
554 |
|
555 |
//when textbox loses focus, clear selection in css
|
556 |
$('#cpu-indicator').blur(function() {
|
557 |
$(this).removeClass('selectedrange');
|
558 |
});
|
559 |
$('#ram-indicator').blur(function() {
|
560 |
$(this).removeClass('selectedrange');
|
561 |
});
|
562 |
$('#storage-indicator').blur(function() {
|
563 |
$(this).removeClass('selectedrange');
|
564 |
});
|
565 |
|
566 |
// exit the wizard
|
567 |
$("#cancel").click(function(){
|
568 |
$("a#create").overlay().close();
|
569 |
});
|
570 |
|
571 |
// starting a new VM through the wizard
|
572 |
$("#start").click(function(){
|
573 |
var imageRef = $('input[type=radio][name=image-id]:checked')[0].id.replace('img-radio-','');
|
574 |
var flavorRef = identify_flavor($("#cpu-indicator")[0].value, $("#storage-indicator")[0].value, $("#ram-indicator")[0].value);
|
575 |
var machineName = $('input[name=machine_name]')[0].value;
|
576 |
if (jQuery.trim(machineName) == ''){
|
577 |
return false;
|
578 |
}
|
579 |
create_vm(machineName, imageRef, flavorRef);
|
580 |
|
581 |
$('a#create').data('overlay').close();
|
582 |
|
583 |
try{console.warn('creating ' + $("input[name=machine_name]")[0].value)} catch(err){}
|
584 |
|
585 |
$("#wizard").hide();
|
586 |
});
|
587 |
|
588 |
// metadata wizard
|
589 |
$(function() {
|
590 |
// initialize scrollable
|
591 |
$("#metadata-wizard").scrollable({
|
592 |
keyboard: false
|
593 |
});
|
594 |
// create wizard overlay
|
595 |
$("a#metadata-scrollable").overlay({
|
596 |
mask: '#000',
|
597 |
effect: 'default',
|
598 |
top: '10%',
|
599 |
closeOnClick: false,
|
600 |
oneInstance: false,
|
601 |
closeOnEsc: true,
|
602 |
load: false,
|
603 |
onClose: function(){
|
604 |
// reset input areas
|
605 |
reset_metadata_input();
|
606 |
serverID = $("#edit-dialog h3 p").text();
|
607 |
get_metadata(serverID);
|
608 |
}
|
609 |
});
|
610 |
});
|
611 |
|
612 |
// bring up metadata scrollable
|
613 |
function show_metadata_wizard() {
|
614 |
// get metadata for current server and fill the dialog
|
615 |
serverID = $("#edit-dialog h3 p").text();
|
616 |
get_metadata(serverID);
|
617 |
$("#metadata-wizard").scrollable().begin();
|
618 |
$("#metadata-wizard").show();
|
619 |
$("a#metadata-scrollable").data('overlay').load();
|
620 |
return false;
|
621 |
}
|
622 |
|
623 |
function reset_metadata_input() {
|
624 |
// reset input areas
|
625 |
$("#metadata-wizard input.key").removeClass("input-enabled");
|
626 |
$("#metadata-wizard input.key")[0].value = 'max 15 characters';
|
627 |
$("#metadata-wizard textarea.value").removeClass("input-enabled");
|
628 |
$("#metadata-wizard textarea.value")[0].value = 'max 150 characters';
|
629 |
}
|
630 |
|
631 |
// update metadata list
|
632 |
function list_metadata(data) {
|
633 |
// empty the list if it already exists
|
634 |
$("#edit-dialog div.content ul.meta-list").empty();
|
635 |
// get the values to show
|
636 |
meta = data.metadata.values;
|
637 |
// show values
|
638 |
for (key in meta) {
|
639 |
pair = $("ul.meta-template li").clone();
|
640 |
//truncate metadata
|
641 |
pair.find("label").text(key.substring(0,15));
|
642 |
if (meta[key].length > 25) {
|
643 |
pair.find("p").text(meta[key].substring(0,25) + "...");
|
644 |
} else {
|
645 |
pair.find("p").text(meta[key]);
|
646 |
}
|
647 |
pair.appendTo("#edit-dialog div.content ul.meta-list").fadeIn();
|
648 |
}
|
649 |
}
|
650 |
|
651 |
// trapping keydown event
|
652 |
jQuery.expr[':'].focus = function( elem ) {
|
653 |
var api = $("#metadata-wizard").data("scrollable");
|
654 |
if (api.getIndex() == 1) {
|
655 |
return elem === document.activeElement && ( elem.type || elem.href );
|
656 |
}
|
657 |
};
|
658 |
|
659 |
$('*').keydown(function (event){
|
660 |
if (event.keyCode == '9') {
|
661 |
event.preventDefault();
|
662 |
return false;
|
663 |
}
|
664 |
if ($('#add-dialog').is(":visible") && !$('#edit-dialog textarea').length && !($('input.key').is(':focus') || $('textarea.value').is(':focus'))){
|
665 |
$('input.key').focus();
|
666 |
$('input.key').focusin();
|
667 |
}
|
668 |
return true;
|
669 |
});
|
670 |
|
671 |
// intercept click on remove button in metadata edit dialog
|
672 |
$('#edit-dialog button.remove').live('click', function() {
|
673 |
// get the server id and meta key needed for the ajax call
|
674 |
var serverID = $(this).closest('div.container').find('h3 p').text();
|
675 |
var meta_key = $(this).parent().find('label').text();
|
676 |
// make the ajax call and list the new GET results
|
677 |
delete_metadata(serverID, meta_key);
|
678 |
return false;
|
679 |
});
|
680 |
|
681 |
// intercept click on edit button in metadata edit dialog
|
682 |
$('#edit-dialog button.edit').live('click', function(){
|
683 |
// show input form for tag value
|
684 |
$(this).parent().find('p').html("<textarea class=\"edit-meta-value\" l=\"3\">" +
|
685 |
$(this).parent().find('p').text() +
|
686 |
"</textarea><p class=\"oldValue\">" +
|
687 |
$(this).parent().find('p').text() + "</p>");
|
688 |
// show/hide the appropriate buttons
|
689 |
$(this).hide(); // this button (edit)
|
690 |
$(this).siblings().show(); // save and cancel buttons
|
691 |
|
692 |
return false;
|
693 |
});
|
694 |
|
695 |
// intercept click on cancel button in metadata edit dialog
|
696 |
$('#edit-dialog button.cancel').live('click', function(){
|
697 |
// put the old value and close the forms
|
698 |
$(this).parent().find('p').html($(this).parent().find('p.oldValue').text());
|
699 |
// show/hide the appropriate buttons
|
700 |
$(this).hide(); // this button (cancel)
|
701 |
$(this).next().hide(); // the save button
|
702 |
$(this).prev().show(); // the edit button
|
703 |
|
704 |
return false;
|
705 |
});
|
706 |
|
707 |
// intercept click on save button in metadata edit dialog
|
708 |
$('#edit-dialog button.save').live('click', function(){
|
709 |
// get the updated values and the old key
|
710 |
var oldKey = $(this).parent().find('label').text();
|
711 |
var newValue = $(this).parent().find('textarea.edit-meta-value').val().substring(0,150);
|
712 |
// put the new value and close the forms
|
713 |
$(this).parent().find('p').html(newValue);
|
714 |
// update meatadata pair
|
715 |
add_metadata(serverID, oldKey, newValue);
|
716 |
|
717 |
// show/hide the appropriate buttons
|
718 |
$(this).hide(); // this button (save)
|
719 |
$(this).prev().hide(); // the cancel button
|
720 |
$(this).prev().prev().show(); // the edit button
|
721 |
|
722 |
return false;
|
723 |
});
|
724 |
|
725 |
// intercept create metadata key focus
|
726 |
$("#metadata-wizard input.key").live('focusin', function() {
|
727 |
if ($(this).hasClass("input-enabled")) {
|
728 |
} else {
|
729 |
$("#metadata-wizard input.key").addClass("input-enabled");
|
730 |
$(this).addClass("input-enabled");
|
731 |
this.value = '';
|
732 |
}
|
733 |
return false;
|
734 |
});
|
735 |
|
736 |
// intercept create metadata key focus out
|
737 |
$("#metadata-wizard input.key").live('focusout', function() {
|
738 |
if (this.value == "") {
|
739 |
$(this).removeClass("input-enabled");
|
740 |
this.value = 'max 15 characters';
|
741 |
}
|
742 |
return false;
|
743 |
});
|
744 |
|
745 |
// intercept create metadata key focus
|
746 |
$("#metadata-wizard textarea.value").live('focusin', function() {
|
747 |
if ($(this).hasClass("input-enabled")) {
|
748 |
} else {
|
749 |
$("#metadata-wizard textarea.value").addClass("input-enabled");
|
750 |
$(this).addClass("input-enabled");
|
751 |
this.value = '';
|
752 |
}
|
753 |
return false;
|
754 |
});
|
755 |
|
756 |
// intercept create metadata key focus out
|
757 |
$("#metadata-wizard textarea.value").live('focusout', function() {
|
758 |
if (this.value == "") {
|
759 |
$(this).removeClass("input-enabled");
|
760 |
this.value = 'max 150 characters';
|
761 |
}
|
762 |
return false;
|
763 |
});
|
764 |
|
765 |
// intercept click on cancel button in metadata add dialog
|
766 |
$('#add-dialog button.cancel').live('click', function() {
|
767 |
reset_metadata_input();
|
768 |
});
|
769 |
|
770 |
// intercept click on save button in metadata add dialog
|
771 |
$('#add-dialog button.save').live('click', function() {
|
772 |
// if both fields are filled in
|
773 |
if ($('input.key').hasClass("input-enabled") && $('textarea.value').hasClass("input-enabled")) {
|
774 |
// get the server id, meta key and meta value needed for the ajax call
|
775 |
var serverID = $(this).parent().find('h3 p').text();
|
776 |
var meta_key = $(this).parent().find('input.key').attr('value');
|
777 |
var meta_value = $(this).parent().find('textarea.value')[0].value;
|
778 |
// make the ajax call and list the new GET results
|
779 |
add_metadata(serverID, meta_key, meta_value);
|
780 |
// reset input areas
|
781 |
reset_metadata_input();
|
782 |
// go to previous step
|
783 |
$('#add-dialog button.prev').click();
|
784 |
} else {
|
785 |
// find which field is not filled in and focus there
|
786 |
if (!$('input.key').hasClass("input-enabled")) {
|
787 |
$('input.key').focus();
|
788 |
$('input.key').focusin();
|
789 |
} else {
|
790 |
$('textarea.value').focus();
|
791 |
$('textarea.value').focusin();
|
792 |
}
|
793 |
}
|
794 |
return false;
|
795 |
});
|
796 |
|
797 |
// confirm all actions
|
798 |
$("div.confirm_multiple .yes").live('click', function(){
|
799 |
while(pending_actions.length > 0){ // if there is a pending action for this server execute it
|
800 |
action = pending_actions.pop(); // extract action
|
801 |
var serverID = action[1];
|
802 |
if ($.cookie("list") != '1') { // standard view
|
803 |
$('#' + serverID + ' .selected').removeClass('selected');
|
804 |
$('#' + serverID + ' .display').removeClass('display');
|
805 |
if (action[0] == shutdown) {
|
806 |
$('#' + serverID + ' .status').text('Shutting down');
|
807 |
} else if (action[0] == start) {
|
808 |
$('#' + serverID + ' .status').text('Starting');
|
809 |
} else if (action[0] == reboot) {
|
810 |
$('#' + serverID + ' .status').text('Rebooting');
|
811 |
} else if (action[0] == destroy) {
|
812 |
$('#' + serverID + ' .status').text('Destroying');
|
813 |
}
|
814 |
$('#' + serverID + ' .spinner').show();
|
815 |
} else { // list view
|
816 |
osIcon = $('#'+serverID).parent().parent().find('.list-logo');
|
817 |
osIcon.attr('os',osIcon.attr('src'));
|
818 |
osIcon.attr('src','static/progress.gif');
|
819 |
if (action[0] == shutdown) {
|
820 |
$('#' + serverID).parent().parent().find('span.status').text('Shutting down');
|
821 |
} else if (action[0] == start) {
|
822 |
$('#' + serverID).parent().parent().find('span.status').text('Starting');
|
823 |
} else if (action[0] == reboot) {
|
824 |
$('#' + serverID).parent().parent().find('span.status').text('Rebooting');
|
825 |
} else if (action[0] == destroy) {
|
826 |
$('#' + serverID).parent().parent().find('span.status').text('Destroying');
|
827 |
}
|
828 |
}
|
829 |
action[0]([serverID]); // execute action
|
830 |
}
|
831 |
update_confirmations();
|
832 |
});
|
833 |
|
834 |
// cancel all actions
|
835 |
$("div.confirm_multiple .no").live('click', function(){
|
836 |
pending_actions = [];
|
837 |
$('.machine .selected').removeClass('selected');
|
838 |
$('.machine .display').removeClass('display');
|
839 |
update_confirmations();
|
840 |
});
|
841 |
|
842 |
// basic functions executed on page load
|
843 |
if (images.length > 0) {
|
844 |
// populate image list
|
845 |
update_wizard_images();
|
846 |
}
|
847 |
if (flavors.length > 0) {
|
848 |
// configure flavors
|
849 |
update_wizard_flavors();
|
850 |
}
|
851 |
// create tabs for main menu
|
852 |
$("ul.tabs").tabs("div.panes ul");
|
853 |
|
854 |
</script>
|