You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by ma...@apache.org on 2019/06/19 23:03:23 UTC

[airavata-django-portal] branch master updated: AIRAVATA-2934 Switch to metadata for side navigation

This is an automated email from the ASF dual-hosted git repository.

machristie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/airavata-django-portal.git


The following commit(s) were added to refs/heads/master by this push:
     new 4922798  AIRAVATA-2934 Switch to metadata for side navigation
4922798 is described below

commit 492279842f946305a40d3fcfbcb132040a506878
Author: Marcus Christie <ma...@apache.org>
AuthorDate: Wed Jun 19 18:59:41 2019 -0400

    AIRAVATA-2934 Switch to metadata for side navigation
---
 django_airavata/apps/admin/apps.py                 | 38 ++++++++++++++
 .../apps/admin/templates/admin/admin_base.html     | 29 -----------
 django_airavata/apps/dataparsers/apps.py           |  7 +++
 .../django_airavata_dataparsers/base.html          |  9 ----
 django_airavata/apps/groups/apps.py                |  7 +++
 .../templates/django_airavata_groups/base.html     |  8 ---
 django_airavata/apps/workspace/apps.py             | 26 ++++++++++
 .../templates/django_airavata_workspace/base.html  | 16 ------
 django_airavata/context_processors.py              | 58 +++++++++++++++-------
 django_airavata/settings.py                        |  7 ++-
 django_airavata/templates/base.html                | 13 +++++
 11 files changed, 135 insertions(+), 83 deletions(-)

diff --git a/django_airavata/apps/admin/apps.py b/django_airavata/apps/admin/apps.py
index d7640f4..93cb6e4 100644
--- a/django_airavata/apps/admin/apps.py
+++ b/django_airavata/apps/admin/apps.py
@@ -12,3 +12,41 @@ class AdminConfig(AiravataAppConfig):
     app_description = """
         Configure and share resources with other users.
     """
+    nav = [
+        {
+            'label': 'Application Catalog',
+            'icon': 'fa fa-cogs',
+            'url': 'django_airavata_admin:app_catalog',
+            'active_prefixes': ['applications']
+        },
+        {
+            'label': 'Manage Users',
+            'icon': 'fa fa-users',
+            'url': 'django_airavata_admin:users',
+            'active_prefixes': ['users']
+        },
+        {
+            'label': 'Experiment Statistics',
+            'icon': 'fa fa-chart-bar',
+            'url': 'django_airavata_admin:experiment-statistics',
+            'active_prefixes': ['experiment-statistics']
+        },
+        {
+            'label': 'Credential Store',
+            'icon': 'fa fa-lock',
+            'url': 'django_airavata_admin:credential_store',
+            'active_prefixes': ['credentials']
+        },
+        {
+            'label': 'Group Resource Profile',
+            'icon': 'fa fa-server',
+            'url': 'django_airavata_admin:group_resource_profile',
+            'active_prefixes': ['group-resource-profiles']
+        },
+        {
+            'label': 'Gateway Resource Profile',
+            'icon': 'fa fa-tasks',
+            'url': 'django_airavata_admin:gateway_resource_profile',
+            'active_prefixes': ['gateway-resource-profile']
+        },
+    ]
diff --git a/django_airavata/apps/admin/templates/admin/admin_base.html b/django_airavata/apps/admin/templates/admin/admin_base.html
index 9b48f21..feca5ca 100644
--- a/django_airavata/apps/admin/templates/admin/admin_base.html
+++ b/django_airavata/apps/admin/templates/admin/admin_base.html
@@ -7,35 +7,6 @@
 {% render_bundle 'chunk-vendors' 'css' 'ADMIN' %}
 {% render_bundle 'app' 'css' 'ADMIN' %}
 <link rel=stylesheet type=text/css href={% static 'django_airavata_admin/static/css/admin.css' %}> {% endblock %}
