Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / ui / static / snf / js / ui / web / ui_vms_base_view.js @ 3635e7ac

History | View | Annotate | Download (25.8 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 75331d54 Kostas Papadimitriou
            return vm_view;
212 8d08f18a Kostas Papadimitriou
        },
213 8d08f18a Kostas Papadimitriou
        
214 8d08f18a Kostas Papadimitriou
        // create vm dom element
215 8d08f18a Kostas Papadimitriou
        create_vm_element: function(vm) {
216 8d08f18a Kostas Papadimitriou
            // clone template
217 23a3bb8e Kostas Papadimitriou
            return this.sel('tpl').clone().attr("id", this.id_tpl + vm.id)
218 8d08f18a Kostas Papadimitriou
        },
219 8d08f18a Kostas Papadimitriou
220 8d08f18a Kostas Papadimitriou
        // get proper vm container
221 8d08f18a Kostas Papadimitriou
        get_vm_container: function(vm) {
222 8d08f18a Kostas Papadimitriou
            if (vm.is_active()) {
223 8d08f18a Kostas Papadimitriou
                return this.sel("vm_cont_active");
224 8d08f18a Kostas Papadimitriou
            } else {
225 8d08f18a Kostas Papadimitriou
                return this.sel("vm_cont_terminated");
226 8d08f18a Kostas Papadimitriou
            }
227 8d08f18a Kostas Papadimitriou
        },
228 8d08f18a Kostas Papadimitriou
229 8d08f18a Kostas Papadimitriou
        // create and append inside the proper container the vm model
230 8d08f18a Kostas Papadimitriou
        // if it doesn't exist update vm data and make it visible
231 8d08f18a Kostas Papadimitriou
        add: function(vm) {
232 8d08f18a Kostas Papadimitriou
            // create if it does not exist
233 75331d54 Kostas Papadimitriou
            if (!hasKey.call(this._vm_els, vm.id)) {
234 75331d54 Kostas Papadimitriou
                var el = this.create_vm(vm);
235 75331d54 Kostas Papadimitriou
                el.show();
236 c343513e Kostas Papadimitriou
                this.post_add(vm);
237 1e882dd7 Kostas Papadimitriou
                this.init_vm_view_handlers(vm);
238 8d08f18a Kostas Papadimitriou
            }
239 8d08f18a Kostas Papadimitriou
240 8d08f18a Kostas Papadimitriou
            return this.vm(vm);
241 8d08f18a Kostas Papadimitriou
        },
242 1e882dd7 Kostas Papadimitriou
243 1e882dd7 Kostas Papadimitriou
        init_vm_view_handlers: function(vm) {
244 1e882dd7 Kostas Papadimitriou
            var self = this;
245 1e882dd7 Kostas Papadimitriou
            var el = this.vm(vm);
246 1e882dd7 Kostas Papadimitriou
247 1e882dd7 Kostas Papadimitriou
            // hidden feature, double click on indicators to display 
248 1e882dd7 Kostas Papadimitriou
            // vm diagnostics.
249 1e882dd7 Kostas Papadimitriou
            el.find(".indicators").bind("dblclick", function(){
250 1e882dd7 Kostas Papadimitriou
                self.show_build_details_for_vm(vm);
251 1e882dd7 Kostas Papadimitriou
            });
252 1e882dd7 Kostas Papadimitriou
253 1e882dd7 Kostas Papadimitriou
            // this button gets visible if vm creation failed.
254 1e882dd7 Kostas Papadimitriou
            el.find("div.build-progress .btn").click(function(){
255 1e882dd7 Kostas Papadimitriou
                self.show_build_details_for_vm(vm);
256 1e882dd7 Kostas Papadimitriou
            });
257 1e882dd7 Kostas Papadimitriou
        },
258 8d08f18a Kostas Papadimitriou
        
259 8d08f18a Kostas Papadimitriou
        // helpers for VMListView descendants
260 8d08f18a Kostas Papadimitriou
        post_add: function(vm) { throw "Not implemented" },
261 8d08f18a Kostas Papadimitriou
        set_vm_handlers: function(vm) { throw "Not implemented" },
262 8d08f18a Kostas Papadimitriou
        set_handlers: function() { throw "Not implemented" },
263 8d08f18a Kostas Papadimitriou
        update_layout: function() { throw "Not implemented" },
264 8d08f18a Kostas Papadimitriou
        post_update_vm: function(vm) { throw "Not implemented" },
265 8d08f18a Kostas Papadimitriou
        update_details: function(vm) {},
266 8d08f18a Kostas Papadimitriou
        
267 8d08f18a Kostas Papadimitriou
        // remove vm
268 8d08f18a Kostas Papadimitriou
        remove_vm: function(vm) {
269 8d08f18a Kostas Papadimitriou
            // FIXME: some kind of transiton ??? effect maybe ???
270 8d08f18a Kostas Papadimitriou
            this.vm(vm).remove();
271 8d08f18a Kostas Papadimitriou
            this.post_remove_vm(vm);
272 75331d54 Kostas Papadimitriou
            if (hasKey.call(this._vm_els, vm.id)) {
273 75331d54 Kostas Papadimitriou
                delete this._vm_els[vm.id];
274 75331d54 Kostas Papadimitriou
            }
275 8d08f18a Kostas Papadimitriou
        },
