Statistics
| Branch: | Tag: | Revision:

root / ui / templates / list.html @ 1508a5ab

History | View | Annotate | Download (14.3 kB)

1
{% load i18n %}
2

    
3
<div id="machinesview_wrapper" class="list">
4
    <div id="spinner"></div>
5
    <div id="machinesview_content">
6
        <div class="actions">
7
            <a id="action-start">{% trans "Start" %}</a>
8
            <a id="action-reboot">{% trans "Reboot" %}</a>
9
            <a id="action-shutdown">{% trans "Shutdown" %}</a>
10
            <br />
11
            <a id="action-destroy">{% trans "Destroy" %}</a>
12
            <br />
13
            <a id="action-details">{% trans "Show Details" %}</a>
14
            <a id="action-group">{% trans "Add to group" %}</a>
15
            <br />
16
            <a id="action-band">{% trans "Out of band" %}</a>
17
            <br />
18
            <a id="action-attach">{% trans "Attach disk" %}</a>
19
            <a id="action-detach">{% trans "Detach disk" %}</a>
20
            <br />
21
            <a id="action-connect">{% trans "Connect to network" %}</a>
22
            <a id="action-disconnect">{% trans "Disconnect from net" %}</a>
23
        </div>
24
        <table class="list-machines" style="display: none">
25
            <thead> 
26
                <tr> 
27
                    <th id="selection" class="select-running">
28
                        <input type="checkbox"/>
29
                        <div class="expand-icon"></div>          
30
                    </th>
31
                    <th id="os">{% trans "OS" %}</th> 
32
                    <th id="name">{% trans "Name" %}</th> 
33
                    <th id="flavor">{% trans "Flavor" %}</th> 
34
                    <th id="group">{% trans "Group" %}</th>
35
                    <th id="status">{% trans "Status" %}</th> 
36
                </tr>
37
            </thead> 
38
            <tbody class="machines"></tbody>
39
        </table>
40
            <ul class="dropdown-selector" style="display: none">
41
                    <li class="select-all" ><a href="#">{% trans "all" %}</a></li>
42
                    <li class="select-none"><a href="#">{% trans "none" %}</a></li>
43
                    <li class="select-group"><a href="#">{% trans "group" %}</a></li>
44
            </ul>  
45
    </div>
46
</div>
47

    
48
<script>
49

50
// select/deselect all from checkbox widget of table headers
51
$("table thead tr th#selection :checkbox").live('change', function() {
52
    if ( $(this).is(":checked") ) {
53
        $(":checkbox").attr("checked", true);
54
    }
55
    else {
56
        $(":checkbox").attr("checked", false);
57
    }
58
        updateActions();
59
        return false;
60
});
61

62
// select all from drop down menu
63
$("ul.dropdown-selector li.select-all a").live('click', function() {
64
        $(":checkbox").attr("checked", true);
65
    $(".dropdown-selector").slideToggle('medium');
66
        updateActions();
67
        return false;        
68
});
69

70
// select none from drop down menu
71
$("ul.dropdown-selector li.select-none a").live('click', function() {
72
        $(":checkbox").attr("checked", false);
73
    $(".dropdown-selector").slideToggle('medium');
74
        updateActions();
75
        return false;        
76
});
77

78
// select group from drop down menu
79
$("ul.dropdown-selector li.select-group a").live('click', function() {
80
        $(":checkbox").attr("checked", true);
81
    $(".dropdown-selector").slideToggle('medium');
82
        updateActions();
83
        return false;
84
});
85

86
// menu toggle, running menu
87
$("table.list-machines thead tr th#selection .expand-icon").click( function (obj) {
88
        $(".dropdown-selector").slideToggle('medium');
89
    return false;
90
});
91

