Merge branch 'onelab' of ssh://git.onelab.eu/git/myslice into fibre
authorLoic & Edelberto <loic.baron@lip6.fr>
Thu, 13 Mar 2014 13:40:28 +0000 (10:40 -0300)
committerLoic & Edelberto <loic.baron@lip6.fr>
Thu, 13 Mar 2014 13:40:28 +0000 (10:40 -0300)
Conflicts:
portal/actions.py

64 files changed:
myslice/urls.py
plugins/googlemap/static/js/googlemap.js
plugins/query_editor/static/js/query_editor.js
plugins/querytable/__init__.py
plugins/querytable/templates/querytable.html
portal/accountview.py
portal/actions.py
portal/experimentview.py [deleted file]
portal/img/account_validated.png.olf [deleted file]
portal/img/icon_slices_color.png [deleted file]
portal/img/icon_support.png [deleted file]
portal/img/icon_testbed_color.png [deleted file]
portal/img/icon_user_color.png [deleted file]
portal/institution.py
portal/manageuserview.py
portal/sliceresourceview.py
portal/slicetabexperiment.py [new file with mode: 0644]
portal/slicetabinfo.py [new file with mode: 0644]
portal/slicetabtestbeds.py [moved from portal/testbedlist.py with 81% similarity]
portal/static/css/onelab.css
portal/static/icons/authority-xs.png [new file with mode: 0644]
portal/static/icons/slices-xs.png [new file with mode: 0644]
portal/static/icons/support-xs.png [new file with mode: 0644]
portal/static/icons/testbed-xs.png [new file with mode: 0644]
portal/static/icons/user-xs.png [new file with mode: 0644]
portal/static/icons/users-xs.png [new file with mode: 0644]
portal/static/img/account_validated.png [moved from portal/img/account_validated.png with 100% similarity]
portal/static/img/icon_authority_color.png
portal/static/img/icon_authority_color_small.png [moved from ui/static/img/icon_authority_color_small.png with 100% similarity]
portal/static/img/icon_slices.png
portal/static/img/icon_slices_small.png [moved from ui/static/img/icon_slices_small.png with 100% similarity]
portal/static/img/icon_support.png
portal/static/img/icon_support_small.png [moved from ui/static/img/icon_support_small.png with 100% similarity]
portal/static/img/icon_testbed_color.png
portal/static/img/icon_testbed_small.png [moved from ui/static/img/icon_testbed_small.png with 100% similarity]
portal/static/img/icon_user_color.png
portal/static/img/icon_user_small.png [moved from ui/static/img/icon_user_small.png with 100% similarity]
portal/static/img/icon_users_color.png [moved from portal/img/icon_users_color.png with 100% similarity]
portal/static/img/icon_users_small.png [moved from ui/static/img/icon_users_small.png with 100% similarity]
portal/static/img/loading.gif [moved from ui/static/img/loading.gif with 100% similarity]
portal/static/js/myslice-ui.js
portal/static/js/myslice.js
portal/static/js/onelab_slice-resource-view.js
portal/templates/about.html
portal/templates/contact_support_email.html [moved from portal/templates/contact-support-email.txt with 100% similarity]
portal/templates/experimentview.html
portal/templates/onelab/onelab__widget-topmenu.html
portal/templates/onelab/onelab_slice-resource-view.html
portal/templates/onelab/onelab_slice-view.html
portal/templates/onelab/onelab_testbed-list.html [deleted file]
portal/templates/onelab/onelab_widget-slice-sections.html
portal/templates/slice-tab-info.html [new file with mode: 0644]
portal/templates/slice-tab-testbeds.html [new file with mode: 0644]
portal/templates/usersview.html
portal/usersview.py
rest/update.py
ui/static/img/icon_authority_color.png [deleted file]
ui/static/img/icon_slices.png [deleted file]
ui/static/img/icon_support.png [deleted file]
ui/static/img/icon_testbed_color.png [deleted file]
ui/static/img/icon_user_color.png [deleted file]
ui/static/img/icon_users_color.png [deleted file]
ui/templates/base.html
ui/templates/messages-transient-header.html

index d134d14..ffe7307 100644 (file)
@@ -23,6 +23,11 @@ platforms_view=portal.platformsview.PlatformsView.as_view()
 import portal.testbedlist
 import portal.sliceview
 import portal.sliceresourceview
+
+import portal.slicetabexperiment
+import portal.slicetabinfo
+import portal.slicetabtestbeds
+
 from portal.sliceuserview import SliceUserView 
 
 #### high level choices
@@ -75,10 +80,15 @@ urls = [
     #
     #
     # Portal
-    (r'^testbeds/(?P<slicename>[^/]+)/?$', portal.testbedlist.TestbedList.as_view()),
+    
     (r'^resources/(?P<slicename>[^/]+)/?$', portal.sliceresourceview.SliceResourceView.as_view()),
-    (r'^users/(?P<slicename>[^/]+)/?$', SliceUserView.as_view()),
+    
     (r'^slice/(?P<slicename>[^/]+)/?$', portal.sliceview.SliceView.as_view()),
+    
+    (r'^info/(?P<slicename>[^/]+)/?$', portal.slicetabinfo.SliceInfoView.as_view()),
+    (r'^testbeds/(?P<slicename>[^/]+)/?$', portal.slicetabtestbeds.SliceTabTestbeds.as_view()),
+    (r'^users/(?P<slicename>[^/]+)/?$', SliceUserView.as_view()),
+    (r'^experiment/(?P<slicename>[^/]+)/?$', portal.slicetabexperiment.ExperimentView.as_view()),
     url(r'^portal/', include('portal.urls')),
 ]
 
index 9cde18c..6db222d 100644 (file)
@@ -76,7 +76,7 @@
         /* PLUGIN EVENTS */
 
         on_show: function(e) {
-           if (debug) messages.debug("googlemap.on_show");
+               if (debug) messages.debug("googlemap.on_show");
             var googlemap = e.data;
             google.maps.event.trigger(googlemap.map, 'resize');
         }, 
index 17b9bf7..68d0265 100644 (file)
@@ -35,7 +35,7 @@
                     // XXX This should be handled by manifold
                     manifold.raise_event(self.options.query_uuid, FILTER_REMOVED, [key, op]);
                 }
-            }
+            };
         },
 
         init: function(options, element) {
index 0b1d29d..6a2bb29 100644 (file)
@@ -92,11 +92,11 @@ Current implementation makes the following assumptions
                           # dataTableExt.afnSortData
                            "js/querytable.js", 
                            ] ,
-            'css_files': [ "css/dataTables.bootstrap.css",
+            'css_files': [ #"css/dataTables.bootstrap.css",
                            # hopefully temporary, when/if datatables supports sPaginationType=bootstrap3
                            # for now we use full_numbers, with our own ad hoc css 
                            "css/dataTables.full_numbers.css",
-                           "css/querytable.css" , 
+                           #"css/querytable.css" , 
                            ],
             }
         return reqs
index 902c55c..bc9cc03 100644 (file)
@@ -1,5 +1,5 @@
 <div id='main-{{ domid }}' class='querytable-spacer'>
-  <table class='table table-striped table-bordered dataTable' id='{{domid}}__table'>
+  <table class='table table-striped table-bordered dataTable' id='{{domid}}__table' width='100%'>
     <thead>
       <tr>
         {% for column in columns %} <th>{{ column }}</th> {% endfor %} 
index 94adaf4..9b0c466 100644 (file)
@@ -346,14 +346,17 @@ def account_process(request):
                         #sfa_update_user(request, user_hrn, user_pub_key)
                         sfa_update_user(request, user_hrn, user_pub_key)
                         result_sfa_user = sfa_get_user(request, user_hrn, public_key)
