Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines_single.html @ dc3e66b9

History | View | Annotate | Download (30.2 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 class="machine-label groups">{% trans "Groups" %}:</div>
70
                </div>
71
                <div class="machine-details">
72
                    <div class="machine-detail name">My Desktop</div>
73
                    <div class="machine-detail cpus">4</div>
74
                    <div class="machine-detail ram">2048</div>
75
                    <div class="machine-detail disk">100</div>
76
                    <div class="machine-detail image-name">windos_XP_blah_blah</div>
77
                    <div class="machine-detail image-size">2.3</div>
78
                    <div class="machine-detail ipv4">no ipv4</div>
79
                    <div class="machine-detail ipv6">2001:db8:1f70::999:de8:7648:6e8</div>
80
                    <div class="machine-detail groups">
81
                        <div class="machine-detail group">group</div>
82
                    </div>
83
                </div>
84
            </div>
85
            <div class="single-actions">
86
                <div class="single-action action-start">{% trans "Start" %}</a></div>
87
                <div class="single-action action-console">{% trans "Console" %}</a></div>
88
                <div class="single-action action-reboot">{% trans "Reboot" %}</a></div>
89
                <div class="single-action action-shutdown">{% trans "Shutdown" %}</a></div>
90
                <div class="single-action action-destroy">{% trans "Destroy" %}</a></div>
91
            </div>
92
            <div class="confirm_single">
93
                <button class="yes">{% trans "Confirm" %}</button>
94
                <button class="no">{% trans "Cancel" %}</button>
95
            </div>
96
            <div class="action_error" align="center">
97
                {% trans "<span class='orange'>Error</span> on" %} <span class="action">{% trans "error action" %}</span>
98
                <span class="code"></span>
99
                <span class="message"></span>
100
                <button class="details">{% trans "Details" %}</button>
101
            </div>
102
        </div>
103
        <div class="lower">
104
            <div class="disks">
105
                {% trans "CPU Usage" %}<span class="toggler">&#710;</span>
106
            </div>
107
            <div class="networks">
108
                {% trans "Network Usage" %}<span class="toggler">&#710;</span>
109
            </div>
110
            <div class="networks-content">
111

    
112
            </div>
113
        </div>
114
    </div>
115
    <div class="column3">
116
        <div class="controls">
117
            <div class="previous">
118
                &lt;{% trans "previous" %}
119
            </div>
120
            <div class="next">
121
                {% trans "next" %}&gt;
122
            </div>
123
        </div>
124
        <div class="separator">
125
        </div>
126
        <div class="servers">
127
            <div class="server-name" id="servers-widget-template" style="display:none;">server1</div>
128
        </div>
129
    </div>
130
</div>
131

    
132
<script>
133

134
//hide the all of the info contents
135
$("#machinesview-single.single .disks-content").hide();
136
$("#machinesview-single.single .networks-content").hide();
137
$("#machinesview-single.single .stats-content").hide();
138

139
// indicate that the requested action was not completed
140
function display_failure(status, serverID, action, responseText) {
141
    $('#machinesview-single.single #'+serverID+ ' .spinner').hide();
142
    $('#machinesview-single.single #'+serverID+ ' .action_error .action').text(action);
143
    $('#machinesview-single.single #'+serverID+ ' .action_error .code').text(status);
144
    $('#machinesview-single.single #'+serverID+ ' .action_error .message').text(responseText);
145
    $('#machinesview-single.single #'+serverID+ ' .action_error').show();
146
}
147

148
// cancel action
149
$("#machinesview-single.single div.confirm_single .no").live('click', function(){
150
    pending_actions = [];
151
    update_confirmations();
152
});
153

154
//show error
155
$("#machinesview-single.single div.action_error .details").live('click', function(){
156
    // remove the action from the pending list
157
    ajax_error($(this).parent().children('.code').text(), undefined, $(this).parent().children('.action').text(), $(this).parent().children('.message').text());
158
    $(this).parent().hide();
159
});
160

161
//confirm action
162
$("#machinesview-single.single div.confirm_single .yes").live('click', function(){
163
    var serverID = $(this).parent().parent().parent().attr("id");
164
    console.info(serverID);
165
    for (i=0;i<pending_actions.length;i++){ // if there is a pending action for this server execute it
166
        if (pending_actions[i][1]==serverID){
167
            action = pending_actions.splice(i,1)[0]; // extract action
168
            // change the status text in cases where no api state exists
169
            if (action[0] == start) {
170
                $(this).parent().parent().find('.state-label').text(TRANSITIONS['Starting']);
171
                $(this).parent().parent().find('.state').removeClass().addClass('state starting-state');
172
                $(this).parent().parent().find('.spinner').show();
173
            } else if (action[0] == shutdown) {
174
                $(this).parent().parent().find('.state-label').text(TRANSITIONS['Shutting down']);
175
                $(this).parent().parent().find('.state').removeClass().addClass('state shutting-state');
176
                $(this).parent().parent().find('.spinner').show();
177
            } else if (action[0] == reboot) {
178
                $(this).parent().parent().find('.state-label').text(TRANSITIONS['Rebooting']);
179
                $(this).parent().parent().find('.state').removeClass().addClass('state rebooting-state');
180
                $(this).parent().parent().find('.spinner').show();
181
            }  else if (action[0] == destroy) {
182
                $(this).parent().parent().find('.state-label').text(TRANSITIONS['Destroying']);
183
                $(this).parent().parent().find('.state').removeClass().addClass('state destroying-state');
184
                $(this).parent().parent().find('.spinner').show();
185
            }
186
            action[0]([action[1]]); // execute action
187
        }
188
    }
189
    $(this).parent().hide();
190
    $(this).parent().parent().children('div.actions').children('a').removeClass('selected');
191
    $(this).parent().parent().children('.state').children('.spinner').show()
192
    $(this).parent().parent().children('div.actions').removeClass('display');
193
    update_confirmations();
194
    return false;
195
});
196

197

198
// intercept start click
199
$("#machinesview-single.single div.action-start").live('click', function(){
200
    var serverID = $(this).parent().parent().parent().attr("id");
201
    var serverName = $(this).parent().parent().parent().find(".machine-details div.name").text();
202
    var found = false;
203
    $(this).parent().children('a').removeClass('selected');
204
    $(this).addClass('selected');
205
    $(this).parent().addClass('display')
206
    $(this).parent().parent().find('.action_error').hide();
207

208
    for (i=0;i<pending_actions.length;i++){ // if there is already a pending action for this server replace it
209
        if (pending_actions[i][1]==serverID){
210
            pending_actions[i][0] = start;
211
            found = true
212
        }
213
    }
214
    if (!found) // no pending action for this server was found, so let's just add it to the list
215
        pending_actions.push([start, serverID, serverName])
216
    update_confirmations()
217
    return false;
218
});
219

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

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

242
// intercept reboot click
243
$("#machinesview-single.single div.action-reboot").live('click', function(){
244
    var serverID = $(this).parent().parent().parent().attr("id");
245
    var serverName = $(this).parent().parent().parent().find(".machine-details div.name").text();
246
    var found = false;
247

248
    $(this).parent().children('a').removeClass('selected');
249
    $(this).addClass('selected');
250
    $(this).parent().addClass('display');
251
    $(this).parent().parent().find('.action_error').hide();
252
    for (i=0;i<pending_actions.length;i++){ // if there is already a pending action for this server replace it
253
        if (pending_actions[i][1]==serverID){
254
            pending_actions[i][0] = reboot;
255
            found = true
256
        }
257
    }
258
    if (!found) // no pending action for this server was found, so let's just add it to the list
259
        pending_actions.push([reboot, serverID, serverName])
260
    update_confirmations();
261
    return false;
262
});
263

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

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

286
// intercept console click
287
$("#machinesview-single.single div.action-console").live('click', function(){
288
    var serverID = $(this).parent().parent().parent().attr("id");
289
    var serverName = $(this).parent().parent().parent().find(".machine-details div.name").text();
290
    var found = false;
291
    $(this).parent().children('a').removeClass('selected');
292
    $(this).addClass('selected');
293
    $(this).parent().addClass('display')
294
    $(this).parent().parent().find('.action_error').hide();
295

296
    for (i=0;i<pending_actions.length;i++){ // if there is already a pending action for this server replace it
297
        if (pending_actions[i][1]==serverID){
298
            pending_actions[i][0] = open_console;
299
            found = true
300
        }
301
    }
302
    if (!found) // no pending action for this server was found, so let's just add it to the list
303
        pending_actions.push([open_console, serverID, serverName])
304
    update_confirmations();
305
    return false;
306
});
307

308
// open console on connect arrow click
309
$("#machinesview-single.single div.connect-arrow").live('click', function(){
310
    $(this).parent().parent().find("div.action-console").click();
311
    return false;
312
});
313

314
// open console on connect arrow border click
315
$("#machinesview-single.single div.connect-border").live('click', function(){
316
    $(this).parent().parent().find("div.action-console").click();
317
    return false;
318
});
319

320
// update the servers list
321
function update_machines_view(data){
322
    /*
323
    Go through the servers in the input data. Update existing entries, add
324
    new ones to the list
325
    */
326

327
    $.each(data.servers.values, function(i,server){
328

329
        existing = $('#machinesview-single.single #' + server.id);
330
        existing_link = $('#machinesview-single div.column3 #link-' + server.id);
331

332
        //hide next button if there is only one vm
333
        if (data.servers.values.length == 1) {
334
            $("#machinesview-single.single .column3 .next").hide();
335
        }
336

337
        // if multiple machines exist in the DOM, delete all but one
338
        // defensive coding - that shouldn't happen normally
339
        while (existing.length > 1){
340
            existing.remove();
341
        }
342
        // get server OS, if it exists
343
        if (!(server.metadata == undefined)) {
344
            var server_image = os_icon(server.metadata);
345
        } else {
346
            var server_image = "unknown"
347
        }
348
        // get server status message, if it exists
349
        var current_message = existing.find(".state-label").text();
350

351
        // server already exists in DOM
352
        if (existing.length){
353
            $("#machinesview-single.single div.single-container:last-child").find("div.separator").show();
354
            //  if the status is deleted, delete it from the DOM
355
            if (server.status == 'DELETED') {
356
                existing.next().show();
357
                existing.remove();
358
                existing_link.remove();
359
                try {
360
                    console.info(existing.find("div.name span.name").text() + ' removed');
361
                } catch(err) {}
362
            }
363
            // if the status has changed
364
            else if ( current_message != STATUSES[server.status]) {
365
                /*
366
                Here there are 4 possibilities:
367
                    1. From an active state to an inactive one
368
                    2. From an inactive state to an active one
369
                    3. From an active state to a different active one
370
                    4. From an inactive state to a different inactive one
371
                The last two (3, 4) can be dealt with the same way
372
                */
373
                if (ACTIVE_STATES.indexOf(current_message) >= 0 &&
374
                    INACTIVE_STATES.indexOf(STATUSES[server.status]) >= 0) {
375
                    // from an active state to an inactive one
376
                    log_server_status_change(existing, server.status);
377
                    existing.find("img.single-image").attr("src","static/icons/machines/large/" + server_image + '-off.png');
378
                    existing.find(".state-label").text(STATUSES[server.status]);
379
                    existing.find(".connect-border").hide();
380
                    existing.find(".connect-arrow").hide();
381
                    existing.find(".spinner").hide();
382
                    existing.find(' .wave').attr('src','static/icons/indicators/medium/wave.gif').show();
383
                    existing.find(".state").removeClass().addClass("state terminated-state");
384
                    setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
385
                }
386
                else if (INACTIVE_STATES.indexOf(current_message) >= 0 &&
387
                         ACTIVE_STATES.indexOf(STATUSES[server.status]) >= 0) {
388
                    // From an inactive state to an active one
389
                    log_server_status_change(existing, server.status);
390
                    existing.find("img.single-image").attr("src","static/icons/machines/large/" + server_image + '-on.png');
391
                    existing.find(".state-label").text(STATUSES[server.status]);
392
                    existing.find(".connect-border").show();
393
                    existing.find(".connect-arrow").show();
394
                    existing.find(".spinner").hide();
395
                    existing.find(' .wave').attr('src','static/icons/indicators/medium/wave.gif').show();
396
                    existing.find(".state").removeClass().addClass("state running-state");
397
                    setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
398
                }
399
                else {
400
                    // handling active to active or inactive to inactive changes
401
                    if (TRANSITIONS[current_message] && TRANSITIONS[current_message] != 'Rebooting') {
402
                        // don't do anything if it is still in transition
403
                    }
404
                    else if ((TRANSITIONS[current_message] == 'Rebooting' && server.status == 'ACTIVE') ||
405
                             (STATUSES['BUILD'] == current_message && server.status == 'ACTIVE')) {
406
                        // if it has been rebooted or just created
407
                        log_server_status_change(existing, server.status);
408
                        existing.find(".state-label").text(STATUSES[server.status]);
409
                        existing.find(".connect-border").show();
410
                        existing.find(".connect-arrow").show();
411
                        existing.find(".spinner").hide();
412
                        existing.find(' .wave').attr('src','static/icons/indicators/medium/wave.gif').show();
413
                        existing.find(".state").removeClass().addClass("state running-state");
414
                        setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
415
                    }
416
                    else {
417
                        // in any other case just change the status and ignore spinners/waves
418
                        existing.find(".state-label").text(STATUSES[server.status]);
419
                    }
420
                }
421
            }
422
            // find and display ips
423
            var ips = get_public_ips(server);
424
            existing.find(".machine-details div.ipv4").text(ips['ip4']);
425
            existing.find(".machine-details div.ipv6").text(ips['ip6']);
426

427
        } else if (server.status != 'DELETED') {
428
            // If it does not exist and it's not deleted, we should create it
429
            var serverwidget = $("#servers-widget-template").clone().attr("id", 'link-' + server.id);
430
            if (server.name.length > 18) {
431
                serverwidget.text(server.name.substring(0,15) + '...');
432
            } else {
433
                serverwidget.text(server.name)
434
            }
435
            serverwidget.appendTo('.servers');
436
            serverwidget.show();
437
            //find and hide the previous selected server
438
            $('.single').find('.single-container').hide();
439
            $('.single .column3').find('.selected').removeClass('selected');
440
            //create and select the new one
441
            var machine = $("#machinesview-single.single #machine-container-template").clone().attr("id", server.id);
442
            machine.find(".machine-details div.name").text(server.name.substring(0,100));
443
            machine.find("img.single-image").attr("src","static/icons/machines/large/"+server_image+'-on.png');
444
            machine.find("span.imagetag").text(server_image);
445
            machine.find(".state-label").text(STATUSES[server.status]);
446
            // find and display ips
447
            var ips = get_public_ips(server);
448
            machine.find(".machine-details div.ipv4").text(ips['ip4']);
449
            machine.find(".machine-details div.ipv6").text(ips['ip6']);
450
            // find and display flavor parameters
451
            var CPUs, RAM, disk, image_name, image_size;
452
            if ( flavors.length > 0 ) {
453
                var current_flavor = '';
454
                for (i=0; i<flavors.length; i++) {
455
                    if (flavors[i]['id'] == server.flavorRef) {
456
                        current_flavor = flavors[i];
457
                    }
458
                }
459
                CPUs = current_flavor['cpu'];
460
                RAM = current_flavor['ram'];
461
                disk = current_flavor['disk'];
462
            } else {
463
                CPUs = 0;
464
                RAM = 0;
465
                disk = 0;
466
            }
467
            if ( images.length > 0 ) {
468
                var current_image = '';
469
                for (i=0; i<images.length; i++) {
470
                    if (images[i]['id'] == server.imageRef) {
471
                        current_image = images[i];
472
                    }
473
                }
474
                image_name = current_image['name'];
475
                image_size = current_image['metadata']['values']['size'];
476
            } else {
477
                image_name = ''
478
                image_size = ''
479
            }
480
            machine.find(".machine-details div.cpus").text(CPUs);
481
            machine.find(".machine-details div.ram").text(RAM);
482
            machine.find(".machine-details div.disk").text(disk);
483
            machine.find(".machine-details div.image-name").text(image_name.substring(0,35));
484
            machine.find(".machine-details div.image-size").text(image_size);
485
            //show off image if server is not active
486
            if (['BUILD', 'ACTIVE', 'REBOOT'].indexOf(server.status) < 0){
487
                    machine.find("img.single-image").attr("src","static/icons/machines/large/"+server_image+'-off.png');
488
                    machine.find(".connect-border").hide();
489
                    machine.find(".connect-arrow").hide();
490
                    machine.find(".state").removeClass().addClass("state terminated-state");
491
            }
492
            //show spinner while machine is building
493
            if (server.status == 'BUILD' ||
494
                [TRANSITIONS['Starting'], TRANSITIONS['Shutting down']].indexOf(existing.find(".status").text()) >= 0 ) {
495
                machine.find('.spinner').show();
496
                machine.find(".connect-border").hide();
497
                machine.find(".connect-arrow").hide();
498
            }
499
            machine.appendTo("#machinesview-single.single");
500
            //disable reboot and shutdown actions while machine is building
501
            if (server.status == 'BUILD') {
502
                $('#machinesview-single.single div.#' + server.id + ' div.action-reboot').hide();
503
                $('#machinesview-single.single div.#' + server.id + ' div.action-shutdown').hide();
504
            }
505
            // show console action only on active servers
506
            if (server.status == 'ACTIVE') {
507
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').show();
508
                $('#machinesview-single.single div.#' + server.id + ' div.action-start').hide();
509
                machine.find(".connect-border").show();
510
                machine.find(".connect-arrow").show();
511
            } else if (server.status == 'REBOOT'){
512
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').hide();
513
            } else {
514
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').hide();
515
                $('#machinesview-single.single div.#' + server.id + ' div.action-reboot').hide();
516
                $('#machinesview-single.single div.#' + server.id + ' div.action-shutdown').hide();
517
            }
518
            //show the first machine and select it in the widget
519
            $('.single-container:eq(1)').show();
520
            $('.single .column3').find('.server-name:eq(1)').addClass('selected');
521
        }
522
    update_iconview_actions(server.id, server.status);
523
    });
524
    $("#machinesview-single.single > div.large-spinner").hide();
525

526
    // show message in case user has no servers!
527
    //if ($('.single-container').length < 2) {
528
    //    showWelcome();
529
    //} else {
530
    //    hideWelcome();
531
    //}
532

533
    // set confirm box position
534
    if (window.innerHeight - 220 < $('#machinesview-single').height())
535
        $('.confirm_multiple').addClass('fixed');
536
    else
537
        $('.confirm_multiple').removeClass('fixed');
538

539
    //enable widget links
540
    $(".server-name").live('click', function() {
541
        $('.single').find('.single-container').hide()
542
        $('.single').find('#' + $(this).attr('id').substring(5)).show();
543
        $('.single .column3').find('.selected').removeClass('selected');
544
        $(this).addClass('selected');
545
        $(".single .column3 .previous").show();
546
        $(".single .column3 .next").show();
547
        if ($(this).attr("id") == $(".single .column3 .server-name:eq(1)").attr("id")) {
548
            $(".single .column3 .previous").hide();
549
        } else if ($(this).attr("id") == $(".single .column3 .server-name:last").attr("id")) {
550
            $(".single .column3 .next").hide();
551
        }
552
    });
553

554
    if ($.cookie('server')) {
555
        $('div#link-' + $.cookie('server')).click();
556
        $.cookie('server', null);
557
    }
558

559
    //if it is the last vm, hide the next button
560
    if ($("#machinesview-single.single .column3 .selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
561
        $("#machinesview-single.single .column3 .next").hide()
562
    } else {
563
        $("#machinesview-single.single .column3 .next").show()
564
    }
565

566
    //if it is the first vm, hide the prev button
567
    if ($("#machinesview-single.single .column3 .selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
568
        $("#machinesview-single.single .column3 .previous").hide()
569
    } else {
570
        $("#machinesview-single.single .column3 .previous").show()
571
    }
572

573
}
574

575
//enable prev-next buttons
576
$("#machinesview-single.single .column3 .previous").live('click', function(){
577
    if ($("#machinesview-single.single .column3 .selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
578
        return false;
579
    } else {
580
        current_server = $('#machinesview-single.single .column3').find('.selected').attr("id").substring(5);
581
        $('#machinesview-single.single').find('#' + current_server).hide();
582
        $('#machinesview-single.single').find('#' + current_server).prev().show();
583
        $('#machinesview-single.single .column3').find('#link-' + current_server).removeClass('selected');
584
        $('#machinesview-single.single .column3').find('#link-' + current_server).prev().addClass('selected');
585
        if ($("#machinesview-single.single .column3 .selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
586
            $(this).hide()
587
        }
588
        $("#machinesview-single.single .column3 .next").show()
589
        return false;
590
    }
591
});
592

593
$("#machinesview-single.single .column3 .next").live('click', function(){
594
    if ($("#machinesview-single.single .column3 .selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
595
        return false;
596
        } else {
597
        current_server = $('#machinesview-single.single .column3').find('.selected').attr("id").substring(5);
598
        $('#machinesview-single.single').find('#' + current_server).hide();
599
        $('#machinesview-single.single').find('#' + current_server).next().show();
600
        $('#machinesview-single.single .column3').find('#link-' + current_server).removeClass('selected');
601
        $('#machinesview-single.single .column3').find('#link-' + current_server).next().addClass('selected');
602
        //if it is the last vm, hide the next button
603
        if ($("#machinesview-single.single .column3 .selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
604
            $(this).hide()
605
        }
606
        $("#machinesview-single.single .column3 .previous").show();
607
        return false;
608
    }
609
});
610

611
//hide prev button on startup
612
$("#machinesview-single.single .column3 .previous").hide()
613

614
// basic functions executed on page load
615
if ( flavors.length == 0 && images.length == 0 ) {
616
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
617
    update_flavors();
618
    // populate image list
619
    update_images();
620
} else if ( flavors.length == 0 && images.length != 0 ) {
621
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
622
    update_flavors();
623
} else if ( flavors.length != 0 && images.length == 0 ) {
624
    // populate image list
625
    update_images();
626
    update_vms(UPDATE_INTERVAL);
627
} else {
628
    // start updating vm list
629
    update_vms(UPDATE_INTERVAL);
630
}
631

632
//FIXME: Hide and show welcome depending on number of machines
633
hideWelcome();
634
</script>