Statistics
| Branch: | Tag: | Revision:

root / ui / templates / standard.html @ 528a931a

History | View | Annotate | Download (13.9 kB)

1
{% load i18n %}
2

    
3
<!-- the standard view -->
4
<div id="machinesview" class="standard">
5
    <div id="emptymachineslist"><h1 id="welcomeheader">{% trans "Welcome to the ocean!" %}</h1><br />
6
        <span class="welcomebody">{% trans "From this panel you will be able to manage your Virtual Machines (VMs). If you don't know what a VM is: take the " %}<a href="#">{% trans "tour" %}</a>.</span><br /><br />
7
        <span class="welcomebody">{% trans "The panel is currently empty, because you don't have any VMs yet. You can start by creating your new VM by clicking the blue button on the right. The wizard will guide you through the hole process." %}</span><br /><br />
8
        <span class="welcomefooter">{% trans "For more information or help, click " %}<a href="#">{% trans "here" %}</a>.</span>
9
    </div>
10
    <div id="spinner"></div>
11
    <div class="machine" id="machine-template" style="display:none">
12
        <div class="actions">
13
            <a href="#" class="action-start">{% trans "Start" %}</a>
14
            <a href="#" class="action-reboot">{% trans "Reboot" %}</a>
15
            <a href="#" class="action-shutdown">{% trans "Shutdown" %}</a>
16
            <a href="#" class="action-destroy">{% trans "Destroy" %}</a>
17
        </div>        
18
        <div class="state">
19
            <div class="status">{% trans "Running" %}</div>
20
            <div class="indicator"></div>
21
            <div class="indicator"></div>
22
            <div class="indicator"></div>
23
            <div class="indicator"></div>
24
            <img class="spinner" style="display:none" src="/static/progress.gif" />
25
            <img class="wave" style="display:none" src="/static/wave.gif" />
26
        </div>
27
        <img class="logo" src="" />
28
        <a href="#" class="name">
29
            <h5>{% trans "Name: " %}<span class="name">node.name</span><span class="rename"></span></h5>
30
        </a>
31
        <a href="#" class="ip">
32
            <h5>{% trans "IP: " %}<span class="public">node.public_ip</span></h5>
33
        </a>
34
        <h5 class="settings">
35
            {% trans "Show:" %} <a href="#">{% trans "disks" %}</a> | <a href="#">{% trans "networks" %}</a> | <a href="#">{% trans "group" %}</a>
36
        </h5>
37

    
38
        <div class="confirm_single">
39
            <button class="yes">{% trans "Confirm" %}</button>
40
            <button class="no">{% trans "Cancel" %}</button>
41
        </div>
42
        <div class="action_error" align="center">
43
            {% trans "<span class='orange'>Error</span> on" %} <span class="action">{% trans "error action" %}</span>
44
            <span class="code"></span>            
45
            <span class="message"></span>
46
            <button class="details">{% trans "Details" %}</button>
47
        </div>
48
        <div class="separator"></div>
49
    </div>
50

    
51
    <div class="running"></div>
52
    <div id="mini" class="separator"></div>
53
    <div class="terminated"></div>
54
</div>
55

    
56
<script>
57
    
58
// intercept reboot click 
59
$("div.actions a.action-reboot").live('click', function(){
60
    var serverID = $(this).parent().parent().attr("id");
61
    var serverName = $(this).parent().prevAll("a.name").find("span.name").text();
62
    var found = false;
63
    
64
    $(this).parent().children('a').removeClass('selected');
65
    $(this).addClass('selected');
66
    $(this).parent().addClass('display');
67
    $(this).parent().parent().find('.action_error').hide();
68
    for (i=0;i<pending_actions.length;i++){ // if there is already a pending action for this server replace it
69
        if (pending_actions[i][1]==serverID){
70
            pending_actions[i][0] = reboot;
71
            found = true
72
        }
73
    }
74
    if (!found) // no pending action for this server was found, so let's just add it to the list
75
        pending_actions.push([reboot, serverID, serverName])
76
    update_confirmations();
77
    return false;
78
});
79

80
// intercept shutdown click
81
$("div.actions a.action-shutdown").live('click', function(){ 
82
    var serverID = $(this).parent().parent().attr("id");
83
    var serverName = $(this).parent().prevAll("a.name").find("span.name").text();
84
    var found = false;
85
    $(this).parent().children('a').removeClass('selected');
86
    $(this).addClass('selected');
87
    $(this).parent().addClass('display')
88
    $(this).parent().parent().find('.action_error').hide();
89

90
    for (i=0;i<pending_actions.length;i++){ // if there is already a pending action for this server replace it
91
        if (pending_actions[i][1]==serverID){
92
            pending_actions[i][0] = shutdown;
93
            found = true
94
        }
95
    }
96
    if (!found) // no pending action for this server was found, so let's just add it to the list 
97
        pending_actions.push([shutdown, serverID, serverName])
98
    update_confirmations();
99
    return false;
100
});
101

