Revision 8afc06d1

b/astakos/im/static/im/cloudbar/README.rst
1
Cloudbar
2
========
3

  
4
Cloudbar is a project to provide common navigation user experience
5
between services that share common authentication mechanism and user
6
entries but get deployed on different domains and may not share
7
common frontend themes/templates.
8

  
9
The project consists of a javascript file which once imported in a
10
html page handles the automatic creation and styling of a bar that
11
is placed on top of the page (first body element absolutely
12
positioned on top). Since the addition of the bar may break the
13
current layout of the site once imported the script tries to load an
14
additional css located in the same url as the script itself named by
15
the ``CLOUDBAR_ACTIVE_SERVICE`` configuration and prefixed by *service_* so 
16
that css changes can be applied without touching the page native styles.
17

  
18
The bar contains links to the refered services application urls, and
19
depending on if the user is authenticated links to account pages
20
(login, change profile, logout etc.).
21

  
22
To identify if a user is authenticated the script checks of a
23
specific cookie which can be configured using ``CLOUDBAR_COOKIE_NAME`` setting
24
contains valid data which should match the following format::
25
    
26
    <username or email>|<authentication token>
27

  
28

  
29
Usage
30
-----
31

  
32
Each page that wants to display the navigation bar should:
33

  
34
    - Include one of the latest jquery builds.
35
    - Set the ``CLOUDBAR_COOKIE_NAME`` variable containing info about the username
36
      and the authentication status of the current visitor of the page.
37
    - Set the ``CLOUDBAR_ACTIVE_SERVICE`` to the id of the service the current
38
      page refers to so that script cat set the appropriate active styles to
39
      the services menu for services ids see ``SERVICES_LINK``
40
      object in cloudbar.js.
41
    - Set the ``CLOUDBAR_LOCATION`` to the url where bar files are served from.
42
    - Include the servicesbar.js script.
43

  
44

  
45
Example
46
*******
47

  
48
.. codeblock:: javascript
49
    
50
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
51
    <script>
52
        var CLOUDBAR_COOKIE_NAME = '_pithos2_a';
53
        var CLOUDBAR_ACTIVE_SERVICE = 'cloud';
54
        var CLOUDBAR_LOCATION = "http://accounts.cloud.grnet.gr/cloudbar/";
55

  
56
        $(document).ready(function(){
57
            $.getScript(CLOUDBAR_LOC + 'cloudbar.js');
58
        })
59
    </script>
60

  
61

  
62
Build styles
63
------------
64

  
65
Cloudbar uses `less-css <http://www.lesscss.org>`_ for css styles
66
definitions. To build the less file you need the bootstrap less files
67
available on 
68
`bootstrap github repository <https://github.com/twitter/bootstrap/>`.
69

  
70
You can build the styles using the following command::
71

  
72
    $ lessc --include-path=<path/to/bootstrap> cloudbar.less > cloudbar.css
73

  
b/astakos/im/static/im/cloudbar/cloudbar.css
1
/*!
2
 * Bootstrap @VERSION
3
 *
4
 * Copyright 2011 Twitter, Inc
5
 * Licensed under the Apache License v2.0
6
 * http://www.apache.org/licenses/LICENSE-2.0
7
 *
8
 * Designed and built with all the love in the world @twitter by @mdo and @fat.
9
 * Date: @DATE
10
 */
11
/* Variables.less
12
 * Variables to customize the look and feel of Bootstrap
13
 * ----------------------------------------------------- */
14
/* Mixins.less
15
 * Snippets of reusable CSS to develop faster and keep code readable
16
 * ----------------------------------------------------------------- */
