Statistics
| Branch: | Tag: | Revision:

root / ui / static / snf / js / ui / web / ui_networks_view.js @ 8c923194

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
276
        },
277

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

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

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

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

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

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

    
306
        update_firewall_layout: function() {
307
        }
308

    
309

    
310
    })
311

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

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

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

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

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

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

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

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

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

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

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

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

    
417
        reset_selected: function() {
418
        },
419

    
420
        submit: function() {
421
        },
422

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

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

    
437
                $(window).trigger("resize");
438
            }, this))
439

    
440
            this.apply.click(_.bind(function(){
441
                this.apply.addClass("in-progress");
442
                this.vm.set_firewall(this.network.id, this.value(), _.bind(function() {
443
                }, this));
444
                this.hide_firewall();
445
            }, this))
446

    
447
            this.inputs.change(_.bind(function(){
448
                this.update_selected();
449
            }, this))
450
            
451
            var self = this;
452
            this.$(".checkbox-legends").click(function(el) {
453
                var el = $(this);
454
                el.prev().click();
455
                self.update_selected();
456
            })
457
        },
458

    
459
        update_selected: function() {
460
            this.update_layout();
461
        },
462

    
463
        show_firewall: function() {
464
            this.content.slideDown(100, function(){$(window).trigger("resize")});
465
            this.toggler.addClass("open");
466
        },
467

    
468
        hide_firewall: function() {
469
            this.content.slideUp(100, function(){$(window).trigger("resize")});
470
            this.toggler.removeClass("open");
471
        },
472

    
473
        value: function() {
474
            return this._get_selected().val();
475
        },
476

    
477
        update_layout: function() {
478
            if (this.value() == this.vm.firewall_profile(this.network.id)) {
479
                this.apply.hide();
480
            } else {
481
                this.apply.show();
482
            }
483

    
484
            profile = this.vm.firewall_profile(this.network.id);
485
            if (this.vm.has_firewall(this.network.id)) {
486
                this.$(".firewall-toggle .label span").text("On");
487
                this.$(".firewall-toggle .label span").removeClass("firewall-off");
488
                this.$(".firewall-toggle .label span").addClass("firewall-on");
489
            } else {
490
                this.$(".firewall-toggle .label span").text("Off");
491
                this.$(".firewall-toggle .label span").removeClass("firewall-on");
492
                this.$(".firewall-toggle .label span").addClass("firewall-off");
493
            }
494
            
495
            this.$("span.checkbox-legends").removeClass("current");
496
            this.inputs.filter("[value={0}]".format(this.vm.firewall_profile(this.network.id))).next().addClass("current");
497

    
498
            var firewalling = this.vm.firewall_pending(this.network.id);
499
            var el = this.el;
500
            
501
            if (firewalling) {
502
                el.find("button").addClass("in-progress").show();
503
                el.find(".network-progress-indicator").show();
504
            } else {
505
                el.find("button").removeClass("in-progress");
506
                el.find(".network-progress-indicator").hide();
507
            }
508
        }
509
    })
