Statistics
| Branch: | Tag: | Revision:

root / ui / templates / home.html @ 9ed51b7e

History | View | Annotate | Download (23.1 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
<html>
37

    
38
{% load i18n %}
39
<!DOCTYPE html>
40
<head>
41
    <title>~okeanos</title>
42
    <!-- include the Tools -->
43
    <!-- jquery tools minified for deployment-->
44
    <script src="static/jquery.tools.min.js"></script>
45
    <!-- jquery tools source for JS debugging -->
46
    <!--
47
    <script src="http://flowplayer.org/tools/download/1.2.5/jquery-1.4.2.js"></script>
48
    <script src="http://flowplayer.org/tools/download/1.2.5/tabs/tabs.js"></script>
49
    <script src="http://flowplayer.org/tools/download/1.2.5/scrollable/scrollable.js"></script>
50
    <script src="http://flowplayer.org/tools/download/1.2.5/overlay/overlay.js"></script>
51
    <script src="http://flowplayer.org/tools/download/1.2.5/rangeinput/rangeinput.js"></script>
52
    <script src="http://flowplayer.org/tools/download/1.2.5/toolbox/toolbox.expose.js"></script>
53
    -->
54
    <script src="static/jquery.cookie.js"></script>
55
    <script src="static/jquery.client.js"></script>
56
    <script src="static/json2.js"></script>
57
    <script src="static/jquery.dataTables.min.js"></script>
58
    <script src="static/invitations.js"></script>
59
    <script src="static/synnefo.js"></script>
60

    
61
    <link rel="stylesheet" type="text/css" href="static/main.css"/>
62
    <!--[if IE]><style type="text/css" media="all">@import url(static/ie.css);</style><![endif]-->
63
    <script>
64
        // empty object for console to avoid errors in browsers that don't support it
65
        if (!window.console) {window.console = {}; window.console.log = window.console.info = window.console.debug =
66
            window.console.error = function() {}};
67

68
        //populate available image icons array
69
        var os_icons = {{image_icons|safe}};
70

71
        // timeout value from settings.py
72
        var TIMEOUT = {{timeout}};
73
        var UPDATE_INTERVAL = {{update_interval}};
74
        var LOGOUT_REDIRECT = undefined;
75
        var INVITATIONS_URL = "{% url invitations %}"
76
        var INVITATIONS_TITLE = "{% trans "Invitations" %}"
77
        var APP_DEBUG = {% if DEBUG %}true{% else %}false{% endif %};
78

79
        // server statuses and transitions
80
        var STATUSES = {
81
            'UNKNOWN'   : '{% trans "Unknown" %}',
82
            'BUILD'     : '{% trans "Building" %}',
83
            'REBOOT'    : '{% trans "Rebooting" %}',
84
            'STOPPED'   : '{% trans "Stopped" %}',
85
            'ACTIVE'    : '{% trans "Running" %}',
86
            'ERROR'     : '{% trans "Error" %}'
87
        };
88

89
        var TRANSITIONS = {
90
            'Shutting down' : '{% trans "Shutting down" %}',
91
            'Rebooting'     : '{% trans "Rebooting" %}',
92
            'Starting'      : '{% trans "Starting" %}',
93
            'Destroying'    : '{% trans "Destroying" %}',
94
            'Connecting'    : '{% trans "Connecting" %}',   // used only in networks
95
            'Disconnecting' : '{% trans "Disconnecting" %}' // used only in networks
96
        };
97

98
        // Server statuses and transitions that should be displayed as active or inactive
99
        var ACTIVE_STATES = [
100
            '{% trans "Building" %}',
101
            '{% trans "Rebooting" %}',
102
            '{% trans "Running" %}',
103
            '{% trans "Shutting down" %}',
104
            '{% trans "Rebooting" %}',
105
            '{% trans "Destroying" %}'
106
        ];
107

108
        var INACTIVE_STATES = [
109
            '{% trans "Unknown" %}',
110
            '{% trans "Stopped" %}',
111
            '{% trans "Error" %}',
112
            '{% trans "Starting" %}',
113
            '{% trans "Destroying" %}'
114
        ];
115

116
        // Network statuses and transitions
117
        var NET_STATES = {
118
            'ACTIVE'        : '{% trans "Private network" %}',  // this comes from the API
119
            'DELETED'       : '{% trans "Deleted" %}',          // this comes from the API
120
            'Destroying'    : '{% trans "Destroying" %}',
121
            'Connecting'    : '{% trans "Connecting" %}',
122
            'Disconnecting' : '{% trans "Disconnecting" %}'
123
        };
124

125
        var ERRORS = {
126
            // error message header
127
            'HEADER' : '{% trans "Error" %}',
128
            // default
129
            'DEFAULT' : '{% trans "Could not contact the service. Please check your network connectivity and try again." %}',
130
            // bad request
131
            '400' : '{% trans "Malformed request." %}',
132
            // not found
133
            '404' : '{% trans "Your request has failed. Resource not found." %}',
134
            // internal server error
135
            '500' : '{% trans "There has been an Internal Error. Our administrators have been notified." %}',
136
            // service unavailable
137
            '501' : '{% trans "This server has not been implemented yet." %}',
138
            // service unavailable
139
            '502' : '{% trans "Bad Gateway error." %}',
140
            // service unavailable
141
            '503' : '{% trans "This service is unavailable right now, please try again later." %}',
142
            // no server handshake
143
            '0' : '{% trans "Could not contact the server." %}',
144
            // no images found
145
            'NO_IMAGES' : '{% trans "Cannot show the Create machine wizard: No images found." %}',
146
            // no flavors found
147
            'NO_FLAVORS' : '{% trans "Cannot show the Create machine wizard: No machine configurations found." %}',
148
            // error box title
149
            'GENERIC_POPUP_HEADER' : '{% trans "Something seems to have gone wrong :( Here is what happened:" %}',
150
            // no advanced details
151
            'NO_DETAILS' : '{% trans "Νο advanced details provided" %}'
152
        };
153

154
        var SUCCESS = {
155
            'HEADER' : '{% trans "Success" %}',
156
            'DEFAULT' : '{% trans "Your request has been succefully executed." %}',
157
            'PASSWORD' : '{% trans "Password:" %}',
158
            'CREATE_VM_SUCCESS' : '{% trans "Success" %}',
159
            'CREATE_VM_SUCCESS_ONE' : '{% trans "Your new machine is now buidling... (this might take a few minutes)" %}',
160
            'CREATE_VM_SUCCESS_TWO' : '{% trans "Write down your password now:" %}',
161
            'CREATE_VM_SUCCESS_THREE' : '{% trans "You will need this later to connect to your machine." %}',
162
            'CREATE_VM_SUCCESS_FOUR' : '{% trans "After closing this window you will NOT be able to retrieve it again." %}'
163
        };
164

165
        var VARIOUS = {
166
            'CONFIRM' : '{% trans "Confirm" %}',
167
            'CANCEL' : '{% trans "Cancel" %}',
168
            'APPLY' : '{% trans "Apply" %}',
169
            'OFF' : '{% trans "Off" %}',
170
            'ON' : '{% trans "On" %}'
171
        };
172

173
        // ajax error checking
174
        function ajax_error(status, serverID, action, responseText) {
175
             // close existing overlays to begin with
176
            close_all_overlays();
177
            // clear old deferred calls (stops all auto-updates)
178
            clearTimeout(deferred);
179

180
            $('#error-success').addClass('error');
181
            $('#error-success').removeClass('success');
182

183
            var serverName = '';
184

185
            if (serverID !== undefined) {
186
                // standard view
187
                serverName = $("#" + serverID).find("span.name").text();
188
                if (serverName === "") { // list view
189
                    serverName = $("#" + serverID).parent().parent().find("span.name").text();
190
                }
191
            }
192

193
            // prepare the error message
194
            $("#error-success h3").text(ERRORS['HEADER']);
195
            if (responseText !== undefined) {
196
                var errors = parse_error(responseText, status), details = '';
197
                if (serverName) {
198
                    serverName = "<p>{% trans "Server" %}: " + serverName + "</p>";
199
                }
200

201
                if ((errors[0].details === undefined) || (errors[0].details === "")) {
202
                    details = ERRORS["NO_DETAILS"];
203
                    
204
                    // if no details message show debug info
205
                    if (window.APP_DEBUG) {
206
                        details = responseText;
207
                        try {
208
                            console.trace();
209
                        } catch (err) {
210
                        }
211
                    }
212
                } else {
213
                    details = errors[0].details;
214
                }
215

216
                $("#error-success .machine-now-building").html(ERRORS["GENERIC_POPUP_HEADER"]);
217
                $("#error-success .popup-header").addClass("popup-header-error");
218
                $("#error-success").addClass("popup-border-error");
219
                $("#error-success .password-container").hide();
220
                $("#error-success .popup-details").addClass("popup-details-error");
221
                $("#error-success .popup-separator").addClass("popup-separator-error");
222
                $("#error-success .popup-details").html("<p>" + 
223
                    (errors[0].message || ERRORS[errors[0].code] || serverID) + 
224
                    "</p>" + serverName + "<p>{% trans "Action" %}:" + 
225
                    action + "</p><p>{% trans "Code" %}: " + errors[0].code + 
226
                    "<p><a class='expand-details' href='#'>{% trans 'Details' %}</a><div class='more-details'>" + 
227
                    details + "</div></p>");
228

229
            } else if (ERRORS[status] !== undefined) {
230
                if (serverID === undefined) {
231
                    //eg no_images, no_flavors cases
232
                    $("#error-success .machine-now-building").html(ERRORS["GENERIC_POPUP_HEADER"]);
233
                    $("#error-success .popup-header").addClass("popup-header-error");
234
                    $("#error-success").addClass("popup-border-error");
235
                    $("#error-success .password-container").hide();
236
                    $("#error-success .popup-details").addClass("popup-details-error");
237
                    $("#error-success .popup-separator").addClass("popup-separator-error");
238
                    $("#error-success .popup-details").html("<p>" + ERRORS[status] + "</p>");
239
                } else {
240
                    $("#error-success .machine-now-building").html(ERRORS["GENERIC_POPUP_HEADER"]);
241
                    $("#error-success .popup-header").addClass("popup-header-error");
242
                    $("#error-success").addClass("popup-border-error");
243
                    $("#error-success .password-container").hide();
244
                    $("#error-success .popup-details").addClass("popup-details-error");
245
                    $("#error-success .popup-separator").addClass("popup-separator-error");
246
                    $("#error-success .popup-details").html("<p>" + ERRORS[status] + "</p><p>" + serverName + "</p>");
247
                }
248
            } else {
249
                $("#error-success .machine-now-building").html(ERRORS["DEFAULT"]);
250
                $("#error-success .popup-header").addClass("popup-header-error");
251
                $("#error-success").addClass("popup-border-error");
252
                $("#error-success .password-container").hide();
253
                $("#error-success .popup-details").hide();
254
                $("#error-success .popup-separator").hide();
255
            }
256
            $("#error-success p:first").css("padding-bottom", "10px");
257
            $("#error-success p:first").css("color", "#800000");
258
            $("#error-success div.more-details").hide();
259
            $("#error-success a.expand-details").live('click', function () {
260
                $(this).parent().parent().find("div.more-details").slideToggle(600);
261
                return false;
262
            });
263
            //stop the progress icon and hide the wizard
264
            if (action !== undefined) {
265
                if (action === 'Create VM') {
266
                    $('#wizard #start').text('{% trans "Create VM" %}');
267
                    $("#wizard").hide();
268
                } else if (action === 'Create network') {
269
                    $('#networks-wizard').hide();
270
                } else if (action === 'Add server to network') {
271
                    $('#add-machines-wizard').hide();
272
                }
273
            }
274

275
            // bring up error notification
276
            var triggers = $("a#notification").overlay({
277
                // some mask tweaks suitable for modal dialogs
278
                mask: '#666',
279
                top: 'center',
280
                closeOnClick: false,
281
                oneInstance: false,
282
                load: false,
283
                onClose: function () {
284
                    // refresh the whole page
285
                    location.reload();
286
                }
287
            });
288

289
            // we need to give the browser some time to close the old overlays before opening the new one
290
            setTimeout("$('a#notification').data('overlay').load()",400);
291
            return false;
292
        }
293

294
        // ajax success checking
295
        function ajax_success(status, password) {
296
            // prepare the error message
297
            // bring up success notification
298
            $('#error-success').addClass('success');
299
            $('#error-success').removeClass('error');
300
            if (status !== undefined && SUCCESS[status]) {
301
                if (password !== undefined && status === "CREATE_VM_SUCCESS") {
302

303
                    //stop the progress icon and hide the wizard
304
                    $('#wizard #start').text('{% trans "Create VM" %}');
305
                    $("#wizard").hide();
306

307
                    $("#error-success h3 span.header-box").text(SUCCESS[status]);
308
                    var CREATE_VM_SUCCESS_MSG = SUCCESS["CREATE_VM_SUCCESS_THREE"] + '<br / >'
309
                        + SUCCESS["CREATE_VM_SUCCESS_FOUR"];
310
                    $("#error-success div.machine-now-building").html(SUCCESS["CREATE_VM_SUCCESS_ONE"]);
311
                    $("#error-success .popup-header").removeClass("popup-header-error");
312
                    $("#error-success").removeClass("popup-border-error");
313
                    $("#error-success .popup-details").removeClass("popup-details-error");
314
                    $("#error-success .popup-separator").removeClass("popup-separator-error");
315
                    $("#error-success .password-container").show();
316

317
                    $("#error-success .popup-details").html("</div><div class=\"write-password-details\">" + CREATE_VM_SUCCESS_MSG + "</div>");
318
                    $("#error-success div.password").html("<div class=\"write-password\">" + SUCCESS["CREATE_VM_SUCCESS_TWO"] + "<div class=\"write-password-password\">" + password + "</div></div>");
319
                    //$("#error-success div.write-password").html(SUCCESS["CREATE_VM_SUCCESS_TWO"]);
320
                    //$("#error-success div.write-password-details").html(CREATE_VM_SUCCESS_MSG);
321
                } else {
322
                    $("#error-success h3").text(SUCCESS['HEADER']);
323
                    $("#error-success div.popup-body-inner").text("<p>" + SUCCESS[status] + "</p>");
324
                }
325
            } else {
326
                $("#error-success h3").text(SUCCESS['HEADER']);
327
                $("#error-success div.popup-body-inner").html("<p>" + SUCCESS['DEFAULT'] + "</p>");
328
            }
329

330
            var triggers = $("a#notification").overlay({
331
                // some mask tweaks suitable for modal dialogs
332
                mask: '#666',
333
                top: 'center',
334
                closeOnClick: false,
335
                oneInstance: false,
336
                load: false,
337
                onClose: function () {
338
                    // With partial refresh working properly,
339
                    // it is no longer necessary to refresh the whole page
340
                    // choose_view();
341
                }
342
            });
343
            $("a#notification").data('overlay').load();
344
            return false;
345
        }
346
    </script>
347
</head>
348
<body>
349
    <div id="container">
350
        <div id='header'>
351
            <div id='user'>
352
                <div class="usermenu">
353
                    <div class="username">{{ request.user.uniq }}</div>
354
                    <ul class="useractions">
355
                        <li class="logout"><a class="action" href="#">{% trans "logout" %}</a></li>
356
                        <li class="invitations last"><a class="action" href="#">{% trans "Invitations" %}</a></li>
357
                    </ul>
358
                </div>
359
                <div class="langmenu">
360
                {% get_available_languages as LANGUAGES %}
361
                {% for lang in LANGUAGES %}
362
                    <a {% if  == lang.0 %}class="current_lang" {% else %}  href="/lang/?l={{lang.0}}" {% endif %}>{{lang.0}}</a>
363
                    {% if not forloop.last %}<span class="sep">~</span>{% endif %}
364
                    {% endfor %}
365
                </div>
366
            </div>
367
            <div class="header-logo">
368
                <a href="/">
369
                    <img src="static/okeanos.png" alt="okeanos"/>
370
                </a>
371
            </div>
372
        </div>
373
        <div id="content">
374
            <div id="wrapper">
375
                <!-- tabs -->
376
                <div class="tab-name">{% trans "machines" %}</div>
377
                <div class="tab-separator"></div>
378
                <ul class="css-tabs">
379
                    <li><a href="machines" title="{% trans "manage  virtual " %}" class="primary" id="machines">
380
                        <img src="static/machines-icon.png" /></a></li><div class="tab-separator"></div>
381
                    <li><a href="networks" title="{% trans "configure " %}" class="primary" id="networks">
382
                        <img src="static/networks-icon.png" /></a></li><div class="tab-separator"></div>
383
                    <li><a href="disks" title="{% trans "manage  storage " %}" class="primary" id="disks">
384
                        <img src="static/disks-icon.png" /></a></li>
385
                </ul>
386
                <div class="css-panes">
387
                    <div id="machines-pane" class="pane" style="display:block;"></div>
388
                    <div id="networks-pane" class="pane"></div>
389
                    <div id="disks-pane" class="pane"></div>
390
                </div>
391
            </div>
392
        </div>
393
        {% include "footer.html" %}
394
    </div>
395

    
396
    <!-- activate tabs with JavaScript -->
397
    <script>
398

399
        $(function() {
400
            // check pane cookie to select the initial pane
401
            var initial = 0, pane = $.cookie("pane");
402
            if (pane > 0)
403
                initial = pane;
404
            //alert(initial);
405
            $("ul.css-tabs").tabs("div.css-panes div.pane", {
406
                initialIndex: initial,
407
                onBeforeClick: function(event, i) {
408
                    this.getPanes().children().remove();
409
                    // get the pane to be opened
410
                    var pane = this.getPanes().eq(i);
411
                    //change the displaying title
412
                    $(".tab-name").text(this.getTabs().eq(i).attr("href"));
413
                    // load it with a page specified in the tab's href attribute
414
                    pane.load(this.getTabs().eq(i).attr("href"),function() {if (!i) {choose_view()}});
415
                }
416
            });
417
        });
418

419
        // set pane cookie whenever the user clicks on a different pane
420
        $("ul.css-tabs a").click(function(i) {
421
            $.cookie("pane", $("ul.css-tabs a").index(this));
422
        });
423

424
        //change menu title on hover
425
        $("ul.css-tabs li").hover(
426
            function () {
427
                if ($(this).find("a.current").length == 0) {
428
                    $(this).parent().parent().find(".tab-name").text($(this).find("a").attr("href"));
429
                }
430
            },
431
            function () {
432
                $(this).parent().parent().find(".tab-name").text($(this).parent().find("a.current").attr("href"));
433
            }
434
        );
435

436
        //load opera css fixes
437
        if ($.browser.opera) {
438
            $("<link/>", {
439
               rel: "stylesheet",
440
               type: "text/css",
441
               href: "static/opera.css"
442
            }).appendTo("head");
443
        }
444

445
        $(document).ready(function(){
446
            // user menu interaction
447
            var resetUserMenu = function() {
448
                $(this).removeClass("hovered");
449
                $(this).removeClass("active");
450
            }
451
            $(".usermenu").live("click", function(){
452
                $(this).addClass("active");
453
            });
454
            $(".usermenu").bind('mouseleave', resetUserMenu);
455
            $(".usermenu").live("mouseover", function(){
456
                $(this).addClass("hovered");
457
            });
458

459
            $(".usermenu li").mouseenter(function(){$(this).addClass("hovered")})
460
            $(".usermenu li").mouseleave(function(){$(this).removeClass("hovered")});
461

462
            // bind menu actions
463
            $(".usermenu .logout").click(function() {
464
                user_session_logout();
465
            });
466

467
            $(".usermenu .invitations").click(show_invitations);
468
            
469
        });
470
    </script>
471
    <!-- base notification for error/success reporting -->
472
    <a id="notification" rel="#error-success" href="#"></a>
473
    <a id="msgbox" rel="#notification-box" href="#"></a>
474

    
475
    <div class="modal" id="error-success">
476
        <h3 class="popup-header">
477
            <span class="header-box"></span>
478
        </h3>
479
        <div class="popup-body">
480
            <div class="popup-body-inner">
481
                <div class="machine-now-building"></div>
482
                <div class="popup-separator"></div>
483
                <div class="password-container">
484
                    <div class="password-header"></div>
485
                    <div class="password"></div>
486
                </div>
487
                <div class="popup-details">
488
                    <div class="write-password"></div>
489
                    <div class="write-password-details">{% trans "More details about the result"%}</div>
490
                </div>
491
            </div>
492
        </div>
493
    </div>
494

    
495
    <div class="modal" id="notification-box">
496
        <h3 class="popup-header">
497
            <span class="header-box"></span>
498
        </h3>
499
        <div class="popup-body">
500
            <div class="popup-body-inner">
501
                <div class="machine-now-building"></div>
502
                <div class="popup-separator"></div>
503
                <div class="password-container">
504
                    <div class="password"></div>
505
                </div>
506
                <div class="sub-text"></div>
507
            </div>
508
        </div>
509
    </div>
510
</body>
511
</html>