276 8d08f18a Kostas Papadimitriou
        
277 8d08f18a Kostas Papadimitriou
        // remove all vms from view
278 8d08f18a Kostas Papadimitriou
        clear: function() {
279 8d08f18a Kostas Papadimitriou
            this.sel('vms').remove();
280 8d08f18a Kostas Papadimitriou
            this.__update_layout();
281 8d08f18a Kostas Papadimitriou
        },
282 8d08f18a Kostas Papadimitriou
283 2506f741 Kostas Papadimitriou
        show: function() {
284 2506f741 Kostas Papadimitriou
            views.VMListView.__super__.show.apply(this, arguments);
285 f44486d8 Kostas Papadimitriou
            if (storage.vms.length == 0) { this.hide() };
286 5dad72ea Kostas Papadimitriou
            if (!snf.config.update_hidden_views) {
287 5dad72ea Kostas Papadimitriou
                this.update_vms(storage.vms.models);
288 5dad72ea Kostas Papadimitriou
            }
289 2506f741 Kostas Papadimitriou
        },
290 2506f741 Kostas Papadimitriou
291 8d08f18a Kostas Papadimitriou
        // do update for provided vms, then update the view layout
292 8d08f18a Kostas Papadimitriou
        update_vms: function(vms) {
293 5dad72ea Kostas Papadimitriou
            if (!this.visible() && !snf.config.update_hidden_views) { return };
294 5dad72ea Kostas Papadimitriou
295 8d08f18a Kostas Papadimitriou
            _.each(vms, _.bind(function(vm){
296 8d08f18a Kostas Papadimitriou
                // vm will be removed
297 8d08f18a Kostas Papadimitriou
                // no need to update
298 8d08f18a Kostas Papadimitriou
                if (vm.get("status") == "DELETED") {
299 8d08f18a Kostas Papadimitriou
                    return;
300 8d08f18a Kostas Papadimitriou
                }
301 8d08f18a Kostas Papadimitriou
302 8d08f18a Kostas Papadimitriou
                // this won't add it additional times
303 8d08f18a Kostas Papadimitriou
                this.add(vm);
304 8d08f18a Kostas Papadimitriou
                this.update_vm(vm);
305 8d08f18a Kostas Papadimitriou
            }, this))
306 8d08f18a Kostas Papadimitriou
            
307 8d08f18a Kostas Papadimitriou
            // update view stuff
308 8d08f18a Kostas Papadimitriou
            this.__update_layout();
309 8d08f18a Kostas Papadimitriou
        },
310 8d08f18a Kostas Papadimitriou
        
311 8d08f18a Kostas Papadimitriou
        // update ui for the given vm
312 8d08f18a Kostas Papadimitriou
        update_vm: function(vm) {
313 643de8c0 Kostas Papadimitriou
            // do not update deleted state vms
314 643de8c0 Kostas Papadimitriou
            if (!vm || vm.get("status") == 'DELETED') { return };
315 8d08f18a Kostas Papadimitriou
            this.check_vm_container(vm);
316 8d08f18a Kostas Papadimitriou
317 8d08f18a Kostas Papadimitriou
            this.update_details(vm);
318 8d08f18a Kostas Papadimitriou
            this.update_transition_state(vm);
319 8d08f18a Kostas Papadimitriou
320 8d08f18a Kostas Papadimitriou
            if (this.action_views) {
321 8d08f18a Kostas Papadimitriou
                this.action_views[vm.id].update();
322 8d08f18a Kostas Papadimitriou
                this.action_views[vm.id].update_layout();
323 8d08f18a Kostas Papadimitriou
            }
324 8d08f18a Kostas Papadimitriou
            
325 027bdc60 Kostas Papadimitriou
            try {
326 027bdc60 Kostas Papadimitriou
                this.post_update_vm(vm);
327 027bdc60 Kostas Papadimitriou
            } catch (err) {};
328 8d08f18a Kostas Papadimitriou
        },
329 8d08f18a Kostas Papadimitriou
330 8d08f18a Kostas Papadimitriou
        // check if vm is placed properly within the view
331 8d08f18a Kostas Papadimitriou
        // container (e.g. some views might have different
332 8d08f18a Kostas Papadimitriou
        // containers for terminated or running machines
