From 5a40dbe074a307538769ae873e446323d6a75f39 Mon Sep 17 00:00:00 2001 From: Ciro Scognamiglio Date: Thu, 27 Mar 2014 11:51:08 +0100 Subject: [PATCH] changed template paths in settings (takes into account the theme) --- myslice/settings.py | 9 + {portal => myslice}/theme.py | 0 portal/about.py | 2 +- portal/accountview.py | 2 +- portal/actions.py | 2 +- portal/contactview.py | 2 +- portal/dashboardview.py | 2 +- portal/django_passresetview.py | 2 +- portal/documentationview.py | 2 +- portal/homeview.py | 2 +- portal/institution.py | 2 +- portal/joinview.py | 2 +- portal/manageuserview.py | 2 +- portal/platformsview.py | 2 +- portal/platformview.py | 2 +- portal/registrationview.py | 2 +- portal/resourceview.py | 2 +- portal/slicerequestview.py | 2 +- portal/sliceresourceview.py | 2 +- portal/slicetabexperiment.py | 2 +- portal/slicetabinfo.py | 2 +- portal/slicetabtestbeds.py | 2 +- portal/slicetabusers.py | 2 +- portal/sliceview.py | 2 +- portal/sliceviewold.py | 2 +- portal/static/css/fantaastic.css | 480 ++++++++++++++++++ portal/static/img/fantaastic-s.png | Bin 0 -> 14113 bytes portal/static/img/ict_logo-s.png | Bin 0 -> 6864 bytes portal/static/js/myslice.js | 64 +-- portal/supportview.py | 2 +- ...dget-topmenu.html => _widget-topmenu.html} | 0 {ui => portal}/templates/base.html | 4 +- .../fantaastic/fantaastic_widget-topmenu.html | 76 +++ ...menu.html => fed4fire_widget-topmenu.html} | 0 portal/templates/home-view.html | 99 +++- portal/templates/institution-tab-info.html | 0 .../onelab/onelab_widget-topmenu.html | 76 +++ portal/templates/slice-resource-view.html | 3 +- portal/templates/slice-tab-info.html | 2 +- portal/templates/slice-view.html | 3 +- portal/templatetags/__init__.py | 0 portal/templatetags/portal_filters.py | 40 ++ portal/usersview.py | 2 +- portal/validationview.py | 2 +- 44 files changed, 820 insertions(+), 88 deletions(-) rename {portal => myslice}/theme.py (100%) create mode 100644 portal/static/css/fantaastic.css create mode 100644 portal/static/img/fantaastic-s.png create mode 100644 portal/static/img/ict_logo-s.png rename portal/templates/{onelab/onelab__widget-topmenu.html => _widget-topmenu.html} (100%) rename {ui => portal}/templates/base.html (93%) create mode 100644 portal/templates/fantaastic/fantaastic_widget-topmenu.html rename portal/templates/fed4fire/{fed4fire__widget-topmenu.html => fed4fire_widget-topmenu.html} (100%) create mode 100644 portal/templates/institution-tab-info.html create mode 100644 portal/templates/onelab/onelab_widget-topmenu.html create mode 100644 portal/templatetags/__init__.py create mode 100644 portal/templatetags/portal_filters.py diff --git a/myslice/settings.py b/myslice/settings.py index 21c28978..ccf94ddb 100644 --- a/myslice/settings.py +++ b/myslice/settings.py @@ -2,6 +2,7 @@ import os.path + DEBUG = True TEMPLATE_DEBUG = DEBUG @@ -19,6 +20,12 @@ except: import traceback traceback.print_exc() +# themes +from myslice.configengine import ConfigEngine +configEngine = ConfigEngine() +if configEngine.myslice.theme : + theme = configEngine.myslice.theme + # find out HTTPROOT, which is different from ROOT # when deployed from a package # this code is run by collectstatic too, so we cannot @@ -186,6 +193,8 @@ TEMPLATE_DIRS = ( # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. + os.path.join(HTTPROOT,"portal/templates", theme), + os.path.join(HTTPROOT,"portal/templates"), os.path.join(HTTPROOT,"templates"), ) diff --git a/portal/theme.py b/myslice/theme.py similarity index 100% rename from portal/theme.py rename to myslice/theme.py diff --git a/portal/about.py b/portal/about.py index 49a890bb..5080601f 100644 --- a/portal/about.py +++ b/portal/about.py @@ -12,7 +12,7 @@ from manifoldapi.manifoldresult import ManifoldResult from ui.topmenu import topmenu_items, the_user from myslice.configengine import ConfigEngine -from theme import ThemeView +from myslice.theme import ThemeView class AboutView (FreeAccessView, ThemeView): template_name = 'about.html' diff --git a/portal/accountview.py b/portal/accountview.py index 9b0c4666..8243e392 100644 --- a/portal/accountview.py +++ b/portal/accountview.py @@ -11,7 +11,7 @@ from django.http import HttpResponse, HttpResponseRedirec from django.contrib import messages from django.contrib.auth.decorators import login_required -from theme import ThemeView +from myslice.theme import ThemeView # import json, os, re, itertools diff --git a/portal/actions.py b/portal/actions.py index 399cae64..c612b096 100644 --- a/portal/actions.py +++ b/portal/actions.py @@ -8,7 +8,7 @@ from django.contrib.auth.models import User from django.template.loader import render_to_string from django.core.mail import EmailMultiAlternatives -from theme import ThemeView +from myslice.theme import ThemeView theme = ThemeView() diff --git a/portal/contactview.py b/portal/contactview.py index 13450dfd..b89aa753 100644 --- a/portal/contactview.py +++ b/portal/contactview.py @@ -7,7 +7,7 @@ from ui.topmenu import topmenu_items, the_user from portal.forms import ContactForm -from theme import ThemeView +from myslice.theme import ThemeView # splitting the 2 functions done here # GET is for displaying the empty form diff --git a/portal/dashboardview.py b/portal/dashboardview.py index 2b0ab828..06f02f83 100644 --- a/portal/dashboardview.py +++ b/portal/dashboardview.py @@ -11,7 +11,7 @@ from unfold.loginrequired import LoginRequiredAutoLogoutView from ui.topmenu import topmenu_items_live, the_user -from theme import ThemeView +from myslice.theme import ThemeView #This view requires login class DashboardView (LoginRequiredAutoLogoutView, ThemeView): diff --git a/portal/django_passresetview.py b/portal/django_passresetview.py index 7d7f52e9..a0018b0f 100644 --- a/portal/django_passresetview.py +++ b/portal/django_passresetview.py @@ -87,7 +87,7 @@ from portal.actions import manifold_update_user from portal.forms import PassResetForm from portal.actions import manifold_update_user -from theme import ThemeView +from myslice.theme import ThemeView # 4 views for password reset: # - password_reset sends the mail diff --git a/portal/documentationview.py b/portal/documentationview.py index 6a75a629..ccd42fa1 100644 --- a/portal/documentationview.py +++ b/portal/documentationview.py @@ -12,7 +12,7 @@ from manifoldapi.manifoldresult import ManifoldResult from ui.topmenu import topmenu_items, the_user from myslice.configengine import ConfigEngine -from theme import ThemeView +from myslice.theme import ThemeView class DocumentationView (FreeAccessView, ThemeView): template_name = 'documentationview.html' diff --git a/portal/homeview.py b/portal/homeview.py index 14487c96..7c47d99c 100644 --- a/portal/homeview.py +++ b/portal/homeview.py @@ -12,7 +12,7 @@ from manifoldapi.manifoldresult import ManifoldResult from ui.topmenu import topmenu_items, the_user from myslice.configengine import ConfigEngine -from theme import ThemeView +from myslice.theme import ThemeView class HomeView (FreeAccessView, ThemeView): template_name = 'home-view.html' diff --git a/portal/institution.py b/portal/institution.py index 6c55517d..4ee9016b 100644 --- a/portal/institution.py +++ b/portal/institution.py @@ -13,7 +13,7 @@ from manifoldapi.manifoldresult import ManifoldResult from ui.topmenu import topmenu_items, the_user from myslice.configengine import ConfigEngine -from theme import ThemeView +from myslice.theme import ThemeView import json class InstitutionView (FreeAccessView, ThemeView): diff --git a/portal/joinview.py b/portal/joinview.py index abe73f39..a2b8b7d9 100644 --- a/portal/joinview.py +++ b/portal/joinview.py @@ -19,7 +19,7 @@ from manifold.core.query import Query from portal.models import PendingUser,PendingAuthority from portal.actions import authority_get_pi_emails, manifold_add_user,manifold_add_account -from theme import ThemeView +from myslice.theme import ThemeView # since we inherit from FreeAccessView we cannot redefine 'dispatch' # so let's override 'get' and 'post' instead diff --git a/portal/manageuserview.py b/portal/manageuserview.py index 369d6e95..7687d341 100644 --- a/portal/manageuserview.py +++ b/portal/manageuserview.py @@ -10,7 +10,7 @@ from ui.topmenu import topmenu_items_live, the_user from django.http import HttpResponse, HttpResponseRedirect from django.contrib import messages from django.contrib.auth.decorators import login_required -from theme import ThemeView +from myslice.theme import ThemeView # import json, os, re, itertools diff --git a/portal/platformsview.py b/portal/platformsview.py index eef773a3..c31cd174 100644 --- a/portal/platformsview.py +++ b/portal/platformsview.py @@ -5,7 +5,7 @@ from unfold.loginrequired import FreeAccessView from ui.topmenu import topmenu_items_live, the_user from plugins.querytable import QueryTable -from theme import ThemeView +from myslice.theme import ThemeView # View for platforms class PlatformsView(FreeAccessView, ThemeView): diff --git a/portal/platformview.py b/portal/platformview.py index d70c99b5..b0fc3ec7 100644 --- a/portal/platformview.py +++ b/portal/platformview.py @@ -15,7 +15,7 @@ from ui.topmenu import topmenu_items_live, the_user from plugins.querytable import QueryTable from myslice.configengine import ConfigEngine -from theme import ThemeView +from myslice.theme import ThemeView # View for 1 platform and its details class PlatformView(FreeAccessView, ThemeView): diff --git a/portal/registrationview.py b/portal/registrationview.py index 9f5f39f4..396d357b 100644 --- a/portal/registrationview.py +++ b/portal/registrationview.py @@ -17,7 +17,7 @@ from manifold.core.query import Query from portal.models import PendingUser from portal.actions import create_pending_user -from theme import ThemeView +from myslice.theme import ThemeView # since we inherit from FreeAccessView we cannot redefine 'dispatch' # so let's override 'get' and 'post' instead diff --git a/portal/resourceview.py b/portal/resourceview.py index a407725a..d670645b 100644 --- a/portal/resourceview.py +++ b/portal/resourceview.py @@ -10,7 +10,7 @@ from plugins.lists.simplelist import SimpleList from plugins.slicestat import SliceStat from myslice.configengine import ConfigEngine -from theme import ThemeView +from myslice.theme import ThemeView # View for 1 platform and its details class ResourceView(FreeAccessView, ThemeView): diff --git a/portal/slicerequestview.py b/portal/slicerequestview.py index dfa46585..fc093d12 100644 --- a/portal/slicerequestview.py +++ b/portal/slicerequestview.py @@ -10,7 +10,7 @@ from portal.forms import SliceRequestForm from unfold.loginrequired import LoginRequiredAutoLogoutView from ui.topmenu import topmenu_items_live, the_user -from theme import ThemeView +from myslice.theme import ThemeView import json, time diff --git a/portal/sliceresourceview.py b/portal/sliceresourceview.py index afd95312..bdffa3fe 100644 --- a/portal/sliceresourceview.py +++ b/portal/sliceresourceview.py @@ -18,7 +18,7 @@ from plugins.googlemap import GoogleMap from plugins.queryupdater import QueryUpdater from plugins.testbeds import TestbedsPlugin -from theme import ThemeView +from myslice.theme import ThemeView class SliceResourceView (LoginRequiredView, ThemeView): template_name = "slice-resource-view.html" diff --git a/portal/slicetabexperiment.py b/portal/slicetabexperiment.py index cd1d6adb..cca8afbd 100644 --- a/portal/slicetabexperiment.py +++ b/portal/slicetabexperiment.py @@ -12,7 +12,7 @@ from manifoldapi.manifoldresult import ManifoldResult from ui.topmenu import topmenu_items, the_user from myslice.configengine import ConfigEngine -from theme import ThemeView +from myslice.theme import ThemeView class ExperimentView (FreeAccessView, ThemeView): template_name = 'slice-tab-experiment.html' diff --git a/portal/slicetabinfo.py b/portal/slicetabinfo.py index 7e7b78ea..fc7fa291 100644 --- a/portal/slicetabinfo.py +++ b/portal/slicetabinfo.py @@ -14,7 +14,7 @@ from unfold.page import Page from manifold.core.query import Query, AnalyzedQuery from manifoldapi.manifoldapi import execute_query -from theme import ThemeView +from myslice.theme import ThemeView class SliceInfoView (LoginRequiredView, ThemeView): template_name = "slice-tab-info.html" diff --git a/portal/slicetabtestbeds.py b/portal/slicetabtestbeds.py index a93f6787..abd6ce65 100644 --- a/portal/slicetabtestbeds.py +++ b/portal/slicetabtestbeds.py @@ -3,7 +3,7 @@ from django.shortcuts import render_to_response from unfold.loginrequired import LoginRequiredView -from theme import ThemeView +from myslice.theme import ThemeView class SliceTabTestbeds (LoginRequiredView, ThemeView): template_name = "slice-tab-testbeds.html" diff --git a/portal/slicetabusers.py b/portal/slicetabusers.py index e1a1742f..861b0cbe 100644 --- a/portal/slicetabusers.py +++ b/portal/slicetabusers.py @@ -14,7 +14,7 @@ from unfold.page import Page from manifold.core.query import Query, AnalyzedQuery from manifoldapi.manifoldapi import execute_query -from theme import ThemeView +from myslice.theme import ThemeView class SliceUserView (LoginRequiredView, ThemeView): template_name = "slice-tab-users-view.html" diff --git a/portal/sliceview.py b/portal/sliceview.py index 008222c1..10cab7cd 100644 --- a/portal/sliceview.py +++ b/portal/sliceview.py @@ -14,7 +14,7 @@ from unfold.page import Page from manifold.core.query import Query, AnalyzedQuery from manifoldapi.manifoldapi import execute_query -from theme import ThemeView +from myslice.theme import ThemeView class SliceView (LoginRequiredView, ThemeView): template_name = "slice-view.html" diff --git a/portal/sliceviewold.py b/portal/sliceviewold.py index e7991537..7cf80f93 100644 --- a/portal/sliceviewold.py +++ b/portal/sliceviewold.py @@ -31,7 +31,7 @@ from plugins.slicestat import SliceStat from myslice.configengine import ConfigEngine -from theme import ThemeView +from myslice.theme import ThemeView tmp_default_slice='ple.upmc.myslicedemo' diff --git a/portal/static/css/fantaastic.css b/portal/static/css/fantaastic.css new file mode 100644 index 00000000..07a77eb6 --- /dev/null +++ b/portal/static/css/fantaastic.css @@ -0,0 +1,480 @@ +html { height: 100% } + +body { + background-color:white; + color:black; + margin:0; + padding:0; + height: 100%; +} +a, a:active, a:focus { + outline: 0; +} + +h1 { + border-bottom:1px solid #DDDDDD; + padding:0 0 0 0; + margin:0 0 0 0; + font-size:18pt; +} +h1 img { + vertical-align:middle; + margin-bottom:6px; +} +h2 { + font-size:14pt; + color:#333333; +} +h3 { + font-size:13pt; + color:#201E62; +} + +div.wrapper { + width:980px; + margin:0 auto; + position:relative; +} +div.container { + width:980px; + margin:25px auto; +} +div.wide { + margin:25px auto; + padding:0 25px; +} + +span.label { + font-size:11pt; + color:gray; + font-weight:normal; + padding:0; +} +/***** Notifications *****/ +.warning { + border: 1px solid red; + margin: 20px 60px; + padding: 10px 20px; + color: red; + background-color: #f2dbdb; + text-align: center; +} +/* HEADER */ +div#header { + height:100px; + background-color:white; +} + +div#secondary { + +} + +div#secondary ul { + position:absolute; + top:20px; + right:0; +} + +div#secondary li { + font-size:10pt; + float:left; + list-style:none; + margin-right:30px; +} +div#secondary li a { + color:black; +} +div#secondary li a:hover { + color:#270A5A; + text-decoration:none; +} +div#secondary li:last-child { + margin-right:0; +} + +div#navigation { + background-color:black; + width:100%; + height:40px; +} +div#navigation div.wrapper { + text-align:center; +} +div#navigation ul { + margin:0; + padding:0; + display: inline-block; + list-style-type: none; + white-space: nowrap; +} + +div#navigation li { + color:white; + font-family:helvetica, sans-serif; + font-size:10pt ; + font-weight:normal; + line-height:0.8em; + letter-spacing:0.6pt; + list-style:none; + float:left; + padding:0; + margin:15px 50px 0 0; +} +div#navigation li a { + color:white; +} +div#navigation li a:hover { + text-decoration:none; + color:#B8B2FF; +} +div#navigation li:last-child { + margin-right:0; +} + +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; + margin:0 auto 25px auto; +} +div#home-dashboard table { + margin:25px; + width:100%; +} +div#home-dashboard table td { + text-align:center; + padding:15px 0; + width:33%; +} +div#home-dashboard table tr:first-child td { + font-size:12pt; + font-weight:bold; + color:#270A5A; +} +div#home-dashboard table tr:last-child td { + vertical-align:top; + padding:25px 0; +} +div#home-dashboard table tr:last-child td.logged-in { + border-right:1px solid #DDDDDD; + padding:25px; +} +div#home-dashboard table tr:last-child td.support { + border-left:1px solid #DDDDDD; + padding:25px; +} +div#home-dashboard table tr:last-child td:first-child { +} +div#home-dashboard table tr:last-child td:last-child { + border-right:0; +} +div#home-dashboard table tr:last-child td.logged-in div { + text-align:left; + padding:25px 0; +} +div#home-dashboard table tr:last-child td.support div { + text-align:left; + padding:25px 0; +} +div#home-dashboard div.login-widget { + padding:20px; +} +div#home-dashboard table td.support { +} +div#home-dashboard table td.support a { +} +div#home-dashboard table td.support a:hover { + text-decoration:none; +} + +div#home-dashboard div#manager { + display:none; +} + +div#home-dashboard div#home-slice-list { + margin:25px 0; + padding:0 25px; + text-align:left; +} +div#home-dashboard div#home-slice-list ul { + list-style: none; + padding:0; + margin:0; +} +div#home-dashboard div#home-slice-list li { + +} + +.login-submit { + vertical-align:middle; + padding:0; +} +.lost-password { + font-size:10pt; + color:#CCCCCC; + text-align:right; + padding:0px; +} +.lost-password a { +} +.login-signup { + border-top:1px solid #CCCCCC; + text-align:center; + margin-top:15px; + padding:5px 0 0 0; +} +/**/ + +/**/ +/* WELL */ +div.well { +} +/**/ +/* BUTTON */ +.btn.btn-default { + font-weight: bold; +} + +.btn.btn-default:hover { + font-weight: bold; +} +/**/ +/* TABLE */ +table.table { + margin:0; +} +table.table thead { + padding:0; +} +table.table tbody { + padding:0; +} +table.table tr { + padding:0; +} +table.table td { + padding:0; +} +/* INSTITUTION */ +div#institution { + color:black; +} +.form-hint { + font-size:11pt; + font-style:italic; + color:gray; +} + + +.form-hint { + font-size:11pt; + font-style:italic; + color:gray; +} + + + +/* TICKET REQUEST */ +div#ticket-request { + color:black; +} +.form-hint { + font-size:11pt; + font-style:italic; + color:gray; +} +div#ticket-request p { + margin:20px 0; +} + +ul.nav-tabs {} +ul.nav-tabs ul {} +ul.nav-tabs li {} + +ul.nav-section li a { + border-bottom:0; +} +ul.nav-section li:first-child { + padding:0; +} +ul.nav-section li:first-child a { + font-weight:bold; + padding:6px 15px 4px 15px; +} +ul.nav-section li:first-child.active a { + padding:6px 15px 3px 15px; +} +ul.nav-section 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; +} + + +/* SLICE VIEW */ + + +div#slice-view { + margin:0; +} +div.list-group-item { + border:0; + background-color:white; + font-weight:bold; + padding-left:0; +} +a.list-group-item { + border:0; + background-color:white; + padding:3px 0 3px 10px; + border-left:2pt white solid; +} +a.list-group-item.active, a.list-group-item.active:hover { + font-weight: bold; + color:black; + background-color:transparent; + border-left:2pt blue solid; +} +a.list-group-item.active:hover { + background-color:#dddddd; +} +a.list-group-item:hover { + border-left:2pt blue solid; +} +a.list-group-item p.list-group-item-text { + font-size:9pt; + font-style:italic; + font-weight: normal; + color: black !important; +} + +div#slice-info { + margin-top:25px; +} +div#slice-info table { + width:100%; + margin:0 auto; +} +div#slice-info table td:first-child { + text-align:right; + font-weight:bold; + padding-right:15px; +} +div#slice-info td { + padding:5px; +} + +/* SLICE VIEW sections */ +.slice-sections, .slice-pending { + margin:0; + padding:0; +} +.slice-sections ul, .slice-pending ul { + margin:0; + padding:0; +} +.slice-pending ul { + width:400px; + margin:0 auto 15px auto; +} +.slice-sections li { + text-align:left; + margin:0; + padding:0; +} +.slice-pending li { + padding-right:15px; +} +.slice-sections li a, .slice-pending li a { + font-size:14px; + color:black; + padding:0; +} +.slice-sections li.active a, .slice-pending li.active a { + color:#201E62; + background-color:#EFEFEF; + text-decoration:underline; + padding:0; +} +.slice-sections ul.nav-pills li a:hover, .slice-pending ul.nav-pills li a:hover { + text-decoration:underline; + background-color:#EFEFEF; + color:black; +} +.slice-sections ul.nav-pills li.active, .slice-pending ul.nav-pills li.active { + +} +.slice-sections li:first-child, .slice-sections li:first-child a { + color:#201E62; + font-weight:bold; +} +.slice-experiment { + text-align:right; + padding:0; +} +.slice-experiment button { + margin:3px 0 0 0; + background-color:#CC4125; + color:white; +} + +.slice-pending { +} +.slice-pending button { + font-size:9pt; + margin:-2px 0 0 0; + padding:3px 5px; +} +.slice-pending button.apply { +} +.slice-pending button.clear { +} +tr.active, tr.active td { + background-color:#FFFFCC !important; +} +div.dataTables_filter label{ + float:left; + width:400px; +} diff --git a/portal/static/img/fantaastic-s.png b/portal/static/img/fantaastic-s.png new file mode 100644 index 0000000000000000000000000000000000000000..ea33949ddbb1f82183d87ef41bcfd77e91705742 GIT binary patch literal 14113 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 ZQnAu%yl?eb~N!!cH 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 literal 0 HcmV?d00001 diff --git a/portal/static/js/myslice.js b/portal/static/js/myslice.js index 7038e53e..c7c32d20 100644 --- a/portal/static/js/myslice.js +++ b/portal/static/js/myslice.js @@ -6,24 +6,6 @@ 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); @@ -60,14 +42,14 @@ function resources() { }; }; -function users() { +function leases() { this.pending = { toremove: new list(), toadd: new list(), }; }; -function leases() { +function users() { this.pending = { toremove: new list(), toadd: new list(), @@ -83,27 +65,19 @@ function slice(name) { 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 = {}; +function user(user) { + this.user = user; + this.testbeds = new list(); + this.slices = new list(); - for (i = 0; i < this.u.slices.length; i++) { - this.slices[this.u.slices[i]] = new slice(this.u.slices[i]); + for (i = 0; i < this.user.slices.length; i++) { + this.slices[this.user.slices[i]] = new slice(this.user.slices[i]); } }; @@ -113,7 +87,7 @@ user.prototype.slice = function(name) { user.prototype.list = function() { for (s in this.slices) { - for (o in s) { + for (o in s) { if (typeof o != 'function') { console.log(o); } else { @@ -128,7 +102,21 @@ user.prototype.list = function() { */ var myslice = { user: {}, - + + user: function() { + if ($.isEmptyObject(this.user)) { + //this.login(function() { return this.user; }); + } else { + return this.user; + } + }, + + login: function(fn) { + $.post("/rest/user/",{'filters':{'user_hrn':'$user_hrn'}}, function( data ) { + myslice.user = new user(data[0]); + }); + }, + getSlices: function(name) { }, @@ -197,6 +185,8 @@ var myslice = { $(document).ready(function() { + //console.log(myslice.user().slices); + // $.post("/rest/user/",{'filters':{'user_hrn':'$user_hrn'}}, function(data) { // myslice.user = new user(data[0]); // console.log(myslice.user.slices); diff --git a/portal/supportview.py b/portal/supportview.py index bbb5b495..f42bbd87 100644 --- a/portal/supportview.py +++ b/portal/supportview.py @@ -12,7 +12,7 @@ from manifoldapi.manifoldresult import ManifoldResult from ui.topmenu import topmenu_items, the_user from myslice.configengine import ConfigEngine -from theme import ThemeView +from myslice.theme import ThemeView class SupportView (FreeAccessView, ThemeView): template_name = 'supportview.html' diff --git a/portal/templates/onelab/onelab__widget-topmenu.html b/portal/templates/_widget-topmenu.html similarity index 100% rename from portal/templates/onelab/onelab__widget-topmenu.html rename to portal/templates/_widget-topmenu.html diff --git a/ui/templates/base.html b/portal/templates/base.html similarity index 93% rename from ui/templates/base.html rename to portal/templates/base.html index 85139519..6dc48e73 100644 --- a/ui/templates/base.html +++ b/portal/templates/base.html @@ -1,3 +1,4 @@ +{% load portal_filters %} {# This is required by insert_above #}{% insert_handler %} OneLab - {{ section }} @@ -8,6 +9,7 @@ + @@ -33,7 +35,7 @@ {% block container %} {% block topmenu %} - {% include theme|add:"__widget-topmenu.html" %} + {% widget "_widget-topmenu.html" %} {% endblock topmenu %} {% include 'messages-transient.html' %} {% block base_content %} diff --git a/portal/templates/fantaastic/fantaastic_widget-topmenu.html b/portal/templates/fantaastic/fantaastic_widget-topmenu.html new file mode 100644 index 00000000..de37b04c --- /dev/null +++ b/portal/templates/fantaastic/fantaastic_widget-topmenu.html @@ -0,0 +1,76 @@ + + + diff --git a/portal/templates/fed4fire/fed4fire__widget-topmenu.html b/portal/templates/fed4fire/fed4fire_widget-topmenu.html similarity index 100% rename from portal/templates/fed4fire/fed4fire__widget-topmenu.html rename to portal/templates/fed4fire/fed4fire_widget-topmenu.html diff --git a/portal/templates/home-view.html b/portal/templates/home-view.html index c88902d2..453ed2fa 100644 --- a/portal/templates/home-view.html +++ b/portal/templates/home-view.html @@ -1,13 +1,13 @@ {% extends "layout.html" %} +{% load portal_filters %} {% block content %} - -
+
-
+
@@ -15,49 +15,106 @@ - - + + -
ACCOUNTSUPPORT
- {% include '_widget-login-user.html' %} + {% if person %} + + +
+ {% if person.last_name %} + {{person.first_name}} {{person.last_name}}
+ {% endif %} + Email: {{person.email}} +
+ {% else %} +
+ {% widget '_widget-login-user.html' %} + {% endif %} - + {% if person %} + +
Loading Slices
+ {% else %} + {% endif %}
- - + +
-
+
- + - - + + -
INSTITUTION SLICESSUPPORTREQUESTS
- {% include '_widget-login-manager.html' %} + {% if person %} + + + {% else %} + + {% widget '_widget-login-manager.html' %} + {% endif %} - + {% if person %} + + {% endif %} - - + {% if person %} + + {% endif %}
+ {% endblock %} diff --git a/portal/templates/institution-tab-info.html b/portal/templates/institution-tab-info.html new file mode 100644 index 00000000..e69de29b diff --git a/portal/templates/onelab/onelab_widget-topmenu.html b/portal/templates/onelab/onelab_widget-topmenu.html new file mode 100644 index 00000000..4ed429ad --- /dev/null +++ b/portal/templates/onelab/onelab_widget-topmenu.html @@ -0,0 +1,76 @@ + + + diff --git a/portal/templates/slice-resource-view.html b/portal/templates/slice-resource-view.html index 1c00cb8a..69f8bc14 100644 --- a/portal/templates/slice-resource-view.html +++ b/portal/templates/slice-resource-view.html @@ -1,4 +1,5 @@ {% extends "layout_wide.html" %} +{% load portal_filters %} {% block head %} @@ -24,7 +25,7 @@
- {% include theme|add:"_widget-slice-sections.html" %} + {% widget '_widget-slice-sections.html' %}