Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines_single.html @ 1e7c8953

History | View | Annotate | Download (31.9 kB)

1
<!--
2
Copyright 2011 GRNET S.A. All rights reserved.
3

4
Redistribution and use in source and binary forms, with or
5
without modification, are permitted provided that the following
6
conditions are met:
7

8
  1. Redistributions of source code must retain the above
9
     copyright notice, this list of conditions and the following
10
     disclaimer.
11

12
  2. Redistributions in binary form must reproduce the above
13
     copyright notice, this list of conditions and the following
14
     disclaimer in the documentation and/or other materials
15
     provided with the distribution.
16

17
THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
POSSIBILITY OF SUCH DAMAGE.
29

30
The views and conclusions contained in the software and
31
documentation are those of the authors and should not be
32
interpreted as representing official policies, either expressed
33
or implied, of GRNET S.A.
34
-->
35

    
36
{% load i18n %}
37

    
38
<!-- the single view -->
39
<div id="machinesview-single" class="single">
40
    <div class="large-spinner"></div>
41
    <div class="single-container" id="machine-container-template" style="display:none;" >
42
        <div class="upper">
43
            <div class="column1">
44
                <div class='connect-border'></div>
45
                <div class='connect-arrow'></div>
46
                <img src="static/icons/machines/large/ubuntu-on.png" class="single-image" />
47
                <div class="state">
48
                    <span class="state-label">{% trans "Running" %}</span>
49
                    <div class="indicators">
50
                        <div class="indicator1"></div>
51
                        <div class="indicator2"></div>
52
                        <div class="indicator3"></div>
53
                        <div class="indicator4"></div>
54
                    </div>
55
                    <img class="spinner" style="display:none" src="static/icons/indicators/medium/progress.gif" />
56
                    <img class="wave" style="display:none" src="static/icons/indicators/medium/wave.gif" />
57
                </div>
58
            </div>
59
            <div class="column2">
60
                <div class="machine-labels">
61
                    <div class="machine-label name">{% trans "Name" %}:</div>
62
                    <div class="machine-label cpus">{% trans "CPUs" %}:</div>
63
                    <div class="machine-label ram">{% trans "RAM (MB)" %}:</div>
64
                    <div class="machine-label disk">{% trans "System Disk (GB)" %}:</div>
65
                    <div class="machine-label image-name">{% trans "Image Name" %}:</div>
66
                    <div class="machine-label image-size">{% trans "Image Size (GB)" %}:</div>
67
                    <div class="machine-label ipv4">{% trans "Public IPv4" %}:</div>
68
                    <div class="machine-label ipv6">{% trans "Public IPv6" %}:</div>
69
                </div>
70
                <div class="machine-details">
71
                    <div class="machine-detail name">My Desktop</div>
72
                    <div class="machine-detail cpus">4</div>
73
                    <div class="machine-detail ram">2048</div>
74
                    <div class="machine-detail disk">100</div>
75
                    <div class="machine-detail image-name">windos_XP_blah_blah</div>
76
                    <div class="machine-detail image-size">2.3</div>
77
                    <div class="machine-detail ipv4">no ipv4</div>
78
                    <div class="machine-detail ipv6">2001:db8:1f70::999:de8:7648:6e8</div>
79
                </div>
80
                <div class="tags">
81
                    <div class="tags-header">
82
                        <div class="tags-label">
83
                            {% trans "Tags" %}
84
                        </div>
85
                        <div class="tags-down-arrow">
86
                        </div>
87
                    </div>
88
                    <div class="tags-content">
89
                    </div>
90
                </div>
91
            </div>
92
            <div class="single-actions">
93
                <div class="single-action action-start">{% trans "Start" %}</a></div>
94
                <div class="single-action action-console">{% trans "Console" %}</a></div>
95
                <div class="single-action action-reboot">{% trans "Reboot" %}</a></div>
96
                <div class="single-action action-shutdown">{% trans "Shutdown" %}</a></div>
97
                <div class="single-action action-destroy">{% trans "Destroy" %}</a></div>
98
            </div>
99
            <div class="confirm_single">