333 8d08f18a Kostas Papadimitriou
        check_vm_container: function(vm){
334 8d08f18a Kostas Papadimitriou
            var el = this.vm(vm);
335 8d08f18a Kostas Papadimitriou
            if (!el.length) { return };
336 8d08f18a Kostas Papadimitriou
            var self = this;
337 8d08f18a Kostas Papadimitriou
            var selector = vm.is_active() ? 'vm_cont_active' : 'vm_cont_terminated';
338 8d08f18a Kostas Papadimitriou
            if (el.parent()[0] != this.sel(selector)[0]) {
339 8d08f18a Kostas Papadimitriou
                var cont = this.sel(selector);
340 8d08f18a Kostas Papadimitriou
                var self = this;
341 7c90e31b Kostas Papadimitriou
342 b042eb04 Kostas Papadimitriou
                el.hide().appendTo(cont).fadeIn(300);
343 7c90e31b Kostas Papadimitriou
                $(window).trigger('resize');
344 7c90e31b Kostas Papadimitriou
345 7c90e31b Kostas Papadimitriou
                //el.fadeOut(200, function() {
346 7c90e31b Kostas Papadimitriou
                    //el.appendTo(cont); 
347 7c90e31b Kostas Papadimitriou
                    //el.fadeIn(200);
348 7c90e31b Kostas Papadimitriou
                    //self.sel(selector).show(function(){
349 7c90e31b Kostas Papadimitriou
                        //$(window).trigger("resize");
350 7c90e31b Kostas Papadimitriou
                    //});
351 7c90e31b Kostas Papadimitriou
                //});
352 8d08f18a Kostas Papadimitriou
            }
353 8d08f18a Kostas Papadimitriou
        },
354 8d08f18a Kostas Papadimitriou
355 8d08f18a Kostas Papadimitriou
        __update_layout: function() {
356 8d08f18a Kostas Papadimitriou
            this.update_layout();
357 8d08f18a Kostas Papadimitriou
        },
358 8d08f18a Kostas Papadimitriou
        
359 8d08f18a Kostas Papadimitriou
        // append handlers for vm specific events
360 8d08f18a Kostas Papadimitriou
        __set_vm_handlers: function(vm) {
361 8d08f18a Kostas Papadimitriou
            // show transition on vm status transit
362 8d08f18a Kostas Papadimitriou
            vm.bind('transition', _.bind(function(){this.show_transition(vm)}, this));
363 8d08f18a Kostas Papadimitriou
            this.set_vm_handlers(vm);
364 8d08f18a Kostas Papadimitriou
        },
365 8d08f18a Kostas Papadimitriou
        
366 8d08f18a Kostas Papadimitriou
        // is vm in transition ??? show the progress spinner
367 8d08f18a Kostas Papadimitriou
        update_transition_state: function(vm) {
368 1e882dd7 Kostas Papadimitriou
            if (vm.in_transition() && !vm.has_pending_action()){
369 8d08f18a Kostas Papadimitriou
                this.sel('vm_spinner', vm.id).show();
370 8d08f18a Kostas Papadimitriou
            } else {
371 8d08f18a Kostas Papadimitriou
                this.sel('vm_spinner', vm.id).hide();
372 8d08f18a Kostas Papadimitriou
            }
373 8d08f18a Kostas Papadimitriou
        },
374 8d08f18a Kostas Papadimitriou
        
375 8d08f18a Kostas Papadimitriou
        show_indicator: function(vm, action) {
376 8d08f18a Kostas Papadimitriou
            var action = action || vm.pending_action;
377 8d08f18a Kostas Papadimitriou
            this.sel('vm_wave', vm.id).hide();
378 8d08f18a Kostas Papadimitriou
            this.sel('vm_spinner', vm.id).hide();
379 8d08f18a Kostas Papadimitriou
            this.vm(vm).find(".action-indicator").removeClass().addClass(action + " action-indicator").show();
380 8d08f18a Kostas Papadimitriou
        },
381 8d08f18a Kostas Papadimitriou
382 8d08f18a Kostas Papadimitriou
        hide_indicator: function(vm) {
383 8d08f18a Kostas Papadimitriou
            this.vm(vm).find(".action-indicator").removeClass().addClass("action-indicator").hide();
384 8d08f18a Kostas Papadimitriou
            this.update_transition_state(vm);
385 8d08f18a Kostas Papadimitriou
        },
386 8d08f18a Kostas Papadimitriou
387 8d08f18a Kostas Papadimitriou
        // display transition animations
388 8d08f18a Kostas Papadimitriou
        show_transition: function(vm) {
389 8d08f18a Kostas Papadimitriou
            var wave = this.sel('vm_wave', vm.id);
390 8d08f18a Kostas Papadimitriou
            if (!wave || !wave.length) { return }
391 8d08f18a Kostas Papadimitriou
392 8d08f18a Kostas Papadimitriou
            var src = wave.attr('src');
393 8d08f18a Kostas Papadimitriou
            // change src to force gif play from the first frame
394 8d08f18a Kostas Papadimitriou
            // animate for 500 ms then hide
395 8d08f18a Kostas Papadimitriou
            wave.attr('src', "").show();
396 8d08f18a Kostas Papadimitriou
            wave.attr('src', src).fadeIn(200).delay(700).fadeOut(300, function() {
397 8d08f18a Kostas Papadimitriou
                wave.hide();
398 8d08f18a Kostas Papadimitriou
            });
399 8d08f18a Kostas Papadimitriou
        },
