Statistics
| Branch: | Tag: | Revision:

root / ui / templates / home.html @ 2641e76c

History | View | Annotate | Download (23.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
<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
        ];
114

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

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

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

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

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

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

182
            var serverName = '';
183

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

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

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

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

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

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

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

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

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

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

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

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

    
398
    <!-- activate tabs with JavaScript -->
399
    <script>
400

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

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

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

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

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

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

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

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

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

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