100
                <button class="yes">{% trans "Confirm" %}</button>
101
                <button class="no">X</button>
102
            </div>
103
            <div class="action_error" align="center">
104
                {% trans "<span class='orange'>Error</span> on" %} <span class="action">{% trans "error action" %}</span>
105
                <span class="code"></span>
106
                <span class="message"></span>
107
                <button class="details">{% trans "Details" %}</button>
108
            </div>
109
        </div>
110
        <div class="lower">
111
            <div class="single-cpu">
112
                <div class="cpu-usage">
113
                    {% trans "CPU Usage" %}<span class="toggler">&#710;</span>
114
                </div>
115
                <div class="cpu-graph">
116

    
117
                </div>
118
            </div>
119
            <div class="single-network">
120
                <div class="network-usage">
121
                    {% trans "Network Usage" %}<span class="toggler">&#710;</span>
122
                </div>
123
                <div class="network-graph">
124

    
125
                </div>
126
            </div>
127
        </div>
128
    </div>
129
    <div class="column3">
130
        <div class="controls">
131
            <div class="previous" style="display:none;">
132
                <div class="prev-arrow">
133

    
134
                </div>
135
                {% trans "previous" %}
136
            </div>
137
            <div class="next" style="display:none;">
138
                {% trans "next" %}
139
                <div class="next-arrow">
140

    
141
                </div>
142
            </div>
143
        </div>
144
        <div class="separator">
145
        </div>
146
        <div class="servers">
147
            <div class="server-name" id="servers-widget-template" style="display:none;">server1</div>
148
        </div>
149
    </div>
150
</div>
151

    
152
<script>
153

154
//hide the all of the info contents
155
$("#machinesview-single.single .disks-content").hide();
156
$("#machinesview-single.single .networks-content").hide();
157
$("#machinesview-single.single .stats-content").hide();
158

159
// indicate that the requested action was not completed
160
function display_failure(status, serverID, action, responseText) {
161
    $('#machinesview-single.single #'+serverID+ ' .spinner').hide();
162
    $('#machinesview-single.single #'+serverID+ ' .action_error .action').text(action);
163
    $('#machinesview-single.single #'+serverID+ ' .action_error .code').text(status);
164
    $('#machinesview-single.single #'+serverID+ ' .action_error .message').text(responseText);
165
    $('#machinesview-single.single #'+serverID+ ' .action_error').show();
166
}
167

168
// cancel action
169
$("#machinesview-single.single div.confirm_single .no").live('click', function(){
170
    pending_actions = [];
171
    update_confirmations();
172
});
173

174
//show error popup box
175
$("#machinesview-single.single div.action_error .details").live('click', function(){
176
    // remove the action from the pending list
177
    ajax_error($(this).parent().children('.code').text(), undefined, $(this).parent().children('.action').text(), $(this).parent().children('.message').text());
178
    $(this).parent().hide();
179
});
180

181
//confirm action
182
$("#machinesview-single.single div.confirm_single .yes").live('click', function(){
183
    var serverID = $(this).parent().parent().parent().attr("id");
184
    console.info(serverID);
185
    for (i=0;i<pending_actions.length;i++){ // if there is a pending action for this server execute it
186
        if (pending_actions[i][1]==serverID){
187
            action = pending_actions.splice(i,1)[0]; // extract action
188
            // change the status text in cases where no api state exists
189
            if (action[0] == start) {
190
                $(this).parent().parent().find('.state-label').text(TRANSITIONS['Starting']);
191
                $(this).parent().parent().find('.state').removeClass().addClass('state starting-state');
192
                $(this).parent().parent().find('.spinner').show();
193
            } else if (action[0] == shutdown) {
194
                $(this).parent().parent().find('.state-label').text(TRANSITIONS['Shutting down']);
195
                $(this).parent().parent().find('.state').removeClass().addClass('state shutting-state');
196
                $(this).parent().parent().find('.spinner').show();
197
            } else if (action[0] == reboot) {
198
                $(this).parent().parent().find('.state-label').text(TRANSITIONS['Rebooting']);
199
                $(this).parent().parent().find('.state').removeClass().addClass('state rebooting-state');
200
                $(this).parent().parent().find('.spinner').show();
201
            }  else if (action[0] == destroy) {
202
                $(this).parent().parent().find('.state-label').text(TRANSITIONS['Destroying']);
203
                $(this).parent().parent().find('.state').removeClass().addClass('state destroying-state');
204
                $(this).parent().parent().find('.spinner').show();
205
            }
206
            action[0]([action[1]]); // execute action
207
        }
208
    }
209
    $(this).parent().hide();
210
    $(this).parent().parent().children('div.actions').children('a').removeClass('selected');
211
    $(this).parent().parent().children('.state').children('.spinner').show()
212
    $(this).parent().parent().children('div.actions').removeClass('display');
213
    update_confirmations();
214
    return false;
215
});
216