-{% block nav-items %}
-
-        {% if request.is_gateway_admin or request.is_read_only_gateway_admin %}
-        <a href="{% url 'django_airavata_admin:app_catalog' %}" class="c-nav__item {% if request.active_nav_item == 'app_catalog' %}is-active{% endif %}" data-toggle=tooltip data-placement=right title="Application Catalog">
-            <i class="fa fa-cogs"></i> <span class=sr-only>Application Catalog</span>
-        </a>
-        {% endif %}
-        {% if request.is_gateway_admin %}
-        <a href="{% url 'django_airavata_admin:users' %}" class="c-nav__item {% if request.active_nav_item == 'users' %}is-active{% endif %}" data-toggle=tooltip data-placement=right title="Manage Users">
-            <i class="fa fa-users"></i> <span class=sr-only>Manage Users</span>
-        </a>
-        {% endif %}
-        {% if request.is_gateway_admin or request.is_read_only_gateway_admin %}
-        <a href="{% url 'django_airavata_admin:experiment-statistics' %}" class="c-nav__item {% if request.active_nav_item == 'experiment-statistics' %}is-active{% endif %}" data-toggle=tooltip data-placement=right title="Experiment Statistics">
-            <i class="fa fa-chart-bar"></i> <span class=sr-only>Experiment Statistics</span>
-        </a>
-        {% endif %}
-        <a href="{% url 'django_airavata_admin:credential_store' %}" class="c-nav__item {% if request.active_nav_item == 'credential_store' %}is-active{% endif %}" data-toggle=tooltip data-placement=right title="Credential Store">
-            <i class="fa fa-lock"></i> <span class=sr-only>Credential Store</span>
-        </a>
-        <a href="{% url 'django_airavata_admin:group_resource_profile' %}" class="c-nav__item {% if request.active_nav_item == 'group_resource_profile' %}is-active{% endif %}" data-toggle=tooltip data-placement=right title="Group Resource Profile">
-            <i class="fa fa-server"></i> <span class=sr-only>Group Resource Profile</span>
-        </a>
-        {% if request.is_gateway_admin %}
-        <a href="{% url 'django_airavata_admin:gateway_resource_profile' %}" class="c-nav__item {% if request.active_nav_item == 'gateway_resource_profile' %}is-active{% endif %}" data-toggle=tooltip data-placement=right title="Gateway Resource Profile">
-            <i class="fa fa-tasks"></i> <span class=sr-only>Gateway Resource Profile</span>
-        </a>
-        {% endif %}
-{% endblock %}
 {% block scripts %}
     {{ block.super }}
     {% render_bundle 'chunk-vendors' 'js' 'ADMIN' %}
