Statistics
| Branch: | Tag: | Revision:

root / ui / templates / home.html @ aff0be51

History | View | Annotate | Download (22.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
<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/synnefo.js"></script>
59
    <link rel="stylesheet" type="text/css" href="static/main.css"/>
60
    <!--[if IE]><style type="text/css" media="all">@import url(static/ie.css);</style><![endif]-->
61
    <script>
62
        // empty object for console to avoid errors in browsers that don't support it
63
        if (!window.console) {window.console = {}; window.console.log = window.console.info = window.console.debug =
64
            window.console.error = function() {}};
65

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

69
        // timeout value from settings.py
70
        var TIMEOUT = {{timeout}};
71
        var UPDATE_INTERVAL = {{update_interval}};
72
        var LOGOUT_REDIRECT = undefined;
73

74
        // server statuses and transitions
75
        var STATUSES = {
76
            'UNKNOWN'   : '{% trans "Unknown" %}',
77
            'BUILD'     : '{% trans "Building" %}',
78
            'REBOOT'    : '{% trans "Rebooting" %}',
79
            'STOPPED'   : '{% trans "Stopped" %}',
80
            'ACTIVE'    : '{% trans "Running" %}',
81
            'ERROR'     : '{% trans "Error" %}'
82
        };
83

84
        var TRANSITIONS = {
85
            'Shutting down' : '{% trans "Shutting down" %}',
86
            'Rebooting'     : '{% trans "Rebooting" %}',
87
            'Starting'      : '{% trans "Starting" %}',
88
            'Destroying'    : '{% trans "Destroying" %}',
89
            'Connecting'    : '{% trans "Connecting" %}',   // used only in networks
90
            'Disconnecting' : '{% trans "Disconnecting" %}' // used only in networks
91
        };
92

93
        // Server statuses and transitions that should be displayed as active or inactive
94
        var ACTIVE_STATES = [
95
            '{% trans "Building" %}',
96
            '{% trans "Rebooting" %}',
97
            '{% trans "Running" %}',
98
            '{% trans "Shutting down" %}',
99
            '{% trans "Rebooting" %}',
100
            '{% trans "Destroying" %}'
101
        ];
102

103
        var INACTIVE_STATES = [
104
            '{% trans "Unknown" %}',
105
            '{% trans "Stopped" %}',
106
            '{% trans "Error" %}',
107
            '{% trans "Starting" %}',
108
            '{% trans "Destroying" %}'
109
        ];
110

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

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

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

160
        var VARIOUS = {
161
            'CONFIRM' : '{% trans "Confirm" %}',
162
            'CANCEL' : '{% trans "Cancel" %}',
163
            'APPLY' : '{% trans "Apply" %}',
164
            'OFF' : '{% trans "Off" %}',
165
            'ON' : '{% trans "On" %}'
166
        };
167

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

175
            $('#error-success').addClass('error');
176
            $('#error-success').removeClass('success');
177

178
            var serverName = '';
179

180
            if (serverID !== undefined) {
181
                // standard view
182
                serverName = $("#" + serverID).find("span.name").text();
183
                if (serverName === "") { // list view
184
                    serverName = $("#" + serverID).parent().parent().find("span.name").text();
185
                }
186
            }
187

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

201
                $("#error-success .machine-now-building").html(ERRORS["GENERIC_POPUP_HEADER"]);
202
                $("#error-success .popup-header").addClass("popup-header-error");
203
                $("#error-success").addClass("popup-border-error");
204
                $("#error-success .password-container").hide();
205
                $("#error-success .popup-details").addClass("popup-details-error");
206
                $("#error-success .popup-separator").addClass("popup-separator-error");
207
                $("#error-success .popup-details").html("<p>" + (errors[0].message || ERRORS[errors[0].code]) + "</p>" + serverName + "<p>{% trans "Action" %}: " + action + "</p><p>{% trans "Code" %}: " + errors[0].code + "<p><a class='expand-details' href='#'>{% trans 'Details' %}</a><div class='more-details'>" + details + "</div></p>");
208
            } else if (ERRORS[status] !== undefined) {
209
                if (serverID === undefined) {
210
                    //eg no_images, no_flavors cases
211
                    $("#error-success .machine-now-building").html(ERRORS["GENERIC_POPUP_HEADER"]);
212
                    $("#error-success .popup-header").addClass("popup-header-error");
213
                    $("#error-success").addClass("popup-border-error");
214
                    $("#error-success .password-container").hide();
215
                    $("#error-success .popup-details").addClass("popup-details-error");
216
                    $("#error-success .popup-separator").addClass("popup-separator-error");
217
                    $("#error-success .popup-details").html("<p>" + ERRORS[status] + "</p>");
218
                } else {
219
                    $("#error-success .machine-now-building").html(ERRORS["GENERIC_POPUP_HEADER"]);
220
                    $("#error-success .popup-header").addClass("popup-header-error");
221
                    $("#error-success").addClass("popup-border-error");
222
                    $("#error-success .password-container").hide();
223
                    $("#error-success .popup-details").addClass("popup-details-error");
224
                    $("#error-success .popup-separator").addClass("popup-separator-error");
225
                    $("#error-success .popup-details").html("<p>" + ERRORS[status] + "</p><p>" + serverName + "</p>");
226
                }
227
            } else {
228
                $("#error-success .machine-now-building").html(ERRORS["DEFAULT"]);
229
                $("#error-success .popup-header").addClass("popup-header-error");
230
                $("#error-success").addClass("popup-border-error");
231
                $("#error-success .password-container").hide();
232
                $("#error-success .popup-details").hide();
233
                $("#error-success .popup-separator").hide();
234
            }