217

218
// intercept start click
219
$("#machinesview-single.single div.action-start").live('click', function(){
220
    var serverID = $(this).parent().parent().parent().attr("id");
221
    var serverName = $(this).parent().parent().parent().find(".machine-details div.name").text();
222
    var found = false;
223
    $(this).parent().children('a').removeClass('selected');
224
    $(this).addClass('selected');
225
    $(this).parent().addClass('display')
226
    $(this).parent().parent().find('.action_error').hide();
227

228
    for (i=0;i<pending_actions.length;i++){ // if there is already a pending action for this server replace it
229
        if (pending_actions[i][1]==serverID){
230
            pending_actions[i][0] = start;
231
            found = true
232
        }
233
    }
234
    if (!found) // no pending action for this server was found, so let's just add it to the list
235
        pending_actions.push([start, serverID, serverName])
236
    update_confirmations()
237
    return false;
238
});
239

240
// intercept shutdown click
241
$("#machinesview-single.single div.action-shutdown").live('click', function(){
242
    var serverID = $(this).parent().parent().parent().attr("id");
243
    var serverName = $(this).parent().parent().parent().find(".machine-details div.name").text();
244
    var found = false;
245
    $(this).parent().children('a').removeClass('selected');
246
    $(this).addClass('selected');
247
    $(this).parent().addClass('display')
248
    $(this).parent().parent().find('.action_error').hide();
249

250
    for (i=0;i<pending_actions.length;i++){ // if there is already a pending action for this server replace it
251
        if (pending_actions[i][1]==serverID){
252
            pending_actions[i][0] = shutdown;
253
            found = true
254
        }
255
    }
256
    if (!found) // no pending action for this server was found, so let's just add it to the list
257
        pending_actions.push([shutdown, serverID, serverName])
258
    update_confirmations();
259
    return false;
260
});
261

262
// intercept reboot click
263
$("#machinesview-single.single div.action-reboot").live('click', function(){
264
    var serverID = $(this).parent().parent().parent().attr("id");
265
    var serverName = $(this).parent().parent().parent().find(".machine-details div.name").text();
266
    var found = false;
267

268
    $(this).parent().children('a').removeClass('selected');
269
    $(this).addClass('selected');
270
    $(this).parent().addClass('display');
271
    $(this).parent().parent().find('.action_error').hide();
272
    for (i=0;i<pending_actions.length;i++){ // if there is already a pending action for this server replace it
273
        if (pending_actions[i][1]==serverID){
274
            pending_actions[i][0] = reboot;
275
            found = true
276
        }
277
    }
278
    if (!found) // no pending action for this server was found, so let's just add it to the list
279
        pending_actions.push([reboot, serverID, serverName])
280
    update_confirmations();
281
    return false;
282
});
283

284
// intercept destroy click
285
$("#machinesview-single.single div.action-destroy").live('click', function(){
286
    var serverID = $(this).parent().parent().parent().attr("id");
287
    var serverName = $(this).parent().parent().parent().find(".machine-details div.name").text();
288
    var found = false;
289

290
    $(this).parent().children('a').removeClass('selected');
291
    $(this).addClass('selected');
292
    $(this).parent().addClass('display')
293
    $(this).parent().parent().find('.action_error').hide();
294
    for (i=0;i<pending_actions.length;i++){ // if there is already a pending action for this server replace it
295
        if (pending_actions[i][1]==serverID){
296
            pending_actions[i][0] = destroy;
297
            found = true
298
        }
299
    }
300
    if (!found) // no pending action for this server was found, so let's just add it to the list
301
        pending_actions.push([destroy, serverID, serverName])
302
    update_confirmations();
303
    return false;
304
});
305