510

    
511
    views.NetworkModelView = views.View.extend({
512
        
513
        firewall: false,
514

    
515
        initialize: function(network, view) {
516
            this.parent_view = view;
517
            this.network = network;
518
            this.init_vm_handlers();
519

    
520
            this.id = "networks_view_" + network.id;
521
            views.NetworkModelView.__super__.initialize.call(this);
522

    
523
            this.vm_views = {};
524

    
525
            this.el = this.create_el();
526

    
527
            // element helpers
528
            this.vms_list = this.$(".machines-list");
529
            this.vms_list_toggler = this.$(".list-toggle");
530
            
531
            this.init_handlers();
532
            this.update_vms();
533
            this.update_layout();
534

    
535
            this.hide_vm_list();
536
            this.vms_list.hide();
537

    
538
            this.rename_view = undefined;
539
            if (!this.network.is_public()) {
540
                this.rename_view = new views.NetworkModelRenameView(this, network);
541
            }
542
        },
543

    
544
        show_vm_list: function() {
545
            if (this.vms_empty()) { return }
546
            this.vms_list_toggler.addClass("open");
547
            this.vms_list.slideDown(function(){
548
                $(window).trigger("resize");
549
            }).closest(".network").addClass("expand");
550
            this.$(".empty-network-slot").show();
551
        },
552

    
553
        hide_vm_list: function() {
554
            this.vms_list_toggler.removeClass("open");
555
            this.vms_list.slideUp(function(){
556
                $(window).trigger("resize");
557
            }).closest(".network").removeClass("expand");
558
            this.$(".empty-network-slot").hide();
559
        },
560

    
561
        // fix left border position
562
        fix_left_border: function() {
563
            var imgheight = 2783;
564
            var contents = this.$(".network-contents");
565
            var last_vm = this.$(".network-machine:last")
566
            var bgpos = imgheight - contents.height() + last_vm.height() - 30;
567
            this.$(".network-contents").css({'background-position':'33px ' + (-bgpos) + 'px'});
568
        },
569

    
570

    
571
        init_handlers: function() {
572
            var self = this;
573

    
574
            this.vms_list_toggler.click(_.bind(function(){
575
                if (this.vms_list.is(":visible")) {
576
                    this.hide_vm_list();
577
                } else {
578
                    this.show_vm_list();
579
                }
580

    
581
                this.check_empty_vms();
582
            }, this));
583

    
584
            this.$(".action-add").click(_.bind(function(e){
585
                e.preventDefault();
586
                this.show_connect_vms();
587
            }, this))
588

    
589
            this.$(".add-icon").click(_.bind(function(e){
590
                e.preventDefault();
591
                this.show_connect_vms();
592
            }, this))
593

    
594
            this.$(".net-actions .destroy a").click(_.bind(function(e){
595
                e.preventDefault();
596
                this.confirm_destroy();
597
            }, this));
598

    
599
            this.$(".net-actions button.no").click(function(e){
600
                e.preventDefault();
601
                var el = $(this);
602
                el.closest(".confirm_single").hide();
603
                el.parent().parent().find("a.selected").removeClass("selected");
604
            });
605

    
606
            this.$(".net-actions button.yes").click(function(e){
607
                e.preventDefault();
608
                var el = $(this);
609
                el.closest(".confirm_single").hide();
610
                el.parent().parent().find(".selected").removeClass("selected");
611
                self.network.remove(function(){
612
                    el.closest(".confirm_single").removeClass("in-progress");
613
                });
614
                el.closest(".confirm_single").addClass("in-progress");
615
            });
616

    
617
            snf.ui.main.bind("view:change", _.bind(function(v) {
618
                if (v == "networks" ){ return }
619
                this.$(".confirm_single").hide();
620
                this.$("a.selected").removeClass("selected");
621
            }, this));
622

    
623
            $(window).bind("resize", _.bind(function() {
624
                this.fix_left_border();
625
            }, this));
626
        },
627

    
628
        show_connect_vms: function() {
629
            this.$(".confirm_single").hide();
630
            this.$("a.selected").removeClass("selected");
631
            var vms = this.network.get_connectable_vms();
632
            this.parent_view.connect_machines_view.show_vms(this.network,
633
                                                            vms, [], 
634
                                                            _.bind(this.connect_vms, this));
635
        },
636

    
637
        confirm_destroy: function() {
638
            this.$(".destroy .confirm_single").show();
639
            this.$(".destroy a").addClass("selected");
640
        },
641

    
642
        connect_vms: function(vms) {
643
            _.each(vms, _.bind(function(vm){
644
                this.network.add_vm(vm);
645
            }, this));
646

    
647
            this.parent_view.connect_machines_view.hide();
648
        },
649

    
650
        create_el: function() {
651
            var el = this.$(this.tpl).clone().attr("id", "network-" + this.network.id)
652
            return el;
653
        },
654

    
655
        init_vm_handlers: function() {
656
            storage.vms.bind("add", _.bind(this.vm_added_handler, this, "add"));
657
            storage.vms.bind("network:connect", _.bind(this.vm_changed_handler, this, "connect"));
658
            storage.vms.bind("change", _.bind(this.vm_changed_handler, this, "change"));
659
            storage.vms.bind("reset", _.bind(this.vm_changed_handler, this, "reset"));
660
            storage.vms.bind("remove", _.bind(this.vm_removed_handler, this, "remove"));
661
            storage.vms.bind("network:disconnect", _.bind(this.vm_removed_handler, this, "disconnect"));
662
        },
663

    
664
        get_vm_id: function(vm) {
665
            return this.vm_id_tpl.format(this.network.id, vm.id)
666
        },
667

    
668
        vm: function(vm) {
669
            return $(this.get_vm_id(vm))
670
        },
671

    
672
        vm_added_handler: function(action, vm) {
673
            if (!this.network.contains_vm(vm)) { return }
674
            this.add_or_update_vm(vm);
675
            this.update_layout();
676
        },
677

    
678
        vm_changed_handler: function(action, vms, model, changes) {
679
            var vms = vms || [];
680
            // reset or change
681
            if (action == "reset") {
682
                vms = vms;
683
            } else {
684
                if (!_.isArray(vms)) {
685
                    vms = [vms]
686
                }
687
            }
688

    
689
            if (action == "connect") {
690
                vms = [model];
691
            }
692
            
693
            _.each(vms, _.bind(function(vm) {
694
                if (!this.network.contains_vm(vm)) { return }
695
                this.add_or_update_vm(vm);
696
            }, this));
697
            this.update_layout();
698
        },
699

    
700
        vm_removed_handler: function(action, vm, model) {
701
            if (action == "disconnect") { vm = model };
702
            this.remove_vm(vm);
703
            this.update_layout();
704
        },
705

    
706
        remove_vm: function(vm) {
707
            if (this.vm(vm).length) {
708
                this.vm(vm).remove();
709
                try {
710
                    delete this.vm_views[vm.id]
711
                } catch (err) {
712
                }
713
            }
714
        },
715
        
716
        create_vm: function(vm) {
717
            vm_el = $(this.vm_tpl).clone().attr({id:this.get_vm_id(vm).replace("#","")});
718
            this.vms_list.append(vm_el);
719
            this.post_vm_add(vm);
720

    
721
            if (!this.vm_views[vm.id]) {
722
                vm_view = this.vm_views[vm.id] = new views.NetworkVMView(vm, this, this.firewall, vm_el);
723
            }
724
        },
725

    
726
        add_or_update_vm: function(vm) {
727
            if (!vm || !this.network.contains_vm(vm)) { return };
728

    
729
            var vm_el = this.vm(vm);
730
            var vm_view = this.vm_views[vm.id];
731

    
732
            if (vm_el.length == 0) {
733
                this.create_vm(vm);
734
            }
735
            
736
            if (vm_view) { vm_view.update_layout() };
737

    
738
            this.update_vm(vm);
739
            this.post_vm_update(vm);
740
        },
741
        update_vm: function(vm){},
742
        post_vm_add: function(vm){},
743
        post_vm_update: function(vm){},
744

    
745
        update_vms: function(vms) {
746
            if (!vms) { vms = this.network.vms.list() };
747
            _.each(vms, _.bind(function(vm){
748
                this.add_or_update_vm(vm);
749
            }, this));
750
        },
751

    
752
        check_empty_vms: function() {
753
            if (this.network.vms.get().length == 0) {
754
                this.hide_vm_list();
755
            }
756
        },
757

    
758
        vms_empty: function() {
759
            return this.network.vms.get().length == 0;
760
        },
761

    
762
        remove: function() {
763
            $(this.el).remove();
764
        },
765

    
766
        update_layout: function() {
767
            // has vms ???
768
            this.check_empty_vms(this.network.vms.list());
769

    
770
            // is expanded ???
771
            //
772
            // whats the network status ???
773
            //
774
            this.$(".machines-count").text(this.network.vms.get().length);
775

    
776
            var net_name = this.network.get("name");
777
            if (net_name == "public") { net_name = "Internet" }
778
            this.$(".name-div span.name").text(net_name);
779

    
780
            if (this.rename_view) {
781
                this.rename_view.update_layout();
782
            }
783
            
784
            this.$(".net-status").text(this.network.state_message());
785

    
786
            if (this.network.in_progress())  {
787
                this.$(".spinner").show();
788
                this.$(".network-indicator").addClass("in-progress");
789
            } else {
790
                this.$(".spinner").hide();
791
                this.$(".network-indicator").removeClass("in-progress");
792
            }
793
        }
794
    })