102
// intercept start click
103
$("div.actions a.action-start").live('click', function(){ 
104
    var serverID = $(this).parent().parent().attr("id");
105
    var serverName = $(this).parent().prevAll("a.name").find("span.name").text();
106
    var found = false;
107
    $(this).parent().children('a').removeClass('selected');
108
    $(this).addClass('selected');
109
    $(this).parent().addClass('display')
110
    $(this).parent().parent().find('.action_error').hide();
111

112
    for (i=0;i<pending_actions.length;i++){ // if there is already a pending action for this server replace it
113
        if (pending_actions[i][1]==serverID){
114
            pending_actions[i][0] = start;
115
            found = true
116
        }
117
    }
118
    if (!found) // no pending action for this server was found, so let's just add it to the list
119
        pending_actions.push([start, serverID, serverName])
120
    update_confirmations();    
121
    return false;
122
});
123

124
// intercept destroy click
125
$("div.actions a.action-destroy").live('click', function(){ 
126
    var serverID = $(this).parent().parent().attr("id");
127
    var serverName = $(this).parent().prevAll("a.name").find("span.name").text();
128
    var found = false;
129
    $(this).parent().children('a').removeClass('selected');
130
    $(this).addClass('selected');
131
    $(this).parent().addClass('display')
132
    $(this).parent().parent().find('.action_error').hide();
133

134
    for (i=0;i<pending_actions.length;i++){ // if there is already a pending action for this server replace it
135
        if (pending_actions[i][1]==serverID){
136
            pending_actions[i][0] = start;
137
            found = true
138
        }
139
    }
140
    if (!found) // no pending action for this server was found, so let's just add it to the list
141
        pending_actions.push([destroy, serverID, serverName])
142
    update_confirmations();    
143
    return false;
144
});
145

146
$("div.confirm_single .yes").live('click', function(){
147
    var serverID = $(this).parent().parent().attr("id");
148
    for (i=0;i<pending_actions.length;i++){ // if there is a pending action for this server execute it
149
        if (pending_actions[i][1]==serverID){
150
            action = pending_actions.splice(i,1)[0]; // extract action
151
            action[0]([action[1]]); // execute action            
152
        }
153
    }
154
    $(this).parent().hide();
155
    $(this).parent().parent().children('div.actions').children('a').removeClass('selected');
156
    $(this).parent().parent().children('.state').children('.spinner').show()
157
    $(this).parent().parent().children('div.actions').removeClass('display');
158
    update_confirmations();    
159
    return false;
160
});
161

162
$("div.confirm_single .no").live('click', function(){
163
    // remove the action from the pending list
164
    var serverID = $(this).parent().parent().attr("id");
165
    
166
    $(this).parent().parent().children('div.actions').children('a').removeClass('selected');
167
    $(this).parent().parent().children('div.actions').removeClass('display');    
168
    for (i=0;i<pending_actions.length;i++){ // if there is a pending action for this server remove it
169
        if (pending_actions[i][1]==serverID){
170
            pending_actions.splice(i,1);
171
        }
172
    }
173
    $(this).parent().hide();
174
    update_confirmations();    
175
    return false;
176
});
177

178
$("div.action_error .details").live('click', function(){
179
    // remove the action from the pending list
180
    ajax_error($(this).parent().children('.code').text(), undefined, $(this).parent().children('.action').text(), $(this).parent().children('.message').text());
181
    $(this).parent().hide();
182
});
183

184

