From: Jordan Augé Date: Fri, 25 Oct 2013 16:01:54 +0000 (+0200) Subject: Merge branch 'master' of ssh://git.onelab.eu/git/myslice X-Git-Tag: 0.2-6~6^2 X-Git-Url: http://git.onelab.eu/?p=myslice.git;a=commitdiff_plain;h=0c8a634162f3271018102e75a3934c5db5e48f59;hp=491bd4d5497b5c431ab35716425f4c95fd2c3696 Merge branch 'master' of ssh://git.onelab.eu/git/myslice --- diff --git a/apache/myslice.conf b/apache/myslice.conf index 9e8a1551..b7824520 100644 --- a/apache/myslice.conf +++ b/apache/myslice.conf @@ -1,7 +1,7 @@ - WSGIScriptAlias / /usr/share/unfold/apache/myslice.wsgi - - + WSGIScriptAlias / /usr/share/unfold/myslice/wsgi.py + + Order deny,allow Allow from all diff --git a/debian/unfold.install b/debian/unfold.install index 4f3996ed..a86e983a 100644 --- a/debian/unfold.install +++ b/debian/unfold.install @@ -12,4 +12,3 @@ usr/share/unfold/trash usr/share/unfold/debug_platform manage.py usr/share/unfold/ apache/myslice.conf /etc/apache2/sites-available -apache/myslice.wsgi usr/share/unfold/apache diff --git a/manifold/manifoldapi.py b/manifold/manifoldapi.py index 042e127e..35fd3d74 100644 --- a/manifold/manifoldapi.py +++ b/manifold/manifoldapi.py @@ -20,13 +20,13 @@ class ManifoldAPI: def __init__(self, auth=None, cainfo=None): - config = Config() self.auth = auth self.cainfo = cainfo self.errors = [] self.trace = [] self.calls = {} self.multicall = False + config = Config() self.url = config.manifold_url() self.server = xmlrpclib.Server(self.url, verbose=False, allow_none=True) diff --git a/manifold/static/js/manifold.js b/manifold/static/js/manifold.js index c4d0ef73..11fad7da 100644 --- a/manifold/static/js/manifold.js +++ b/manifold/static/js/manifold.js @@ -738,7 +738,7 @@ var manifold = { expires: false, speed: 1000 }); -*/ +*/ } if (manifold.asynchroneous_debug) messages.debug ("========== asynchroneous_success " + query.object + " -- before process_query_records"); diff --git a/myslice/config.py b/myslice/config.py index 31dc7e31..53295c4a 100644 --- a/myslice/config.py +++ b/myslice/config.py @@ -2,15 +2,19 @@ import os.path from ConfigParser import RawConfigParser from myslice.settings import ROOT -# myslice/myslice.ini -# as this code suggests, you have the option to write myslice/myslice.ini +# as this code suggests, you have the option to override these defaults +# by writing a file myslice/myslice.ini # that looks like this #[manifold] #url = http://manifold.pl.sophia.inria.fr:7080/ #admin_user = admin #admin_password = admin -class Config: +# use a singleton instead of staticmethods +from manifold.util.singleton import Singleton + +class Config(object): + __metaclass__ = Singleton # the OpenLab-wide backend as managed by UPMC # xxx production should probably use https of course @@ -20,40 +24,25 @@ class Config: # the INRIA setup is with "http://manifold.pl.sophia.inria.fr:7080/" default_manifold_admin_user = 'admin' - default_manifold_admin_password = None - - _config_parser = None - - # having grown tired of screwing up with git stashes - # taking away my local config, we now more properly use - # an external config file to override teh default - # XXX we might use support from manifold util classes --jordan - @staticmethod - def manifold_url (): - if Config._config_parser: - return Config._config_parser.get('manifold','url') - config = RawConfigParser () - config.add_section('manifold') - config.set ('manifold', 'url', Config.default_manifold_url) - config.read (os.path.join(ROOT,'myslice/myslice.ini')) - Config._config_parser=config - return Config.manifold_url() - - @staticmethod - def manifold_admin_user_password(): - if Config._config_parser: - admin_user = Config._config_parser.get('manifold','admin_user') - admin_password = Config._config_parser.get('manifold','admin_password') - return (admin_user, admin_password) - config = RawConfigParser () - config.add_section('manifold') - config.set ('manifold', 'admin_user', Config.default_manifold_admin_user) - config.set ('manifold', 'admin_password', Config.default_manifold_admin_password) - config.read (os.path.join(ROOT,'myslice/myslice.ini')) - Config._config_parser=config - return Config.manifold_admin_user_password() + default_manifold_admin_password = 'demo' + + + def __init__ (self): + parser = RawConfigParser () + parser.add_section('manifold') + parser.set ('manifold', 'url', Config.default_manifold_url) + parser.set ('manifold', 'admin_user', Config.default_manifold_admin_user) + parser.set ('manifold', 'admin_password', Config.default_manifold_admin_password) + parser.read (os.path.join(ROOT,'myslice/myslice.ini')) + self.config_parser=parser + + def manifold_url (self): + return self.config_parser.get('manifold','url') + + def manifold_admin_user_password(self): + return (self.config_parser.get('manifold','admin_user'), + self.config_parser.get('manifold','admin_password')) # exporting these details to js - @staticmethod - def manifold_js_export (): - return "var MANIFOLD_URL = '%s';\n"%Config.manifold_url(); + def manifold_js_export (self): + return "var MANIFOLD_URL = '%s';\n"%self.manifold_url(); diff --git a/myslice/myslice.ini b/myslice/myslice.ini.localhost similarity index 100% rename from myslice/myslice.ini rename to myslice/myslice.ini.localhost diff --git a/apache/myslice.wsgi b/myslice/wsgi.py similarity index 100% rename from apache/myslice.wsgi rename to myslice/wsgi.py diff --git a/plugins/hazelnut/static/js/hazelnut.js b/plugins/hazelnut/static/js/hazelnut.js index 21b23f5b..dcd4e1ff 100644 --- a/plugins/hazelnut/static/js/hazelnut.js +++ b/plugins/hazelnut/static/js/hazelnut.js @@ -272,6 +272,7 @@ on_filter_added: function(filter) { // XXX + console.log(filter); this.redraw_table(); }, diff --git a/plugins/slicestat/__init__.py b/plugins/slicestat/__init__.py index 14cfdad8..dadebd01 100644 --- a/plugins/slicestat/__init__.py +++ b/plugins/slicestat/__init__.py @@ -1,6 +1,6 @@ from unfold.plugin import Plugin -class Slicestat(Plugin): +class SliceStat(Plugin): def __init__ (self, query, **settings): Plugin.__init__ (self, **settings) @@ -12,8 +12,9 @@ class Slicestat(Plugin): def requirements (self): reqs = { 'js_files' : [ - 'js/date.js', - 'js/slicestat.js' + + 'js/slicestat.js', + ], 'css_files': [ 'css/slicestat.css', diff --git a/plugins/slicestat/static/css/slicestat.css b/plugins/slicestat/static/css/slicestat.css index e69de29b..9962c83b 100644 --- a/plugins/slicestat/static/css/slicestat.css +++ b/plugins/slicestat/static/css/slicestat.css @@ -0,0 +1,6 @@ +iframe#slicestat_resource { + width:100%; + height:400px; + border:0; + overflow: hidden; +} diff --git a/plugins/slicestat/static/js/slicestat.js b/plugins/slicestat/static/js/slicestat.js index 4c63b849..a815e7f6 100644 --- a/plugins/slicestat/static/js/slicestat.js +++ b/plugins/slicestat/static/js/slicestat.js @@ -13,7 +13,7 @@ (function($){ - var Slicestat = Plugin.extend({ + var SliceStat = Plugin.extend({ /** XXX to check * @brief Plugin constructor @@ -24,10 +24,7 @@ */ init: function(options, element) { // Call the parent constructor, see FAQ when forgotten - this._super(options, element); - - google.load("visualization", "1.0", {packages:["corechart"]}); - + this._super(options, element); /* Member variables */ @@ -93,52 +90,8 @@ { console.log(record); - var node = record.hostname; - var slice = 'root'; - - google.setOnLoadCallback(function() { - - var options = { - pointSize: 2, - lineWidth: 1, - title: 'Slice '+slice+' last 24 hours', 'width':780, 'height':400, - vAxes: { - 0: {format: '###,##%'}, - 1: {format: '#Kb',} - }, - hAxis: { title: "", format: 'HH:mm'}, - series: { - 0: { type: "line", targetAxisIndex: 0}, - 1: { type: "line", targetAxisIndex: 0}, - 2: { type: "line", targetAxisIndex: 1}, - 3: { type: "line", targetAxisIndex: 1} - } - }; - - var jsonData = $.ajax({ - type: 'POST', - url: "/db/slice", - dataType: "json", - async: false, - data: { period: 'day', resources: 'cpu,pmc_per,asb,arb', slice: slice, node: node }, - success: function(ret) { - var result = []; - var data = new google.visualization.DataTable(); - data.addColumn('datetime', 'Date'); - data.addColumn('number', 'CPU (%)'); - data.addColumn('number', 'MEM (%)'); - data.addColumn('number', 'Traffic Sent (Kb)'); - data.addColumn('number', 'Traffic Received (Kb)'); - $.each(ret, function() { - result.push([new Date(this[0]), this[1], this[2], this[3], this[4]]); - }); - data.addRows(result); - var chart = new google.visualization.LineChart(document.getElementById('graph')); - chart.draw(data, options); - } - }).responseText; - - }); + $('iframe#slicestat_resource').attr('src','http://plestats.planet-lab.eu/node.php?node='+record.hostname); + }, /* INTERNAL FUNCTIONS */ @@ -149,7 +102,7 @@ }); /* Plugin registration */ - $.plugin('Slicestat', Slicestat); + $.plugin('SliceStat', SliceStat); // TODO Here use cases for instanciating plugins in different ways like in the pastie. diff --git a/plugins/slicestat/templates/slicestat.html b/plugins/slicestat/templates/slicestat.html index cb9474c8..c97cd9e0 100644 --- a/plugins/slicestat/templates/slicestat.html +++ b/plugins/slicestat/templates/slicestat.html @@ -1,4 +1,3 @@
-