-                        result_sfa_user = result_sfa_user[0]
-                        if 'keys' in result_sfa_user and result_sfa_user['keys'][0] == public_key:
-                            # updating manifold
-                            updated_config = json.dumps(account_config) 
-                            user_params = { 'config': keypair, 'auth_type':'managed'}
-                            manifold_update_account(request, user_id, user_params)
-                            messages.success(request, 'Sucess: New Keypair Generated! Delegation of your credentials will be automatic.')
-                        else:
+                        try:
+                            result_sfa_user = result_sfa_user[0]
+                            if 'keys' in result_sfa_user and result_sfa_user['keys'][0] == public_key:
+                                # updating manifold
+                                updated_config = json.dumps(account_config) 
+                                user_params = { 'config': keypair, 'auth_type':'managed'}
+                                manifold_update_account(request, user_id, user_params)
+                                messages.success(request, 'Sucess: New Keypair Generated! Delegation of your credentials will be automatic.')
+                            else:
+                                raise Exception,"Keys are not matching"
+                        except Exception,e:
                             messages.error(request, 'Error: An error occured during the update of your public key at the Registry, or your public key is not matching the one stored.')
                         return HttpResponseRedirect("/portal/account/")
         else:
index 6955c62..ca87543 100644 (file)
@@ -705,7 +705,6 @@ def create_pending_user(wsgi_request, request, user_detail):
             .filter_by('platform', '==', 'myslice')           \
             .select('platform_id')
         reg_platform = execute_admin_query(wsgi_request, reg_platform_query)