306
// intercept console click
307
$("#machinesview-single.single div.action-console").live('click', function(){
308
    var serverID = $(this).parent().parent().parent().attr("id");
309
    var serverName = $(this).parent().parent().parent().find(".machine-details div.name").text();
310
    var found = false;
311
    $(this).parent().children('a').removeClass('selected');
312
    $(this).addClass('selected');
313
    $(this).parent().addClass('display')
314
    $(this).parent().parent().find('.action_error').hide();
315

316
    for (i=0;i<pending_actions.length;i++){ // if there is already a pending action for this server replace it
317
        if (pending_actions[i][1]==serverID){
318
            pending_actions[i][0] = open_console;
319
            found = true
320
        }
321
    }
322
    if (!found) // no pending action for this server was found, so let's just add it to the list
323
        pending_actions.push([open_console, serverID, serverName])
324
    update_confirmations();
325
    return false;
326
});
327

328
// open console on connect arrow click
329
$("#machinesview-single.single div.connect-arrow").live('click', function(){
330
    $(this).parent().parent().find("div.action-console").click();
331
    return false;
332
});
333

334
// open console on connect arrow border click
335
$("#machinesview-single.single div.connect-border").live('click', function(){
336
    $(this).parent().parent().find("div.action-console").click();
337
    return false;
338
});
339

