Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (11.8 kB)

1
;(function(root){
2

    
3
    // root
4
    var root = root;
5
    
6
    // setup namepsaces
7
    var snf = root.synnefo = root.synnefo || {};
8
    var models = snf.models = snf.models || {}
9
    var storage = snf.storage = snf.storage || {};
10
    var ui = snf.ui = snf.ui || {};
11
    var util = snf.util = snf.util || {};
12

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

    
15
    // shortcuts
16
    var bb = root.Backbone;
17
    
18
    views.ListMultipleActions = views.View.extend({
19
        
20
        view_id: "list_actions",
21

    
22
        initialize: function(view) {
23
            this.parent = view;
24
            this.el = this.parent.el;
25
           
26
            views.ListMultipleActions.__super__.initialize.call(this);
27
            this.set_handlers();
28
            this.update_layout();
29

    
30
            this.selected_action = undefined;
31
            this.available_actions = [];
32
            this.multi_view = synnefo.ui.main.multiple_actions_view;
33
        },
34

    
35
        set_handlers: function() {
36
            // bind multiple actions view handlers
37
            this.multi_view = synnefo.ui.main.multiple_actions_view;
38
            this.bind("change", _.bind(this.multi_view.handle_add, this.multi_view));
39
        },
40
        
41
        get_selected_vms: function() {
42
            var selected = $(this.el).find(".list-vm-checkbox:checked");
43
            var vms = []
44
            _.each(selected, function(el){
45
                var id = parseInt($(el).attr("id").replace("checkbox-list-vm-", ""));
46
                vm = storage.vms.get(id);
47
                vms.push(vm);
48
            });
49

    
50
            return vms;
51
        },
52

    
53
        update_actions: function() {
54
            actions = undefined;
55
            this.available_actions = [];
56
            _.each(this.get_selected_vms(), function(vm) {
57
                if (!actions) {
58
                    actions = vm.get_available_actions();
59
                    return;
60
                }
61
                actions = _.intersection(actions, vm.get_available_actions());
62
            });
63

    
64
            this.available_actions = actions;
65

    
66
            this.$(".actions a").removeClass("enabled");
67
            _.each(this.available_actions, _.bind(function(name){
68
                this.$("#action-" + name).addClass("enabled");
69
            }, this))
70
        },
71

    
72
        update_layout: function() {
73
            this.update_actions();
74
        }
75
    });
76

    
77
    // VMs list view
78
    views.ListView = views.VMListView.extend({
79
        
80
        // view id (this could be used to identify 
81
        // the view object from global context
82
        view_id: 'vm_list',
83

    
84
        el: '#machinesview-list',
85
        id_tpl: 'list-vm-{0}',
86
        link_id_tpl: 'list-vm-at-{0}',
87

    
88
        hide_actions: false,
89

    
90
        selectors: {
91
            'vms': '.list-container',
92
            'vm': '#list-vm-{0}',
93
            'view': '#machinesview-list',
94
            'tpl': '.list-container#machine-container-template',
95
            'spinner': '.large-spinner',
96
            'vm_spinner': '#list-vm-{0} .spinner',
97
            'vm_wave': '#list-vm-{0} .wave',
98
            'os_icon': '#list-vm-{0} .os_icon',
99
            'vm_cont_active': '#machinesview-list',
100
            'vm_cont_terminated': '#machinesview-list'
101
        },
102
        
103
        initialize: function() {
104
            this.current_vm = 0;
105
            
106
            // button selectors
107
            this.prev_button = this.$(".controls .previous");
108
            this.next_button = this.$(".controls .next");
109

    
110
            this.actions = this.$(".actions").show();
111
            this.datatable_cont = this.$(".dataTables_wrapper").show();
112
            this.content = this.$("#machinesview_content").show();
113
            this.filter = this.$(".dataTables_filter").show().css({'display':'block'});
114
            this.table_el = this.$(".list-machines").show();
115
            this.select_all = $("#list-view-select-all");
116

    
117
            this.actions = new views.ListMultipleActions(this);
118

    
119
            this.table = $("div.list table.list-machines").dataTable({
120
                "bInfo": false,
121
                "bRetrieve": true,
122
                "bPaginate": false,
123
                "bAutoWidth": false,
124
                "bSort": true,
125
                "bStateSave": true,
126
                "sScrollXInner": "500px",
127
                "aoColumnDefs": [
128
                    { "bSortable": false, "aTargets": [ 0 ] }
129
                ]
130
            });
131

    
132
            this.table_data = {};
133
            views.ListView.__super__.initialize.apply(this, arguments);
134
        },
135

    
136
        // overload show function
137
        show_view: function() {
138
            this.log.debug("showing");
139
            this.sel('spinner').hide();
140
            this.__update_layout();
141
        },
142
        
143
        check_vm_container: function() {
144
        },
145

    
146
        // identify vm model instance id based on DOM element
147
        vm_id_for_element: function(el) {
148
            return el.attr('id').replace("list-vm-", "");
149
        },
150
        
151
        // set generic view handlers
152
        set_handlers: function() {
153
            //init_action_indicator_handlers('list');
154

    
155
            this.$(".list-vm-checkbox").live('change', _.bind(function(){
156
                this.actions.update_layout();
157
                if (this.$("tbody input:checked").length > 0) {
158
                    this.select_all.attr("checked", true);
159
                } else {
160
                    this.select_all.attr("checked", false);
161
                }
162
            }, this))
163

    
164
            var self = this;
165
            this.select_all.click(function(){
166
                if ($(this).is(":checked")) {
167
                    self.$("tbody input").attr("checked", true);
168
                } else {
169
                    self.$("tbody input").attr("checked", false);
170
                }
171
                self.actions.update_layout();
172
            });
173
        },  
174

    
175
        create_vm: function(vm) {
176
            params = this.get_vm_table_data(vm);
177
            var index = this.table.fnAddData.call(this.table, params);
178
            this.table_data["vm_" + vm.id] = {index: index[0], params: params};
179
            
180
            // append row id
181
            $(this.table.fnGetNodes(index)).attr("id", this.id_tpl.format(vm.id));
182
            
183
            // hide indicators on creation
184
            this.vm(vm).find(".spinner").hide();
185
            this.vm(vm).find(".wave").hide();
186
            this.vm(vm).find(".os_icon").show();
187
            
188
            // ancestor method
189
            this.__set_vm_handlers(vm);
190
            this.set_vm_handlers(vm);
191
            this.post_add(vm);
192
        },
193

    
194
        // remove vm
195
        remove_vm: function(vm) {
196
            var index = this.table_data["vm_" + vm.id].index;
197
            this.table.fnDeleteRow(index);
198
            delete this.table_data["vm_" + vm.id];
199
            this.update_data();
200
        },
201

    
202
        update_data: function() {
203
            var new_data = this.table.fnGetData();
204
            _.each(new_data, _.bind(function(row, i){
205
                this.table_data["vm_" + row[5]].index = i;
206
                this.table_data["vm_" + row[5]].params = row;
207
            }, this));
208
        },
209

    
210
        get_vm_table_data: function(vm) {
211
            var checkbox = '<input type="checkbox" class="' + 
212
                views.ListView.STATE_CLASSES[vm.state()].join(" ") + 
213
                ' list-vm-checkbox" id="checkbox-' + this.id_tpl.format(vm.id) + '"/>';
214

    
215
            var img = '<img class="os_icon" src="'+ this.get_vm_icon_path(vm, "small") +'" />';
216
            img = img + '<img src="static/icons/indicators/small/progress.gif" class="spinner" />';
217
            img = img + '<img src="static/icons/indicators/medium/wave.gif" class="wave" />';
218

    
219
            var name = util.truncate(vm.get('name'), 20);
220
            var flavor = vm.get_flavor().details_string();
221
            var status = STATE_TEXTS[vm.state()];
222
            
223
            return [checkbox, img, name, flavor, status, vm.id];
224
        },
225

    
226
        post_add: function(vm) {
227
        },
228

    
229
        // is vm in transition ??? show the progress spinner
230
        update_transition_state: function(vm) {
231
            if (vm.in_transition()){
232
                this.sel('vm_spinner', vm.id).show();
233
                this.sel('vm_wave', vm.id).hide();
234
                this.sel('os_icon', vm.id).hide();
235
            } else {
236
                this.sel('vm_spinner', vm.id).hide();
237
            }
238
        },
239

    
240
        // display transition animations
241
        show_transition: function(vm) {
242
            var wave = this.sel('vm_wave', vm.id);
243
            if (!wave.length) {
244
                return
245
            }
246
            
247
            this.sel('vm_spinner', vm.id).hide();
248
            this.sel('os_icon', vm.id).hide();
249

    
250
            var src = wave.attr('src');
251
            var self = this;
252

    
253
            // change src to force gif play from the first frame
254
            // animate for 500 ms then hide
255
            wave.attr('src', "").show().attr('src', src).fadeIn(500).delay(700).fadeOut(300, function() {
256
                if (vm.in_transition()) {
257
                    self.sel("vm_spinner", vm.id).fadeIn(200);
258
                } else {
259
                    self.sel("os_icon", vm.id).fadeIn(200);
260
                }
261
            });
262
        },
263

    
264
        update_actions_layout: function(vm) {
265
        },
266

    
267
        post_update_vm: function(vm) {
268
            var index = this.table_data["vm_" + vm.id].index;
269
            params = this.get_vm_table_data(vm);
270
            this.table_data["vm_" + vm.id].params = params;
271
            data = this.table.fnGetData()[index];
272

    
273
            // do not recreate checkboxes and images to avoid messing
274
            // with user interaction
275
            this.table.fnUpdate(params[2], parseInt(index), 2);
276
            this.table.fnUpdate(params[3], parseInt(index), 3);
277
            this.table.fnUpdate(params[4], parseInt(index), 4);
278
            
279
            this.update_os_icon(vm);
280
            this.update_transition_state(vm);
281
        },
282

    
283
        update_os_icon: function(vm) {
284
            this.sel('os_icon', vm.id).attr('src', this.get_vm_icon_path(vm, "small"));
285
        },
286
        
287
        // vm specific event handlers
288
        set_vm_handlers: function(vm) {
289

    
290
        },
291

    
292
        // generic stuff to do on each view update
293
        // called once after each vm has been updated
294
        update_layout: function() {
295
            this.actions.update_layout();
296
        },
297

    
298
        // update vm details
299
        update_details: function(vm) {
300
        },
301
            
302
        get_vm_icon_os: function(vm) {
303
            var os = vm.get_os();
304
            var icons = window.os_icons || views.ListView.VM_OS_ICONS;
305
            if (icons.indexOf(os) == -1) {
306
                os = "unknown";
307
            }
308
            return os;
309
        },
310

    
311
        // TODO: move to views.utils (the method and the VM_OS_ICON vars)
312
        get_vm_icon_path: function(vm, icon_type) {
313
            var os = vm.get_os();
314
            var icons = window.os_icons || views.ListView.VM_OS_ICONS;
315

    
316
            if (icons.indexOf(os) == -1) {
317
                os = "unknown";
318
            }
319
            
320
            var st = "off";
321
            if (vm.is_active()) {
322
                st = "on"
323
            }
324

    
325
            return views.ListView.VM_OS_ICON_TPLS[icon_type].format(os, st);
326
        }
327
    })
328

    
329
    views.ListView.VM_OS_ICON_TPLS = {
330
        "small": "/static/icons/machines/small/{0}-{1}.png"
331
    }
332

    
333
    views.ListView.VM_OS_ICONS = window.os_icons || [];
334

    
335
    views.ListView.STATE_CLASSES = {
336
        'UNKNOWN':          ['error-state'],
337
        'BUILD':            ['build-state'],
338
        'REBOOT':           ['rebooting-state'],
339
        'STOPPED':          ['terminated-state'],
340
        'ACTIVE':           ['running-state'],
341
        'ERROR':            ['error-state'],
342
        'DELETE':           ['destroying-state'],
343
        'DESTROY':          ['destroying-state'],
344
        'BUILD_INIT':       ['build-state'], 
345
        'BUILD_COPY':       ['build-state'],
346
        'BUILD_FINAL':      ['build-state'],
347
        'SHUTDOWN':         ['shutting-state'],
348
        'START':            ['starting-state'],
349
        'CONNECT':          ['connecting-state'],
350
        'DISCONNECT':       ['disconnecting-state']
351
    };
352

    
353
})(this);