92
// TODO: This should be populated with more rules for all available states
93
var actions = { 'reboot':                ['ACTIVE', 'REBOOT', 'multiple'],
94
                                'shutdown':                ['ACTIVE', 'REBOOT', 'multiple'],
95
                                'connect':                ['ACTIVE', ],
96
                                'disconnect':        ['ACTIVE', 'network'],
97
                                'band':                        ['ACTIVE', 'REBOOT'],
98
                                'details':                ['ACTIVE', 'REBOOT', 'STOPPED'],
99
                                'start':                 ['STOPPED', 'multiple'],
100
                                'destroy':                ['ACTIVE', 'STOPPED', 'REBOOT', 'ERROR', 'multiple', 'BUILD'],
101
                                'group':                ['ACTIVE', 'STOPPED', 'REBOOT','multiple'],
102
                           };
103

104
// on checkbox click, update the actions
105
$("tbody input[type='checkbox']").live('change', function() { 
106
    updateActions();
107
    pending_actions = [];
108
    $(".selected").removeClass('selected');
109
    update_confirmations(); 
110
});
111

112
$("div.confirm_multiple button").click(function() {
113
    $(".selected").removeClass('selected');
114
});
115

116
// destroy action
117
$("a.enabled#action-destroy").live('click', function() {
118
        var checked = $("table.list-machines tbody input[type='checkbox']:checked");
119
    $(".selected").removeClass('selected');
120
    $(this).addClass('selected');
121
        pending_actions = []; // reset pending actions
122
        checked.each(function(i,c) {
123
                serverID=c.id;
124
                serverName = $('#'+serverID+' span.name').text();
125
                pending_actions.push([destroy, serverID]);
126
        });
127
        update_confirmations();
128
        return false;
129
});
130

131
$("a.enabled#action-reboot").live('click', function() {
132
        var checked = $("table.list-machines tbody input[type='checkbox']:checked");
133
    $(".selected").removeClass('selected');
134
    $(this).addClass('selected');
135
        pending_actions = []; // reset pending actions
136
        checked.each(function(i,c) {
137
                serverID=c.id;
138
                serverName = $('#'+serverID+' span.name').text();
139
                pending_actions.push([reboot, serverID]);
140
        });
141
        update_confirmations();
142
        return false;
143
});
144

145
$("a.enabled#action-start").live('click', function() {
146
        var checked = $("table.list-machines tbody input[type='checkbox']:checked");
147
    $(".selected").removeClass('selected');
148
    $(this).addClass('selected');
149
        pending_actions = []; // reset pending actions
150
        checked.each(function(i,c) {
151
                serverID=c.id;
152
                serverName = $('#'+serverID+' span.name').text();
153
                pending_actions.push([start, serverID]);
154
        });
155
        update_confirmations();
156
        return false;
157
});
158

159
$("a.enabled#action-shutdown").live('click', function() {
160
        var checked = $("table.list-machines tbody input[type='checkbox']:checked");
161
    $(".selected").removeClass('selected');
162
    $(this).addClass('selected');
163
        pending_actions = []; // reset pending actions
164
        checked.each(function(i,c) {
165
                serverID=c.id;
166
                serverName = $('#'+serverID+' span.name').text();
167
                pending_actions.push([shutdown, serverID]);
168
        });
169
        update_confirmations();
170
        return false;
171
});
172

