Statistics
| Branch: | Tag: | Revision:

root / ui / templates / list.html @ db234816

History | View | Annotate | Download (14.5 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
        serverlength -= 1;
126
                pending_actions.push([destroy, serverID]);
127
        });
128
        update_confirmations();  
129
        return false;
130
});
131

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

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

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

174

175

176
function update_machines_view(data){
177
    /* 
178
    Go through the servers in the input data. Update existing entries, add
179
    new ones to the list
180
    */
181
        tableData = vmTable.fnGetData();
182

183
    $.each(data.servers.values, function(i,server){        
184
        current = -1;
185
        // check server status to select the appropriate OS icon
186
        osTag = os_icon(server.metadata);
187
        var osIcon = osTag + ".png", imgStr, imgSrc;
188

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

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

277
            // add new row to the table
278
            vmTable.fnAddData([
279
                "<input class=" + server.status + " id=" + server.id + " type=checkbox>",
280
                "<span class=imagetag>" + osTag + "</span><img class=list-logo src=" + osIcon +
281
                    " title=" + osTag + " height=16 width=16>",
282
                "<a class=name><span class=name>" + server.name.substring(0,60) + "</span></a>",
283
                "<a class=flavor><span>"+ flavorLabel + "</span></a>",
284
                "group",
285
                "<span class=status>" + STATUS_MESSAGES[server.status] + "</span>"
286
            ]);
287
        }  else if (server.status == "DELETED") {
288
        }
289
    });
290
        updateActions();
291
        $("#spinner").hide();        
292
    // in case there are no data, leave the page empty
293
    if ($("div.list table.list-machines tbody").length > 0) {
294
        $("div.list div.dataTables_filter").show();
295
        $("div.list div.dataTables_filter input").show();
296
        $("div.list table.list-machines").show();
297
        $("div.list div.actions").show();
298
    }
299
        
300
    // show message in case user has no servers!
301
    if ($("tbody.machines .dataTables_empty").length > 0) {
302
        standard_view();
303
    } else {
304
        hideWelcome();
305
                $("#machinesview_content").fadeIn("fast");
306
    }
307
        
308
        // set confirm box position
309
    if (window.innerHeight - 200 < $('#machinesview').height())
310
        $('.confirm_multiple').addClass('fixed');
311
    else
312
        $('.confirm_multiple').removeClass('fixed');
313
}
314

315
function display_success(serverID) {
316
        // do nothing
317
}
318

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

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

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

    
363
</script>