Statistics
| Branch: | Tag: | Revision:

root / ui / static / snf / js / ui / web / ui_create_view.js @ bd8fa10c

History | View | Annotate | Download (28.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
            this.copy = this.$(".clip-copy");
34

    
35
            this.$(".show-machine").click(_.bind(function(){
36
                this.hide();
37
                snf.ui.main.show_vm_details(storage.vms.get(this.vm_id));
38
            }, this));
39
            
40
        },
41
        
42
        show_password: function() {
43
            this.password.text(this.pass);
44
        },
45

    
46
        onClose: function() {
47
            this.password.text("");
48
        },
49
        
50
        beforeOpen: function() {
51
            if (this.clipboard) { return };
52
            console.log(this.copy);
53
            this.clipboard = new util.ClipHelper(this.copy);
54
            this.clipboard.el.tooltip();
55
        },
56
        
57
        onOpen: function() {
58
            this.clipboard.setText(this.pass);
59
        },
60

    
61
        show: function(pass, vm_id) {
62
            this.pass = pass;
63
            this.vm_id = vm_id;
64

    
65
            views.VMCreationPasswordView.__super__.show.apply(this, arguments);
66
            this.show_password();
67
        }
68
    })
69

    
70

    
71
    
72
    views.CreateVMStepView = views.View.extend({
73
        step: "1",
74
        title: "Image",
75
        submit: false,
76

    
77
        initialize: function(view) {
78
            this.parent = view;
79
            this.el = view.$("div.create-step-cont.step-" + this.step);
80
            this.header = this.$(".step-header .step-" + this.step);
81
            this.view_id = "create_step_" + this.step;
82

    
83
            views.CreateVMStepView.__super__.initialize.apply(this);
84
        },
85

    
86
        show: function() {
87
            // show current
88
            this.el.show();
89
            this.header.addClass("current");
90
            this.header.show();
91
            this.update_layout();
92
        },
93

    
94
        reset: function() {
95
        }
96
    })