235
            $("#error-success p:first").css("padding-bottom", "10px");
236
            $("#error-success p:first").css("color", "#800000");
237
            $("#error-success div.more-details").hide();
238
            $("#error-success a.expand-details").live('click', function () {
239
                $(this).parent().parent().find("div.more-details").slideToggle(600);
240
                return false;
241
            });
242
            //stop the progress icon and hide the wizard
243
            if (action !== undefined) {
244
                if (action === 'Create VM') {
245
                    $('#wizard #start').text('{% trans "Create VM" %}');
246
                    $("#wizard").hide();
247
                } else if (action === 'Create network') {
248
                    $('#networks-wizard').hide();
249
                } else if (action === 'Add server to network') {
250
                    $('#add-machines-wizard').hide();
251
                }
252
            }
253

254
            // bring up error notification
255
            var triggers = $("a#notification").overlay({
256
                // some mask tweaks suitable for modal dialogs
257
                mask: '#666',
258
                top: 'center',
259
                closeOnClick: false,
260
                oneInstance: false,
261
                load: false,
262
                onClose: function () {
263
                    // refresh the whole page
264
                    location.reload();
265
                }
266
            });
267

268
            // we need to give the browser some time to close the old overlays before opening the new one
269
            setTimeout("$('a#notification').data('overlay').load()",400);
270
            return false;
271
        }
272

273
        // ajax success checking