400 8d08f18a Kostas Papadimitriou
401 8d08f18a Kostas Papadimitriou
        connect_to_console: function(vm) {
402 738a9b18 Kostas Papadimitriou
            // It seems that Safari allows popup windows only if the window.open
403 738a9b18 Kostas Papadimitriou
            // call is made within an html element click event context. 
404 738a9b18 Kostas Papadimitriou
            // Otherwise its behaviour is based on "Block Pop-Up Windows" 
405 738a9b18 Kostas Papadimitriou
            // setting, which when enabled no notification appears for the user. 
406 738a9b18 Kostas Papadimitriou
            // Since there is no easy way to check for the setting value we use
407 738a9b18 Kostas Papadimitriou
            // async:false for the action call so that action success handler 
408 738a9b18 Kostas Papadimitriou
            // which opens the new window is called inside the click event 
409 738a9b18 Kostas Papadimitriou
            // context.
410 738a9b18 Kostas Papadimitriou
            var use_async = true;
411 738a9b18 Kostas Papadimitriou
            if ($.client.browser == "Safari") {
412 738a9b18 Kostas Papadimitriou
                use_async = false;
413 738a9b18 Kostas Papadimitriou
            }
414 738a9b18 Kostas Papadimitriou
415 8d08f18a Kostas Papadimitriou
            vm.call("console", function(console_data) {
416 8d08f18a Kostas Papadimitriou
                var url = vm.get_console_url(console_data);
417 5e6357ff Kostas Papadimitriou
                snf.util.open_window(url, "VM_" + vm.get("id") + "_CONSOLE", {});
418 738a9b18 Kostas Papadimitriou
            }, undefined, {async: use_async});
419 8d08f18a Kostas Papadimitriou
        }
420 8d08f18a Kostas Papadimitriou
421 8d08f18a Kostas Papadimitriou
    });
422 8d08f18a Kostas Papadimitriou
    
423 8d08f18a Kostas Papadimitriou
    // empty message view (just a wrapper to the element containing 
424 8d08f18a Kostas Papadimitriou
    // the empty information message)
425 8d08f18a Kostas Papadimitriou
    views.EmptyView = views.View.extend({
426 8d08f18a Kostas Papadimitriou
        el: '#emptymachineslist'
427 8d08f18a Kostas Papadimitriou
    })
