Merge branch 'onelab' of ssh://git.onelab.eu/git/myslice into onelab
authorLoic Baron <loic.baron@lip6.fr>
Fri, 20 Feb 2015 10:54:22 +0000 (11:54 +0100)
committerLoic Baron <loic.baron@lip6.fr>
Fri, 20 Feb 2015 10:54:22 +0000 (11:54 +0100)
16 files changed:
README
myslice/myslice.ini.onelab [new file with mode: 0644]
myslice/settings.py
myslice/urls.py
plugins/apply/templates/apply.html
plugins/filter_status/templates/filter_status.html
plugins/testbeds/static/js/testbeds.js
plugins/testbeds/templates/testbeds.html
portal/static/css/fed4fire.css
portal/static/css/onelab.css
portal/static/css/smartfire.css
portal/static/icons/IoTLab.png [new file with mode: 0644]
portal/static/icons/Mobile.png [new file with mode: 0644]
portal/static/icons/PlanetLab.png [new file with mode: 0644]
portal/static/icons/Wireless.png [new file with mode: 0644]
portal/templates/servicedirectory.html

diff --git a/README b/README
index eae4973..7eb5c8c 100644 (file)
--- a/README
+++ b/README
@@ -1,48 +1,66 @@
 This file documents the contents of this module
 change
-Last update 4 FEB. 2015
+Last update 20 FEB. 2015
 
-See the devel/ subdir for more devel-oriented doc.
+Installation
+=================================================================
+OS
+==
+Download a vm of Debian GNU/Linux 7.5 (wheezy) x64
 
-==================== 1 minute howto
+PYTHON DEPENDENCIES
+=====================
+sudo apt-get install python-pip or sudo easy_install pip==1.4.1
+sudo apt-get install python-dev (for paramiko and pyOpenSSL)
+sudo apt-get install libffi-dev (for pyOpenSSL)
 
-*  REQUIREMENTS  is to have python + django (1.5.2) installed django
-** should be straightforward
-** see devel/django-install.txt in case of trouble
-$ apt-get install python-pip or sudo easy_install pip==1.4.1
-$ pip install django=="1.5.2
+$ pip install django=="1.5.2"
 $ apt-get install python-django-south
 $ pip install requests
 $ pip install djangorestframework
 $ pip install django-celery
 $ pip install geopy
 $ pip install paramiko
+$ pip install pyparsing
+$ pip install python-dateutil
+$ pip instal pyOpenSSL
 
-* git clone git://git.onelab.eu/myslice.git
--- or --
-* git clone ssh://yourlogin@git.onelab.eu/git/myslice.git
+MYSLICE
+=======
+git clone ssh://yourlogin@git.onelab.eu/git/myslice.git
+cd myslice
+git checkout onelab
 
-* edit/create myslice/myslice.ini and enter the details of your manifold backend
+edit/create myslice/myslice.ini and enter the details of your manifold backend
+
+mkdir /var/unfold
+copy unfold.sqlite3 to /var/unfold
 
-$ apt-get install python-django-south
-* init django
-** when django prompts for creating an admin account, create it and 
-** keep the username and password safe
 $ ./manage.py syncdb
 $ ./manage.py migrate
 
-* gather static files
-$ ./manage.py collectstatic 
--- or --
-$ ./manage.py collectstatic --noinput
--- or --
-$ make static (which is a shorthand for cleaning up and run manage collectstatic --noinput)
+use the unfold.sqlite3 i gave to u
+
+$ make redo
+$ ./devel/server-loop.sh
+
+MANIFOLD
+==========
+git clone git://git.onelab.eu/manifold.git
+cd manifold
+git checkout devel
+make && make install
+
+SFA
+===
+$ git clone -b geni-v3 git://git.onelab.eu/sfa.git
+$ cd sfa 
+$ git checkout geni-v3
 
-* gather templates files 
-  for now we still seem to rely on a make-based templates-collection process
-  that creates templates/ 
-$ make templates [$ make redo (each time when you pull, do that and restart the server)]
+$ make version
+$ python ./setup.py install
 
