Statistics
| Branch: | Tag: | Revision:

root / ui / templates / networks.html @ a5bc3755

History | View | Annotate | Download (38.3 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 create button -->
39
<div id="networks-createcontainer">
40
    <div id="beforecreate"></div>
41
    <a id="networkscreate" rel="#networks-wizard" href="#">{% trans "Create New +" %}</a>
42
</div>
43

    
44
<!-- add new network overlay -->
45
<div>
46
    <div class="modal" id="networks-wizard">
47
        <div class="header">
48
        </div>
49
        <h2>{% trans "Name your network" %}</h2>
50
        <hr class="topruler" />
51
        <div class="container">
52
            <div class="name-input">
53
                <label>{% trans "Name" %}:</label>
54
                <input type="text" class="text" name="machine_name"></input>
55
                <span class="help">{% trans "(* Required field)" %}</span>
56
            </div>
57
        </div>
58
        <hr class="bottomruler" />
59
        <button type="button" id="add-network-cancel" class="cancel">{% trans "Cancel" %}</button>
60
        <button type="button" id="add-network-create" class="create">{% trans "Create Network" %}</button>
61
        <hr class="separator-end"></hr>
62
    </div>
63
</div>
64

    
65
<!-- networks list -->
66
<div id="networks-container">
67
    <!-- spinner while loading list -->
68
    <div class = "large-spinner"></div>
69

    
70
    <!-- public network template -->
71
    <div class="network" id="public-template">
72
        <div class="actions">
73
            {# Commented out the following until there is full public network support #}
74
            {# <a href="#" class="action-add">{% trans "Add Machine" %}</a> #}
75
        </div>
76
        <div class="confirm_single">
77
            <button class="yes">{% trans "Confirm" %}</button>
78
            <button class="no">{% trans "Cancel" %}</button>
79
        </div>
80
        <div class="action_error" align="center">
81
            {% trans "<span class='orange'>Error</span> on" %} <span class="action">{% trans "error action" %}</span>
82
            <span class="code"></span>
83
            <span class="message"></span>
84
            <button class="details">{% trans "Details" %}</button>
85
        </div>
86
        <div class="state">
87
            <div class="status">{% trans "Public Network" %}</div>
88
            <div class="indicator"></div>
89
            <div class="indicator"></div>
90
            <div class="indicator"></div>
91
            <div class="indicator"></div>
92
        </div>
93
        <img class="network-logos" src="static/internet.png" />
94
        <div href="#" class="name-div">
95
            <h5 class="namecontainer">
96
                <span class="name">{% trans "Internet" %}</span>
97
            </h5>
98
        </div>
99
        <h5 class="network-machines">
100
            {% trans "Show:" %} <span class="show-machines">{% trans "machines" %}</span>
101
            (<span class="machines-count">0</span>)
102
        </h5>
103
        <div class="network-contents">
104
            <div class="network-placeholder">
105
                <div class="network-contents-start-separator"></div>
106
                <div class="machines-list">
107
                <!-- append machines here -->
108
                </div>
109
                <div class="empty-network-slot" id="machine-template">
110
                    <div class='network-add-machine'>
111
                        {# Replace the following with the comment below for full public network functionality #}
112
                        {# <span class="add-icon">+</span> #}
113
                        <span>&nbsp;</span>
114
                    </div>
115
                </div>
116
            </div>
117
            <div class="network-contents-end-separator"></div>
118
        </div>
119
    </div>
120

    
121
    <!-- template for machines in public network -->
122
    <div class="network-machine" id="public-machine-template">
123
        <div class="machine-actions">
124
            <a href="#" class="action-details">{% trans "Details" %}</a>
125
        </div>
126
        <div class="confirm_single">
127
            <button class="yes">{% trans "Confirm" %}</button>
128
            <button class="no">{% trans "Cancel" %}</button>
129
        </div>
130
        <div class="action_error" align="center">
131
            {% trans "<span class='orange'>Error</span> on" %} <span class="action">{% trans "error action" %}</span>
132
            <span class="code"></span>
133
            <span class="message"></span>
134
            <button class="details">{% trans "Details" %}</button>
135
        </div>
136
        <div class="state">
137
            <div class="ip4-container status">
138
                <span class="discreet">{% trans "IPv4" %}: </span>
139
                <span class="ip4">192.94.73.15</span>
140
            </div>
141
            <div class="ip6-container status">
142
                <span class="discreet">{% trans "IPv6" %}: </span>
143
                <span class="ip6">vv</span>
144
            </div>
145
            <img class="spinner" style="display:none" src="static/icons/indicators/medium/progress.gif" />
146
            <img class="wave" style="display:none" src="static/icons/indicators/medium/wave.gif" />
147
        </div>
148
        <img class="logo" src="static/icons/machines/medium/debian-on.png" />
149
        <div class='network-remove-machine'>
150
            {# Replace the following with the comment below for full public network functionality #}
151
            {# <span class="remove-icon">X</span> #}
152
            <span>&nbsp;</span>
153
        </div>
154
        <div href="#" class="machine-name-div">
155
            <h5 class="namecontainer">
156
                <span class="name">my desktop1</span>
157
            </h5>
158
        </div>
159
        <h5 class="machine-settings">
160
            <span class="ip">{% trans "IPs" %}</span> |
161
            <span class="show-firewall">{% trans "Firewall" %}</span>
162
            (<span class="firewall-off">{% trans "Off" %}</span>)
163
        </h5>
164
        <div class="firewall-content">
165
            <div class="firewall-contents-start-separator"></div>
166
            <input type="radio" class="checkboxes" name="image-id1" />
167
            <span class="checkbox-legends">{% trans "Unprotected mode (Firewall off)" %}</span>
168
            <br />
169
            <input type="radio" class="checkboxes" name="image-id1" />
170
            <span class="checkbox-legends">{% trans "Fully protected mode (Firewall on)" %}</span>
171
            <br />
172
            <input type="radio" class="checkboxes" name="image-id1" />
173
            <span class="checkbox-legends">{% trans "Basically protected mode (Firewall on)" %}</span>
174
            <br />
175
            <input type="radio" class="checkboxes" name="image-id1" />
176
            <span class="checkbox-legends">{% trans "Custom protection" %} <a href="#" class="firewall-settings">{% trans "settings" %}</a> {% trans "(Advanced users only)" %}</span>
177
            <button type="submit" class="firewall-apply">{% trans "Apply" %}</button>
178
            <div class="firewall-contents-end-separator"></div>
179
        </div>
180
        <div class="network-separator machines"></div>
181
    </div>
182

    
183
    <!-- private network template -->
184
    <div class="network" id="private-template">
185
        <div class="actions">
186
            <a href="#" class="action-add">{% trans "Add Machine" %}</a>
187
            <a href="#" class="action-network-destroy">{% trans "Destroy" %}</a>
188
        </div>
189
        <div class="confirm_single">
190
            <button class="yes">{% trans "Confirm" %}</button>
191
            <button class="no">{% trans "Cancel" %}</button>
192
        </div>
193
        <div class="action_error" align="center">
194
            {% trans "<span class='orange'>Error</span> on" %} <span class="action">{% trans "error action" %}</span>
195
            <span class="code"></span>
196
            <span class="message"></span>
197
            <button class="details">{% trans "Details" %}</button>
198
        </div>
199
        <div class="state">
200
            <div class="status">{% trans "Private Network" %}</div>
201
            <div class="indicator"></div>
202
            <div class="indicator"></div>
203
            <div class="indicator"></div>
204
            <div class="indicator"></div>
205
            <img class="spinner" style="display:none" src="static/icons/indicators/medium/progress.gif" />
206
            <img class="wave" style="display:none" src="static/icons/indicators/medium/wave.gif" />
207
        </div>
208
        <img class="network-logos" src="static/network.png" />
209
        <div href="#" class="name-div">
210
            <h5 class="namecontainer editable">
211
                <span class="name">{% trans "My Network 1" %}</span>
212
                <span class="rename-network"></span>
213
                <div class="editbuttons" style="display:none">
214
                    <span class="save" />
215
                    <span class="cancel" />
216
                </div>
217
            </h5>
218
        </div>
219
        <h5 class="network-machines">
220
            {% trans "Show:" %} <span class="show-machines">{% trans "machines" %}</span>
221
            (<span class="machines-count">0</span>)
222
        </h5>
223
        <div class="network-contents">
224
            <div class="network-placeholder">
225
                <div class="network-contents-start-separator"></div>
226
                <div class="machines-list">
227
                <!-- append machines here -->
228
                </div>
229
                <div class="empty-network-slot" id="machine-template">
230
                    <div class='network-add-machine'><span class="add-icon">+</span></div>
231
                </div>
232
            </div>
233
            <div class="network-contents-end-separator"></div>
234
        </div>
235
        <div class="separator"></div>
236
    </div>
237

    
238
    <!-- template for machines in private network -->
239
    <div class="network-machine" id="private-machine-template">
240
        <div class="machine-actions">
241
            <a href="#" class="action-disconnect">{% trans "Disconnect" %}</a>
242
            <a href="#" class="action-details">{% trans "Details" %}</a>
243
        </div>
244
        <div class="confirm_single">
245
            <button class="yes">{% trans "Confirm" %}</button>
246
            <button class="no">{% trans "Cancel" %}</button>
247
        </div>
248
        <div class="action_error" align="center">
249
            {% trans "<span class='orange'>Error</span> on" %} <span class="action">{% trans "error action" %}</span>
250
            <span class="code"></span>
251
            <span class="message"></span>
252
            <button class="details">{% trans "Details" %}</button>
253
        </div>
254
        <div class="state">
255
            <img class="spinner" style="display:none" src="static/icons/indicators/medium/progress.gif" />
256
            <img class="wave" style="display:none" src="static/icons/indicators/medium/wave.gif" />
257
        </div>
258
        <img class="logo" src="static/icons/machines/medium/debian-on.png" />
259
        <div class='network-remove-machine'><span class="remove-icon">X</span></div>
260
        <div href="#" class="machine-name-div">
261
            <h5 class="namecontainer editable">
262
                <span class="name">my desktop1</span>
263
            </h5>
264
        </div>
265
        <h5 class='machine-connect'>
266
            <span>{% trans "Connect" %}</span> {% trans "to manage private IPs" %}
267
        </h5>
268
        <div class="network-separator machines"></div>
269
    </div>
270

    
271
    <!-- the actual structure to be populated -->
272
    <div class="public-networks"></div>
273
    <div class="private-networks" style="display:none;"></div>
274
</div>
275

    
276
<!-- add servers to network overlay -->
277
<div>
278
    <div id="add-machines-wizard" class="modal">
279
        <h3 class="popup-header">{% trans "Add machine" %}</h3>
280
        <p style='display:none;'>hidden network id</p>
281
        <div class="popup-body">
282
            <div class="popup-body-inner">
283
                <div class="popup-title">{% trans "Select machines to add to:" %}</div>
284
                <div class="network-name"></div>
285
                <div class="popup-separator"></div>
286
                <div class="machines-container">
287
                    <div class="large-spinner"></div>
288
                    <div id='machine-entry-template' style="display:none;">
289
                        <input type="checkbox" />
290
                        <img class=list-logo src="static/icons/machines/small/debian-on.png" title="debian"></img>
291
                        <span class="machine-name">kati</span>
292
                    </div>
293
                </div>
294
            </div>
295
        </div>
296
        <div class="buttons">
297
            <button type="button" class="cancel" id="add-server-cancel">{% trans "Cancel" %}</button>
298
            <button type="button" class="add" id="add-server-add">{% trans "Add" %}</button>
299
        </div>
300
    </div>
301
</div>
302

    
303
<a id="add-machines-overlay" href="#" rel="#add-machines-wizard"></a>
304

    
305
<!-- multiple confirmation dialog -->
306
<div class="confirm_multiple">
307
    <p>{% trans "Your actions will affect" %} <span class="actionLen">XX</span> {% trans "networks" %}</p>
308
    <button class="yes">{% trans "Confirm All" %}</button>
309
    <button class="no">{% trans "Cancel All" %}</button>
310
</div>
311

    
312
<script>
313
// add network wizard initialization
314
$(function() {
315
    // create wizard overlay
316
    $("a#networkscreate").overlay({
317
        mask: '#000',
318
        effect: 'default',
319
        top: '10%',
320
        closeOnClick: false,
321
        oneInstance: false,
322
        closeOnEsc: true,
323
        load: false
324
    });
325
});
326

327
// intercept click to create new private network
328
$("#networkscreate").click(function() {
329
    // reset and load wizard
330
    $('#networks-wizard span.help').removeClass('red');
331
    $('#networks-wizard input').val('');
332
    $('#networks-wizard #add-network-create').text('{% trans 'Create Network' %}');
333
    $("#networks-wizard").show();
334
    $('#networks-wizard input').focus();
335
    $("a#networkscreate").data('overlay').load();
336
    return false;
337
});
338

339
// exit the add machine to network wizard
340
$("#add-network-cancel").live('click', function() {
341
    $("a#networkscreate").overlay().close();
342
});
343

344
// add selected machines to network
345
$("#add-network-create").live('click', function() {
346
    if ($('#networks-wizard input').val() == '') {
347
        $('#networks-wizard input').focus();
348
        $('#networks-wizard span.help').addClass('red');
349
    } else {
350
        $(this).text('');
351
        $(this).html('<img src="static/icons/indicators/medium/horizontal-progress.gif"></img>');
352
        networkName = $('#networks-wizard input').val();
353
        create_network(networkName);
354
    }
355
    return false;
356
});
357

358
// toggle component with class network-contents
359
$("#networks-pane .show-machines").live('click', function() {
360
    if ($('#networks-pane .network-contents .network-machine').length > 0) {
361
        $(this).parent().next("#networks-pane .network-contents").slideToggle(600);
362
    }
363
    return false;
364
});
365

366
// toggle component with class network-contents
367
$("#networks-pane .network-logos").live('click', function() {
368
    $(this).siblings("#networks-pane .network-contents").slideToggle(600);
369
    return false;
370
});
371

372
//initiate network renaming
373
$("#networks-pane .name-div .rename-network, #networks-pane .name-div h5.editable span.name").live('click', function() {
374
    $(this).parent().find('.name').html("<input id=\"txtEdit\" type=\"text\" class=\"nametextbox\" value=\"" +
375
                                        $(this).parent().find('.name').text() +
376
                                        "\" / ><span class=\"oldValue\">" +
377
                                        $(this).parent().find('.name').text() + "</span>");
378
    $(this).parent().find('.rename-network').hide();
379
    $(this).parent().find(".editbuttons").fadeIn();
380
    $(this).parent().find(".nametextbox").focus().select();
381
    $(this).parent().removeClass('editable');
382

383
    //submit wizard by pressing enter on the name textbox
384
    $("#txtEdit").keydown(function (e) {
385
        if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
386
            $(this).parent().parent().find('div.editbuttons span.save').click();
387
            return false;
388
        } else if ((e.which && e.which == 27) || (e.keyCode && e.keyCode == 27)) {
389
            $(this).parent().parent().find('div.editbuttons span.cancel').click();
390
            return true;
391
        }
392
    });
393
    return false;
394
});
395

396
//rename machine
397
$("#networks-pane .name-div .editbuttons .save").live('click', function() {
398
    networkID = $(this).closest('.network').attr("id").split('-').pop();
399
    networkName = $(this).parent().parent().find('.nametextbox').val();
400
    if (networkName.trim() == ''){
401
        return false;
402
    }
403
    $(this).parent().parent().find('.name').html($(this).parent().parent().find('.nametextbox').val());
404
    $(this).parent().parent().find(".editbuttons").fadeOut("fast");
405
    $(this).parent().parent().find(".rename-network").fadeIn("slow");
406
    rename_network(networkID, networkName);
407
    return false;
408
});
409

410
//cancel renaming
411
$("#networks-pane .name-div .editbuttons .cancel").live('click', function() {
412
    $(this).parent().parent().find('.name').html($(this).parent().parent().find('.oldValue').text());
413
    $(this).parent().parent().find(".editbuttons").hide();
414
    $(this).parent().parent().find(".rename-network").fadeIn();
415
    $(this).parent().parent().addClass('editable');
416
    return false;
417
});
418

419
// intercept click to delete network
420
$("#networks-pane .action-network-destroy").live('click', function() {
421
    var networkID = $(this).parent().parent().attr('id').split('-').pop();
422
    var networkName = $(this).parent().parent().find(".name-div span.name").text();
423
    var found = false;
424
    $(this).parent().children('a').removeClass('selected');
425
    $(this).addClass('selected');
426
    $(this).parent().addClass('display')
427
    $(this).parent().parent().find('.action_error').hide();
428
    for (i=0; i < pending_actions.length; i++){ // if there is already a pending action for this network replace it
429
        if (pending_actions[i][0] == delete_network && pending_actions[i][1] == networkID){
430
            pending_actions[i][0] = delete_network;
431
            found = true
432
        }
433
    }
434
    if (!found) {
435
        // no pending action for this network was found, so let's just add it to the list
436
        pending_actions.push([delete_network, networkID, networkName]);
437
    }
438
    update_network_confirmations();
439
    return false;
440
});
441

442
// intercept click to remove machine from network
443
$("#networks-pane .remove-icon").live('click', function() {
444
    $(this).closest('.network-machine').find('.action-disconnect').click();
445
    return false;
446
});
447

448
// intercept click to remove machine from network
449
$("#networks-pane .action-disconnect").live('click', function() {
450
    var serverID = $(this).parent().parent().attr('id').split('-').pop();
451
    var networkID = $(this).closest('.network').attr('id').split('-').pop();
452
    var found = false;
453
    $(this).parent().children('a').removeClass('selected');
454
    $(this).addClass('selected');
455
    $(this).parent().addClass('display')
456
    $(this).parent().parent().find('.action_error').hide();
457
    for (i=0; i < pending_actions.length; i++){
458
        // if there is already a pending action for this network replace it
459
        if (pending_actions[i][0] == remove_server_from_network &&
460
            pending_actions[i][1] == networkID &&
461
            pending_actions[i][2] == serverID) {
462
                pending_actions[i][0] = remove_server_from_network;
463
                found = true
464
        }
465
    }
466
    if (!found) {
467
        // no pending action for this network was found, so let's just add it to the list
468
        pending_actions.push([remove_server_from_network, networkID, serverID]);
469
    }
470
    update_network_confirmations();
471
    return false;
472
});
473

474
$("#networks-pane .action-details").live('click', function() {
475
    var serverID = $(this).parent().parent().attr('id').split('-').pop();
476
    $.cookie('view', '2');
477
    $.cookie('server', serverID);
478
    $('a#machines').click();
479
    return false
480
});
481

482
// add machines wizard initialization
483
$(function() {
484
    // create wizard overlay
485
    $("a#add-machines-overlay").overlay({
486
        mask: '#000',
487
        effect: 'default',
488
        top: '10%',
489
        closeOnClick: false,
490
        oneInstance: false,
491
        closeOnEsc: true,
492
        load: false
493
    });
494
});
495

496
// intercept click to add machine to  network
497
$("#networks-pane .action-add").live('click', function() {
498
    // reset pre-existing values
499
    $('#add-server-add').text('{% trans 'Add' %}');
500
    $("#add-machines-wizard .network-name").text($(this).closest('.network').find('.name-div span.name').text());
501
    $("#add-machines-wizard p").text($(this).closest('.network').attr('id').split('-').pop());
502
    $("#add-machines-wizard .large-spinner").show();
503
    $('[id^="list-entry-server-"]').remove();
504
    // list new values
505
    list_machines();
506
    // load wizard
507
    $("#add-machines-wizard").show();
508
    $("a#add-machines-overlay").data('overlay').load();
509
    return false;
510
});
511

512
//submit wizard by pressing enter on the name textbox
513
$("#networks-wizard div.name-input input.text").keypress(function (e) {
514
    if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
515
        $('#add-network-create').click();
516
        return false;
517
    } else {
518
        return true;
519
    }
520
});
521

522
// intercept click to bring up the add machine to network wizard
523
$("#networks-pane .add-icon").live('click', function() {
524
    $(this).closest('.network').find('.action-add').click();
525
});
526

527
// get machines in public network and list them in add server to network wizard
528
function list_machines() {
529
    var networkID = $("#add-machines-wizard p").text();
530
    // get the list of servers from the UI
531
    var all_machines = $("#networks-pane .public-networks .network-machine");
532

533
    $.each(all_machines, function(i, machine) {
534
        var currentID = machine.id.split('-').pop();
535
        // if machine already exists in private network
536
        if ( $('#net-' + networkID + '-server-' + currentID).length > 0 ) {
537
            // do nothing
538
        } else {
539
            // put it in the list
540
            var entry = $("#add-machines-wizard #machine-entry-template").clone().attr("id", "list-entry-server-" + currentID);
541
            entry.find('input').attr("name", currentID);
542
            entry.find('img').attr('src', 'static/icons/machines/small/' + $(machine).find('img.logo').attr('src').split('/').pop());
543
            entry.find('.machine-name').text($(machine).find('span.name').text());
544
            entry.appendTo("#add-machines-wizard .machines-container");
545
        }
546
    });
547
    $("#add-machines-wizard .large-spinner").hide();
548
    $('[id^="list-entry-server-"]').fadeIn("slow");
549
    return false;
550
}
551

552
// exit the add machine to network wizard
553
$("#add-server-cancel").live('click', function() {
554
    $("a#add-machines-overlay").overlay().close();
555
});
556

557
// add selected machines to network
558
$("#add-server-add").live('click', function() {
559
    var selections = $("#add-machines-wizard :checkbox:checked");
560
    var networkID = $("#add-machines-wizard p").text();
561
    var serverIDs = [];
562
    $.each(selections, function(i, selection) {
563
        serverIDs.push(selection.name);
564
    });
565
    $(this).text('');
566
    add_server_to_network(networkID, serverIDs);
567
    $(this).html('<img src="static/icons/indicators/medium/horizontal-progress.gif"></img>');
568
    return false;
569
});
570

571
// toggle component with class firewall-contents
572
$("#networks-pane .show-firewall").live('click', function() {
573
    $(this).parent().next(".firewall-content").slideToggle(600);
574
    return false;
575
});
576

577
//hide firewall content on apply click
578
$("#networks-pane .firewall-apply").live('click', function() {
579
    $(this).parent().slideToggle(600);
580
    return false;
581
});
582

583
// confirm single action
584
$("#networks-pane div.confirm_single .yes").live('click', function() {
585
    // this works both for server and network actions
586
    var serverID = [];
587
    if ($(this).closest('.network-machine').attr('id')) {
588
        serverID = $(this).closest('.network-machine').attr('id').split('-').pop();
589
    }
590
    var networkID = $(this).closest('.network').attr("id").split('-').pop();
591
    // execute actions
592
    for (i=0;i<pending_actions.length;i++){
593
        // if there is a pending action for this server execute it
594
        if (pending_actions[i][0] == delete_network &&
595
            pending_actions[i][1] == networkID){
596
                action = pending_actions.splice(i,1)[0];
597
                $(this).parent().parent().find('.status').text(TRANSITIONS['Destroying']);
598
                $(this).parent().parent().find('.spinner').show();
599
                action[0]([action[1]]); // execute action
600
        } else if ( pending_actions[i][0] == remove_server_from_network &&
601
                    pending_actions[i][1] == networkID &&
602
                    pending_actions[i][2] == serverID) {
603
                        action = pending_actions.splice(i,1)[0];
604
                        action[0]([action[1]], [action[2]]); // execute action
605
        }
606
    }
607
    $(this).parent().hide();
608
    $(this).parent().prev().children('a').removeClass('selected');
609
    $(this).parent().prev().removeClass('display');
610
    update_network_confirmations();
611
    return false;
612
});
613

614
// cancel single action
615
$("#networks-pane div.confirm_single .no").live('click', function(){
616
    // this works both for server and network actions
617
    var serverID = [];
618
    if ($(this).closest('.network-machine').attr('id')) {
619
        serverID = $(this).closest('.network-machine').attr('id').split('-').pop();
620
    }
621
    var networkID = $(this).closest('.network').attr("id").split('-').pop();
622
    // remove the action from the pending list
623
    $(this).parent().prev().children('a').removeClass('selected');
624
    $(this).parent().prev().removeClass('display');
625
    for (i=0; i < pending_actions.length; i++){ // if there is a pending action for this network remove it
626
        if (pending_actions[i][0] == delete_network && pending_actions[i][1] == networkID){
627
                pending_actions.splice(i,1);
628
        } else if ( pending_actions[i][0] == remove_server_from_network &&
629
                    pending_actions[i][1] == networkID &&
630
                    pending_actions[i][2] == serverID) {
631
                        pending_actions.splice(i,1);
632
        }
633
    }
634
    $(this).parent().hide();
635
    update_network_confirmations();
636
    return false;
637
});
638

639
// show, single action, error details
640
$("#networks-pane div.action_error .details").live('click', function(){
641
    // remove the action from the pending list
642
    ajax_error($(this).parent().children('.code').text(),
643
                 undefined,
644
                 $(this).parent().children('.action').text(),
645
                 $(this).parent().children('.message').text());
646
    $(this).parent().hide();
647
    return false;
648
});
649

650
// confirm all actions
651
$("#networks-pane div.confirm_multiple .yes").live('click', function(){
652
    while(pending_actions.length > 0){ // if there is a pending action for this network execute it
653
        action = pending_actions.pop(); // extract action
654
        var networkID = action[1];
655
        $('#networks-pane .selected').removeClass('selected');
656
        $('#networks-pane .display').removeClass('display');
657
        if (action[0] == delete_network) {
658
            $('#networks-pane #net-' + networkID + ' .status').text(TRANSITIONS['Destroying']);
659
            $('#networks-pane #net-' + networkID + ' .spinner').show();
660
            action[0]([networkID]); // execute action
661
        } else if (action[0] == remove_server_from_network) {
662
            action[0]([action[1]], [action[2]]); // execute action
663
        }
664
    }
665
    update_network_confirmations();
666
    return false;
667
});
668

669
// cancel all actions
670
$("#networks-pane div.confirm_multiple .no").live('click', function(){
671
    pending_actions = [];
672
    $('#networks-pane .selected').removeClass('selected');
673
    $('#networks-pane .display').removeClass('display');
674
    update_network_confirmations();
675
    return false;
676
});
677

678
// update the networks list
679
function update_networks_view(servers_data, networks_data){
680
    /*
681
    Go through the input data. Update existing entries, add
682
    new ones to the list
683
    */
684

685
    // check for changes in networks
686
    if (networks_data){
687
        /*
688
        Here we are interested in private networks only
689
        and not for any server they might contain
690
        */
691

692
        // update private networks
693
        $.each(networks_data.networks.values, function(i,network) {
694
            // search DOM for this network
695
            existing = $('#networks-pane #net-' + network.id);
696

697
            // if multiple machines exist in the DOM, delete all but one
698
            // defensive coding - that shouldn't happen normally
699
            while (existing.length > 1){
700
                existing.remove();
701
            }
702
            // If network already exists in DOM, update it
703
            if (existing.length){
704
                // network was deleted
705
                if (network.status == 'DELETED') {
706
                    existing.remove();
707
                }
708

709
                // network was renamed
710
                if (existing.find('.name-div span.name').text() != network.name) {
711
                    // set the new name
712
                    existing.find('.name-div span.name').text(network.name);
713
                }
714
            }
715
            // If network does not exist in DOM, create it, do not take into account public network
716
            else if (network.id != 'public'){
717
                var privNet = $("#networks-pane #private-template").clone().attr("id", "net-" + network.id);
718
                privNet.find(".name-div span.name").text(network.name).fadeIn("slow");
719
                privNet.appendTo("#networks-pane .private-networks");
720
            }
721
        });
722
    }
723

724
    // check for changes in servers
725
    if (servers_data) {
726
        /*
727
        Here we are interested in any server contained
728
        either in a public network or a private one
729
        */
730
        $.each(servers_data.servers.values, function(i,server) {
731
            /*
732
            First update the public network
733
            */
734

735
            // search public network's DOM for this server
736
            existing_public = $('#networks-pane #net-pub-server-' + server.id);
737
            // get the server's OS icon
738
            var server_image = os_icon(server.metadata);
739

740
            // if multiple servers exist in public network, delete all but one
741
            // defensive coding - that shouldn't happen normally
742
            while (existing_public.length > 1){
743
                existing_public.remove();
744
            }
745

746
            // server was deleted
747
            if (server.status == 'DELETED') {
748
                existing_public.remove();
749
            }
750

751
            // If server already exists in public network, update it
752
            if (existing_public.length){
753
                // server was renamed
754
                if (server.name != existing_public.find('span.name').text()) {
755
                    existing_public.find('span.name').text(server.name);
756
                }
757
                // server has changed state
758
                if (server.status=='BUILD' || server.status=='ACTIVE' ||server.status=='REBOOT') {
759
                    existing_public.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-on.png');
760
                } else {
761
                    existing_public.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-off.png');
762
                }
763
                // server has new ips
764
                var old_ip4 = existing_public.find('span.ip4').text();
765
                var old_ip6 = existing_public.find('span.ip6').text();
766
                // the following are valid because the public ips always come in this order from the api
767
                var new_ips = get_public_ips(server);
768
                var new_ip4 = new_ips['ip4'];
769
                var new_ip6 = new_ips['ip6'];
770
                if (old_ip4 != new_ip4) {
771
                    if (new_ips['ip4'] == undefined) {
772
                        existing_public.find(".ip4-container").hide();
773
                    } else {
774
                        existing_public.find('span.ip4').text(new_ip4);
775
                    }
776
                }
777
                if (old_ip6 != new_ip6) {
778
                    if (new_ip6 == undefined) {
779
                        existing_public.find(".ip6-container").hide();
780
                    } else {
781
                        existing_public.find('span.ip6').text(new_ip6);
782
                    }
783
                }
784
                //TODO: server has changed OS
785
            }
786
            // If server does not exist in public network, create it
787
            else {
788
                var machine = $("#networks-pane #public-machine-template").clone().attr("id", "net-pub-server-" + server.id).fadeIn("slow");
789
                machine.find('span.name').text(server.name);
790
                // find and display ips
791
                var ips = get_public_ips(server);
792
                if (ips['ip4'] == undefined) {
793
                    machine.find(".ip4-container").hide();
794
                } else {
795
                    machine.find("span.ip4").text(ips['ip4']);
796
                }
797
                if (ips['ip6'] == undefined) {
798
                    machine.find(".ip6-container").hide();
799
                } else {
800
                    machine.find("span.ip6").text(ips['ip6']);
801
                }
802
                // add the proper icon
803
                if (server.status=='BUILD' || server.status=='ACTIVE' ||server.status=='REBOOT') {
804
                    machine.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-on.png');
805
                } else {
806
                    machine.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-off.png');
807
                }
808
                machine.appendTo("#networks-pane .public-networks .machines-list");
809
            }
810
            /*
811
            Now update all private networks
812
            Since one server may belong to more than one private networks,
813
            we follow a different approach.
814
            We check each server and add, update or leave it as it is accordingly
815
            */
816
            try {
817
                $.each(server.addresses.values, function(i,server_net) {
818
                    // find in which private networks it belongs
819
                    if (server_net.id != "public") {
820
                        var existing_private = $("#networks-pane .private-networks #net-" + server_net.id + "-server-" + server.id);
821
                        // add new server
822
                        if (!existing_private.length) {
823
                            var machine = $("#networks-pane #private-machine-template").clone().attr("id", "net-" + server_net.id + "-server-" + server.id).fadeIn("slow");
824
                            machine.find('span.name').text(server.name);
825
                            if (server.status=='BUILD' || server.status=='ACTIVE' ||server.status=='REBOOT') {
826
                                machine.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-on.png');
827
                            } else {
828
                                machine.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-off.png');
829
                            }
830
                            machine.appendTo("#networks-pane .private-networks #net-" + server_net.id + " .machines-list");
831
                        }
832
                        // server was deleted
833
                        if (server.status == 'DELETED') {
834
                            existing_private.remove();
835
                        }
836
                        // server was renamed
837
                        if (server.name != existing_private.find('span.name').text()) {
838
                            existing_private.find('span.name').text(server.name);
839
                        }
840
                        // server has changed state
841
                        if (server.status=='BUILD' || server.status=='ACTIVE' ||server.status=='REBOOT') {
842
                            existing_private.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-on.png');
843
                        } else {
844
                            existing_private.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-off.png');
845
                        }
846
                        //TODO: server has changed OS
847
                    }
848
                });
849
            } catch (err) {
850
                try{console.info('Server ' + server.id + ' has no network addresses')}catch(err){};
851
            }
852
        });
853
    }
854

855
    $("#networks-pane #networks-container > .large-spinner").hide();
856

857
    // show all separators and hide the last one
858
    $("div.private-networks div.network div.separator").show();
859
    $("div.private-networks div.network div.separator:last").hide();
860
    // update the counters of servers in each network
861
    var nets = $('#networks-pane .network');
862
    $.each(nets, function(i,net) {
863
        $(net).find('span.machines-count').text($(net).find('.network-machine').length);
864
    });
865

866
    // the private div shows only when private networks are available
867
    if ($("div.private-networks div.network").length > 0) {
868
        $("div.private-networks").fadeIn("slow");
869
    } else {
870
        $("div.private-networks").fadeOut("slow");
871
    }
872

873
    // tag the last seperator for better styling
874
    $("#pub .network-machine").removeClass('last');
875
    $("#pub .network-machine").last().addClass('last');
876
}
877

878
// reposition multiple confirmation box on window resize
879
$(window).resize(function(){
880
    if (this.innerHeight - 220 < $('#networks-pane #networks-container').height())
881
        $('#networks-pane .confirm_multiple').addClass('fixed');
882
    else
883
        $('#networks-pane .confirm_multiple').removeClass('fixed');
884
});
885

886
// basic functions executed on page load
887
// hide the all of the networks contents
888
$("#networks-pane .network-contents").hide();
889
// hide the all of the firewall contents
890
$("#networks-pane .firewall-content").hide();
891
changes_since = 0; // to reload full list of servers
892
networks_changes_since= 0; // to reload full list of networks
893
// there is alway one public network to render
894
var pubNet = $("#networks-pane #public-template").clone().attr("id", "pub").fadeIn("slow");
895
pubNet.appendTo("#networks-pane .public-networks");
896
update_networks(UPDATE_INTERVAL);
897

    
898
</script>