Statistics
| Branch: | Tag: | Revision:

root / ui / static / snf / js / ui / web / ui_main_view.js @ 8d08f18a

History | View | Annotate | Download (27.5 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

    
12
    var views = snf.views = snf.views || {}
13

    
14
    // shortcuts
15
    var bb = root.Backbone;
16
    var util = snf.util;
17
    
18
    views.ErrorView = views.Overlay.extend({
19
        
20
        view_id: "error_view",
21
        content_selector: "#error-overlay-content",
22
        css_class: 'overlay-error',
23
        overlay_id: "error-overlay",
24

    
25
        initialize: function() {
26
            views.ErrorView.__super__.initialize.apply(this, arguments);
27
            var self = this;
28

    
29
            this.error_state = false;
30

    
31
            this.$(".actions .show-details, .actions .hide-details").click(function() {
32
                self.$(".error-details").toggle();
33
                self.$(".show-details").toggle();
34
                self.$(".hide-details").toggle();
35
            });
36

    
37
            this.$(".key.details").click(function() {
38
                $(this).next().toggle();
39
                if (!$(this).next().is(":visible")) {
40
                    $(this).addClass("expand");
41
                } else {
42
                    $(this).removeClass("expand");
43
                }
44
            })
45

    
46
            this.$(".actions .report-error").click(_.bind(function() {
47
                this.report_error();
48
            }, this));
49

    
50
            this.$(".actions .hide-details").hide();
51

    
52
            this.$(".reload-app").click(function(){
53
                window.location.reload(true);
54
            })
55
        },
56

    
57
        error_object: function() {
58
            return {ns:this.ns, code:this.code, message:this.message, details:this.details};
59
        },
60

    
61
        report_error: function() {
62
            this.feedback_view = this.feedback_view || ui.main.feedback_view;
63
            this.feedback_view.show(this.get_report_message(), true, {error: this.error_object()});
64
        },
65

    
66
        get_report_message: function() {
67
            var fdb_msg =   "Error report\n" +
68
                "-------------------" + "\n" +
69
                "Code: " + this.code + "\n" + 
70
                "Type: " + this.type + "\n" +
71
                "Message: " + this.message + "\n" +
72
                "Module: " + this.ns + "\n" +
73
                "Details: " + this.details + "\n\n" +
74
                "Please describe the actions that triggered the error:\n"
75
            
76
            return fdb_msg;
77
        },
78

    
79
        show_error: function(ns, code, message, type, details, error_options) {
80
            this.error_options = {'allow_report': true, 'allow_reload': true, 'extra_details': {}, 'non_critical': false};
81

    
82
            if (error_options) {
83
                this.error_options = _.extend(this.error_options, error_options);
84
            }
85

    
86
            this.hide();
87

    
88
            this.code = code;
89
            this.ns = ns;
90
            this.type = type;
91
            this.details = details ? (details.toString ? details.toString() : details) : undefined;
92
            this.message = message;
93

    
94
            this.update_details();
95
            
96
            if (error_options.non_critical) {
97
                this.el.addClass("non-critical");
98
            } else {
99
                this.el.removeClass("non-critical");
100
            }
101

    
102
            this.show();
103
            
104
            this.$(".actions .show-details").click();
105
            this.$(".key.details").click();
106
            this.$(".error-more-details").hide();
107
        },
108

    
109
        update_details: function() {
110
            var title = "Application error";
111
            if (this.ns && this.type) {
112
                title = this.type + ": " + this.message;
113
            }
114
            this.$(".header .title").text(title);
115
            this.$(".error-code").text(this.code || "");
116
            this.$(".error-type").text(this.type || "");
117
            this.$(".error-module").text(this.ns || "");
118
            this.$(".message p").text(this.message || "");
119
            this.$(".error-more-details p").html(this.details || "no info");
120

    
121
            this.$(".extra-details").remove();
122
            _.each(this.error_options.extra_details, function(value, key){
123
                var opt = $(('<span class="extra-details key">{0}</span>' +
124
                            '<span class="extra-details value">{1}</span>').format(key, value))
125
                this.$(".value.error-type").after(opt);
126
            })
127

    
128
        },
129

    
130
        beforeOpen: function() {
131
            this.$(".error-details").hide();
132
            this.$(".show-details").show();
133
            this.$(".hide-details").hide();
134

    
135
            if (this.error_options.allow_report) {
136
                this.$(".report-error").show();
137
            } else {
138
                this.$(".report-error").hide();
139
            }
140

    
141
            if (this.error_options.allow_reload) {
142
                this.$(".reload-app").show();
143
            } else {
144
                this.$(".reload-app").hide();
145
            }
146
        },
147

    
148
        onClose: function() {
149
            this.trigger("close", this);
150
        }
151
    });
152

    
153
    views.NoticeView = views.Overlay.extend({
154
    
155
    });
156

    
157
    views.MultipleActionsView = views.View.extend({
158
        view_id: "multiple_actions",
159

    
160
        _actions: {},
161
        el: '#multiple_actions_container',
162
        
163
        initialize: function() {
164
            this.actions = {};
165
            views.MultipleActionsView.__super__.initialize.call(this);
166
            this.init_handlers();
167
            this.update_layout();
168
            
169
            // for heavy resize/scroll window events
170
            // do it `like a boss` 
171
            this.fix_position = _.throttle(this.fix_position, 50);
172
            this.show_limit = 1;
173
        },
174

    
175
        init_handlers: function() {
176
            
177
            // position handlers
178
            $(window).bind("view:change", function(){
179
            })
180
            $(window).resize(_.bind(function(){
181
                this.fix_position();
182
            }, this));
183
            $(window).scroll(_.bind(function(){
184
                this.fix_position();
185
            }, this));
186
            var self = this;
187
            $(this.el).find("button.yes").click(function(){
188
                self.do_all();
189
            })
190
            $(this.el).find("button.no").click(function(){
191
                self.reset_action_views();
192
                self.reset();
193
            });
194

    
195
            storage.vms.bind("change:pending_action", _.bind(function(vm) {
196
                this.handle_vm_pending_action_change(vm);
197
            }, this));
198
        },
199
    
200
        handle_vm_pending_action_change: function(vm) {
201
            if (vm.has_pending_action()) {
202
                var action = vm.get("pending_action");
203
                this.add_action(vm, action, ui.main.current_view);
204
            } else {
205
                this.remove_action(vm);
206
            }
207
        },
208

    
209
        add_action: function(vm, action, view) {
210
            if (this._actions[vm.id] && this._actions[vm.id].views.indexOf(view) == -1) {
211
                var new_views = this._actions[vm.id].views;
212
                new_views.push(view);
213
                this._actions[vm.id] = {'vm': vm, 'action': action, 'views': new_views};
214
            } else {
215
                this._actions[vm.id] = {'vm': vm, 'action': action, 'views': [view]};
216
            }
217
            this.update_layout();
218
        },
219

    
220
        remove_action: function(vm) {
221
            delete this._actions[vm.id];
222
            this.update_layout();
223
        },
224

    
225
        reset: function() {
226
            this._actions = {};
227
            this.update_layout();
228
        },
229

    
230
        do_all: function() {
231
            _.each(this._actions, function(action){
232
                action.vm.call(action.action);
233
            }, this)  
234
            this.reset_action_views();
235
        },
236

    
237
        reset_action_views: function() {
238
            _.each(this._actions, function(action){
239
                var action = action;
240
                _.each(action.views, function (view) {
241
                    try {
242
                        view.reset();
243
                        view.update_layout();
244
                        view.hide_actions();
245
                    } catch(err) {
246
                        console.error("view", view, "failed to reset");
247
                    }
248
                })
249
            })  
250
        },
251
        
252
        handle_add: function(data) {
253
            if (data.remove) {
254
                this.remove_action(data.vm);
255
            } else {
256
                this.add_action(data.vm, data.action, data.view);
257
            }
258

    
259
            this.update_layout();
260
        },
261
        
262
        fix_position: function() {
263
            $('.confirm_multiple').removeClass('fixed');
264
            if (($(this.el).offset().top +$(this.el).height())> ($(window).scrollTop() + $(window).height())) {
265
                $('.confirm_multiple').addClass('fixed');
266
            }
267
        },
268
        
269
        set_title: function() {
270
            $(this.$("p").get(0)).html('Your actions will affect <span class="actionLen"></span> machines');
271
        },
272

    
273
        set_force_title: function() {
274
            $(this.$("p").get(0)).html('<span class="actionLen"></span> machines needs to be rebooted for changes to apply');
275
        },
276

    
277
        check_force_notify: function() {
278
            this.show_limit = 1;
279
            this.set_title();
280
            storage.vms.each(_.bind(function(vm) {
281
                if (vm.get("force_pending_notify")) {
282
                    this.show_limit = 0;
283
                    this.set_force_title(window.force_actions_title);
284
                }
285
            }, this));
286
        },
287

    
288
        update_layout: function() {
289
            this.check_force_notify();
290
            if (_.size(this._actions) > this.show_limit) {
291
                $(this.el).show();
292
            } else {
293
                $(this.el).hide();
294
                return;
295
            }
296
            $(this.el).find(".actionLen").text(_.size(this._actions));
297
            $(window).trigger("resize");
298
            this.fix_position();
299
        }
300
    })
301
    
302
    // menu wrapper view
303
    views.SelectView = views.View.extend({
304
        
305
        initialize: function(view) {
306
            this.parent = view;
307

    
308
            this.pane_view_selector = $(".css-tabs");
309
            this.machine_view_selector = $("#view-select");
310
            this.el = $(".css-tabs");
311
            this.title = $(".tab-name");
312

    
313
            this.set_handlers();
314
            this.update_layout();
315

    
316
            views.SelectView.__super__.initialize.apply(this, arguments);
317
        },
318
        
319
        clear_active: function() {
320
            this.pane_view_selector.find("a").removeClass("active");
321
            this.machine_view_selector.find("a").removeClass("activelink");
322
        },
323
        
324
        // intercept menu links
325
        set_handlers: function() {
326
            var self = this;
327
            this.pane_view_selector.find("a").hover(function(){
328
                // FIXME: title from href ? omg
329
                self.title.text($(this).attr("href"));
330
            }, function(){
331
                self.title.text(self.parent.get_title());
332
            });
333

    
334
            this.pane_view_selector.find("a#machines_view_link").click(_.bind(function(ev){
335
                ev.preventDefault();
336
                this.parent.show_view("machines");
337
            }, this))
338
            this.pane_view_selector.find("a#networks_view_link").click(_.bind(function(ev){
339
                ev.preventDefault();
340
                this.parent.show_view("networks");
341
            }, this))
342
            this.pane_view_selector.find("a#disks_view_link").click(_.bind(function(ev){
343
                ev.preventDefault();
344
                this.parent.show_view("disks");
345
            }, this))
346
            
347
            this.machine_view_selector.find("a#machines_view_icon_link").click(_.bind(function(ev){
348
                ev.preventDefault();
349
                var d = $.now();
350
                this.parent.show_view("icon");
351
            }, this))
352
            this.machine_view_selector.find("a#machines_view_list_link").click(_.bind(function(ev){
353
                ev.preventDefault();
354
                this.parent.show_view("list");
355
            }, this))
356
            this.machine_view_selector.find("a#machines_view_single_link").click(_.bind(function(ev){
357
                ev.preventDefault();
358
                this.parent.show_view("single");
359
            }, this))
360
        },
361

    
362
        update_layout: function() {
363
            this.clear_active();
364

    
365
            var pane_index = this.parent.pane_ids[this.parent.current_view_id];
366
            $(this.pane_view_selector.find("a")).removeClass("active");
367
            $(this.pane_view_selector.find("a").get(pane_index)).addClass("active");
368
            
369
            if (this.parent.current_view && this.parent.current_view.vms_view) {
370

    
371
                if (storage.vms.length > 0) {
372
                    this.machine_view_selector.show();
373
                    var machine_index = this.parent.views_ids[this.parent.current_view_id];
374
                    $(this.machine_view_selector.find("a").get(machine_index)).addClass("activelink");
375
                } else {
376
                    this.machine_view_selector.hide();
377
                }
378
            } else {
379
                this.machine_view_selector.hide();
380
            }
381

    
382
        }
383
    });
384

    
385
    views.MainView = views.View.extend({
386
        el: 'body',
387
        view_id: 'main',
388
        
389
        // FIXME: titles belong to SelectView
390
        views_titles: {
391
            'icon': 'machines', 'single': 'machines', 
392
            'list': 'machines', 'networks': 'networks',
393
            'disks': 'disks'
394
        },
395

    
396
        // indexes registry
397
        views_indexes: {0: 'icon', 2:'single', 1: 'list', 3:'networks'},
398
        views_pane_indexes: {0:'single', 1:'networks', 2:'disks'},
399

    
400
        // views classes registry
401
        views_classes: {'icon': views.IconView, 'single': views.SingleView, 
402
            'list': views.ListView, 'networks': views.NetworksView},
403

    
404
        // view ids
405
        views_ids: {'icon':0, 'single':2, 'list':1, 'networks':3},
406

    
407
        // on which pane id each view exists
408
        // machine views (icon,single,list) are all on first pane
409
        pane_ids: {'icon':0, 'single':0, 'list':0, 'networks':1, 'disks':2},
410
    
411
        initialize: function(show_view) {
412
            if (!show_view) { show_view = 'icon' };
413
            
414
            // fallback to browser error reporting (true for debug)
415
            this.skip_errors = true
416

    
417
            // reset views
418
            this.views = {};
419

    
420
            this.el = $("body");
421
            // reset main view status
422
            this._loaded = false;
423
            this.status = "Initializing...";
424

    
425
            // initialize handlers
426
            this.init_handlers();
427

    
428
            // identify initial view from user cookies
429
            // this view will be visible after loading of
430
            // main view
431
            this.initial_view = this.session_view();
432

    
433
            views.MainView.__super__.initialize.call(this);
434
        },
435
        
436
        vms_handlers_registered: false,
437

    
438
        // register event handlers
439
        // 
440
        // vms storage events to identify if vms list 
441
        // is empty and display empty view if user viewing
442
        // a machine view
443
        //
444
        // api/ui error event handlers
445
        init_handlers: function() {
446
            // vm handlers
447
            storage.vms.bind("remove", _.bind(this.check_empty, this));
448
            storage.vms.bind("add", _.bind(this.check_empty, this));
449
            storage.vms.bind("change", _.bind(this.check_empty, this));
450
            storage.vms.bind("reset", _.bind(this.check_empty, this));
451
            
452
            // api calls handlers
453
            synnefo.api.bind("error", _.bind(this.handle_api_error, this));
454
            synnefo.ui.bind("error", _.bind(this.handle_ui_error, this));
455
        },
456
        
457
        handle_error_close: function(view) {
458
            snf.api.stop_calls = false;
459
            this.update_intervals();
460
        },
461

    
462
        handle_api_error: function(xhr, type, message) {
463
            this.error_state = true;
464
            this.log.error("API ERRROR", arguments);
465
            
466
            var xhr = arguments[0];
467
            var args = util.parse_api_error(arguments);
468
            
469
            this.stop_intervals();
470
            snf.api.stop_calls = true;
471
            this.error_view.show_error(args.ns, args.code, args.message, args.type, args.details, args);
472
        },
473

    
474
        handle_ui_error: function(error) {
475
            error = error + "<br /><br />" + snf.util.stacktrace().replace("at", "<br /><br />at");
476
            this.error_view.show_error("Application", -1, "Something went wrong", "JS Exception", error);
477
        },
478

    
479
        init_overlays: function() {
480
            this.create_vm_view = new views.CreateVMView();
481
            //this.notice_view = new views.NoticeView();
482
        },
483
        
484
        show_loading_view: function() {
485
            $("#container #content").hide();
486
            $("#loading-view").show();
487
        },
488

    
489
        hide_loading_view: function() {
490
            $("#container #content").show();
491
            $("#loading-view").hide();
492
            $(".css-panes").show();
493
        },
494
        
495
        items_to_load: 4,
496
        completed_items: 0,
497
        check_status: function(loaded) {
498
            this.completed_items++;
499
            // images, flavors loaded
500
            if (this.completed_items == 2) {
501
                this.load_nets_and_vms();
502
            }
503
            if (this.completed_items == this.items_to_load) {
504
                this.after_load();
505
            }
506
        },
507

    
508
        load_nets_and_vms: function() {
509
            var self = this;
510
            this.update_status("Loading vms...");
511
            storage.vms.fetch({refresh:true, update:false, success: function(){
512
                self.update_status("VMS Loaded.");
513
                self.check_status()
514
            }});
515
            this.update_status("Loading networks...");
516
            storage.networks.fetch({refresh:true, update:false, success: function(){
517
                self.update_status("Networks loaded.");
518
                self.check_status()
519
            }});
520
        },  
521

    
522
        init_intervals: function() {
523
            this._networks = storage.networks.get_fetcher(snf.config.update_interval, snf.config.update_interval/3, 3, true, undefined);
524
            this._vms = storage.vms.get_fetcher(snf.config.update_interval, snf.config.update_interval/3, 3, true, undefined);
525
        },
526

    
527
        stop_intervals: function() {
528
            this._networks.stop();
529
            this._vms.stop();
530
        },
531

    
532
        update_intervals: function() {
533
            this._networks.stop();
534
            this._networks.start();
535
            this._vms.stop();
536
            this._vms.start();
537
        },
538

    
539
        after_load: function() {
540
            this.update_status("Setting vms update interval...");
541
            this.init_intervals();
542
            this.update_intervals();
543
            this.update_status("Loaded");
544
            // FIXME: refactor needed
545
            // initialize views
546
            this.initialize_views()
547
            this.update_status("Initializing overlays...");
548
            this.init_overlays();
549
            // display initial view
550
            this.loaded = true;
551
            this.show_initial_view();
552
        },
553

    
554
        load: function() {
555
            this.error_view = new views.ErrorView();
556
            this.error_view.bind("close", _.bind(this.handle_error_close, this));
557
            var self = this;
558
            // initialize overlay views
559
            
560
            // display loading message
561
            this.show_loading_view();
562
            // sync load initial data
563
            this.update_status("Loading images...");
564
            storage.images.fetch({refresh:true, update:false, success: function(){
565
                self.check_status()
566
            }});
567
            this.update_status("Loading flavors...");
568
            storage.flavors.fetch({refresh:true, update:false, success:function(){
569
                self.check_status()
570
            }});
571
        },
572

    
573
        update_status: function(msg) {
574
            this.log.debug(msg)
575
            this.status = msg;
576
            $("#loading-view .info").removeClass("hidden")
577
            $("#loading-view .info").text(this.status);
578
        },
579

    
580
        initialize_views: function() {
581
            this.empty_view = new views.EmptyView();
582
            this.select_view = new views.SelectView(this);
583
            this.metadata_view = new views.MetadataView();
584
            this.multiple_actions_view = new views.MultipleActionsView();
585
            this.feedback_view = new views.FeedbackView();
586
            
587
            this.add_view("icon");
588
            this.add_view("list");
589
            this.add_view("single");
590
            this.add_view("networks");
591

    
592
            this.init_menu();
593
        },
594

    
595
        init_menu: function() {
596
            $(".usermenu .feedback").click(_.bind(function(){
597
                this.feedback_view.show();
598
            }, this));
599
        },
600
        
601
        // initial view based on user cookie
602
        show_initial_view: function() {
603
          this.set_vm_view_handlers();
604
          this.hide_loading_view();
605
          this.show_view(this.initial_view);
606
          this.trigger("initial");
607
        },
608

    
609
        show_vm_details: function(vm) {
610
            snf.ui.main.show_view("single")
611
            snf.ui.main.current_view.show_vm(vm);
612
        },
613

    
614
        set_vm_view_handlers: function() {
615
            $("#createcontainer #create").click(_.bind(function(){
616
                this.create_vm_view.show();
617
            }, this))
618
        },
619

    
620
        check_empty: function() {
621
            if (!this.loaded) { return }
622
            if (storage.vms.length == 0) {
623
                this.show_empty();
624
            } else {
625
                this.hide_empty();
626
            }
627
            this.select_view.update_layout();
628
        },
629

    
630
        show_empty: function() {
631
            $("#machines-pane-top").addClass("empty");
632

    
633
            this.$(".panes").hide();
634
            this.$("#machines-pane").show();
635

    
636
            this.hide_views([]);
637
            this.empty_view.show();
638
        },
639

    
640
        hide_empty: function() {
641
            $("#machines-pane-top").removeClass("empty");
642

    
643
            this.empty_view = new views.EmptyView();
644
            this.empty_view.hide();
645
            if (this.current_view && !this.current_view.visible()) { 
646
                this.current_view.show(); 
647
            }
648
        },
649
        
650
        get_title: function(view_id) {
651
            var view_id = view_id || this.current_view_id;
652
            return this.views_titles[view_id];
653
        },
654

    
655
        // return class object for the given view or false if
656
        // the view is not registered
657
        get_class_for_view: function (view_id) {
658
            if (!this.views_classes[view_id]) {
659
                return false;
660
            }
661
            return this.views_classes[view_id];
662
        },
663

    
664
        view: function(view_id) {
665
            return this.views[view_id];
666
        },
667

    
668
        add_view: function(view_id) {
669
            if (!this.views[view_id]) {
670
                var cls = this.get_class_for_view(view_id);
671
                if (this.skip_errors) {
672
                    this.views[view_id] = new cls();
673
                    $(this.views[view_id]).bind("resize", _.bind(function() {
674
                        window.positionFooter();
675
                        this.multiple_actions_view.fix_position();
676
                    }, this));
677
                } else {
678
                    // catch ui errors
679
                    try {
680
                        this.views[view_id] = new cls();
681
                        $(this.views[view_id]).bind("resize", _.bind(function() {
682
                            window.positionFooter();
683
                            this.multiple_actions_view.fix_position();
684
                        }, this));
685
                    } catch (err) {snf.ui.trigger("error", err)}
686
                }
687
            } else {
688
            }
689

    
690
            if (this.views[view_id].vms_view) {
691
                this.views[view_id].metadata_view = this.metadata_view;
692
            }
693
            return this.views[view_id];
694
        },
695
            
696
        hide_views: function(skip) {
697
            _.each(this.views, function(view) {
698
                if (skip.indexOf(view) === -1) {
699
                    $(view.el).hide();
700
                }
701
            }, this)
702
        },
703
        
704
        get: function(view_id) {
705
            return this.views[view_id];
706
        },
707
        
708
        session_view: function() {
709
            if (this.pane_view_from_session() > 0) {
710
                return this.views_pane_indexes[this.pane_view_from_session()];
711
            } else {
712
                return this.views_indexes[this.machine_view_from_session()];
713
            }
714
        },
715

    
716
        pane_view_from_session: function() {
717
            return $.cookie("pane_view") || 0;
718
        },
719

    
720
        machine_view_from_session: function() {
721
            return $.cookie("machine_view") || 0;
722
        },
723

    
724
        update_session: function() {
725
            $.cookie("pane_view", this.pane_ids[this.current_view_id]);
726
            if (this.current_view.vms_view) {
727
                $.cookie("machine_view", this.views_ids[this.current_view_id]);
728
            }
729
        },
730

    
731
        identify_view: function(view_id) {
732
            // machines view_id is an alias to
733
            // one of the 3 machines view
734
            // identify which one (if no cookie set defaults to icon)
735
            if (view_id == "machines") {
736
                var index = this.machine_view_from_session();
737
                view_id = this.views_indexes[index];
738
            }
739
            return view_id;
740
        },
741
        
742
        // switch to current view pane
743
        // if differs from the visible one
744
        show_view_pane: function() {
745
            if (this.current_view.pane != this.current_pane) {
746
                $(this.current_view.pane).show();
747
                $(this.current_pane).hide();
748
                this.current_pane = this.current_view.pane;
749
            }
750
        },
751

    
752
        show_view: function(view_id) {
753
            // same view, visible
754
            // get out of here asap
755
            if (this.current_view && 
756
                this.current_view.id == view_id && 
757
                this.current_view.visible()) {
758
                return;
759
            }
760

    
761
            view_id = this.identify_view(view_id);
762
            // add/create view and update current view
763
            var view = this.add_view(view_id);
764

    
765
            this.current_view = view;
766
            this.current_view_id = view_id;
767

    
768
            // hide all other views
769
            this.hide_views([this.current_view]);
770
            
771
            // FIXME: depricated
772
            $(".large-spinner").remove();
773

    
774
            // show current view
775
            this.show_view_pane();
776
            view.show();
777
            
778
            // update menus
779
            if (this.select_view) {
780
                this.select_view.update_layout();
781
            }
782
            this.current_view.__update_layout();
783

    
784
            // update cookies
785
            this.update_session();
786

    
787
            if (this.current_view.vms_view) {
788
                $("#machines-pane").show();
789
            } else {
790
                $("#machines-pane").hide();
791
            }
792
            
793
            // fix footer position
794
            // TODO: move footer handlers in
795
            // main view (from home.html)
796
            if (window.positionFooter) {
797
                window.positionFooter();
798
            }
799
            
800
            this.trigger("view:change", this.current_view.view_id);
801
            $(window).trigger("view:change");
802
            storage.vms.reset_pending_actions();
803
            return view;
804
        },
805

    
806
        reset_vm_actions: function() {
807
        
808
        },
809
        
810
        // identify current view
811
        // based on views element visibility
812
        current_view_id: function() {
813
            var found = false;
814
            _.each(this.views, function(key, value) {
815
                if (value.visible()) {
816
                    found = value;
817
                }
818
            })
819
            return found;
820
        }
821

    
822
    });
823

    
824
    snf.ui.main = new views.MainView();
825

    
826
})(this);