340
// update the servers list
341
function update_machines_view(data){
342
    /*
343
    Go through the servers in the input data. Update existing entries, add
344
    new ones to the list
345
    */
346

347
    $.each(data.servers.values, function(i,server){
348

349
        existing = $('#machinesview-single.single #' + server.id);
350
        existing_link = $('#machinesview-single div.column3 #link-' + server.id);
351
        var current_Id = current_serverId();
352

353
        //hide next button if there is only one vm
354
        if (data.servers.values.length == 1) {
355
            $("#machinesview-single.single .column3 .next").hide();
356
        }
357

358
        // if multiple machines exist in the DOM, delete all but one
359
        // defensive coding - that shouldn't happen normally
360
        while (existing.length > 1){
361
            existing.remove();
362
        }
363
        // get server OS, if it exists
364
        if (!(server.metadata == undefined)) {
365
            var server_image = os_icon(server.metadata);
366
        } else {
367
            var server_image = "unknown"
368
        }
369
        // get server status message, if it exists
370
        var current_message = existing.find(".state-label").text();
371

372
        // server already exists in DOM
373
        if (existing.length){
374
            $("#machinesview-single.single div.single-container:last-child").find("div.separator").show();
375
            //  if the status is deleted, delete it from the DOM
376
            if (server.status == 'DELETED') {
377
                existing.remove();
378
                existing_link.remove();
379
                //if the deleted vm is the displayed one, display the 1st vm
380
                if (server.id == current_Id) {
381
                    $("#machinesview-single.single div.single-container:eq(1)").show()
382
                    $('#machinesview-single.single .column3').find('.server-name:eq(1)').addClass('selected');
383
                }
384
                try {
385
                    console.info(existing.find(".machine-details div.name").text() + ' removed');
386
                } catch(err) {}
387
            }
388
            // if the status has changed
389
            else if ( current_message != STATUSES[server.status]) {
390
                /*
391
                Here there are 4 possibilities:
392
                    1. From an active state to an inactive one
393
                    2. From an inactive state to an active one
394
                    3. From an active state to a different active one
395
                    4. From an inactive state to a different inactive one
396
                The last two (3, 4) can be dealt with the same way
397
                */
398
                if (ACTIVE_STATES.indexOf(current_message) >= 0 &&
399
                    INACTIVE_STATES.indexOf(STATUSES[server.status]) >= 0) {
400
                    // from an active state to an inactive one
401
                    log_server_status_change(existing, server.status);
402
                    existing.find("img.single-image").attr("src","static/icons/machines/large/" + server_image + '-off.png');
403
                    existing.find(".state-label").text(STATUSES[server.status]);
404
                    existing.find(".connect-border").hide();
405
                    existing.find(".connect-arrow").hide();
406
                    existing.find(".spinner").hide();
407
                    existing.find(' .wave').attr('src','static/icons/indicators/medium/wave.gif').show();
408
                    existing.find(".state").removeClass().addClass("state terminated-state");
409
                    setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
410
                }
411
                else if (INACTIVE_STATES.indexOf(current_message) >= 0 &&
412
                         ACTIVE_STATES.indexOf(STATUSES[server.status]) >= 0) {
413
                    // From an inactive state to an active one
414
                    log_server_status_change(existing, server.status);
415
                    existing.find("img.single-image").attr("src","static/icons/machines/large/" + server_image + '-on.png');
416
                    existing.find(".state-label").text(STATUSES[server.status]);
417
                    existing.find(".connect-border").show();
418
                    existing.find(".connect-arrow").show();
419
                    existing.find(".spinner").hide();
420
                    existing.find(' .wave').attr('src','static/icons/indicators/medium/wave.gif').show();
421
                    existing.find(".state").removeClass().addClass("state running-state");
422
                    setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
423
                }
424
                else {
425
                    // handling active to active or inactive to inactive changes
426
                    if (TRANSITIONS[current_message] && TRANSITIONS[current_message] != 'Rebooting') {
427
                        // don't do anything if it is still in transition
428
                    }
429
                    else if ((TRANSITIONS[current_message] == 'Rebooting' && server.status == 'ACTIVE') ||
430
                             (STATUSES['BUILD'] == current_message && server.status == 'ACTIVE')) {
431
                        // if it has been rebooted or just created
432
                        log_server_status_change(existing, server.status);
433
                        existing.find(".state-label").text(STATUSES[server.status]);
434
                        existing.find(".connect-border").show();
435
                        existing.find(".connect-arrow").show();
436
                        existing.find(".spinner").hide();
437
                        existing.find(' .wave').attr('src','static/icons/indicators/medium/wave.gif').show();
438
                        existing.find(".state").removeClass().addClass("state running-state");
439
                        setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
440
                    }
441
                    else {
442
                        // in any other case just change the status and ignore spinners/waves
443
                        existing.find(".state-label").text(STATUSES[server.status]);
444
                    }
445
                }
446
            }
447
            // find and display ips
448
            var ips = get_public_ips(server);
449
            existing.find(".machine-details div.ipv4").text(ips['ip4']);
450
            existing.find(".machine-details div.ipv6").text(ips['ip6']);
451

452
        } else if (server.status != 'DELETED') {
453
            // If it does not exist and it's not deleted, we should create it
454
            var serverwidget = $("#servers-widget-template").clone().attr("id", 'link-' + server.id);
455
            if (server.name.length > 18) {
456
                serverwidget.text(server.name.substring(0,15) + '...');
457
            } else {
458
                serverwidget.text(server.name)
459
            }
460
            serverwidget.appendTo('.servers');
461
            serverwidget.show();
462
            //find and hide the previously selected server
463
            $('.single').find('.single-container').hide();
464
            $('.single .column3').find('.selected').removeClass('selected');
465
            //create and select the new one
466
            var machine = $("#machinesview-single.single #machine-container-template").clone().attr("id", server.id);
467
            machine.find(".machine-details div.name").text(server.name.substring(0,100));
468
            machine.find("img.single-image").attr("src","static/icons/machines/large/"+server_image+'-on.png');
469
            machine.find("span.imagetag").text(server_image);
470
            machine.find(".state-label").text(STATUSES[server.status]);
471
            // find and display ips
472
            var ips = get_public_ips(server);
473
            machine.find(".machine-details div.ipv4").text(ips['ip4']);
474
            machine.find(".machine-details div.ipv6").text(ips['ip6']);
475
            // find and display flavor parameters
476
            var CPUs, RAM, disk, image_name, image_size;
477
            if ( flavors.length > 0 ) {
478
                var current_flavor = '';
479
                for (i=0; i<flavors.length; i++) {
480
                    if (flavors[i]['id'] == server.flavorRef) {
481
                        current_flavor = flavors[i];
482
                    }
483
                }
484
                CPUs = current_flavor['cpu'];
485
                RAM = current_flavor['ram'];
486
                disk = current_flavor['disk'];
487
            } else {
488
                CPUs = 0;
489
                RAM = 0;
490
                disk = 0;
491
            }
492
            if ( images.length > 0 ) {
493
                var current_image = '';
494
                for (i=0; i<images.length; i++) {
495
                    if (images[i]['id'] == server.imageRef) {
496
                        current_image = images[i];
497
                    }
498
                }
499
                image_name = current_image['name'];
500
                image_size = current_image['metadata']['values']['size'];
501
            } else {
502
                image_name = ''
503
                image_size = ''
504
            }
505
            machine.find(".machine-details div.cpus").text(CPUs);
506
            machine.find(".machine-details div.ram").text(RAM);
507
            machine.find(".machine-details div.disk").text(disk);
508
            machine.find(".machine-details div.image-name").text(image_name.substring(0,35));
509
            machine.find(".machine-details div.image-size").text(image_size);
510
            //show off image if server is not active
511
            if (['BUILD', 'ACTIVE', 'REBOOT'].indexOf(server.status) < 0){
512
                    machine.find("img.single-image").attr("src","static/icons/machines/large/"+server_image+'-off.png');
513
                    machine.find(".connect-border").hide();
514
                    machine.find(".connect-arrow").hide();
515
                    machine.find(".state").removeClass().addClass("state terminated-state");
516
            }
517
            //show spinner while machine is building or rebooting
518
            if (server.status == 'BUILD' ||
519
                [TRANSITIONS['Starting'], TRANSITIONS['Shutting down']].indexOf(existing.find(".status").text()) >= 0 ) {
520
                machine.find('.spinner').show();
521
                machine.find(".connect-border").hide();
522
                machine.find(".connect-arrow").hide();
523
                machine.find('.state').removeClass().addClass('state build-state');
524
            }
525
            if (server.status == 'REBOOT') {
526
                machine.find('.spinner').show();
527
                machine.find(".connect-border").hide();
528
                machine.find(".connect-arrow").hide();
529
                machine.find('.state').removeClass().addClass('state rebooting-state');
530
            }
531
            machine.appendTo("#machinesview-single.single");
532
            //disable reboot and shutdown actions while machine is building
533
            if (server.status == 'BUILD') {
534
                $('#machinesview-single.single div.#' + server.id + ' div.action-reboot').hide();
535
                $('#machinesview-single.single div.#' + server.id + ' div.action-shutdown').hide();
536
            }
537
            // show console action only on active servers
538
            if (server.status == 'ACTIVE') {
539
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').show();
540
                $('#machinesview-single.single div.#' + server.id + ' div.action-start').hide();
541
                machine.find(".connect-border").show();
542
                machine.find(".connect-arrow").show();
543
            } else if (server.status == 'REBOOT'){
544
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').hide();
545
            } else {
546
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').hide();
547
                $('#machinesview-single.single div.#' + server.id + ' div.action-reboot').hide();
548
                $('#machinesview-single.single div.#' + server.id + ' div.action-shutdown').hide();
549
            }
550
            //show the first machine and select it in the widget
551
            $('.single-container:eq(1)').show();
552
            $('.single .column3').find('.server-name:eq(1)').addClass('selected');
553
        }
554
    update_iconview_actions(server.id, server.status);
555
    });
556
    $("#machinesview-single.single > div.large-spinner").hide();
557

558
    // show message in case user has no servers!
559
    //if ($('.single-container').length < 2) {
560
    //    showWelcome();
561
    //} else {
562
    //    hideWelcome();
563
    //}
564

565
    // set confirm box position
566
    if (window.innerHeight - 220 < $('#machinesview-single').height())
567
        $('.confirm_multiple').addClass('fixed');
568
    else
569
        $('.confirm_multiple').removeClass('fixed');
570

571
    //enable widget links
572
    $(".server-name").live('click', function() {
573
        $('.single').find('.single-container').hide()
574
        $('.single').find('#' + $(this).attr('id').substring(5)).show();
575
        $('.single .column3').find('.selected').removeClass('selected');
576
        $(this).addClass('selected');
577
        //show prev next links only if there are prev next servers
578
        if ($("#machinesview-single.single .column3 .selected").attr("id") != $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
579
            $(".single .column3 .previous").show();
580
        } else {
581
            $(".single .column3 .previous").hide();
582
        }
583
        if ($("#machinesview-single.single .column3 .selected").attr("id") != $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
584
            $(".single .column3 .next").show();
585
        } else {
586
            $(".single .column3 .next").hide();
587
        }
588
    });
589

590
    if ($.cookie('server')) {
591
        $('div#link-' + $.cookie('server')).click();
592
        $.cookie('server', null);
593
    }
594

595
    //if it is the last vm, hide the next button
596
    if ($("#machinesview-single.single .column3 .selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
597
        $("#machinesview-single.single .column3 .next").hide()
598
    } else {
599
        $("#machinesview-single.single .column3 .next").show()
600
    }
601

602
    //if it is the first vm, hide the prev button
603
    if ($("#machinesview-single.single .column3 .selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
604
        $("#machinesview-single.single .column3 .previous").hide()
605
    } else {
606
        $("#machinesview-single.single .column3 .previous").show()
607
    }
608
}
609

610
//get currently displayed serverId
611
function current_serverId() {
612
    return $("#machinesview-single.single").find("div.single-container:visible").attr("id");
613
}
614

615
//enable prev-next buttons
616
$("#machinesview-single.single .column3 .previous").live('click', function(){
617
    if ($("#machinesview-single.single .column3 .selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
618
        return false;
619
    } else {
620
        current_server = $('#machinesview-single.single .column3').find('.selected').attr("id").substring(5);
621
        $('#machinesview-single.single').find('#' + current_server).hide();
622
        $('#machinesview-single.single').find('#' + current_server).prev().show();
623
        $('#machinesview-single.single .column3').find('#link-' + current_server).removeClass('selected');
624
        $('#machinesview-single.single .column3').find('#link-' + current_server).prev().addClass('selected');
625
        if ($("#machinesview-single.single .column3 .selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
626
            $(this).hide()
627
        }
628
        $("#machinesview-single.single .column3 .next").show()
629
        return false;
630
    }
631
});
632

633
$("#machinesview-single.single .column3 .next").live('click', function(){
634
    if ($("#machinesview-single.single .column3 .selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
635
        return false;
636
        } else {
637
        current_server = $('#machinesview-single.single .column3').find('.selected').attr("id").substring(5);
638
        $('#machinesview-single.single').find('#' + current_server).hide();
639
        $('#machinesview-single.single').find('#' + current_server).next().show();
640
        $('#machinesview-single.single .column3').find('#link-' + current_server).removeClass('selected');
641
        $('#machinesview-single.single .column3').find('#link-' + current_server).next().addClass('selected');
642
        //if it is the last vm, hide the next button
643
        if ($("#machinesview-single.single .column3 .selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
644
            $(this).hide()
645
        }
646
        $("#machinesview-single.single .column3 .previous").show();
647
        return false;
648
    }
649
});
650

651
//hide prev button on startup
652
$("#machinesview-single.single .column3 .previous").hide()
653

654
// basic functions executed on page load
655
if ( flavors.length == 0 && images.length == 0 ) {
656
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
657
    update_flavors();
658
    // populate image list
659
    update_images();
660
} else if ( flavors.length == 0 && images.length != 0 ) {
661
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
662
    update_flavors();
663
} else if ( flavors.length != 0 && images.length == 0 ) {
664
    // populate image list
665
    update_images();
666
    update_vms(UPDATE_INTERVAL);
667
} else {
668
    // start updating vm list
669
    update_vms(UPDATE_INTERVAL);
670
}
671

672
//FIXME: Hide and show welcome depending on number of machines
673
hideWelcome();
674
</script>