+=====================================================================
 
 ## Whenever doing a git pull the following operations are recommended:
 
diff --git a/myslice/myslice.ini.onelab b/myslice/myslice.ini.onelab
new file mode 100644 (file)
index 0000000..1415031
--- /dev/null
@@ -0,0 +1,2 @@
+[manifold]
+url = http://portal.onelab.eu:7080/
index bd1474b..10b3953 100644 (file)
@@ -1,5 +1,7 @@
 # Django settings for unfold project.
 
+from __future__ import print_function
+
 import os.path
 
 import djcelery
@@ -13,7 +15,9 @@ except:
     building=True
 
 DEBUG = True
-TEMPLATE_DEBUG = DEBUG
+
+# show the various settings as we go
+DEBUG_SETTINGS = False
 
 # compute ROOT from where this file is installed
 # should fit every need including developers
@@ -48,6 +52,10 @@ except:
 HTTPROOT="/var/myslice-f4f"
 # the place to store local data, like e.g. the sqlite db
 DATAROOT="/var/unfold"
+if not os.path.isdir(DATAROOT):
+    print("WARNING: {} is a non-existing directory".format(DATAROOT))
+    print("consequently we assume development mode and re-route DATAROOT to {}".format(ROOT))
+    DATAROOT=ROOT
 # if not there, then we assume it's from a devel tree
 if not os.path.isdir (os.path.join(HTTPROOT,"static")):
     HTTPROOT=ROOT
@@ -55,6 +63,11 @@ if not os.path.isdir (os.path.join(HTTPROOT,"static")):
 if not os.path.isdir(ROOT): raise Exception,"Cannot find ROOT %s for unfold"%ROOT
 if not os.path.isdir(HTTPROOT): raise Exception,"Cannot find HTTPROOT %s for unfold"%HTTPROOT
 
+if DEBUG_SETTINGS:
+    print('ROOT', ROOT)
+    print('DATAROOT', DATAROOT)
+    print('HTTPROOT', HTTPROOT)
+
 # dec 2013 - we currently have 2 auxiliary subdirs with various utilities
 # that we do not wish to package 
 # * sandbox is for plugin developers
@@ -101,6 +114,9 @@ DATABASES = {
     }
 }
 
+if DEBUG_SETTINGS:
+    print('DATABASE NAME',DATABASES['default']['NAME'])
+
 # Local time zone for this installation. Choices can be found here:
 # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
 # although not all choices may be available on all operating systems.
@@ -252,7 +268,7 @@ BROKER_URL = "amqp://myslice:myslice@localhost:5672/myslice"
 
 for aux in auxiliaries:
     if os.path.isdir(os.path.join(ROOT,aux)): 
-        print "Using devel auxiliary",aux
+        print("Using devel auxiliary",aux)
         INSTALLED_APPS.append(aux)
 
 ACCOUNT_ACTIVATION_DAYS = 7 # One-week activation window; you may, of course, use a different value.
index da697cf..ca150a4 100644 (file)
@@ -132,7 +132,7 @@ urls = [
     url(r'^portal/', include('portal.urls')),
 
     # SLA
-    url(r'^sla/', include('sla.urls')),
+#    url(r'^sla/', include('sla.urls')),
 ]
 
 #this one would not match the convention
index f05af49..9e251b7 100644 (file)
@@ -1,16 +1,18 @@
-<div id={{ domid }}>
-  <!-- Modal - columns selector -->
+<div id="{{ domid }}" class="sl-filter-resources">
+    <button class="btn btn-onelab btn-apply"  id="{{domid}}__apply" data-toggle="modal" data-target="#{{domid}}__apply__window">Apply</button>
+</div> 
+<!-- Modal - columns selector -->
   <div class="modal fade" id="{{domid}}__apply__window" tabindex="-1" role="dialog" aria-labelledby="{{domid}}__apply__label" aria-hidden="true">
     <div class="modal-dialog modal-dialog-large">
       <div class="modal-content">
         <div class="modal-header">
           <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
             <h4 class="modal-title" id="{{domid}}__apply__label">