97

    
98
    views.CreateImageSelectView = views.CreateVMStepView.extend({
99

    
100
        initialize: function() {
101
            views.CreateImageSelectView.__super__.initialize.apply(this, arguments);
102

    
103
            // elements
104
            this.images_list_cont = this.$(".images-list-cont");
105
            this.images_list = this.$(".images-list-cont ul");
106
            this.image_details = this.$(".images-info-cont");
107
            this.image_details_desc = this.$(".images-info-cont .description p");
108
            this.image_details_title = this.$(".images-info-cont h4");
109
            this.image_details_size = this.$(".images-info-cont .size p");
110
            this.image_details_os = this.$(".images-info-cont .os p");
111
            this.image_details_kernel = this.$(".images-info-cont .kernel p");
112
            this.image_details_gui = this.$(".images-info-cont .gui p");
113

    
114
            this.types = this.$(".type-filter li");
115
            this.categories_list = this.$(".category-filters");
116

    
117
            // params initialization
118
            this.type_selections = ["system", "custom"]
119
            this.selected_type = "system";
120
            this.selected_categories = [];
121
            this.images = [];
122

    
123
            // update
124
            this.update_images();
125

    
126
            // handlers initialization
127
            this.init_handlers();
128
            this.init_position();
129
        },
130

    
131
        init_position: function() {
132
            //this.el.css({position: "absolute"});
133
            //this.el.css({top:"10px"})
134
        },
135
        
136
        init_handlers: function() {
137
            var self = this;
138
            this.types.live("click", function() {
139
                self.select_type($(this).attr("id").replace("type-select-",""));
140
            })
141
        },
142

    
143
        update_images: function() {
144
            this.images = storage.images.active();
145
            this.images_ids = _.map(this.images, function(img){return img.id});
146
            if (this.selected_type == "custom") { this.images = []; this.images_ids = []; }
147

    
148
            return this.images;
149
        },
150

    
151
        update_layout: function() {
152
            this.select_type(this.selected_type);
153
        },
154
        
155
        get_categories: function(images) {
156
            return [];
157
            return ["Desktop", "Server", "Linux", "Windows"];
158
        },
159

    
160
        reset_categories: function() {
161
            var categories = this.get_categories(this.images);
162
            this.categories_list.find("li").remove();
163

    
164
            _.each(categories, _.bind(function(cat) {
165
                var el = $("<li />");
166
                el.text(cat);
167
                this.categories_list.append(el);
168
            }, this));
169

    
170
            if (!categories.length) { 
171
                this.categories_list.parent().find(".clear").hide();
172
                this.categories_list.parent().find(".empty").show();
173
            } else {
174
                this.categories_list.parent().find(".clear").show();
175
                this.categories_list.parent().find(".empty").hide();
176
            }
177
        },
178
        
179
        select_type: function(type) {
180
            this.selected_type = type;
181
            this.types.removeClass("selected");
182
            this.types.filter("#type-select-" + this.selected_type).addClass("selected");
183

    
184
            this.reset_categories();
185
            this.update_images();
186
            this.reset_images();
187
            this.select_image();
188
        },
189

    
190
        select_image: function(image) {
191
            if (!image && this.images_ids.length) {
192
                if (this.selected_image && this.images_ids.indexOf(this.selected_image.id) > -1) {
193
                    image = this.selected_image;
194
                } else {
195
                    image = storage.images.get(this.images_ids[0]);
196
                }
197
            }
198

    
199
            if (!this.images_ids.length) { image = this.selected_image || undefined };
200
            
201
            this.selected_image = image;
202
            this.trigger("change", image);
203
            
204
            if (image) {
205
                this.image_details.show();
206
                this.images_list.find(".image-details").removeClass("selected");
207
                this.images_list.find(".image-details#create-vm-image-" + this.selected_image.id).addClass("selected");
208
                
209
                this.image_details_desc.text(image.get("description"));
210
                
211
                var img = snf.ui.helpers.os_icon_tag(image.get("OS"))
212
                this.image_details_title.html(img + image.get("name"));
213
                this.image_details_os.text(_(image.get("OS")).capitalize());
214
                this.image_details_kernel.text(image.get("kernel"));
215

    
216
                var size = util.readablizeBytes(parseInt(image.get("size")) * 1024 * 1024);
217
                this.image_details_size.text(size);
218
                this.image_details_gui.text(image.get("GUI"));
219

    
220
            } else {
221
                this.image_details.hide();
222
            }
223
        },
224

    
225
        reset_images: function() {
226
            this.images_list.find("li").remove();
227
            _.each(this.images, _.bind(function(img){
228
                this.add_image(img);
229
            }, this))
230
            
231
            if (this.images.length) {
232
                this.images_list.parent().find(".empty").hide();
233
            } else {
234
                this.images_list.parent().find(".empty").show();
235
            }
236

    
237
            this.select_image();
238
            
239
            var self = this;
240
            this.images_list.find(".image-details").click(function(){
241
                self.select_image($(this).data("image"));
242
            });
243
            
244
        },
245

    
246
        show: function() {
247
            views.CreateImageSelectView.__super__.show.apply(this, arguments);
248
        },
249

    
250
        add_image: function(img) {
251
            var image = $(('<li id="create-vm-image-{1}"' +
252
                           'class="image-details clearfix">{2}{0}' +
253
                           '<p>{4}</p><span class="size">{3}' +
254
                           '</span></li>').format(img.get("name"), 
255
                                                  img.id, 
256
                                                  snf.ui.helpers.os_icon_tag(img.get("OS")),
257
                                                  util.readablizeBytes(parseInt(img.get("size"))* 1024 * 1024),
258
                                                  util.truncate(img.get("description"),35)));
259
            image.data("image", img);
260
            image.data("image_id", img.id);
261
            this.images_list.append(image);
262
        },
263

    
264
        reset: function() {
265
            this.selected_image = undefined;
266
            this.reset_images();
267
        },
268

    
269
        get: function() {
270
            return {'image': this.selected_image};
271
        }
272
    });
