Statistics
| Branch: | Tag: | Revision:

root / ui / static / snf / js / ui / web / ui_networks_view.js @ 7b389cf5

History | View | Annotate | Download (30.8 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
            this.vm_connect = this.$(".machine-connect");
234

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

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

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

    
269
                this.$(".remove-icon").click(_.bind(function(){
270
                    this.confirm_disconnect();
271
                }, this));
272

    
273
                this.vm_connect.click(_.bind(function() {
274
                    this.connect_overlay.show(this.vm);
275
                }, this));
276
            }
277
            
278
            var vm = this.vm;
279
            this.details.click(function(){
280
                snf.ui.main.show_vm_details(vm);
281
            })
282

    
283
        },
284

    
285
        confirm_disconnect: function() {
286
            this.confirm_el.show();
287
            this.disconnect.addClass("selected");
288
        },
289

    
290
        init_layout: function() {
291
            if (!this.firewall_controls) { return };
292
        },
293

    
294
        update_layout: function() {
295
            this.$(".vm-name").text(snf.util.truncate(this.vm.get("name"), 40));
296
            this.$("img.logo").attr("src", ui.helpers.vm_icon_path(this.vm, "medium"));
297

    
298
            if (this.firewall_view) {
299
                this.$(".ipv4-text").text(this.vm.get_addresses().ip4);
300
                this.$(".ipv6-text").text(this.vm.get_addresses().ip6);
301
            }
302

    
303
            if (this.firewall_view) {
304
                this.firewall_view.update_layout();
305
            }
306
        },
307

    
308
        disconnect_vm: function() {
309
            this.$("a.selected").removeClass("selected");
310
            this.parent.network.remove_vm(this.vm);
311
        },
312

    
313
        update_firewall_layout: function() {
314
        }
315

    
316

    
317
    })
318

    
319
    views.NetworkModelRenameView = views.View.extend({
320
        initialize: function(parent, network) {
321
            this.parent = parent;
322
            this.network = network;
323
            this.el = this.parent.el.find(".name-div");
324

    
325
            this.icon = this.$(".rename-network");
326
            this.save = this.$("span.save");
327
            this.cancel = this.$("span.cancel");
328
            this.buttons = this.$(".editbuttons");
329
            this.name = this.$("span.name");
330
            this.editing = false;
331
            this.init_handlers();
332
            this.update_layout();
333
        },
334

    
335
        init_handlers: function() {
336
            this.icon.click(_.bind(function(){
337
                this.editing = true;
338
                this.update_layout();
339
            }, this));
340
            this.cancel.click(_.bind(function(){
341
                this.editing = false;
342
                this.update_layout();
343
            }, this));
344
            this.save.click(_.bind(function(){
345
                this.submit();
346
            }, this))
347
        },
348
        
349
        submit: function() {
350
            var value = _(this.input.val()).trim();
351
            if (value == "") { return }
352

    
353
            this.network.rename(value, _.bind(function(){
354
                this.editing = false;
355
                this.update_layout();
356
            }, this));
357
        },
358

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

    
372
        remove_input: function() {
373
            if (!this.input) { return }
374
            this.input.remove();
375
        },
376

    
377
        update_layout: function() {
378
            if (this.editing) {
379
                if (this.buttons.is(":visible")) { return }
380
                this.icon.hide();
381
                this.buttons.show();
382
                this.create_input();
383
                this.name.hide();
384
            } else {
385
                this.buttons.hide();
386
                this.remove_input();
387
                this.name.show();
388
                this.icon.show();
389
            }
390
        }
391
    })