-    
         reg_platform_id = reg_platform[0]['platform_id']
         account_params = {
             'platform_id'   : reg_platform_id, # XXX ALERT !!
diff --git a/portal/experimentview.py b/portal/experimentview.py
deleted file mode 100644 (file)
index 70d4267..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-# this somehow is not used anymore - should it not be ?
-from django.core.context_processors import csrf
-from django.http import HttpResponseRedirect
-from django.contrib.auth import authenticate, login, logout
-from django.template import RequestContext
-from django.shortcuts import render_to_response
-from django.shortcuts import render
-
-from unfold.loginrequired import FreeAccessView
-
-from manifoldapi.manifoldresult import ManifoldResult
-from ui.topmenu import topmenu_items, the_user
-from myslice.configengine import ConfigEngine
-
-from theme import ThemeView
-
-class ExperimentView (FreeAccessView, ThemeView):
-    template_name = 'experimentview.html'
-        
-    # expose this so we can mention the backend URL on the welcome page
-    def default_env (self):
-        return { 
-                 'MANIFOLD_URL':ConfigEngine().manifold_url(),
-                 }
-
-    def post (self,request):
-        env = self.default_env()
-        env['theme'] = self.theme
-        return render_to_response(self.template, env, context_instance=RequestContext(request))
-
-    def get (self, request, state=None):
-        env = self.default_env()
-
-        if request.user.is_authenticated(): 
-            env['person'] = self.request.user
-        else: 
-            env['person'] = None
-    
-        env['theme'] = self.theme
-    
-
-        env['username']=the_user(request)
-        env['topmenu_items'] = topmenu_items(None, request)
-        if state: env['state'] = state
-        elif not env['username']: env['state'] = None
-        # use one or two columns for the layout - not logged in users will see the login prompt
-        env['layout_1_or_2']="layout-unfold2.html" if not env['username'] else "layout-unfold1.html"
-        
-        
-        return render_to_response(self.template, env, context_instance=RequestContext(request))
-
diff --git a/portal/img/account_validated.png.olf b/portal/img/account_validated.png.olf
deleted file mode 100644 (file)
index d2da4cf..0000000
Binary files a/portal/img/account_validated.png.olf and /dev/null differ
diff --git a/portal/img/icon_slices_color.png b/portal/img/icon_slices_color.png
deleted file mode 100644 (file)
index bd3bc34..0000000
Binary files a/portal/img/icon_slices_color.png and /dev/null differ
diff --git a/portal/img/icon_support.png b/portal/img/icon_support.png
deleted file mode 100644 (file)
index 6c77efc..0000000
Binary files a/portal/img/icon_support.png and /dev/null differ
diff --git a/portal/img/icon_testbed_color.png b/portal/img/icon_testbed_color.png
deleted file mode 100644 (file)
index d1169d5..0000000
Binary files a/portal/img/icon_testbed_color.png and /dev/null differ
diff --git a/portal/img/icon_user_color.png b/portal/img/icon_user_color.png
deleted file mode 100644 (file)
index a8ef8c6..0000000
Binary files a/portal/img/icon_user_color.png and /dev/null differ
index 70d88dd..9bc0a86 100644 (file)
@@ -36,7 +36,10 @@ class InstitutionView (FreeAccessView, ThemeView):
             env['person'] = self.request.user
             user_query  = Query().get('user').select('user_hrn','parent_authority').filter_by('user_hrn','==','$user_hrn')
             user_details = execute_query(self.request, user_query)
-            env['user_details'] = user_details[0]
+            try:
+                env['user_details'] = user_details[0]
+            except Exception,e:
+                env['error'] = "Please check your Credentials"
         else: 
             env['person'] = None
     
index 5b8d2db..369d6e9 100644 (file)
@@ -261,42 +261,37 @@ def user_process(request, **kwargs):
                     account_config = json.loads(account_detail['config'])
                     acc_slice_cred = account_config.get('delegated_slice_credentials','N/A')
                     acc_auth_cred = account_config.get('delegated_authority_credentials','N/A')
-                
-
                     
-    
-    # adding the slices and corresponding credentials to list
-    if 'N/A' not in acc_slice_cred:
-        slice_list = []
-        slice_cred = [] 
-        for key, value in acc_slice_cred.iteritems():
-            slice_list.append(key)       
-            slice_cred.append(value)
-        # special case: download each slice credentials separately 
-        for i in range(0, len(slice_list)):
-            if 'dl_'+slice_list[i] in request.POST:
-                slice_detail = "Slice name: " + slice_list[i] +"\nSlice Credentials: \n"+ slice_cred[i]
-                response = HttpResponse(slice_detail, content_type='text/plain')
-                response['Content-Disposition'] = 'attachment; filename="slice_credential.txt"'
-                return response
-
-    # adding the authority and corresponding credentials to list
-    if 'N/A' not in acc_auth_cred:
-        auth_list = []
-        auth_cred = [] 
-        for key, value in acc_auth_cred.iteritems():
-            auth_list.append(key)       
-            auth_cred.append(value)
-        # special case: download each slice credentials separately
-        for i in range(0, len(auth_list)):
-            if 'dl_'+auth_list[i] in request.POST:
-                auth_detail = "Authority: " + auth_list[i] +"\nAuthority Credentials: \n"+ auth_cred[i]
-                response = HttpResponse(auth_detail, content_type='text/plain')
-                response['Content-Disposition'] = 'attachment; filename="auth_credential.txt"'
-                return response
-
-
-             
+                    # adding the slices and corresponding credentials to list
+                    if 'N/A' not in acc_slice_cred:
+                        slice_list = []
+                        slice_cred = [] 
+                        for key, value in acc_slice_cred.iteritems():
+                            slice_list.append(key)       
+                            slice_cred.append(value)
+                        # special case: download each slice credentials separately 
+                        for i in range(0, len(slice_list)):
+                            if 'dl_'+slice_list[i] in request.POST:
+                                slice_detail = "Slice name: " + slice_list[i] +"\nSlice Credentials: \n"+ slice_cred[i]
+                                response = HttpResponse(slice_detail, content_type='text/plain')
+                                response['Content-Disposition'] = 'attachment; filename="slice_credential.txt"'
+                                return response
+
+                    # adding the authority and corresponding credentials to list
+                    if 'N/A' not in acc_auth_cred:
+                        auth_list = []
+                        auth_cred = [] 
+                        for key, value in acc_auth_cred.iteritems():
+                            auth_list.append(key)       
+                            auth_cred.append(value)
+                        # special case: download each slice credentials separately
+                        for i in range(0, len(auth_list)):
+                            if 'dl_'+auth_list[i] in request.POST:
+                                auth_detail = "Authority: " + auth_list[i] +"\nAuthority Credentials: \n"+ auth_cred[i]
+                                response = HttpResponse(auth_detail, content_type='text/plain')
+                                response['Content-Disposition'] = 'attachment; filename="auth_credential.txt"'
+                                return response
+
     if 'submit_name' in request.POST:
         edited_first_name =  request.POST['fname']
         edited_last_name =  request.POST['lname']
index 4f0775d..520a72e 100644 (file)
@@ -14,14 +14,117 @@ from unfold.page                     import Page
 from manifold.core.query             import Query, AnalyzedQuery
 from manifoldapi.manifoldapi         import execute_query
 
+from myslice.configengine            import ConfigEngine
+from plugins.querytable              import QueryTable
+from plugins.googlemap               import GoogleMap
+from plugins.queryupdater            import QueryUpdater
+
 from theme import ThemeView
 
 class SliceResourceView (LoginRequiredView, ThemeView):
     template_name = "slice-resource-view.html"
     
     def get(self, request, slicename):
+
         if request.GET.get('message') : 
             msg = "Slice successfully updated"
         else :
             msg = None
-        return render_to_response(self.template, {"msg" : msg, "slice": slicename, "theme": self.theme, "username": request.user, "section":"resources"}, context_instance=RequestContext(request))
+
+        page = Page(request)
+        metadata = page.get_metadata()
+        page.expose_js_metadata()
+
+        resource_md = metadata.details_by_object('resource')
+        resource_fields = [column['name'] for column in resource_md['column']]
+
+        user_md = metadata.details_by_object('user')
+        user_fields = ['user_hrn'] # [column['name'] for column in user_md['column']]
+
+        # TODO The query to run is embedded in the URL
+        main_query = Query.get('slice').filter_by('slice_hrn', '=', slicename)
+        main_query.select(
+                'slice_hrn',
+                'resource.urn', 
+                'resource.hostname', 'resource.type',
+                'resource.network_hrn',
+                'lease.urn',
+                'user.user_hrn',
+                #'application.measurement_point.counter'
+        )
+        # for internal use in the querytable plugin;
+        # needs to be a unique column present for each returned record
+        main_query_init_key = 'urn'
+        aq = AnalyzedQuery(main_query, metadata=metadata)
+        page.enqueue_query(main_query, analyzed_query=aq)
+
+        query_resource_all = Query.get('resource').select(resource_fields)
+        page.enqueue_query(query_resource_all)
+
+        sq_resource    = aq.subquery('resource')
+        sq_lease       = aq.subquery('lease')
+
+        list_resources = QueryTable(
+            page       = page,
+            domid      = 'resources-list',
+            title      = 'List view',
+            query      = sq_resource,
+            query_all  = query_resource_all,
+            init_key   = "urn",
+            checkboxes = True,
+            datatables_options = {
+                'iDisplayLength': 25,
+                'bLengthChange' : True,
+                'bAutoWidth'    : True,
+                },
+        )
+
+        # --------------------------------------------------------------------------
+        # RESOURCES
+        # the resources part is made of a Tabs (Geographic, List), 
+
+        map_resources  = GoogleMap(
+            page       = page,
+            title      = 'Geographic view',
+            domid      = 'resources-map',
+            # tab's sons preferably turn this off
+            togglable  = False,
+            query      = sq_resource,
+            query_all  = query_resource_all,
+            # this key is the one issued by google
+            googlemap_api_key = ConfigEngine().googlemap_api_key(),
+            # the key to use at init-time
+            init_key   = main_query_init_key,
+            checkboxes = True,
+            # center on Paris
+            latitude   = 49.,
+            longitude  = 9,
+            zoom       = 4,
+        )
+
+        # --------------------------------------------------------------------------
+        # QueryUpdater (Pending Operations)
+        pending_resources = QueryUpdater(
+            page                = page,
+            title               = 'Pending operations',
+            query               = main_query,
+            togglable           = True,
+            # start turned off, it will open up itself when stuff comes in
+            toggled             = False,
+            domid               = 'pending',
+            outline_complete    = True,
+        )
+
+        template_env = {}
+        template_env['list_resources'] = list_resources.render(self.request)
+        template_env['map_resources'] = map_resources.render(self.request)
+        template_env['pending_resources'] = pending_resources.render(self.request)
+        template_env["theme"] = self.theme
+        template_env["username"] = request.user
+        template_env["slice"] = slicename
+        template_env["section"] = "resources"
+        template_env["msg"] = msg
+        template_env.update(page.prelude_env())
+
+        return render_to_response(self.template, template_env, context_instance=RequestContext(request))
diff --git a/portal/slicetabexperiment.py b/portal/slicetabexperiment.py
new file mode 100644 (file)
index 0000000..f13c9d8
--- /dev/null
@@ -0,0 +1,23 @@
+# this somehow is not used anymore - should it not be ?
+from django.core.context_processors import csrf
+from django.http import HttpResponseRedirect
+from django.contrib.auth import authenticate, login, logout
+from django.template import RequestContext
+from django.shortcuts import render_to_response
+from django.shortcuts import render
+
+from unfold.loginrequired import FreeAccessView
+
+from manifoldapi.manifoldresult import ManifoldResult
+from ui.topmenu import topmenu_items, the_user
+from myslice.configengine import ConfigEngine
+
+from theme import ThemeView
+
+class ExperimentView (FreeAccessView, ThemeView):
+    template_name = 'experimentview.html'
+
+    def get (self, request, slicename, state=None):
+        
+        return render_to_response(self.template, { 'theme' : self.theme }, context_instance=RequestContext(request))
+
diff --git a/portal/slicetabinfo.py b/portal/slicetabinfo.py
new file mode 100644 (file)
index 0000000..7e7b78e
--- /dev/null
@@ -0,0 +1,23 @@
+from django.template                 import RequestContext
+from django.shortcuts                import render_to_response
+
+from manifold.core.query             import Query, AnalyzedQuery
+from manifoldapi.manifoldapi         import execute_query
+
+from django.views.generic.base      import TemplateView
+
+from unfold.loginrequired           import LoginRequiredView
+from django.http import HttpResponse
+from django.shortcuts import render
+
+from unfold.page                     import Page
+from manifold.core.query             import Query, AnalyzedQuery
+from manifoldapi.manifoldapi         import execute_query
+
+from theme import ThemeView
+
+class SliceInfoView (LoginRequiredView, ThemeView):
+    template_name = "slice-tab-info.html"
+    
+    def get(self, request, slicename):
+        return render_to_response(self.template, {"slice": slicename, "theme": self.theme, "username": request.user, "section":"slice"}, context_instance=RequestContext(request))
similarity index 81%
rename from portal/testbedlist.py
rename to portal/slicetabtestbeds.py
index a545ec4..a93f678 100644 (file)
@@ -5,8 +5,8 @@ from unfold.loginrequired           import LoginRequiredView
 
 from theme import ThemeView
 
-class TestbedList (LoginRequiredView, ThemeView):
-    template_name = "testbed-list.html"
+class SliceTabTestbeds (LoginRequiredView, ThemeView):
+    template_name = "slice-tab-testbeds.html"
     
     def get(self, request, slicename):
         return render_to_response(self.template, {"theme": self.theme, "username": request.user, "slice" : slicename, "section":"testbeds"}, context_instance=RequestContext(request))
index da7718c..c39de29 100644 (file)
@@ -13,13 +13,13 @@ a, a:active, a:focus {
 
 h1 {
     border-bottom:1px solid #DDDDDD;
-    padding:0 0 5px 0;
-    margin:0 0 15px 0;
+    padding:0 0 0 0;
+    margin:0 0 0 0;
     font-size:18pt;
 }
 h1 img {
     vertical-align:middle;
-    margin-bottom:4px;
+    margin-bottom:6px;
 }
 h2 {
     font-size:14pt;
@@ -29,6 +29,7 @@ h3 {
     font-size:13pt;
     color:#201E62;
 }
+
 div.wrapper {
     width:980px;
     margin:0 auto;
@@ -132,12 +133,41 @@ div#navigation li:last-child {
 
 div#navigation li.active {
        padding:5px;
+    padding-top: 15px;
     min-height: 40px;
     margin-top: 0px;
        background-color:gray;
        color:#FF0000;
 }
+div#navigation li.slices {
+    position:relative;
+    cursor:pointer;
+}
+div#navigation .dropdown-menu {
+    color:white;
+    padding:0 15px 15px 15px;
+    margin-top:5px;
+    margin-left:-16px;
+    background-color:black;
+}
+div#navigation .dropdown-menu a {
+    color:white;
+}
 