diff --git a/django_airavata/apps/dataparsers/apps.py b/django_airavata/apps/dataparsers/apps.py
index 02d3793..834e2ec 100644
--- a/django_airavata/apps/dataparsers/apps.py
+++ b/django_airavata/apps/dataparsers/apps.py
@@ -12,3 +12,10 @@ class DataParsersConfig(AiravataAppConfig):
         Define data parsers for post-processing experimental and ad-hoc
         datasets.
     """
+    nav = [
+        {
+            'label': 'Home',
+            'icon': 'fa fa-home',
+            'url': 'django_airavata_dataparsers:home',
+        },
+    ]
diff --git a/django_airavata/apps/dataparsers/templates/django_airavata_dataparsers/base.html b/django_airavata/apps/dataparsers/templates/django_airavata_dataparsers/base.html
index b129520..24fac9b 100644
--- a/django_airavata/apps/dataparsers/templates/django_airavata_dataparsers/base.html
+++ b/django_airavata/apps/dataparsers/templates/django_airavata_dataparsers/base.html
@@ -11,15 +11,6 @@
 {% render_bundle bundle_name 'css' 'DATAPARSERS' %}
 {% endblock %}
 
-{% block nav-items %}
-
-        <a href="{% url 'django_airavata_dataparsers:home' %}"
-            class="c-nav__item {% if request.active_nav_item == 'home' %}is-active{% endif %}"
-            data-toggle=tooltip data-placement=right title="Home">
-            <i class="fa fa-home"></i> <span class=sr-only>Home</span>
-        </a>
-{% endblock %}
-
 {% block content %}
 <div id="{{ bundle_name }}"/>
 {% endblock content %}
diff --git a/django_airavata/apps/groups/apps.py b/django_airavata/apps/groups/apps.py
index b0c8744..f1e5e6f 100755
--- a/django_airavata/apps/groups/apps.py
+++ b/django_airavata/apps/groups/apps.py
@@ -11,3 +11,10 @@ class GroupsConfig(AiravataAppConfig):
     app_description = """
         Create and manage user groups.
     """
+    nav = [
+        {
+            'label': 'Groups',
+            'icon': 'fa fa-users',
+            'url': 'django_airavata_groups:manage',
+        },
+    ]
diff --git a/django_airavata/apps/groups/templates/django_airavata_groups/base.html b/django_airavata/apps/groups/templates/django_airavata_groups/base.html
index 1d7ae26..7763f08 100755
--- a/django_airavata/apps/groups/templates/django_airavata_groups/base.html
+++ b/django_airavata/apps/groups/templates/django_airavata_groups/base.html
@@ -9,14 +9,6 @@
 {% render_bundle bundle_name 'css' 'GROUPS' %}
 {% endblock %}
 
-{% block nav-items %}
-
-        <a href="{% url 'django_airavata_groups:manage' %}" class="c-nav__item {% if request.active_nav_item == 'manage' %}is-active{% endif %}" data-toggle=tooltip data-placement=right title=Groups>
-            <i class="fa fa-users"></i> <span class=sr-only>Groups</span>
-        </a>
-
-{% endblock %}
-
 {% block content %}
 <div id="{{ bundle_name }}"/>
 {% endblock content %}
diff --git a/django_airavata/apps/workspace/apps.py b/django_airavata/apps/workspace/apps.py
index ff14232..368fa12 100644
--- a/django_airavata/apps/workspace/apps.py
+++ b/django_airavata/apps/workspace/apps.py
@@ -11,6 +11,32 @@ class WorkspaceConfig(AiravataAppConfig):
     app_description = """
         Launch applications and manage your experiments and projects.
     """
+    nav = [
+        {
+            'label': 'Dashboard',
+            'icon': 'fa fa-tachometer-alt',
+            'url': 'django_airavata_workspace:dashboard',
+            'active_prefixes': ['applications', 'dashboard']
+        },
+        {
+            'label': 'Experiments',
+            'icon': 'fa fa-flask',
+            'url': 'django_airavata_workspace:experiments',
+            'active_prefixes': ['experiments']
+        },
+        {
+            'label': 'Projects',
+            'icon': 'fa fa-box',
+            'url': 'django_airavata_workspace:projects',
+            'active_prefixes': ['projects']
+        },
+        {
+            'label': 'Storage',
+            'icon': 'fa fa-folder-open',
+            'url': 'django_airavata_workspace:storage',
+            'active_prefixes': ['storage']
+        },
+    ]
 
     def ready(self):
         import django_airavata.apps.workspace.signals  # noqa
diff --git a/django_airavata/apps/workspace/templates/django_airavata_workspace/base.html b/django_airavata/apps/workspace/templates/django_airavata_workspace/base.html
index fe3d726..2a12d15 100644
--- a/django_airavata/apps/workspace/templates/django_airavata_workspace/base.html
+++ b/django_airavata/apps/workspace/templates/django_airavata_workspace/base.html
@@ -9,22 +9,6 @@
 {% render_bundle bundle_name 'css' 'WORKSPACE' %}
 {% endblock %}
 
-{% block nav-items %}
-
-        <a href="{% url 'django_airavata_workspace:dashboard' %}" class="c-nav__item {% if request.active_nav_item == 'dashboard' %}is-active{% endif %}" data-toggle=tooltip data-placement=right title=Dashboard>
-            <i class="fa fa-tachometer-alt"></i> <span class=sr-only>Dashboard</span>
-        </a>
-        <a href="{% url 'django_airavata_workspace:experiments' %}" class="c-nav__item {% if request.active_nav_item == 'experiments' %}is-active{% endif %}" data-toggle=tooltip data-placement=right title=Experiments>
-            <i class="fa fa-flask"></i> <span class=sr-only>Experiments</span>
-        </a>
-        <a href="{% url 'django_airavata_workspace:projects' %}" class="c-nav__item {% if request.active_nav_item == 'projects' %}is-active{% endif %}" data-toggle=tooltip data-placement=right title=Projects>
-            <i class="fa fa-box"></i> <span class=sr-only>Projects</span>
-        </a>
-        <a href="{% url 'django_airavata_workspace:storage' %}" class="c-nav__item {% if request.active_nav_item == 'storage' %}is-active{% endif %}" data-toggle=tooltip data-placement=right title=Storage>
-            <i class="fa fa-folder-open"></i> <span class=sr-only>Storage</span>
-        </a>
-{% endblock %}
-
 {% block content %}
 <div id="{{ bundle_name }}"/>
 {% endblock content %}
diff --git a/django_airavata/context_processors.py b/django_airavata/context_processors.py
index 6970cf5..8e61532 100644
--- a/django_airavata/context_processors.py
+++ b/django_airavata/context_processors.py
@@ -1,4 +1,6 @@
+import copy
 import logging
+import re
 
 from django.apps import apps
 from django.conf import settings
@@ -16,9 +18,13 @@ def airavata_app_registry(request):
     airavata_apps.sort(
         key=lambda app: "{:09}-{}".format(app.app_order,
                                           app.verbose_name.lower()))
+    current_app = _get_current_app(request, airavata_apps)
+
     return {
         'airavata_apps': airavata_apps,
-        'current_airavata_app': _get_current_app(request, airavata_apps),
+        'current_airavata_app': current_app,
+        'airavata_app_nav': (_get_app_nav(request, current_app)
+                             if current_app else None)
     }
 
 
@@ -28,24 +34,11 @@ def custom_app_registry(request):
     custom_apps.sort(key=lambda app: app.verbose_name.lower())
     current_custom_app = _get_current_app(request, custom_apps)
     return {
-        'custom_apps': list(map(_app_to_dict, custom_apps)),
-        'current_custom_app': _app_to_dict(current_custom_app)
-    }
-
-
-def _app_to_dict(app):
-    # For some reason adding the AppConfig instance directly to the context
-    # doesn't allow its properties to be read. This code converts it into a
-    # simple dict.
-    if not app:
-        return None
-    return {
-        'name': app.name,
-        'label': app.label,
-        'verbose_name': app.verbose_name,
-        'url_home': app.url_home,
-        'fa_icon_class': app.fa_icon_class,
-        'app_description': app.app_description,
+        # 'custom_apps': list(map(_app_to_dict, custom_apps)),
+        'custom_apps': custom_apps,
+        'current_custom_app': current_custom_app,
+        'custom_app_nav': (_get_app_nav(request, current_custom_app)
+                           if current_custom_app else None)
     }
 
 
@@ -57,6 +50,33 @@ def _get_current_app(request, apps):
     return current_app[0] if len(current_app) > 0 else None
 
 
+def _get_app_nav(request, current_app):
+    if hasattr(current_app, 'nav'):
+        nav = copy.copy(current_app.nav)
+        # convert "/djangoapp/path/in/app" to "path/in/app"
+        app_path = "/".join(request.path.split("/")[2:])
+        for nav_item in nav:
+            if 'active_prefixes' in nav_item:
+                if re.match("|".join(nav_item['active_prefixes']), app_path):
+                    nav_item['active'] = True
+                else:
+                    nav_item['active'] = False
+            else:
+                # 'active_prefixes' is optional, and if not specified, assume
+                # current item is active
+                nav_item['active'] = True
+    else:
+        # Default to the home view in the app
+        nav = [
+            {
+                'label': current_app.verbose_name,
+                'icon': 'fa ' + current_app.fa_icon_class,
+                'url': current_app.url_home
+            }
+        ]
+    return nav
+
+
 def resolver_match(request):
     """Put resolver_match (ResolverMatch instance) into the context."""
     return {'resolver_match': request.resolver_match}
diff --git a/django_airavata/settings.py b/django_airavata/settings.py
index 0aec9e2..4939467 100644
--- a/django_airavata/settings.py
+++ b/django_airavata/settings.py
@@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/1.10/ref/settings/
 """
 
 import os