273

    
274
    views.CreateFlavorSelectView = views.CreateVMStepView.extend({
275
        step: 2,
276
        initialize: function() {
277
            views.CreateFlavorSelectView.__super__.initialize.apply(this, arguments);
278
            this.parent.bind("image:change", _.bind(this.handle_image_change, this));
279

    
280
            this.cpus = this.$(".flavors-cpu-list");
281
            this.disks = this.$(".flavors-disk-list");
282
            this.mems = this.$(".flavors-mem-list");
283

    
284
            this.predefined_flavors = SUGGESTED_FLAVORS;
285
            this.predefined = this.$(".predefined-list");
286
            this.update_predefined_flavors();
287
        },
288

    
289
        handle_image_change: function(data) {
290
            this.current_image = data;
291
            this.update_valid_predefined();
292
            this.update_flavors_data();
293
            this.reset_flavors();
294
            this.update_layout();
295
        },
296

    
297
        reset_flavors: function() {
298
            this.$(".flavor-opts-list .option").remove();
299
            this.create_flavors();
300
        },
301

    
302
        update_predefined_flavors: function() {
303
            this.predefined.find("li").remove();
304
            _.each(this.predefined_flavors, _.bind(function(val, key) {
305
                var el = $(('<li class="predefined-selection" id="predefined-flavor-{0}">' +
306
                           '{1}</li>').format(key, key));
307

    
308
                this.predefined.append(el);
309
                el.data({flavor: storage.flavors.get_flavor(val.cpu, val.ram, val.disk, this.flavors)})
310
                el.click(_.bind(function() {
311
                    this.handle_predefined_click(el);
312
                }, this))
313
            }, this));
314
            this.update_valid_predefined();
315
        },
316

    
317
        handle_predefined_click: function(el) {
318
            if (el.hasClass("disabled")) { return };
319
            this.set_current(el.data("flavor"))
320
        },
321

    
322
        update_valid_predefined: function() {
323
            this.update_unavailable_values();
324
            var self = this;
325
            this.valid_predefined = _.select(_.map(this.predefined_flavors, function(flv, key){
326
                var existing = storage.flavors.get_flavor(flv.cpu, flv.ram, flv.disk, self.flavors);
327
                // non existing
328
                if (!existing) {
329
                    return false;
330
                }
331
                
332
                // not available for image
333
                if (self.unavailable_values && self.unavailable_values.disk.indexOf(existing.get_disk_size()) > -1) {
334
                    return false
335
                }
336

    
337
                return key;
338
            }), function(ret) { return ret });
339
            
340
            $("li.predefined-selection").addClass("disabled");
341
            _.each(this.valid_predefined, function(key) {
342
                $("#predefined-flavor-" + key).removeClass("disabled");
343
            })
344
        },
345

    
346
        update_selected_predefined: function() {
347
            var self = this;
348
            this.predefined.find("li").removeClass("selected");
349

    
350
            _.each(this.valid_predefined, function(key){
351
                var flv = self.predefined_flavors[key];
352
                var exists = storage.flavors.get_flavor(flv.cpu, flv.ram, flv.disk, self.flavors);
353

    
354
                if (exists && (exists.id == self.current_flavor.id)) {
355
                    $("#predefined-flavor-" + key).addClass("selected");
356
                }
357
            })
358
        },
359
        
360
        update_flavors_data: function() {
361
            this.flavors = storage.flavors.active();
362
            this.flavors_data = storage.flavors.get_data(this.flavors);
363
            
364
            var self = this;
365
            var set = false;
366
            
367
            // FIXME: validate current flavor
368
            
369
            if (!this.current_flavor) {
370
                _.each(this.valid_predefined, function(key) {
371
                    var flv = self.predefined_flavors[key];
372
                    var exists = storage.flavors.get_flavor(flv.cpu, flv.ram, flv.disk, self.flavors);
373
                    if (exists && !set) {
374
                        self.set_current(exists);
375
                        set = true;
376
                    }
377
                })
378
            }
379

    
380
            this.update_unavailable_values();
381
        },
382

    
383
        update_unavailable_values: function() {
384
            if (!this.current_image) { this.unavailable_values = {disk:[], ram:[], cpu:[]}; return };
385
            this.unavailable_values = storage.flavors.unavailable_values_for_image(this.current_image);
386
        },
387
        
388
        flavor_is_valid: function(flv) {
389
            if (!flv) { return false };
390
            var existing = storage.flavors.get_flavor(flv.get("cpu"), flv.get("ram"), flv.get("disk"), this.flavors);
391
            if (!existing) { return false };
392
            if (this.unavailable_values && this.unavailable_values.disk.indexOf(flv.get("disk") > -1)) {
393
                return false
394
            }
395
            return true;
396
        },
397
            
398
        set_current: function(flv) {
399
            //console.log(flv);
400
            //if (!this.flavor_is_valid(flv)) { flv = undefined };
401
            
402
            this.current_flavor = flv;
403
            this.trigger("change");
404
            this.update_selected_flavor();
405
            this.update_selected_predefined();
406
        },
407
        
408
        select_default_flavor: function() {
409
               
410
        },
411

    
412
        update_selected_from_ui: function() {
413
            this.set_current(this.ui_selected());
414
        },
415
        
416
        update_disabled_flavors: function() {
417
            this.$(".flavor-options.disk li").removeClass("disabled");
418
            if (!this.unavailable_values) { return }
419

    
420
            this.$(".flavor-options.disk li").each(_.bind(function(i, el){
421
                var el_value = $(el).data("value") * 1024;
422
                if (this.unavailable_values.disk.indexOf(el_value) > -1) {
423
                    $(el).addClass("disabled");
424
                };
425
            }, this));
426
        },
427

    
428
        create_flavors: function() {
429
            var flavors = this.get_active_flavors();
430
            var valid_flavors = this.get_valid_flavors();
431

    
432
            _.each(flavors, _.bind(function(flv){
433
                this.add_flavor(flv);
434
            }, this));
435
            
436
            var self = this;
437
            this.$(".flavor-options li.option").click(function(){
438
                var el = $(this);
439

    
440
                if (el.hasClass("disabled")) { return }
441

    
442
                el.parent().find(".option").removeClass("selected");
443
                el.addClass("selected");
444
                
445
                if (el.hasClass("mem")) { this.last_choice = "mem" }
446
                if (el.hasClass("cpu")) { this.last_choice = "cpu" }
447
                if (el.hasClass("disk")) { this.last_choice = "disk" }
448

    
449
                self.update_selected_from_ui();
450
            })
451
        },
452
        
453
        ui_selected: function() {
454
            var args = [this.$(".option.cpu.selected").data("value"), 
455
                this.$(".option.mem.selected").data("value"), 
456
                this.$(".option.disk.selected").data("value"),
457
            this.flavors];
458

    
459
            var flv = storage.flavors.get_flavor.apply(storage.flavors, args);
460
            return flv;
461
        },
462

    
463
        update_selected_flavor: function() {
464
            var flv = this.current_flavor;
465
            this.$(".option").removeClass("selected");
466

    
467
            this.$(".option.cpu.value-" + flv.get("cpu")).addClass("selected");
468
            this.$(".option.mem.value-" + flv.get("ram")).addClass("selected");
469
            this.$(".option.disk.value-" + flv.get("disk")).addClass("selected");
470
        },
471

    
472
        add_flavor: function(flv) {
473
            var values = {'cpu': flv.get('cpu'), 'mem': flv.get('ram'), 'disk': flv.get('disk')};
474

    
475
            disabled = "";
476

    
477
            if (this.$('li.option.cpu.value-{0}'.format(values.cpu)).length == 0) {
478
                var cpu = $(('<li class="option cpu value-{0} {1}">' + 
479
                             '<span class="value">{0}</span>' + 
480
                             '<span class="metric">x</span></li>').format(values.cpu, disabled)).data('value', values.cpu);
481

    
482
                this.cpus.append(cpu);
483
            }
484
            if (this.$('li.option.mem.value-{0}'.format(values.mem)).length == 0) {
485
                var mem = $(('<li class="option mem value-{0}">' + 
486
                             '<span class="value">{0}</span>' + 
487
                             '<span class="metric">MB</span></li>').format(values.mem)).data('value', values.mem);
488

    
489
                this.mems.append(mem);
490
            }
491
            if (this.$('li.option.disk.value-{0}'.format(values.disk)).length == 0) {
492
                var disk = $(('<li class="option disk value-{0}">' + 
493
                              '<span class="value">{0}</span>' + 
494
                              '<span class="metric">GB</span></li>').format(values.disk)).data('value', values.disk);
495

    
496
                this.disks.append(disk);
497
            }
498
            
499
        },
500
        
501
        get_active_flavors: function() {
502
            return storage.flavors.active();
503
        },
504

    
505
        get_valid_flavors: function() {
506
            return this.flavors;
507
        },
508

    
509
        update_layout: function() {
510
            this.update_selected_flavor();
511
            this.update_disabled_flavors();
512
        },
513

    
514
        reset: function() {
515
            this.current_image = storage.images.at(0);
516
            this.flavors = [];
517
            this.flavors_data = {'cpu':[], 'mem':[], 'disk':[]};
518
            this.update_flavors_data();
519
            this.reset_flavors();
520
        },
521

    
522
        get: function() {
523
            return {'flavor': this.current_flavor}
524
        }
525

    
526
    });