+div#menu-slice-list{
+    display:none;
+    position:absolute;
+    background-color:black;
+    padding:15px;
+    left:-15px;
+    z-index:10;
+}
+
+div#navigation .dropdown-menu li:first-child {
+    border-bottom:1px solid white;
+    padding-bottom:5px;
+     
+}
 /* HOME DASHBOARD */
 div#home-dashboard {
     color:black;
@@ -234,7 +264,6 @@ div#home-dashboard div#home-slice-list li {
 /* NAV TABS */
 
 .nav.nav-tabs {
-    margin-bottom:25px;
 }
 
 .nav.nav-tabs li.active a {
@@ -310,6 +339,32 @@ div#ticket-request p {
 }
 
 /* SLICE VIEW */
+ul.nav-sliceview {}
+ul.nav-sliceview li {
+    
+}
+ul.nav-sliceview li:first-child {
+    padding:0;
+}
+ul.nav-sliceview li:first-child a {
+    font-weight:bold;
+    padding:6px 15px 4px 15px;
+}
+ul.nav-sliceview li:first-child img {
+    margin:0 4px 1px 0;
+    padding:0;
+}
+
+ul.nav-resources {
+    margin:15px 0;
+}
+ul.nav-resources a {
+    padding: 4px 10px 5px 10px;
+}
+
+
+
+
 div#slice-view {
     margin:0;
 }