173
function update_machines_view(data){
174
    /* 
175
    Go through the servers in the input data. Update existing entries, add
176
    new ones to the list
177
    */
178
        tableData = vmTable.fnGetData();
179
    $.each(data.servers.values, function(i,server){        
180
        current = -1;
181
        // check server status to select the appropriate OS icon
182
        osTag = os_icon(server.metadata);
183
        var osIcon = osTag + ".png", imgStr, imgSrc;
184

185
                // check if the server already exists in the datatable
186
                tableData.forEach(function(row,index){
187
                        
188
                        if (row[0].split(' ')[2].replace('id=','') == server.id){
189
                                current = index;
190
                        } 
191
                });
192
        
193
        if (current != -1) { // if it's there, update the values
194
            // get current status description, including non api states
195
            var server_row = $('#' + server.id).parent().parent();
196
            var status_desc = server_row.find('span.status').text();
197
            // firebug console logging
198
                        try { 
199
                                console.info(server.name + ' from ' + status_desc + ' to ' + STATUS_MESSAGES[server.status]);
200
                        } catch(err) {}
201
                    // when server is in deleted status it must be removed from the list
202
                        if (server.status == "DELETED") {
203
                                vmTable.fnDeleteRow(current);        
204
                        } else { // when server is not be deleted, it should be updated
205
                if (['BUILD','ACTIVE','REBOOT'].indexOf(server.status) >= 0 &&
206
                    [STATUS_MESSAGES['STOPPED'], STATUS_MESSAGES['ERROR'],
207
                     'Starting'].indexOf(server_row.find('span.status').text()) >= 0) {        
208
                    // from stopped, on error or starting to building, active or rebooting
209
                    // starting is not an api state, it means the server is stopped or on error
210
                                        tableData[current][0] = "<input class="+server.status+" id="+server.id+" type=checkbox>";
211
                    imgSrc = "static/wave.gif";
212
                                        imgStr = "<img class=list-logo src=" + imgSrc + " title=" + osTag + " height=16 width=16 />";
213
                                        tableData[current][1] = "<span class=imagetag>" + osTag + "</span>" + imgStr;
214
                                        tableData[current][2] = "<a class=name><span class=name>" + server.name + "</span></a>";
215
                                        //tableData[current][4] = "group"; //TODO
216
                                        tableData[current][5] = "<span class=status>" + STATUS_MESSAGES[server.status] + "</span>";
217
                                        vmTable.fnUpdate(tableData[current],current);
218
                    setTimeout("$('#"+server.id+"').parent().parent().find('.list-logo').attr('src','static/os_logos/" 
219
                                                                                               + osIcon + "')", 1600);
220
                } else if (['STOPPED','ERROR'].indexOf(server.status) >= 0 &&
221
                           [STATUS_MESSAGES['ACTIVE'], STATUS_MESSAGES['BUILD'], STATUS_MESSAGES['REBOOT'],
222
                            'Shutting down'].indexOf(server_row.find('span.status').text()) >= 0) {
223
                                        tableData[current][0] = "<input class="+server.status+" id="+server.id+" type=checkbox>";
224
                    imgSrc = "static/wave.gif";
225
                                        imgStr = "<img class=list-logo src=" + imgSrc + " title=" + osTag + " height=16 width=16 />";
226
                                        tableData[current][1] = "<span class=imagetag>" + osTag + "</span>" + imgStr;
227
                                        tableData[current][2] = "<a class=name><span class=name>" + server.name + "</span></a>";
228
                                        //tableData[current][4] = "group"; //TODO
229
                                        tableData[current][5] = "<span class=status>" + STATUS_MESSAGES[server.status] + "</span>";
230
                                        vmTable.fnUpdate(tableData[current],current);
231
                    setTimeout("$('#"+server.id+"').parent().parent().find('.list-logo').attr('src','static/os_logos/" 
232
                                                                                        + osTag + "-off.png')", 1600);        
233
                } else if ( STATUS_MESSAGES[server.status] == server_row.find('span.status').text()) {
234

235
                } else if (server.status == 'ACTIVE' && 
236
                           [STATUS_MESSAGES['BUILD'], 'Rebooting'].indexOf(server_row.find('span.status').text()) >= 0) {
237
                                        tableData[current][0] = "<input class="+server.status+" id="+server.id+" type=checkbox>";
238
                    imgSrc = "static/wave.gif";
239
                                        imgStr = "<img class=list-logo src=" + imgSrc + " title=" + osTag + " height=16 width=16 />";
240
                                        tableData[current][1] = "<span class=imagetag>" + osTag + "</span>" + imgStr;
241
                                        tableData[current][2] = "<a class=name><span class=name>" + server.name + "</span></a>";
242
                                        //tableData[current][4] = "group"; //TODO
243
                                        tableData[current][5] = "<span class=status>" + STATUS_MESSAGES[server.status] + "</span>";
244
                                        vmTable.fnUpdate(tableData[current],current);
245
                    setTimeout("$('#"+server.id+"').parent().parent().find('.list-logo').attr('src','static/os_logos/" 
246
                                                                                               + osIcon + "')", 1600);
247
                }
248
                        }
249
                        updateActions();
250
        } else if (server.status != "DELETED") { // does not exist, we should create it
251
            // check server status to select the appropriate OS icon
252
            if (['ERROR', 'STOPPED'].indexOf(server.status) >= 0) {
253
                osIcon = "static/os_logos/" + osTag + "-off.png";
254
            } else if ( server.status == 'BUILD') {
255
                osIcon = "static/progress.gif"; 
256
            } else {
257
                osIcon = "static/os_logos/" + osTag + ".png";
258
            }
259
            // find flavor parameters
260
            var current_flavor = '';
261
            for (i=0; i<flavors.length; i++) {
262
                if (flavors[i]['id'] == server.flavorRef) {
263
                    current_flavor = flavors[i];
264
                }
265
            } 
266
            var flavor_label = '';
267
            if (current_flavor['cpu'] == '1') {
268
                flavorLabel = '1 CPU, ';
269
            } else {
270
                flavorLabel = current_flavor['cpu'] + ' CPUs, ';
271
            }
272
            flavorLabel = flavorLabel + current_flavor['ram'] + 'MB, ' + current_flavor['disk'] + 'GB'; 
273

274
            // add new row to the table
275
            vmTable.fnAddData([
276
                "<input class=" + server.status + " id=" + server.id + " type=checkbox>",
277
                "<span class=imagetag>" + osTag + "</span><img class=list-logo src=" + osIcon +
278
                    " title=" + osTag + " height=16 width=16>",
279
                "<a class=name><span class=name>" + server.name + "</span></a>",
280
                "<a class=flavor><span>"+ flavorLabel + "</span></a>",
281
                "group",
282
                "<span class=status>" + STATUS_MESSAGES[server.status] + "</span>"
283
            ]);
284
        }
285
    });
286
        updateActions();
287
        $("#spinner").hide();        
288
    // in case there are no data, leave the page empty
289
    if ($("div.list table.list-machines tbody").length > 0) {
290
        $("div.list div.dataTables_filter").show();
291
        $("div.list div.dataTables_filter input").show();
292
        $("div.list table.list-machines").show();
293
        $("div.list div.actions").show();
294
    }
295

296
    // show message in case user has no servers!
297
    if (servers.length == 0) {
298
        showWelcome()
299
    } else {
300
        hideWelcome()
301
        $("#machinesview_content").fadeIn("fast")
302
    }      
303
        
304
        // set confirm box position
305
    if (window.innerHeight - 200 < $('#machinesview').height())
306
        $('.confirm_multiple').addClass('fixed');
307
    else
308
        $('.confirm_multiple').removeClass('fixed');
309
}
310

