Statistics
| Branch: | Tag: | Revision:

root / ui / static / snf / js / ui / web / ui_networks_view.js @ 3450cf0d

History | View | Annotate | Download (30.4 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 || {};
12
    var views = snf.views = snf.views || {}
13

    
14
    // shortcuts
15
    var bb = root.Backbone;
16
    
17
    // logging
18
    var logger = new snf.logging.logger("SNF-VIEWS");
19
    var debug = _.bind(logger.debug, logger);
20
    
21
    
22
    views.NetworkConnectVMsOverlay = views.Overlay.extend({
23
        title: "Connect machine",
24
        overlay_id: "overlay-select-vms",
25
        content_selector: "#network-vms-select-content",
26
        css_class: "overlay-info",
27

    
28
        initialize: function() {
29
            views.NetworkConnectVMsOverlay.__super__.initialize.apply(this);
30
            this.list = this.$(".vms-list ul");
31
            this.empty_message = this.$(".empty-message");
32
        },
33
        
34
        init_handlers: function() {
35
            var self = this;
36
            this.list.find("li").click(function(){
37
                $(this).toggleClass("selected");
38
            });
39

    
40
            this.el.find(".create").click(_.bind(function() {
41
                this.submit();
42
            }, this));
43
        },
44

    
45
        reset: function() {
46
            this.list.find("li").remove();
47
        },
48

    
49
        beforeOpen: function() {
50
            this.reset();
51
            this.update_layout();
52
        },
53
        
54
        vm: function(vm) {
55
            if (vm.id) { var id = vm.id } else {var id = vm}
56
            return this.list.find(".vm-" + id);
57
        },
58

    
59
        get_selected: function() {
60
            return this.list.find(".selected").map(function() {return $(this).data('vm')})
61
        },
62

    
63
        update_layout: function() {
64
            if (this.vms.length == 0) {
65
                this.empty_message.show();
66
            } else {
67
                this.empty_message.hide();
68
            }
69

    
70
            _.each(this.vms, _.bind(function(vm){
71
                var html = '<li class="vm option options-object vm-{0}">' +
72
                           '<div class="options-object-cont">' +
73
                           '{2}' + 
74
                           '<span class="title">{1}</span>' + 
75
                           '<span class="value">{3}</span></div>' + 
76
                           '</li>';
77
                var el = $(html.format(vm.id, 
78
                                       util.truncate(vm.get("name"), 23), 
79
                                       snf.ui.helpers.vm_icon_tag(vm, "small", {'class':'os'}),
80
                                       vm.get_os()
81
                                      ))
82
                el.data({vm:vm,vm_id:vm.id})
83
                this.list.append(el);
84

    
85
                vm.bind("remove", function(){ el.remove()})
86
                vm.bind("change:name", function(i,v){el.find(".title").text(v)})
87
            }, this));
88

    
89
            this.init_handlers();
90
            this.set_selected();
91
        },
92

    
93
        set_selected: function() {
94
            _.each(this.selected, _.bind(function(el){
95
                this.vm(el).addClass("selected");
96
            }, this));
97
        },
98

    
99
        show_vms: function(network, vms, selected, callback) {
100
            this.network = network;
101
            this.reset();
102
            this.set_subtitle(network.get("name"));
103
            this.vms = vms;
104
            this.selected = selected;
105
            this.cb = callback;
106
            this.show();
107
        },
108

    
109
        submit: function() {
110
            this.cb(this.get_selected());
111
        }
112
    })
113

    
114
    views.NetworkActionsView = views.View.extend({
115
        
116
        initialize: function(view, net, el, opts) {
117
            this.parent = view
118
            this.network = net;
119
            this.el = el;
120
            
121
            this.actions = this.$(".actions");
122
            this.selected = undefined;
123

    
124
            this.destroy = this.$(".actions .destroy a");
125
            this.connect = this.$(".actions .add");
126

    
127
            this.init_handlers();
128
            this.update_layout();
129
        },
130

    
131
        init_handlers: function() {
132
            this.connect.click(_.bind(function(e){
133
                e.preventDefault();
134
            }))
135
        },
136

    
137
        update_layout: function() {
138
        }
139
    });
140

    
141
    views.NetworkCreateView = views.Overlay.extend({
142
        view_id: "network_create_view",
143
        content_selector: "#networks-create-content",
144
        css_class: 'overlay-networks-create overlay-info',
145
        overlay_id: "network-create-overlay",
146

    
147
        title: "Create new private network",
148
        subtitle: "Networks",
149

    
150
        initialize: function(options) {
151
            views.NetworkCreateView.__super__.initialize.apply(this);
152

    
153
            this.create_button = this.$("form .form-action.create");
154
            this.text = this.$(".network-create-name");
155
            this.form = this.$("form");
156
            this.init_handlers();
157
        },
158

    
159
        init_handlers: function() {
160
            this.create_button.click(_.bind(function(e){
161
                this.submit();
162
            }, this));
163

    
164
            this.form.submit(_.bind(function(e){
165
                e.preventDefault();
166
                this.submit;
167
                return false;
168
            }, this))
169

    
170
            this.text.keypress(_.bind(function(e){
171
                if (e.which == 13) {this.submit()};
172
            },this))
173
        },
174

    
175
        submit: function() {
176
            if (this.validate()) {
177
                this.create();
178
            };
179
        },
180
        
181
        validate: function() {
182
            // sanitazie
183
            var t = this.text.val();
184
            t = t.replace(/^\s+|\s+$/g,"");
185
            this.text.val(t);
186

    
187
            if (this.text.val() == "") {
188
                this.text.closest(".form-field").addClass("error");
189
                this.text.focus();
190
                return false;
191
            } else {
192
                return true;
193
            }
194
        },
195

    
196
        create: function() {
197
            this.create_button.addClass("in-progress");
198
            snf.storage.networks.create(this.text.val(), _.bind(function(){
199
                this.hide();
200
            }, this));
201
        },
202

    
203
        beforeOpen: function() {
204
            this.create_button.removeClass("in-progress")
205
            this.text.val("");
206
            this.text.show();
207
            this.text.focus();
208
        },
209

    
210
        onOpen: function() {
211
            this.text.focus();
212
        }
213
    });
214

    
215
    views.NetworkVMView = views.View.extend({
216

    
217
        initialize: function(vm, parent, firewall_controls, el) {
218
            this.firewall_controls = firewall_controls || false;
219
            this.vm = vm;
220
            // parent view di
221
            this.parent = parent;
222
            // TODO make it better
223
            this.el = el || this.parent.vm(vm);
224

    
225
            this.init_layout();
226
            this.update_layout();
227

    
228
            this.disconnect = this.$(".action-disconnect");
229
            this.confirm_el = this.$(".confirm_single");
230
            this.cancel = this.$("button.no");
231
            this.confirm = this.$("button.yes");
232
            this.details = this.$(".action-details");
233

    
234
            this.init_handlers();
235
            
236
            this.firewall_view = undefined;
237
            if (this.firewall_controls) {
238
                this.firewall_view = new views.FirewallEditView(this.vm, this.parent.network, this);
239
            }
240

    
241
        },
242
        
243
        init_handlers: function() {
244
            if (!this.parent.network.is_public()) {
245
                this.disconnect.click(_.bind(function(e){
246
                    e.preventDefault();
247
                    this.confirm_disconnect();
248
                }, this));
249
                this.cancel.click(_.bind(function(e){
250
                    e.preventDefault()
251
                    this.confirm_el.hide();
252
                    this.disconnect.removeClass("selected");
253
                }, this));
254
                this.confirm.click(_.bind(function(e){
255
                    e.preventDefault()
256
                    this.disconnect_vm();
257
                    this.confirm_el.hide();
258
                    this.disconnect.removeClass("selected");
259
                }, this));
260

    
261
                snf.ui.main.bind("view:change", _.bind(function(v) {
262
                    if (v == "networks" ){ return }
263
                    this.confirm_el.hide();
264
                    this.disconnect.removeClass("selected");
265
                }, this));
266

    
267
                this.$(".remove-icon").click(_.bind(function(){
268
                    this.confirm_disconnect();
269
                }, this))
270
            }
271
            
272
            var vm = this.vm;
273
            this.details.click(function(){
274
                snf.ui.main.show_vm_details(vm);
275
            })
276

    
277
        },
278

    
279
        confirm_disconnect: function() {
280
            this.confirm_el.show();
281
            this.disconnect.addClass("selected");
282
        },
283

    
284
        init_layout: function() {
285
            if (!this.firewall_controls) { return };
286
        },
287

    
288
        update_layout: function() {
289
            this.$(".vm-name").text(snf.util.truncate(this.vm.get("name"), 40));
290
            this.$("img.logo").attr("src", ui.helpers.vm_icon_path(this.vm, "medium"));
291

    
292
            if (this.firewall_view) {
293
                this.$(".ipv4-text").text(this.vm.get_addresses().ip4);
294
                this.$(".ipv6-text").text(this.vm.get_addresses().ip6);
295
            }
296

    
297
            if (this.firewall_view) {
298
                this.firewall_view.update_layout();
299
            }
300
        },
301

    
302
        disconnect_vm: function() {
303
            this.$("a.selected").removeClass("selected");
304
            this.parent.network.remove_vm(this.vm);
305
        },
306

    
307
        update_firewall_layout: function() {
308
        }
309

    
310

    
311
    })
312

    
313
    views.NetworkModelRenameView = views.View.extend({
314
        initialize: function(parent, network) {
315
            this.parent = parent;
316
            this.network = network;
317
            this.el = this.parent.el.find(".name-div");
318

    
319
            this.icon = this.$(".rename-network");
320
            this.save = this.$("span.save");
321
            this.cancel = this.$("span.cancel");
322
            this.buttons = this.$(".editbuttons");
323
            this.name = this.$("span.name");
324
            this.editing = false;
325
            this.init_handlers();
326
            this.update_layout();
327
        },
328

    
329
        init_handlers: function() {
330
            this.icon.click(_.bind(function(){
331
                this.editing = true;
332
                this.update_layout();
333
            }, this));
334
            this.cancel.click(_.bind(function(){
335
                this.editing = false;
336
                this.update_layout();
337
            }, this));
338
            this.save.click(_.bind(function(){
339
                this.submit();
340
            }, this))
341
        },
342
        
343
        submit: function() {
344
            var value = _(this.input.val()).trim();
345
            if (value == "") { return }
346

    
347
            this.network.rename(value, _.bind(function(){
348
                this.editing = false;
349
                this.update_layout();
350
            }, this));
351
        },
352

    
353
        create_input: function() {
354
            this.input = $('<input type="text" class="network-rename-input" />');
355
            this.input.val(this.network.get("name"));
356
            this.el.append(this.input);
357
            this.input.focus();
358
            this.input.bind("keypress", _.bind(function(ev){
359
                if (ev.which == 13) {
360
                    this.submit();
361
                }
362
                if (ev.keyCode == 17) {this.editing = false; this.update_layout()};
363
            }, this));
364
        },
365

    
366
        remove_input: function() {
367
            if (!this.input) { return }
368
            this.input.remove();
369
        },
370

    
371
        update_layout: function() {
372
            if (this.editing) {
373
                if (this.buttons.is(":visible")) { return }
374
                this.icon.hide();
375
                this.buttons.show();
376
                this.create_input();
377
                this.name.hide();
378
            } else {
379
                this.buttons.hide();
380
                this.remove_input();
381
                this.name.show();
382
                this.icon.show();
383
            }
384
        }
385
    })
386

    
387
    views.FirewallEditView = views.View.extend({
388
        initialize: function(vm, network, parent) {
389
            this.parent = parent;
390
            this.vm = vm;
391
            this.network = network;
392
            this.el = this.parent.el;
393

    
394
            views.FirewallEditView.__super__.initialize.apply(this);
395

    
396
            // elements
397
            this.toggler = this.$(".firewall-toggle");
398
            this.indicator = this.$(".machines-label span");
399
            this.progress = this.$(".network-progress-indicator");
400
            this.content = this.$(".firewall-content");
401
            this.inputs = this.$("input[type=radio]");
402
            this.labels = this.$("span.checkbox-legends, label.checkbox-legends");
403
            this.apply = this.$(".firewall-apply");
404

    
405
            this.$(".firewall-content").hide();
406
            this.$(".firewall-content input[type=radio]").attr("name", "firewall-opt-for-{0}".format(this.vm.id))
407
            var mode = this.vm.firewall_profile(this.network.id);
408
            this.$(".firewall-content input[value={0}]".format(mode)).attr("checked", true);
409

    
410
            this.init_handlers();
411
            this.update_layout();
412
        },
413
        
414
        _get_selected: function() {
415
            return this.inputs.filter(":checked");
416
        },
417

    
418
        reset_selected: function() {
419
        },
420

    
421
        submit: function() {
422
        },
423

    
424
        reset_value: function() {
425
            this.inputs.filter("[value={0}]".format(this.vm.firewall_profile(this.network.id))).attr("checked");
426
        },
427

    
428
        init_handlers: function() {
429
            this.toggler.click(_.bind(function(){
430
                cont = this.content;
431
                if (cont.is(":visible")) {
432
                    this.hide_firewall();
433
                    this.reset_value();
434
                } else {
435
                    this.show_firewall();
436
                }
437

    
438
                $(window).trigger("resize");
439
            }, this))
440
            
441
            this.apply.click(_.bind(function(){
442
                this.apply.addClass("in-progress");
443
                
444
                // make the api call
445
                this.vm.set_firewall(this.network.id, this.value(), 
446
                // complete
447
                _.bind(function() {
448
                    // complete callback
449
                    this.apply.removeClass("in-progress");
450
                }, this), 
451
                // error
452
                _.bind(function(){
453
                    this.vm.remove_pending_firewall(this.network.id, this.value());
454
                }, this));
455
                this.hide_firewall();
456
            }, this))
457

    
458
            this.inputs.change(_.bind(function(){
459
                this.update_selected();
460
            }, this))
461
            
462
            var self = this;
463
            this.$(".checkbox-legends").click(function(el) {
464
                var el = $(this);
465
                el.prev().click();
466
                self.update_selected();
467
            })
468
        },
469

    
470
        update_selected: function() {
471
            this.update_layout();
472
        },
473

    
474
        show_firewall: function() {
475
            this.content.slideDown(100, function(){$(window).trigger("resize")});
476
            this.toggler.addClass("open");
477
        },
478

    
479
        hide_firewall: function() {
480
            this.content.slideUp(100, function(){$(window).trigger("resize")});
481
            this.toggler.removeClass("open");
482
        },
483

    
484
        value: function() {
485
            return this._get_selected().val();
486
        },
487

    
488
        update_layout: function() {
489
            if (this.value() == this.vm.firewall_profile(this.network.id)) {
490
                this.apply.hide();
491
            } else {
492
                this.apply.show();
493
            }
494

    
495
            profile = this.vm.firewall_profile(this.network.id);
496
            if (this.vm.has_firewall(this.network.id)) {
497
                this.$(".firewall-toggle .label span").text("On");
498
                this.$(".firewall-toggle .label span").removeClass("firewall-off");
499
                this.$(".firewall-toggle .label span").addClass("firewall-on");
500
            } else {
501
                this.$(".firewall-toggle .label span").text("Off");
502
                this.$(".firewall-toggle .label span").removeClass("firewall-on");
503
                this.$(".firewall-toggle .label span").addClass("firewall-off");
504
            }
505
            
506
            this.$("span.checkbox-legends").removeClass("current");
507
            this.inputs.filter("[value={0}]".format(this.vm.firewall_profile(this.network.id))).next().addClass("current");
508

    
509
            var firewalling = this.vm.firewall_pending(this.network.id);
510
            var el = this.el;
511
            
512
            if (firewalling) {
513
                el.find("button").addClass("in-progress").show();
514
                el.find(".network-progress-indicator").show();
515
            } else {
516
                el.find("button").removeClass("in-progress");
517
                el.find(".network-progress-indicator").hide();
518
            }
519
        }
520
    })
521

    
522
    views.NetworkModelView = views.View.extend({
523
        
524
        firewall: false,
525

    
526
        initialize: function(network, view) {
527
            this.parent_view = view;
528
            this.network = network;
529
            this.init_vm_handlers();
530

    
531
            this.id = "networks_view_" + network.id;
532
            views.NetworkModelView.__super__.initialize.call(this);
533

    
534
            this.vm_views = {};
535

    
536
            this.el = this.create_el();
537

    
538
            // element helpers
539
            this.vms_list = this.$(".machines-list");
540
            this.vms_list_toggler = this.$(".list-toggle");
541
            
542
            this.init_handlers();
543
            this.update_vms();
544
            this.update_layout();
545

    
546
            this.hide_vm_list();
547
            this.vms_list.hide();
548

    
549
            this.rename_view = undefined;
550
            if (!this.network.is_public()) {
551
                this.rename_view = new views.NetworkModelRenameView(this, network);
552
            }
553
        },
554

    
555
        show_vm_list: function() {
556
            if (this.vms_empty()) { return }
557
            this.vms_list_toggler.addClass("open");
558
            this.vms_list.slideDown(function(){
559
                $(window).trigger("resize");
560
            }).closest(".network").addClass("expand");
561
            this.$(".empty-network-slot").show();
562
        },
563

    
564
        hide_vm_list: function() {
565
            this.vms_list_toggler.removeClass("open");
566
            this.vms_list.slideUp(function(){
567
                $(window).trigger("resize");
568
            }).closest(".network").removeClass("expand");
569
            this.$(".empty-network-slot").hide();
570
        },
571

    
572
        // fix left border position
573
        fix_left_border: function() {
574
            if (!this.visible()) { return };
575
            var imgheight = 2783;
576
            var contents = this.$(".network-contents");
577
            var last_vm = this.$(".network-machine:last")
578
            var bgpos = imgheight - contents.height() + last_vm.height() - 30;
579
            this.$(".network-contents").css({'background-position':'33px ' + (-bgpos) + 'px'});
580
        },
581

    
582

    
583
        init_handlers: function() {
584
            var self = this;
585

    
586
            this.vms_list_toggler.click(_.bind(function(){
587
                if (this.vms_list.is(":visible")) {
588
                    this.hide_vm_list();
589
                } else {
590
                    this.show_vm_list();
591
                }
592

    
593
                this.check_empty_vms();
594
            }, this));
595

    
596
            this.$(".action-add").click(_.bind(function(e){
597
                e.preventDefault();
598
                this.show_connect_vms();
599
            }, this))
600

    
601
            this.$(".add-icon").click(_.bind(function(e){
602
                e.preventDefault();
603
                this.show_connect_vms();
604
            }, this))
605

    
606
            this.$(".net-actions .destroy a").click(_.bind(function(e){
607
                e.preventDefault();
608
                this.confirm_destroy();
609
            }, this));
610

    
611
            this.$(".net-actions button.no").click(function(e){
612
                e.preventDefault();
613
                var el = $(this);
614
                el.closest(".confirm_single").hide();
615
                el.parent().parent().find("a.selected").removeClass("selected");
616
            });
617

    
618
            this.$(".net-actions button.yes").click(function(e){
619
                e.preventDefault();
620
                var el = $(this);
621
                el.closest(".confirm_single").hide();
622
                el.parent().parent().find(".selected").removeClass("selected");
623
                self.network.remove(function(){
624
                    el.closest(".confirm_single").removeClass("in-progress");
625
                });
626
                el.closest(".confirm_single").addClass("in-progress");
627
            });
628

    
629
            snf.ui.main.bind("view:change", _.bind(function(v) {
630
                if (v == "networks" ){ return }
631
                this.$(".confirm_single").hide();
632
                this.$("a.selected").removeClass("selected");
633
            }, this));
634

    
635
            $(window).bind("resize", _.bind(function() {
636
                this.fix_left_border();
637
            }, this));
638
        },
639

    
640
        show_connect_vms: function() {
641
            this.$(".confirm_single").hide();
642
            this.$("a.selected").removeClass("selected");
643
            var vms = this.network.get_connectable_vms();
644
            this.parent_view.connect_machines_view.show_vms(this.network,
645
                                                            vms, [], 
646
                                                            _.bind(this.connect_vms, this));
647
        },
648

    
649
        confirm_destroy: function() {
650
            this.$(".destroy .confirm_single").show();
651
            this.$(".destroy a").addClass("selected");
652
        },
653

    
654
        connect_vms: function(vms) {
655
            _.each(vms, _.bind(function(vm){
656
                this.network.add_vm(vm);
657
            }, this));
658

    
659
            this.parent_view.connect_machines_view.hide();
660
        },
661

    
662
        create_el: function() {
663
            var el = this.$(this.tpl).clone().attr("id", "network-" + this.network.id)
664
            return el;
665
        },
666

    
667
        init_vm_handlers: function() {
668
            storage.vms.bind("add", _.bind(this.vm_added_handler, this, "add"));
669
            storage.vms.bind("network:connect", _.bind(this.vm_changed_handler, this, "connect"));
670
            storage.vms.bind("change", _.bind(this.vm_changed_handler, this, "change"));
671
            storage.vms.bind("reset", _.bind(this.vm_changed_handler, this, "reset"));
672
            storage.vms.bind("remove", _.bind(this.vm_removed_handler, this, "remove"));
673
            storage.vms.bind("network:disconnect", _.bind(this.vm_removed_handler, this, "disconnect"));
674
        },
675

    
676
        get_vm_id: function(vm) {
677
            return this.vm_id_tpl.format(this.network.id, vm.id)
678
        },
679

    
680
        vm: function(vm) {
681
            return $(this.get_vm_id(vm))
682
        },
683

    
684
        vm_added_handler: function(action, vm) {
685
            if (!this.network.contains_vm(vm)) { return }
686
            this.add_or_update_vm(vm);
687
            this.update_layout();
688
        },
689

    
690
        vm_changed_handler: function(action, vms, model, changes) {
691
            var vms = vms || [];
692
            // reset or change
693
            if (action == "reset") {
694
                vms = vms;
695
            } else {
696
                if (!_.isArray(vms)) {
697
                    vms = [vms]
698
                }
699
            }
700

    
701
            if (action == "connect") {
702
                vms = [model];
703
            }
704
            
705
            _.each(vms, _.bind(function(vm) {
706
                if (!this.network.contains_vm(vm)) { return }
707
                this.add_or_update_vm(vm);
708
            }, this));
709
            this.update_layout();
710
        },
711

    
712
        vm_removed_handler: function(action, vm, model) {
713
            if (action == "disconnect") { vm = model };
714
            this.remove_vm(vm);
715
            this.update_layout();
716
        },
717

    
718
        remove_vm: function(vm) {
719
            if (this.vm(vm).length) {
720
                this.vm(vm).remove();
721
                try {
722
                    delete this.vm_views[vm.id]
723
                } catch (err) {
724
                }
725
            }
726
        },
727
        
728
        create_vm: function(vm) {
729
            vm_el = $(this.vm_tpl).clone().attr({id:this.get_vm_id(vm).replace("#","")});
730
            this.vms_list.append(vm_el);
731
            this.post_vm_add(vm);
732

    
733
            if (!this.vm_views[vm.id]) {
734
                vm_view = this.vm_views[vm.id] = new views.NetworkVMView(vm, this, this.firewall, vm_el);
735
            }
736
        },
737

    
738
        add_or_update_vm: function(vm) {
739
            if (!vm || !this.network.contains_vm(vm)) { return };
740

    
741
            var vm_el = this.vm(vm);
742
            var vm_view = this.vm_views[vm.id];
743

    
744
            if (vm_el.length == 0) {
745
                this.create_vm(vm);
746
            }
747
            
748
            if (vm_view) { vm_view.update_layout() };
749

    
750
            this.update_vm(vm);
751
            this.post_vm_update(vm);
752
        },
753
        update_vm: function(vm){},
754
        post_vm_add: function(vm){},
755
        post_vm_update: function(vm){},
756

    
757
        update_vms: function(vms) {
758
            if (!vms) { vms = this.network.vms.list() };
759
            _.each(vms, _.bind(function(vm){
760
                this.add_or_update_vm(vm);
761
            }, this));
762
        },
763

    
764
        check_empty_vms: function() {
765
            if (this.network.vms.get().length == 0) {
766
                this.hide_vm_list();
767
            }
768
        },
769

    
770
        vms_empty: function() {
771
            return this.network.vms.get().length == 0;
772
        },
773

    
774
        remove: function() {
775
            $(this.el).remove();
776
        },
777

    
778
        update_layout: function() {
779
            // has vms ???
780
            this.check_empty_vms(this.network.vms.list());
781

    
782
            // is expanded ???
783
            //
784
            // whats the network status ???
785
            //
786
            this.$(".machines-count").text(this.network.vms.get().length);
787

    
788
            var net_name = this.network.get("name");
789
            if (net_name == "public") { net_name = "Internet" }
790
            this.$(".name-div span.name").text(net_name);
791

    
792
            if (this.rename_view) {
793
                this.rename_view.update_layout();
794
            }
795
            
796
            this.$(".net-status").text(this.network.state_message());
797

    
798
            if (this.network.in_progress())  {
799
                this.$(".spinner").show();
800
                this.$(".network-indicator").addClass("in-progress");
801
            } else {
802
                this.$(".spinner").hide();
803
                this.$(".network-indicator").removeClass("in-progress");
804
            }
805
        }
806
    })
807

    
808
    views.PublicNetworkView = views.NetworkModelView.extend({
809
        firewall: true,
810
        tpl: "#public-template",
811
        vm_tpl: "#public-machine-template",
812
        vm_id_tpl: "#network-{0}-vm-{1}",
813

    
814
        update_vm: function(vm) {
815
        }
816
    })
817
    
818
    views.PrivateNetworkView = views.NetworkModelView.extend({
819
        tpl: "#private-template",
820
        vm_tpl: "#private-machine-template",
821
        vm_id_tpl: "#network-{0}-vm-{1}"
822
    })
823

    
824
    views.NetworksView = views.View.extend({
825
        
826
        view_id: "networks",
827
        pane: "#networks-pane",
828
        el: "#networks-pane",
829

    
830
        initialize: function() {
831
            // elements shortcuts
832
            this.create_cont = this.$("#networks-createcontainer");
833
            this.container = this.$("#networks-container");
834
            this.public_list = this.$(".public-networks");
835
            this.private_list = this.$(".private-networks");
836

    
837
            views.NetworksView.__super__.initialize.call(this);
838
            this.init_handlers();
839
            this.network_views = {};
840
            this.update_networks(storage.networks.models);
841

    
842
            this.create_view = new views.NetworkCreateView();
843
            this.connect_machines_view = new views.NetworkConnectVMsOverlay();
844
        },
845
        
846
        exists: function(net) {
847
            return this.network_views[net.id];
848
        },
849

    
850
        add_or_update: function(net) {
851
            var nv = this.exists(net);
852
            if (!nv) {
853
                nv = this.create_network_view(net)
854
                this.network_views[net.id] = nv;
855
                
856
                if (net.is_public()) {
857
                    this.public_list.append(nv.el);
858
                    this.public_list.show();
859
                } else {
860
                    this.private_list.append(nv.el);
861
                    this.private_list.show();
862
                }
863
            }
864

    
865
            // update vms
866
            // for cases where network servers list
867
            // get updated after vm addition and
868
            // vm_added_handler fails to append the
869
            // vm to the list
870
            nv.update_vms();
871
            nv.update_layout();
872
        },
873
        
874
        create_network_view: function(net) {
875
            if (net.is_public()) {
876
                return new views.PublicNetworkView(net, this);
877
            }
878
            return new views.PrivateNetworkView(net, this);
879
        },
880
        
881
        init_handlers: function() {
882
            storage.networks.bind("add", _.bind(this.network_added_handler, this, "add"));
883
            storage.networks.bind("change", _.bind(this.network_changed_handler, this, "change"));
884
            storage.networks.bind("reset", _.bind(this.network_changed_handler, this, "reset"));
885
            storage.networks.bind("remove", _.bind(this.network_removed_handler, this, "remove"));
886

    
887
            this.$("#networkscreate").click(_.bind(function(e){
888
                e.preventDefault();
889
                this.create_view.show();
890
            }, this));
891
            
892
        },
893

    
894
        update_networks: function(nets) {
895
            _.each(nets, _.bind(function(net){
896
                if (net.get("status") == "DELETED") { return }
897
                view = this.add_or_update(net);
898
            }, this));
899
        },
900

    
901
        show: function() {
902
            this.container.show();
903
            $(this.el).show();
904
        },
905

    
906
        network_added_handler: function(type, net) {
907
            this.update_networks([net]);
908
        },
909

    
910
        network_changed_handler: function(type, models) {
911
            var nets = [];
912
            if (type == "change") {
913
                nets = [models]
914
            } else {
915
                nets = models.models;
916
            }
917

    
918
            this.update_networks(nets)
919
        },
920

    
921
        network_removed_handler: function(type, net) {
922
            this.remove_net(net)
923
            if (this.private_list.find(".network").length == 0) {
924
                this.private_list.hide();
925
            }
926
        },
927

    
928
        network_added: function(net) {
929
            return this.network_views[net.id];
930
        },
931

    
932
        get_network_view: function(net) {
933
            return this.network_views[net.id];
934
        },
935

    
936
        remove_net: function(net) {
937
            if (this.network_added(net)) {
938
                var view = this.get_network_view(net);
939
                view.remove();
940
                delete this.network_views[net.id];
941
            }
942
        },
943

    
944
        __update_layout: function() {
945
        }
946
    });
947

    
948
})(this);