Merge branch 'onelab' of ssh://git.onelab.eu/git/myslice into onelab
authorCiro Scognamiglio <ciro.scognamiglio@cslash.net>
Tue, 27 Jan 2015 17:43:26 +0000 (18:43 +0100)
committerCiro Scognamiglio <ciro.scognamiglio@cslash.net>
Tue, 27 Jan 2015 17:43:26 +0000 (18:43 +0100)
Conflicts:
portal/actions.py
portal/static/js/myslice.js

1  2 
.settings/org.eclipse.core.resources.prefs
myslice/settings.py
portal/actions.py
portal/models.py
portal/projectrequestview.py
portal/static/css/fed4fire.css
portal/static/js/myslice.js
portal/templates/_widget-slice-sections.html
portal/templates/fed4fire/fed4fire_projectrequest_view.html
portal/templates/management-tab-requests.html
portal/templates/slice-resource-view.html

@@@ -2,7 -2,7 +2,10 @@@ eclipse.preferences.version=
  encoding//portal/django_passresetview.py=utf-8
  encoding//portal/forms.py=utf-8
  encoding//portal/migrations/0002_extend_slice.py=utf-8
++encoding//portal/migrations/0005_extend_user.py=utf-8
++encoding//portal/migrations/0008_extend_user.py=utf-8
++encoding//portal/migrations/0009_initial.py=utf-8
++encoding//portal/migrations/0010_project.py=utf-8
  encoding//portal/models.py=utf-8
  encoding//portal/urls.py=utf-8
  encoding//portal/validationview.py=utf-8
--encoding//portal/views.py=utf-8
diff --combined myslice/settings.py
@@@ -47,7 -47,7 +47,7 @@@ except
  # assume we have ./static present already
  HTTPROOT="/var/myslice-f4f"
  # the place to store local data, like e.g. the sqlite db
--DATAROOT="/var/unfold"
++DATAROOT="/Users/moray/Sites/upmc/myslice"
  # if not there, then we assume it's from a devel tree
  if not os.path.isdir (os.path.join(HTTPROOT,"static")):
      HTTPROOT=ROOT
diff --combined portal/actions.py
@@@ -1,17 -1,19 +1,19 @@@
- 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, PendingProject
+ 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
++from portal.models                  import PendingUser, PendingSlice, PendingAuthority, PendingProject
+ from unfold.page                    import Page
  import json
  
- from django.contrib.auth.models  import User
- from django.contrib.sites.models import Site
- from django.contrib.auth        import get_user_model
- from django.template.loader     import render_to_string
- from django.core.mail           import EmailMultiAlternatives, send_mail
+ from django.contrib.auth.models     import User
+ from django.contrib.sites.models    import Site
+ from django.contrib.auth            import get_user_model
+ from django.template.loader         import render_to_string
+ from django.core.mail               import EmailMultiAlternatives, send_mail
  
- from myslice.theme              import ThemeView
- from myslice.configengine       import ConfigEngine
+ from myslice.theme                  import ThemeView
+ from myslice.configengine           import ConfigEngine
  
  
  theme = ThemeView()
@@@ -28,7 -30,7 +30,7 @@@ import activity.slic
  def authority_get_pis(request, authority_hrn):
  
      # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
-     query = Query.get('authority').filter_by('authority_hrn', '==', authority_hrn).select('pi_users')
+     query = Query.get('myslice:authority').filter_by('authority_hrn', '==', authority_hrn).select('pi_users')
      results = execute_admin_query(request, query)
      print "authority_get_pis = %s" % results
      # NOTE: temporarily commented. Because results is giving empty list. 