311
function display_success(serverID) {
312
        // do nothing
313
}
314

315
// indicate that the requested action was not completed
316
function display_failure(status, serverID, action, responseText) {
317
        osIcon = $('#'+serverID).parent().parent().find('.list-logo');
318
        osIcon.attr('src',osIcon.attr('os'));
319
    ajax_error(status, serverID, action, responseText);
320
}
321

322
var vmTable = $("div.list table.list-machines").dataTable({
323
    "bInfo": false,
324
    "bRetrieve": true,
325
    "bPaginate": false,
326
    "bAutoWidth": false,
327
    "bSort": true,    
328
    "bStateSave": true,
329
    "sScrollY": "270px",
330
    "sScrollX": "515px",
331
    "sScrollXInner": "500px",
332
    "aoColumnDefs": [
333
        { "bSortable": false, "aTargets": [ 0 ] }
334
    ]
335
});
336

337
// basic functions executed on page load
338
if (images.length == 0) {
339
    // populate image list
340
    update_images();
341
}
342
if (flavors.length == 0) {
343
    // configure flavors
344
    update_flavors(); 
345
}
346
// set the label of the multiple buttons 
347
$('div.confirm_multiple button.yes').text('Confirm');
348
$('div.confirm_multiple button.no').text('Cancel');
349
// reposition multiple confirmation box on window resize
350
$(window).resize(function(){
351
    if (this.innerHeight - 200 < $('#machinesview').height())
352
        $('.confirm_multiple').addClass('fixed');
353
    else
354
        $('.confirm_multiple').removeClass('fixed');
355
});
356
// start updating vm list
357
update_vms(UPDATE_INTERVAL);
358

    
359
</script>