Statistics
| Branch: | Tag: | Revision:

root / ui / templates / home.html @ 2b837adf

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

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

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

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

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

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

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

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

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

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

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

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

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

177
            var serverName = '';
178

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

439
            // bind menu actions
440
            $(".usermenu .logout").click(function() {
441
                user_session_logout();
442
            });
443
        });
444
    </script>
445
    <!-- base notification for error/success reporting -->
446
    <a id="notification" rel="#error-success" href="#"></a>
447

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