From: Loic & Edelberto Date: Thu, 13 Mar 2014 13:26:02 +0000 (-0300) Subject: FIBRE templates and images X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=afee7d500850b1779e2c08a56a0d9dff99e5f092;p=unfold.git FIBRE templates and images --- diff --git a/portal/actions-100314.py b/portal/actions-100314.py new file mode 100644 index 00000000..62f95bc4 --- /dev/null +++ b/portal/actions-100314.py @@ -0,0 +1,602 @@ +from django.http import HttpResponse +from manifold.core.query import Query +from manifoldapi.manifoldapi import execute_query,execute_admin_query +from portal.models import PendingUser, PendingSlice, PendingAuthority +import json + +from django.contrib.auth.models import User +from django.template.loader import render_to_string +from django.core.mail import EmailMultiAlternatives + +from theme import ThemeView + +theme = ThemeView() + +# Thierry: moving this right into the code so +# most people can use myslice without having to install sfa +# XXX tmp sfa dependency, should be moved to SFA gateway +#from sfa.util.xrn import Xrn + + +# Get the list of authorities + +def authority_get_pis(request, authority_hrn): + query = Query.get('authority').filter_by('authority_hrn', '==', authority_hrn).select('pi_users') + results = execute_admin_query(request, query) + # NOTE: temporarily commented. Because results is giving empty list. + # Needs more debugging + #if not results: + # raise Exception, "Authority not found: %s" % authority_hrn + #result, = results + #return result['pi_users'] + return results + +def authority_get_pi_emails(request, authority_hrn): + pi_users = authority_get_pis(request,authority_hrn) + if any(d['pi_users'] == None for d in pi_users): + theme.template_name = 'email_default_recipients.txt' + default_email = render_to_string(theme.template, request) + default_email = default_email.replace('\n', '') + return default_email + else: + pi_user_hrns = [ hrn for x in pi_users for hrn in x['pi_users'] ] + query = Query.get('user').filter_by('user_hrn', 'included', pi_user_hrns).select('user_email') + results = execute_admin_query(request, query) + return [result['user_email'] for result in results] + +def is_pi(wsgi_request, user_hrn, authority_hrn): + # XXX could be done in a single query ! + + # select pi_authorities from user where user_hrn == "ple.upmc.jordan_auge" + query = Query.get('user').filter_by('user_hrn', '==', user_hrn).select('pi_authorities') + results = execute_admin_query(wsgi_request, query) + if not results: + # XXX Warning ? + return False + result = results[0] + user_authority_hrns = result.get('pi_authorities', []) + return authority_hrn in user_authority_hrns + +# SFA get record + +def sfa_get_user(request, user_hrn, pub): + query_sfa_user = Query.get('user').filter_by('user_hrn', '==', user_hrn) + result_sfa_user = execute_query(request, query_sfa_user) + return result_sfa_user + +def sfa_update_user(request, user_hrn, user_params): + # user_params: keys [public_key] + if 'email' in user_params: + user_params['user_email'] = user_params['email'] + query = Query.update('user').filter_by('user_hrn', '==', user_hrn).set(user_params).select('user_hrn') + results = execute_query(request,query) + return results + +def sfa_add_authority(request, authority_params): + query = Query.create('authority').set(authority_params).select('authority_hrn') + results = execute_query(request, query) + print "sfa_add_auth results=",results + if not results: + raise Exception, "Could not create %s. Already exists ?" % authority_params['hrn'] + return results + +def sfa_add_user_to_slice(request, user_hrn, slice_params): +# UPDATE myslice:slice SET researcher=['ple.upmc.jordan_auge','ple.inria.thierry_parmentelat','ple.upmc.loic_baron','ple.upmc.ciro_scognamiglio','ple.upmc.mohammed-yasin_rahman','ple.upmc.azerty'] where slice_hrn=='ple.upmc.myslicedemo' + query_current_users = Query.get('slice').select('user').filter_by('slice_hrn','==',slice_params['hrn']) + results_current_users = execute_query(request, query_current_users) + slice_params['researcher'] = slice_params['researcher'] | results_current_users + query = Query.update('slice').filter_by('user_hrn', '==', user_hrn).set(slice_params).select('slice_hrn') + results = execute_query(request, query) +# Also possible but not supported yet +# UPDATE myslice:user SET slice=['ple.upmc.agent','ple.upmc.myslicedemo','ple.upmc.tophat'] where user_hrn=='ple.upmc.azerty' + if not results: + raise Exception, "Could not create %s. Already exists ?" % slice_params['hrn'] + return results + +# Propose hrn + +def manifold_add_user(wsgi_request, request): + """Add a Manifold user corresponding to a user request. + + Args: + wsgi_request: a WSGIRequest instance + request (dict): a dictionary containing the user request built from the + form. + + Returns: + The user_id of the inserted user. + + Raises: + ? + + """ + USER_CONFIG = '{"firstname": "%(first_name)s", "lastname": "%(last_name)s", "authority": "%(authority_hrn)s"}' + + user_params = { + 'email' : request['email'], + 'password' : request['password'], + 'config' : USER_CONFIG % request, + 'status' : 1, + } + + query = Query.create('local:user').set(user_params).select('email') + results = execute_admin_query(request, query) + if not results: + raise Exception, "Failed creating manifold user: %s" % user_params['email'] + result = results[0] + return result['email'] + +def manifold_update_user(request, email, user_params): + # user_params: password, config e.g., + query = Query.update('local:user').filter_by('email', '==', email).set(user_params).select('email') + results = execute_admin_query(request,query) + # NOTE: results remains empty and goes to Exception. However, it updates the manifold DB. + # That's why I commented the exception part. -- Yasin + #if not results: + # raise Exception, "Failed updating manifold user: %s" % user_params['email'] + #result, = results + return results + +def manifold_add_account(request, account_params): + query = Query.create('local:account').set(account_params).select(['user', 'platform']) + results = execute_admin_query(request,query) + if not results: + raise Exception, "Failed creating manifold account on platform %s for user: %s" % (account_params['platform'], account_params['user']) + result, = results + return result['user_id'] + +def manifold_update_account(request,user_id,account_params): + # account_params: config + query = Query.update('local:account').filter_by('platform', '==', 'myslice').filter_by('user_id', '==', user_id).set(account_params).select('user_id') + results = execute_admin_query(request,query) + return results + +#explicitly mention the platform_id +def manifold_delete_account(request, platform_id, user_id, account_params): + query = Query.delete('local:account').filter_by('platform_id', '==', platform_id).filter_by('user_id', '==', user_id).set(account_params).select('user_id') + results = execute_admin_query(request,query) + return results + + +#not tested +def manifold_add_platform(request, platform_params): + query = Query.create('local:platform').set(platform_params).select(['user', 'platform']) + results = execute_admin_query(request,query) + if not results: + raise Exception, "Failed creating manifold platform %s for user: %s" % (platform_params['platform'], platform_params['user']) + result, = results + return result['platform_id'] + + +def make_request_user(user): + request = {} + request['type'] = 'user' + request['id'] = user.id + request['timestamp'] = user.created # XXX in DB ? + request['authority_hrn'] = user.authority_hrn + request['first_name'] = user.first_name + request['last_name'] = user.last_name + request['email'] = user.email + request['login'] = user.login + request['user_hrn'] = user.user_hrn + request['public_key'] = user.public_key + request['private_key'] = user.private_key + return request + +def make_request_slice(slice): + request = {} + request['type'] = 'slice' + request['id'] = slice.id + request['user_hrn'] = slice.user_hrn + request['timestamp'] = slice.created + request['authority_hrn'] = slice.authority_hrn + request['slice_name'] = slice.slice_name + request['number_of_nodes'] = slice.number_of_nodes + request['type_of_nodes'] = slice.type_of_nodes + request['purpose'] = slice.purpose + return request + +def make_request_authority(authority): + request = {} + request['type'] = 'authority' + request['id'] = authority.id + request['site_name'] = authority.site_name + request['site_latitude'] = authority.site_latitude + request['site_longitude'] = authority.site_longitude + request['site_url'] = authority.site_url + request['site_authority'] = authority.site_authority + request['site_abbreviated_name'] = authority.site_abbreviated_name + request['address_line1'] = authority.address_line1 + request['address_line2'] = authority.address_line2 + request['address_line3'] = authority.address_line3 + request['address_city'] = authority.address_city + request['address_postalcode'] = authority.address_postalcode + request['address_state'] = authority.address_state + request['address_country'] = authority.address_country + request['authority_hrn'] = authority.authority_hrn + request['timestamp'] = authority.created + return request + +def make_requests(pending_users, pending_slices, pending_authorities): + requests = [] + for user in pending_users: + requests.append(make_request_user(user)) + for slice in pending_slices: + requests.append(make_request_slice(slice)) + for authority in pending_authorities: + requests.append(make_request_authority(authority)) + return requests + +def get_request_by_id(ids): + sorted_ids = { 'user': [], 'slice': [], 'authority': [] } + for type__id in ids: + type, id = type__id.split('__') + sorted_ids[type].append(id) + + if not ids: + pending_users = PendingUser.objects.all() + pending_slices = PendingSlice.objects.all() + pending_authorities = PendingAuthority.objects.all() + else: + pending_users = PendingUser.objects.filter(id__in=sorted_ids['user']).all() + pending_slices = PendingSlice.objects.filter(id__in=sorted_ids['slice']).all() + pending_authorities = PendingAuthority.objects.filter(id__in=sorted_ids['authority']).all() + + return make_requests(pending_users, pending_slices, pending_authorities) + +def get_requests(authority_hrns=None): + print "get_request_by_authority auth_hrns = ", authority_hrns + if not authority_hrns: + pending_users = PendingUser.objects.all() + pending_slices = PendingSlice.objects.all() + pending_authorities = PendingAuthority.objects.all() + else: + pending_users = PendingUser.objects.filter(authority_hrn__in=authority_hrns).all() + pending_slices = PendingSlice.objects.filter(authority_hrn__in=authority_hrns).all() + pending_authorities = PendingAuthority.objects.filter(authority_hrn__in=authority_hrns).all() + + return make_requests(pending_users, pending_slices, pending_authorities) + +# XXX Is it in sync with the form fields ? + +def portal_validate_request(wsgi_request, request_ids): + status = {} + + if not isinstance(request_ids, list): + request_ids = [request_ids] + + requests = get_request_by_id(request_ids) + for request in requests: + # type, id, timestamp, details, allowed -- MISSING: authority_hrn + # CAREFUL about details + # user : first name, last name, email, password, keypair + # slice : number of nodes, type of nodes, purpose + + request_status = {} + + if request['type'] == 'user': + + try: + create_user(wsgi_request, request) + request_status['SFA user'] = {'status': True } + + except Exception, e: + request_status['SFA user'] = {'status': False, 'description': str(e)} + +# user_params = {'status':2} +# manifold_update_user(request, request['email'], user_params) + + # MANIFOLD user should be added beforehand, during registration + #try: + # manifold_user_params = { key: request[key] for key in MANIFOLD_USER_KEYS } + # # XXX # manifold_add_user(manifold_user_params) + # request_status['MySlice user'] = {'status': True } + #except Exception, e: + # request_status['MySlice user'] = {'status': False, 'description': str(e)} + + # XXX + #manifold_account_params = { key: request[key] for key in MANIFOLD_ACCOUNT_KEYS } + #manifold_add_account(manifold_account_params) + #request_status['MySlice testbed accounts'] = {'status': False } + + elif request['type'] == 'slice': + try: + create_slice(wsgi_request, request) + request_status['SFA slice'] = {'status': True } + + except Exception, e: + request_status['SFA slice'] = {'status': False, 'description': str(e)} + + elif request['type'] == 'authority': + try: + #hrn = "%s.%s" % (request['authority_hrn'], request['site_authority']) + hrn = request['site_authority'] + # XXX tmp sfa dependency + from sfa.util.xrn import Xrn + urn = Xrn(hrn, request['type']).get_urn() + + sfa_authority_params = { + 'hrn' : hrn, + 'urn' : urn, + 'type' : request['type'], + #'pi' : None, + 'enabled' : True + } + print "ADD Authority" + sfa_add_authority(wsgi_request, sfa_authority_params) + request_status['SFA authority'] = {'status': True } + + except Exception, e: + request_status['SFA authority'] = {'status': False, 'description': str(e)} + + # XXX Remove from Pendings in database + + status['%s__%s' % (request['type'], request['id'])] = request_status + + return status + + +def validate_action(request, **kwargs): + ids = filter(None, kwargs['id'].split('/')) + status = portal_validate_request(request, ids) + json_answer = json.dumps(status) + return HttpResponse (json_answer, mimetype="application/json") + +# Django and ajax +# http://djangosnippets.org/snippets/942/ + + + +#------------------------------------------------------------------------------- +# REQUESTS - Slices +#------------------------------------------------------------------------------- + +def create_slice(wsgi_request, request): + """ + Arguments: + wsgi_request (~ WSGIRequest) : + request (dict) : the slice request in our own dict format + + Raises: + Exception + """ + hrn = "%s.%s" % (request['authority_hrn'], request['slice_name']) + # XXX tmp sfa dependency + from sfa.util.xrn import Xrn + urn = Xrn(hrn, request['type']).get_urn() + + # Add User to Slice if we have the user_hrn in pendingslice table + user_hrn = request.get('user_hrn', None) + user_hrns = list([user_hrn]) if user_hrn else list() + + # XXX We should create a slice with Manifold terminology + slice_params = { + 'slice_hrn' : hrn, + 'slice_urn' : urn, + 'slice_type' : request['type'], + 'users' : user_hrns, + 'slice_enabled' : True + } + # ignored in request: id, timestamp, number_of_nodes, type_of_nodes, purpose + + query = Query.create('slice').set(slice_params).select('slice_hrn') + results = execute_query(wsgi_request, query) + if not results: + raise Exception, "Could not create %s. Already exists ?" % slice_params['hrn'] + return results + +def create_pending_slice(wsgi_request, request, email): + """ + """ + + # Insert an entry in the PendingSlice table + s = PendingSlice( + slice_name = request['slice_name'], + user_hrn = request['user_hrn'], + authority_hrn = request['authority_hrn'], + number_of_nodes = request['number_of_nodes'], + purpose = request['purpose'], + ) + s.save() + + try: + # Send an email: the recipients are the PI of the authority + recipients = authority_get_pi_emails(wsgi_request, request['authority_hrn']) + + theme.template_name = 'slice_request_email.txt' + text_content = render_to_string(theme.template, request) + + theme.template_name = 'slice_request_email.html' + html_content = render_to_string(theme.template, request) + + theme.template_name = 'slice_request_email_subject.txt' + subject = render_to_string(theme.template, request) + subject = subject.replace('\n', '') + + sender = email + msg = EmailMultiAlternatives(subject, text_content, sender, [recipients]) + print msg + msg.attach_alternative(html_content, "text/html") + msg.send() + except Exception, e: + print "Failed to send email, please check the mail templates and the SMTP configuration of your server" + +#------------------------------------------------------------------------------- +# REQUESTS - Users +#------------------------------------------------------------------------------- + +def manifold_add_reference_user_accounts(wsgi_request, request): + """When a new user is created, add reference accounts to the reference platform. + """ + # XXX XXX XXX The rest of this function has to be checked XXX XXX XXX + + # Retrieve user information + user_query = Query().get('local:user') \ + .select('user_id', 'config', 'email', 'status') \ + .filter_by('email', '==', request['email']) + user_details = execute_admin_query(wsgi_request, user_query) + + # USER MAIN ACCOUNT != reference + #print 'USER MAIN ACCOUNT != reference' + list_accounts_query = Query().get('local:account') \ + .select('user_id', 'platform_id', 'auth_type', 'config') \ + .filter_by('user_id', '==', user_details[0]['user_id']) \ + .filter_by('auth_type', '!=', 'reference') + list_accounts = execute_admin_query(wsgi_request, list_accounts_query) + + # XXX main_platform is being erased several times ??? + for account in list_accounts: + main_platform_query = Query().get('local:platform') \ + .select('platform_id', 'platform') \ + .filter_by('platform_id', '==', account['platform_id']) + main_platform = execute_admin_query(wsgi_request, main_platform_query) + + # Add reference accounts on SFA enabled platforms + platforms_query = Query().get('local:platform') \ + .filter_by('disabled', '==', '0') \ + .filter_by('gateway_type', '==', 'sfa') \ + .select('platform_id', 'gateway_type') + platforms = execute_admin_query(wsgi_request, platforms_query) + for platform in platforms: + #print "add reference to platform ",platform + manifold_account_params = { + 'user_id' : user_details[0]['user_id'], + 'platform_id' : platform['platform_id'], + 'auth_type' : 'reference', + 'config' : '{"reference_platform": "' + main_platform[0]['platform'] + '"}', + } + manifold_add_account(wsgi_request, manifold_account_params) + +def sfa_create_user(wsgi_request, request): + """ + Arguments: + wsgi_request (~ WSGIRequest) : + request (dict) : the user request in our own dict format + + Raises: + Exception + """ + from sfa.util.xrn import Xrn + + auth_pi = request.get('pi', None) + auth_pi = list([auth_pi]) if auth_pi else list() + + # We create a user request with Manifold terminology + sfa_user_params = { + 'user_hrn' : request['user_hrn'], + 'user_email' : request['email'], + 'user_urn' : Xrn(request['user_hrn'], request['type']).get_urn(), + 'user_type' : request['type'], + 'keys' : request['public_key'], + 'user_first_name' : request['first_name'], + 'user_last_name' : request['last_name'], + 'pi_authorities' : auth_pi, + 'user_enabled' : True + } + + query = Query.create('user').set(sfa_user_params).select('user_hrn') + results = execute_query(wsgi_request, query) + if not results: + raise Exception, "Could not create %s. Already exists ?" % sfa_user_params['user_hrn'] + return results + +#def ldap_create_user + +def create_user(wsgi_request, request): + + # XXX This has to be stored centrally + USER_STATUS_ENABLED = 2 + + # NOTE : if we were to create a user directly (just like we create slices, + # we would have to perform the steps in create_pending_user too + + # Add the user to the SFA registry + sfa_create_user(wsgi_request, request) + + # Update Manifold user status + manifold_update_user(wsgi_request, request['email'], {'status': USER_STATUS_ENABLED}) + + # Add reference accounts for platforms + manifold_add_reference_user_accounts(wsgi_request, request) + +def create_pending_user(wsgi_request, request, user_detail): + """ + """ + + # Insert an entry in the PendingUser table + b = PendingUser( + first_name = request['first_name'], + last_name = request['last_name'], + authority_hrn = request['authority_hrn'], + email = request['email'], + password = request['password'], + public_key = request['public_key'], + private_key = request['private_key'], + user_hrn = request['user_hrn'], + pi = '', # XXX Why not None ? + ) + b.save() + + # saves the user to django auth_user table [needed for password reset] + user = User.objects.create_user(request['email'], request['email'], request['password']) + + # Creating a manifold user + user_id = manifold_add_user(wsgi_request, request) + + # Creating a Manifold account on the MySlice platform + # Note the JSON representation of public and private keys already includes quotes + account_config = { + 'user_hrn' : request['user_hrn'], + 'user_public_key' : request['public_key'], + } + if request['private_key']: + account_config['user_private_key'] = request['private_key'] + + user_id = user_detail['user_id'] + 1 # the user_id for the newly created user in local:user + + # XXX TODO: Require a myslice platform + # ALERT: this will disapear with ROUTERV2 of Manifold + # We have to consider the case where several registries can be used + # Removed hardcoded platform = 5 + # This platform == 'myslice' is a TMP FIX !! + try: + reg_platform_query = Query().get('local:platform') \ + .filter_by('platform', '==', 'myslice') \ + .select('platform_id') + reg_platform = execute_admin_query(wsgi_request, reg_platform_query) + + registry_platform_id = reg_platform[0]['platform_id'] + account_params = { + 'platform_id' : reg_platform_id, # XXX ALERT !! + 'user_id' : user_id, + 'auth_type' : request['auth_type'], + 'config' : json.dumps(account_config), + } + manifold_add_account(wsgi_request, account_params) + except Exception, e: + print "Failed creating manifold account on platform %s for user: %s" % ('myslice', request['email']) + + try: + # Send an email: the recipients are the PI of the authority + # If No PI is defined for this Authority, send to a default email (different for each theme) + recipients = authority_get_pi_emails(wsgi_request, request['authority_hrn']) + + theme.template_name = 'user_request_email.html' + html_content = render_to_string(theme.template, request) + + theme.template_name = 'user_request_email.txt' + text_content = render_to_string(theme.template, request) + + theme.template_name = 'user_request_email_subject.txt' + subject = render_to_string(theme.template, request) + subject = subject.replace('\n', '') + + theme.template_name = 'email_default_sender.txt' + sender = render_to_string(theme.template, request) + sender = sender.replace('\n', '') + + msg = EmailMultiAlternatives(subject, text_content, sender, [recipients]) + msg.attach_alternative(html_content, "text/html") + msg.send() + except Exception, e: + print "Failed to send email, please check the mail templates and the SMTP configuration of your server" diff --git a/portal/static/css/fibre.css b/portal/static/css/fibre.css new file mode 100644 index 00000000..ef27a2e9 --- /dev/null +++ b/portal/static/css/fibre.css @@ -0,0 +1,420 @@ +body { + background-color:white; + color:black; + margin:0; + padding:0; +} +a, a:active, a:focus { + outline: 0; +} + +h1 { + border-bottom:1px solid #DDDDDD; + padding:0 0 5px 0; + margin:0 0 15px 0; + font-size:18pt; +} +h1 img { + vertical-align:middle; + margin-bottom:4px; +} +h2 { + font-size:14pt; + color:#333333; +} +h3 { + font-size:13pt; + color:#201E62; +} +div.wrapper { + width:980px; + margin:0 auto; + position:relative; +} +div.container { + width:80%; + margin:25px auto; +} +div.wide { + margin:25px auto; + padding:0 25px; +} + +span.label { + font-size:11pt; + color:gray; + font-weight:normal; + padding:0; +} +/***** Notifications *****/ +.warning { + border: 1px solid red; + margin: 20px 60px; + padding: 10px 20px; + color: red; + background-color: #f2dbdb; + text-align: center; +} +/* HEADER */ +div#header { + height:100px; + background-color:white; +} + +div#secondary { + +} + +div#secondary ul { + position:absolute; + top:20px; + right:0; +} + +div#secondary li { + font-size:10pt; + float:left; + list-style:none; + margin-right:30px; +} +div#secondary li a { + color:black; +} +div#secondary li a:hover { + color:#270A5A; + text-decoration:none; +} +div#secondary li:last-child { + margin-right:0; +} + +div#navigation { + background-color:rgb(30, 88, 111); + width:100%; + height:40px; +} +div#navigation div.wrapper { + text-align:center; +} +div#navigation ul { + margin:0; + padding:0; + display: inline-block; + list-style-type: none; + white-space: nowrap; +} + +div#navigation li { + color:white; + font-family:helvetica, sans-serif; + font-size:10pt ; + font-weight:normal; + line-height:0.8em; + letter-spacing:0.6pt; + list-style:none; + float:left; + padding:0; + margin:15px 50px 0 0; +} +div#navigation li a { + color:white; +} +div#navigation li a:hover { + text-decoration:none; + color:#B8B2FF; +} +div#navigation li:last-child { + margin-right:0; +} + +/* HOME DASHBOARD */ +div#home-dashboard { + color:black; + margin:0 auto 25px auto; +} +div#home-dashboard table { +/* margin:25px; */ + width:100% !important; +} +div#home-dashboard table td { + text-align:center; + padding:15px 0; + width:33%; +} +div#home-dashboard table tr:first-child td { + font-size:12pt; + font-weight:bold; + color:#270A5A; +} +div#home-dashboard table tr:last-child td { + vertical-align:top; + padding:25px 0; +} +div#home-dashboard table tr:last-child td.logged-in { + /* border-right:1px solid #DDDDDD; */ + padding:25px; +} +div#home-dashboard table tr:last-child td.support { + /* border-left:1px solid #DDDDDD; */ + padding:25px; +} +div#home-dashboard table tr:last-child td:first-child { +} +div#home-dashboard table tr:last-child td:last-child { + border-right:0; +} +div#home-dashboard table tr:last-child td.logged-in div { + text-align:left; + padding:25px 0; +} +div#home-dashboard table tr:last-child td.support div { + text-align:left; + padding:25px 0; +} + +/* Edelberto */ +.bar1 { + width: 100%; + background: #FCFCFC; + border: 1px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} + +.well { + width: 350px !important; +} + +#footer { + width: 100%; + float: left; + background-color: rgb(65, 119, 139); + height: 30px; + padding: 5px; + text-align: center; + color: white; +} + +.logo { + padding-bottom: 5px; +} + +/* Edelberto end */ + +div#home-dashboard div.login-widget { + padding:20px; +} +div#home-dashboard table td.support { +} +div#home-dashboard table td.support a { +} +div#home-dashboard table td.support a:hover { + text-decoration:none; +} + +div#home-dashboard div#manager { + display:none; +} + +div#home-dashboard div#home-slice-list { + margin:25px 0; + padding:0 25px; + text-align:left; +} +div#home-dashboard div#home-slice-list ul { + list-style: none; + padding:0; + margin:0; +} +div#home-dashboard div#home-slice-list li { + +} + +.login-submit { + vertical-align:middle; + padding:0; +} +.lost-password { + font-size:10pt; + color:#CCCCCC; + text-align:right; + padding:0px; +} +.lost-password a { +} +.login-signup { + border-top:1px solid #CCCCCC; + text-align:center; + margin-top:15px; + padding:5px 0 0 0; +} +/**/ + +/* NAV TABS */ + +.nav.nav-tabs { + margin-bottom:25px; +} + +.nav.nav-tabs li.active a { + +} + +.nav.nav-tabs li a { +} + +.nav.nav-tabs li a:hover { +} + +/**/ +/* WELL */ +div.well { +} +/**/ +/* BUTTON */ +.btn.btn-default { + font-weight: bold; +} + +.btn.btn-default:hover { + font-weight: bold; +} +/**/ +/* TABLE */ +table.table { + margin:0; +} +table.table thead { + padding:0; +} +table.table tbody { + padding:0; +} +table.table tr { + padding:0; +} +table.table td { + padding:0; +} +/* INSTITUTION */ +div#institution { + color:black; +} +.form-hint { + font-size:11pt; + font-style:italic; + color:gray; +} + + +.form-hint { + font-size:11pt; + font-style:italic; + color:gray; +} + + + +/* TICKET REQUEST */ +div#ticket-request { + color:black; +} +.form-hint { + font-size:11pt; + font-style:italic; + color:gray; +} +div#ticket-request p { + margin:20px 0; +} + +/* SLICE VIEW */ +div#slice-view { + margin:0; +} +div.list-group-item { + border:0; + background-color:white; + font-weight:bold; + padding-left:0; +} +a.list-group-item { + border:0; + background-color:white; + padding:3px 0 3px 10px; + border-left:2pt white solid; +} +a.list-group-item.active, a.list-group-item:hover { + border-left:2pt blue solid; +} +a.list-group-item p.list-group-item-text { + font-size:9pt; + font-style:italic; +} + +/* SLICE VIEW sections */ +.slice-sections, .slice-pending { + margin:0; + padding:0; +} +.slice-sections ul, .slice-pending ul { + margin:0; + padding:0; +} +.slice-pending ul { + width:400px; + margin:0 auto 15px auto; +} +.slice-sections li { + text-align:left; + margin:0; + padding:0; +} +.slice-pending li { + padding-right:15px; +} +.slice-sections li a, .slice-pending li a { + font-size:14px; + color:black; + padding:0; +} +.slice-sections li.active a, .slice-pending li.active a { + color:#201E62; + background-color:#EFEFEF; + text-decoration:underline; + padding:0; +} +.slice-sections ul.nav-pills li a:hover, .slice-pending ul.nav-pills li a:hover { + text-decoration:underline; + background-color:#EFEFEF; + color:black; +} +.slice-sections ul.nav-pills li.active, .slice-pending ul.nav-pills li.active { + +} +.slice-sections li:first-child, .slice-sections li:first-child a { + color:#201E62; + font-weight:bold; +} +.slice-experiment { + text-align:right; + padding:0; +} +.slice-experiment button { + margin:3px 0 0 0; + background-color:#CC4125; + color:white; +} + +.slice-pending { +} +.slice-pending button { + font-size:9pt; + margin:-2px 0 0 0; + padding:3px 5px; +} +.slice-pending button.apply { +} +.slice-pending button.clear { +} diff --git a/portal/static/css/onelab_edelberto.css b/portal/static/css/onelab_edelberto.css new file mode 100644 index 00000000..797d79c4 --- /dev/null +++ b/portal/static/css/onelab_edelberto.css @@ -0,0 +1,457 @@ +/* @override unfold/static/css/plugin.css */ + +/*-------------------------------- MARKO'S STYLES -----*/ + +/* GENERAL */ + +a, a:visited { + color: rgb(13, 187, 255) !important; + text-decoration: none !important; +} + +a:hover { + color: blue !important; + text-decoration: none !important; +} + +.container { + /*padding: 0 !important;*/ + padding-top: 60px !important; + color: #fff; +/* background: url(http://new.fit-equipex.fr/images/background.jpg) no-repeat; */ + background-color: rgb(237, 241, 243); + margin: 0; + width: 100%; + max-width: 100%; + min-height: 100%; + height: 100%; +} + +.container h1, .container h2 { + color: #fff !important; +} + +.navbar-brand { + padding: 5px !important; +} + +.nav { + padding-top: 30px !important; + padding-left: 20px !important; +} + +.navbar-default { + background-color: #fff !important; +} + +p.login-status { + color: blue !important; +} + +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 */ +div.well-lg { + background-color: rgba(168, 32, 202, 0.5) !important; +} +div.onelab-title { + background-color: #3A5FCD !important; + /*background-color: rgba(168, 32, 202, 0.5) !important;*/ +} +div.well { + /*background-color: rgba(0, 0, 0, 0.5) !important;*/ + background-color: #fff !important; + color: rgb(37, 37, 37) !important; +} +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: 40px; + 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; +} + + + +/* if window enlarged wider than background picture */ +body { + background: rgb(237, 241, 243) !important; + /*background: black !important;*/ +} + +/* TOPMENU.CSS */ + +/* Thierry : turning this off +body { + *//* background: #30196d !important; *//* + background: black !important; + padding-top: 60px; + padding-bottom: 0px; +} +Thierry */ + +/* Thierry : turning this off +div.topmenu { + padding-top: 0px; + font-family: Ubuntu, Arial, sans-serif; + font-weight: bold; + 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); +} +Thierry */ + +/* Thierry : turning this off +.navbar-nav li a, +.navbar-nav li.other a { + padding-top: 25px; + padding-bottom: 20px; +} +Thierry */ + +.navbar-nav li a:hover { + color: #572bc9 !important; +} + +.navbar-nav li.active a { + background: #eee !important; +} + +/* Thierry : turning this off +ul.logged-in { + padding-top: 25px; +} +Thierry */ +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; */ + background: #ff7394; + border: 2px solid #ff7394; + 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; */ + background: #ff7394; + 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; +} + + + + +/* QUERYTABLE */ + +div.QueryTable 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.png') no-repeat !important; +} + +div.QueryTable table.dataTable td, div.QueryTable table.dataTable textarea, div.QueryTable 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.QueryTable table.dataTable thead { + background: url('../img/tablesort-header.png') repeat-x !important; + background-color: #caebea; +} + +div.QueryTable 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.QueryUpdater, +/* Thierry : turning this off +.plugin.Tabs +Thierry */ +{ + 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: #ff7394 !important; +/* color: #ff0099 !important; */ +} + +.ms-dashboard-content a:hover { + color: white !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; +} + diff --git a/portal/static/img/fibre-logo.gif b/portal/static/img/fibre-logo.gif new file mode 100644 index 00000000..e215771d Binary files /dev/null and b/portal/static/img/fibre-logo.gif differ diff --git a/portal/static/img/fibre/icon_authority_color.png b/portal/static/img/fibre/icon_authority_color.png new file mode 100644 index 00000000..342a1dd3 Binary files /dev/null and b/portal/static/img/fibre/icon_authority_color.png differ diff --git a/portal/static/img/fibre/icon_slices.png b/portal/static/img/fibre/icon_slices.png new file mode 100644 index 00000000..9527461c Binary files /dev/null and b/portal/static/img/fibre/icon_slices.png differ diff --git a/portal/static/img/fibre/icon_support.png b/portal/static/img/fibre/icon_support.png new file mode 100644 index 00000000..54bce1b7 Binary files /dev/null and b/portal/static/img/fibre/icon_support.png differ diff --git a/portal/static/img/fibre/icon_testbed_color.png b/portal/static/img/fibre/icon_testbed_color.png new file mode 100644 index 00000000..f3c55e46 Binary files /dev/null and b/portal/static/img/fibre/icon_testbed_color.png differ diff --git a/portal/static/img/fibre/icon_user_color.png b/portal/static/img/fibre/icon_user_color.png new file mode 100644 index 00000000..e88d5594 Binary files /dev/null and b/portal/static/img/fibre/icon_user_color.png differ diff --git a/portal/static/img/fibre/icones.zip b/portal/static/img/fibre/icones.zip new file mode 100644 index 00000000..bab607b5 Binary files /dev/null and b/portal/static/img/fibre/icones.zip differ diff --git a/portal/static/img/icon_authority_color.png b/portal/static/img/icon_authority_color.png new file mode 100644 index 00000000..342a1dd3 Binary files /dev/null and b/portal/static/img/icon_authority_color.png differ diff --git a/portal/static/img/icon_slices.png b/portal/static/img/icon_slices.png new file mode 100644 index 00000000..9527461c Binary files /dev/null and b/portal/static/img/icon_slices.png differ diff --git a/portal/static/img/icon_support.png b/portal/static/img/icon_support.png new file mode 100644 index 00000000..54bce1b7 Binary files /dev/null and b/portal/static/img/icon_support.png differ diff --git a/portal/static/img/icon_testbed_color.png b/portal/static/img/icon_testbed_color.png new file mode 100644 index 00000000..f3c55e46 Binary files /dev/null and b/portal/static/img/icon_testbed_color.png differ diff --git a/portal/static/img/icon_user_color.png b/portal/static/img/icon_user_color.png new file mode 100644 index 00000000..e88d5594 Binary files /dev/null and b/portal/static/img/icon_user_color.png differ diff --git a/portal/static/img/original-backup/authority-icon.png b/portal/static/img/original-backup/authority-icon.png new file mode 100644 index 00000000..bde603ad Binary files /dev/null and b/portal/static/img/original-backup/authority-icon.png differ diff --git a/portal/static/img/original-backup/experiments.png b/portal/static/img/original-backup/experiments.png new file mode 100644 index 00000000..cd97086b Binary files /dev/null and b/portal/static/img/original-backup/experiments.png differ diff --git a/portal/static/img/original-backup/f4f-logo.png b/portal/static/img/original-backup/f4f-logo.png new file mode 100644 index 00000000..8a72315d Binary files /dev/null and b/portal/static/img/original-backup/f4f-logo.png differ diff --git a/portal/static/img/original-backup/marker1.png b/portal/static/img/original-backup/marker1.png new file mode 100644 index 00000000..5f29aea8 Binary files /dev/null and b/portal/static/img/original-backup/marker1.png differ diff --git a/portal/static/img/original-backup/marker2.png b/portal/static/img/original-backup/marker2.png new file mode 100644 index 00000000..9dce718a Binary files /dev/null and b/portal/static/img/original-backup/marker2.png differ diff --git a/portal/static/img/original-backup/ques_icon.png b/portal/static/img/original-backup/ques_icon.png new file mode 100644 index 00000000..4113c121 Binary files /dev/null and b/portal/static/img/original-backup/ques_icon.png differ diff --git a/portal/static/img/original-backup/resource-icon.png b/portal/static/img/original-backup/resource-icon.png new file mode 100644 index 00000000..919bdbe5 Binary files /dev/null and b/portal/static/img/original-backup/resource-icon.png differ diff --git a/portal/static/img/original-backup/slice-icon.png b/portal/static/img/original-backup/slice-icon.png new file mode 100644 index 00000000..9e8747bb Binary files /dev/null and b/portal/static/img/original-backup/slice-icon.png differ diff --git a/portal/static/img/original-backup/testbeds.png b/portal/static/img/original-backup/testbeds.png new file mode 100644 index 00000000..ed9aa0e4 Binary files /dev/null and b/portal/static/img/original-backup/testbeds.png differ diff --git a/portal/static/img/original-backup/user-icon.png b/portal/static/img/original-backup/user-icon.png new file mode 100644 index 00000000..88f6bf82 Binary files /dev/null and b/portal/static/img/original-backup/user-icon.png differ diff --git a/portal/static/img/original-backup/user.png b/portal/static/img/original-backup/user.png new file mode 100644 index 00000000..fa72bdd2 Binary files /dev/null and b/portal/static/img/original-backup/user.png differ diff --git a/portal/templates/fibre/fibre__widget-login-ldap-manager.html b/portal/templates/fibre/fibre__widget-login-ldap-manager.html new file mode 100644 index 00000000..7c5f170e --- /dev/null +++ b/portal/templates/fibre/fibre__widget-login-ldap-manager.html @@ -0,0 +1,26 @@ +
+ {% if state %} + {{ state }} + {% endif %} +
+ {% csrf_token %} + {% if next %} + + {% endif %} +
+ + +
+
+ + +
+ + +
+
diff --git a/portal/templates/fibre/fibre__widget-login-ldap-user.html b/portal/templates/fibre/fibre__widget-login-ldap-user.html new file mode 100644 index 00000000..e43df37e --- /dev/null +++ b/portal/templates/fibre/fibre__widget-login-ldap-user.html @@ -0,0 +1,26 @@ +
+ {% if state %} + {{ state }} + {% endif %} +
+ {% csrf_token %} + {% if next %} + + {% endif %} +
+ + +
+
+ + +
+ + +
+
diff --git a/portal/templates/fibre/fibre__widget-login-manager.html b/portal/templates/fibre/fibre__widget-login-manager.html new file mode 100644 index 00000000..7c5f170e --- /dev/null +++ b/portal/templates/fibre/fibre__widget-login-manager.html @@ -0,0 +1,26 @@ +
+ {% if state %} + {{ state }} + {% endif %} +
+ {% csrf_token %} + {% if next %} + + {% endif %} +
+ + +
+
+ + +
+ + +
+
diff --git a/portal/templates/fibre/fibre__widget-login-user.html b/portal/templates/fibre/fibre__widget-login-user.html new file mode 100644 index 00000000..9e248875 --- /dev/null +++ b/portal/templates/fibre/fibre__widget-login-user.html @@ -0,0 +1,26 @@ +
+ {% if state %} + {{ state }} + {% endif %} +
+ {% csrf_token %} + {% if next %} + + {% endif %} +
+ + +
+
+ + +
+ + +
+
diff --git a/portal/templates/fibre/fibre__widget-topmenu.html b/portal/templates/fibre/fibre__widget-topmenu.html new file mode 100644 index 00000000..b9163949 --- /dev/null +++ b/portal/templates/fibre/fibre__widget-topmenu.html @@ -0,0 +1,55 @@ +{% insert_str prelude "js/bootstrap.js" %} +{% insert_str prelude "css/bootstrap.css" %} +{% insert_str prelude "css/topmenu.css" %} +{% insert_str prelude "js/logout.js" %} + + diff --git a/portal/templates/fibre/fibre_base.html b/portal/templates/fibre/fibre_base.html new file mode 100644 index 00000000..499ed886 --- /dev/null +++ b/portal/templates/fibre/fibre_base.html @@ -0,0 +1,38 @@ +{# This is required by insert_above #}{% insert_handler %} + +FIBRE - {{ section }} + + +{# This is where insert_str will end up #}{% media_container prelude %} +{% include 'messages-transient-header.html' %} + + + + + +{{ header_prelude }} +{% block head %} {% endblock head %} +{# let's add these ones no matter what #} +{% insert_str prelude "js/jquery.min.js" %} +{% insert_str prelude "js/jquery.html5storage.min.js" %} +{% insert_str prelude "js/messages-runtime.js" %} +{% insert_str prelude "js/class.js" %} +{% insert_str prelude "js/plugin-helper.js" %} +{% insert_str prelude "js/mustache.js" %} +{% insert_str prelude "js/plugin.js" %} +{% insert_str prelude "js/manifold.js" %} +{% insert_str prelude "css/manifold.css" %} +{% insert_str prelude "css/plugin.css" %} + + + +{% block container %} + {% block topmenu %} + {% include theme|add:"__widget-topmenu.html" %} + {% endblock topmenu %} + {% include 'messages-transient.html' %} + {% block base_content %} + {% endblock %} +{% endblock container %} + + diff --git a/portal/templates/fibre/fibre_home-view.html b/portal/templates/fibre/fibre_home-view.html new file mode 100644 index 00000000..f2b25b38 --- /dev/null +++ b/portal/templates/fibre/fibre_home-view.html @@ -0,0 +1,126 @@ +{% extends "layout.html" %} + +{% block content %} +
+ +
+ + + + + + + + + + + + + {% if person %} + + + + +
ACCOUNTSLICESSUPPORT
+ +
+ {% if person.last_name %} + {{person.first_name}} {{person.last_name}}
+ {% endif %} + Email: {{person.email}} +
+ {% else %} +
+ {% include 'fibre__widget-login-user.html' %} + {% include 'fibre__widget-login-ldap-user.html' %} + {% endif %} + + {% if person %} + +
Loading Slices
+ {% else %} + {% endif %} +
+ + +
+
+
+ + + + + + + + + + + +
INSTITUTIONSLICESREQUESTS
+ + + {% if person %} + + + + +
+ + {% else %} + + {% include 'fibre__widget-login-manager.html' %} + {% include 'fibre__widget-login-ldap-manager.html' %} + {% endif %} + + {% if person %} + + {% endif %} + + {% if person %} + + {% endif %} +
+
+
+ + +{% endblock %} diff --git a/portal/templates/fibre/fibre_slice-resource-view.html b/portal/templates/fibre/fibre_slice-resource-view.html new file mode 100644 index 00000000..a2971d18 --- /dev/null +++ b/portal/templates/fibre/fibre_slice-resource-view.html @@ -0,0 +1,45 @@ +{% extends "layout_wide.html" %} + +{% block head %} + +{% endblock %} + +{% block content %} +
+
+
+ + + +
+
+
+ {% include theme|add:"_widget-slice-sections.html" %} +
+
+ +
+
+ +
+
+
+{% endblock %} \ No newline at end of file diff --git a/portal/templates/fibre/fibre_slice-user-view.html b/portal/templates/fibre/fibre_slice-user-view.html new file mode 100644 index 00000000..02bad235 --- /dev/null +++ b/portal/templates/fibre/fibre_slice-user-view.html @@ -0,0 +1,95 @@ +{% extends "layout_wide.html" %} + + +{% block content %} +
+
+
+ + + +
+
+
+ {% include theme|add:"_widget-slice-sections.html" %} +
+
+ +
+
+ +
+
Loading Useres
+ + + +{% endblock %} diff --git a/portal/templates/fibre/fibre_slice-view.html b/portal/templates/fibre/fibre_slice-view.html new file mode 100644 index 00000000..a67d34b2 --- /dev/null +++ b/portal/templates/fibre/fibre_slice-view.html @@ -0,0 +1,61 @@ +{% extends "layout_wide.html" %} + +{% block content %} +
+
+
+ {% include theme|add:"_widget-slice-sections.html" %} +
+
+ +
+
+
+
+
Loading Slices
+ +
+ + +{% endblock %} diff --git a/portal/templates/fibre/fibre_testbed-list.html b/portal/templates/fibre/fibre_testbed-list.html new file mode 100644 index 00000000..a0872bf6 --- /dev/null +++ b/portal/templates/fibre/fibre_testbed-list.html @@ -0,0 +1,18 @@ +{% extends "layout_wide.html" %} + +{% block content %} +
+
+
+ {% include theme|add:"_widget-slice-sections.html" %} +
+
+ +
+
+
+{% endblock %} \ No newline at end of file diff --git a/portal/templates/fibre/fibre_widget-slice-sections.html b/portal/templates/fibre/fibre_widget-slice-sections.html new file mode 100644 index 00000000..e637b15a --- /dev/null +++ b/portal/templates/fibre/fibre_widget-slice-sections.html @@ -0,0 +1,13 @@ + +