@@@ -172,19 -174,26 +174,26 @@@ def clear_user_creds(request, user_emai
          return None
  
  def is_pi(wsgi_request, user_hrn, authority_hrn):
-     # XXX could be done in a single query !
-     # seauthorities from user where user_hrn == "ple.upmc.jordan_auge"
-     # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
-     query = Query.get('myslice: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
+     # authorities from user where user_hrn == "ple.upmc.jordan_auge"
+     print "#### actions.py is_pi authority_hrn = ", authority_hrn
+     try:
+         # CACHE PB with fields
+         page = Page(wsgi_request)
+         metadata = page.get_metadata()
+         user_md = metadata.details_by_object('user')
+         user_fields = [column['name'] for column in user_md['column']]
+         
+         # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
+         query  = Query().get('myslice:user').select(user_fields).filter_by('user_hrn','==',user_hrn)
+         #query = Query.get('myslice:user').filter_by('user_hrn', '==', user_hrn).select('pi_authorities')
+         results = execute_query(wsgi_request, query)
+         print "is_pi results = ", results
+         for user_detail in results:
+             if authority_hrn in user_detail['pi_authorities']:
+                 return True
+     except Exception,e:
+         print "Exception in actions.py in is_pi %s" % e
+     return False
      
  # SFA get record
  
@@@ -340,16 -349,6 +349,16 @@@ def make_request_slice(slice)
      request['purpose'] = slice.purpose
      return request
  
 +def make_request_project(project):
 +    request = {}
 +    request['type'] = 'project'
 +    request['user_hrn'] = project.user_hrn
 +    request['timestamp'] = project.created
 +    request['authority_hrn'] = project.authority_hrn
 +    request['project_name'] = project.project_name
 +    request['purpose'] = project.purpose
 +    return request
 +
  def make_request_authority(authority):
      request = {}
      request['type']                  = 'authority'
      request['timestamp']             = authority.created
      return request
  
 -def make_requests(pending_users, pending_slices, pending_authorities):
 +def make_requests(pending_users, pending_slices, pending_authorities, pending_projects):
      requests = []
      for user in pending_users:
          requests.append(make_request_user(user))
          requests.append(make_request_slice(slice))
      for authority in pending_authorities:
          requests.append(make_request_authority(authority))
 +    for project in pending_projects:
 +        requests.append(make_request_project(project))
      return requests   
  
  def get_request_by_id(ids):
@@@ -407,33 -404,26 +416,33 @@@ def get_requests(authority_hrns=None)
          pending_users  = PendingUser.objects.filter(status__iexact = 'True')
          pending_slices = PendingSlice.objects.all()
          pending_authorities = PendingAuthority.objects.all()
 +        pending_projects = PendingProject.objects.all()
 +        print "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" , pending_projects
      else:
          pending_users  = PendingUser.objects
          pending_slices = PendingSlice.objects
          pending_authorities = PendingAuthority.objects
 +        pending_projects = PendingProject.objects
          from django.db.models import Q
          list_user_Q = list()
          list_slice_Q = list()
          list_auth_Q = list()
 +        list_proj_Q = list()
          for hrn in authority_hrns:
              list_user_Q.append(Q(authority_hrn__startswith=hrn, status__iexact = 'True'))
              list_slice_Q.append(Q(authority_hrn__startswith=hrn))
              list_auth_Q.append(Q(site_authority__startswith=hrn))
 +            list_proj_Q.append(Q(authority_hrn__startswith=hrn))
 +            print "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" , list_proj_Q
              print "startswith hrn = ",hrn
          from operator import __or__ as OR
          pending_users        = pending_users.filter(reduce(OR, list_user_Q))
          pending_slices       = pending_slices.filter(reduce(OR, list_slice_Q))
          pending_authorities  = pending_authorities.filter(reduce(OR, list_auth_Q))
 +        pending_projects     = pending_projects.filter(reduce(OR, list_auth_Q))
          #pending_authorities  = pending_authorities.all() #filter(reduce(OR, list_Q))
  
 -    return make_requests(pending_users, pending_slices, pending_authorities)
 +    return make_requests(pending_users, pending_slices, pending_authorities, pending_projects)
  
  # XXX Is it in sync with the form fields ?
  
@@@ -713,9 -703,16 +722,16 @@@ def create_slice(wsgi_request, request)
      # 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()
-     
+    
+     # CACHE PB with fields
+     page = Page(wsgi_request)
+     metadata = page.get_metadata()
+     user_md = metadata.details_by_object('user')
+     user_fields = [column['name'] for column in user_md['column']]
      # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
-     user_query  = Query().get('myslice:user').select('user_hrn','user_email').filter_by('user_hrn','==',user_hrn)
+     #user_query  = Query().get('myslice:user').select('user_hrn','user_email').filter_by('user_hrn','==',user_hrn)
+     user_query  = Query().get('myslice:user').select(user_fields).filter_by('user_hrn','==',user_hrn)
      user_details_sfa = execute_admin_query(wsgi_request, user_query)
      if not user_details_sfa:
          raise Exception, "User %s doesn't exist, validate user before validating slice" % user_hrn
@@@ -802,42 -799,6 +818,42 @@@ def create_pending_slice(wsgi_request, 
      except Exception, e:
          print "Failed to send email, please check the mail templates and the SMTP configuration of your server"
  
 +
 +def create_pending_project(wsgi_request, request):
 +    """
 +    """
 +
 +    # Insert an entry in the PendingProject table
 +    s = PendingProject(
 +        project_name    = request['project_name'],
 +        user_hrn        = request['user_hrn'],
 +        authority_hrn   = request['authority_hrn'],
 +        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)
 +#         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
  #-------------------------------------------------------------------------------
diff --combined portal/models.py
@@@ -96,3 -96,3 +96,10 @@@ class PendingSlice(models.Model)
      type_of_nodes   = models.TextField(default='NA')
      purpose         = models.TextField(default='NA')
      created         = models.DateTimeField(auto_now_add = True)
++    
++class PendingProject(models.Model):
++    project_name    = models.TextField()
++    user_hrn        = models.TextField()
++    authority_hrn   = models.TextField(null=True)
++    purpose         = models.TextField(default='NA')
++    created         = models.DateTimeField(auto_now_add = True)
  from django.shortcuts           import render
  from django.contrib.sites.models import Site
  
--
--from unfold.page                import Page
--
  from manifold.core.query        import Query
  from manifoldapi.manifoldapi    import execute_admin_query, execute_query
  
--from portal.actions             import is_pi, create_slice, create_pending_slice, clear_user_creds
--#from portal.forms               import SliceRequestForm
  from unfold.loginrequired       import LoginRequiredAutoLogoutView
--from ui.topmenu                 import topmenu_items_live, the_user
++
++from portal.actions import create_pending_project
++
++from portal.models import PendingProject
  
  from myslice.theme import ThemeView
  
  import json, time, re
  
--import activity.user
--
--class ProjectRequestView (LoginRequiredAutoLogoutView, ThemeView):
++class ProjectRequestView(LoginRequiredAutoLogoutView, ThemeView):
      template_name = 'projectrequest_view.html'
      
--    # because we inherit LoginRequiredAutoLogoutView that is implemented by redefining 'dispatch'
--    # we cannot redefine dispatch here, or we'd lose LoginRequired and AutoLogout behaviours
--    def post (self, request):
--        return self.get_or_post (request, 'POST')
++    def getAuthorities(self, request):
++        authorities_query = Query.get('authority').select('name', 'authority_hrn')
++        authorities = execute_admin_query(request, authorities_query)
++        if authorities is not None:
++            authorities = sorted(authorities, key=lambda k: k['authority_hrn'])
++            authorities = sorted(authorities, key=lambda k: k['name'])
++        return authorities
++    
++    def getUserAuthority(self, request):
++        # Get user_email (XXX Would deserve to be simplified)
++        user_query  = Query().get('local:user').select('email','config')
++        user_details = execute_query(request, user_query)
++        for user_detail in user_details:
++            user_config = json.loads(user_detail['config'])
++            user_authority = user_config.get('authority','N/A')
++        return user_authority
++    
++    def getUserHrn(self, request):
++        user_hrn = None
++        
++        account_query  = Query().get('local:account').select('user_id','platform_id','auth_type','config')
++        account_details = execute_query(request, account_query)
++
++        platform_query  = Query().get('local:platform').select('platform_id','platform','gateway_type','disabled')
++        platform_details = execute_query(request, platform_query)
++        
++        # getting user_hrn from local:account
++        for account_detail in account_details:
++            for platform_detail in platform_details:
++                if platform_detail['platform_id'] == account_detail['platform_id']:
++                    # taking user_hrn only from myslice account
++                    # NOTE: we should later handle accounts filter_by auth_type= managed OR user
++                    if 'myslice' in platform_detail['platform']:
++                        account_config = json.loads(account_detail['config'])
++                        user_hrn = account_config.get('user_hrn','N/A')
++        return user_hrn        
++                   
++    def post(self, request):
++        return self.handle_request(request, 'POST')
  
--    def get (self, request):
--        return self.get_or_post (request, 'GET')
++    def get(self, request):
++        return self.handle_request(request, 'GET')
  
--    def get_or_post  (self, wsgi_request, method):
++    def handle_request(self, wsgi_request, method):
++        errors = []
++        authority_hrn = None
++        authority_name = None
++        
++        user_hrn = self.getUserHrn(wsgi_request)
++        
++        authorities = self.getAuthorities(wsgi_request)
++        
++        user_authority = self.getUserAuthority(wsgi_request)
++        
++        # getting the org from authority
++        for authority in authorities:
++            if authority['authority_hrn'] == user_authority:
++                authority_name = authority['name']
++        
++        if method == 'POST' :
++           
++            post = {
++                'user_hrn'          : user_hrn,
++                'authority_hrn'     : wsgi_request.POST.get('authority_name', ''),
++                'project_name'      : wsgi_request.POST.get('project_name', ''),
++                'purpose'           : wsgi_request.POST.get('purpose', ''),
++            }
++        
++#             # create slice_hrn based on authority_hrn and slice_name
++#             #             slice_name = slice_request['slice_name']
++#             req_slice_hrn = authority_hrn + '.' + slice_name
++#             # comparing requested slice_hrn with the existing slice_hrn 
++#             slice_query  = Query().get('myslice:slice').select('slice_hrn','parent_authority').filter_by('parent_authority','==',authority_hrn)
++#             slice_details_sfa = execute_admin_query(wsgi_request, slice_query)
++#             for _slice in slice_details_sfa:
++#                 if _slice['slice_hrn'] == req_slice_hrn:
++#                     errors.append('Slice already exists. Please use a different slice name.')
++            
++
++            # What kind of slice name is valid?
++            if (post['project_name'] is None or post['project_name'] == ''):
++                errors.append('Project name is mandatory')
++            
++            if (re.search(r'^[A-Za-z0-9_]*$', post['project_name']) == None):
++                errors.append('Project name may contain only letters, numbers, and underscore.')
++            
++            if (post['authority_hrn'] is None or post['authority_hrn'] == ''):
++                errors.append('Organization is mandatory')
++    
++            if (post['purpose'] is None or post['purpose'] == ''):
++                errors.append('Experiment purpose is mandatory')
++
++            if not errors:
++                create_pending_project(wsgi_request, post)
++        
++        # retrieves the pending projects list
++        pending_projects = PendingProject.objects.all().filter(user_hrn=user_hrn)
++                    
++        env = {
++               'errors':        errors,
++               'username':      wsgi_request.user,
++               'theme':         self.theme,
++               'authorities':   authorities,
++               'authority_hrn': user_authority,
++               'pending_projects': pending_projects,
++        }
++        return render(wsgi_request, self.template, env)
++    
++        
++    
          """
          """
          errors = []
          #
          platform_query  = Query().get('local:platform').select('platform_id','platform','gateway_type','disabled')
          platform_details = execute_query(wsgi_request, platform_query)
++        
          user_hrn = None
          # getting user_hrn from local:account
          for account_detail in account_details:
  
  
          # Page rendering
--        page = Page(wsgi_request)
--        page.add_js_files  ( [ "js/jquery.validate.js", "js/jquery-ui.js" ] )
--        page.add_css_files ( [ "https://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" ] )
--        page.expose_js_metadata()
++        page = Page(wsgi_request)
++        page.add_js_files  ( [ "js/jquery.validate.js", "js/jquery-ui.js" ] )
++        page.add_css_files ( [ "https://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" ] )
++        page.expose_js_metadata()
  
          if method == 'POST':
              # The form has been submitted
  
              # get the domain url
--            current_site = Site.objects.get_current()
--            current_site = current_site.domain
++            current_site = Site.objects.get_current()
++            current_site = current_site.domain
              
              # getting the authority_hrn from the selected organization
              for authority in authorities:
              }
              
              # create slice_hrn based on authority_hrn and slice_name
--            slice_name = slice_request['slice_name']
++            slice_name = slice_request['slice_name']
              req_slice_hrn = authority_hrn + '.' + slice_name
              # comparing requested slice_hrn with the existing slice_hrn 
              slice_query  = Query().get('myslice:slice').select('slice_hrn','parent_authority').filter_by('parent_authority','==',authority_hrn)
  
          template_env = {
              'username': wsgi_request.user.email,
--            'topmenu_items': topmenu_items_live('Request a slice', page),
              'errors': errors,
              'slice_name': slice_name,
              'purpose': purpose,
@@@ -31,6 -31,6 +31,20 @@@ h3 
      color:#201E62;
  }
  
++input[type=text], input[type=password], input[type=email], input[type=tel], input[type=number] {
++    min-width:260px;
++    padding:6px;
++    border:1pt solid #CCCCCC;
++    vertical-align:bottom;
++    border-radius:0;
++}
++
++textarea {
++    padding:6px;
++    border:1pt solid #CCCCCC !important;
++    border-radius:0 !important;
++}
++
  div.wrapper {
      width:980px;
      margin:0 auto;
@@@ -174,6 -174,29 +174,29 @@@ var myslice = 
                    $.post("/rest/myslice:user/",{'filters':{'user_hrn':'$user_hrn'}}, function( data ) {
                        if (data.length > 0) {
                            localStorage.setItem('user', JSON.stringify(data[0]));
+                     projects = [];
+                           $.each(data[0].pi_authorities, function(idx, auth) {
+                         // PI on projects
+                         if(auth.split('.').length>2){
+                             if($.inArray(auth,projects) == -1){
+                                 projects.push(auth);
+                             }
+                         }else if (auth.split('.').length>1){
+                         // PI on authorities
+                             // What are the projects under this authority?
+                             $.post("/rest/myslice:authority/",{'fields':['authority_hrn'],'filters':{'authority_hrn':'CONTAINS'+auth}}, function( data ) {
+                                       $.each(data, function(idx, project) {
+                                     console.log(project.authority_hrn);
+                                     if($.inArray(project.authority_hrn,projects) == -1){
+                                         projects.push(project.authority_hrn);
+                                     }
+                                 });
+                             });
+                         }else{
+                             console.log("admin account - we don't list all from root");
+                         }
+                     });
+                     localStorage.setItem('projects', JSON.stringify(projects));
                      myslice.loadSlices(data[0].slices);
                      if(isFunction(fn)){
                          fn();
          }
  
        },
-       loadProjects: function(fn) {
-           var u = localStorage.getItem('user');
-           if (u !== 'undefined') {
-             var user = JSON.parse(u);
-             var projects = localStorage.getItem('projects');
-             if($.isEmptyObject(projects)){
-                 if($.isEmptyObject(user) || $.isEmptyObject(user.parent_authority)){
-                       $.post("/rest/myslice:user/",{'filters':{'user_hrn':'$user_hrn'},'fields':['parent_authority']}, function( data ) {
-                         parent_authority = data[0].parent_authority;
-     
-                     });
-                 }else{
-                     parent_authority = user.parent_authority;
-                 }
-                 // REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
-                 $.post("/rest/myslice:authority/",{'fields':['authority_hrn'],'filters':{'authority_hrn':'CONTAINS'+parent_authority}}, function( data ) {
-                     localStorage.setItem('projects', JSON.stringify(data));
-                     if(isFunction(fn)){
-                         fn();
-                     }
-                 });
-             }else{
-                 if(isFunction(fn)){
-                     fn();
-                 }
-             }
-         }
  
-       },
 +
      getSlices: function(name) {
        
      },
@@@ -4,7 -4,7 +4,7 @@@
        <li><a href="/slice/{{ slice }}#testbeds">Testbeds</a></li>
        <li class="active"><a class="link" href="/resources/{{ slice }}">Resources</a></li>
        <li><a href="/slice/{{ slice }}#users">Users</a></li>
--      <!--<li><a href="/slice/{{ slice }}#statistics">Statistics</a></li> -->
++      <li><a href="/slice/{{ slice }}#statistics">Statistics</a></li>
        <li><a href="/slice/{{ slice }}#measurements">Measurements</a></li>
        <li><a href="/slice/{{ slice }}#experiment" data-toggle="tab">Experiment</a></li>
        <li><a href="/slice/{{ slice }}#sla">SLA</a></li>
@@@ -15,7 -15,7 +15,7 @@@
        <li class="testbeds"><a href="#testbeds">Testbeds</a></li>
        <li><a class="link" href="/resources/{{ slice }}">Resources</a></li>
        <li class="users"><a href="#users">Users</a></li>
--<!--  <li class="statistics"><a href="#statistics">Statistics</a></li> -->
++      <li class="statistics"><a href="#statistics">Statistics</a></li>
        <li class="measurements"><a href="#measurements">Measurements</a></li>
        <li class="experiment"><a href="#experiment" data-toggle="tab">Experiment</a></li>
        <li class="sla"><a href="#sla" data-toggle="tab">SLA</a></li>
  {% load i18n %}
  
  {% block content %}
--      <div class="row">
--              <div class="col-md-12">
--                       <div class="breadcrumbs">
--                               Experiment &nbsp;>&nbsp; Request a new Project or Join an existing one
--                       </div>
--              </div>
--      </div>
++<br />
++<div class="row">
++    <div class="col-md-12">
++        <ul class="nav nav-tabs nav-section">
++            <li class="active"><a href="#existing">Join existing Project</a></li>
++            <li><a href="#new">Create new Project</a></li>
++            
++        </ul>
++    </div>
++</div>
  
--      {% if errors %}
--      <div class="row">
--              <div class="col-md-12">
--              <ul class="error">
--                {% for error in errors %}
--                <li>{{ error }}</li>
--                {% endfor %}
--              </ul>
--              </div>
--      </div>
--      {% endif %}
--      
--      <div class="row">
--              <div class="col-md-8 el">
--                      <form role="form" method="post">
--                      {% csrf_token %}
--                        <div class="form-group" style="display:none">
--                          <input type="email" class="form-control" id="email" style="width:300px" value="{{ email }}" readonly="readonly">
--                        </div>
--                        <div class="form-group">
--                              <select id="org_name" name="org_name" class="form-control" style="width:590px" value="{{ organization }}" required> 
--                {% if authorities %}
--                    {% for authority in authorities %}
--                        {% if authority.name %}
--                            <option value="{{ authority.authority_hrn }}">{{authority.name}}</option>
--                        {% else %}
--                            <option value="{{ authority.authority_hrn }}">{{authority.authority_hrn}}</option>
--                        {% endif %}
--                    {% endfor %} 
--                {% endif %}
--                </select>
--                        </div>
--                        <div class="form-group">
--                <input type="text">New Project</input>
--                        </div>
--                        <div class="form-group">
--                <input type="text">Existing Project</input>
--                        </div>
--                        <div class="form-group">
--                              <textarea id="purpose" name="purpose" class="form-control" rows="6" placeholder="Project purpose" style="width:300px" 
--                              title="Purpose of your project (informative)" required="required">{{ purpose }}</textarea>
--                        </div>
--                        {%if 'is_pi'  in pi %}        
--                        <button type="submit" id=submit_pi class="btn btn-onelab"><span class="glyphicon glyphicon-plus"></span> Create slice</button>
--                        {%else%}
--                        <button type="submit" class="btn btn-onelab"><span class="glyphicon glyphicon-plus"></span> Request slice</button>
--                        {%endif%}     
--                      </form>
--      
--              </div>
--      </div>
++{% if errors %}
++<div class="row">
++    <div class="col-md-12">
++    <ul class="error">
++      {% for error in errors %}
++      <li>{{ error }}</li>
++      {% endfor %}
++    </ul>
++    </div>
++</div>
++{% endif %}
++
++<div class="container tab-content">
++    
++      <div class="tab-pane active" id="existing"> 
++        <div class="row">
++            <div class="col-md-6">
++                 <h3>Join an existing Project</h3>
++            </div>
++            <div class="col-md-6">
++                 <h3>List of projects you are part of</h3>
++            </div>
++        </div>
++        <div class="row">
++            <div class="col-md-6">
++                <form role="form" method="post">
++                {% csrf_token %}
++                <select id="projects"></select> <button type="submit" class="btn">Join</button>
++                </form>
++            </div>
++            <div class="col-md-6">
++                <table class="table project-list">
++                    {% for pending in pending_projects %}
++                    <tr><td>(PENDING) {{ pending.project_name }}</td><td>{{ pending.authority_hrn }}</td><td>{{ pending.created|date:"d/m/Y" }}</td></tr>
++                    {% endfor %}
++                </table>
++            </div>
++        </div>
++    </div>
++    
++    <div class="tab-pane" id="new"> 
++        <div class="row">
++            <div class="col-md-12">
++                 <h3>Create a new Project</h3>
++            </div>
++        </div>
++    
++        
++        <div class="row">
++            <div class="col-md-12">
++                <form role="form" method="post" action="/portal/project_request">
++                {% csrf_token %}
++                  <div class="form-group">
++                    <input type="text" name="project_name" value="" placeholder="Name" required>
++                  </div>
++                  <div class="form-group">
++                    <select id="org_name" name="authority_name" class="form-control" style="width:590px" value="{{ organization }}" required> 
++                    {% if authorities %}
++                        {% for authority in authorities %}
++                            {% if authority.name %}
++                                <option value="{{ authority.authority_hrn }}">{{authority.name}}</option>
++                            {% else %}
++                                <option value="{{ authority.authority_hrn }}">{{authority.authority_hrn}}</option>
++                            {% endif %}
++                        {% endfor %} 
++                    {% endif %}
++                    </select>
++                  </div>
++                  
++                  
++                  <div class="form-group">
++                    <textarea id="purpose" name="purpose" class="form-control" rows="6" placeholder="Description" style="width:300px" title="Purpose of your project (informative)" required="required"></textarea>
++                  </div>
++                  <button type="submit" class="btn btn-onelab"><span class="glyphicon glyphicon-plus"></span> Send Request</button>
++                </form>
++        
++            </div>
++        </div>
++    </div>
++    
++</div>
                
  <script>
--jQuery(document).ready(function(){
++$(document).ready(function() {
++    var myprojects = localStorage.getItem('projects');
++    console.log(myprojects);
++    if (myprojects) {
++        
++    } else {
++        $('.project-list').html('<tr><td>no projetcs</td></tr>');
++    }
++    
++    $('.nav-tabs a').click(function (e) {
++        e.preventDefault();
++        $(this).tab('show');
++    });
++    $.post("/rest/myslice:authority/",{'fields':['authority_hrn','pi_users'],'filters':{'authority_hrn':'CONTAINS{{ authority_hrn }}' }}, function( data ) {
++       
++        var projects = [];
++        project_row = "<option value=''> - </option>";
++        projects.push(project_row);
++       
++        $.each( data, function( key, val ) {
++            console.log(val);
++            project_row = "<option value='"+val.authority_hrn+"'>"+val.authority_hrn+"</option>";
++            projects.push(project_row);
++        });
++        $("#projects").html(projects.join( "" ));
++    });
  /*
        
        $("#authority_hrn").load("/rest/user/", {"fields" : ["parent_authority"], "filters": {"user_hrn": "{{ user_hrn }}"}}, function(data) {
                localStorage.clear();
        });
        // auto-complete the form
--    jQuery("#org_name").combobox();
++    //jQuery("#org_name").combobox();
  
  });
  </script>
                  <b>{{request.first_name}} {{request.last_name}}</b> &lt;<a href="mailto:{{request.email}}">{{request.email}}</a>&gt;
              {% elif request.type == 'slice' %}
              <b>{{request.slice_name}}</b> -- Number of nodes: {{request.number_of_nodes}} -- Type of nodes: {{request.type_of_nodes}} -- Purpose: {{request.purpose}}
++            {% elif request.type == 'project' %}
++            <b>{{request.project_name}}</b>  -- {{ request.user_hrn }} -- Purpose: {{request.purpose}}
              {% else %}
              <b>{{request.site_name}}</b> ({{request.site_authority}}) -- {{request.address_city}}, {{request.address_country}}
              {% endif %}
                {% else %}
                    {% if request.type == 'slice' %}
                Slice name: {{request.slice_name}} -- Number of nodes: {{request.number_of_nodes}} -- Type of nodes: {{request.type_of_nodes}} -- Purpose: {{request.purpose}}
++                 {% elif request.type == 'project' %}
++            <b>{{request.project_name}}</b>  -- {{ request.user_hrn }} -- Purpose: {{request.purpose}}   
                    {% else %} {# authority #}
                Authority name: {{request.site_name}} -- authority_hrn: {{request.site_authority}} -- City: {{request.address_city}} -- Country: {{request.address_country}}
                    {% endif %}
                        {% else %}
                            {% if request.type == 'slice' %}
                        Slice name: {{request.slice_name}} -- Number of nodes: {{request.number_of_nodes}} -- Type of nodes: {{request.type_of_nodes}} -- Purpose: {{request.purpose}}
++                          {% elif request.type == 'project' %}
++                    <b>{{request.project_name}}</b>  -- {{ request.user_hrn }} -- Purpose: {{request.purpose}}
                            {% else %} {# authority #}
                        Authority name: {{request.site_name}} -- authority_hrn: {{request.site_authority}} -- City: {{request.address_city}} -- Country: {{request.address_country}}
                            {% endif %}
@@@ -54,9 -54,9 +54,9 @@@ $(document).ready(function() 
                        <ul class="nav nav-tabs">
                          <li class="active"><a href="#resourcelist" role="tab" data-toggle="tab">Table</a></li>
                          <li> <a href="#resourcemap" role="tab" data-toggle="tab">Map</a></li>
--              <li> <a href="#openflowcontroller" role="tab" data-toggle="tab">OpenFlow Controller</a></li>
++              <!-- <li> <a href="#openflowcontroller" role="tab" data-toggle="tab">OpenFlow Controller</a></li>
                <li> <a href="#resourceflowspace" role="tab" data-toggle="tab">Flowspace</a></li>
--                        <li> <a href="#resourcescheduler" role="tab" data-toggle="tab">Scheduler</a></li>
++                        <li> <a href="#resourcescheduler" role="tab" data-toggle="tab">Scheduler</a></li> -->
                        </ul>
                        </div>
                </div>