795

    
796
    views.PublicNetworkView = views.NetworkModelView.extend({
797
        firewall: true,
798
        tpl: "#public-template",
799
        vm_tpl: "#public-machine-template",
800
        vm_id_tpl: "#network-{0}-vm-{1}",
801

    
802
        update_vm: function(vm) {
803
        }
804
    })
805
    
806
    views.PrivateNetworkView = views.NetworkModelView.extend({
807
        tpl: "#private-template",
808
        vm_tpl: "#private-machine-template",
809
        vm_id_tpl: "#network-{0}-vm-{1}"
810
    })
811

    
812
    views.NetworksView = views.View.extend({
813
        
814
        view_id: "networks",
815
        pane: "#networks-pane",
816
        el: "#networks-pane",
817

    
818
        initialize: function() {
819
            // elements shortcuts
820
            this.create_cont = this.$("#networks-createcontainer");
821
            this.container = this.$("#networks-container");
822
            this.public_list = this.$(".public-networks");
823
            this.private_list = this.$(".private-networks");
824

    
825
            views.NetworksView.__super__.initialize.call(this);
826
            this.init_handlers();
827
            this.network_views = {};
828
            this.update_networks(storage.networks.models);
829

    
830
            this.create_view = new views.NetworkCreateView();
831
            this.connect_machines_view = new views.NetworkConnectVMsOverlay();
832
        },
833
        
834
        exists: function(net) {
835
            return this.network_views[net.id];
836
        },
837

    
838
        add_or_update: function(net) {
839
            var nv = this.exists(net);
840
            if (!nv) {
841
                nv = this.create_network_view(net)
842
                this.network_views[net.id] = nv;
843
                
844
                if (net.is_public()) {
845
                    this.public_list.append(nv.el);
846
                    this.public_list.show();
847
                } else {
848
                    this.private_list.append(nv.el);
849
                    this.private_list.show();
850
                }
851
            }
852

    
853
            // update vms
854
            // for cases where network servers list
855
            // get updated after vm addition and
856
            // vm_added_handler fails to append the
857
            // vm to the list
858
            nv.update_vms();
859
            nv.update_layout();
860
        },
861
        
862
        create_network_view: function(net) {
863
            if (net.is_public()) {
864
                return new views.PublicNetworkView(net, this);
865
            }
866
            return new views.PrivateNetworkView(net, this);
867
        },
868
        
869
        init_handlers: function() {
870
            storage.networks.bind("add", _.bind(this.network_added_handler, this, "add"));
871
            storage.networks.bind("change", _.bind(this.network_changed_handler, this, "change"));
872
            storage.networks.bind("reset", _.bind(this.network_changed_handler, this, "reset"));
873
            storage.networks.bind("remove", _.bind(this.network_removed_handler, this, "remove"));
874

    
875
            this.$("#networkscreate").click(_.bind(function(e){
876
                e.preventDefault();
877
                this.create_view.show();
878
            }, this));
879
            
880
        },
881

    
882
        update_networks: function(nets) {
883
            _.each(nets, _.bind(function(net){
884
                if (net.get("status") == "DELETED") { return }
885
                view = this.add_or_update(net);
886
            }, this));
887
        },
888

    
889
        show: function() {
890
            this.container.show();
891
            $(this.el).show();
892
        },
893

    
894
        network_added_handler: function(type, net) {
895
            this.update_networks([net]);
896
        },
897

    
898
        network_changed_handler: function(type, models) {
899
            var nets = [];
900
            if (type == "change") {
901
                nets = [models]
902
            } else {
903
                nets = models.models;
904
            }
905

    
906
            this.update_networks(nets)
907
        },
908

    
909
        network_removed_handler: function(type, net) {
910
            this.remove_net(net)
911
            if (this.private_list.find(".network").length == 0) {
912
                this.private_list.hide();
913
            }
914
        },
915

    
916
        network_added: function(net) {
917
            return this.network_views[net.id];
918
        },
919

    
920
        get_network_view: function(net) {
921
            return this.network_views[net.id];
922
        },
923

    
924
        remove_net: function(net) {
925
            if (this.network_added(net)) {
926
                var view = this.get_network_view(net);
927
                view.remove();
928
                delete this.network_views[net.id];
929
            }
930
        },
931

    
932
        __update_layout: function() {
933
        }
934
    });
935

    
936
})(this);