428 8d08f18a Kostas Papadimitriou
429 8d08f18a Kostas Papadimitriou
    views.VMActionsView = views.View.extend({
430 8d08f18a Kostas Papadimitriou
        
431 8d08f18a Kostas Papadimitriou
        initialize: function(vm, parent, el, hide) {
432 8d08f18a Kostas Papadimitriou
            this.hide = hide || false;
433 8d08f18a Kostas Papadimitriou
            this.view = parent;
434 8d08f18a Kostas Papadimitriou
            this.vm = vm;
435 8d08f18a Kostas Papadimitriou
            this.vm_el = el;
436 8d08f18a Kostas Papadimitriou
            this.el = $("#" + parent.view_id + "-actions-" + vm.id);
437 8d08f18a Kostas Papadimitriou
            this.all_action_names = _.keys(views.VMActionsView.STATUS_ACTIONS);
438 8d08f18a Kostas Papadimitriou
            
439 8d08f18a Kostas Papadimitriou
            // state params
440 8d08f18a Kostas Papadimitriou
            this.selected_action = false;
441 8d08f18a Kostas Papadimitriou
442 8d08f18a Kostas Papadimitriou
            _.bindAll(this);
443 8d08f18a Kostas Papadimitriou
            window.acts = this;
444 8d08f18a Kostas Papadimitriou
            this.view_id = "vm_" + vm.id + "_actions";
445 8d08f18a Kostas Papadimitriou
            views.VMActionsView.__super__.initialize.call(this);
446 8d08f18a Kostas Papadimitriou
447 6a3a5bf7 Kostas Papadimitriou
            this.hovered = false;
448 40810d73 Kostas Papadimitriou
            this.set_hover_handlers();
449 8d08f18a Kostas Papadimitriou
        },
450 8d08f18a Kostas Papadimitriou
451 8d08f18a Kostas Papadimitriou
        action: function(name) {
452 8d08f18a Kostas Papadimitriou
            return $(this.el).find(".action-container." + name);
453 8d08f18a Kostas Papadimitriou
        },
454 8d08f18a Kostas Papadimitriou
455 8d08f18a Kostas Papadimitriou
        action_link: function(name) {
456 8d08f18a Kostas Papadimitriou
            return this.action(name).find("a");
457 8d08f18a Kostas Papadimitriou
        },
458 8d08f18a Kostas Papadimitriou
        
459 8d08f18a Kostas Papadimitriou
        action_confirm_cont: function(name) {
460 8d08f18a Kostas Papadimitriou
            return this.action_confirm(name).parent();
461 8d08f18a Kostas Papadimitriou
        },
462 8d08f18a Kostas Papadimitriou
463 8d08f18a Kostas Papadimitriou
        action_confirm: function(name) {
464 8d08f18a Kostas Papadimitriou
            return this.action(name).find("button.yes");
465 8d08f18a Kostas Papadimitriou
        },
466 8d08f18a Kostas Papadimitriou
467 8d08f18a Kostas Papadimitriou
        action_cancel: function(name) {
468 8d08f18a Kostas Papadimitriou
            return this.action(name).find("button.no");
469 8d08f18a Kostas Papadimitriou
        },
470 8d08f18a Kostas Papadimitriou
471 8d08f18a Kostas Papadimitriou
        hide_actions: function() {
472 8d08f18a Kostas Papadimitriou
            $(this.el).find("a").css("visibility", "hidden");
473 8d08f18a Kostas Papadimitriou
        },
474 8d08f18a Kostas Papadimitriou
475 8d08f18a Kostas Papadimitriou
        // update the actions layout, depending on the selected actions
476 8d08f18a Kostas Papadimitriou
        update_layout: function() {
477 a09b6d74 Kostas Papadimitriou
478 a09b6d74 Kostas Papadimitriou
            if (!this.vm_handlers_initialized) {
479 8d08f18a Kostas Papadimitriou
                this.vm = storage.vms.get(this.vm.id);
480 6a3a5bf7 Kostas Papadimitriou
                this.init_vm_handlers();
481 a09b6d74 Kostas Papadimitriou
            }
482 122850c5 Kostas Papadimitriou
483 8d08f18a Kostas Papadimitriou
            if (!this.vm) { return }
484 6a3a5bf7 Kostas Papadimitriou
            
485 40810d73 Kostas Papadimitriou
            if (!this.hovered && !this.vm.has_pending_action() && this.hide && !this.vm.action_error) { 
486 40810d73 Kostas Papadimitriou
                this.el.hide();
487 40810d73 Kostas Papadimitriou
                this.view.hide_indicator(this.vm);
488 40810d73 Kostas Papadimitriou
                return 
489 40810d73 Kostas Papadimitriou
            };
490 40810d73 Kostas Papadimitriou
491 40810d73 Kostas Papadimitriou
            if (!this.el.is(":visible") && !this.hide) { return };
492 40810d73 Kostas Papadimitriou
            if (!this.handlers_initialized) { this.set_handlers(); }
493 40810d73 Kostas Papadimitriou
494 40810d73 Kostas Papadimitriou
495 8d08f18a Kostas Papadimitriou
            // update selected action
496 8d08f18a Kostas Papadimitriou
            if (this.vm.pending_action) {
497 8d08f18a Kostas Papadimitriou
                this.selected_action = this.vm.pending_action;
498 8d08f18a Kostas Papadimitriou
            } else {
499 8d08f18a Kostas Papadimitriou
                this.selected_action = false;
500 8d08f18a Kostas Papadimitriou
            }
501 8d08f18a Kostas Papadimitriou
            
502 8d08f18a Kostas Papadimitriou
            // vm actions tha can be performed
503 8d08f18a Kostas Papadimitriou
            var actions = this.vm.get_available_actions();
504 8d08f18a Kostas Papadimitriou
            
505 8d08f18a Kostas Papadimitriou
            // had pending action but actions changed and now selected action is
506 8d08f18a Kostas Papadimitriou
            // not available, hide it from user
507 8d08f18a Kostas Papadimitriou
            if (this.selected_action && actions.indexOf(this.selected_action) == -1) {
508 8d08f18a Kostas Papadimitriou
                this.reset();
509 8d08f18a Kostas Papadimitriou
            }
510 8d08f18a Kostas Papadimitriou
            
511 6a3a5bf7 Kostas Papadimitriou
            this.el.show();
512 6a3a5bf7 Kostas Papadimitriou
            
513 6a3a5bf7 Kostas Papadimitriou
            if ((this.selected_action || this.hovered) && !this.vm.action_error) {
514 8d08f18a Kostas Papadimitriou
                // show selected action
515 8d08f18a Kostas Papadimitriou
                $(this.el).show();
516 8d08f18a Kostas Papadimitriou
                $(this.el).find("a").css("visibility", "visible");
517 8d08f18a Kostas Papadimitriou
                // show action icon
518 8d08f18a Kostas Papadimitriou
                this.view.show_indicator(this.vm);
519 8d08f18a Kostas Papadimitriou
            } else {
520 6a3a5bf7 Kostas Papadimitriou
                if (this.hide || this.vm.action_error) {
521 8d08f18a Kostas Papadimitriou
                    // view shows actions on machine hover
522 122850c5 Kostas Papadimitriou
                    $(this.el).find("a").css("visibility", "hidden");
523 8d08f18a Kostas Papadimitriou
                } else {
524 6a3a5bf7 Kostas Papadimitriou
                    if (!this.vm.action_error) {
525 6a3a5bf7 Kostas Papadimitriou
                        // view shows actions always
526 6a3a5bf7 Kostas Papadimitriou
                        $(this.el).find("a").css("visibility", "visible");
527 6a3a5bf7 Kostas Papadimitriou
                        $(this.el).show();
528 6a3a5bf7 Kostas Papadimitriou
                    }
529 8d08f18a Kostas Papadimitriou
                }
530 8d08f18a Kostas Papadimitriou
                
531 8d08f18a Kostas Papadimitriou
                this.view.hide_indicator(this.vm);
532 8d08f18a Kostas Papadimitriou
            }
533 a09b6d74 Kostas Papadimitriou
                
534 8d08f18a Kostas Papadimitriou
            // update action link styles and shit
535 8d08f18a Kostas Papadimitriou
            _.each(models.VM.ACTIONS, function(action, index) {
536 8d08f18a Kostas Papadimitriou
                if (actions.indexOf(action) > -1) {
537 8d08f18a Kostas Papadimitriou
                    this.action(action).removeClass("disabled");
538 8d08f18a Kostas Papadimitriou
                    if (this.selected_action == action) {
539 8d08f18a Kostas Papadimitriou
                        this.action_confirm_cont(action).css('display', 'block');
540 8d08f18a Kostas Papadimitriou
                        this.action_confirm(action).show();
541 8d08f18a Kostas Papadimitriou
                        this.action(action).removeClass("disabled");
542 8d08f18a Kostas Papadimitriou
                        this.action_link(action).addClass("selected");
543 8d08f18a Kostas Papadimitriou
                    } else {
544 8d08f18a Kostas Papadimitriou
                        this.action_confirm_cont(action).hide();
545 8d08f18a Kostas Papadimitriou
                        this.action_confirm(action).hide();
546 8d08f18a Kostas Papadimitriou
                        this.action_link(action).removeClass("selected");
547 8d08f18a Kostas Papadimitriou
                    }
548 8d08f18a Kostas Papadimitriou
                } else {
549 8d08f18a Kostas Papadimitriou
                    this.action().hide();
550 8d08f18a Kostas Papadimitriou
                    this.action(action).addClass("disabled");
551 8d08f18a Kostas Papadimitriou
                    this.action_confirm(action).hide();
552 8d08f18a Kostas Papadimitriou
                }
553 8d08f18a Kostas Papadimitriou
            }, this);
554 8d08f18a Kostas Papadimitriou
        },
555 8d08f18a Kostas Papadimitriou
        
556 6a3a5bf7 Kostas Papadimitriou
        init_vm_handlers: function() {
557 6a3a5bf7 Kostas Papadimitriou
            try {
558 6a3a5bf7 Kostas Papadimitriou
                this.vm.unbind("action:fail", this.update_layout)
559 6a3a5bf7 Kostas Papadimitriou
                this.vm.unbind("action:fail:reset", this.update_layout)
560 a09b6d74 Kostas Papadimitriou
            } catch (err) { console.log("Error")};
561 a09b6d74 Kostas Papadimitriou
            
562 6a3a5bf7 Kostas Papadimitriou
            this.vm.bind("action:fail", this.update_layout)
563 6a3a5bf7 Kostas Papadimitriou
            this.vm.bind("action:fail:reset", this.update_layout)
564 a09b6d74 Kostas Papadimitriou
565 a09b6d74 Kostas Papadimitriou
            this.vm_handlers_initialized = true;
566 6a3a5bf7 Kostas Papadimitriou
        },
567 40810d73 Kostas Papadimitriou
        
568 40810d73 Kostas Papadimitriou
        set_hover_handlers: function() {
569 8d08f18a Kostas Papadimitriou
            // vm container hover (icon view)
570 6a3a5bf7 Kostas Papadimitriou
            this.view.vm(this.vm).hover(_.bind(function() {
571 6a3a5bf7 Kostas Papadimitriou
                this.hovered = true;
572 6a3a5bf7 Kostas Papadimitriou
                this.update_layout();
573 8d08f18a Kostas Papadimitriou
574 6a3a5bf7 Kostas Papadimitriou
            }, this),  _.bind(function() {
575 c343513e Kostas Papadimitriou
                this.hovered = false;
576 c343513e Kostas Papadimitriou
                this.update_layout();
577 6a3a5bf7 Kostas Papadimitriou
            }, this));
578 40810d73 Kostas Papadimitriou
        },
579 6a3a5bf7 Kostas Papadimitriou
580 40810d73 Kostas Papadimitriou
        // bind event handlers
581 40810d73 Kostas Papadimitriou
        set_handlers: function() {
582 40810d73 Kostas Papadimitriou
            var self = this;
583 40810d73 Kostas Papadimitriou
            var vm = this.vm;
584 40810d73 Kostas Papadimitriou
            
585 40810d73 Kostas Papadimitriou
            // initial hide
586 40810d73 Kostas Papadimitriou
            if (this.hide) { $(this.el).hide() };
587 8d08f18a Kostas Papadimitriou
            
588 8d08f18a Kostas Papadimitriou
            // action links events
589 8d08f18a Kostas Papadimitriou
            _.each(models.VM.ACTIONS, function(action) {
590 8d08f18a Kostas Papadimitriou
                var action = action;
591 8d08f18a Kostas Papadimitriou
                // indicator hovers
592 8d08f18a Kostas Papadimitriou
                this.view.vm(this.vm).find(".action-container."+action+" a").hover(function() {
593 8d08f18a Kostas Papadimitriou
                    self.view.show_indicator(self.vm, action);
594 8d08f18a Kostas Papadimitriou
                }, function() {
595 8d08f18a Kostas Papadimitriou
                    // clear or show selected action indicator
596 8d08f18a Kostas Papadimitriou
                    if (self.vm.pending_action) {
597 8d08f18a Kostas Papadimitriou
                        self.view.show_indicator(self.vm);
598 8d08f18a Kostas Papadimitriou
                    } else {
599 8d08f18a Kostas Papadimitriou
                        self.view.hide_indicator(self.vm);
600 8d08f18a Kostas Papadimitriou
                    }
601 8d08f18a Kostas Papadimitriou
                })
602 8d08f18a Kostas Papadimitriou
                
603 8d08f18a Kostas Papadimitriou
                // action links click events
604 8d08f18a Kostas Papadimitriou
                $(this.el).find(".action-container."+action+" a").click(function(ev) {
605 8d08f18a Kostas Papadimitriou
                    ev.preventDefault();
606 8d08f18a Kostas Papadimitriou
                    self.set(action);
607 8d08f18a Kostas Papadimitriou
                }).data("action", action);
608 8d08f18a Kostas Papadimitriou
609 8d08f18a Kostas Papadimitriou
                // confirms
610 8d08f18a Kostas Papadimitriou
                $(this.el).find(".action-container."+action+" button.no").click(function(ev) {
611 8d08f18a Kostas Papadimitriou
                    ev.preventDefault();
612 8d08f18a Kostas Papadimitriou
                    self.reset();
613 8d08f18a Kostas Papadimitriou
                });
614 8d08f18a Kostas Papadimitriou
615 8d08f18a Kostas Papadimitriou
                // cancels
616 8d08f18a Kostas Papadimitriou
                $(this.el).find(".action-container."+action+" button.yes").click(function(ev) {
617 8d08f18a Kostas Papadimitriou
                    ev.preventDefault();
618 b042eb04 Kostas Papadimitriou
                    // override console
619 b042eb04 Kostas Papadimitriou
                    // ui needs to act (open the console window)
620 b042eb04 Kostas Papadimitriou
                    if (action == "console") {
621 b042eb04 Kostas Papadimitriou
                        self.view.connect_to_console(self.vm);
622 b042eb04 Kostas Papadimitriou
                    } else {
623 b042eb04 Kostas Papadimitriou
                        self.vm.call(action);
624 b042eb04 Kostas Papadimitriou
                    }
625 8d08f18a Kostas Papadimitriou
                    self.reset();
626 8d08f18a Kostas Papadimitriou
                });
627 8d08f18a Kostas Papadimitriou
            }, this);
628 40810d73 Kostas Papadimitriou
629 40810d73 Kostas Papadimitriou
            this.handlers_initialized = true;
630 8d08f18a Kostas Papadimitriou
        },
631 8d08f18a Kostas Papadimitriou
        
632 8d08f18a Kostas Papadimitriou
        // reset actions
633 8d08f18a Kostas Papadimitriou
        reset: function() {
634 8d08f18a Kostas Papadimitriou
            var prev_action = this.selected_action;
635 8d08f18a Kostas Papadimitriou
            this.selected_action = false;
636 8d08f18a Kostas Papadimitriou
            this.vm.clear_pending_action();
637 8d08f18a Kostas Papadimitriou
            this.trigger("change", {'action': prev_action, 'vm': this.vm, 'view': this, remove: true});
638 8d08f18a Kostas Papadimitriou
            this.trigger("remove", {'action': prev_action, 'vm': this.vm, 'view': this, remove: true});
639 8d08f18a Kostas Papadimitriou
        },
640 8d08f18a Kostas Papadimitriou
        
641 8d08f18a Kostas Papadimitriou
        // set selected action
642 8d08f18a Kostas Papadimitriou
        set: function(action_name) {
643 8d08f18a Kostas Papadimitriou
            this.selected_action = action_name;
644 8d08f18a Kostas Papadimitriou
            this.vm.update_pending_action(this.selected_action);
645 8d08f18a Kostas Papadimitriou
            this.view.vm(this.vm).find(".action-indicator").show().removeClass().addClass(action_name + " action-indicator");
646 8d08f18a Kostas Papadimitriou
            this.trigger("change", {'action': this.selected_action, 'vm': this.vm, 'view': this});
647 8d08f18a Kostas Papadimitriou
        },
648 8d08f18a Kostas Papadimitriou
649 8d08f18a Kostas Papadimitriou
        update: function() {
650 8d08f18a Kostas Papadimitriou
        }
651 8d08f18a Kostas Papadimitriou
    })