527

    
528
    views.CreateSubmitView = views.CreateVMStepView.extend({
529
        step: 3,
530
        initialize: function() {
531
            views.CreateSubmitView.__super__.initialize.apply(this, arguments);
532
            this.roles = this.$("li.predefined-meta.role .values");
533
            this.confirm = this.$(".confirm-params ul");
534
            this.name = this.$("input.rename-field");
535
            this.name_changed = false;
536
            this.init_suggested_roles();
537
            this.init_handlers();
538
        },
539

    
540
        init_suggested_roles: function() {
541
            var cont = this.roles;
542
            cont.empty();
543
            
544
            // TODO: get suggested from snf.api.conf
545
            _.each(window.SUGGESTED_ROLES, function(r){
546
                var el = $('<span class="val">{0}</span>'.format(r));
547
                el.data("value", r);
548
                cont.append(el);
549
                el.click(function() {
550
                    $(this).parent().find(".val").removeClass("selected");
551
                    $(this).toggleClass("selected");
552
                })
553
            })
554
        },
555

    
556
        init_handlers: function() {
557
            this.name.bind("keypress", _.bind(function(e) {
558
                this.name_changed = true;
559
                if (e.keyCode == 13) { this.parent.submit() };    
560
            }, this));
561

    
562
            this.name.bind("click", _.bind(function() {
563
                if (!this.name_changed) {
564
                    this.name.val("");
565
                }
566
            }, this))
567
        },
568

    
569
        show: function() {
570
            views.CreateSubmitView.__super__.show.apply(this, arguments);
571
            this.update_layout();
572
        },
573
        
574
        update_flavor_details: function() {
575
            var flavor = this.parent.get_params().flavor;
576

    
577
            function set_detail(sel, key) {
578
                var val = key;
579
                if (key == undefined) { val = flavor.get(sel) };
580
                this.$(".confirm-cont.flavor .flavor-" + sel + " .value").text(val)
581
            }
582
            
583
            set_detail("cpu");
584
            set_detail("ram", flavor.get("ram") + " MB");
585
            set_detail("disk", util.readablizeBytes(flavor.get("disk") * 1024 * 1024 * 1024));
586
        },
587

    
588
        update_image_details: function() {
589
            var image = this.parent.get_params().image;
590

    
591
            function set_detail(sel, key) {
592
                var val = key;
593
                if (key == undefined) { val = image.get(sel) };
594
                this.$(".confirm-cont.image .image-" + sel + " .value").text(val)
595
            }
596
            
597
            set_detail("description");
598
            set_detail("name");
599
            set_detail("os", image.get("OS"));
600
            set_detail("gui", image.get("GUI"));
601
            set_detail("size", util.readablizeBytes(image.get_size() * 1024 * 1024));
602
            set_detail("kernel");
603
        },
604

    
605
        update_layout: function() {
606
            var params = this.parent.get_params();
607

    
608
            if (!params.image) { return }
609
            var vm_name = "My {0} server".format(params.image.get("name"));
610
            var orig_name = vm_name;
611
            
612
            var existing = true;
613
            var j = 0;
614
            while (existing && !this.name_changed) {
615
                var existing = storage.vms.select(function(vm){return vm.get("name") == vm_name}).length
616
                if (existing) {
617
                    j++;
618
                    vm_name = orig_name + " " + j;
619
                }
620
            }
621
            if (!_(this.name.val()).trim() || !this.name_changed) {
622
                this.name.val(vm_name);
623
            }
624

    
625
            this.confirm.find("li.image .value").text(params.flavor.get("image"));
626
            this.confirm.find("li.cpu .value").text(params.flavor.get("cpu") + "x");
627
            this.confirm.find("li.mem .value").text(params.flavor.get("ram"));
628
            this.confirm.find("li.disk .value").text(params.flavor.get("disk"));
629

    
630
            if (!this.name_changed) {
631
                this.name.select().focus();
632
            }
633
            
634
            var img = snf.ui.helpers.os_icon_path(params.image.get("OS"))
635
            this.name.css({backgroundImage:"url({0})".format(img)})
636

    
637
            this.update_image_details();
638
            this.update_flavor_details();
639
        },
640

    
641
        reset: function() {
642
            this.roles.find(".val").removeClass("selected");
643
            this.name_changed = false;
644
            this.update_layout();
645
        },
646

    
647
        get_meta: function() {
648
            if (this.roles.find(".selected").length == 0) {
649
                return false;
650
            }
651

    
652
            var role = $(this.roles.find(".selected").get(0)).data("value");
653
            return {'Role': role }
654
        },
655

    
656
        get: function() {
657
            var val = {'name': this.name.val() };
658
            if (this.get_meta()) {
659
                val.metadata = this.get_meta();
660
            }
661
            
662
            console.log(val, this.get_meta());
663
            return val;
664
        }
665
    });