Slicestat

-
+
diff --git a/portal/contactview.py b/portal/contactview.py index 0f2e4010..c07f3977 100644 --- a/portal/contactview.py +++ b/portal/contactview.py @@ -40,6 +40,6 @@ class ContactView (View): def _display (self, request, form): return render(request, 'contact.html', { 'form': form, - 'topmenu_items': topmenu_items('Contact Us', request), + 'topmenu_items': topmenu_items('Contact', request), 'username': the_user (request) }) diff --git a/portal/homeview.py b/portal/homeview.py index b9d039a5..960c8f0d 100644 --- a/portal/homeview.py +++ b/portal/homeview.py @@ -14,8 +14,9 @@ class HomeView (View): # expose this so we can mention the backend URL on the welcome page def default_env (self): + config=Config() return { - 'MANIFOLD_URL':Config.manifold_url(), + 'MANIFOLD_URL':config.manifold_url(), } def post (self,request): @@ -56,7 +57,7 @@ class HomeView (View): def get (self, request, state=None): env = self.default_env() env['username']=the_user(request) - env['topmenu_items'] = topmenu_items('', request) + env['topmenu_items'] = topmenu_items(None, request) if state: env['state'] = state elif not env['username']: env['state'] = "Please sign in" return render_to_response('home-view.html',env, context_instance=RequestContext(request)) diff --git a/portal/resourceview.py b/portal/resourceview.py index 04218540..0ba8a26c 100644 --- a/portal/resourceview.py +++ b/portal/resourceview.py @@ -8,7 +8,7 @@ from ui.topmenu import topmenu_items, the_user from plugins.googlemap import GoogleMap from plugins.hazelnut import Hazelnut from plugins.lists.simplelist import SimpleList -from plugins.slicestat import Slicestat +from plugins.slicestat import SliceStat # View for 1 platform and its details class ResourceView(TemplateView): @@ -16,6 +16,8 @@ class ResourceView(TemplateView): def get_context_data(self, **kwargs): page = Page(self.request) + + page.add_js_files ( [ "js/common.functions.js" ] ) for key, value in kwargs.iteritems(): print "%s = %s" % (key, value) @@ -64,9 +66,10 @@ class ResourceView(TemplateView): # query = resource_query, # ) - resource_stats = Slicestat( + resource_stats = SliceStat( title = None, page = page, + stats = 'node', key = 'hrn', query = resource_query ) @@ -81,7 +84,7 @@ class ResourceView(TemplateView): # more general variables expected in the template context['title'] = 'Information about a resource' # the menu items on the top - context['topmenu_items'] = topmenu_items('Dashboard', self.request) + context['topmenu_items'] = topmenu_items(None, self.request) # so we can sho who is logged context['username'] = the_user(self.request) diff --git a/portal/sliceview.py b/portal/sliceview.py index 9d335f49..15a5e51a 100644 --- a/portal/sliceview.py +++ b/portal/sliceview.py @@ -26,7 +26,8 @@ from myslice.config import Config tmp_default_slice='ple.upmc.myslicedemo' # temporary : turn off the users part to speed things up -do_query_users=True +#do_query_users=True +do_query_users=False class SliceView (LoginRequiredAutoLogoutView): @@ -37,7 +38,8 @@ class SliceView (LoginRequiredAutoLogoutView): page.add_js_files ( [ "js/common.functions.js" ] ) page.add_js_chunks ('$(function() { messages.debug("sliceview: jQuery version " + $.fn.jquery); });') page.add_js_chunks ('$(function() { messages.debug("sliceview: users turned %s"); });'%("on" if do_query_users else "off")) - page.add_js_chunks ('$(function() { messages.debug("manifold URL %s"); });'%(Config.manifold_url())) + config=Config() + page.add_js_chunks ('$(function() { messages.debug("manifold URL %s"); });'%(config.manifold_url())) page.expose_js_metadata() metadata = page.get_metadata() @@ -189,33 +191,33 @@ class SliceView (LoginRequiredAutoLogoutView): # -------------------------------------------------------------------------- # USERS - if do_query_users: - tab_users = Tabs( - page = page, - domid = 'users', - outline_complete = True, - togglable = True, - title = 'Users', - active_domid = 'users-list', - ) - main_stack.insert(tab_users) - - tab_users.insert(Hazelnut( - page = page, - title = 'Users List', - domid = 'users-list', - # tab's sons preferably turn this off - togglable = False, - # this is the query at the core of the slice list - query = sq_user, - query_all = query_user_all, - checkboxes = True, - datatables_options = { - 'iDisplayLength' : 25, - 'bLengthChange' : True, - 'bAutoWidth' : True, - }, - )) +# if do_query_users: +# tab_users = Tabs( +# page = page, +# domid = 'users', +# outline_complete = True, +# togglable = True, +# title = 'Users', +# active_domid = 'users-list', +# ) +# main_stack.insert(tab_users) +# +# tab_users.insert(Hazelnut( +# page = page, +# title = 'Users List', +# domid = 'users-list', +# # tab's sons preferably turn this off +# togglable = False, +# # this is the query at the core of the slice list +# query = sq_user, +# query_all = query_user_all, +# checkboxes = True, +# datatables_options = { +# 'iDisplayLength' : 25, +# 'bLengthChange' : True, +# 'bAutoWidth' : True, +# }, +# )) # DEMO # -------------------------------------------------------------------------- # MEASUREMENTS diff --git a/portal/templates/contact.html b/portal/templates/contact.html index 5161971b..26526477 100644 --- a/portal/templates/contact.html +++ b/portal/templates/contact.html @@ -22,9 +22,7 @@
{{ field.errors }} {{ field }}