652 8d08f18a Kostas Papadimitriou
653 8d08f18a Kostas Papadimitriou
654 8d08f18a Kostas Papadimitriou
    views.VMActionsView.STATUS_ACTIONS = { 
655 8d08f18a Kostas Papadimitriou
        'reboot':        ['UNKOWN', 'ACTIVE', 'REBOOT'],
656 8d08f18a Kostas Papadimitriou
        'shutdown':      ['UNKOWN', 'ACTIVE', 'REBOOT'],
657 8d08f18a Kostas Papadimitriou
        'console':       ['ACTIVE'],
658 8d08f18a Kostas Papadimitriou
        'start':         ['UNKOWN', 'STOPPED'],
659 8d08f18a Kostas Papadimitriou
        'destroy':       ['UNKOWN', 'ACTIVE', 'STOPPED', 'REBOOT', 'ERROR', 'BUILD']
660 8d08f18a Kostas Papadimitriou
    };
661 8d08f18a Kostas Papadimitriou
662 8d08f18a Kostas Papadimitriou
    // UI helpers
663 8d08f18a Kostas Papadimitriou
    var uihelpers = snf.ui.helpers = {};
664 f5b3adc1 Kostas Papadimitriou
    
665 f5b3adc1 Kostas Papadimitriou
    // OS icon helpers