274
        function ajax_success(status, password) {
275
            // prepare the error message
276
            // bring up success notification
277
            $('#error-success').addClass('success');
278
            $('#error-success').removeClass('error');
279
            if (status !== undefined && SUCCESS[status]) {
280
                if (password !== undefined && status === "CREATE_VM_SUCCESS") {
281

282
                    //stop the progress icon and hide the wizard
283
                    $('#wizard #start').text('{% trans "Create VM" %}');
284
                    $("#wizard").hide();
285

286
                    $("#error-success h3 span.header-box").text(SUCCESS[status]);
287
                    var CREATE_VM_SUCCESS_MSG = SUCCESS["CREATE_VM_SUCCESS_THREE"] + '<br / >'
288
                        + SUCCESS["CREATE_VM_SUCCESS_FOUR"];
289
                    $("#error-success div.machine-now-building").html(SUCCESS["CREATE_VM_SUCCESS_ONE"]);
290
                    $("#error-success .popup-header").removeClass("popup-header-error");
291
                    $("#error-success").removeClass("popup-border-error");
292
                    $("#error-success .popup-details").removeClass("popup-details-error");
293
                    $("#error-success .popup-separator").removeClass("popup-separator-error");
294
                    $("#error-success .password-container").show();
295

296
                    $("#error-success .popup-details").html("</div><div class=\"write-password-details\">" + CREATE_VM_SUCCESS_MSG + "</div>");
297
                    $("#error-success div.password").html("<div class=\"write-password\">" + SUCCESS["CREATE_VM_SUCCESS_TWO"] + "<div class=\"write-password-password\">" + password + "</div></div>");
298
                    //$("#error-success div.write-password").html(SUCCESS["CREATE_VM_SUCCESS_TWO"]);
299
                    //$("#error-success div.write-password-details").html(CREATE_VM_SUCCESS_MSG);
300
                } else {
301
                    $("#error-success h3").text(SUCCESS['HEADER']);
302
                    $("#error-success div.popup-body-inner").text("<p>" + SUCCESS[status] + "</p>");
303
                }
304
            } else {
305
                $("#error-success h3").text(SUCCESS['HEADER']);
306
                $("#error-success div.popup-body-inner").html("<p>" + SUCCESS['DEFAULT'] + "</p>");
307
            }
308

309
            var triggers = $("a#notification").overlay({
310
                // some mask tweaks suitable for modal dialogs
311
                mask: '#666',
312
                top: 'center',
313
                closeOnClick: false,
314
                oneInstance: false,
315
                load: false,
316
                onClose: function () {
317
                    // With partial refresh working properly,
318
                    // it is no longer necessary to refresh the whole page
319
                    // choose_view();
320
                }
321
            });
322
            $("a#notification").data('overlay').load();
323
            return false;
324
        }
325
    </script>
326
</head>
327
<body>
328
    <div id="container">
329
        <div id='header'>
330
            <div id='user'>
331
                <div class="usermenu">
332
                    <div class="username">{{ request.user.uniq }}</div>
333
                    <ul class="useractions">
334
                        <li class="logout last"><a class="action" href="#">{% trans "logout" %}</a></li>
335
                    </ul>
336
                </div>
337
                <div class="langmenu">
338
                {% get_available_languages as LANGUAGES %}
339
                {% for lang in LANGUAGES %}
340
                    <a {% if  == lang.0 %}class="current_lang" {% else %}  href="/lang/?l={{lang.0}}" {% endif %}>{{lang.0}}</a>
341
                    {% if not forloop.last %}<span class="sep">~</span>{% endif %}
342
                    {% endfor %}
343
                </div>
344
            </div>
345
            <div class="header-logo">
346
                <a href="/">
347
                    <img src="static/okeanos.png" alt="okeanos"/>
348
                </a>
349
            </div>
350
        </div>
351
        <div id="content">
352
            <div id="wrapper">
353
                <!-- tabs -->
354
                <div class="tab-name">{% trans "machines" %}</div>
355
                <div class="tab-separator"></div>
356
                <ul class="css-tabs">
357
                    <li><a href="machines" title="{% trans "manage  virtual " %}" class="primary" id="machines">
358
                        <img src="static/machines-icon.png" /></a></li><div class="tab-separator"></div>
359
                    <li><a href="networks" title="{% trans "configure " %}" class="primary" id="networks">
360
                        <img src="static/networks-icon.png" /></a></li><div class="tab-separator"></div>
361
                    <li><a href="disks" title="{% trans "manage  storage " %}" class="primary" id="disks">
362
                        <img src="static/disks-icon.png" /></a></li>
363
                </ul>
364
                <div class="css-panes">
365
                    <div id="machines-pane" class="pane" style="display:block;"></div>
366
                    <div id="networks-pane" class="pane"></div>
367
                    <div id="disks-pane" class="pane"></div>
368
                </div>
369
            </div>
370
        </div>
371
        {% include "footer.html" %}
