Statistics
| Branch: | Tag: | Revision:

root / ui / static / snf / js / ui / web / ui_vms_base_view.js @ dbad5dcb

History | View | Annotate | Download (19 kB)

1 8d08f18a Kostas Papadimitriou
;(function(root){
2 8d08f18a Kostas Papadimitriou
    
3 8d08f18a Kostas Papadimitriou
    // root
4 8d08f18a Kostas Papadimitriou
    var root = root;
5 8d08f18a Kostas Papadimitriou
    
6 8d08f18a Kostas Papadimitriou
    // setup namepsaces
7 8d08f18a Kostas Papadimitriou
    var snf = root.synnefo = root.synnefo || {};
8 8d08f18a Kostas Papadimitriou
    var models = snf.models = snf.models || {}
9 8d08f18a Kostas Papadimitriou
    var storage = snf.storage = snf.storage || {};
10 8d08f18a Kostas Papadimitriou
    var ui = snf.ui = snf.ui || {};
11 8d08f18a Kostas Papadimitriou
12 8d08f18a Kostas Papadimitriou
    var views = snf.views = snf.views || {}
13 8d08f18a Kostas Papadimitriou
14 8d08f18a Kostas Papadimitriou
    // shortcuts
15 8d08f18a Kostas Papadimitriou
    var bb = root.Backbone;
16 8d08f18a Kostas Papadimitriou
    
17 8d08f18a Kostas Papadimitriou
    // logging
18 8d08f18a Kostas Papadimitriou
    var logger = new snf.logging.logger("SNF-VIEWS");
19 8d08f18a Kostas Papadimitriou
    var debug = _.bind(logger.debug, logger);
20 8d08f18a Kostas Papadimitriou
    
21 8d08f18a Kostas Papadimitriou
    // base class for views that contain/handle VMS
22 8d08f18a Kostas Papadimitriou
    views.VMListView = views.View.extend({
23 8d08f18a Kostas Papadimitriou
24 8d08f18a Kostas Papadimitriou
        // just a flag to identify that
25 8d08f18a Kostas Papadimitriou
        // views of this type handle vms
26 8d08f18a Kostas Papadimitriou
        vms_view: true,
27 8d08f18a Kostas Papadimitriou
28 8d08f18a Kostas Papadimitriou
        selectors: {},
29 8d08f18a Kostas Papadimitriou
        hide_actions: true,
30 8d08f18a Kostas Papadimitriou
        pane: "#machines-pane",
31 8d08f18a Kostas Papadimitriou
        metadata_view: undefined,
32 8d08f18a Kostas Papadimitriou
33 8d08f18a Kostas Papadimitriou
        initialize: function() {
34 8d08f18a Kostas Papadimitriou
            views.VMListView.__super__.initialize.call(this);
35 8d08f18a Kostas Papadimitriou
            this.set_storage_handlers();
36 8d08f18a Kostas Papadimitriou
            this.set_handlers();
37 8d08f18a Kostas Papadimitriou
            this.vms_updated_handler();
38 550d9733 Kostas Papadimitriou
            this.connect_overlay = new views.VMConnectView();
39 44660f58 Kostas Papadimitriou
            this.vm_selector = this.selectors.vm;
40 8d08f18a Kostas Papadimitriou
        },
41 8d08f18a Kostas Papadimitriou
42 8d08f18a Kostas Papadimitriou
        // Helpers
43 8d08f18a Kostas Papadimitriou
        //
44 8d08f18a Kostas Papadimitriou
        // get element based on this.selectors key/value pairs
45 8d08f18a Kostas Papadimitriou
        sel: function(id, params) {
46 8d08f18a Kostas Papadimitriou
            if (!this.selectors[id]){ return };
47 8d08f18a Kostas Papadimitriou
            return $(this.selectors[id].format(params));
48 8d08f18a Kostas Papadimitriou
        },
49 8d08f18a Kostas Papadimitriou
        
50 8d08f18a Kostas Papadimitriou
        // vm element based on vm model instance provided
51 8d08f18a Kostas Papadimitriou
        vm: function(vm) {
52 44660f58 Kostas Papadimitriou
            return $(this.vm_selector + vm.id);
53 8d08f18a Kostas Papadimitriou
        },
54 8d08f18a Kostas Papadimitriou
        
55 8d08f18a Kostas Papadimitriou
        // get vm model instance from DOM element
56 8d08f18a Kostas Papadimitriou
        vm_for_element: function(el) {
57 8d08f18a Kostas Papadimitriou
            return storage.vms.sel(this.vm_id_for_element(el));
58 8d08f18a Kostas Papadimitriou
        },
59 8d08f18a Kostas Papadimitriou
        
60 8d08f18a Kostas Papadimitriou
61 8d08f18a Kostas Papadimitriou
        // Event binding and stuff like that
62 8d08f18a Kostas Papadimitriou
        //
63 8d08f18a Kostas Papadimitriou
        set_storage_handlers: function() {
64 8d08f18a Kostas Papadimitriou
            storage.vms.bind("add", _.bind(this.vms_updated_handler, this, "add"));
65 8d08f18a Kostas Papadimitriou
            storage.vms.bind("change", _.bind(this.vms_updated_handler, this, "change"));
66 8d08f18a Kostas Papadimitriou
            storage.vms.bind("reset", _.bind(this.vms_updated_handler, this, "reset"));
67 8d08f18a Kostas Papadimitriou
            storage.vms.bind("remove", _.bind(this.vms_updated_handler, this, "remove"));
68 8d08f18a Kostas Papadimitriou
        },
69 8d08f18a Kostas Papadimitriou
        
70 8d08f18a Kostas Papadimitriou
        // vms updated triggered, update view vms
71 8d08f18a Kostas Papadimitriou
        vms_updated_handler: function (method, model, arg2, arg3) {
72 8d08f18a Kostas Papadimitriou
            var updated = storage.vms.models;
73 8d08f18a Kostas Papadimitriou
            if (method == "add") { updated = [model] };
74 8d08f18a Kostas Papadimitriou
            if (method == "change") { updated = [model] };
75 8d08f18a Kostas Papadimitriou
            if (method == "remove") { updated = [model] };
76 8d08f18a Kostas Papadimitriou
77 8d08f18a Kostas Papadimitriou
            if (method == "remove") {
78 8d08f18a Kostas Papadimitriou
                this.remove_vm(model)
79 8d08f18a Kostas Papadimitriou
                return;
80 8d08f18a Kostas Papadimitriou
            }
81 44660f58 Kostas Papadimitriou
            
82 8d08f18a Kostas Papadimitriou
            this.update_vms(updated);
83 8d08f18a Kostas Papadimitriou
        },
84 8d08f18a Kostas Papadimitriou
85 8d08f18a Kostas Papadimitriou
        // create vm
86 8d08f18a Kostas Papadimitriou
        // append it on proper view container
87 8d08f18a Kostas Papadimitriou
        create_vm: function(vm) {
88 8d08f18a Kostas Papadimitriou
            // create dom element
89 8d08f18a Kostas Papadimitriou
            var vm_view = this.create_vm_element(vm);
90 8d08f18a Kostas Papadimitriou
            vm_view.find(".vm-actions").attr("id", this.view_id+"-actions-" + vm.id);
91 b042eb04 Kostas Papadimitriou
            var container = this.get_vm_container(vm);
92 8d08f18a Kostas Papadimitriou
            container.append(vm_view);
93 8d08f18a Kostas Papadimitriou
            vm_view.find(".action-indicator").text("");
94 8d08f18a Kostas Papadimitriou
            if (this.visible()) {
95 8d08f18a Kostas Papadimitriou
                container.show()
96 8d08f18a Kostas Papadimitriou
            }
97 8d08f18a Kostas Papadimitriou
98 8d08f18a Kostas Papadimitriou
            // initialize vm specific event handlers 
99 8d08f18a Kostas Papadimitriou
            this.__set_vm_handlers(vm);
100 8d08f18a Kostas Papadimitriou
        },
101 8d08f18a Kostas Papadimitriou
        
102 8d08f18a Kostas Papadimitriou
        // create vm dom element
103 8d08f18a Kostas Papadimitriou
        create_vm_element: function(vm) {
104 8d08f18a Kostas Papadimitriou
            // clone template
105 23a3bb8e Kostas Papadimitriou
            return this.sel('tpl').clone().attr("id", this.id_tpl + vm.id)
106 8d08f18a Kostas Papadimitriou
        },
107 8d08f18a Kostas Papadimitriou
108 8d08f18a Kostas Papadimitriou
        // get proper vm container
109 8d08f18a Kostas Papadimitriou
        get_vm_container: function(vm) {
110 8d08f18a Kostas Papadimitriou
            if (vm.is_active()) {
111 8d08f18a Kostas Papadimitriou
                return this.sel("vm_cont_active");
112 8d08f18a Kostas Papadimitriou
            } else {
113 8d08f18a Kostas Papadimitriou
                return this.sel("vm_cont_terminated");
114 8d08f18a Kostas Papadimitriou
            }
115 8d08f18a Kostas Papadimitriou
        },
116 8d08f18a Kostas Papadimitriou
117 8d08f18a Kostas Papadimitriou
        // create and append inside the proper container the vm model
118 8d08f18a Kostas Papadimitriou
        // if it doesn't exist update vm data and make it visible
119 8d08f18a Kostas Papadimitriou
        add: function(vm) {
120 8d08f18a Kostas Papadimitriou
            // create if it does not exist
121 8d08f18a Kostas Papadimitriou
            if (this.vm(vm).length == 0) {
122 8d08f18a Kostas Papadimitriou
                this.create_vm(vm);
123 8d08f18a Kostas Papadimitriou
                this.vm(vm).show();
124 c343513e Kostas Papadimitriou
                this.post_add(vm);
125 8d08f18a Kostas Papadimitriou
            }
126 8d08f18a Kostas Papadimitriou
127 8d08f18a Kostas Papadimitriou
            return this.vm(vm);
128 8d08f18a Kostas Papadimitriou
        },
129 8d08f18a Kostas Papadimitriou
        
130 8d08f18a Kostas Papadimitriou
        // helpers for VMListView descendants
131 8d08f18a Kostas Papadimitriou
        post_add: function(vm) { throw "Not implemented" },
132 8d08f18a Kostas Papadimitriou
        set_vm_handlers: function(vm) { throw "Not implemented" },
133 8d08f18a Kostas Papadimitriou
        set_handlers: function() { throw "Not implemented" },
134 8d08f18a Kostas Papadimitriou
        update_layout: function() { throw "Not implemented" },
135 8d08f18a Kostas Papadimitriou
        post_update_vm: function(vm) { throw "Not implemented" },
136 8d08f18a Kostas Papadimitriou
        update_details: function(vm) {},
137 8d08f18a Kostas Papadimitriou
        
138 8d08f18a Kostas Papadimitriou
        // remove vm
139 8d08f18a Kostas Papadimitriou
        remove_vm: function(vm) {
140 8d08f18a Kostas Papadimitriou
            // FIXME: some kind of transiton ??? effect maybe ???
141 8d08f18a Kostas Papadimitriou
            this.vm(vm).remove();
142 8d08f18a Kostas Papadimitriou
            this.post_remove_vm(vm);
143 8d08f18a Kostas Papadimitriou
        },
144 8d08f18a Kostas Papadimitriou
        
145 8d08f18a Kostas Papadimitriou
        // remove all vms from view
146 8d08f18a Kostas Papadimitriou
        clear: function() {
147 8d08f18a Kostas Papadimitriou
            this.sel('vms').remove();
148 8d08f18a Kostas Papadimitriou
            this.__update_layout();
149 8d08f18a Kostas Papadimitriou
        },
150 8d08f18a Kostas Papadimitriou
151 2506f741 Kostas Papadimitriou
        show: function() {
152 2506f741 Kostas Papadimitriou
            views.VMListView.__super__.show.apply(this, arguments);
153 f44486d8 Kostas Papadimitriou
            if (storage.vms.length == 0) { this.hide() };
154 5dad72ea Kostas Papadimitriou
            if (!snf.config.update_hidden_views) {
155 5dad72ea Kostas Papadimitriou
                this.update_vms(storage.vms.models);
156 5dad72ea Kostas Papadimitriou
            }
157 2506f741 Kostas Papadimitriou
        },
158 2506f741 Kostas Papadimitriou
159 8d08f18a Kostas Papadimitriou
        // do update for provided vms, then update the view layout
160 8d08f18a Kostas Papadimitriou
        update_vms: function(vms) {
161 5dad72ea Kostas Papadimitriou
            if (!this.visible() && !snf.config.update_hidden_views) { return };
162 5dad72ea Kostas Papadimitriou
163 8d08f18a Kostas Papadimitriou
            _.each(vms, _.bind(function(vm){
164 8d08f18a Kostas Papadimitriou
                // vm will be removed
165 8d08f18a Kostas Papadimitriou
                // no need to update
166 8d08f18a Kostas Papadimitriou
                if (vm.get("status") == "DELETED") {
167 8d08f18a Kostas Papadimitriou
                    return;
168 8d08f18a Kostas Papadimitriou
                }
169 8d08f18a Kostas Papadimitriou
170 8d08f18a Kostas Papadimitriou
                // this won't add it additional times
171 8d08f18a Kostas Papadimitriou
                this.add(vm);
172 8d08f18a Kostas Papadimitriou
                this.update_vm(vm);
173 8d08f18a Kostas Papadimitriou
            }, this))
174 8d08f18a Kostas Papadimitriou
            
175 8d08f18a Kostas Papadimitriou
            // update view stuff
176 8d08f18a Kostas Papadimitriou
            this.__update_layout();
177 8d08f18a Kostas Papadimitriou
        },
178 8d08f18a Kostas Papadimitriou
        
179 8d08f18a Kostas Papadimitriou
        // update ui for the given vm
180 8d08f18a Kostas Papadimitriou
        update_vm: function(vm) {
181 643de8c0 Kostas Papadimitriou
            // do not update deleted state vms
182 643de8c0 Kostas Papadimitriou
            if (!vm || vm.get("status") == 'DELETED') { return };
183 8d08f18a Kostas Papadimitriou
            this.check_vm_container(vm);
184 8d08f18a Kostas Papadimitriou
185 8d08f18a Kostas Papadimitriou
            this.update_details(vm);
186 8d08f18a Kostas Papadimitriou
            this.update_transition_state(vm);
187 8d08f18a Kostas Papadimitriou
188 8d08f18a Kostas Papadimitriou
            if (this.action_views) {
189 8d08f18a Kostas Papadimitriou
                this.action_views[vm.id].update();
190 8d08f18a Kostas Papadimitriou
                this.action_views[vm.id].update_layout();
191 8d08f18a Kostas Papadimitriou
            }
192 8d08f18a Kostas Papadimitriou
            
193 027bdc60 Kostas Papadimitriou
            try {
194 027bdc60 Kostas Papadimitriou
                this.post_update_vm(vm);
195 027bdc60 Kostas Papadimitriou
            } catch (err) {};
196 8d08f18a Kostas Papadimitriou
        },
197 8d08f18a Kostas Papadimitriou
198 8d08f18a Kostas Papadimitriou
        // check if vm is placed properly within the view
199 8d08f18a Kostas Papadimitriou
        // container (e.g. some views might have different
200 8d08f18a Kostas Papadimitriou
        // containers for terminated or running machines
201 8d08f18a Kostas Papadimitriou
        check_vm_container: function(vm){
202 8d08f18a Kostas Papadimitriou
            var el = this.vm(vm);
203 8d08f18a Kostas Papadimitriou
            if (!el.length) { return };
204 8d08f18a Kostas Papadimitriou
            var self = this;
205 8d08f18a Kostas Papadimitriou
            var selector = vm.is_active() ? 'vm_cont_active' : 'vm_cont_terminated';
206 8d08f18a Kostas Papadimitriou
            if (el.parent()[0] != this.sel(selector)[0]) {
207 8d08f18a Kostas Papadimitriou
                var cont = this.sel(selector);
208 8d08f18a Kostas Papadimitriou
                var self = this;
209 7c90e31b Kostas Papadimitriou
210 b042eb04 Kostas Papadimitriou
                el.hide().appendTo(cont).fadeIn(300);
211 7c90e31b Kostas Papadimitriou
                $(window).trigger('resize');
212 7c90e31b Kostas Papadimitriou
213 7c90e31b Kostas Papadimitriou
                //el.fadeOut(200, function() {
214 7c90e31b Kostas Papadimitriou
                    //el.appendTo(cont); 
215 7c90e31b Kostas Papadimitriou
                    //el.fadeIn(200);
216 7c90e31b Kostas Papadimitriou
                    //self.sel(selector).show(function(){
217 7c90e31b Kostas Papadimitriou
                        //$(window).trigger("resize");
218 7c90e31b Kostas Papadimitriou
                    //});
219 7c90e31b Kostas Papadimitriou
                //});
220 8d08f18a Kostas Papadimitriou
            }
221 8d08f18a Kostas Papadimitriou
        },
222 8d08f18a Kostas Papadimitriou
223 8d08f18a Kostas Papadimitriou
        __update_layout: function() {
224 8d08f18a Kostas Papadimitriou
            this.update_layout();
225 8d08f18a Kostas Papadimitriou
        },
226 8d08f18a Kostas Papadimitriou
        
227 8d08f18a Kostas Papadimitriou
        // append handlers for vm specific events
228 8d08f18a Kostas Papadimitriou
        __set_vm_handlers: function(vm) {
229 8d08f18a Kostas Papadimitriou
            // show transition on vm status transit
230 8d08f18a Kostas Papadimitriou
            vm.bind('transition', _.bind(function(){this.show_transition(vm)}, this));
231 8d08f18a Kostas Papadimitriou
            this.set_vm_handlers(vm);
232 8d08f18a Kostas Papadimitriou
        },
233 8d08f18a Kostas Papadimitriou
        
234 8d08f18a Kostas Papadimitriou
        // is vm in transition ??? show the progress spinner
235 8d08f18a Kostas Papadimitriou
        update_transition_state: function(vm) {
236 8d08f18a Kostas Papadimitriou
            if (vm.in_transition() && !vm.pending_action){
237 8d08f18a Kostas Papadimitriou
                this.sel('vm_spinner', vm.id).show();
238 8d08f18a Kostas Papadimitriou
            } else {
239 8d08f18a Kostas Papadimitriou
                this.sel('vm_spinner', vm.id).hide();
240 8d08f18a Kostas Papadimitriou
            }
241 8d08f18a Kostas Papadimitriou
        },
242 8d08f18a Kostas Papadimitriou
        
243 8d08f18a Kostas Papadimitriou
        show_indicator: function(vm, action) {
244 8d08f18a Kostas Papadimitriou
            var action = action || vm.pending_action;
245 8d08f18a Kostas Papadimitriou
            this.sel('vm_wave', vm.id).hide();
246 8d08f18a Kostas Papadimitriou
            this.sel('vm_spinner', vm.id).hide();
247 8d08f18a Kostas Papadimitriou
            this.vm(vm).find(".action-indicator").removeClass().addClass(action + " action-indicator").show();
248 8d08f18a Kostas Papadimitriou
        },
249 8d08f18a Kostas Papadimitriou
250 8d08f18a Kostas Papadimitriou
        hide_indicator: function(vm) {
251 8d08f18a Kostas Papadimitriou
            this.vm(vm).find(".action-indicator").removeClass().addClass("action-indicator").hide();
252 8d08f18a Kostas Papadimitriou
            this.update_transition_state(vm);
253 8d08f18a Kostas Papadimitriou
        },
254 8d08f18a Kostas Papadimitriou
255 8d08f18a Kostas Papadimitriou
        // display transition animations
256 8d08f18a Kostas Papadimitriou
        show_transition: function(vm) {
257 8d08f18a Kostas Papadimitriou
            var wave = this.sel('vm_wave', vm.id);
258 8d08f18a Kostas Papadimitriou
            if (!wave || !wave.length) { return }
259 8d08f18a Kostas Papadimitriou
260 8d08f18a Kostas Papadimitriou
            var src = wave.attr('src');
261 8d08f18a Kostas Papadimitriou
            // change src to force gif play from the first frame
262 8d08f18a Kostas Papadimitriou
            // animate for 500 ms then hide
263 8d08f18a Kostas Papadimitriou
            wave.attr('src', "").show();
264 8d08f18a Kostas Papadimitriou
            wave.attr('src', src).fadeIn(200).delay(700).fadeOut(300, function() {
265 8d08f18a Kostas Papadimitriou
                wave.hide();
266 8d08f18a Kostas Papadimitriou
            });
267 8d08f18a Kostas Papadimitriou
        },
268 8d08f18a Kostas Papadimitriou
269 8d08f18a Kostas Papadimitriou
        connect_to_console: function(vm) {
270 8d08f18a Kostas Papadimitriou
            vm.call("console", function(console_data) {
271 8d08f18a Kostas Papadimitriou
                var url = vm.get_console_url(console_data);
272 dbad5dcb Kostas Papadimitriou
                snf.util.open_window(url, "Console to '" + vm.get("name") + "'", {});
273 8d08f18a Kostas Papadimitriou
            })
274 8d08f18a Kostas Papadimitriou
        }
275 8d08f18a Kostas Papadimitriou
276 8d08f18a Kostas Papadimitriou
    });
277 8d08f18a Kostas Papadimitriou
    
278 8d08f18a Kostas Papadimitriou
    // empty message view (just a wrapper to the element containing 
279 8d08f18a Kostas Papadimitriou
    // the empty information message)
280 8d08f18a Kostas Papadimitriou
    views.EmptyView = views.View.extend({
281 8d08f18a Kostas Papadimitriou
        el: '#emptymachineslist'
282 8d08f18a Kostas Papadimitriou
    })
283 8d08f18a Kostas Papadimitriou
284 8d08f18a Kostas Papadimitriou
    views.VMActionsView = views.View.extend({
285 8d08f18a Kostas Papadimitriou
        
286 8d08f18a Kostas Papadimitriou
        initialize: function(vm, parent, el, hide) {
287 8d08f18a Kostas Papadimitriou
            this.hide = hide || false;
288 8d08f18a Kostas Papadimitriou
            this.view = parent;
289 8d08f18a Kostas Papadimitriou
            this.vm = vm;
290 8d08f18a Kostas Papadimitriou
            this.vm_el = el;
291 8d08f18a Kostas Papadimitriou
            this.el = $("#" + parent.view_id + "-actions-" + vm.id);
292 8d08f18a Kostas Papadimitriou
            this.set_handlers();
293 8d08f18a Kostas Papadimitriou
            this.all_action_names = _.keys(views.VMActionsView.STATUS_ACTIONS);
294 8d08f18a Kostas Papadimitriou
            
295 8d08f18a Kostas Papadimitriou
            // state params
296 8d08f18a Kostas Papadimitriou
            this.selected_action = false;
297 8d08f18a Kostas Papadimitriou
298 8d08f18a Kostas Papadimitriou
            _.bindAll(this);
299 8d08f18a Kostas Papadimitriou
            window.acts = this;
300 8d08f18a Kostas Papadimitriou
            this.view_id = "vm_" + vm.id + "_actions";
301 8d08f18a Kostas Papadimitriou
            views.VMActionsView.__super__.initialize.call(this);
302 8d08f18a Kostas Papadimitriou
303 6a3a5bf7 Kostas Papadimitriou
            this.hovered = false;
304 8d08f18a Kostas Papadimitriou
        },
305 8d08f18a Kostas Papadimitriou
306 8d08f18a Kostas Papadimitriou
        action: function(name) {
307 8d08f18a Kostas Papadimitriou
            return $(this.el).find(".action-container." + name);
308 8d08f18a Kostas Papadimitriou
        },
309 8d08f18a Kostas Papadimitriou
310 8d08f18a Kostas Papadimitriou
        action_link: function(name) {
311 8d08f18a Kostas Papadimitriou
            return this.action(name).find("a");
312 8d08f18a Kostas Papadimitriou
        },
313 8d08f18a Kostas Papadimitriou
        
314 8d08f18a Kostas Papadimitriou
        action_confirm_cont: function(name) {
315 8d08f18a Kostas Papadimitriou
            return this.action_confirm(name).parent();
316 8d08f18a Kostas Papadimitriou
        },
317 8d08f18a Kostas Papadimitriou
318 8d08f18a Kostas Papadimitriou
        action_confirm: function(name) {
319 8d08f18a Kostas Papadimitriou
            return this.action(name).find("button.yes");
320 8d08f18a Kostas Papadimitriou
        },
321 8d08f18a Kostas Papadimitriou
322 8d08f18a Kostas Papadimitriou
        action_cancel: function(name) {
323 8d08f18a Kostas Papadimitriou
            return this.action(name).find("button.no");
324 8d08f18a Kostas Papadimitriou
        },
325 8d08f18a Kostas Papadimitriou
326 8d08f18a Kostas Papadimitriou
        hide_actions: function() {
327 8d08f18a Kostas Papadimitriou
            $(this.el).find("a").css("visibility", "hidden");
328 8d08f18a Kostas Papadimitriou
        },
329 8d08f18a Kostas Papadimitriou
330 8d08f18a Kostas Papadimitriou
        // update the actions layout, depending on the selected actions
331 8d08f18a Kostas Papadimitriou
        update_layout: function() {
332 8d08f18a Kostas Papadimitriou
            try {
333 122850c5 Kostas Papadimitriou
                // it doesn't seem to work without this
334 122850c5 Kostas Papadimitriou
                // some serious debugging is needed to 
335 122850c5 Kostas Papadimitriou
                // find out what is going on
336 8d08f18a Kostas Papadimitriou
                this.vm = storage.vms.get(this.vm.id);
337 6a3a5bf7 Kostas Papadimitriou
                this.init_vm_handlers();
338 6a3a5bf7 Kostas Papadimitriou
            } catch (err) { console.error(err); return }
339 122850c5 Kostas Papadimitriou
340 8d08f18a Kostas Papadimitriou
            if (!this.vm) { return }
341 6a3a5bf7 Kostas Papadimitriou
            
342 8d08f18a Kostas Papadimitriou
            // update selected action
343 8d08f18a Kostas Papadimitriou
            if (this.vm.pending_action) {
344 8d08f18a Kostas Papadimitriou
                this.selected_action = this.vm.pending_action;
345 8d08f18a Kostas Papadimitriou
            } else {
346 8d08f18a Kostas Papadimitriou
                this.selected_action = false;
347 8d08f18a Kostas Papadimitriou
            }
348 8d08f18a Kostas Papadimitriou
            
349 8d08f18a Kostas Papadimitriou
            // vm actions tha can be performed
350 8d08f18a Kostas Papadimitriou
            var actions = this.vm.get_available_actions();
351 8d08f18a Kostas Papadimitriou
            
352 8d08f18a Kostas Papadimitriou
            // had pending action but actions changed and now selected action is
353 8d08f18a Kostas Papadimitriou
            // not available, hide it from user
354 8d08f18a Kostas Papadimitriou
            if (this.selected_action && actions.indexOf(this.selected_action) == -1) {
355 8d08f18a Kostas Papadimitriou
                this.reset();
356 8d08f18a Kostas Papadimitriou
            }
357 8d08f18a Kostas Papadimitriou
            
358 6a3a5bf7 Kostas Papadimitriou
            this.el.show();
359 6a3a5bf7 Kostas Papadimitriou
            
360 6a3a5bf7 Kostas Papadimitriou
            if ((this.selected_action || this.hovered) && !this.vm.action_error) {
361 8d08f18a Kostas Papadimitriou
                // show selected action
362 8d08f18a Kostas Papadimitriou
                $(this.el).show();
363 8d08f18a Kostas Papadimitriou
                $(this.el).find("a").css("visibility", "visible");
364 8d08f18a Kostas Papadimitriou
                // show action icon
365 8d08f18a Kostas Papadimitriou
                this.view.show_indicator(this.vm);
366 8d08f18a Kostas Papadimitriou
            } else {
367 6a3a5bf7 Kostas Papadimitriou
                if (this.hide || this.vm.action_error) {
368 8d08f18a Kostas Papadimitriou
                    // view shows actions on machine hover
369 122850c5 Kostas Papadimitriou
                    $(this.el).find("a").css("visibility", "hidden");
370 8d08f18a Kostas Papadimitriou
                } else {
371 6a3a5bf7 Kostas Papadimitriou
                    if (!this.vm.action_error) {
372 6a3a5bf7 Kostas Papadimitriou
                        // view shows actions always
373 6a3a5bf7 Kostas Papadimitriou
                        $(this.el).find("a").css("visibility", "visible");
374 6a3a5bf7 Kostas Papadimitriou
                        $(this.el).show();
375 6a3a5bf7 Kostas Papadimitriou
                    }
376 8d08f18a Kostas Papadimitriou
                }
377 8d08f18a Kostas Papadimitriou
                
378 8d08f18a Kostas Papadimitriou
                this.view.hide_indicator(this.vm);
379 8d08f18a Kostas Papadimitriou
            }
380 8d08f18a Kostas Papadimitriou
            
381 8d08f18a Kostas Papadimitriou
            // update action link styles and shit
382 8d08f18a Kostas Papadimitriou
            _.each(models.VM.ACTIONS, function(action, index) {
383 8d08f18a Kostas Papadimitriou
                if (actions.indexOf(action) > -1) {
384 8d08f18a Kostas Papadimitriou
                    this.action(action).removeClass("disabled");
385 8d08f18a Kostas Papadimitriou
                    if (this.selected_action == action) {
386 8d08f18a Kostas Papadimitriou
                        this.action_confirm_cont(action).css('display', 'block');
387 8d08f18a Kostas Papadimitriou
                        this.action_confirm(action).show();
388 8d08f18a Kostas Papadimitriou
                        this.action(action).removeClass("disabled");
389 8d08f18a Kostas Papadimitriou
                        this.action_link(action).addClass("selected");
390 8d08f18a Kostas Papadimitriou
                    } else {
391 8d08f18a Kostas Papadimitriou
                        this.action_confirm_cont(action).hide();
392 8d08f18a Kostas Papadimitriou
                        this.action_confirm(action).hide();
393 8d08f18a Kostas Papadimitriou
                        this.action_link(action).removeClass("selected");
394 8d08f18a Kostas Papadimitriou
                    }
395 8d08f18a Kostas Papadimitriou
                } else {
396 8d08f18a Kostas Papadimitriou
                    this.action().hide();
397 8d08f18a Kostas Papadimitriou
                    this.action(action).addClass("disabled");
398 8d08f18a Kostas Papadimitriou
                    this.action_confirm(action).hide();
399 8d08f18a Kostas Papadimitriou
                }
400 8d08f18a Kostas Papadimitriou
401 8d08f18a Kostas Papadimitriou
            }, this);
402 8d08f18a Kostas Papadimitriou
        },
403 8d08f18a Kostas Papadimitriou
        
404 6a3a5bf7 Kostas Papadimitriou
        init_vm_handlers: function() {
405 6a3a5bf7 Kostas Papadimitriou
            try {
406 6a3a5bf7 Kostas Papadimitriou
                this.vm.unbind("action:fail", this.update_layout)
407 6a3a5bf7 Kostas Papadimitriou
                this.vm.unbind("action:fail:reset", this.update_layout)
408 6a3a5bf7 Kostas Papadimitriou
            } catch (err) {};
409 6a3a5bf7 Kostas Papadimitriou
410 6a3a5bf7 Kostas Papadimitriou
            this.vm.bind("action:fail", this.update_layout)
411 6a3a5bf7 Kostas Papadimitriou
            this.vm.bind("action:fail:reset", this.update_layout)
412 6a3a5bf7 Kostas Papadimitriou
        },
413 6a3a5bf7 Kostas Papadimitriou
414 8d08f18a Kostas Papadimitriou
        // bind event handlers
415 8d08f18a Kostas Papadimitriou
        set_handlers: function() {
416 8d08f18a Kostas Papadimitriou
            var self = this;
417 8d08f18a Kostas Papadimitriou
            var vm = this.vm;
418 8d08f18a Kostas Papadimitriou
            
419 8d08f18a Kostas Papadimitriou
            // initial hide
420 8d08f18a Kostas Papadimitriou
            if (this.hide) { $(this.el).hide() };
421 8d08f18a Kostas Papadimitriou
            
422 8d08f18a Kostas Papadimitriou
            // vm container hover (icon view)
423 6a3a5bf7 Kostas Papadimitriou
            this.view.vm(this.vm).hover(_.bind(function() {
424 6a3a5bf7 Kostas Papadimitriou
                this.hovered = true;
425 6a3a5bf7 Kostas Papadimitriou
                this.update_layout();
426 8d08f18a Kostas Papadimitriou
427 6a3a5bf7 Kostas Papadimitriou
            }, this),  _.bind(function() {
428 c343513e Kostas Papadimitriou
                this.hovered = false;
429 c343513e Kostas Papadimitriou
                this.update_layout();
430 6a3a5bf7 Kostas Papadimitriou
            }, this));
431 6a3a5bf7 Kostas Papadimitriou
432 8d08f18a Kostas Papadimitriou
            
433 8d08f18a Kostas Papadimitriou
            // action links events
434 8d08f18a Kostas Papadimitriou
            _.each(models.VM.ACTIONS, function(action) {
435 8d08f18a Kostas Papadimitriou
                var action = action;
436 8d08f18a Kostas Papadimitriou
                // indicator hovers
437 8d08f18a Kostas Papadimitriou
                this.view.vm(this.vm).find(".action-container."+action+" a").hover(function() {
438 8d08f18a Kostas Papadimitriou
                    self.view.show_indicator(self.vm, action);
439 8d08f18a Kostas Papadimitriou
                }, function() {
440 8d08f18a Kostas Papadimitriou
                    // clear or show selected action indicator
441 8d08f18a Kostas Papadimitriou
                    if (self.vm.pending_action) {
442 8d08f18a Kostas Papadimitriou
                        self.view.show_indicator(self.vm);
443 8d08f18a Kostas Papadimitriou
                    } else {
444 8d08f18a Kostas Papadimitriou
                        self.view.hide_indicator(self.vm);
445 8d08f18a Kostas Papadimitriou
                    }
446 8d08f18a Kostas Papadimitriou
                })
447 8d08f18a Kostas Papadimitriou
                
448 8d08f18a Kostas Papadimitriou
                // action links click events
449 8d08f18a Kostas Papadimitriou
                $(this.el).find(".action-container."+action+" a").click(function(ev) {
450 8d08f18a Kostas Papadimitriou
                    ev.preventDefault();
451 8d08f18a Kostas Papadimitriou
                    self.set(action);
452 8d08f18a Kostas Papadimitriou
                }).data("action", action);
453 8d08f18a Kostas Papadimitriou
454 8d08f18a Kostas Papadimitriou
                // confirms
455 8d08f18a Kostas Papadimitriou
                $(this.el).find(".action-container."+action+" button.no").click(function(ev) {
456 8d08f18a Kostas Papadimitriou
                    ev.preventDefault();
457 8d08f18a Kostas Papadimitriou
                    self.reset();
458 8d08f18a Kostas Papadimitriou
                });
459 8d08f18a Kostas Papadimitriou
460 8d08f18a Kostas Papadimitriou
                // cancels
461 8d08f18a Kostas Papadimitriou
                $(this.el).find(".action-container."+action+" button.yes").click(function(ev) {
462 8d08f18a Kostas Papadimitriou
                    ev.preventDefault();
463 b042eb04 Kostas Papadimitriou
                    // override console
464 b042eb04 Kostas Papadimitriou
                    // ui needs to act (open the console window)
465 b042eb04 Kostas Papadimitriou
                    if (action == "console") {
466 b042eb04 Kostas Papadimitriou
                        self.view.connect_to_console(self.vm);
467 b042eb04 Kostas Papadimitriou
                    } else {
468 b042eb04 Kostas Papadimitriou
                        self.vm.call(action);
469 b042eb04 Kostas Papadimitriou
                    }
470 8d08f18a Kostas Papadimitriou
                    self.reset();
471 8d08f18a Kostas Papadimitriou
                });
472 8d08f18a Kostas Papadimitriou
            }, this);
473 8d08f18a Kostas Papadimitriou
        },
474 8d08f18a Kostas Papadimitriou
        
475 8d08f18a Kostas Papadimitriou
        // reset actions
476 8d08f18a Kostas Papadimitriou
        reset: function() {
477 8d08f18a Kostas Papadimitriou
            var prev_action = this.selected_action;
478 8d08f18a Kostas Papadimitriou
            this.selected_action = false;
479 8d08f18a Kostas Papadimitriou
            this.vm.clear_pending_action();
480 8d08f18a Kostas Papadimitriou
            this.trigger("change", {'action': prev_action, 'vm': this.vm, 'view': this, remove: true});
481 8d08f18a Kostas Papadimitriou
            this.trigger("remove", {'action': prev_action, 'vm': this.vm, 'view': this, remove: true});
482 8d08f18a Kostas Papadimitriou
        },
483 8d08f18a Kostas Papadimitriou
        
484 8d08f18a Kostas Papadimitriou
        // set selected action
485 8d08f18a Kostas Papadimitriou
        set: function(action_name) {
486 8d08f18a Kostas Papadimitriou
            this.selected_action = action_name;
487 8d08f18a Kostas Papadimitriou
            this.vm.update_pending_action(this.selected_action);
488 8d08f18a Kostas Papadimitriou
            this.view.vm(this.vm).find(".action-indicator").show().removeClass().addClass(action_name + " action-indicator");
489 8d08f18a Kostas Papadimitriou
            this.trigger("change", {'action': this.selected_action, 'vm': this.vm, 'view': this});
490 8d08f18a Kostas Papadimitriou
        },
491 8d08f18a Kostas Papadimitriou
492 8d08f18a Kostas Papadimitriou
        update: function() {
493 8d08f18a Kostas Papadimitriou
        }
494 8d08f18a Kostas Papadimitriou
    })
495 8d08f18a Kostas Papadimitriou
496 8d08f18a Kostas Papadimitriou
497 8d08f18a Kostas Papadimitriou
    views.VMActionsView.STATUS_ACTIONS = { 
498 8d08f18a Kostas Papadimitriou
        'reboot':        ['UNKOWN', 'ACTIVE', 'REBOOT'],
499 8d08f18a Kostas Papadimitriou
        'shutdown':      ['UNKOWN', 'ACTIVE', 'REBOOT'],
500 8d08f18a Kostas Papadimitriou
        'console':       ['ACTIVE'],
501 8d08f18a Kostas Papadimitriou
        'start':         ['UNKOWN', 'STOPPED'],
502 8d08f18a Kostas Papadimitriou
        'destroy':       ['UNKOWN', 'ACTIVE', 'STOPPED', 'REBOOT', 'ERROR', 'BUILD']
503 8d08f18a Kostas Papadimitriou
    };
504 8d08f18a Kostas Papadimitriou
505 8d08f18a Kostas Papadimitriou
    // UI helpers
506 8d08f18a Kostas Papadimitriou
    var uihelpers = snf.ui.helpers = {};
507 f5b3adc1 Kostas Papadimitriou
    
508 f5b3adc1 Kostas Papadimitriou
    // OS icon helpers
509 f5b3adc1 Kostas Papadimitriou
    var os_icon = uihelpers.os_icon = function(os) {
510 8d08f18a Kostas Papadimitriou
        var icons = window.os_icons;
511 8d08f18a Kostas Papadimitriou
        if (icons.indexOf(os) == -1) {
512 8d08f18a Kostas Papadimitriou
            os = "unknown";
513 8d08f18a Kostas Papadimitriou
        }
514 8d08f18a Kostas Papadimitriou
        return os;
515 8d08f18a Kostas Papadimitriou
    }
516 f5b3adc1 Kostas Papadimitriou
517 f5b3adc1 Kostas Papadimitriou
    var os_icon_path = uihelpers.os_icon_path = function(os, size, active) {
518 8d08f18a Kostas Papadimitriou
        size = size || "small";
519 f5b3adc1 Kostas Papadimitriou
        if (active == undefined) { active = true };
520 8d08f18a Kostas Papadimitriou
521 f5b3adc1 Kostas Papadimitriou
        var icon = os_icon(os);
522 f5b3adc1 Kostas Papadimitriou
        if (active) {
523 8d08f18a Kostas Papadimitriou
            icon = icon + "-on";
524 8d08f18a Kostas Papadimitriou
        } else {
525 8d08f18a Kostas Papadimitriou
            icon = icon + "-off";
526 8d08f18a Kostas Papadimitriou
        }
527 8d08f18a Kostas Papadimitriou
528 8d08f18a Kostas Papadimitriou
        return "/static/icons/machines/{0}/{1}.png".format(size, icon)
529 8d08f18a Kostas Papadimitriou
    }
530 f5b3adc1 Kostas Papadimitriou
531 f5b3adc1 Kostas Papadimitriou
    var os_icon_tag = uihelpers.os_icon_tag = function (os, size, active, attrs) {
532 f5b3adc1 Kostas Papadimitriou
        attrs = attrs || {};
533 f5b3adc1 Kostas Papadimitriou
        return '<img src="{0}" />'.format(os_icon_path(os, size, active));
534 f5b3adc1 Kostas Papadimitriou
    }
535 f5b3adc1 Kostas Papadimitriou
536 f5b3adc1 Kostas Papadimitriou
    // VM Icon helpers
537 f5b3adc1 Kostas Papadimitriou
    //
538 f5b3adc1 Kostas Papadimitriou
    // identify icon
539 f5b3adc1 Kostas Papadimitriou
    var vm_icon = uihelpers.vm_icon = function(vm) {
540 f5b3adc1 Kostas Papadimitriou
        return os_icon(vm.get_os());
541 f5b3adc1 Kostas Papadimitriou
    }
542 f5b3adc1 Kostas Papadimitriou
    
543 f5b3adc1 Kostas Papadimitriou
    // get icon url
544 f5b3adc1 Kostas Papadimitriou
    var vm_icon_path = uihelpers.vm_icon_path = function(vm, size) {
545 f5b3adc1 Kostas Papadimitriou
        return os_icon_path(vm.get_os(), size, vm.is_active());
546 f5b3adc1 Kostas Papadimitriou
    }
547 8d08f18a Kostas Papadimitriou
    
548 8d08f18a Kostas Papadimitriou
    // get icon IMG tag
549 8d08f18a Kostas Papadimitriou
    var vm_icon_tag = uihelpers.vm_icon_tag = function (vm, size, attrs) {
550 f5b3adc1 Kostas Papadimitriou
       return os_icon_tag(vm.get_os(), size, vm.is_active(), attrs);
551 8d08f18a Kostas Papadimitriou
    }
552 8d08f18a Kostas Papadimitriou
    
553 8d08f18a Kostas Papadimitriou
    snf.ui = _.extend(snf.ui, bb.Events);
554 8d08f18a Kostas Papadimitriou
555 8d08f18a Kostas Papadimitriou
})(this);