diff --git a/portal/static/icons/authority-xs.png b/portal/static/icons/authority-xs.png
new file mode 100644 (file)
index 0000000..471bbd5
Binary files /dev/null and b/portal/static/icons/authority-xs.png differ
diff --git a/portal/static/icons/slices-xs.png b/portal/static/icons/slices-xs.png
new file mode 100644 (file)
index 0000000..6b64058
Binary files /dev/null and b/portal/static/icons/slices-xs.png differ
diff --git a/portal/static/icons/support-xs.png b/portal/static/icons/support-xs.png
new file mode 100644 (file)
index 0000000..409ffc6
Binary files /dev/null and b/portal/static/icons/support-xs.png differ
diff --git a/portal/static/icons/testbed-xs.png b/portal/static/icons/testbed-xs.png
new file mode 100644 (file)
index 0000000..b5242a7
Binary files /dev/null and b/portal/static/icons/testbed-xs.png differ
diff --git a/portal/static/icons/user-xs.png b/portal/static/icons/user-xs.png
new file mode 100644 (file)
index 0000000..942c5a8
Binary files /dev/null and b/portal/static/icons/user-xs.png differ
diff --git a/portal/static/icons/users-xs.png b/portal/static/icons/users-xs.png
new file mode 100644 (file)
index 0000000..563a23e
Binary files /dev/null and b/portal/static/icons/users-xs.png differ
index 342a1dd..27d2343 100644 (file)
Binary files a/portal/static/img/icon_authority_color.png and b/portal/static/img/icon_authority_color.png differ
index 9527461..bd3bc34 100644 (file)
Binary files a/portal/static/img/icon_slices.png and b/portal/static/img/icon_slices.png differ
index 54bce1b..0e69ae7 100644 (file)
Binary files a/portal/static/img/icon_support.png and b/portal/static/img/icon_support.png differ
index f3c55e4..d1169d5 100644 (file)
Binary files a/portal/static/img/icon_testbed_color.png and b/portal/static/img/icon_testbed_color.png differ
index e88d559..a8ef8c6 100644 (file)
Binary files a/portal/static/img/icon_user_color.png and b/portal/static/img/icon_user_color.png differ
index 4aa83ce..747098a 100644 (file)
@@ -7,46 +7,7 @@ $(document).ready(function() {
                
        
        
-       /* Testbeds list */
-
-       $.post("/rest/network/", { "fields" : ["network_hrn", "network_longname", "description"]}, function(data) {
-                       var testbed_data = [];
-                       var testbed_row = "<thead>";
-                       testbed_row += "<tr>";
-                       testbed_row += "<th id=testbed_check><input type=\"checkbox\" name=\"network_hrn\" value=\"all\"/></th>";
-                       testbed_row += "<th id=testbed_icon></th>";
-                       testbed_row += "<th>network_hrn</th>";
-                       testbed_row += "<th>Full name</th>";
-                       testbed_row += "<th>Description</th>";
-                       testbed_row += "</tr>";
-                       testbed_row += "</thead>";
-                       testbed_data.push(testbed_row);
-                       $.each( data, function(key, val) {
-                               testbed_row = "<tr data-keys=\""+val.network_hrn+"\" class=\"odd\">"
-                               testbed_row += "<td><input type=\"checkbox\" name=\"network_hrn\" value=\""+val.network_hrn+"\"/></td>";
-                               testbed_row += "<td><img src='/static/img/testbeds/"+val.network_hrn+".png' alt='' /></td>";
-                               testbed_row += "<td>"+val.network_hrn+"</td>";
-                               testbed_row += "<td>"+val.network_longname+"</td>";
-                               testbed_row += "<td>"+val.description+"</td>";
-                               testbed_row += "</thead>";
        
-                               testbed_data.push(testbed_row);
-                       });
-               $("table#testbedList").html(testbed_data.join(''));
-               $("div#testbed-list-loaded").css("display","block");
-               $("div#testbed-list-loading").css("display","none");
-                       
-               $("input[type=checkbox]").click(function() {
-                       var cnt = 0;
-                       var id = $(this).val();
-                       var row = $(this).parent().parent()
-                       if (row.hasClass("active")) {
-                               row.removeClass("active");
-                       } else {
-                               row.addClass("active");
-                               }
-               });
-       });
        
        $("#objectList").load("/table/resource/", {"fields" : ["hostname","hrn","country","type"], "options": ["checkbox"] }, function(data) {
                $(this).dataTable( {
index a67e314..7038e53 100644 (file)
  * MySlice Class
  */
 
-var myslice = {
-       slice: null,
-    pending: [],
-    reserved: [],
-    
-    add: function(resource) {
-       if (!this.has(resource)) {
-               this.pending.push(resource);
-               this.save();
-       }
-    },
+function list() {
+       this.elements = [];
+}
+
+list.prototype.save = function() {
+       for (var prop in this) {
+      if (typeof this[prop] != 'function') {
+        console.log("prop: " + prop);
+      } else {
+       console.log("func: " + prop);
+      }
+    }
+       //localStorage.setItem(name, JSON.stringify(value));
+};
+
+list.prototype.load = function(name) {
+       this.pending = JSON.parse(localStorage.getItem(name));
+       if (!this.pending) {
+               this.pending = [];
+       }
+};
+
+list.prototype.add = function(element) {
+       if (!this.has(element)) {
+               this.elements.push(element);
+       }
+};
     
-    del: function(resource) {
-       if (this.has(resource)) {
-               this.pending.splice(index, 1);
-       }
-    },
+list.prototype.del = function(element) {
+       if (this.has(element)) {
+               this.elements.splice(index, 1);
+       }
+};
     
-    has: function(resource) {
-       index = jQuery.inArray( resource, this.pending );
-       if (index != -1) {
-               return true;
-       }
-       return false;
-    },
+list.prototype.has = function(element) {
+       index = $.inArray( element, this.elements );
+       if (index != -1) {
+               return true;
+       }
+       return false;
+};
     
-    count: function() {
-       return this.pending.length;
-    },
+list.prototype.count = function() {
+    return this.elements.length;
+};
+
+
+/*
+ * resources, users, leases
+ */
+
+function resources() {
+       this.pending = {
+               toremove: new list(),
+               toadd: new list(),
+       };
+};
+
+function users() {
+       this.pending = {
+               toremove: new list(),
+               toadd: new list(),
+       };
+};
+
+function leases() {
+       this.pending = {
+               toremove: new list(),
+               toadd: new list(),
+       };
+};
+
+/*
+ * Slice
+ */
+function slice(name) {
+       this.name = name;
+       this.resources = new resources();
+       this.users = new users();
+       this.leases = new leases();
+       
+};
+slice.prototype.pending = function() {
+       
+};
+slice.prototype.reserve = function() {
+       
+};
+slice.prototype.unreserve = function() {
+       
+};
+
+/*
+ * User
+ */
+function user(u) {
+       this.u = u;
+       this.testbeds = {};
+       this.slices = {};
+       
+       for (i = 0; i < this.u.slices.length; i++) {
+               this.slices[this.u.slices[i]] = new slice(this.u.slices[i]);
+       }
+};
+
+user.prototype.slice = function(name) {
+       return this.slices[name];
+};
+
+user.prototype.list = function() {
+    for (s in this.slices) {
+       for (o in s) {
+      if (typeof o != 'function') {
+        console.log(o);
+      } else {
+       console.log("w "+o);
+      }
+      }
+    }
+};
+
+/*
+ * MySlice
+ */
+var myslice = {
+       user: {},
     
-    save: function() {
-       localStorage.setItem('pending', JSON.stringify(this.pending));
+    getSlices: function(name) {
+       
     },
     
-    load: function() {
-       this.pending = JSON.parse(localStorage.getItem('pending'));
-       if (!this.pending) {
-               this.pending = [];
-       }
+    refreshUser: function() {
+       
     },
     
     apply: function() {
-       $('div#loading').show();
-       this.pending = [];
-       this.save();
-       setTimeout(function(){
-               $('div#loading').hide();
-               window.location.href = '/resources/' + this.slice + '?message=true';
-               },6000);
+
+       //$('div#loading').show();
+       //this.pending = [];
+       //this.save();
+       //setTimeout(function(){
+               //$('div#loading').hide();
+               //window.location.href = '/resources/' + this.slice + '?message=true';
+               //},6000);
        
         
 
-       // $.post("/rest/slice/", { 'fields': ['resource','slice_hrn'], 'filters': { 'slice_hrn' : this.slice  } }, function(data) {
-               // console.log(data);
-               // resources = [];
-               // reserved = [];
-               // update = [];
-               // if ('resource' in data[0]) {
-                       // $.each(data[0].resource, function(idx, r) {
-                               // resources.push(r.urn);
-                       // });
-               // }
-               // //myslice.pending
-               // console.log(myslice.pending);
-               // console.log(resources);
-               // $.each(resources.concat(myslice.pending), function(idx, v) {
-                       // update.push({ 'resource': v });
-               // });
-               // console.log(update);
-               // $.post("/update/slice/", { 'filters': { 'slice_hrn' : myslice.slice  }, 'params' : update }, function(data) {
-                       // console.log(data);
-               // });
-       // });
-       //console.log(this.slice);
+        $.post("/rest/slice/", { 'fields': ['resource','slice_hrn'], 'filters': { 'slice_hrn' : this.slice  } }, function(data) {
+                console.log(data);
+                resources = [];
+                reserved = [];
+                update = [];
+                if ('resource' in data[0]) {
+                        $.each(data[0].resource, function(idx, r) {
+                                resources.push(r.urn);
+                        });
+                }
+                //myslice.pending
+                console.log(myslice.pending);
+                console.log(resources);
+                $.each(resources.concat(myslice.pending), function(idx, v) {
+                        update.push( v );
+                });
+                console.log(update);
+                $.post("/update/slice/", { 'filters': { 'slice_hrn' : myslice.slice  }, 'params' : update }, function(data) {
+                        console.log(data);
+                });
+        });
+       console.log(this.slice);
     }
     
 };
 
+
+/* MySlice Init */
+
+// var Reflector = function(obj) {
+  // this.getProperties = function() {
+    // var properties = [];
+    // for (var prop in obj) {
+      // if (typeof obj[prop] != 'function') {
+        // properties.push(prop);
+        // console.log("prop: " + prop);
+      // } else {
+       // console.log("func: " + prop);
+      // }
+    // }
+    // return properties;
+  // };
+// };
+// var reflector = new Reflector(myslice.slices[0].resources.pending);
+// reflector.getProperties();
+
+
 $(document).ready(function() {
+       // $.post("/rest/user/",{'filters':{'user_hrn':'$user_hrn'}}, function(data) {
+               // myslice.user = new user(data[0]);
+               // console.log(myslice.user.slices);
+               // myslice.user.list();
+//       
+       // }).fail(function() {
+               // throw "error retreiving user data";
+       // });
        // Put the object into storage
        //localStorage.setItem('testObject', JSON.stringify(testObject));
 
        // Retrieve the object from storage
-       myslice.load();
+       //myslice.load();
 
 });
+
+/* EXEMPLES */
+// add a resource to pending
+
+//myslice.user.slice('ple.upmc.myslicedemo').resources.pending.add(resource);
+
index 28b1a4e..a418093 100644 (file)
@@ -1,13 +1,18 @@
 $(document).ready(function() {
+    $('li#GoogleMap').click(function (e) {
+        $('.'+this.id).trigger('show');
+    });
+
        $('ul.nav-resources a').click(function() {
         $('ul.nav-resources li').removeClass('active');
         $(this).parent().addClass('active');
         $('div.panel').hide();
         $('div#'+$(this).data('panel')).show();
-        
+        /*
         if ($(this).data('panel') == 'map') {
                mapInit();
         }
+        */
     });
     
     $.get("/rest/network", function(data) {
index bddeb7e..9b124f2 100644 (file)
@@ -2,7 +2,7 @@
 
 {% block content %}
 <div class="row">
-       <h1><img src="{{ STATIC_URL }}img/icon_slices_small.png" alt="About MySlice" /> About</h1>
+       <h1><img src="{{ STATIC_URL }}icons/slices-xs.png" alt="About MySlice" /> About</h1>
 </div>
 
 <div class="row">
index 1c7ba2a..9056eb4 100644 (file)
@@ -1,12 +1,3 @@
-{% extends "layout.html" %}
-
-{% block content %}
-
-<div class="row">
-       <h1><img src="{{ STATIC_URL }}img/icon_slices_small.png" alt="Experiment Tools" /> Experiment Tools</h1>
-</div>
-<div class="row">
-
 <h2>Secure Shell (SSH)</h2>
 <p>
 Secure Shell (SSH) is a cryptographic network protocol for secure data communication, remote command-line login, remote command execution, and other secure network services between two networked computers that connects, via a secure channel over an insecure network, a server and a client (running SSH server and SSH client programs, respectively). The protocol specification distinguishes between two major versions that are referred to as SSH-1 and SSH-2.
@@ -27,7 +18,4 @@ OMF was originally developed for the ORBIT wireless testbed at Winlab, Rutgers U
 <p>In addition to the main OMF software, this site also hosts OMF sub-projects addressing various related aspects of a testbed's control, measurement, and management.</p>
 
 
-<p>More Info: <a href="http://mytestbed.net/projects/omf" target="_blank">http://mytestbed.net/projects/omf</a></p>
-
-</div>
-{% endblock %}
+<p>More Info: <a href="http://mytestbed.net/projects/omf" target="_blank">http://mytestbed.net/projects/omf</a></p>
\ No newline at end of file
index 7742b8d..da834ac 100644 (file)
@@ -1,7 +1,4 @@
-{% insert_str prelude "js/bootstrap.js" %}
-{% insert_str prelude "css/bootstrap.css" %}
-{% insert_str prelude "css/topmenu.css" %}
-{% insert_str prelude "js/logout.js" %}
+
 <div id="header">
        <div class="wrapper">
                <div class="logo">
                        <li id="nav-account"><a href="/portal/account/">{{ username }}</a></li>
                        <li>|</li>
                        <li id="nav-institution" class=""><a href="/portal/institution">INSTITUTION</a></li>
-                       <li>SLICES</li>
+                       <li class="slices">
+                               <a class="dropdown-toggle" data-toggle="dropdown" href="#">
+                                       SLICES <span class="caret"></span>
+                       </a>
+                               
+                               <div class="dropdown-menu">
+                                               <ul>
+                                                       <li><a href="/portal/slice_request/">Request Slice</a></li>
+                                                       <li><a href="/slice/ple.upmc.agent3/">ple.upmc.agent3</a></li>
+                                                   <li><a href="/slice/ple.upmc.agent/">ple.upmc.agent</a></li>
+                                                   <li><a href="/slice/ple.upmc.myslicedemo/">ple.upmc.myslicedemo</a></li>
+                                                   <li><a href="/slice/ple.upmc.slicestat/">ple.upmc.slicestat</a></li>
+                                                   <li><a href="/slice/ple.upmc.agent2/">ple.upmc.agent2</a></li>
+                                               </ul>
+                               </div>
+                               </li>
                        <li id="nav-request"><a href="/portal/validate">REQUESTS</a></li>
                        <li id="nav-support"><a href="/portal/support/">SUPPORT</a></li>
                        <li>|</li>
 </div>
 <script>
        $(document).ready(function() {
+               $('li.slices').mouseenter(function() {
+                       $('div#menu-slice-list').fadeIn(100);
+               });
+               $('div#menu-slice-list').mouseleave(function(e) {
+                       if (!$('li.slices').is(":hover")) {
+                               $(this).fadeOut(100);
+                       }
+               });
                // var slices = localStorage.getItem('slices');
                // if (slices.length == 0) {
                        // $.post("/rest/user/",{'filters':{'user_hrn':'$user_hrn'}}, function( data ) {
index d6682d2..80c3fcc 100644 (file)
@@ -1,10 +1,10 @@
 {% extends "layout_wide.html" %}
 
 {% block head %}
-<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyC1RUj824JAiHRVqgc2CSIg4CpKHhh84Lw&sensor=false"></script>
+<!-- <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyC1RUj824JAiHRVqgc2CSIg4CpKHhh84Lw&sensor=false"></script> -->
 <script src="{{ STATIC_URL }}js/onelab_slice-resource-view.js"></script>
 <script>
-       myslice.slice = "{{ slice }}";
+       //myslice.slice = "{{ slice }}";
 </script>
 {% endblock %}
 
                <div id="select-platform" class="list-group">
                </div>
                        
-               <ul class="list-group">
+               <!-- <ul class="list-group">
                  <li class="list-group-item">Filter: CPU</li>
                  <li class="list-group-item">Filter: Interface</li>
                  <li class="list-group-item">...</li>
                  <li class="list-group-item">...</li>
                  <li class="list-group-item">...</li>
-               </ul>
+               </ul> -->
        
        </div>
        <div class="col-md-10" style="height:100%;">
                <div class="row">
                        {% include theme|add:"_widget-slice-sections.html" %}
                </div>
-               <div class="row slice-pending">
+               <!-- <div class="row slice-pending">
                        <ul class="nav nav-pills">
                                <li><a href="">Unreserved</a></li>
                                <li><a href="">Reserved</a></li>
                                        <div id="loading" style="display:none;"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading" /></div>
                                </li>
                        </ul>
-               </div>
+               </div> -->
                <div class="row">
                        {% if msg %}
                        <div class="col-md-12"><p class="alert-success">{{ msg }}</p></div>
                        {% endif %}
                </div>
                <div class="row">
-                       <ul class="nav nav-tabs nav-resources">
+                       <ul class="nav nav-pills nav-resources">
                          <li class="active"><a data-panel="resources" href="#">Resources</a></li>
-                         <li><a data-panel="map" href="#">Map</a></li>
+                         <li id="GoogleMap"><a data-panel="map" href="#">Map</a></li>
+                         <li><a data-panel="pending" href="#">Pending</a></li>
                          <li><a href="#"></a></li>
                        </ul>
                </div>
                <div class="row" style="height:100%;">
                        <div id="resources" class="panel">
-                               <table cellpadding="0" cellspacing="0" border="0" class="table" id="objectList"></table>
+                {{list_resources}}
+                               <!-- <table cellpadding="0" cellspacing="0" border="0" class="table" id="objectList"></table> -->
                        </div>
                        <div id="map" class="panel" style="height:370px;display:none;">
-                               <div id="map-canvas" style="height:100%;"></div>
+                {{map_resources}}
+                       </div>
+                       <div id="pending" class="panel" style="height:370px;display:none;">
+                {{pending_resources}}
                        </div>
                </div>
        </div>
-{% endblock %}
\ No newline at end of file
+{% endblock %}
index a67d34b..0444a82 100644 (file)
@@ -1,61 +1,25 @@
 {% extends "layout_wide.html" %}
 
-{% block content %}
-       <div class="col-md-2"></div>
-       <div class="col-md-10">
-               <div class="row">
-                       {% include theme|add:"_widget-slice-sections.html" %}
-               </div>
-    </div>
-    
-       <div class="col-md-2"></div>
-       <div class="col-md-10">
-        <br>
-        <br>
-        <div id="slice-tab-loading"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading Slices" /></div>
-        <div id="slice-tab-loaded" style="display:none;">
-            <table id="slice-tab">
-            </table>
-        </div>
-       </div>
-<script>
-    $(document).ready(function() {
-        $.post("/rest/slice/",{'filters':{'slice_hrn':'{{slice}}'}}, function( data ) {
-            var table_slices = [];
-            /* "slice_hrn", "slice_description", "slice_type", "parent_authority", "created", "nodes", "slice_url", "slice_last_updated", "user", "slice_urn", "slice_expires" */
-            $.each( data, function( key, val ) {
-                if(val.nodes=="undefined" || val.nodes==null){
-                    nodes_length=0;
-                }else{
-                    nodes_length=val.nodes.length;
-                }
+{% block head %}
+
+{% endblock %}
 
-                if(val.user=="undefined" || val.user==null){
-                    user_length=0;
-                }else{
-                    user_length=val.user.length;
-                }
+{% block content %}
 
-                if(val.slice_url=="undefined" || val.slice_url==null){
-                    slice_url="";
-                }else{
-                    slice_url="<a href='"+val.slice_url+"' target='_blank'>"+val.slice_url+"</a>";
-                }
-                
-                slice_row = "<tr><td><b>Description:</b></td><td>"+val.slice_description+"</td></tr>";
-                slice_row += "<tr><td><b>url:</b></td><td><a href='"+val.slice_url+" target='_blank'>"+val.slice_url+"</a></td></tr>";
-                slice_row += "<tr><td><b>users:</b></td><td>"+user_length+"</td></tr>";
-                slice_row += "<tr><td><b>resources:</b></td><td>"+nodes_length+"</td></tr>";
-                slice_row += "<tr><td><b>created:</b></td><td>"+val.created+"</td></tr>";
-                slice_row += "<tr><td><b>last update:</b></td><td>"+val.last_updated+"</td></tr>";
-                slice_row += "<tr><td><b>expires:</b></td><td>"+val.slice_expires+"</td></tr>";
-                table_slices.push(slice_row);
-            });
-           $("table#slice-tab").html(table_slices.join( "" ));
-           $("div#slice-tab-loaded").css("display","block");
-           $("div#slice-tab-loading").css("display","none");
-        });
-    });
-</script>
+<div class="wrapper">
+       <div class="row">
+               <div class="col-md-12">
+                       {% include theme|add:"_widget-slice-sections.html" %}
+           </div>
+       </div>
+</div>
+<div class="container-fluid tab-content">
+  <div class="tab-pane active row" id="info">...</div>
+  <div class="tab-pane row" id="testbeds">...</div>
+  <div class="tab-pane row" id="resources">...</div>
+  <div class="tab-pane row" id="users">...</div>
+  <div class="tab-pane row" id="statistics">...</div>
+  <div class="tab-pane row" id="measurements">...</div>
+  <div class="tab-pane row" id="experiment">...</div>
+</div>         
 {% endblock %}
diff --git a/portal/templates/onelab/onelab_testbed-list.html b/portal/templates/onelab/onelab_testbed-list.html
deleted file mode 100644 (file)
index b2f6835..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-{% extends "layout_wide.html" %}
-
-{% block content %}
-       <div class="col-md-2"></div>
-       <div class="col-md-10">
-               <div class="row">
-                       {% include theme|add:"_widget-slice-sections.html" %}
-               </div>
-               <div class="row">
-                       <ul class="nav nav-tabs">
-                         <li class="active"><a href="#">Testbeds</a></li>
-                         <li><a href="#"></a></li>
-                         <li><a href="#"></a></li>
-                       </ul>
-               </div>
-               <div id="testbed-list-loading"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading Testbeds" /></div>
-               <div id="testbed-list-loaded" style="display:none;">
-                       <table cellpadding="0" cellspacing="0" border="0" class="table" id="testbedList"></table>
-               </div>
-       </div>
-{% endblock %}
index e637b15..47dea17 100644 (file)
@@ -1,13 +1,23 @@
-<div class="col-md-8 slice-sections">
-       <ul class="nav nav-pills nav-justified">
-               <li {% if section == 'slice' %}class="active"{% endif %}><a href="/slice/{{ slice }}/">{{ slice }}</a></li>
-               <li {% if section == 'testbeds' %}class="active"{% endif %}><a href="/testbeds/{{ slice }}/">Testbeds</a></li>
-               <li {% if section == 'resources' %}class="active"{% endif %}><a href="/resources/{{ slice }}/">Resources</a></li>
-               <li {% if section == 'users' %}class="active"{% endif %}><a href="/users/{{ slice }}/">Users</a></li>
-               <li><a href="">Statistics</a></li>
-               <li><a href="">Measurements</a></li>
-       </ul>
-</div>
-<div class="col-md-4 slice-experiment">
-       <a href="/portal/experiment"><button type="button" class="btn btn-default">Experiment</button></a>
-</div>
+<ul class="nav nav-tabs nav-sliceview">
+       <li {% if section != "resources" %}class="active"{% endif %}>
+               <a href="#info"><img src="{{ STATIC_URL }}icons/slices-xs.png" alt="About MySlice" /> {{ slice }}</a>
+       </li>
+       <li><a href="#testbeds">Testbeds</a></li>
+       <li {% if section == "resources" %}class="active"{% endif %}><a class="link" href="/resources/{{ slice }}">Resources</a></li>
+       <li><a href="#users">Users</a></li>
+       <li><a href="#experiment">Statistics</a></li>
+       <li><a href="#experiment">Measurements</a></li>
+       <li><a href="#experiment" data-toggle="tab">Experiment</a></li>
+</ul>
+<script>
+$(document).ready(function() {
+       $('.nav-sliceview a').click(function (e) {
+               if ($(this).hasClass('link')) return;
+               e.preventDefault();
+               $(this).tab('show');
+       var id = $(this).attr('href').substr(1);        
+       $("#" + id).load('/' + id + '/{{ slice }}/');
+       });
+       $('div#info').load('/info/{{ slice }}/');
+});
+</script>
diff --git a/portal/templates/slice-tab-info.html b/portal/templates/slice-tab-info.html
new file mode 100644 (file)
index 0000000..78be6ff
--- /dev/null
@@ -0,0 +1,50 @@
+<div class="col-md-2">
+</div>
+<div class="col-md-8">
+       <div id="slice-tab-loading"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading Slices" /></div>
+       <div id="slice-tab-loaded" style="display:none;margin-top:15px;">
+           <table id="slice-tab">
+           </table>
+       </div>
+</div>
+<div class="col-md-2">
+</div>
+<script>
+    $(document).ready(function() {
+        $.post("/rest/slice/",{'filters':{'slice_hrn':'{{slice}}'}}, function( data ) {
+            var table_slices = [];
+            /* "slice_hrn", "slice_description", "slice_type", "parent_authority", "created", "nodes", "slice_url", "slice_last_updated", "user", "slice_urn", "slice_expires" */
+            $.each( data, function( key, val ) {
+                if(val.nodes=="undefined" || val.nodes==null){
+                    nodes_length=0;
+                }else{
+                    nodes_length=val.nodes.length;
+                }
+
+                if(val.user=="undefined" || val.user==null){
+                    user_length=0;
+                }else{
+                    user_length=val.user.length;
+                }
+
+                if(val.slice_url=="undefined" || val.slice_url==null){
+                    slice_url="";
+                }else{
+                    slice_url="<a href='"+val.slice_url+"' target='_blank'>"+val.slice_url+"</a>";
+                }
+                
+                slice_row = "<tr><td><b>Description:</b></td><td>"+val.slice_description+"</td></tr>";
+                slice_row += "<tr><td><b>url:</b></td><td><a href='"+val.slice_url+" target='_blank'>"+val.slice_url+"</a></td></tr>";
+                slice_row += "<tr><td><b>users:</b></td><td>"+user_length+"</td></tr>";
+                slice_row += "<tr><td><b>resources:</b></td><td>"+nodes_length+"</td></tr>";
+                slice_row += "<tr><td><b>created:</b></td><td>"+val.created+"</td></tr>";
+                slice_row += "<tr><td><b>last update:</b></td><td>"+val.last_updated+"</td></tr>";
+                slice_row += "<tr><td><b>expires:</b></td><td>"+val.slice_expires+"</td></tr>";
+                table_slices.push(slice_row);
+            });
+           $("table#slice-tab").html(table_slices.join( "" ));
+           $("div#slice-tab-loaded").css("display","block");
+           $("div#slice-tab-loading").css("display","none");
+        });
+    });
+</script>
\ No newline at end of file
diff --git a/portal/templates/slice-tab-testbeds.html b/portal/templates/slice-tab-testbeds.html
new file mode 100644 (file)
index 0000000..e609bcf
--- /dev/null
@@ -0,0 +1,52 @@
+<div class="col-md-2">
+</div>
+<div class="col-md-8">         
+       <div id="testbed-list-loading"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading Testbeds" /></div>
+       <div id="testbed-list-loaded" style="display:none;margin-top:15px;">
+               <table cellpadding="0" cellspacing="0" border="0" class="table" id="testbedList"></table>
+       </div>
+</div>
+<div class="col-md-2">
+</div>
+<script>
+$(document).ready(function() {
+       $.post("/rest/network/", { "fields" : ["network_hrn", "network_longname", "description"]}, function(data) {
+                       var testbed_data = [];
+                       var testbed_row = "<thead>";
+                       testbed_row += "<tr>";
+                       testbed_row += "<th id=testbed_check><input type=\"checkbox\" name=\"network_hrn\" value=\"all\"/></th>";
+                       testbed_row += "<th id=testbed_icon></th>";
+                       testbed_row += "<th>network_hrn</th>";
+                       testbed_row += "<th>Full name</th>";
+                       testbed_row += "<th>Description</th>";
+                       testbed_row += "</tr>";
+                       testbed_row += "</thead>";
+                       testbed_data.push(testbed_row);
+                       $.each( data, function(key, val) {
+                               testbed_row = "<tr data-keys=\""+val.network_hrn+"\" class=\"odd\">"
+                               testbed_row += "<td><input type=\"checkbox\" name=\"network_hrn\" value=\""+val.network_hrn+"\"/></td>";
+                               testbed_row += "<td><img src='/static/img/testbeds/"+val.network_hrn+".png' alt='' /></td>";
+                               testbed_row += "<td>"+val.network_hrn+"</td>";
+                               testbed_row += "<td>"+val.network_longname+"</td>";
+                               testbed_row += "<td>"+val.description+"</td>";
+                               testbed_row += "</thead>";
+       
+                               testbed_data.push(testbed_row);
+                       });
+               $("table#testbedList").html(testbed_data.join(''));
+               $("div#testbed-list-loaded").css("display","block");
+               $("div#testbed-list-loading").css("display","none");
+                       
+               $("input[type=checkbox]").click(function() {
+                       var cnt = 0;
+                       var id = $(this).val();
+                       var row = $(this).parent().parent()
+                       if (row.hasClass("active")) {
+                               row.removeClass("active");
+                       } else {
+                               row.addClass("active");
+                       }
+               });
+       });
+});
+</script>
index f82d865..8ac4609 100644 (file)
@@ -1,15 +1,5 @@
-{# fine for either layout-unfold1.html (logged in) or layout-unfold2.html (needs a login prompt) #}
-{% extends layout_1_or_2 %}
-
-{% block unfold_margin %}
-{% include 'widget-login.html' %}
-{% endblock unfold_margin %}
-
-{% block head %}
-<link rel="stylesheet" type="text/css" href="{{STATIC_URL}}/css/dashboard.css" />
-{% endblock %}
-
-{% block unfold_main %}
+{% extends "layout.html" %}
+{% block content %}
 
 <h1>MySlice Users</h1>
 <div id="middle" align="center">
index 6395465..e8b7b68 100644 (file)
@@ -1,29 +1,36 @@
+from django.contrib.auth        import authenticate, login, logout
+from django.template            import RequestContext
+from django.shortcuts           import render, render_to_response
+
+from manifoldapi.manifoldresult import ManifoldResult
+from ui.topmenu                 import topmenu_items, the_user
+from myslice.configengine       import ConfigEngine
 from manifold.core.query        import Query
 from unfold.page                import Page
-
-from ui.topmenu                 import topmenu_items_live, the_user
 from manifoldapi.manifoldapi    import execute_admin_query
-
-from plugins.querytable         import QueryTable
 from unfold.loginrequired       import LoginRequiredAutoLogoutView
-from theme import ThemeView
-
-from django.shortcuts import render, render_to_response
 
+from theme import ThemeView
 import json
 
-# View for platforms
-class UsersView(LoginRequiredAutoLogoutView, ThemeView):
-    template_name = "usersview.html"
-    def dispatch(self, *args, **kwargs):
-        return super(UsersView, self).dispatch(*args, **kwargs)
+class UsersView (LoginRequiredAutoLogoutView, ThemeView):
+    template_name = 'usersview.html'
+        
+    # expose this so we can mention the backend URL on the welcome page
+    def default_env (self):
+        return { 
+                 'MANIFOLD_URL':ConfigEngine().manifold_url(),
+                 }
+
+    def post (self,request):
+        env = self.default_env()
+        env['theme'] = self.theme
+        return render_to_response(self.template, env, context_instance=RequestContext(request))
 
+    def get (self, request, state=None):
+        env = self.default_env()
+        
 
-    def get_context_data(self, **kwargs):
-        page = Page(self.request)
-        page.add_js_files  ( [ "js/common.functions.js" ] )
-        #platform_query  = Query().get('local:platform').filter_by('disabled', '==', '0').select('platform','platform_longname','gateway_type')
-        #platform_query  = Query().get('local:platform').select('platform','platform_longname','gateway_type')
         email_list = []
         status_list = []
         authority_list = []
@@ -55,20 +62,21 @@ class UsersView(LoginRequiredAutoLogoutView, ThemeView):
         user_list = [{'email': t[0], 'status': t[1], 'authority':t[2]}
             for t in zip(email_list, status_list, authority_list)]
 
-        context = super(UsersView, self).get_context_data(**kwargs)
-        context['person']   = self.request.user
-        context['user_list'] = user_list
-
-        # XXX This is repeated in all pages
-        # more general variables expected in the template
-        context['title'] = 'Users in MySlice'
-        # the menu items on the top
-        # so we can sho who is logged
-        context['username'] = the_user(self.request)
-        context['theme'] = self.theme
+        if request.user.is_authenticated(): 
+            env['person'] = self.request.user
+        else: 
+            env['person'] = None
+    
+        env['theme'] = self.theme
+        env['user_list']= user_list
 
-        context['layout_1_or_2']="layout-unfold2.html" if not context['username'] else "layout-unfold1.html"
-        #prelude_env = page.prelude_env()
-        #context.update(prelude_env)
+        env['username']=the_user(request)
+        env['topmenu_items'] = topmenu_items(None, request)
+        if state: env['state'] = state
+        elif not env['username']: env['state'] = None
+        # use one or two columns for the layout - not logged in users will see the login prompt
+        env['layout_1_or_2']="layout-unfold2.html" if not env['username'] else "layout-unfold1.html"
+        
+        
+        return render_to_response(self.template, env, context_instance=RequestContext(request))
 
-        return render_to_response(self.template)
index b1a8875..d2dd71e 100644 (file)
@@ -23,17 +23,18 @@ def dispatch(request, object_type, object_name):
     elif request.method == 'GET':
         #return error('only post request is supported')
         req_items = request.GET
+    print req_items
     for el in req_items.items():
         
-        print "#===============>",o.params
+        print "#===============>",el
         if el[0].startswith('filters'):
             o.filters[el[0][8:-1]] = el[1]
         elif el[0].startswith('params'):
-            print "#======>", el[0]
-            print "#======>", el[0][7:8]
-            print "#======>", el[0][10:-1]
-            print "#======>", el[1]
-            o.params.append({ el[0][10:-1] : el[1] })
+            print "#======> 0 ", el[0]
+            #print "#======>", el[0][7:8]
+            #print "#======>", el[0][10:-1]
+            print "#======> 1 ", el[1]
+            o.params = req_items.getlist('params[]')
             
             
         elif el[0].startswith('fields'):
diff --git a/ui/static/img/icon_authority_color.png b/ui/static/img/icon_authority_color.png
deleted file mode 100644 (file)
index 27d2343..0000000
Binary files a/ui/static/img/icon_authority_color.png and /dev/null differ
diff --git a/ui/static/img/icon_slices.png b/ui/static/img/icon_slices.png
deleted file mode 100644 (file)
index bd3bc34..0000000
Binary files a/ui/static/img/icon_slices.png and /dev/null differ
diff --git a/ui/static/img/icon_support.png b/ui/static/img/icon_support.png
deleted file mode 100644 (file)
index 0e69ae7..0000000
Binary files a/ui/static/img/icon_support.png and /dev/null differ
diff --git a/ui/static/img/icon_testbed_color.png b/ui/static/img/icon_testbed_color.png
deleted file mode 100644 (file)
index d1169d5..0000000
Binary files a/ui/static/img/icon_testbed_color.png and /dev/null differ
diff --git a/ui/static/img/icon_user_color.png b/ui/static/img/icon_user_color.png
deleted file mode 100644 (file)
index a8ef8c6..0000000
Binary files a/ui/static/img/icon_user_color.png and /dev/null differ
diff --git a/ui/static/img/icon_users_color.png b/ui/static/img/icon_users_color.png
deleted file mode 100644 (file)
index 6cf3888..0000000
Binary files a/ui/static/img/icon_users_color.png and /dev/null differ
index c2001f8..467b816 100644 (file)
 {% insert_str prelude "js/manifold.js" %}
 {% insert_str prelude "css/manifold.css" %}
 {% insert_str prelude "css/plugin.css" %}
+{% insert_str prelude "js/bootstrap.js" %}
+{% insert_str prelude "css/bootstrap.css" %}
+{% insert_str prelude "css/topmenu.css" %}
+{% insert_str prelude "js/logout.js" %}
 <link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/{{ theme }}.css">
 </head>
 <body>
index 4028f1a..151ab1c 100644 (file)
@@ -23,10 +23,10 @@ $(function(){
        $(document).ready(function(){
                {% for message in messages %}
             $("#notifications").notify("create", {
-              title: 'Test Notification',
+              title: 'Notification',
               text: '{{ message }}'
             },{
-              expires: false,
+              expires: true,
               speed: 1000
             });
                {% endfor %}