Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / ui / static / snf / js / ui / web / ui_vms_base_view.js @ 643fe7e3

History | View | Annotate | Download (30.5 kB)

1 00469232 Kostas Papadimitriou
// Copyright 2011 GRNET S.A. All rights reserved.
2 00469232 Kostas Papadimitriou
// 
3 00469232 Kostas Papadimitriou
// Redistribution and use in source and binary forms, with or
4 00469232 Kostas Papadimitriou
// without modification, are permitted provided that the following
5 00469232 Kostas Papadimitriou
// conditions are met:
6 00469232 Kostas Papadimitriou
// 
7 00469232 Kostas Papadimitriou
//   1. Redistributions of source code must retain the above
8 00469232 Kostas Papadimitriou
//      copyright notice, this list of conditions and the following
9 00469232 Kostas Papadimitriou
//      disclaimer.
10 00469232 Kostas Papadimitriou
// 
11 00469232 Kostas Papadimitriou
//   2. Redistributions in binary form must reproduce the above
12 00469232 Kostas Papadimitriou
//      copyright notice, this list of conditions and the following
13 00469232 Kostas Papadimitriou
//      disclaimer in the documentation and/or other materials
14 00469232 Kostas Papadimitriou
//      provided with the distribution.
15 00469232 Kostas Papadimitriou
// 
16 00469232 Kostas Papadimitriou
// THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 00469232 Kostas Papadimitriou
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 00469232 Kostas Papadimitriou
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 00469232 Kostas Papadimitriou
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 00469232 Kostas Papadimitriou
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 00469232 Kostas Papadimitriou
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 00469232 Kostas Papadimitriou
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 00469232 Kostas Papadimitriou
// USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 00469232 Kostas Papadimitriou
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 00469232 Kostas Papadimitriou
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 00469232 Kostas Papadimitriou
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 00469232 Kostas Papadimitriou
// POSSIBILITY OF SUCH DAMAGE.
28 00469232 Kostas Papadimitriou
// 
29 00469232 Kostas Papadimitriou
// The views and conclusions contained in the software and
30 00469232 Kostas Papadimitriou
// documentation are those of the authors and should not be
31 00469232 Kostas Papadimitriou
// interpreted as representing official policies, either expressed
32 00469232 Kostas Papadimitriou
// or implied, of GRNET S.A.
33 00469232 Kostas Papadimitriou
// 
34 00469232 Kostas Papadimitriou
35 8d08f18a Kostas Papadimitriou
;(function(root){
36 8d08f18a Kostas Papadimitriou
    
37 8d08f18a Kostas Papadimitriou
    // root
38 8d08f18a Kostas Papadimitriou
    var root = root;
39 8d08f18a Kostas Papadimitriou
    
40 8d08f18a Kostas Papadimitriou
    // setup namepsaces
41 8d08f18a Kostas Papadimitriou
    var snf = root.synnefo = root.synnefo || {};
42 8d08f18a Kostas Papadimitriou
    var models = snf.models = snf.models || {}
43 8d08f18a Kostas Papadimitriou
    var storage = snf.storage = snf.storage || {};
44 8d08f18a Kostas Papadimitriou
    var ui = snf.ui = snf.ui || {};
45 8d08f18a Kostas Papadimitriou
46 8d08f18a Kostas Papadimitriou
    var views = snf.views = snf.views || {}
47 8d08f18a Kostas Papadimitriou
48 8d08f18a Kostas Papadimitriou
    // shortcuts
49 8d08f18a Kostas Papadimitriou
    var bb = root.Backbone;
50 8d08f18a Kostas Papadimitriou
    
51 8d08f18a Kostas Papadimitriou
    // logging
52 8d08f18a Kostas Papadimitriou
    var logger = new snf.logging.logger("SNF-VIEWS");
53 8d08f18a Kostas Papadimitriou
    var debug = _.bind(logger.debug, logger);
54 8d08f18a Kostas Papadimitriou
    
55 75331d54 Kostas Papadimitriou
    var hasKey = Object.prototype.hasOwnProperty;
56 75331d54 Kostas Papadimitriou
57 8d08f18a Kostas Papadimitriou
    // base class for views that contain/handle VMS
58 8d08f18a Kostas Papadimitriou
    views.VMListView = views.View.extend({
59 8d08f18a Kostas Papadimitriou
60 8d08f18a Kostas Papadimitriou
        // just a flag to identify that
61 8d08f18a Kostas Papadimitriou
        // views of this type handle vms
62 8d08f18a Kostas Papadimitriou
        vms_view: true,
63 8d08f18a Kostas Papadimitriou
64 8d08f18a Kostas Papadimitriou
        selectors: {},
65 8d08f18a Kostas Papadimitriou
        hide_actions: true,
66 8d08f18a Kostas Papadimitriou
        pane: "#machines-pane",
67 8d08f18a Kostas Papadimitriou
        metadata_view: undefined,
68 8d08f18a Kostas Papadimitriou
69 8d08f18a Kostas Papadimitriou
        initialize: function() {
70 8d08f18a Kostas Papadimitriou
            views.VMListView.__super__.initialize.call(this);
71 75331d54 Kostas Papadimitriou
            this._vm_els = {};
72 8d08f18a Kostas Papadimitriou
            this.set_storage_handlers();
73 8d08f18a Kostas Papadimitriou
            this.set_handlers();
74 8d08f18a Kostas Papadimitriou
            this.vms_updated_handler();
75 550d9733 Kostas Papadimitriou
            this.connect_overlay = new views.VMConnectView();
76 8d08f18a Kostas Papadimitriou
        },
77 8d08f18a Kostas Papadimitriou
78 1e882dd7 Kostas Papadimitriou
        // display vm diagnostics detail overlay view, update based on
79 1e882dd7 Kostas Papadimitriou
        // diagnostics_update_interval config value.
80 1e882dd7 Kostas Papadimitriou
        show_build_details_for_vm: function(vm) {
81 1e882dd7 Kostas Papadimitriou
            var cont = null;
82 1e882dd7 Kostas Papadimitriou
            var success = function(data) {
83 1e882dd7 Kostas Papadimitriou
                var message = "";
84 1e882dd7 Kostas Papadimitriou
                var title = vm.get('name');
85 1e882dd7 Kostas Papadimitriou
                var info = '<em>Status log messages:</em>';
86 1e882dd7 Kostas Papadimitriou
87 1e882dd7 Kostas Papadimitriou
                var list_el = $('<div class="diagnostics-list">');
88 1e882dd7 Kostas Papadimitriou
                list_el.append('<div class="empty">No data available</div>');
89 1e882dd7 Kostas Papadimitriou
90 1e882dd7 Kostas Papadimitriou
                cont = list_el;
91 1e882dd7 Kostas Papadimitriou
                var messages = _.clone(data);
92 1e882dd7 Kostas Papadimitriou
93 1e882dd7 Kostas Papadimitriou
                update_overlay_diagnostics(data, cont);
94 1e882dd7 Kostas Papadimitriou
                synnefo.ui.main.details_view.show(title, info, cont);
95 1e882dd7 Kostas Papadimitriou
            }
96 1e882dd7 Kostas Papadimitriou
97 1e882dd7 Kostas Papadimitriou
            var update_overlay_diagnostics = function(data) {
98 1e882dd7 Kostas Papadimitriou
                var existing = cont.find(".msg-log-entry");
99 1e882dd7 Kostas Papadimitriou
                var messages = _.clone(data);
100 1e882dd7 Kostas Papadimitriou
                
101 1e882dd7 Kostas Papadimitriou
                var to_append = messages.slice(0, messages.length - existing.length);
102 1e882dd7 Kostas Papadimitriou
                to_append.reverse();
103 1e882dd7 Kostas Papadimitriou
104 1e882dd7 Kostas Papadimitriou
                var appending = to_append.length != messages.length;
105 1e882dd7 Kostas Papadimitriou
                
106 1e882dd7 Kostas Papadimitriou
                if (to_append.length) { cont.find(".empty").hide() } else {
107 1e882dd7 Kostas Papadimitriou
                    if (!messages.length) { cont.find(".empty").show() }
108 1e882dd7 Kostas Papadimitriou
                }
109 1e882dd7 Kostas Papadimitriou
                _.each(to_append, function(msg){
110 1e882dd7 Kostas Papadimitriou
                    var el = $('<div class="clearfix msg-log-entry ' + msg.level.toLowerCase() + '">');
111 1e882dd7 Kostas Papadimitriou
                    if (msg.details) {
112 1e882dd7 Kostas Papadimitriou
                      el.addClass("with-details");
113 1e882dd7 Kostas Papadimitriou
                    }
114 1e882dd7 Kostas Papadimitriou
                    var display_source_date = synnefo.config.diagnostics_display_source_date;
115 1e882dd7 Kostas Papadimitriou
                    var source_date = "";
116 1e882dd7 Kostas Papadimitriou
                    if (display_source_date) {
117 1e882dd7 Kostas Papadimitriou
                        source_date = '('+synnefo.util.formatDate(new Date(msg.source_date))+')';
118 1e882dd7 Kostas Papadimitriou
                    }
119 1e882dd7 Kostas Papadimitriou
120 1e882dd7 Kostas Papadimitriou
                    el.append('<span class="date">' + synnefo.util.formatDate(new Date(msg.created)) + source_date + '</span>');
121 1e882dd7 Kostas Papadimitriou
                    el.append('<span class="src">' + _.escape(msg.source) + '</span>');
122 1e882dd7 Kostas Papadimitriou
                    el.append('<span class="msg">' + _.escape(msg.message) + '</span>');
123 1e882dd7 Kostas Papadimitriou
                    if (msg.details) {
124 1e882dd7 Kostas Papadimitriou
                        el.append('<pre class="details">' + _.escape(msg.details) + '</pre>');
125 1e882dd7 Kostas Papadimitriou
                    }
126 1e882dd7 Kostas Papadimitriou
                    if (appending) { el.hide(0); el.css({'display':'none'})}
127 1e882dd7 Kostas Papadimitriou
                    cont.prepend(el);
128 1e882dd7 Kostas Papadimitriou
                    el.click(function(el) {
129 1e882dd7 Kostas Papadimitriou
                        $(this).find(".details").slideToggle();
130 1e882dd7 Kostas Papadimitriou
                        $(this).toggleClass("expanded");
131 1e882dd7 Kostas Papadimitriou
                    });
132 1e882dd7 Kostas Papadimitriou
133 1e882dd7 Kostas Papadimitriou
                    if (appending) { el.fadeIn(800); }
134 1e882dd7 Kostas Papadimitriou
                });
135 1e882dd7 Kostas Papadimitriou
                
136 1e882dd7 Kostas Papadimitriou
                window.setTimeout(function(){
137 1e882dd7 Kostas Papadimitriou
                    if (cont.is(":visible")) {
138 1e882dd7 Kostas Papadimitriou
                        vm.get_diagnostics(update_overlay_diagnostics);
139 1e882dd7 Kostas Papadimitriou
                    }
140 1e882dd7 Kostas Papadimitriou
                }, synnefo.config.diagnostics_update_interval);
141 1e882dd7 Kostas Papadimitriou
            }
142 1e882dd7 Kostas Papadimitriou
143 1e882dd7 Kostas Papadimitriou
            vm.get_diagnostics(success);
144 1e882dd7 Kostas Papadimitriou
        },
145 1e882dd7 Kostas Papadimitriou
146 8d08f18a Kostas Papadimitriou
        // Helpers
147 8d08f18a Kostas Papadimitriou
        //
148 8d08f18a Kostas Papadimitriou
        // get element based on this.selectors key/value pairs
149 8d08f18a Kostas Papadimitriou
        sel: function(id, params) {
150 8d08f18a Kostas Papadimitriou
            if (!this.selectors[id]){ return };
151 8d08f18a Kostas Papadimitriou
            return $(this.selectors[id].format(params));
152 8d08f18a Kostas Papadimitriou
        },
153 8d08f18a Kostas Papadimitriou
        
154 8d08f18a Kostas Papadimitriou
        // vm element based on vm model instance provided
155 8d08f18a Kostas Papadimitriou
        vm: function(vm) {
156 75331d54 Kostas Papadimitriou
            if (hasKey.call(this._vm_els, vm.id)) {
157 75331d54 Kostas Papadimitriou
                ret = this._vm_els[vm.id];
158 75331d54 Kostas Papadimitriou
            } else {
159 75331d54 Kostas Papadimitriou
                return $([]);
160 75331d54 Kostas Papadimitriou
            }
161 75331d54 Kostas Papadimitriou
162 75331d54 Kostas Papadimitriou
            return ret;
163 8d08f18a Kostas Papadimitriou
        },
164 8d08f18a Kostas Papadimitriou
        
165 8d08f18a Kostas Papadimitriou
        // get vm model instance from DOM element
166 8d08f18a Kostas Papadimitriou
        vm_for_element: function(el) {
167 8d08f18a Kostas Papadimitriou
            return storage.vms.sel(this.vm_id_for_element(el));
168 8d08f18a Kostas Papadimitriou
        },
169 8d08f18a Kostas Papadimitriou
        
170 8d08f18a Kostas Papadimitriou
171 8d08f18a Kostas Papadimitriou
        // Event binding and stuff like that
172 8d08f18a Kostas Papadimitriou
        //
173 8d08f18a Kostas Papadimitriou
        set_storage_handlers: function() {
174 8d08f18a Kostas Papadimitriou
            storage.vms.bind("add", _.bind(this.vms_updated_handler, this, "add"));
175 8d08f18a Kostas Papadimitriou
            storage.vms.bind("change", _.bind(this.vms_updated_handler, this, "change"));
176 8d08f18a Kostas Papadimitriou
            storage.vms.bind("reset", _.bind(this.vms_updated_handler, this, "reset"));
177 8d08f18a Kostas Papadimitriou
            storage.vms.bind("remove", _.bind(this.vms_updated_handler, this, "remove"));
178 8d08f18a Kostas Papadimitriou
        },
179 8d08f18a Kostas Papadimitriou
        
180 8d08f18a Kostas Papadimitriou
        // vms updated triggered, update view vms
181 8d08f18a Kostas Papadimitriou
        vms_updated_handler: function (method, model, arg2, arg3) {
182 8d08f18a Kostas Papadimitriou
            var updated = storage.vms.models;
183 8d08f18a Kostas Papadimitriou
            if (method == "add") { updated = [model] };
184 8d08f18a Kostas Papadimitriou
            if (method == "change") { updated = [model] };
185 8d08f18a Kostas Papadimitriou
            if (method == "remove") { updated = [model] };
186 8d08f18a Kostas Papadimitriou
187 8d08f18a Kostas Papadimitriou
            if (method == "remove") {
188 8d08f18a Kostas Papadimitriou
                this.remove_vm(model)
189 8d08f18a Kostas Papadimitriou
                return;
190 8d08f18a Kostas Papadimitriou
            }
191 44660f58 Kostas Papadimitriou
            
192 8d08f18a Kostas Papadimitriou
            this.update_vms(updated);
193 8d08f18a Kostas Papadimitriou
        },
194 8d08f18a Kostas Papadimitriou
195 8d08f18a Kostas Papadimitriou
        // create vm
196 8d08f18a Kostas Papadimitriou
        // append it on proper view container
197 8d08f18a Kostas Papadimitriou
        create_vm: function(vm) {
198 8d08f18a Kostas Papadimitriou
            // create dom element
199 8d08f18a Kostas Papadimitriou
            var vm_view = this.create_vm_element(vm);
200 8d08f18a Kostas Papadimitriou
            vm_view.find(".vm-actions").attr("id", this.view_id+"-actions-" + vm.id);
201 75331d54 Kostas Papadimitriou
            this._vm_els[vm.id] = vm_view;
202 b042eb04 Kostas Papadimitriou
            var container = this.get_vm_container(vm);
203 8d08f18a Kostas Papadimitriou
            container.append(vm_view);
204 8d08f18a Kostas Papadimitriou
            vm_view.find(".action-indicator").text("");
205 8d08f18a Kostas Papadimitriou
            if (this.visible()) {
206 8d08f18a Kostas Papadimitriou
                container.show()
207 8d08f18a Kostas Papadimitriou
            }
208 8d08f18a Kostas Papadimitriou
209 8d08f18a Kostas Papadimitriou
            // initialize vm specific event handlers 
210 8d08f18a Kostas Papadimitriou
            this.__set_vm_handlers(vm);
211 a6b9836b Kostas Papadimitriou
            vm_view.find(".suspended-notice").click(function(){
212 a6b9836b Kostas Papadimitriou
              synnefo.ui.main.suspended_view.show(vm);
213 a6b9836b Kostas Papadimitriou
            })
214 75331d54 Kostas Papadimitriou
            return vm_view;
215 8d08f18a Kostas Papadimitriou
        },
216 8d08f18a Kostas Papadimitriou
        
217 8d08f18a Kostas Papadimitriou
        // create vm dom element
218 8d08f18a Kostas Papadimitriou
        create_vm_element: function(vm) {
219 8d08f18a Kostas Papadimitriou
            // clone template
220 23a3bb8e Kostas Papadimitriou
            return this.sel('tpl').clone().attr("id", this.id_tpl + vm.id)
221 8d08f18a Kostas Papadimitriou
        },
222 8d08f18a Kostas Papadimitriou
223 8d08f18a Kostas Papadimitriou
        // get proper vm container
224 8d08f18a Kostas Papadimitriou
        get_vm_container: function(vm) {
225 8d08f18a Kostas Papadimitriou
            if (vm.is_active()) {
226 8d08f18a Kostas Papadimitriou
                return this.sel("vm_cont_active");
227 8d08f18a Kostas Papadimitriou
            } else {
228 8d08f18a Kostas Papadimitriou
                return this.sel("vm_cont_terminated");
229 8d08f18a Kostas Papadimitriou
            }
230 8d08f18a Kostas Papadimitriou
        },
231 8d08f18a Kostas Papadimitriou
232 8d08f18a Kostas Papadimitriou
        // create and append inside the proper container the vm model
233 8d08f18a Kostas Papadimitriou
        // if it doesn't exist update vm data and make it visible
234 8d08f18a Kostas Papadimitriou
        add: function(vm) {
235 8d08f18a Kostas Papadimitriou
            // create if it does not exist
236 75331d54 Kostas Papadimitriou
            if (!hasKey.call(this._vm_els, vm.id)) {
237 75331d54 Kostas Papadimitriou
                var el = this.create_vm(vm);
238 75331d54 Kostas Papadimitriou
                el.show();
239 c343513e Kostas Papadimitriou
                this.post_add(vm);
240 1e882dd7 Kostas Papadimitriou
                this.init_vm_view_handlers(vm);
241 8d08f18a Kostas Papadimitriou
            }
242 8d08f18a Kostas Papadimitriou
243 8d08f18a Kostas Papadimitriou
            return this.vm(vm);
244 8d08f18a Kostas Papadimitriou
        },
245 1e882dd7 Kostas Papadimitriou
246 1e882dd7 Kostas Papadimitriou
        init_vm_view_handlers: function(vm) {
247 1e882dd7 Kostas Papadimitriou
            var self = this;
248 1e882dd7 Kostas Papadimitriou
            var el = this.vm(vm);
249 1e882dd7 Kostas Papadimitriou
250 1e882dd7 Kostas Papadimitriou
            // hidden feature, double click on indicators to display 
251 1e882dd7 Kostas Papadimitriou
            // vm diagnostics.
252 1e882dd7 Kostas Papadimitriou
            el.find(".indicators").bind("dblclick", function(){
253 1e882dd7 Kostas Papadimitriou
                self.show_build_details_for_vm(vm);
254 1e882dd7 Kostas Papadimitriou
            });
255 1e882dd7 Kostas Papadimitriou
256 1e882dd7 Kostas Papadimitriou
            // this button gets visible if vm creation failed.
257 1e882dd7 Kostas Papadimitriou
            el.find("div.build-progress .btn").click(function(){
258 1e882dd7 Kostas Papadimitriou
                self.show_build_details_for_vm(vm);
259 1e882dd7 Kostas Papadimitriou
            });
260 1e882dd7 Kostas Papadimitriou
        },
261 8d08f18a Kostas Papadimitriou
        
262 8d08f18a Kostas Papadimitriou
        // helpers for VMListView descendants
263 8d08f18a Kostas Papadimitriou
        post_add: function(vm) { throw "Not implemented" },
264 8d08f18a Kostas Papadimitriou
        set_vm_handlers: function(vm) { throw "Not implemented" },
265 8d08f18a Kostas Papadimitriou
        set_handlers: function() { throw "Not implemented" },
266 8d08f18a Kostas Papadimitriou
        update_layout: function() { throw "Not implemented" },
267 8d08f18a Kostas Papadimitriou
        post_update_vm: function(vm) { throw "Not implemented" },
268 8d08f18a Kostas Papadimitriou
        update_details: function(vm) {},
269 8d08f18a Kostas Papadimitriou
        
270 8d08f18a Kostas Papadimitriou
        // remove vm
271 8d08f18a Kostas Papadimitriou
        remove_vm: function(vm) {
272 8d08f18a Kostas Papadimitriou
            // FIXME: some kind of transiton ??? effect maybe ???
273 8d08f18a Kostas Papadimitriou
            this.vm(vm).remove();
274 8d08f18a Kostas Papadimitriou
            this.post_remove_vm(vm);
275 75331d54 Kostas Papadimitriou
            if (hasKey.call(this._vm_els, vm.id)) {
276 75331d54 Kostas Papadimitriou
                delete this._vm_els[vm.id];
277 75331d54 Kostas Papadimitriou
            }
278 8d08f18a Kostas Papadimitriou
        },
279 8d08f18a Kostas Papadimitriou
        
280 8d08f18a Kostas Papadimitriou
        // remove all vms from view
281 8d08f18a Kostas Papadimitriou
        clear: function() {
282 8d08f18a Kostas Papadimitriou
            this.sel('vms').remove();
283 8d08f18a Kostas Papadimitriou
            this.__update_layout();
284 8d08f18a Kostas Papadimitriou
        },
285 8d08f18a Kostas Papadimitriou
286 2506f741 Kostas Papadimitriou
        show: function() {
287 2506f741 Kostas Papadimitriou
            views.VMListView.__super__.show.apply(this, arguments);
288 f44486d8 Kostas Papadimitriou
            if (storage.vms.length == 0) { this.hide() };
289 5dad72ea Kostas Papadimitriou
            if (!snf.config.update_hidden_views) {
290 5dad72ea Kostas Papadimitriou
                this.update_vms(storage.vms.models);
291 5dad72ea Kostas Papadimitriou
            }
292 2506f741 Kostas Papadimitriou
        },
293 2506f741 Kostas Papadimitriou
294 8d08f18a Kostas Papadimitriou
        // do update for provided vms, then update the view layout
295 8d08f18a Kostas Papadimitriou
        update_vms: function(vms) {
296 5dad72ea Kostas Papadimitriou
            if (!this.visible() && !snf.config.update_hidden_views) { return };
297 5dad72ea Kostas Papadimitriou
298 8d08f18a Kostas Papadimitriou
            _.each(vms, _.bind(function(vm){
299 8d08f18a Kostas Papadimitriou
                // vm will be removed
300 8d08f18a Kostas Papadimitriou
                // no need to update
301 8d08f18a Kostas Papadimitriou
                if (vm.get("status") == "DELETED") {
302 8d08f18a Kostas Papadimitriou
                    return;
303 8d08f18a Kostas Papadimitriou
                }
304 8d08f18a Kostas Papadimitriou
305 8d08f18a Kostas Papadimitriou
                // this won't add it additional times
306 8d08f18a Kostas Papadimitriou
                this.add(vm);
307 8d08f18a Kostas Papadimitriou
                this.update_vm(vm);
308 8d08f18a Kostas Papadimitriou
            }, this))
309 8d08f18a Kostas Papadimitriou
            
310 8d08f18a Kostas Papadimitriou
            // update view stuff
311 8d08f18a Kostas Papadimitriou
            this.__update_layout();
312 8d08f18a Kostas Papadimitriou
        },
313 8d08f18a Kostas Papadimitriou
        
314 e6a4b75c Kostas Papadimitriou
        update_toggles_visibility: function(vm) {
315 e6a4b75c Kostas Papadimitriou
          if (vm.is_building() || vm.in_error_state() || vm.get("status") == "DESTROY") {
316 e6a4b75c Kostas Papadimitriou
            this.vm(vm).find(".cont-toggler-wrapper.ips").addClass("disabled");
317 e6a4b75c Kostas Papadimitriou
          } else {
318 e6a4b75c Kostas Papadimitriou
            this.vm(vm).find(".cont-toggler-wrapper.ips").removeClass("disabled");
319 e6a4b75c Kostas Papadimitriou
          }
320 e6a4b75c Kostas Papadimitriou
        },
321 e6a4b75c Kostas Papadimitriou
322 8d08f18a Kostas Papadimitriou
        // update ui for the given vm
323 8d08f18a Kostas Papadimitriou
        update_vm: function(vm) {
324 643de8c0 Kostas Papadimitriou
            // do not update deleted state vms
325 643de8c0 Kostas Papadimitriou
            if (!vm || vm.get("status") == 'DELETED') { return };
326 8d08f18a Kostas Papadimitriou
            this.check_vm_container(vm);
327 8d08f18a Kostas Papadimitriou
328 8d08f18a Kostas Papadimitriou
            this.update_details(vm);
329 8d08f18a Kostas Papadimitriou
            this.update_transition_state(vm);
330 e6a4b75c Kostas Papadimitriou
            this.update_toggles_visibility(vm);
331 8d08f18a Kostas Papadimitriou
332 8d08f18a Kostas Papadimitriou
            if (this.action_views) {
333 8d08f18a Kostas Papadimitriou
                this.action_views[vm.id].update();
334 8d08f18a Kostas Papadimitriou
                this.action_views[vm.id].update_layout();
335 8d08f18a Kostas Papadimitriou
            }
336 8d08f18a Kostas Papadimitriou
            
337 a6b9836b Kostas Papadimitriou
            var el = this.vm(vm);
338 ab3df8df Kostas Papadimitriou
            if (vm.can_resize()) {
339 ab3df8df Kostas Papadimitriou
              el.addClass("can-resize");
340 ab3df8df Kostas Papadimitriou
            } else {
341 ab3df8df Kostas Papadimitriou
              el.removeClass("can-resize");
342 ab3df8df Kostas Papadimitriou
            }
343 ab3df8df Kostas Papadimitriou
344 a6b9836b Kostas Papadimitriou
            if (vm.get('suspended')) {
345 a6b9836b Kostas Papadimitriou
              el.addClass("suspended");
346 a6b9836b Kostas Papadimitriou
            } else {
347 a6b9836b Kostas Papadimitriou
              el.removeClass("suspended");
348 a6b9836b Kostas Papadimitriou
            }
349 a6b9836b Kostas Papadimitriou
350 027bdc60 Kostas Papadimitriou
            try {
351 027bdc60 Kostas Papadimitriou
                this.post_update_vm(vm);
352 027bdc60 Kostas Papadimitriou
            } catch (err) {};
353 8d08f18a Kostas Papadimitriou
        },
354 8d08f18a Kostas Papadimitriou
355 8d08f18a Kostas Papadimitriou
        // check if vm is placed properly within the view
356 8d08f18a Kostas Papadimitriou
        // container (e.g. some views might have different
357 8d08f18a Kostas Papadimitriou
        // containers for terminated or running machines
358 8d08f18a Kostas Papadimitriou
        check_vm_container: function(vm){
359 8d08f18a Kostas Papadimitriou
            var el = this.vm(vm);
360 8d08f18a Kostas Papadimitriou
            if (!el.length) { return };
361 8d08f18a Kostas Papadimitriou
            var self = this;
362 8d08f18a Kostas Papadimitriou
            var selector = vm.is_active() ? 'vm_cont_active' : 'vm_cont_terminated';
363 8d08f18a Kostas Papadimitriou
            if (el.parent()[0] != this.sel(selector)[0]) {
364 8d08f18a Kostas Papadimitriou
                var cont = this.sel(selector);
365 8d08f18a Kostas Papadimitriou
                var self = this;
366 7c90e31b Kostas Papadimitriou
367 b042eb04 Kostas Papadimitriou
                el.hide().appendTo(cont).fadeIn(300);
368 7c90e31b Kostas Papadimitriou
                $(window).trigger('resize');
369 7c90e31b Kostas Papadimitriou
370 7c90e31b Kostas Papadimitriou
                //el.fadeOut(200, function() {
371 7c90e31b Kostas Papadimitriou
                    //el.appendTo(cont); 
372 7c90e31b Kostas Papadimitriou
                    //el.fadeIn(200);
373 7c90e31b Kostas Papadimitriou
                    //self.sel(selector).show(function(){
374 7c90e31b Kostas Papadimitriou
                        //$(window).trigger("resize");
375 7c90e31b Kostas Papadimitriou
                    //});
376 7c90e31b Kostas Papadimitriou
                //});
377 8d08f18a Kostas Papadimitriou
            }
378 8d08f18a Kostas Papadimitriou
        },
379 8d08f18a Kostas Papadimitriou
380 8d08f18a Kostas Papadimitriou
        __update_layout: function() {
381 8d08f18a Kostas Papadimitriou
            this.update_layout();
382 8d08f18a Kostas Papadimitriou
        },
383 8d08f18a Kostas Papadimitriou
        
384 8d08f18a Kostas Papadimitriou
        // append handlers for vm specific events
385 8d08f18a Kostas Papadimitriou
        __set_vm_handlers: function(vm) {
386 8d08f18a Kostas Papadimitriou
            // show transition on vm status transit
387 8d08f18a Kostas Papadimitriou
            vm.bind('transition', _.bind(function(){this.show_transition(vm)}, this));
388 8d08f18a Kostas Papadimitriou
            this.set_vm_handlers(vm);
389 8d08f18a Kostas Papadimitriou
        },
390 8d08f18a Kostas Papadimitriou
        
391 8d08f18a Kostas Papadimitriou
        // is vm in transition ??? show the progress spinner
392 8d08f18a Kostas Papadimitriou
        update_transition_state: function(vm) {
393 1e882dd7 Kostas Papadimitriou
            if (vm.in_transition() && !vm.has_pending_action()){
394 8d08f18a Kostas Papadimitriou
                this.sel('vm_spinner', vm.id).show();
395 8d08f18a Kostas Papadimitriou
            } else {
396 8d08f18a Kostas Papadimitriou
                this.sel('vm_spinner', vm.id).hide();
397 8d08f18a Kostas Papadimitriou
            }
398 8d08f18a Kostas Papadimitriou
        },
399 8d08f18a Kostas Papadimitriou
        
400 8d08f18a Kostas Papadimitriou
        show_indicator: function(vm, action) {
401 8d08f18a Kostas Papadimitriou
            var action = action || vm.pending_action;
402 8d08f18a Kostas Papadimitriou
            this.sel('vm_wave', vm.id).hide();
403 8d08f18a Kostas Papadimitriou
            this.sel('vm_spinner', vm.id).hide();
404 8d08f18a Kostas Papadimitriou
            this.vm(vm).find(".action-indicator").removeClass().addClass(action + " action-indicator").show();
405 8d08f18a Kostas Papadimitriou
        },
406 8d08f18a Kostas Papadimitriou
407 8d08f18a Kostas Papadimitriou
        hide_indicator: function(vm) {
408 8d08f18a Kostas Papadimitriou
            this.vm(vm).find(".action-indicator").removeClass().addClass("action-indicator").hide();
409 8d08f18a Kostas Papadimitriou
            this.update_transition_state(vm);
410 8d08f18a Kostas Papadimitriou
        },
411 8d08f18a Kostas Papadimitriou
412 8d08f18a Kostas Papadimitriou
        // display transition animations
413 8d08f18a Kostas Papadimitriou
        show_transition: function(vm) {
414 8d08f18a Kostas Papadimitriou
            var wave = this.sel('vm_wave', vm.id);
415 8d08f18a Kostas Papadimitriou
            if (!wave || !wave.length) { return }
416 8d08f18a Kostas Papadimitriou
417 8d08f18a Kostas Papadimitriou
            var src = wave.attr('src');
418 8d08f18a Kostas Papadimitriou
            // change src to force gif play from the first frame
419 8d08f18a Kostas Papadimitriou
            // animate for 500 ms then hide
420 8d08f18a Kostas Papadimitriou
            wave.attr('src', "").show();
421 8d08f18a Kostas Papadimitriou
            wave.attr('src', src).fadeIn(200).delay(700).fadeOut(300, function() {
422 8d08f18a Kostas Papadimitriou
                wave.hide();
423 8d08f18a Kostas Papadimitriou
            });
424 8d08f18a Kostas Papadimitriou
        },
425 8d08f18a Kostas Papadimitriou
426 8d08f18a Kostas Papadimitriou
        connect_to_console: function(vm) {
427 738a9b18 Kostas Papadimitriou
            // It seems that Safari allows popup windows only if the window.open
428 738a9b18 Kostas Papadimitriou
            // call is made within an html element click event context. 
429 738a9b18 Kostas Papadimitriou
            // Otherwise its behaviour is based on "Block Pop-Up Windows" 
430 738a9b18 Kostas Papadimitriou
            // setting, which when enabled no notification appears for the user. 
431 738a9b18 Kostas Papadimitriou
            // Since there is no easy way to check for the setting value we use
432 738a9b18 Kostas Papadimitriou
            // async:false for the action call so that action success handler 
433 738a9b18 Kostas Papadimitriou
            // which opens the new window is called inside the click event 
434 738a9b18 Kostas Papadimitriou
            // context.
435 738a9b18 Kostas Papadimitriou
            var use_async = true;
436 738a9b18 Kostas Papadimitriou
            if ($.client.browser == "Safari") {
437 738a9b18 Kostas Papadimitriou
                use_async = false;
438 738a9b18 Kostas Papadimitriou
            }
439 738a9b18 Kostas Papadimitriou
440 8d08f18a Kostas Papadimitriou
            vm.call("console", function(console_data) {
441 8d08f18a Kostas Papadimitriou
                var url = vm.get_console_url(console_data);
442 a0839230 Kostas Papadimitriou
                snf.util.open_window(url, "VM_" + vm.get("id") + "_CONSOLE", {'scrollbars': 1, 'fullscreen': 0});
443 738a9b18 Kostas Papadimitriou
            }, undefined, {async: use_async});
444 8d08f18a Kostas Papadimitriou
        }
445 8d08f18a Kostas Papadimitriou
446 8d08f18a Kostas Papadimitriou
    });
447 8d08f18a Kostas Papadimitriou
    
448 8d08f18a Kostas Papadimitriou
    // empty message view (just a wrapper to the element containing 
449 8d08f18a Kostas Papadimitriou
    // the empty information message)
450 8d08f18a Kostas Papadimitriou
    views.EmptyView = views.View.extend({
451 8d08f18a Kostas Papadimitriou
        el: '#emptymachineslist'
452 8d08f18a Kostas Papadimitriou
    })
453 8d08f18a Kostas Papadimitriou
454 8d08f18a Kostas Papadimitriou
    views.VMActionsView = views.View.extend({
455 8d08f18a Kostas Papadimitriou
        
456 8d08f18a Kostas Papadimitriou
        initialize: function(vm, parent, el, hide) {
457 8d08f18a Kostas Papadimitriou
            this.hide = hide || false;
458 8d08f18a Kostas Papadimitriou
            this.view = parent;
459 8d08f18a Kostas Papadimitriou
            this.vm = vm;
460 8d08f18a Kostas Papadimitriou
            this.vm_el = el;
461 8d08f18a Kostas Papadimitriou
            this.el = $("#" + parent.view_id + "-actions-" + vm.id);
462 8d08f18a Kostas Papadimitriou
            this.all_action_names = _.keys(views.VMActionsView.STATUS_ACTIONS);
463 8d08f18a Kostas Papadimitriou
            
464 8d08f18a Kostas Papadimitriou
            // state params
465 8d08f18a Kostas Papadimitriou
            this.selected_action = false;
466 8d08f18a Kostas Papadimitriou
467 8d08f18a Kostas Papadimitriou
            _.bindAll(this);
468 8d08f18a Kostas Papadimitriou
            window.acts = this;
469 8d08f18a Kostas Papadimitriou
            this.view_id = "vm_" + vm.id + "_actions";
470 8d08f18a Kostas Papadimitriou
            views.VMActionsView.__super__.initialize.call(this);
471 8d08f18a Kostas Papadimitriou
472 6a3a5bf7 Kostas Papadimitriou
            this.hovered = false;
473 40810d73 Kostas Papadimitriou
            this.set_hover_handlers();
474 8d08f18a Kostas Papadimitriou
        },
475 8d08f18a Kostas Papadimitriou
476 8d08f18a Kostas Papadimitriou
        action: function(name) {
477 8d08f18a Kostas Papadimitriou
            return $(this.el).find(".action-container." + name);
478 8d08f18a Kostas Papadimitriou
        },
479 8d08f18a Kostas Papadimitriou
480 8d08f18a Kostas Papadimitriou
        action_link: function(name) {
481 8d08f18a Kostas Papadimitriou
            return this.action(name).find("a");
482 8d08f18a Kostas Papadimitriou
        },
483 8d08f18a Kostas Papadimitriou
        
484 8d08f18a Kostas Papadimitriou
        action_confirm_cont: function(name) {
485 8d08f18a Kostas Papadimitriou
            return this.action_confirm(name).parent();
486 8d08f18a Kostas Papadimitriou
        },
487 8d08f18a Kostas Papadimitriou
488 8d08f18a Kostas Papadimitriou
        action_confirm: function(name) {
489 8d08f18a Kostas Papadimitriou
            return this.action(name).find("button.yes");
490 8d08f18a Kostas Papadimitriou
        },
491 8d08f18a Kostas Papadimitriou
492 8d08f18a Kostas Papadimitriou
        action_cancel: function(name) {
493 8d08f18a Kostas Papadimitriou
            return this.action(name).find("button.no");
494 8d08f18a Kostas Papadimitriou
        },
495 8d08f18a Kostas Papadimitriou
496 8d08f18a Kostas Papadimitriou
        hide_actions: function() {
497 8d08f18a Kostas Papadimitriou
            $(this.el).find("a").css("visibility", "hidden");
498 8d08f18a Kostas Papadimitriou
        },
499 80bb2140 Kostas Papadimitriou
        
500 80bb2140 Kostas Papadimitriou
        set_can_start: function() {
501 80bb2140 Kostas Papadimitriou
          var el = $(this.el).find("a.action-start").parent();
502 80bb2140 Kostas Papadimitriou
          el.removeClass("disabled-visible");
503 80bb2140 Kostas Papadimitriou
        },
504 80bb2140 Kostas Papadimitriou
505 80bb2140 Kostas Papadimitriou
        set_cannot_start: function() {
506 80bb2140 Kostas Papadimitriou
          var el = $(this.el).find("a.action-start").parent();
507 80bb2140 Kostas Papadimitriou
          el.addClass("disabled-visible")
508 80bb2140 Kostas Papadimitriou
        },
509 8d08f18a Kostas Papadimitriou
510 8d08f18a Kostas Papadimitriou
        // update the actions layout, depending on the selected actions
511 8d08f18a Kostas Papadimitriou
        update_layout: function() {
512 80bb2140 Kostas Papadimitriou
            
513 80bb2140 Kostas Papadimitriou
            if (this.vm.get('status') == 'STOPPED') {
514 80bb2140 Kostas Papadimitriou
              if (this.vm.can_start()) {
515 80bb2140 Kostas Papadimitriou
                this.set_can_start();
516 80bb2140 Kostas Papadimitriou
              } else {
517 80bb2140 Kostas Papadimitriou
                this.set_cannot_start();
518 80bb2140 Kostas Papadimitriou
              }
519 80bb2140 Kostas Papadimitriou
            }
520 a09b6d74 Kostas Papadimitriou
521 a09b6d74 Kostas Papadimitriou
            if (!this.vm_handlers_initialized) {
522 8d08f18a Kostas Papadimitriou
                this.vm = storage.vms.get(this.vm.id);
523 6a3a5bf7 Kostas Papadimitriou
                this.init_vm_handlers();
524 a09b6d74 Kostas Papadimitriou
            }
525 122850c5 Kostas Papadimitriou
526 8d08f18a Kostas Papadimitriou
            if (!this.vm) { return }
527 6a3a5bf7 Kostas Papadimitriou
            
528 40810d73 Kostas Papadimitriou
            if (!this.hovered && !this.vm.has_pending_action() && this.hide && !this.vm.action_error) { 
529 40810d73 Kostas Papadimitriou
                this.el.hide();
530 40810d73 Kostas Papadimitriou
                this.view.hide_indicator(this.vm);
531 40810d73 Kostas Papadimitriou
                return 
532 40810d73 Kostas Papadimitriou
            };
533 40810d73 Kostas Papadimitriou
534 40810d73 Kostas Papadimitriou
            if (!this.el.is(":visible") && !this.hide) { return };
535 40810d73 Kostas Papadimitriou
            if (!this.handlers_initialized) { this.set_handlers(); }
536 40810d73 Kostas Papadimitriou
537 40810d73 Kostas Papadimitriou
538 8d08f18a Kostas Papadimitriou
            // update selected action
539 8d08f18a Kostas Papadimitriou
            if (this.vm.pending_action) {
540 8d08f18a Kostas Papadimitriou
                this.selected_action = this.vm.pending_action;
541 8d08f18a Kostas Papadimitriou
            } else {
542 8d08f18a Kostas Papadimitriou
                this.selected_action = false;
543 8d08f18a Kostas Papadimitriou
            }
544 8d08f18a Kostas Papadimitriou
            
545 8d08f18a Kostas Papadimitriou
            // vm actions tha can be performed
546 8d08f18a Kostas Papadimitriou
            var actions = this.vm.get_available_actions();
547 8d08f18a Kostas Papadimitriou
            
548 8d08f18a Kostas Papadimitriou
            // had pending action but actions changed and now selected action is
549 8d08f18a Kostas Papadimitriou
            // not available, hide it from user
550 8d08f18a Kostas Papadimitriou
            if (this.selected_action && actions.indexOf(this.selected_action) == -1) {
551 8d08f18a Kostas Papadimitriou
                this.reset();
552 8d08f18a Kostas Papadimitriou
            }
553 8d08f18a Kostas Papadimitriou
            
554 6a3a5bf7 Kostas Papadimitriou
            this.el.show();
555 6a3a5bf7 Kostas Papadimitriou
            
556 6a3a5bf7 Kostas Papadimitriou
            if ((this.selected_action || this.hovered) && !this.vm.action_error) {
557 8d08f18a Kostas Papadimitriou
                // show selected action
558 8d08f18a Kostas Papadimitriou
                $(this.el).show();
559 8d08f18a Kostas Papadimitriou
                $(this.el).find("a").css("visibility", "visible");
560 8d08f18a Kostas Papadimitriou
                // show action icon
561 8d08f18a Kostas Papadimitriou
                this.view.show_indicator(this.vm);
562 8d08f18a Kostas Papadimitriou
            } else {
563 6a3a5bf7 Kostas Papadimitriou
                if (this.hide || this.vm.action_error) {
564 8d08f18a Kostas Papadimitriou
                    // view shows actions on machine hover
565 122850c5 Kostas Papadimitriou
                    $(this.el).find("a").css("visibility", "hidden");
566 8d08f18a Kostas Papadimitriou
                } else {
567 6a3a5bf7 Kostas Papadimitriou
                    if (!this.vm.action_error) {
568 6a3a5bf7 Kostas Papadimitriou
                        // view shows actions always
569 6a3a5bf7 Kostas Papadimitriou
                        $(this.el).find("a").css("visibility", "visible");
570 6a3a5bf7 Kostas Papadimitriou
                        $(this.el).show();
571 6a3a5bf7 Kostas Papadimitriou
                    }
572 8d08f18a Kostas Papadimitriou
                }
573 8d08f18a Kostas Papadimitriou
                
574 8d08f18a Kostas Papadimitriou
                this.view.hide_indicator(this.vm);
575 8d08f18a Kostas Papadimitriou
            }
576 a09b6d74 Kostas Papadimitriou
                
577 8d08f18a Kostas Papadimitriou
            // update action link styles and shit
578 8d08f18a Kostas Papadimitriou
            _.each(models.VM.ACTIONS, function(action, index) {
579 8d08f18a Kostas Papadimitriou
                if (actions.indexOf(action) > -1) {
580 8d08f18a Kostas Papadimitriou
                    this.action(action).removeClass("disabled");
581 13925182 Kostas Papadimitriou
                    var inactive = models.VM.AVAILABLE_ACTIONS_INACTIVE[action];
582 13925182 Kostas Papadimitriou
583 2b516a38 Kostas Papadimitriou
                    if (inactive && !_.contains(inactive, this.vm.get('status'))) {
584 13925182 Kostas Papadimitriou
                      this.action(action).addClass("inactive");
585 13925182 Kostas Papadimitriou
                    } else {
586 13925182 Kostas Papadimitriou
                      this.action(action).removeClass("inactive");
587 13925182 Kostas Papadimitriou
                    }
588 13925182 Kostas Papadimitriou
589 8d08f18a Kostas Papadimitriou
                    if (this.selected_action == action) {
590 8d08f18a Kostas Papadimitriou
                        this.action_confirm_cont(action).css('display', 'block');
591 8d08f18a Kostas Papadimitriou
                        this.action_confirm(action).show();
592 8d08f18a Kostas Papadimitriou
                        this.action(action).removeClass("disabled");
593 8d08f18a Kostas Papadimitriou
                        this.action_link(action).addClass("selected");
594 8d08f18a Kostas Papadimitriou
                    } else {
595 8d08f18a Kostas Papadimitriou
                        this.action_confirm_cont(action).hide();
596 8d08f18a Kostas Papadimitriou
                        this.action_confirm(action).hide();
597 8d08f18a Kostas Papadimitriou
                        this.action_link(action).removeClass("selected");
598 8d08f18a Kostas Papadimitriou
                    }
599 8d08f18a Kostas Papadimitriou
                } else {
600 8d08f18a Kostas Papadimitriou
                    this.action().hide();
601 8d08f18a Kostas Papadimitriou
                    this.action(action).addClass("disabled");
602 8d08f18a Kostas Papadimitriou
                    this.action_confirm(action).hide();
603 8d08f18a Kostas Papadimitriou
                }
604 8d08f18a Kostas Papadimitriou
            }, this);
605 8d08f18a Kostas Papadimitriou
        },
606 8d08f18a Kostas Papadimitriou
        
607 6a3a5bf7 Kostas Papadimitriou
        init_vm_handlers: function() {
608 6a3a5bf7 Kostas Papadimitriou
            try {
609 6a3a5bf7 Kostas Papadimitriou
                this.vm.unbind("action:fail", this.update_layout)
610 6a3a5bf7 Kostas Papadimitriou
                this.vm.unbind("action:fail:reset", this.update_layout)
611 a09b6d74 Kostas Papadimitriou
            } catch (err) { console.log("Error")};
612 a09b6d74 Kostas Papadimitriou
            
613 6a3a5bf7 Kostas Papadimitriou
            this.vm.bind("action:fail", this.update_layout)
614 6a3a5bf7 Kostas Papadimitriou
            this.vm.bind("action:fail:reset", this.update_layout)
615 a09b6d74 Kostas Papadimitriou
616 a09b6d74 Kostas Papadimitriou
            this.vm_handlers_initialized = true;
617 6a3a5bf7 Kostas Papadimitriou
        },
618 40810d73 Kostas Papadimitriou
        
619 40810d73 Kostas Papadimitriou
        set_hover_handlers: function() {
620 8d08f18a Kostas Papadimitriou
            // vm container hover (icon view)
621 6a3a5bf7 Kostas Papadimitriou
            this.view.vm(this.vm).hover(_.bind(function() {
622 6a3a5bf7 Kostas Papadimitriou
                this.hovered = true;
623 6a3a5bf7 Kostas Papadimitriou
                this.update_layout();
624 8d08f18a Kostas Papadimitriou
625 6a3a5bf7 Kostas Papadimitriou
            }, this),  _.bind(function() {
626 c343513e Kostas Papadimitriou
                this.hovered = false;
627 c343513e Kostas Papadimitriou
                this.update_layout();
628 6a3a5bf7 Kostas Papadimitriou
            }, this));
629 40810d73 Kostas Papadimitriou
        },
630 6a3a5bf7 Kostas Papadimitriou
631 40810d73 Kostas Papadimitriou
        // bind event handlers
632 40810d73 Kostas Papadimitriou
        set_handlers: function() {
633 40810d73 Kostas Papadimitriou
            var self = this;
634 40810d73 Kostas Papadimitriou
            var vm = this.vm;
635 40810d73 Kostas Papadimitriou
            
636 40810d73 Kostas Papadimitriou
            // initial hide
637 40810d73 Kostas Papadimitriou
            if (this.hide) { $(this.el).hide() };
638 8d08f18a Kostas Papadimitriou
            
639 8d08f18a Kostas Papadimitriou
            // action links events
640 8d08f18a Kostas Papadimitriou
            _.each(models.VM.ACTIONS, function(action) {
641 8d08f18a Kostas Papadimitriou
                var action = action;
642 8d08f18a Kostas Papadimitriou
                // indicator hovers
643 8d08f18a Kostas Papadimitriou
                this.view.vm(this.vm).find(".action-container."+action+" a").hover(function() {
644 8d08f18a Kostas Papadimitriou
                    self.view.show_indicator(self.vm, action);
645 8d08f18a Kostas Papadimitriou
                }, function() {
646 8d08f18a Kostas Papadimitriou
                    // clear or show selected action indicator
647 8d08f18a Kostas Papadimitriou
                    if (self.vm.pending_action) {
648 8d08f18a Kostas Papadimitriou
                        self.view.show_indicator(self.vm);
649 8d08f18a Kostas Papadimitriou
                    } else {
650 8d08f18a Kostas Papadimitriou
                        self.view.hide_indicator(self.vm);
651 8d08f18a Kostas Papadimitriou
                    }
652 8d08f18a Kostas Papadimitriou
                })
653 8d08f18a Kostas Papadimitriou
                
654 8d08f18a Kostas Papadimitriou
                // action links click events
655 8d08f18a Kostas Papadimitriou
                $(this.el).find(".action-container."+action+" a").click(function(ev) {
656 8d08f18a Kostas Papadimitriou
                    ev.preventDefault();
657 2c239b28 Kostas Papadimitriou
                    if (action == "start" && !self.vm.can_start() && !vm.in_error_state()) {
658 80bb2140 Kostas Papadimitriou
                        ui.main.vm_resize_view.show_with_warning(self.vm);
659 80bb2140 Kostas Papadimitriou
                        return;
660 80bb2140 Kostas Papadimitriou
                    }
661 80bb2140 Kostas Papadimitriou
662 13925182 Kostas Papadimitriou
                    if (action == "resize") {
663 13925182 Kostas Papadimitriou
                        ui.main.vm_resize_view.show(self.vm);
664 80bb2140 Kostas Papadimitriou
                        return;
665 13925182 Kostas Papadimitriou
                    } else {
666 13925182 Kostas Papadimitriou
                        self.set(action);
667 13925182 Kostas Papadimitriou
                    }
668 8d08f18a Kostas Papadimitriou
                }).data("action", action);
669 8d08f18a Kostas Papadimitriou
670 8d08f18a Kostas Papadimitriou
                // confirms
671 8d08f18a Kostas Papadimitriou
                $(this.el).find(".action-container."+action+" button.no").click(function(ev) {
672 8d08f18a Kostas Papadimitriou
                    ev.preventDefault();
673 8d08f18a Kostas Papadimitriou
                    self.reset();
674 8d08f18a Kostas Papadimitriou
                });
675 8d08f18a Kostas Papadimitriou
676 8d08f18a Kostas Papadimitriou
                // cancels
677 8d08f18a Kostas Papadimitriou
                $(this.el).find(".action-container."+action+" button.yes").click(function(ev) {
678 8d08f18a Kostas Papadimitriou
                    ev.preventDefault();
679 b042eb04 Kostas Papadimitriou
                    // override console
680 b042eb04 Kostas Papadimitriou
                    // ui needs to act (open the console window)
681 b042eb04 Kostas Papadimitriou
                    if (action == "console") {
682 b042eb04 Kostas Papadimitriou
                        self.view.connect_to_console(self.vm);
683 b042eb04 Kostas Papadimitriou
                    } else {
684 b042eb04 Kostas Papadimitriou
                        self.vm.call(action);
685 b042eb04 Kostas Papadimitriou
                    }
686 8d08f18a Kostas Papadimitriou
                    self.reset();
687 8d08f18a Kostas Papadimitriou
                });
688 8d08f18a Kostas Papadimitriou
            }, this);
689 40810d73 Kostas Papadimitriou
690 40810d73 Kostas Papadimitriou
            this.handlers_initialized = true;
691 8d08f18a Kostas Papadimitriou
        },
692 8d08f18a Kostas Papadimitriou
        
693 8d08f18a Kostas Papadimitriou
        // reset actions
694 8d08f18a Kostas Papadimitriou
        reset: function() {
695 8d08f18a Kostas Papadimitriou
            var prev_action = this.selected_action;
696 8d08f18a Kostas Papadimitriou
            this.selected_action = false;
697 8d08f18a Kostas Papadimitriou
            this.vm.clear_pending_action();
698 8d08f18a Kostas Papadimitriou
            this.trigger("change", {'action': prev_action, 'vm': this.vm, 'view': this, remove: true});
699 8d08f18a Kostas Papadimitriou
            this.trigger("remove", {'action': prev_action, 'vm': this.vm, 'view': this, remove: true});
700 8d08f18a Kostas Papadimitriou
        },
701 8d08f18a Kostas Papadimitriou
        
702 8d08f18a Kostas Papadimitriou
        // set selected action
703 8d08f18a Kostas Papadimitriou
        set: function(action_name) {
704 d6d1f049 Kostas Papadimitriou
            if (action_name == "snapshot") { return }
705 8d08f18a Kostas Papadimitriou
            this.selected_action = action_name;
706 8d08f18a Kostas Papadimitriou
            this.vm.update_pending_action(this.selected_action);
707 8d08f18a Kostas Papadimitriou
            this.view.vm(this.vm).find(".action-indicator").show().removeClass().addClass(action_name + " action-indicator");
708 8d08f18a Kostas Papadimitriou
            this.trigger("change", {'action': this.selected_action, 'vm': this.vm, 'view': this});
709 8d08f18a Kostas Papadimitriou
        },
710 8d08f18a Kostas Papadimitriou
711 8d08f18a Kostas Papadimitriou
        update: function() {
712 8d08f18a Kostas Papadimitriou
        }
713 8d08f18a Kostas Papadimitriou
    })
714 8d08f18a Kostas Papadimitriou
715 8d08f18a Kostas Papadimitriou
716 8d08f18a Kostas Papadimitriou
    views.VMActionsView.STATUS_ACTIONS = { 
717 8d08f18a Kostas Papadimitriou
        'reboot':        ['UNKOWN', 'ACTIVE', 'REBOOT'],
718 8d08f18a Kostas Papadimitriou
        'shutdown':      ['UNKOWN', 'ACTIVE', 'REBOOT'],
719 8d08f18a Kostas Papadimitriou
        'console':       ['ACTIVE'],
720 8d08f18a Kostas Papadimitriou
        'start':         ['UNKOWN', 'STOPPED'],
721 13925182 Kostas Papadimitriou
        'resize':        ['UNKOWN', 'ACTIVE', 'STOPPED', 'REBOOT', 'ERROR', 'BUILD'],
722 de0693f8 Kostas Papadimitriou
        'snapshot':      ['ACTIVE', 'STOPPED'],
723 8d08f18a Kostas Papadimitriou
        'destroy':       ['UNKOWN', 'ACTIVE', 'STOPPED', 'REBOOT', 'ERROR', 'BUILD']
724 8d08f18a Kostas Papadimitriou
    };
725 8d08f18a Kostas Papadimitriou
726 8d08f18a Kostas Papadimitriou
    // UI helpers
727 8d08f18a Kostas Papadimitriou
    var uihelpers = snf.ui.helpers = {};
728 f5b3adc1 Kostas Papadimitriou
    
729 f5b3adc1 Kostas Papadimitriou
    // OS icon helpers
730 f5b3adc1 Kostas Papadimitriou
    var os_icon = uihelpers.os_icon = function(os) {
731 8d08f18a Kostas Papadimitriou
        var icons = window.os_icons;
732 d42817ee Olga Brani
        if (!icons) { return "unknown" }
733 8d08f18a Kostas Papadimitriou
        if (icons.indexOf(os) == -1) {
734 d42817ee Olga Brani
            os = "unknown";
735 8d08f18a Kostas Papadimitriou
        }
736 8d08f18a Kostas Papadimitriou
        return os;
737 8d08f18a Kostas Papadimitriou
    }
738 f5b3adc1 Kostas Papadimitriou
739 f5b3adc1 Kostas Papadimitriou
    var os_icon_path = uihelpers.os_icon_path = function(os, size, active) {
740 8d08f18a Kostas Papadimitriou
        size = size || "small";
741 f5b3adc1 Kostas Papadimitriou
        if (active == undefined) { active = true };
742 8d08f18a Kostas Papadimitriou
743 f5b3adc1 Kostas Papadimitriou
        var icon = os_icon(os);
744 f5b3adc1 Kostas Papadimitriou
        if (active) {
745 8d08f18a Kostas Papadimitriou
            icon = icon + "-on";
746 8d08f18a Kostas Papadimitriou
        } else {
747 8d08f18a Kostas Papadimitriou
            icon = icon + "-off";
748 8d08f18a Kostas Papadimitriou
        }
749 8d08f18a Kostas Papadimitriou
750 c62c6b91 Kostas Papadimitriou
        return (snf.config.machines_icons_url + "{0}/{1}.png").format(size, icon)
751 8d08f18a Kostas Papadimitriou
    }
752 f5b3adc1 Kostas Papadimitriou
753 f5b3adc1 Kostas Papadimitriou
    var os_icon_tag = uihelpers.os_icon_tag = function (os, size, active, attrs) {
754 f5b3adc1 Kostas Papadimitriou
        attrs = attrs || {};
755 f5b3adc1 Kostas Papadimitriou
        return '<img src="{0}" />'.format(os_icon_path(os, size, active));
756 f5b3adc1 Kostas Papadimitriou
    }
757 f5b3adc1 Kostas Papadimitriou
758 f5b3adc1 Kostas Papadimitriou
    // VM Icon helpers
759 f5b3adc1 Kostas Papadimitriou
    //
760 f5b3adc1 Kostas Papadimitriou
    // identify icon
761 f5b3adc1 Kostas Papadimitriou
    var vm_icon = uihelpers.vm_icon = function(vm) {
762 f5b3adc1 Kostas Papadimitriou
        return os_icon(vm.get_os());
763 f5b3adc1 Kostas Papadimitriou
    }
764 f5b3adc1 Kostas Papadimitriou
    
765 f5b3adc1 Kostas Papadimitriou
    // get icon url
766 f5b3adc1 Kostas Papadimitriou
    var vm_icon_path = uihelpers.vm_icon_path = function(vm, size) {
767 f5b3adc1 Kostas Papadimitriou
        return os_icon_path(vm.get_os(), size, vm.is_active());
768 f5b3adc1 Kostas Papadimitriou
    }
769 8d08f18a Kostas Papadimitriou
    
770 8d08f18a Kostas Papadimitriou
    // get icon IMG tag
771 8d08f18a Kostas Papadimitriou
    var vm_icon_tag = uihelpers.vm_icon_tag = function (vm, size, attrs) {
772 f5b3adc1 Kostas Papadimitriou
       return os_icon_tag(vm.get_os(), size, vm.is_active(), attrs);
773 8d08f18a Kostas Papadimitriou
    }
774 8d08f18a Kostas Papadimitriou
    
775 9ffd10ce Kostas Papadimitriou
776 8d08f18a Kostas Papadimitriou
    snf.ui = _.extend(snf.ui, bb.Events);
777 9ffd10ce Kostas Papadimitriou
    snf.ui.trigger_error = function(code, msg, error, extra) {
778 52a432c7 Kostas Papadimitriou
        if (msg.match(/Script error/i)) {
779 52a432c7 Kostas Papadimitriou
          // No usefull information to display in this case. Plus it's an
780 52a432c7 Kostas Papadimitriou
          // exception that probably doesn't affect our app.
781 52a432c7 Kostas Papadimitriou
          return 0;
782 52a432c7 Kostas Papadimitriou
        }
783 52a432c7 Kostas Papadimitriou
        snf.ui.trigger("error", { code:code, msg:msg, error:error, extra:extra || {} });
784 9ffd10ce Kostas Papadimitriou
    };
785 365af933 Kostas Papadimitriou
    
786 365af933 Kostas Papadimitriou
    views.VMPortView = views.ext.ModelView.extend({
787 365af933 Kostas Papadimitriou
      tpl: '#vm-port-view-tpl',
788 365af933 Kostas Papadimitriou
      classes: 'port-item clearfix',
789 9145aad9 Kostas Papadimitriou
      
790 9145aad9 Kostas Papadimitriou
      update_in_progress: function() {
791 5d213e95 Kostas Papadimitriou
        if (this.model.get("in_progress_no_vm")) {
792 9145aad9 Kostas Papadimitriou
          this.set_in_progress();
793 9145aad9 Kostas Papadimitriou
        } else {
794 9145aad9 Kostas Papadimitriou
          this.unset_in_progress();
795 9145aad9 Kostas Papadimitriou
        }
796 9145aad9 Kostas Papadimitriou
      },
797 9145aad9 Kostas Papadimitriou
798 9145aad9 Kostas Papadimitriou
      set_in_progress: function() {
799 9145aad9 Kostas Papadimitriou
        this.el.find(".type").hide();
800 90fbedb6 Kostas Papadimitriou
        this.el.find(".in-progress").removeClass("hidden").show();
801 9145aad9 Kostas Papadimitriou
      },
802 9145aad9 Kostas Papadimitriou
803 9145aad9 Kostas Papadimitriou
      unset_in_progress: function() {
804 9145aad9 Kostas Papadimitriou
        this.el.find(".type").show();
805 9145aad9 Kostas Papadimitriou
        this.el.find(".in-progress").hide();
806 9145aad9 Kostas Papadimitriou
      },
807 9145aad9 Kostas Papadimitriou
808 9145aad9 Kostas Papadimitriou
      disconnect_port: function(model, e) {
809 9145aad9 Kostas Papadimitriou
        e && e.stopPropagation();
810 9145aad9 Kostas Papadimitriou
        var network = this.model.get("network");
811 9145aad9 Kostas Papadimitriou
        this.model.actions.reset_pending();
812 9145aad9 Kostas Papadimitriou
        this.model.disconnect(_.bind(this.disconnect_port_complete, this));
813 9145aad9 Kostas Papadimitriou
      },
814 9145aad9 Kostas Papadimitriou
815 9145aad9 Kostas Papadimitriou
      disconnect_port_complete: function() {
816 9145aad9 Kostas Papadimitriou
      },
817 9145aad9 Kostas Papadimitriou
818 365af933 Kostas Papadimitriou
      get_network_name: function() {
819 365af933 Kostas Papadimitriou
        var network = this.model.get('network');
820 365af933 Kostas Papadimitriou
        var name = network && network.get('name');
821 365af933 Kostas Papadimitriou
        if (!name) {
822 33299f73 Kostas Papadimitriou
          if (network && network.get('is_public')) {
823 efb056c0 Kostas Papadimitriou
            name = 'Internet'
824 efb056c0 Kostas Papadimitriou
          } else {
825 efb056c0 Kostas Papadimitriou
            name = '(no network name)'
826 efb056c0 Kostas Papadimitriou
          }
827 365af933 Kostas Papadimitriou
        }
828 af32efaa Kostas Papadimitriou
        var truncate_length = this.parent_view.options.truncate || 40;
829 6201f0e3 Kostas Papadimitriou
        name = synnefo.util.truncate(name, truncate_length, '...');
830 365af933 Kostas Papadimitriou
        return name || 'Loading...';
831 365af933 Kostas Papadimitriou
      },
832 365af933 Kostas Papadimitriou
833 365af933 Kostas Papadimitriou
      get_network_icon: function() {
834 365af933 Kostas Papadimitriou
        var ico;
835 365af933 Kostas Papadimitriou
        var network = this.model.get('network');
836 365af933 Kostas Papadimitriou
        if (network) {
837 365af933 Kostas Papadimitriou
          ico = network.get('is_public') ? 'internet-small.png' : 'network-small.png';
838 365af933 Kostas Papadimitriou
        } else {
839 365af933 Kostas Papadimitriou
          ico = 'network-small.png';
840 365af933 Kostas Papadimitriou
        }
841 365af933 Kostas Papadimitriou
        return synnefo.config.media_url + 'images/' + ico;
842 365af933 Kostas Papadimitriou
      },
843 365af933 Kostas Papadimitriou
    });
844 365af933 Kostas Papadimitriou
    
845 365af933 Kostas Papadimitriou
    views.VMPortListView = views.ext.CollectionView.extend({
846 365af933 Kostas Papadimitriou
      tpl: '#vm-port-list-view-tpl',
847 365af933 Kostas Papadimitriou
      model_view_cls: views.VMPortView
848 365af933 Kostas Papadimitriou
    });
849 365af933 Kostas Papadimitriou
850 365af933 Kostas Papadimitriou
    views.VMPortIpView = views.ext.ModelView.extend({
851 9145aad9 Kostas Papadimitriou
      tpl: '#vm-port-ip-tpl',
852 9145aad9 Kostas Papadimitriou
      css_classes: "clearfix"
853 365af933 Kostas Papadimitriou
    });
854 365af933 Kostas Papadimitriou
855 365af933 Kostas Papadimitriou
    views.VMPortIpsView = views.ext.CollectionView.extend({
856 365af933 Kostas Papadimitriou
      tpl: '#vm-port-ips-tpl',
857 365af933 Kostas Papadimitriou
      model_view_cls: views.VMPortIpView
858 365af933 Kostas Papadimitriou
    });
859 8d08f18a Kostas Papadimitriou
860 8d08f18a Kostas Papadimitriou
})(this);