-                Applying pending changes...                    
+                 Applying pending changes...                
             </h4>
             <div>
-               <img id="applyloading" src="/static/img/loading.gif" /> &nbsp;&nbsp;
-               Please be patient, this operation can take a minute or two.
+                <img id="applyloading" src="/static/img/loading.gif" /> &nbsp;&nbsp;
+                Please be patient, this operation can take a minute or two.
             </div>
         </div>
         <div class="modal-body">
         </div>
       </div>
     </div>
-  </div>
-
-  
-  <!-- Button toolbar -->
-  <button class="btn btn-onelab btn-apply"  id="{{domid}}__apply" data-toggle="modal" data-target="#{{domid}}__apply__window">Apply</button>
-  <!-- <button class="btn btn-default btn-sm" id="{{domid}}__cancel">Cancel</button> -->
-</div> 
+  </div>
\ No newline at end of file
index 8350eb1..3d1c44b 100644 (file)
@@ -1,5 +1,5 @@
-<div id={{ domid }}>
-  <span class="list-group-item-heading sl-resources" style='font-size:inherit;'>View:</span>
+<div id="{{ domid }}" class="sl-filter-resources">
+  <span class="list-group-item-heading sl-resources">View:</span>
   
   <a href="#" 
      class="list-group-item sl-resources active" 
@@ -28,7 +28,7 @@
      title="View resources that you have selected to add to your slice, that require configuration before they can be reserved. Hover you mouse over the symbol next to the checkbox for more details."
      rel='tooltip'>
        Unconfigured
-       <span class="badge" id="badge-unconfigured" style="display:none;"></span></a>
+       <span class="badge" id="badge-unconfigured" style="display:none;"></span>
   </a>
   
   <a href="#" class="list-group-item sl-resources" 
@@ -38,6 +38,6 @@
      title="View pending changes to your slice: resources that you have selected to add, and resources that you have selected to remove. Click on the Apply button to apply those changes, or on the Cancel button to cancel them."
      rel='tooltip'>
        Pending
-       <span class="badge" id="badge-pending" style="display:none;"></span></a>
+       <span class="badge" id="badge-pending" style="display:none;"></span>
   </a>
 </div> 
index e628a67..ba40d00 100644 (file)
                 $scope._testbed_active[facility] = new Object();
             $scope._testbed_active[facility][testbed] = value;
         };
