Enable to refresh ngdetails view

For now refreshing ngdetails view by browser using F5 key or reload
button, it causes 404 error from django. To fix this issue, this patch
adds the url for '/ngdetails'.

Furthermore, to specify current navigation and to check access grants
to current panel, each access to Horizon django framework needs its
dashboard and panel objects. It means that we need to specify dashboard
and panel that ngdetails view belongs to.

Also, this patch adds the process and settings to specify dashboard and
panel object for each ngdetails view.

Change-Id: I4bcffd2e222ce2df186551cceba0aa38f600d9c8
Closes-Bug: #1681627
This commit is contained in:
Shu Muto 2017-05-25 18:39:15 +09:00
parent 08089b01c4
commit fe0df4579c
6 changed files with 112 additions and 0 deletions

View File

@ -47,6 +47,7 @@ if Horizon:
get_dashboard = Horizon.get_dashboard
get_default_dashboard = Horizon.get_default_dashboard
get_dashboards = Horizon.get_dashboards
get_details_path = Horizon.get_details_path
urls = Horizon._lazy_urls
# silence flake8 about unused imports here:
@ -62,5 +63,6 @@ __all__ = [
"get_dashboard",
"get_default_dashboard",
"get_dashboards",
"get_details_path",
"urls",
]

View File

@ -693,6 +693,7 @@ class Site(Registry, HorizonComponent):
namespace = 'horizon'
slug = 'horizon'
urls = 'horizon.site_urls'
details = {}
def __repr__(self):
return u"<Site: %s>" % self.slug
@ -822,6 +823,24 @@ class Site(Registry, HorizonComponent):
"""
return self.get_default_dashboard().get_absolute_url()
def get_details_path(self, resource_type):
"""Returns classes of dashboard and panel for details view
This method returns the specified :class:`~horizon.Dashboard` instance
and :class:`~horizon.Panel` instance for details view specified by
resource_type.
"""
details = self.details.get(resource_type)
dashboard = None
panel = None
if details is not None:
dashboard = self.get_dashboard(details.get('dashboard'))
panel = dashboard.get_panel(details.get('panel'))
else:
dashboard = self.get_default_dashboard()
panel = dashboard.get_panels()[0]
return dashboard, panel
@property
def _lazy_urls(self):
"""Lazy loading for URL patterns.
@ -906,6 +925,7 @@ class Site(Registry, HorizonComponent):
# are added to them and Dashboard._autodiscover() doesn't wipe out any
# panels previously added when its panel groups are instantiated.
panel_configs = []
details_configs = []
for config in panel_customization:
if config.get('PANEL'):
panel_configs.append(config)
@ -914,9 +934,16 @@ class Site(Registry, HorizonComponent):
else:
LOG.warning("Skipping %s because it doesn't have PANEL or "
"PANEL_GROUP defined.", config.__name__)
if config.get('ADD_DETAIL_PAGES'):
details_configs.append(config)
# Now process the panels.
for config in panel_configs:
self._process_panel_configuration(config)
# And process the details views.
for config in details_configs:
self._process_details_configuration(config)
def _process_panel_configuration(self, config):
"""Add, remove and set default panels on the dashboard."""
@ -1004,6 +1031,26 @@ class Site(Registry, HorizonComponent):
'%(exc)s',
{'panel_group': panel_group_slug, 'exc': e})
def _process_details_configuration(self, config):
"""Add details view."""
detail_pages = config.get('ADD_DETAIL_PAGES')
urlpatterns = self._get_default_urlpatterns()
views = import_module('horizon.browsers.views')
for details in detail_pages:
try:
urlpatterns.append(url(r'^ngdetails/%s/[^/]+' % details,
views.AngularDetailsView.as_view(),
name='ngdetails'))
_decorate_urlconf(urlpatterns, require_auth)
dashboard, panel = detail_pages[details]
self.details[details] = {'dashboard': dashboard,
'panel': panel}
except Exception as e:
LOG.warning('Could not add %(details) to %(panel)s on '
'%(dashboard)s: %(exc)s',
{'dashboard': dashboard, 'panel': panel,
'details': details, 'exc': e})
class HorizonSite(Site):
"""A singleton implementation of Site.

View File

@ -15,6 +15,7 @@
from django.utils.translation import ugettext_lazy as _
from django.views import generic
import horizon
from horizon.tables import MultiTableView
from horizon.utils import memoized
@ -83,3 +84,20 @@ class AngularIndexView(generic.TemplateView):
else:
context["page_title"] = self.page_title
return context
class AngularDetailsView(AngularIndexView):
'''View for Angularized details view
To use surely the template same as AngularIndexView, this class
inherits AngularIndexView.
'''
def get_context_data(self, **kwargs):
context = super(AngularDetailsView, self).get_context_data(**kwargs)
resource_path = self.request.path.partition('/ngdetails/')[2]
resource_type = resource_path.split('/')[0]
dashboard, panel = horizon.get_details_path(resource_type)
self.request.horizon['dashboard'] = dashboard
self.request.horizon['panel'] = panel
return context

View File

@ -21,3 +21,10 @@ PANEL_GROUP = 'compute'
# Python panel class of the PANEL to be added.
ADD_PANEL = 'openstack_dashboard.dashboards.project.images.panel.Images'
# The details view to be belonged to the PANEL_DASHBOARD and PANEL.
# If the details view uses ngdetails, this setting is needed to refresh the
# details view.
ADD_DETAIL_PAGES = {
'OS::Glance::Image': (PANEL_DASHBOARD, PANEL)
}

View File

@ -1,3 +1,15 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# The slug of the panel to be added to HORIZON_CONFIG. Required.
PANEL = 'domains'
# The slug of the dashboard the PANEL associated with. Required.
@ -7,3 +19,10 @@ PANEL_GROUP = 'default'
# Python panel class of the PANEL to be added.
ADD_PANEL = 'openstack_dashboard.dashboards.identity.domains.panel.Domains'
# The details view to be belonged to the PANEL_DASHBOARD and PANEL.
# If the details view uses ngdetails, this setting is needed to refresh the
# details view.
ADD_DETAIL_PAGES = {
'OS::Keystone::Domain': (PANEL_DASHBOARD, PANEL)
}

View File

@ -1,3 +1,15 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# The slug of the panel to be added to HORIZON_CONFIG. Required.
PANEL = 'users'
# The slug of the dashboard the PANEL associated with. Required.
@ -7,3 +19,10 @@ PANEL_GROUP = 'default'
# Python panel class of the PANEL to be added.
ADD_PANEL = 'openstack_dashboard.dashboards.identity.users.panel.Users'
# The details view to be belonged to the PANEL_DASHBOARD and PANEL.
# If the details view uses ngdetails, this setting is needed to refresh the
# details view.
ADD_DETAIL_PAGES = {
'OS::Keystone::User': (PANEL_DASHBOARD, PANEL)
}