17
.servicesbar {
18
  font-family: arial, sans-serif;
19
  font-size: 13px !important;
20
  line-height: 13px;
21
  letter-spacing: 0px;
22
  zoom: 1;
23
  color: #ccc;
24
  z-index: 1000;
25
  border-bottom: 1px solid #444;
26
  background-color: #000000;
27
  position: relative;
28
}
29
.servicesbar ol, .servicesbar ul {
30
  list-style: none;
31
  margin: 0;
32
  padding: 0;
33
}
34
.servicesbar li {
35
  margin: 0;
36
  padding: 0;
37
}
38
.servicesbar:before, .servicesbar:after {
39
  display: table;
40
  content: "";
41
  zoom: 1;
42
}
43
.servicesbar:after {
44
  clear: both;
45
}
46
.servicesbar a {
47
  border: none !important;
48
  font-size: inherit !important;
49
  color: #e6e6e6;
50
  text-decoration: none;
51
  display: block;
52
  float: left;
53
  padding: 11px;
54
  height: 13px;
55
}
56
.servicesbar a:hover {
57
  background-color: #444;
58
}
59
.servicesbar a.active {
60
  font-weight: bold;
61
  background-color: #333;
62
}
63
.servicesbar .services {
64
  zoom: 1;
65
}
66
.servicesbar .services:before, .servicesbar .services:after {
67
  display: table;
68
  content: "";
69
  zoom: 1;
70
}
71
.servicesbar .services:after {
72
  clear: both;
73
}
74
.servicesbar .profile {
75
  margin-top: -35px;
76
  zoom: 1;
77
  text-align: right;
78
  min-width: 200px;
79
  background-color: #000000;
80
  zoom: 1;
81
  position: absolute;
82
  right: 0;
83
  float: right;
84
}
85
.servicesbar .profile:before, .servicesbar .profile:after {
86
  display: table;
87
  content: "";
88
  zoom: 1;
89
}
90
.servicesbar .profile:after {
91
  clear: both;
92
}
93
.servicesbar .profile a {
94
  float: none;
95
}
96
.servicesbar .profile ul {
97
  display: none;
98
}
99
.servicesbar .profile ul li {
100
  width: 100%;
101
  border-bottom: 1px solid #444;
102
  background-color: #333;
103
}
104
.servicesbar .profile ul li a {
105
  float: none;
106
  display: block;
107
}
108
.servicesbar .profile:hover {
109
  background-color: #222;
110
}
111
.servicesbar .profile:hover ul {
112
  display: block;
113
}
114
.servicesbar .profile:before, .servicesbar .profile:after {
115
  display: table;
116
  content: "";
117
  zoom: 1;
118
}
119
.servicesbar .profile:after {
120
  clear: both;
121
}
b/astakos/im/static/im/cloudbar/cloudbar.js
1
$(document).ready(function(){
2
    
3
    /*
4
    * LINKS CONFIGURATION
5
    */
6

  
7
    var PROFILE_URL = "https://accounts.cloud.grnet.gr";
8
    var SERVICES_LINKS = window.CLOUDBAR_SERVICES_LINKS || {
9
        'cloud':   { url:'http://pithos.dev.grnet.gr/im/', name:'grnet cloud', id:'cloud', icon:'home-icon.png' },
10
        'okeanos': { url:'http://staging.okeanos.grnet.gr/ui/', name:'~okeanos', id:'okeanos' },
11
        'pithos':  { url:'http://pithos.dev.grnet.gr/ui/', name:'pithos+', id:'pithos' }
12
    };
13
    
14
    var PROFILE_LINKS = window.CLOUDBAR_PROFILE_LINKS || {
15
        'login': { url: '/im/login?next=' + window.location.toString(), auth:false, name: "login...", visible:false },
16
        'profile': { url: '/im/profile', auth:true, name: "change your profile..." },
17
        'invitations': { url: '/im/invite', auth:true, name: "invite some friends..." },
18
        'feedback': { url: '/im/feedback', auth:true, name: "feedback..." },
19
        'logout': { url: '/im/logout', auth:true, name: "logout..." }
20
    };
21

  
22

  
23
    // cookie plugin https://raw.github.com/carhartl/jquery-cookie/master/jquery.cookie.js 
24
    //  * Copyright (c) 2010 Klaus Hartl, @carhartl
25
    //  * Dual licensed under the MIT and GPL licenses
26
    var cookie=function(key,value,options){if(arguments.length>1&&(!/Object/.test(Object.prototype.toString.call(value))||value===null||value===undefined)){options=$.extend({},options);if(value===null||value===undefined){options.expires=-1}if(typeof options.expires==='number'){var days=options.expires,t=options.expires=new Date();t.setDate(t.getDate()+days)}value=String(value);return(document.cookie=[encodeURIComponent(key),'=',options.raw?value:encodeURIComponent(value),options.expires?'; expires='+options.expires.toUTCString():'',options.path?'; path='+options.path:'',options.domain?'; domain='+options.domain:'',options.secure?'; secure':''].join(''))}options=value||{};var decode=options.raw?function(s){return s}:decodeURIComponent;var pairs=document.cookie.split('; ');for(var i=0,pair;pair=pairs[i]&&pairs[i].split('=');i++){if(decode(pair[0])===key)return decode(pair[1]||'')}return null};
27

  
28
    var ACTIVE_MENU = window.CLOUDBAR_ACTIVE_SERVICE || 'cloud';
29
    var USER_DATA = window.CLOUDBAR_USER_DATA || {'user': 'Not logged in', 'logged_in': false};
30
    var COOKIE_NAME = window.CLOUDBAR_COOKIE_NAME || '_pithos2_a';
31

  
32
    var cssloc = window.CLOUDBAR_LOCATION || "http://127.0.0.1:8989/";
33
    
34
    // load css
35
    var css = $("<link />");
36
    css.attr({rel:'stylesheet', type:'text/css', href:cssloc + 'cloudbar.css'});
37
    $("head").append(css);
38

  
39
    // load service specific css
40
    var SKIP_ADDITIONAL_CSS = window.SKIP_ADDITIONAL_CSS == undefined ? false : window.SKIP_ADDITIONAL_CSS;
41

  
42
    if (!SKIP_ADDITIONAL_CSS) {
43
        var css = $("<link />");
44
        css.attr({rel:'stylesheet', type:'text/css', href:cssloc + 'service_' + ACTIVE_MENU + '.css'});
45
        $("head").append(css);
46
    }
47

  
48
    var root = $('body');
49
    var bar = $('<div class="servicesbar"></div>');
50
    var services = $('<div class="services"></div>');
51
    var profile = $('<div class="profile"></div>');
52
    
53
    
54
    // create services links and set the active class to the current service
55
    $.each(SERVICES_LINKS, function(i, el){
56
        var slink = $("<a>");
57
        if (el.icon) {
58
            slink.append($('<img src="'+cssloc+el.icon+'"/>'));
59
        } else {
60
            slink.text(el.name);
61
        }
62
        slink.attr('href', el.url);
63
        slink.attr('title', el.name);
64
        services.append(slink);
65
        if (el.id == ACTIVE_MENU) {
66
            slink.addClass("active");
67
        }
68
    });
69

  
70
    var USERNAME, LOGGED_IN;
71
    var authcookie = cookie(COOKIE_NAME);
72
    var anonymous = {'user': 'Login...', 'logged_in': false};
73

  
74
    if (authcookie && authcookie.indexOf("|") > -1) {
75
        USER_DATA.logged_in = true;
76
        USER_DATA.user = authcookie.split("|")[0];
77
    } else {
78
        USER_DATA = anonymous;
79
    }
80

  
81
    USERNAME = USER_DATA.user;
82
    LOGGED_IN = USER_DATA.logged_in;
83

  
84
    // clear username
85
    USERNAME = USERNAME.replace(/\\'/g,'');
86
    USERNAME = USERNAME.replace(/\"/g,'');
87

  
88
    var user = $('<div class="user"></div>');
89
    var username = $('<a href="#"></a>');
90
    username.text(USERNAME);
91
    
92
    // create profile links
93
    var usermenu = $("<ul>");
94
    $.each(PROFILE_LINKS, function(i,el) {
95
        if (!LOGGED_IN && el.auth) { return }
96
        if (LOGGED_IN && !el.auth) { return }
97
        var li = $("<li />");
98
        var link = $("<a />");
99
        link.text(el.name);
100
        link.attr({href:el.url});
101
        li.append(link);
102
        if (el.visible == false) {
103
            li.hide();
104
        }
105
        usermenu.append(li);
106
    });
107

  
108
    //profile.filter(".user a").attr("href", 
109
                                   //profile.find("li a").get(0).attr("href"))
110
    
111

  
112
    
113
    user.append(username);
114
    user.append(usermenu);
115
    profile.append(user);
116
    bar.append(services).append(profile);
117
    
118

  
119
    root.prepend(bar);
120
    var firstlink = profile.find("ul li:first-child a").attr("href");
121
    profile.find(".user > a").attr("href", firstlink);
122
});
b/astakos/im/static/im/cloudbar/cloudbar.less
1
@import "less/bootstrap.less";
2

  
3
@toolbarBg: #222;
4
@toolbarColor: darken(@white, 10%);
5
@toolbarHeight: 30px;
6

  
7
.servicesbar {
8

  
9
    // mini reset
10
    ol, ul { list-style:none; margin:0; padding:0;}
11
    li {margin:0; padding:0;}
12
    font-family: arial, sans-serif;
13
    font-size: 13px !important;
14
    line-height: 13px;
15
    letter-spacing: 0px;
16
    .clearfix();
17
    color: #ccc;
18
    z-index: 1000;
19
    border-bottom: 1px solid #444;
20

  
21
    background-color: darken(@toolbarBg, 40%);
22

  
23
    a {
24
        border: none !important;
25
        font-size: inherit !important;
26
        color: @toolbarColor;    
27
        text-decoration: none;
28
        display: block;
29
        float: left;
30
        padding: 11px;
31
        height: 13px;
32
        &:hover {
33
            background-color: #444;
34
        }
35
        &.active {
36
            font-weight: bold;
37
            background-color: #333;
38
        }
39
    }
40

  
41
    .services {
42
        .clearfix();
43
    }    
44

  
45
    position: relative;
46

  
47
    .profile {
48
        margin-top: -35px;
49
        .clearfix();
50
        text-align: right;
51
        min-width: 200px;
52
        a {
53
                    float: none;
54
        }
55
        ul {
56
            display: none;    
57
            li {
58
                width: 100%;
59
                border-bottom: 1px solid #444;
60
                background-color: #333;
61
                a {
62
                    float: none;
63
                    display: block;
64
                }
65
            }
66
        }
67
        &:hover {
68
            background-color: #222;
69
            ul {
70
                display: block;    
71
            }
72
        }
73
        background-color: @black;
74
        .clearfix();
75
        position: absolute;
76
        right: 0;
77
        float: right;    
78
    }
79
}
b/astakos/im/static/im/cloudbar/service_okeanos.css
1
body {
2
    background-color: #4085A5;
3
    background-position: 20px 34px;
4
}
b/astakos/im/static/im/cloudbar/service_pithos.css
1
.gwt-HTML.pithos-logo {
2
    top: 65px !important;
3
}
4

  
5
.pithos-usernameMenu  {
6
    display: none;
7
}

Also available in: Unified diff