666

    
667
    views.CreateVMView = views.Overlay.extend({
668
        
669
        view_id: "create_vm_view",
670
        content_selector: "#createvm-overlay-content",
671
        css_class: 'overlay-createvm overlay-info',
672
        overlay_id: "metadata-overlay",
673

    
674
        subtitle: false,
675
        title: "Create new machine",
676

    
677
        initialize: function(options) {
678
            views.CreateVMView.__super__.initialize.apply(this);
679
            this.current_step = 1;
680

    
681
            this.password_view = new views.VMCreationPasswordView();
682

    
683
            this.steps = [];
684
            this.steps[1] = new views.CreateImageSelectView(this);
685
            this.steps[1].bind("change", _.bind(function(data) {this.trigger("image:change", data)}, this));
686

    
687
            this.steps[2] = new views.CreateFlavorSelectView(this);
688
            this.steps[3] = new views.CreateSubmitView(this);
689

    
690
            this.cancel_btn = this.$(".create-controls .cancel")
691
            this.next_btn = this.$(".create-controls .next")
692
            this.prev_btn = this.$(".create-controls .prev")
693
            this.submit_btn = this.$(".create-controls .submit")
694
            
695
            this.init_handlers();
696
            this.update_layout();
697

    
698
        },
699

    
700
        init_handlers: function() {
701
            this.next_btn.click(_.bind(function(){
702
                this.show_step(this.current_step + 1);
703
                this.update_layout();
704
            }, this))
705
            this.prev_btn.click(_.bind(function(){
706
                this.show_step(this.current_step - 1);
707
                this.update_layout();
708
            }, this))
709
            this.cancel_btn.click(_.bind(function(){
710
                this.close_all();
711
            }, this))
712
            this.submit_btn.click(_.bind(function(){
713
                this.submit();
714
            }, this))
715
        },
716

    
717
        set_step: function(st) {
718
        },
719
        
720
        validate: function(data) {
721
            if (_(data.name).trim() == "") {
722
                this.$(".form-field").addClass("error");
723
                return false;
724
            } else {
725
                return true;
726
            }
727
        },
728

    
729
        submit: function() {
730
            if (this.submiting) { return };
731
            var data = this.get_params();
732
            var meta = {};
733
            if (this.validate(data)) {
734
                this.submit_btn.addClass("in-progress");
735
                this.submiting = true;
736
                if (data.metadata) { meta = data.metadata; }
737
                storage.vms.create(data.name, data.image, data.flavor, meta, {}, _.bind(function(data){
738
                    this.close_all();
739
                    this.password_view.show(data.server.adminPass, data.server.id);
740
                    this.submiting = false;
741
                }, this));
742
            }
743
        },
744

    
745
        close_all: function() {
746
            this.hide();
747
        },
748

    
749
        reset: function() {
750
            this.current_step = 1;
751
            this.steps[1].reset();
752
            this.steps[2].reset();
753
            this.steps[3].reset();
754

    
755
            this.submit_btn.removeClass("in-progress");
756
        },
757

    
758
        onShow: function() {
759
            this.reset()
760
            this.update_layout();
761
        },
762

    
763
        update_layout: function() {
764
            this.show_step(this.current_step);
765
            this.current_view.update_layout();
766
        },
767

    
768
        beforeOpen: function() {
769
            this.submiting = false;
770
            this.reset();
771
            this.current_step = 1;
772
            this.$(".steps-container").css({"margin-left":0 + "px"});
773
            this.show_step(1);
774
        },
775

    
776
        show_step: function(step) {
777
            if (step <= 1) {
778
                step = 1
779
            }
780
            if (step > this.steps.length - 1) {
781
                step = this.steps.length - 1;
782
            }
783
                
784
            this.steps[step].show();
785
            this.current_step = step;
786
            this.current_view = this.steps[step];
787
            this.update_controls();
788

    
789
            // hide other
790
            //this.$(".step-header .header-step").removeClass("current").hide();
791
            //this.$(".create-step-cont").hide();
792
            var width = this.el.find('.container').width();
793
            var left = (step -1) * width * -1;
794
            //this.$(".steps-container").animate({"margin-left": left + "px"}, 300);
795
            this.$(".steps-container").css({marginLeft:left + "px"});
796
            
797
        },
798

    
799
        update_controls: function() {
800
            var step = this.current_step;
801
            if (step == 1) {
802
                this.prev_btn.hide();
803
                this.cancel_btn.show();
804
            } else {
805
                this.prev_btn.show();
806
                this.cancel_btn.hide();
807
            }
808
            
809
            if (step == this.steps.length - 1) {
810
                this.next_btn.hide();
811
                this.submit_btn.show();
812
            } else {
813
                this.next_btn.show();
814
                this.submit_btn.hide();
815
            }
816
        },
817

    
818
        get_params: function() {
819
            return _.extend({}, this.steps[1].get(), this.steps[2].get(), this.steps[3].get());
820
        }
821
    });
822
    
823
})(this);
824