+from importlib import import_module
 
 from pkg_resources import iter_entry_points
 
@@ -93,8 +94,10 @@ CUSTOM_DJANGO_APPS = []
 #    )
 #
 for entry_point in iter_entry_points(group='airavata.djangoapp'):
-    custom_app = enhance_custom_app_config(entry_point.load())
-    CUSTOM_DJANGO_APPS.append(custom_app)
+    custom_app_class = entry_point.load()
+    custom_app_class = enhance_custom_app_config(custom_app_class)
+    custom_app_instance = custom_app_class(entry_point.name, import_module(entry_point.module_name))
+    CUSTOM_DJANGO_APPS.append(custom_app_instance)
     # Create path to AppConfig class (otherwise the ready() method doesn't get
     # called)
     INSTALLED_APPS.append("{}.{}".format(entry_point.module_name,
diff --git a/django_airavata/templates/base.html b/django_airavata/templates/base.html
index 01aeb99..c83c374 100644
--- a/django_airavata/templates/base.html
+++ b/django_airavata/templates/base.html
@@ -156,6 +156,9 @@
             {% if current_airavata_app %}
             <i class="fa {{ current_airavata_app.fa_icon_class }} mr-2"></i>
             {{ current_airavata_app.verbose_name }}
+            {% elif current_custom_app %}
+            <i class="fa {{ current_custom_app.fa_icon_class }} mr-2"></i>
+            {{ current_custom_app.verbose_name }}
             {% else %}
             Menu
             {% endif %}
@@ -220,6 +223,16 @@
     </div>
     <nav class=c-nav>
       {% block nav-items %}
+        {% for nav_item in airavata_app_nav %}
+          <a href="{% url nav_item.url %}" class="c-nav__item {% if nav_item.active %}is-active{% endif %}" data-toggle=tooltip data-placement=right title="{{ nav_item.label }}">
+              <i class="{{ nav_item.icon }}"></i> <span class=sr-only>{{ nav_item.label }}</span>
+          </a>
+        {% endfor %}
+        {% for nav_item in custom_app_nav %}
+          <a href="{% url nav_item.url %}" class="c-nav__item {% if nav_item.active %}is-active{% endif %}" data-toggle=tooltip data-placement=right title="{{ nav_item.label }}">
+              <i class="{{ nav_item.icon }}"></i> <span class=sr-only>{{ nav_item.label }}</span>
+          </a>
+        {% endfor %}
       {% endblock %}
     </nav>
     {% comment %}