root / ui / static / snf / js / ui / web / ui_create_view.js @ 60599850
History | View | Annotate | Download (14.3 kB)
1 |
;(function(root){
|
---|---|
2 |
|
3 |
// root
|
4 |
var root = root;
|
5 |
|
6 |
// setup namepsaces
|
7 |
var snf = root.synnefo = root.synnefo || {};
|
8 |
var models = snf.models = snf.models || {}
|
9 |
var storage = snf.storage = snf.storage || {};
|
10 |
var ui = snf.ui = snf.ui || {};
|
11 |
var util = snf.util = snf.util || {};
|
12 |
|
13 |
var views = snf.views = snf.views || {}
|
14 |
|
15 |
// shortcuts
|
16 |
var bb = root.Backbone;
|
17 |
|
18 |
|
19 |
views.VMCreationPasswordView = views.Overlay.extend({ |
20 |
view_id: "creation_password_view", |
21 |
content_selector: "#creation-password-overlay", |
22 |
css_class: 'overlay-password overlay-info', |
23 |
overlay_id: "creation-password-overlay", |
24 |
|
25 |
subtitle: "", |
26 |
title: "Machine password", |
27 |
|
28 |
initialize: function(options) { |
29 |
views.FeedbackView.__super__.initialize.apply(this, arguments); |
30 |
_.bindAll(this, 'show_password'); |
31 |
|
32 |
this.password = this.$("#new-machine-password"); |
33 |
|
34 |
this.$(".show-machine").click(_.bind(function(){ |
35 |
this.hide();
|
36 |
snf.ui.main.show_vm_details(storage.vms.get(this.vm_id));
|
37 |
}, this));
|
38 |
}, |
39 |
|
40 |
show_password: function() { |
41 |
this.password.text(this.pass); |
42 |
}, |
43 |
|
44 |
onClose: function() { |
45 |
this.password.text(""); |
46 |
}, |
47 |
|
48 |
show: function(pass, vm_id) { |
49 |
this.pass = pass;
|
50 |
this.vm_id = vm_id;
|
51 |
|
52 |
views.VMCreationPasswordView.__super__.show.apply(this, arguments); |
53 |
this.show_password();
|
54 |
} |
55 |
}) |
56 |
|
57 |
|
58 |
|
59 |
views.CreateVMStepView = views.View.extend({ |
60 |
step: "1", |
61 |
title: "Image", |
62 |
submit: false, |
63 |
|
64 |
initialize: function(view) { |
65 |
this.parent = view;
|
66 |
this.el = view.$("div.create-step-cont.step-" + this.step); |
67 |
this.header = view.$(".subheader .step-" + this.step); |
68 |
this.view_id = "create_step_" + this.step; |
69 |
|
70 |
views.CreateVMStepView.__super__.initialize.apply(this);
|
71 |
}, |
72 |
|
73 |
show: function() { |
74 |
// show current
|
75 |
this.el.show();
|
76 |
this.header.addClass("current"); |
77 |
this.update_layout();
|
78 |
}, |
79 |
|
80 |
reset: function() { |
81 |
} |
82 |
}) |
83 |
|
84 |
views.CreateImageSelectView = views.CreateVMStepView.extend({ |
85 |
|
86 |
initialize: function() { |
87 |
views.CreateImageSelectView.__super__.initialize.apply(this, arguments); |
88 |
|
89 |
this.predefined = this.$(".predefined-images ul"); |
90 |
this.custom = this.$(".predefined-images ul"); |
91 |
this.selected_image = undefined; |
92 |
this.reset_images();
|
93 |
}, |
94 |
|
95 |
update_layout: function() { |
96 |
}, |
97 |
|
98 |
select_image: function(image) { |
99 |
if (!image) {
|
100 |
image = storage.images.at(0);
|
101 |
} |
102 |
|
103 |
this.selected_image = image;
|
104 |
this.trigger("change", this.selected_image); |
105 |
|
106 |
this.predefined.find(".image-details").removeClass("selected"); |
107 |
this.predefined.find(".image-details#create-vm-image-" + this.selected_image.id).addClass("selected") |
108 |
}, |
109 |
|
110 |
reset_images: function() { |
111 |
this.$(".image-details").remove(); |
112 |
_.each(storage.images.active(), _.bind(function(img){
|
113 |
this.add_image(img);
|
114 |
}, this))
|
115 |
|
116 |
this.select_image();
|
117 |
|
118 |
var self = this; |
119 |
this.predefined.find(".image-details").click(function(){ |
120 |
self.select_image($(this).data("image")); |
121 |
}) |
122 |
}, |
123 |
|
124 |
add_image: function(img) { |
125 |
var image = $('<li id="create-vm-image-{1}" class="image-details">{0}</li>'.format(img.get("name"), img.id)); |
126 |
image.data("image", img);
|
127 |
image.data("image_id", img.id);
|
128 |
this.predefined.append(image);
|
129 |
}, |
130 |
|
131 |
reset: function() { |
132 |
this.selected_image = undefined; |
133 |
this.reset_images();
|
134 |
}, |
135 |
|
136 |
get: function() { |
137 |
return {'image': this.selected_image}; |
138 |
} |
139 |
}); |
140 |
|
141 |
views.CreateFlavorSelectView = views.CreateVMStepView.extend({ |
142 |
step: 2, |
143 |
initialize: function() { |
144 |
views.CreateFlavorSelectView.__super__.initialize.apply(this, arguments); |
145 |
this.parent.bind("image:change", _.bind(this.handle_image_change, this)); |
146 |
|
147 |
this.cpus = this.$(".flavors-cpu-list") |
148 |
this.disks = this.$(".flavors-disk-list") |
149 |
this.mems = this.$(".flavors-mem-list") |
150 |
|
151 |
this.reset();
|
152 |
this.update_layout();
|
153 |
}, |
154 |
|
155 |
handle_image_change: function(data) { |
156 |
this.current_image = data;
|
157 |
this.update_flavors_data();
|
158 |
this.reset_flavors();
|
159 |
this.update_layout();
|
160 |
}, |
161 |
|
162 |
reset_flavors: function() { |
163 |
this.$(".flavor-opts-list .option").remove(); |
164 |
this.create_flavors();
|
165 |
}, |
166 |
|
167 |
update_flavors_data: function() { |
168 |
this.flavors = storage.flavors.for_image(this.current_image); |
169 |
this.flavors_data = storage.flavors.get_data(this.flavors); |
170 |
|
171 |
if (this.flavors.indexOf(this.current_flavor) == -1) { |
172 |
this.set_current(this.flavors[0]); |
173 |
} |
174 |
}, |
175 |
|
176 |
set_current: function(flv) { |
177 |
this.current_flavor = flv;
|
178 |
this.trigger("change"); |
179 |
this.update_selected_flavor();
|
180 |
}, |
181 |
|
182 |
create_flavors: function() { |
183 |
var flavors = this.get_flavors(); |
184 |
_.each(flavors, _.bind(function(flv){
|
185 |
this.add_flavor(flv);
|
186 |
}, this));
|
187 |
|
188 |
var self = this; |
189 |
this.$(".flavor-options li.option").click(function(){ |
190 |
var el = $(this); |
191 |
el.parent().find(".option").removeClass("selected"); |
192 |
el.addClass("selected");
|
193 |
self.update_selected_from_ui(); |
194 |
}) |
195 |
}, |
196 |
|
197 |
ui_selected: function() { |
198 |
args = [this.$(".option.cpu.selected").data("value"), |
199 |
this.$(".option.mem.selected").data("value"), |
200 |
this.$(".option.disk.selected").data("value"), |
201 |
this.flavors];
|
202 |
|
203 |
storage.flavors.apply(storage.flavors, args) |
204 |
}, |
205 |
|
206 |
update_selected_flavor: function() { |
207 |
|
208 |
}, |
209 |
|
210 |
add_flavor: function(flv) { |
211 |
var values = {'cpu': flv.get('cpu'), 'mem': flv.get('ram'), 'disk': flv.get('disk')}; |
212 |
|
213 |
if (this.$('li.option.cpu.value-{0}'.format(values.cpu)).length == 0) { |
214 |
var cpu = $('<li class="option cpu value-{0}">{0}</li>'.format(values.cpu)).data('value', values.cpu); |
215 |
this.cpus.append(cpu);
|
216 |
} |
217 |
if (this.$('li.option.mem.value-{0}'.format(values.mem)).length == 0) { |
218 |
var mem = $('<li class="option mem value-{0}">{0}</li>'.format(values.mem)).data('value', values.mem); |
219 |
this.mems.append(mem);
|
220 |
} |
221 |
if (this.$('li.option.disk.value-{0}'.format(values.disk)).length == 0) { |
222 |
var disk = $('<li class="option disk value-{0}">{0}</li>'.format(values.disk)).data('value', values.disk); |
223 |
this.disks.append(disk);
|
224 |
} |
225 |
|
226 |
}, |
227 |
|
228 |
get_flavors: function() { |
229 |
return this.flavors; |
230 |
}, |
231 |
|
232 |
update_layout: function() { |
233 |
var flv = this.current_flavor; |
234 |
this.$(".option.value").removeClass("selected"); |
235 |
|
236 |
this.$(".option.cpu.value-" + flv.get("cpu")).addClass("selected"); |
237 |
this.$(".option.mem.value-" + flv.get("ram")).addClass("selected"); |
238 |
this.$(".option.disk.value-" + flv.get("disk")).addClass("selected"); |
239 |
}, |
240 |
|
241 |
reset: function() { |
242 |
this.current_image = storage.images.at(0); |
243 |
this.flavors = [];
|
244 |
this.flavors_data = {'cpu':[], 'mem':[], 'disk':[]}; |
245 |
this.update_flavors_data();
|
246 |
this.reset_flavors();
|
247 |
}, |
248 |
|
249 |
get: function() { |
250 |
return {'flavor': this.current_flavor} |
251 |
} |
252 |
|
253 |
}); |
254 |
|
255 |
views.CreateSubmitView = views.CreateVMStepView.extend({ |
256 |
step: 3, |
257 |
initialize: function() { |
258 |
views.CreateSubmitView.__super__.initialize.apply(this, arguments); |
259 |
this.confirm = this.$(".confirm-params ul"); |
260 |
this.name = this.$("input"); |
261 |
this.name_changed = false; |
262 |
this.init_handlers();
|
263 |
}, |
264 |
|
265 |
init_handlers: function() { |
266 |
this.name.bind("keypress", _.bind(function() { |
267 |
this.name_changed = true; |
268 |
}, this));
|
269 |
|
270 |
this.name.bind("click", _.bind(function() { |
271 |
if (!this.name_changed) { |
272 |
this.name.val(""); |
273 |
} |
274 |
}, this))
|
275 |
}, |
276 |
|
277 |
show: function() { |
278 |
views.CreateSubmitView.__super__.show.apply(this, arguments); |
279 |
this.update_layout();
|
280 |
}, |
281 |
|
282 |
update_layout: function() { |
283 |
var params = this.parent.get_params(); |
284 |
var vm_name = "My {0} server".format(params.image.get("name")); |
285 |
var orig_name = vm_name;
|
286 |
|
287 |
var existing = true; |
288 |
var j = 0; |
289 |
while (existing) {
|
290 |
var existing = storage.vms.select(function(vm){return vm.get("name") == vm_name}).length |
291 |
if (existing) {
|
292 |
j++; |
293 |
vm_name = orig_name + " " + j;
|
294 |
} |
295 |
} |
296 |
|
297 |
if (!_(this.name.val()).trim() || !this.name_changed) { |
298 |
this.name.val(vm_name);
|
299 |
} |
300 |
|
301 |
this.confirm.find("li.image .value").text(params.flavor.get("image")); |
302 |
this.confirm.find("li.cpu .value").text(params.flavor.get("cpu")); |
303 |
this.confirm.find("li.mem .value").text(params.flavor.get("ram")); |
304 |
this.confirm.find("li.disk .value").text(params.flavor.get("disk")); |
305 |
}, |
306 |
|
307 |
reset: function() { |
308 |
this.update_layout();
|
309 |
}, |
310 |
|
311 |
get: function() { |
312 |
return {'name': this.name.val() }; |
313 |
} |
314 |
}); |
315 |
|
316 |
views.CreateVMView = views.Overlay.extend({ |
317 |
|
318 |
view_id: "create_vm_view", |
319 |
content_selector: "#createvm-overlay-content", |
320 |
css_class: 'overlay-createvm overlay-info', |
321 |
overlay_id: "metadata-overlay", |
322 |
|
323 |
subtitle: false, |
324 |
title: "Create new machine", |
325 |
|
326 |
initialize: function(options) { |
327 |
views.CreateVMView.__super__.initialize.apply(this);
|
328 |
this.current_step = 1; |
329 |
|
330 |
this.password_view = new views.VMCreationPasswordView(); |
331 |
|
332 |
this.steps = [];
|
333 |
this.steps[1] = new views.CreateImageSelectView(this); |
334 |
this.steps[1].bind("change", _.bind(function(data) {this.trigger("image:change", data)}, this)); |
335 |
|
336 |
this.steps[2] = new views.CreateFlavorSelectView(this); |
337 |
this.steps[3] = new views.CreateSubmitView(this); |
338 |
|
339 |
this.cancel_btn = this.$(".create-controls .cancel") |
340 |
this.next_btn = this.$(".create-controls .next") |
341 |
this.prev_btn = this.$(".create-controls .prev") |
342 |
this.submit_btn = this.$(".create-controls .submit") |
343 |
|
344 |
this.init_handlers();
|
345 |
this.update_layout();
|
346 |
}, |
347 |
|
348 |
init_handlers: function() { |
349 |
this.next_btn.click(_.bind(function(){ |
350 |
this.show_step(this.current_step + 1); |
351 |
this.update_layout();
|
352 |
}, this))
|
353 |
this.prev_btn.click(_.bind(function(){ |
354 |
this.show_step(this.current_step - 1); |
355 |
this.update_layout();
|
356 |
}, this))
|
357 |
this.cancel_btn.click(_.bind(function(){ |
358 |
this.close_all();
|
359 |
}, this))
|
360 |
this.submit_btn.click(_.bind(function(){ |
361 |
this.submit();
|
362 |
}, this))
|
363 |
}, |
364 |
|
365 |
set_step: function(st) { |
366 |
}, |
367 |
|
368 |
validate: function(data) { |
369 |
if (_(data.name).trim() == "") { |
370 |
this.$(".form-field").addClass("error"); |
371 |
return false; |
372 |
} else {
|
373 |
return true; |
374 |
} |
375 |
}, |
376 |
|
377 |
submit: function() { |
378 |
var data = this.get_params(); |
379 |
if (this.validate(data)) { |
380 |
this.submit_btn.addClass("in-progress"); |
381 |
storage.vms.create(data.name, data.image, data.flavor, {}, {}, _.bind(function(data){
|
382 |
this.close_all();
|
383 |
this.password_view.show(data.server.adminPass);
|
384 |
}, this));
|
385 |
} |
386 |
}, |
387 |
|
388 |
close_all: function() { |
389 |
this.hide();
|
390 |
}, |
391 |
|
392 |
reset: function() { |
393 |
this.current_step = 1; |
394 |
this.steps[1].reset(); |
395 |
this.steps[2].reset(); |
396 |
this.steps[3].reset(); |
397 |
|
398 |
this.submit_btn.removeClass("in-progress"); |
399 |
}, |
400 |
|
401 |
onShow: function() { |
402 |
this.reset()
|
403 |
this.update_layout();
|
404 |
}, |
405 |
|
406 |
update_layout: function() { |
407 |
this.show_step(this.current_step); |
408 |
this.current_view.update_layout();
|
409 |
}, |
410 |
|
411 |
beforeOpen: function() { |
412 |
this.reset();
|
413 |
this.current_step = 1; |
414 |
this.show_step(1); |
415 |
}, |
416 |
|
417 |
show_step: function(step) { |
418 |
if (step <= 1) { |
419 |
step = 1
|
420 |
} |
421 |
if (step > this.steps.length - 1) { |
422 |
step = this.steps.length - 1; |
423 |
} |
424 |
|
425 |
// hide other
|
426 |
this.$(".subheader .header-step").removeClass("current"); |
427 |
this.$(".create-step-cont").hide(); |
428 |
|
429 |
this.steps[step].show();
|
430 |
this.current_step = step;
|
431 |
this.current_view = this.steps[step]; |
432 |
//
|
433 |
this.update_controls();
|
434 |
}, |
435 |
|
436 |
update_controls: function() { |
437 |
var step = this.current_step; |
438 |
if (step == 1) { |
439 |
this.prev_btn.hide();
|
440 |
this.cancel_btn.show();
|
441 |
} else {
|
442 |
this.prev_btn.show();
|
443 |
this.cancel_btn.hide();
|
444 |
} |
445 |
|
446 |
if (step == this.steps.length - 1) { |
447 |
this.next_btn.hide();
|
448 |
this.submit_btn.show();
|
449 |
} else {
|
450 |
this.next_btn.show();
|
451 |
this.submit_btn.hide();
|
452 |
} |
453 |
}, |
454 |
|
455 |
get_params: function() { |
456 |
return _.extend({}, this.steps[1].get(), this.steps[2].get(), this.steps[3].get()); |
457 |
} |
458 |
}); |
459 |
|
460 |
})(this);
|
461 |
|