185
// update the servers list
186
function update_machines_view(data){
187
    /* 
188
    Go through the servers in the input data. Update existing entries, add
189
    new ones to the list
190
    */    
191
    $.each(data.servers.values, function(i,server){
192
        existing = $('#' + server.id);
193
        
194
        // if multiple machines exist in the DOM, delete all but one
195
        // defensive coding - that shouldn't happen normally
196
        while (existing.length > 1){
197
            existing.remove();
198
        }
199
        
200
        // server already exists in DOM
201
        if (existing.length){
202
            $("div.machine:last-child").find("div.separator").show();                
203

204
            //  if the status is deleted, delete it from the DOM
205
            if (server.status == 'DELETED') {
206
                existing.remove();            
207
                try {
208
                    console.info(existing.find("a.name span.name").text() + ' removed');
209
                } catch(err) {}            
210
            } else if (existing.find(".status").text() != STATUS_MESSAGES[server.status]) {
211
                
212
                try { // firebug console logging
213
                    console.info(existing.find("a.name span.name").text() + ' from ' 
214
                                + existing.find(".status").text() + ' to ' + STATUS_MESSAGES[server.status]);
215
                } catch(err) {}
216
                
217
                if (['BUILD','ACTIVE','REBOOT'].indexOf(server.status) >= 0 &&
218
                    [STATUS_MESSAGES['STOPPED'], STATUS_MESSAGES['ERROR']].indexOf(existing.find(".status").text()) >= 0) {
219
                    // from stopped to running
220
                    moved = existing.clone().appendTo(".running");
221
                    moved.find("img.logo").attr("src","static/machines/"+image_tags[server.imageRef]+'.png');
222
                    existing.remove();
223
                    existing = moved;
224
                } else if (['STOPPED','ERROR'].indexOf(server.status) >= 0 &&
225
                           [STATUS_MESSAGES['ACTIVE'], STATUS_MESSAGES['BUILD'], STATUS_MESSAGES['REBOOT']].indexOf(existing.find(".status").text()) >= 0) {
226
                    moved = existing.clone().appendTo(".terminated");
227
                    moved.find("img.logo").attr("src","static/machines/"+image_tags[server.imageRef]+'-off.png');
228
                    existing.remove();
229
                    existing = moved;
230
                } 
231
                existing.find('.spinner').hide();
232
                existing.find(' .wave').attr('src','static/wave.gif').show();
233
                setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);         
234
                existing.find(".status").text(STATUS_MESSAGES[server.status]);
235
                            
236
            }
237
            existing.find("a.name span.name").text(server.name);
238
            existing.find("a.ip span.public").text(String(server.addresses.values[0].values[0].addr).replace(',',' '));
239
        } else if (server.status != 'DELETED') {
240
            // If it does not exist and it's not deleted, we should create it
241
            var machine = $("#machine-template").clone().attr("id", server.id).fadeIn("slow");
242
            machine.find("a.name span.name").text(server.name);
243
            machine.find("img.logo").attr("src","static/machines/"+image_tags[server.imageRef]+'.png');
244
            machine.find("span.imagetag").text(image_tags[server.imageRef]);
245
            machine.find("a.ip span.public").text(String(server.addresses.values[0].values[0].addr).replace(',',' '));            
246
            machine.find(".status").text(STATUS_MESSAGES[server.status]);
247
            if (['BUILD', 'ACTIVE', 'REBOOT'].indexOf(server.status) >= 0){
248
                machine.appendTo(".running");
249
            } else {
250
                machine.find("img.logo").attr("src","static/machines/"+image_tags[server.imageRef]+'-off.png');
251
                machine.appendTo(".terminated");
252
            }
253
            //machine.find(' .wave').attr('src','static/wave.gif').show();
254
            //setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);  
255
        }
256
    });
257

258
    $("#spinner").hide();
259
    // show all separators
260
    $("div.machine div.separator").show();
261
    // hide the last one
262
    $("div.machine:last-child").find("div.separator").hide();
263
    // the separator shows only when running and terminated machines are available
264
    if ($(".terminated a.name").length > 0 && $(".running a.name").length > 0) {
265
        $("#mini.separator").fadeIn("slow");
266
    } else {
267
        $("#mini.separator").fadeOut("slow");
268
    }
269

270
    // show message in case user has no servers!
271
    if (servers.length == 0) {
272
        showWelcome()
273
    } else {
274
        hideWelcome()
275
    }           
276
    
277
    // set confirm box position
278
    if (window.innerHeight - 220 < $('#machinesview').height())
279
        $('.confirm_multiple').addClass('fixed');
280
    else
281
        $('.confirm_multiple').removeClass('fixed');
282
}
283

284
// indicate that the requested action was succesfully completed
285
function display_success(serverID) {
286

287
}
288

289
// indicate that the requested action was not completed
290
function display_failure(status, serverID, action, responseText) {
291
    $('#'+serverID+ ' .spinner').hide();
292
    $('#'+serverID+ ' .action_error .action').text(action);
293
    $('#'+serverID+ ' .action_error .code').text(status);
294
    $('#'+serverID+ ' .action_error .message').text(responseText);
295
    $('#'+serverID+ ' .action_error').show();
296
    
297
}
298

299
if (images.length == 0) {
300
    // populate image list
301
    update_images();
302
}
303
if (flavors.length == 0) {
304
    // configure flavors
305
    update_flavors(); 
306
}
307
// set the label of the multiple buttons 
308
$('div.confirm_multiple button.yes').text('Confirm All');
309
$('div.confirm_multiple button.no').text('Cancel All');
310

311
// reposition multiple confirmation box on window resize
312
$(window).resize(function(){
313
    if (this.innerHeight - 220 < $('#machinesview').height())
314
        $('.confirm_multiple').addClass('fixed');
315
    else
316
        $('.confirm_multiple').removeClass('fixed');
317
});
318

319
// start updating vm list
320
update_vms(UPDATE_INTERVAL);
321
</script>