{{ field.help_text }}

{% endfor %} -
- -
+ diff --git a/portal/templates/registration_view.html b/portal/templates/registration_view.html index d8abb5d5..3d1010c5 100644 --- a/portal/templates/registration_view.html +++ b/portal/templates/registration_view.html @@ -104,9 +104,8 @@

Account Delegation: Manual (Advanced Users)

-
- -
+ +
diff --git a/portal/templates/resource.html b/portal/templates/resource.html index 5bdfdc9a..27089a72 100644 --- a/portal/templates/resource.html +++ b/portal/templates/resource.html @@ -8,6 +8,6 @@

Resource

{{resource}} -{{resource_stats}} {{resource_as_map}} +{{resource_stats}} {% endblock %} diff --git a/portal/templates/slice-request-view.html b/portal/templates/slice-request-view.html index f437ae00..6aede04f 100644 --- a/portal/templates/slice-request-view.html +++ b/portal/templates/slice-request-view.html @@ -25,9 +25,7 @@

{{ field.help_text }}

{% endfor %} -
- -
+ diff --git a/setup.py b/setup.py index 98d1368e..157641a9 100644 --- a/setup.py +++ b/setup.py @@ -20,5 +20,5 @@ setup(packages = packages, ( 'static/img', glob ('static/img/*')), ( 'static/fonts', glob ('static/fonts/*')), ( 'templates', glob ('templates/*')), - ( 'apache', [ 'apache/myslice.conf', 'apache/myslice.wsgi' ]), + ( 'apache', [ 'apache/myslice.conf' ]), ]) diff --git a/ui/templates/widget-topmenu.html b/ui/templates/widget-topmenu.html index f5308de0..b31b1330 100644 --- a/ui/templates/widget-topmenu.html +++ b/ui/templates/widget-topmenu.html @@ -23,7 +23,7 @@ diff --git a/ui/topmenu.py b/ui/topmenu.py index 72904f9b..bdee674d 100644 --- a/ui/topmenu.py +++ b/ui/topmenu.py @@ -7,33 +7,35 @@ # ### a dropdown # { 'label': ..., 'href'=..., 'dropdown':True, 'contents': [ { 'label':.., 'href'} ] } # , ..] + +# current: the beginning of the label in the menu that you want to outline def topmenu_items (current,request=None): has_user=request.user.is_authenticated() result=[] if has_user: result.append({'label':'Dashboard', 'href': '/portal/dashboard/'}) result.append({'label':'Request a slice', 'href': '/portal/slice_request/'}) - result.append({'label':'My Account', 'href': '/portal/account/'}) - result.append({'label':'Contact Support', 'href': '/portal/contact/'}) -# Not really useful at this point, is it ? -# This should probably go into dashboard at some point -# result.append({'label':'Platforms', 'href': '/portal/platforms/'}) -# the code for building a dropdown instead - but somehow this is broken -# dropdown = [ {'label':'..', 'href': '..'}, ...] -# result.append({'label': 'More', 'href':"#", 'dropdown':True, 'contents':dropdown}) + dropdown = [] + dropdown.append({'label':'My Account', 'href': '/portal/account/'}) + dropdown.append({'label':'Contact Support', 'href': '/portal/contact/'}) + result.append({'label': 'More', 'href':"#", 'dropdown':True, 'contents':dropdown}) else: result.append({'label':'Home', 'href': '/login'}) # looks like this is accessible to non-logged users result.append({'label':'Platforms', 'href': '/portal/platforms/'}) result.append({'label':'Register', 'href': '/portal/register/'}) result.append({'label':'Contact Support', 'href': '/portal/contact/'}) - # mark active - for d in result: - if 'dropdown' in d: - for dd in d['contents']: - if dd['label'] == current: dd['is_active']=True - else: - if d['label'] == current: d['is_active']=True + # mark active if the provided 'current', even if shorter, matches the beginning of d['label'] + + if current is not None: + current=current.lower() + curlen=len(current) + def mark_active(d): + if d['label'][:curlen].lower() == current: d['is_active']=True + for d in result: + mark_active(d) + if 'dropdown' in d: + for dd in d['contents']: mark_active(dd) return result def the_user (request): diff --git a/unfold/loginrequired.py b/unfold/loginrequired.py index 0f46ff79..ebe33d51 100644 --- a/unfold/loginrequired.py +++ b/unfold/loginrequired.py @@ -32,7 +32,9 @@ def logout_on_manifold_exception (fun_that_returns_httpresponse): except ManifoldException, manifold_result: # xxx we need a means to display this message to user... from django.contrib.auth import logout - logout(request) + # in some unusual cases, this might fail + try: logout(request) + except: pass return HttpResponseRedirect ('/') except Exception, e: # xxx we need to sugarcoat this error message in some error template... diff --git a/unfold/page.py b/unfold/page.py index 07879e7b..5922ae7e 100644 --- a/unfold/page.py +++ b/unfold/page.py @@ -34,6 +34,7 @@ class Page: self._queue=[] # global prelude object self.prelude=Prelude(css_files='css/plugin.css') + self.prelude=Prelude(css_files='css/onelab_marko.css') # record known plugins hashed on their domid def record_plugin (self, plugin): @@ -140,7 +141,8 @@ class Page: self.add_js_chunks("var MANIFOLD_METADATA =" + self.get_metadata().to_json() + ";") def expose_js_manifold_config (self): - self.add_js_chunks(Config.manifold_js_export()) + config=Config() + self.add_js_chunks(config.manifold_js_export()) #################### requirements/prelude management # just forward to self.prelude - see decorator above diff --git a/unfold/static/css/onelab_marko.css b/unfold/static/css/onelab_marko.css new file mode 100644 index 00000000..b31174ce --- /dev/null +++ b/unfold/static/css/onelab_marko.css @@ -0,0 +1,410 @@ +/* @override + http://test.myslice.info/static/css/plugin.css +*/ + + + +/*-------------------------------- MARKO'S STYLES -----*/ + + +/* GENERAL */ + +.container { + padding: 0 !important; + color: #fff; +} + +.container h1 { + color: #fff !important; + font-family: Ubuntu; + margin-top: 60px; +} + +div.plugin-outline-complete, +div.plugin-outline-body { + border: 0px solid; + border-radius: 0; + border-color: #ccc; + -webkit-transition: padding 200ms ease-out; + -moz-transition: padding 200ms ease-out; + -o-transition: padding 200ms ease-out; + transition: padding 0.2s ease-out; + padding: 20px; + margin: 0; +} +/* +div.plugin-outline-complete:hover, +div.plugin-outline-body:hover { + padding: 80px 80px 120px 80px; +} +*/ +a.plugin-tooltip { + font-size: 130%; + font-style: normal; + font-weight: bold; + padding: 5px; + color: #333; + font-family: Ubuntu, Arial, sans-serif; + text-transform: uppercase; +} + +a.plugin-tooltip:hover { + color: #fff; + text-decoration: none; +} + + + +/* LIST VIEW */ + +h2.well.well-lg { + border-radius:0; + border: 0; + font-family: Ubuntu, arial, sans-serif; + text-transform: ; + font-weight: normal; + font-size: 40px; + /* color: #30196d; */ + color: white; + margin-bottom: 0px; + margin-top: 0; + padding: 30px; + opacity: 1; + text-align: center; + background-color: #30196d; +} + +#complete-resources { +/* background-color: #92f79e !important; */ + background-color: #B8B2FF !important; +} + +#complete-filters { +/* background-color: #4af25d; */ + background-color: #add7ff; +} + +#complete-users { +/* background-color: #ff7394 !important; */ + background-color: #add7ff !important; +} + +#complete-measurements { + background-color: !important; +} + +#complete-pending { +/* background-color: #add7ff !important; */ + background-color: #B8B2FF !important; + +} + +#complete-customize-resources { + background-color: #efdfdf; +} + +#complete-msgs-pre { + background-color: #ccc; +} + +#complete-resources, +#complete-filters, +#complete-users, +#complete-measurements, +#complete-pending, +#complete-customize-resources, +#complete-msgs-pre { + opacity: 1; + text-align: center; + color: #333; +} + +#complete-resources:hover, +#complete-filters:hover, +#complete-users:hover, +#complete-measurements:hover, +#complete-pending:hover, +#complete-customize-resources:hover, +#complete-msgs-pre:hover { + opacity: 1; +} + +.nav.nav-tabs { + font-family: Ubuntu, Arial, sans-serif; + border: 0 !important; + border-bottom: 3px solid #fff !important; + margin-bottom: 40px; +} + +.nav.nav-tabs li.active a { + color: #572bc9; + border-left: 0px solid #572bc9; + border-top: 0px solid #572bc9; + border-right: 0px solid #572bc9; +} + +.nav.nav-tabs li a { + color: #333; + border: 0 !important; + margin-right: 5px; +} + +.nav.nav-tabs li a:hover { + color: #333; + background: #572bc9; + color: #fff; + border: 0 !important; +} + + + + + +/* TOPMENU.CSS */ + +body { + background: #30196d !important; + padding-top: 60px; + padding-bottom: 0px; +} + +div.topmenu { + padding-top: 0px; + font-family: Ubuntu, Arial, sans-serif; + font-weight: bold; + text-transform: ; + background: #fff; + -webkit-box-shadow: 0px 10px 10px rgba(50, 50, 50, 0.44); + -moz-box-shadow: 0px 10px 10px rgba(50, 50, 50, 0.44); + box-shadow: 0px 10px 10px rgba(50, 50, 50, 0.44); +} + +.navbar-nav li a, +.navbar-nav li.other a { + padding-top: 25px; + padding-bottom: 20px; +} + +.navbar-nav li a:hover { + color: #572bc9 !important; +} + +.navbar-nav li.active a { +.navbar-nav li.active a { + background: #eee !important; +} + +ul.logged-in { + padding-top: 25px; +} +button.logged-in { + font-size: 1em; + font-weight: bold; + margin-left: 5px; + margin-top: -5px; + background: #572bc9; + border: 2px solid #572bc9; + color: #eee; + padding: 5px 15px; + border-radius:5px; +} + +button.logged-in:hover { + background: #4af25d; + border: 2px solid #4af25d; + color: #333; +} +li.username { + margin-bottom: 10px; + font-size: 0.8em; + text-transform: none; + font-weight: normal; + color: #999; +} + + +/* BOOTSTRAP */ + + +ul.pagination li a { + background: ; + color: #572bc9; + font-family: Ubuntu, Arial, sans-serif; +} + +ul.pagination li.active a { + background: #572bc9; + border: 1px solid #572bc9; +} + +.btn.btn-default { + background: #572bc9; + color: #ccc; + font-family: Ubuntu, Arial, sans-serif; + font-weight: bold; + border: 0px; +} + +.btn.btn-default:hover { + background: #4af25d; + color: #333; + font-family: Ubuntu, Arial, sans-serif; + font-weight: bold; + border: 0px; +} + +input { + border-radius: 3px; + border: none; + border: 1px solid #ccc; +} + + +div.dataTables_length label, +div.dataTables_filter label, +div.dataTables_info { + font-family: Ubuntu, Arial, sans-serif !important; +} + + + + +/* HAZELNUT */ + +div.Hazelnut table.dataTable th { + font: bold 12px/22px Ubuntu, Arial, sans-serif; + color: #333 !important; + border-right: 0px solid #333 !important; + border-bottom: 0px solid #C1DAD7 !important; + border-top: 0px solid #C1DAD7 !important; + letter-spacing: 1px; + text-transform: uppercase; + text-align: left; + padding: 8px 12px 4px 20px; + vertical-align:middle; + background: # url(../img/tablesort-header.jpg) no-repeat !important; +} + +div.Hazelnut table.dataTable td, div.Hazelnut table.dataTable textarea, div.Hazelnut table.dataTable input [type="text"] { + font: normal 12px Ubuntu, Arial, Helvetica, sans-serif; + border-right: 0px solid #fff !important; + border-bottom: 1px solid #fff !important; +} + +div.Hazelnut table.dataTable thead { + background: url('../img/tablesort-header.png') repeat-x !important; + background-color: #caebea; +} + +div.Hazelnut table.dataTable tfoot { + background: url('../img/tablesort-header.png') repeat-x !important; + background-color: # !important; +} + + +/* QUERY EDITOR */ + +table.query-editor { + margin: 40px auto !important; + clear: both; + /* width: 80%;*/ + width: 100% !important; + font-family: Ubuntu; +} + +.query-editor-spacer, +.plugin.ResourcesSelected, +.plugin.Tabs { + margin-top: 60px !important; +} + +table.query-editor td { + padding: 5px 5px !important; + font: normal 12px Ubuntu, Arial, sans-serif !important; +} + + + +/* DASHBOARD */ + +#ms-dashboard-profile, +#ms-dashboard-testbeds, +#ms-dashboard-slices { + -webkit-transition: all 50ms ease-out; + -moz-transition: all 50ms ease-out; + -o-transition: all 50ms ease-out; + transition: all 0.05s ease-out; + padding-top: 140px; + padding-bottom: 60px; + margin-top: 60px; + color: #fff; + font-family: Ubuntu, Arial, sans-serif; + text-align: center; + +} + +#ms-dashboard-profile:hover, +#ms-dashboard-testbeds:hover, +#ms-dashboard-slices:hover { + margin-top: 65px; +} + +#ms-dashboard-profile { + background: url("../img/icon_users_color.png") top center no-repeat; + +} + +#ms-dashboard-testbeds { + background: url("../img/icon_testbed_color.png") top center no-repeat; +} + +#ms-dashboard-slices { + background: url("../img/icon_slices_color.png") top center no-repeat; +} + +.ms-dashboard-content ul { + list-style-type: none !important; + padding-left: 0; + text-align: center !important; +} + +.ms-dashboard-content { + padding: 0 !important; +} + +.ms-dashboard-content a { + color: /*#572bc9*/ #ff7394 !important; +} + +.ms-dashboard-caption h2 { + font-family: Ubuntu, Arial, sans-serif; + border-bottom: 0 !important; + text-transform: uppercase; +} + +#ms-dashboard-profile>div.ms-dashboard-caption { + background: no-repeat url(#) !important; + padding-left: 0 !important; +} + +#ms-dashboard-testbeds>div.ms-dashboard-caption { + background: no-repeat url(#) !important; + padding-left: 0 !important; +} + +#ms-dashboard-slices>div.ms-dashboard-caption { + background: no-repeat url(#) !important; + padding-left: 0 !important; +} + +.simplelist { + font-size: 100%; + text-align: center !important; + margin: 0 auto; +} + + + + + +