372
    </div>
373

    
374
    <!-- activate tabs with JavaScript -->
375
    <script>
376

377
        $(function() {
378
            // check pane cookie to select the initial pane
379
            var initial = 0, pane = $.cookie("pane");
380
            if (pane > 0)
381
                initial = pane;
382
            //alert(initial);
383
            $("ul.css-tabs").tabs("div.css-panes div.pane", {
384
                initialIndex: initial,
385
                onBeforeClick: function(event, i) {
386
                    this.getPanes().children().remove();
387
                    // get the pane to be opened
388
                    var pane = this.getPanes().eq(i);
389
                    //change the displaying title
390
                    $(".tab-name").text(this.getTabs().eq(i).attr("href"));
391
                    // load it with a page specified in the tab's href attribute
392
                    pane.load(this.getTabs().eq(i).attr("href"),function() {if (!i) {choose_view()}});
393
                }
394
            });
395
        });
396

397
        // set pane cookie whenever the user clicks on a different pane
398
        $("ul.css-tabs a").click(function(i) {
399
            $.cookie("pane", $("ul.css-tabs a").index(this));
400
        });
401

402
        //change menu title on hover
403
        $("ul.css-tabs li").hover(
404
            function () {
405
                if ($(this).find("a.current").length == 0) {
406
                    $(this).parent().parent().find(".tab-name").text($(this).find("a").attr("href"));
407
                }
408
            },
409
            function () {
410
                $(this).parent().parent().find(".tab-name").text($(this).parent().find("a.current").attr("href"));
411
            }
412
        );
413

414
        //load opera css fixes
415
        if ($.browser.opera) {
416
            $("<link/>", {
417
               rel: "stylesheet",
418
               type: "text/css",
419
               href: "static/opera.css"
420
            }).appendTo("head");
421
        }
422

423
        // user menu interaction
424
        $(document).ready(function(){
425
            var resetUserMenu = function() {
426
                $(this).removeClass("hovered");
427
                $(this).removeClass("active");
428
            }
429
            $(".usermenu").live("click", function(){
430
                $(this).addClass("active");
431
            });
432
            $(".usermenu").bind('mouseleave', resetUserMenu);
433
            $(".usermenu").live("mouseover", function(){
434
                $(this).addClass("hovered");
435
            });
436

437
            $(".usermenu li").mouseenter(function(){$(this).addClass("hovered")})
438
            $(".usermenu li").mouseleave(function(){$(this).removeClass("hovered")});
439

440
            // bind menu actions
441
            $(".usermenu .logout").click(function() {
442
                user_session_logout();
443
            });
444

445
        });
446
    </script>
447
    <!-- base notification for error/success reporting -->
448
    <a id="notification" rel="#error-success" href="#"></a>
449
    <a id="msgbox" rel="#notification-box" href="#"></a>
450

    
451
    <div class="modal" id="error-success">
452
        <h3 class="popup-header">
453
            <span class="header-box"></span>
454
        </h3>
455
        <div class="popup-body">
456
            <div class="popup-body-inner">
457
                <div class="machine-now-building"></div>
458
                <div class="popup-separator"></div>
459
                <div class="password-container">
460
                    <div class="password-header"></div>
461
                    <div class="password"></div>
462
                </div>
463
                <div class="popup-details">
464
                    <div class="write-password"></div>
465
                    <div class="write-password-details">{% trans "More details about the result"%}</div>
466
                </div>
467
            </div>
468
        </div>
469
    </div>
470

    
471
    <div class="modal" id="notification-box">
472
        <h3 class="popup-header">
473
            <span class="header-box"></span>
474
        </h3>
475
        <div class="popup-body">
476
            <div class="popup-body-inner">
477
                <div class="machine-now-building"></div>
478
                <div class="popup-separator"></div>
479
                <div class="password-container">
480
                    <div class="password-header"></div>
481
                    <div class="password"></div>
482
                </div>
483
            </div>
484
        </div>
485
    </div>
486
</body>
487
</html>