666 f5b3adc1 Kostas Papadimitriou
    var os_icon = uihelpers.os_icon = function(os) {
667 8d08f18a Kostas Papadimitriou
        var icons = window.os_icons;
668 2d485d37 Kostas Papadimitriou
        if (!icons) { return "okeanos" }
669 8d08f18a Kostas Papadimitriou
        if (icons.indexOf(os) == -1) {
670 2d485d37 Kostas Papadimitriou
            os = "okeanos";
671 8d08f18a Kostas Papadimitriou
        }
672 8d08f18a Kostas Papadimitriou
        return os;
673 8d08f18a Kostas Papadimitriou
    }
674 f5b3adc1 Kostas Papadimitriou
675 f5b3adc1 Kostas Papadimitriou
    var os_icon_path = uihelpers.os_icon_path = function(os, size, active) {
676 8d08f18a Kostas Papadimitriou
        size = size || "small";
677 f5b3adc1 Kostas Papadimitriou
        if (active == undefined) { active = true };
678 8d08f18a Kostas Papadimitriou
679 f5b3adc1 Kostas Papadimitriou
        var icon = os_icon(os);
680 f5b3adc1 Kostas Papadimitriou
        if (active) {
681 8d08f18a Kostas Papadimitriou
            icon = icon + "-on";
682 8d08f18a Kostas Papadimitriou
        } else {
683 8d08f18a Kostas Papadimitriou
            icon = icon + "-off";
684 8d08f18a Kostas Papadimitriou
        }
685 8d08f18a Kostas Papadimitriou
686 c62c6b91 Kostas Papadimitriou
        return (snf.config.machines_icons_url + "{0}/{1}.png").format(size, icon)
687 8d08f18a Kostas Papadimitriou
    }