+        
+        $scope.tolower = function(string) {
+            return string.toLowerCase(string);  
+        };
     
         /* Click event */
 
         {
             var selected, prev_selected, num, num_selected, num_prev_selected, filter;
 
-            prev_selected = $.map($scope.facility_names, function(x, i) {
-                return $scope.is_facility_active(x) ? x : null;
-            });
+            // prev_selected = $.map($scope.facility_names, function(x, i) {
+                // return $scope.is_facility_active(x) ? x : null;
+            // });
 
             $scope.set_facility_active(facility, ! $scope.is_facility_active(facility));
-
-            selected = $.map($scope.facility_names, function(x, i) {
-                return $scope.is_facility_active(x) ? x : null;
+            
+            $.each($scope.testbed_names[facility], function(j, testbed_name) {
+                $scope.select_testbed(facility, testbed_name);
             });
-
-            num = $scope.facility_names.length;
-            prev_num_selected = prev_selected.length;
-            num_selected = selected.length;
-
-            if ((prev_num_selected != 0) && (prev_num_selected != num)) {
-                // Remove previous filter
-                filter = ['facility_name', 'included', prev_selected];
-                manifold.raise_event($scope.instance.options.query_uuid, FILTER_REMOVED, filter);
-            }
-
-            if (num_selected != num) {
-                filter = ['facility_name', 'included', selected];
-                manifold.raise_event($scope.instance.options.query_uuid, FILTER_ADDED, filter);
-            }
+            console.log($scope);
+            // selected = $.map($scope.facility_names, function(x, i) {
+                // return $scope.is_facility_active(x) ? x : null;
+            // });
+
+            // num = $scope.facility_names.length;
+            // prev_num_selected = prev_selected.length;
+            // num_selected = selected.length;
+
+            // if ((prev_num_selected != 0) && (prev_num_selected != num)) {
+                // // Remove previous filter
+                // filter = ['facility_name', 'included', prev_selected];
+                // manifold.raise_event($scope.instance.options.query_uuid, FILTER_REMOVED, filter);
+            // }
+// 
+            // if (num_selected != num) {
+                // filter = ['facility_name', 'included', selected];
+                // manifold.raise_event($scope.instance.options.query_uuid, FILTER_ADDED, filter);
+            // }
         };
 
         $scope.select_testbed = function(facility, testbed)
 
         _get_scope : function()
         {
-            return angular.element('[ng-controller=TestbedsCtrl]').scope()
+            return angular.element('[ng-controller=TestbedsCtrl]').scope();
         },
 
 /*
index 296e5ef..755bc35 100644 (file)
@@ -1,34 +1,27 @@
-<div id={{ domid }} ng-controller="TestbedsCtrl">
-
-<div class="list-group-item sl-platform"><span class="list-group-item-heading">Facilities</span></div>
-
-<div ng-repeat="facility_name in facility_names">
-       <a href="#" 
-          class="list-group-item sl-platform"
-          ng-class="{active: is_facility_active(facility_name)}"
-          id="facility-filter_{[{ facility_name }]}"
-          ng-click="select_facility(facility_name)"
-          data-platform="{[{ facility_name }]}">
-       <span class="list-group-item-heading">{[{ facility_name }]}</span>
-       </a>
-       <div ng-repeat="testbed_name in testbed_names[facility_name]">
-               <a href="#" 
-                  class="list-group-item sl-platform"
-                  ng-class="{active: is_testbed_active(facility_name, testbed_name)}"
-                  id="testbeds-filter_{[{ testbed_name }]}"
-                ng-click="select_testbed(facility_name, testbed_name)"
-                  data-platform="{[{ testbed_name }]}">
-               <span class="list-group-item-heading">&nbsp;&nbsp;{[{testbed_name}]}</span>
-               </a>
-       </div>
-</div>
-
-<!--
-<style>
-a.sl-platform  {
-    text-transform: uppercase;
-}
-
-</style>
--->
+<div id="{{ domid }}" class="sl-filter-facilities" ng-controller="TestbedsCtrl">
+    <h4>
+       Facilities
+    </h4>
+    <div>
+        <div class="sl-facilities" ng-repeat="facility_name in facility_names">
+            <a href="#" 
+               class="sl-facility"
+               ng-class="{active: is_facility_active(facility_name)}"
+               id="facility-filter_{[{ facility_name }]}"
+               ng-click="select_facility(facility_name)"
+               data-platform="{[{ facility_name }]}">
+               <img class="sl-image" src="/static/icons/{[{ tolower(facility_name) }]}.png" /> {[{ facility_name }]}
+            </a>
+            <div class="sl-testbeds" ng-repeat="testbed_name in testbed_names[facility_name]">
+                <a href="#" 
+                   class="sl-testbed"
+                   ng-class="{active: is_testbed_active(facility_name, testbed_name)}"
+                   id="testbeds-filter_{[{ testbed_name }]}"
+                   ng-click="select_testbed(facility_name, testbed_name)"
+                   data-platform="{[{ testbed_name }]}">
+                    <input ng-checked="is_testbed_active(facility_name, testbed_name)" type="checkbox">&nbsp;{[{testbed_name}]}
+                </a>
+            </div>
+        </div>
+    </div>
 </div>
index ca827bf..70de2a8 100644 (file)
@@ -30,7 +30,10 @@ h3 {
     font-size:13pt;
     color:#201E62;
 }
-
+input[type=checkbox] {
+  min-width:5px !important;
+  margin-left:0 !important;
+}
 input[type=text], input[type=password], input[type=email], input[type=tel], input[type=number] {
     min-width:260px;
     padding:6px;
@@ -57,7 +60,7 @@ div.wrapper {
 
 
 div.wide {
-    margin:25px auto;
+    margin:0 auto 25px auto;
     padding:0 25px;
 }
 
@@ -382,37 +385,54 @@ ul.nav-resources a {
 div#slice-view {
     margin:0;
 }
-div.list-group-item {
-    border:0;
-    background-color:white;
-    font-weight:bold;
-    padding-left:0;
+
+/* FACILITY/TESTBED filters */
+div.sl-filter-facilities {
+    padding:0 5px;
 }
-a.list-group-item {
-    border:0;
-    background-color:white;
-    padding:3px 0 3px 10px;
-    border-left:2pt white solid;
+div.sl-filter-facilities h4 {
+    margin-bottom:15px;
+    
 }
-a.list-group-item.active, a.list-group-item.active:hover {
-    font-weight: bold;
+img.sl-image {
+    margin:0 5px 5px 0;
+    padding:0;
+    vertical-align:middle;
+}
+a.sl-facility {
+    color:gray;
+    text-decoration:none;
+}
+a.sl-facility:hover {
+    color:#342961;
+}
+a.sl-facility.active {
     color:black;
-    background-color:transparent;
-    border-left:2pt blue solid;
+    text-decoration:none;
 }
-a.list-group-item.active:hover {
-    background-color:#dddddd;
+a.sl-facility::before {
+    content: " ";
 }
-a.list-group-item:hover {
-    border-left:2pt blue solid;
+div.sl-facilities {
+    border-bottom:#CCCCCC 1px solid;
+    padding-bottom:15px;
+    margin-bottom:15px;
 }
-a.list-group-item p.list-group-item-text {
-    font-size:9pt;
-    font-style:italic;
-    font-weight: normal;
-    color: black !important;
+div.sl-facilities:last-child {
+    border:0;
+}
+a.sl-testbed {
+    color:gray;
+    text-decoration:none;
+    margin-left:25px;
+    margin-bottom:5px;
+}
+a.sl-testbed:hover {
+    color:#342961;
+}
+a.sl-testbed.active {
+    color:black;
 }
-
 div#slice-info {
     margin-top:25px;
 }
@@ -502,12 +522,51 @@ div.dataTables_filter label{
     width:400px;
 }
 
+div.sl-filter-resources {
+    margin:10px 0;
+    text-align:center;
+}
+span.sl-resources {
+    font-size:9pt;
+    color:gray;
+}
+a.sl-resources {
+    font-size:9pt;
+    border:0;
+    padding:2px 8px;
+    margin:0 5px;
+    -moz-border-radius: 2px;
+    border-radius: 2px;
+    text-align: center;
+}
+a.sl-resources.active, a.sl-resources.active:hover, a.sl-resources.active:focus {
+    border:0;
+    padding:2px 8px;
+    -moz-border-radius: 2px;
+    border-radius: 2px;
+    background-color:#FFA500;
+    color:#000000;
+}
+a.sl-resources:first-child {
+}
+button.btn-apply {
+    background-color:#FFA500;
+    border-bottom: 2pt solid #FFCA00;
+    color:black;
+    font-size:13px;
+    padding:2px 8px;
+    margin:0 5px;
+    -moz-border-radius: 2px;
+    border-radius: 2px;
+    text-align: center;
+}
+
 /**/
 .header {
   -moz-box-shadow:    0 0 1px rgba(82,82,82,0.6);
   -webkit-box-shadow: 0 0 1px rgba(82,82,82,0.6);
   box-shadow:         0 0 1px rgba(82,82,82,0.6);
-  height:61px;
+  height:60#px;
   background-color:white;
 }
 div.navigation {
@@ -607,7 +666,11 @@ div.dataTables_filter label{
     float:left;
     width:400px;
 }
-
+div.breadcrumbs {
+    margin:15px 0;
+    color:gray;
+    font-size:10pt;
+}
 /* Service Directory */
 
 div#appservices div.row {
index 27c6b47..45f5efc 100644 (file)
@@ -82,6 +82,10 @@ span.version {
     font-size:8pt;
     color:#888888;
 }
+input[type=checkbox] {
+  min-width:5px !important;
+  margin-left:0 !important;
+}
 input[type=text], input[type=password], input[type=email], input[type=tel], input[type=number], select, option {
     min-width:260px;
     padding:6px;
@@ -378,71 +382,87 @@ div.container-resource, div.container-slice {
 div#slice-view {
     margin:0;
 }
-div.list-group-item {
-    border:0;
-    -moz-border-radius: 0;
-    border-radius: 0;
-    background-color:white;
-    font-weight:bold;
-    padding-left:0;
+
+div.sl-filter-facilities {
+    padding:0 5px;
 }
-a.list-group-item {
-    -moz-border-radius: 0;
-    border-radius: 0;
-    border:0;
-    background-color:white;
-    padding:3px 2px 3px 10px;
-    border-left:2pt white solid;
+div.sl-filter-facilities h4 {
+    margin-bottom:15px;
+    
+}
+img.sl-image {
+    margin:0 5px 5px 0;
+    padding:0;
+    vertical-align:middle;
+}
+a.sl-facility {
+    color:gray;
+    text-decoration:none;
 }
-a.list-group-item.active, a.list-group-item.active:hover, a.list-group-item.active:focus {
-    -moz-border-radius: 0;
-    border-radius: 0;
-    font-weight: bold;
+a.sl-facility:hover {
+    color:#342961;
+}
+a.sl-facility.active {
     color:black;
-    background-color:#F5F5F5;
-    border-left:2pt blue solid;
+    text-decoration:none;
 }
-
-a.list-group-item:hover {
-    -moz-border-radius: 0;
-    border-radius: 0;
-    border-left:2pt blue solid;
+a.sl-facility::before {
+    content: " ";
 }
-a.list-group-item p.list-group-item-text {
-    -moz-border-radius: 0;
-    border-radius: 0;
-    font-size:9pt;
-    font-style:italic;
-    font-weight: normal;
-    color: black !important;
+div.sl-facilities {
+    border-bottom:#CCCCCC 1px solid;
+    padding-bottom:15px;
+    margin-bottom:15px;
+}
+div.sl-facilities:last-child {
+    border:0;
+}
+a.sl-testbed {
+    color:gray;
+    text-decoration:none;
+    margin-left:25px;
+    margin-bottom:5px;
+}
+a.sl-testbed:hover {
+    color:#342961;
+}
+a.sl-testbed.active {
+    color:black;
+}
+div.sl-filter-resources {
+    margin:0 0 10px 0;
+    text-align:center;
 }
-
 span.sl-resources {
     font-size:9pt;
     color:gray;
 }
-a.sl-resources, a.sl-resources:hover {
+a.sl-resources {
     font-size:9pt;
     border:0;
-    padding:2px 4px;
-    -moz-border-radius: 4px;
-    border-radius: 4px;
-    width:105px;
-    margin-left:4px;
-    margin-bottom:8px;
+    padding:2px 8px;
+    margin:0 5px;
+    -moz-border-radius: 2px;
+    border-radius: 2px;
     text-align: center;
 }
 a.sl-resources.active, a.sl-resources.active:hover, a.sl-resources.active:focus {
     border:0;
-    -moz-border-radius: 4px;
-    border-radius: 4px;
+    padding:2px 8px;
+    -moz-border-radius: 2px;
+    border-radius: 2px;
+    background-color:#E7A6E7;
+    color:#000000;
 }
 a.sl-resources:first-child {
-    margin-left:12px;
 }
 button.btn-apply {
     font-size:13px;
     padding:2px 8px;
+    margin:0 5px;
+    -moz-border-radius: 2px;
+    border-radius: 2px;
+    text-align: center;
 }
 div#slice-info {
     margin-top:25px;
index 9f9a03a..4627124 100644 (file)
@@ -82,6 +82,10 @@ span.version {
     font-size:8pt;
     color:#888888;
 }
+input[type=checkbox] {
+  min-width:5px !important;
+  margin-left:0 !important;
+}
 input[type=text], input[type=password], input[type=email], input[type=tel], input[type=number], select, option {
     min-width:260px;
     padding:6px;
@@ -378,43 +382,53 @@ div.container-resource, div.container-slice {
 div#slice-view {
     margin:0;
 }
-div.list-group-item {
-    border:0;
-    -moz-border-radius: 0;
-    border-radius: 0;
-    background-color:white;
-    font-weight:bold;
-    padding-left:0;
+
+/* FACILITY/TESTBED filters */
+div.sl-filter-facilities {
+    padding:0 5px;
 }
-a.list-group-item {
-    -moz-border-radius: 0;
-    border-radius: 0;
-    border:0;
-    background-color:white;
-    padding:3px 2px 3px 10px;
-    border-left:2pt white solid;
+div.sl-filter-facilities h4 {
+    margin-bottom:15px;
+    
+}
+img.sl-image {
+    margin:0 5px 5px 0;
+    padding:0;
+    vertical-align:middle;
+}
+a.sl-facility {
+    color:gray;
+    text-decoration:none;
 }
-a.list-group-item.active, a.list-group-item.active:hover, a.list-group-item.active:focus {
-    -moz-border-radius: 0;
-    border-radius: 0;
-    font-weight: bold;
+a.sl-facility:hover {
+    color:#342961;
+}
+a.sl-facility.active {
     color:black;
-    background-color:#F5F5F5;
-    border-left:2pt blue solid;
+    text-decoration:none;
 }
-
-a.list-group-item:hover {
-    -moz-border-radius: 0;
-    border-radius: 0;
-    border-left:2pt blue solid;
+a.sl-facility::before {
+    content: " ";
 }
-a.list-group-item p.list-group-item-text {
-    -moz-border-radius: 0;
-    border-radius: 0;
-    font-size:9pt;
-    font-style:italic;
-    font-weight: normal;
-    color: black !important;
+div.sl-facilities {
+    border-bottom:#CCCCCC 1px solid;
+    padding-bottom:15px;
+    margin-bottom:15px;
+}
+div.sl-facilities:last-child {
+    border:0;
+}
+a.sl-testbed {
+    color:gray;
+    text-decoration:none;
+    margin-left:25px;
+    margin-bottom:5px;
+}
+a.sl-testbed:hover {
+    color:#342961;
+}
+a.sl-testbed.active {
+    color:black;
 }
 
 span.sl-resources {
diff --git a/portal/static/icons/IoTLab.png b/portal/static/icons/IoTLab.png
new file mode 100644 (file)
index 0000000..56a8e56
Binary files /dev/null and b/portal/static/icons/IoTLab.png differ
diff --git a/portal/static/icons/Mobile.png b/portal/static/icons/Mobile.png
new file mode 100644 (file)
index 0000000..81ee438
Binary files /dev/null and b/portal/static/icons/Mobile.png differ
diff --git a/portal/static/icons/PlanetLab.png b/portal/static/icons/PlanetLab.png
new file mode 100644 (file)
index 0000000..a74082a
Binary files /dev/null and b/portal/static/icons/PlanetLab.png differ
diff --git a/portal/static/icons/Wireless.png b/portal/static/icons/Wireless.png
new file mode 100644 (file)
index 0000000..4db0aa3
Binary files /dev/null and b/portal/static/icons/Wireless.png differ
index 78502cf..a4485af 100644 (file)
@@ -1,13 +1,10 @@
 {% extends "layout_wide.html" %}
 
-{% block head %} 
-<!-- <script type="text/javascript" src="{{STATIC_URL}}/js/institution.js"></script> -->
-{% endblock head %}
-
 {% block content %}
 <div class="container">
        <div class="row">
                <div class="col-md-12">
+                   <br />
                        <ul class="nav nav-tabs nav-section-mod">
                                <li class="active"><a href="#appservices"> Application Services </a></li>
                                <li><a href="#fedservices"> Federation Services </a></li>