392

    
393
    views.FirewallEditView = views.View.extend({
394
        initialize: function(vm, network, parent) {
395
            this.parent = parent;
396
            this.vm = vm;
397
            this.network = network;
398
            this.el = this.parent.el;
399

    
400
            views.FirewallEditView.__super__.initialize.apply(this);
401

    
402
            // elements
403
            this.toggler = this.$(".firewall-toggle");
404
            this.indicator = this.$(".machines-label span");
405
            this.progress = this.$(".network-progress-indicator");
406
            this.content = this.$(".firewall-content");
407
            this.inputs = this.$("input[type=radio]");
408
            this.labels = this.$("span.checkbox-legends, label.checkbox-legends");
409
            this.apply = this.$(".firewall-apply");
410

    
411
            this.$(".firewall-content").hide();
412
            this.$(".firewall-content input[type=radio]").attr("name", "firewall-opt-for-{0}".format(this.vm.id))
413
            var mode = this.vm.firewall_profile(this.network.id);
414
            this.$(".firewall-content input[value={0}]".format(mode)).attr("checked", true);
415

    
416
            this.init_handlers();
417
            this.update_layout();
418
        },
419
        
420
        _get_selected: function() {
421
            return this.inputs.filter(":checked");
422
        },
423

    
424
        reset_selected: function() {
425
        },
426

    
427
        submit: function() {
428
        },
429

    
430
        reset_value: function() {
431
            this.inputs.filter("[value={0}]".format(this.vm.firewall_profile(this.network.id))).attr("checked");
432
        },
433

    
434
        init_handlers: function() {
435
            this.toggler.click(_.bind(function(){
436
                cont = this.content;
437
                if (cont.is(":visible")) {
438
                    this.hide_firewall();
439
                    this.reset_value();
440
                } else {
441
                    this.show_firewall();
442
                }
443

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

    
464
            this.inputs.change(_.bind(function(){
465
                this.update_selected();
466
            }, this))
467
            
468
            var self = this;
469
            this.$(".checkbox-legends").click(function(el) {
470
                var el = $(this);
471
                el.prev().click();
472
                self.update_selected();
473
            })
474
        },
475

    
476
        update_selected: function() {
477
            this.update_layout();
478
        },
479

    
480
        show_firewall: function() {
481
            this.content.slideDown(100, function(){$(window).trigger("resize")});
482
            this.toggler.addClass("open");
483
        },
484

    
485
        hide_firewall: function() {
486
            this.content.slideUp(100, function(){$(window).trigger("resize")});
487
            this.toggler.removeClass("open");
488
        },
489

    
490
        value: function() {
491
            return this._get_selected().val();
492
        },
493

    
494
        update_layout: function() {
495
            if (this.value() == this.vm.firewall_profile(this.network.id)) {
496
                this.apply.hide();
497
            } else {
498
                this.apply.show();
499
            }
500

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

    
515
            var firewalling = this.vm.firewall_pending(this.network.id);
516
            var el = this.el;
517
            
518
            if (firewalling) {
519
                el.find("button").addClass("in-progress").show();
520
                el.find(".network-progress-indicator").show();
521
            } else {
522
                el.find("button").removeClass("in-progress");
523
                el.find(".network-progress-indicator").hide();
524
            }
525
        }
526
    })
527

    
528
    views.NetworkModelView = views.View.extend({
529
        
530
        firewall: false,
531

    
532
        initialize: function(network, view) {
533
            this.parent_view = view;
534
            this.network = network;
535
            this.is_public = network.is_public();
536

    
537
            this.init_vm_handlers();
538

    
539
            this.view_id = "networks_view_" + network.id;
540
            views.NetworkModelView.__super__.initialize.call(this);
541

    
542
            this.vm_views = {};
543

    
544
            this.el = this.create_el();
545

    
546
            // element helpers
547
            this.vms_list = this.$(".machines-list");
548
            this.vms_list_toggler = this.$(".list-toggle");
549
            
550
            this.init_handlers();
551
            this.update_vms();
552
            this.update_layout();
553

    
554
            this.hide_vm_list();
555
            this.vms_list.hide();
556

    
557
            this.rename_view = undefined;
558
            if (!this.network.is_public()) {
559
                this.rename_view = new views.NetworkModelRenameView(this, network);
560
            }
561
        },
562

    
563
        show_vm_list: function() {
564
            if (this.vms_empty()) { return }
565
            this.vms_list_toggler.addClass("open");
566
            this.vms_list.slideDown(function(){
567
                $(window).trigger("resize");
568
            }).closest(".network").addClass("expand");
569
            this.$(".empty-network-slot").show();
570
        },
571

    
572
        hide_vm_list: function() {
573
            this.vms_list_toggler.removeClass("open");
574
            this.vms_list.slideUp(function(){
575
                $(window).trigger("resize");
576
            }).closest(".network").removeClass("expand");
577
            this.$(".empty-network-slot").hide();
578
        },
579

    
580
        // fix left border position
581
        fix_left_border: function() {
582
            if (!this.visible()) { return };
583
            var imgheight = 2783;
584
            if (!this.is_public) { imgheight = 2700 };
585
            var contents = this.$(".network-contents");
586
            var last_vm = this.$(".network-machine:last")
587
            var bgpos = imgheight - contents.height() + last_vm.height() - 30;
588
            this.$(".network-contents").css({'background-position':'33px ' + (-bgpos) + 'px'});
589
        },
590

    
591

    
592
        init_handlers: function() {
593
            var self = this;
594

    
595
            this.vms_list_toggler.click(_.bind(function(){
596
                if (this.vms_list.is(":visible")) {
597
                    this.hide_vm_list();
598
                } else {
599
                    this.show_vm_list();
600
                }
601

    
602
                this.check_empty_vms();
603
            }, this));
604

    
605
            this.$(".action-add").click(_.bind(function(e){
606
                e.preventDefault();
607
                this.show_connect_vms();
608
            }, this))
609

    
610
            this.$(".add-icon").click(_.bind(function(e){
611
                e.preventDefault();
612
                this.show_connect_vms();
613
            }, this))
614

    
615
            this.$(".net-actions .destroy a").click(_.bind(function(e){
616
                e.preventDefault();
617
                this.confirm_destroy();
618
            }, this));
619

    
620
            this.$(".net-actions button.no").click(function(e){
621
                e.preventDefault();
622
                var el = $(this);
623
                el.closest(".confirm_single").hide();
624
                el.parent().parent().find("a.selected").removeClass("selected");
625
            });
626

    
627
            this.$(".net-actions button.yes").click(function(e){
628
                e.preventDefault();
629
                var el = $(this);
630
                el.closest(".confirm_single").hide();
631
                el.parent().parent().find(".selected").removeClass("selected");
632
                self.network.remove(function(){
633
                    el.closest(".confirm_single").removeClass("in-progress");
634
                });
635
                el.closest(".confirm_single").addClass("in-progress");
636
            });
637

    
638
            snf.ui.main.bind("view:change", _.bind(function(v) {
639
                if (v == "networks" ){ return }
640
                this.$(".confirm_single").hide();
641
                this.$("a.selected").removeClass("selected");
642
            }, this));
643

    
644
            $(window).bind("resize", _.bind(function() {
645
                this.fix_left_border();
646
            }, this));
647
        },
648

    
649
        show_connect_vms: function() {
650
            this.$(".confirm_single").hide();
651
            this.$("a.selected").removeClass("selected");
652
            var vms = this.network.get_connectable_vms();
653
            this.parent_view.connect_machines_view.show_vms(this.network,
654
                                                            vms, [], 
655
                                                            _.bind(this.connect_vms, this));
656
        },
657

    
658
        confirm_destroy: function() {
659
            this.$(".destroy .confirm_single").show();
660
            this.$(".destroy a").addClass("selected");
661
        },
662

    
663
        connect_vms: function(vms) {
664
            _.each(vms, _.bind(function(vm){
665
                this.network.add_vm(vm);
666
            }, this));
667

    
668
            this.parent_view.connect_machines_view.hide();
669
        },
670

    
671
        create_el: function() {
672
            var el = this.$(this.tpl).clone().attr("id", "network-" + this.network.id)
673
            return el;
674
        },
675

    
676
        init_vm_handlers: function() {
677
            storage.vms.bind("add", _.bind(this.vm_added_handler, this, "add"));
678
            storage.vms.bind("network:connect", _.bind(this.vm_changed_handler, this, "connect"));
679
            storage.vms.bind("change", _.bind(this.vm_changed_handler, this, "change"));
680
            storage.vms.bind("reset", _.bind(this.vm_changed_handler, this, "reset"));
681
            storage.vms.bind("remove", _.bind(this.vm_removed_handler, this, "remove"));
682
            storage.vms.bind("network:disconnect", _.bind(this.vm_removed_handler, this, "disconnect"));
683
        },
684

    
685
        get_vm_id: function(vm) {
686
            return this.vm_id_tpl.format(this.network.id, vm.id)
687
        },
688

    
689
        vm: function(vm) {
690
            return $(this.get_vm_id(vm))
691
        },
692

    
693
        vm_added_handler: function(action, vm) {
694
            if (!this.network.contains_vm(vm)) { return }
695
            this.add_or_update_vm(vm);
696
            this.fix_left_border();
697
            this.update_layout();
698
        },
699

    
700
        vm_changed_handler: function(action, vms, model, changes) {
701
            var vms = vms || [];
702
            // reset or change
703
            if (action == "reset") {
704
                vms = vms;
705
            } else {
706
                if (!_.isArray(vms)) {
707
                    vms = [vms]
708
                }
709
            }
710

    
711
            if (action == "connect") {
712
                vms = [model];
713
            }
714
            
715
            _.each(vms, _.bind(function(vm) {
716
                if (!this.network.contains_vm(vm)) { return }
717
                this.add_or_update_vm(vm);
718
            }, this));
719
            this.update_layout();
720
        },
721

    
722
        vm_removed_handler: function(action, vm, model) {
723
            if (action == "disconnect") { vm = model };
724
            this.remove_vm(vm);
725
            this.update_layout();
726
        },
727

    
728
        remove_vm: function(vm) {
729
            if (this.vm(vm).length) {
730
                this.vm(vm).remove();
731
                try {
732
                    delete this.vm_views[vm.id]
733
                } catch (err) {
734
                }
735
            }
736
        },
737
        
738
        create_vm: function(vm) {
739
            vm_el = $(this.vm_tpl).clone().attr({id:this.get_vm_id(vm).replace("#","")});
740
            this.vms_list.append(vm_el);
741
            this.post_vm_add(vm);
742

    
743
            if (!this.vm_views[vm.id]) {
744
                vm_view = this.vm_views[vm.id] = new views.NetworkVMView(vm, this, this.firewall, vm_el);
745
            }
746
        },
747

    
748
        add_or_update_vm: function(vm) {
749
            if (!vm || !this.network.contains_vm(vm)) { return };
750

    
751
            var vm_el = this.vm(vm);
752
            var vm_view = this.vm_views[vm.id];
753

    
754
            if (vm_el.length == 0) {
755
                this.create_vm(vm);
756
            }
757
            
758
            if (vm_view) { vm_view.update_layout() };
759

    
760
            this.update_vm(vm);
761
            this.post_vm_update(vm);
762
        },
763
        update_vm: function(vm){},
764
        post_vm_add: function(vm){},
765
        post_vm_update: function(vm){},
766

    
767
        update_vms: function(vms) {
768
            if (!vms) { vms = this.network.vms.list() };
769
            _.each(vms, _.bind(function(vm){
770
                this.add_or_update_vm(vm);
771
            }, this));
772
        },
773

    
774
        check_empty_vms: function() {
775
            if (this.network.vms.get().length == 0) {
776
                this.hide_vm_list();
777
            }
778
        },
779

    
780
        vms_empty: function() {
781
            return this.network.vms.get().length == 0;
782
        },
783

    
784
        remove: function() {
785
            $(this.el).remove();
786
        },
787

    
788
        update_layout: function() {
789
            // has vms ???
790
            this.check_empty_vms(this.network.vms.list());
791

    
792
            // is expanded ???
793
            //
794
            // whats the network status ???
795
            //
796
            this.$(".machines-count").text(this.network.vms.get().length);
797

    
798
            var net_name = this.network.get("name");
799
            if (net_name == "public") { net_name = "Internet" }
800
            this.$(".name-div span.name").text(net_name);
801

    
802
            if (this.rename_view) {
803
                this.rename_view.update_layout();
804
            }
805
            
806
            this.$(".net-status").text(this.network.state_message());
807

    
808
            if (this.network.in_progress())  {
809
                this.$(".spinner").show();
810
                this.$(".network-indicator").addClass("in-progress");
811
            } else {
812
                this.$(".spinner").hide();
813
                this.$(".network-indicator").removeClass("in-progress");
814
            }
815
        }
816
    })
817

    
818
    views.PublicNetworkView = views.NetworkModelView.extend({
819
        firewall: true,
820
        tpl: "#public-template",
821
        vm_tpl: "#public-machine-template",
822
        vm_id_tpl: "#network-{0}-vm-{1}",
823

    
824
        update_vm: function(vm) {
825
        }
826
    })
827
    
828
    views.PrivateNetworkView = views.NetworkModelView.extend({
829
        tpl: "#private-template",
830
        vm_tpl: "#private-machine-template",
831
        vm_id_tpl: "#network-{0}-vm-{1}"
832
    })
833

    
834
    views.NetworksView = views.View.extend({
835
        
836
        view_id: "networks",
837
        pane: "#networks-pane",
838
        el: "#networks-pane",
839

    
840
        initialize: function() {
841
            // elements shortcuts
842
            this.create_cont = this.$("#networks-createcontainer");
843
            this.container = this.$("#networks-container");
844
            this.public_list = this.$(".public-networks");
845
            this.private_list = this.$(".private-networks");
846

    
847
            views.NetworksView.__super__.initialize.call(this);
848
            this.init_handlers();
849
            this.network_views = {};
850
            this.update_networks(storage.networks.models);
851

    
852
            this.create_view = new views.NetworkCreateView();
853
            this.connect_machines_view = new views.NetworkConnectVMsOverlay();
854
        },
855
        
856
        exists: function(net) {
857
            return this.network_views[net.id];
858
        },
859

    
860
        add_or_update: function(net) {
861
            var nv = this.exists(net);
862
            if (!nv) {
863
                nv = this.create_network_view(net)
864
                this.network_views[net.id] = nv;
865
                
866
                if (net.is_public()) {
867
                    this.public_list.append(nv.el);
868
                    this.public_list.show();
869
                } else {
870
                    this.private_list.append(nv.el);
871
                    this.private_list.show();
872
                }
873
            }
874

    
875
            // update vms
876
            // for cases where network servers list
877
            // get updated after vm addition and
878
            // vm_added_handler fails to append the
879
            // vm to the list
880
            nv.update_vms();
881
            nv.update_layout();
882
        },
883
        
884
        create_network_view: function(net) {
885
            if (net.is_public()) {
886
                return new views.PublicNetworkView(net, this);
887
            }
888
            return new views.PrivateNetworkView(net, this);
889
        },
890
        
891
        init_handlers: function() {
892
            storage.networks.bind("add", _.bind(this.network_added_handler, this, "add"));
893
            storage.networks.bind("change", _.bind(this.network_changed_handler, this, "change"));
894
            storage.networks.bind("reset", _.bind(this.network_changed_handler, this, "reset"));
895
            storage.networks.bind("remove", _.bind(this.network_removed_handler, this, "remove"));
896

    
897
            this.$("#networkscreate").click(_.bind(function(e){
898
                e.preventDefault();
899
                this.create_view.show();
900
            }, this));
901
            
902
        },
903

    
904
        update_networks: function(nets) {
905
            _.each(nets, _.bind(function(net){
906
                if (net.get("status") == "DELETED") { return }
907
                view = this.add_or_update(net);
908
            }, this));
909
        },
910

    
911
        show: function() {
912
            this.container.show();
913
            $(this.el).show();
914
        },
915

    
916
        network_added_handler: function(type, net) {
917
            this.update_networks([net]);
918
        },
919

    
920
        network_changed_handler: function(type, models) {
921
            var nets = [];
922
            if (type == "change") {
923
                nets = [models]
924
            } else {
925
                nets = models.models;
926
            }
927

    
928
            this.update_networks(nets)
929
        },
930

    
931
        network_removed_handler: function(type, net) {
932
            this.remove_net(net)
933
            if (this.private_list.find(".network").length == 0) {
934
                this.private_list.hide();
935
            }
936
        },
937

    
938
        network_added: function(net) {
939
            return this.network_views[net.id];
940
        },
941

    
942
        get_network_view: function(net) {
943
            return this.network_views[net.id];
944
        },
945

    
946
        remove_net: function(net) {
947
            if (this.network_added(net)) {
948
                var view = this.get_network_view(net);
949
                view.remove();
950
                delete this.network_views[net.id];
951
            }
952
        },
953

    
954
        __update_layout: function() {
955
        }
956
    });
957

    
958
})(this);