688 f5b3adc1 Kostas Papadimitriou
689 f5b3adc1 Kostas Papadimitriou
    var os_icon_tag = uihelpers.os_icon_tag = function (os, size, active, attrs) {
690 f5b3adc1 Kostas Papadimitriou
        attrs = attrs || {};
691 f5b3adc1 Kostas Papadimitriou
        return '<img src="{0}" />'.format(os_icon_path(os, size, active));
692 f5b3adc1 Kostas Papadimitriou
    }
693 f5b3adc1 Kostas Papadimitriou
694 f5b3adc1 Kostas Papadimitriou
    // VM Icon helpers
695 f5b3adc1 Kostas Papadimitriou
    //
696 f5b3adc1 Kostas Papadimitriou
    // identify icon
697 f5b3adc1 Kostas Papadimitriou
    var vm_icon = uihelpers.vm_icon = function(vm) {
698 f5b3adc1 Kostas Papadimitriou
        return os_icon(vm.get_os());
699 f5b3adc1 Kostas Papadimitriou
    }
700 f5b3adc1 Kostas Papadimitriou
    
701 f5b3adc1 Kostas Papadimitriou
    // get icon url
702 f5b3adc1 Kostas Papadimitriou
    var vm_icon_path = uihelpers.vm_icon_path = function(vm, size) {
703 f5b3adc1 Kostas Papadimitriou
        return os_icon_path(vm.get_os(), size, vm.is_active());
704 f5b3adc1 Kostas Papadimitriou
    }
705 8d08f18a Kostas Papadimitriou
    
706 8d08f18a Kostas Papadimitriou
    // get icon IMG tag
707 8d08f18a Kostas Papadimitriou
    var vm_icon_tag = uihelpers.vm_icon_tag = function (vm, size, attrs) {
708 f5b3adc1 Kostas Papadimitriou
       return os_icon_tag(vm.get_os(), size, vm.is_active(), attrs);
709 8d08f18a Kostas Papadimitriou
    }
710 8d08f18a Kostas Papadimitriou
    
711 9ffd10ce Kostas Papadimitriou
712 8d08f18a Kostas Papadimitriou
    snf.ui = _.extend(snf.ui, bb.Events);
713 9ffd10ce Kostas Papadimitriou
    snf.ui.trigger_error = function(code, msg, error, extra) {
714 9ffd10ce Kostas Papadimitriou
        snf.ui.trigger("error", { code:code, msg:msg, error:error, extra:extra || {} })
715 9ffd10ce Kostas Papadimitriou
    };
716 8d08f18a Kostas Papadimitriou
717 8d08f18a Kostas Papadimitriou
})(this);