Navigation improvements

Rename the get_menu_links and get_menus_links to
navigation_resolve_menu.

Change the return value of the menu resolving to include
the resolved object.

Update the links display templates to show which object the
links belong to when there is more than one object.

Update the links display templates to show which menu
the links belong to when there is more than one menu.

Remove the sidebar menu and unify its links with the
secondary menu.

Signed-off-by: Roberto Rosario <Roberto.Rosario@mayan-edms.com>
This commit is contained in:
Roberto Rosario
2019-02-14 02:34:23 -04:00
parent 18e5ee1e4f
commit b25c3be969
13 changed files with 286 additions and 171 deletions

View File

@@ -237,6 +237,13 @@
document type selection screen. The document type view
permission is now required in addition to the index
template edit permission.
- Update the links display templates to show which object the
links belong to when there is more than one object.
- Update the links display templates to show which menu
the links belong to when there is more than one menu.
- Remove the sidebar menu and unify its links with the
secondary menu.
3.1.9 (2018-11-01)
==================

View File

@@ -37,7 +37,7 @@
</div>
</div>
{% get_menus_links names='facet,list facet' sort_results=True as links_facet %}
{% navigation_resolve_menus names='facet,list facet' sort_results=True as facet_menus_link_results %}
<style>
@@ -45,12 +45,12 @@
<div class="row">
<div class="col-xs-12 {% if links_facet %}has-sidebar{% endif %}" id="viewport">
<div class="col-xs-12 {% if facet_menus_link_results %}has-sidebar{% endif %}" id="viewport">
{% include 'appearance/calculate_form_title.html' %}
{# action menu #}
{% get_menus_links names='object,sidebar,secondary' sort_results=True as links_actions %}
{% if links_actions %}
{% navigation_resolve_menus names='object,secondary' sort_results=True as action_menus_link_results %}
{% if action_menus_link_results %}
<div class="pull-right btn-group" id="menu-actions">
<button aria-expanded="true" class="btn btn-danger btn-sm dropdown-toggle" data-toggle="dropdown" type="button">
{% trans 'Actions' %}
@@ -58,19 +58,39 @@
<span class="sr-only">{% trans 'Toggle Dropdown' %}</span>
</button>
<ul class="dropdown-menu" role="menu">
{% for object_navigation_links in links_actions %}
{% with 'true' as as_li %}
{% with 'true' as hide_active_anchor %}
{% with 'btn-sm' as link_classes %}
{% include 'navigation/generic_navigation.html' %}
{% endwith %}
{% endwith %}
{% endwith %}
{% for menus_link_result in action_menus_link_results %}
{% if action_menus_link_results|length > 1 %}
<li class="dropdown-header">{{ menus_link_result.menu.label }}</li>
{% endif %}
{% if not forloop.last and object_navigation_links %}
{% for link_group in menus_link_result.link_groups %}
{% if navigation_object_list %}
{% ifchanged link_group.object %}
<li class="dropdown-header">{% common_get_object_verbose_name obj=link_group.object %}</li>
{% endifchanged %}
{% endif %}
{% with link_group.links as object_navigation_links %}
{% with 'true' as as_li %}
{% with 'true' as hide_active_anchor %}
{% with 'btn-sm' as link_classes %}
{% include 'navigation/generic_navigation.html' %}
{% endwith %}
{% endwith %}
{% endwith %}
{% endwith %}
{% if not forloop.last and link_group %}
<li class="divider"></li>
{% endif %}
{% endfor %}
{% if not forloop.last and menus_link_result %}
<li class="divider"></li>
{% endif %}
{% endfor %}
</ul>
</div>
<div class="clearfix"></div>
@@ -80,17 +100,21 @@
{% block footer %}{% endblock %}
</div>
{% if links_facet %}
{% if facet_menus_link_results %}
<div id="sidebar">
<div class="pull-right list-group">
{% for object_navigation_links in links_facet %}
{% with 'true' as hide_active_anchor %}
{% with 'active' as link_class_active %}
{% with 'list-group-item btn-sm' as link_classes %}
{% include 'navigation/generic_navigation.html' %}
{% endwith %}
{% endwith %}
{% endwith %}
{% for menu_link_result in facet_menus_link_results %}
{% for link_group in menu_link_result.link_groups %}
{% with link_group.links as object_navigation_links %}
{% with 'true' as hide_active_anchor %}
{% with 'active' as link_class_active %}
{% with 'list-group-item btn-sm' as link_classes %}
{% include 'navigation/generic_navigation.html' %}
{% endwith %}
{% endwith %}
{% endwith %}
{% endwith %}
{% endfor %}
{% endfor %}
</div>
</div>

View File

@@ -11,8 +11,10 @@
<div class="well center-block">
<div class="row">
{% with 'navigation/large_button_link.html' as link_template %}
{% for object_navigation_links in resolved_links %}
{% include 'navigation/generic_navigation.html' %}
{% for menu_results in resolved_links %}
{% with menu_results.links as object_navigation_links %}
{% include 'navigation/generic_navigation.html' %}
{% endwith %}
{% empty %}
<p class="text-center">
{% include 'appearance/no_results.html' %}

View File

@@ -27,7 +27,7 @@
<div class="well center-block">
{% if object_list %}
{% if not hide_multi_item_actions %}
{% get_menu_links name='multi item' sort_results=True source=object_list.0 as links_multi_item %}
{% navigation_resolve_menu name='multi item' sort_results=True source=object_list.0 as links_multi_menus_results %}
{% endif %}
{% endif %}
@@ -45,7 +45,7 @@
<div class="form-group">
<div class="checkbox">
<label for="id_indexes_0">
{% if links_multi_item %}
{% if links_multi_menus_results %}
<input class="form-multi-object-action-checkbox check-all-slave checkbox" name="pk_{{ object.pk }}" type="checkbox" />
{% endif %}
@@ -84,9 +84,9 @@
{% endfor %}
{% if not hide_links %}
{% get_menus_links names='list facet,object' source=object as links %}
{% navigation_resolve_menus names='list facet,object' source=object as facet_menus_link_results %}
{% if links %}
{% if facet_menus_link_results %}
<div class="dropdown text-center">
<button aria-expanded="false" aria-haspopup="true" class="btn btn-default btn-danger btn-sm dropdown-toggle" data-toggle="dropdown">
{% trans 'Actions' %}
@@ -94,18 +94,25 @@
<span class="sr-only">{% trans 'Toggle Dropdown' %}</span>
</button>
<ul class="dropdown-menu" role="menu">
{% for object_navigation_links in links %}
{% with 'true' as as_li %}
{% with 'true' as hide_active_anchor %}
{% with 'btn-sm' as link_classes %}
{% include 'navigation/generic_navigation.html' %}
{% endwith %}
{% endwith %}
{% endwith %}
{% for facet_menu_link_result in facet_menus_link_results %}
{% for link_group in facet_menu_link_result.link_groups %}
{% if not forloop.last and object_navigation_links %}
{% with link_group.links as object_navigation_links %}
{% with 'true' as as_li %}
{% with 'true' as hide_active_anchor %}
{% with 'btn-sm' as link_classes %}
{% include 'navigation/generic_navigation.html' %}
{% endwith %}
{% endwith %}
{% endwith %}
{% endwith %}
{% endfor %}
{% if not forloop.last and facet_menu_link_result %}
<li class="divider"></li>
{% endif %}
{% endfor %}
</ul>
</div>

View File

@@ -27,7 +27,7 @@
<div class="well center-block">
{% if object_list %}
{% if not hide_multi_item_actions %}
{% get_menu_links name='multi item' sort_results=True source=object_list.0 as links_multi_item %}
{% navigation_resolve_menu name='multi item' sort_results=True source=object_list.0 as links_multi_menus_results %}
{% endif %}
{% endif %}
@@ -42,7 +42,7 @@
<thead>
{% if not hide_header %}
<tr>
{% if links_multi_item %}
{% if links_multi_menus_results %}
<th class="first"></th>
{% endif %}
@@ -95,7 +95,7 @@
<tbody>
{% for object in object_list %}
<tr>
{% if links_multi_item %}
{% if links_multi_menus_results %}
<td>
<input class="form-multi-object-action-checkbox check-all-slave checkbox" name="pk_{{ object.pk }}" type="checkbox" value="" />
</td>
@@ -131,21 +131,29 @@
{% endfor %}
{% if not hide_links %}
<td class="last">
{% get_menu_links name='list facet' sort_results=True source=object as resolved_links %}
{% for object_navigation_links in resolved_links %}
{% with 'true' as horizontal %}
{% with 'true' as hide_icon %}
{% include 'navigation/generic_navigation.html' %}
{% endwith %}
{% endwith %}
{% navigation_resolve_menu name='list facet' sort_results=True source=object as facet_menus_results %}
{% for facet_menu_results in facet_menus_results %}
{% for link_group in facet_menu_results.link_groups %}
{% with link_group.links as object_navigation_links %}
{% with 'true' as horizontal %}
{% with 'true' as hide_icon %}
{% include 'navigation/generic_navigation.html' %}
{% endwith %}
{% endwith %}
{% endwith %}
{% endfor %}
{% endfor %}
{% get_menu_links name='object' source=object as resolved_links %}
{% for object_navigation_links in resolved_links %}
{% with 'true' as horizontal %}
{% with 'true' as hide_icon %}
{% include 'navigation/generic_navigation.html' %}
{% endwith %}
{% endwith %}
{% navigation_resolve_menu name='object' source=object as object_menus_results %}
{% for object_menu_results in object_menus_results %}
{% for link_group in object_menu_results.link_groups %}
{% with link_group.links as object_navigation_links %}
{% with 'true' as horizontal %}
{% with 'true' as hide_icon %}
{% include 'navigation/generic_navigation.html' %}
{% endwith %}
{% endwith %}
{% endwith %}
{% endfor %}
{% endfor %}
</td>
{% endif %}

View File

@@ -6,7 +6,7 @@
<div class="pull-left">
<div class="btn-toolbar" role="toolbar">
<div class="btn-group">
{% if links_multi_item %}
{% if links_multi_menus_results %}
<a class="btn btn-default btn-sm check-all" data-checked=false data-icon-checked="fa fa-check-square" data-icon-unchecked="far fa-square" title="{% trans 'Select/Deselect all' %}">
<i class="far fa-square"></i>
</a>
@@ -19,7 +19,7 @@
</div>
{% if links_multi_item %}
{% if links_multi_menus_results %}
<p class="pull-right" id="multi-item-title" style="margin-top: 4px;">{% trans 'Select items to activate bulk actions. Use Shift + click to select many.' %}</p>
<div class="pull-right btn-group" id="multi-item-actions" style="display: none;">
@@ -29,16 +29,20 @@
<span class="sr-only">{% trans 'Toggle Dropdown' %}</span>
</button>
<ul class="dropdown-menu" role="menu">
{% for object_navigation_links in links_multi_item %}
{% with 'true' as as_li %}
{% with 'true' as hide_active_anchor %}
{% with 'btn-sm btn-multi-item-action' as link_classes %}
{% include 'navigation/generic_navigation.html' %}
{% endwith %}
{% endwith %}
{% endwith %}
{% for multi_item_menu_results in links_multi_menus_results %}
{% for link_group in multi_item_menu_results.link_groups %}
{% with link_group.links as object_navigation_links %}
{% with 'true' as as_li %}
{% with 'true' as hide_active_anchor %}
{% with 'btn-sm btn-multi-item-action' as link_classes %}
{% include 'navigation/generic_navigation.html' %}
{% endwith %}
{% endwith %}
{% endwith %}
{% endwith %}
{% if not forloop.last and object_navigation_links %}
{% endfor %}
{% if not forloop.last and link_group %}
<li class="divider"></li>
{% endif %}
{% endfor %}

View File

@@ -8,58 +8,62 @@
{% spaceless %}
<div class="panel-group" id="accordion-sidebar" role="tablist" aria-multiselectable="true">
{% get_menu_links name='main' as menu_links %}
{% for link_set in menu_links %}
{% for link in link_set %}
{% with 'active' as li_class_active %}
{% with ' ' as link_classes %}
{% if link|get_type == "<class 'mayan.apps.navigation.classes.Menu'>" %}
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="headingOne">
<h4 class="panel-title">
<a class="non-ajax collapsed" role="button" data-toggle="collapse" data-parent="#accordion-sidebar" href="#accordion-body-{{ forloop.counter }}" aria-expanded="false" aria-controls="collapseOne">
<div class="pull-left">
{% if link.icon %}
<i class="hidden-xs hidden-sm hidden-md {{ link.icon }}"></i>
{% endif %}
{% if link.icon_class %}{{ link.icon_class.render }}{% endif %}
{{ link.label }}
</div>
<div class="accordion-indicator pull-right"><span class="caret"></span></div>
<div class="clearfix"></div>
</a>
</h4>
</div>
<div id="accordion-body-{{ forloop.counter }}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingOne">
<div class="panel-body">
<ul class="list-unstyled">
{% get_menu_links name=link.name as menu_links %}
{% for linkset in menu_links %}
{% with '' as link_class_active %}
{% with 'a-main-menu-accordion-link' as link_classes %}
{% with 'true' as as_li %}
{% with linkset as object_navigation_links %}
{% include 'navigation/generic_navigation.html' %}
{% endwith %}
{% endwith %}
{% endwith %}
{% endwith %}
{% endfor %}
</ul>
{% navigation_resolve_menu name='main' as main_menus_results %}
{% for main_menu_results in main_menus_results %}
{% for link_group in main_menu_results.link_groups %}
{% for link in link_group.links %}
{% with 'active' as li_class_active %}
{% with ' ' as link_classes %}
{% if link|get_type == "<class 'mayan.apps.navigation.classes.Menu'>" %}
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="headingOne">
<h4 class="panel-title">
<a class="non-ajax collapsed" role="button" data-toggle="collapse" data-parent="#accordion-sidebar" href="#accordion-body-{{ forloop.counter }}" aria-expanded="false" aria-controls="collapseOne">
<div class="pull-left">
{% if link.icon %}
<i class="hidden-xs hidden-sm hidden-md {{ link.icon }}"></i>
{% endif %}
{% if link.icon_class %}{{ link.icon_class.render }}{% endif %}
{{ link.label }}
</div>
<div class="accordion-indicator pull-right"><span class="caret"></span></div>
<div class="clearfix"></div>
</a>
</h4>
</div>
<div id="accordion-body-{{ forloop.counter }}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingOne">
<div class="panel-body">
<ul class="list-unstyled">
{% navigation_resolve_menu name=link.name as sub_menus_results %}
{% for sub_menu_results in sub_menus_results %}
{% for link_group in sub_menu_results.link_groups %}
{% with '' as link_class_active %}
{% with 'a-main-menu-accordion-link' as link_classes %}
{% with 'true' as as_li %}
{% with link_group.links as object_navigation_links %}
{% include 'navigation/generic_navigation.html' %}
{% endwith %}
{% endwith %}
{% endwith %}
{% endwith %}
{% endfor %}
{% endfor %}
</ul>
</div>
</div>
</div>
</div>
{% else %}
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="headingOne">
<h4 class="panel-title">
{% include 'navigation/generic_link_instance.html' %}
</h4>
{% else %}
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="headingOne">
<h4 class="panel-title">
{% include 'navigation/generic_link_instance.html' %}
</h4>
</div>
</div>
</div>
{% endif %}
{% endwith %}
{% endwith %}
{% endif %}
{% endwith %}
{% endwith %}
{% endfor %}
{% endfor %}
{% endfor %}
</div>

View File

@@ -18,20 +18,22 @@
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
{% get_menu_links name='topbar' as menu_links %}
{% for link_set in menu_links %}
{% for link in link_set %}
{% with 'true' as as_li %}
{% with 'true' as hide_active_anchor %}
{% with 'active' as li_class_active %}
{% with 'first' as li_class_first %}
{% with ' ' as link_classes %}
{% include 'navigation/generic_subnavigation.html' %}
{% endwith %}
{% endwith %}
{% endwith %}
{% endwith %}
{% endwith %}
{% navigation_resolve_menu name='topbar' as topbar_menus_results %}
{% for tobpar_menu_result in topbar_menus_results %}
{% for link_group in tobpar_menu_result.link_groups %}
{% for link in link_group.links %}
{% with 'true' as as_li %}
{% with 'true' as hide_active_anchor %}
{% with 'active' as li_class_active %}
{% with 'first' as li_class_first %}
{% with ' ' as link_classes %}
{% include 'navigation/generic_subnavigation.html' %}
{% endwith %}
{% endwith %}
{% endwith %}
{% endwith %}
{% endwith %}
{% endfor %}
{% endfor %}
{% endfor %}
</ul>

View File

@@ -8,21 +8,20 @@ from .icons import icon_menu_about, icon_menu_user
__all__ = (
'menu_about', 'menu_facet', 'menu_list_facet', 'menu_main', 'menu_object',
'menu_multi_item', 'menu_secondary', 'menu_setup', 'menu_sidebar',
'menu_multi_item', 'menu_secondary', 'menu_setup', 'menu_secondary',
'menu_tools', 'menu_topbar', 'menu_user'
)
menu_about = Menu(
icon_class=icon_menu_about, label=_('System'), name='about'
)
menu_facet = Menu(name='facet')
menu_list_facet = Menu(name='list facet')
menu_facet = Menu(label=_('Facet'), name='facet')
menu_list_facet = Menu(label=_('Facet'), name='list facet')
menu_main = Menu(name='main')
menu_multi_item = Menu(name='multi item')
menu_object = Menu(name='object')
menu_secondary = Menu(name='secondary')
menu_object = Menu(label=_('Actions'), name='object')
menu_secondary = Menu(label=_('Secondary'), name='secondary')
menu_setup = Menu(name='setup')
menu_sidebar = Menu(name='sidebar')
menu_tools = Menu(name='tools')
menu_topbar = Menu(name='topbar')
menu_user = Menu(

View File

@@ -51,6 +51,14 @@ def common_calculate_title(context):
return _('Create')
@register.simple_tag
def common_get_object_verbose_name(obj):
try:
return obj._meta.verbose_name
except AttributeError:
return type(obj)
@register.simple_tag
def get_collections():
return Collection.get_all()

View File

@@ -216,6 +216,9 @@ class Menu(object):
self.__class__._registry[name] = self
self.non_sorted_sources = non_sorted_sources or []
def __repr__(self):
return '<Menu: {}>'.format(self.name)
def _map_links_to_source(self, links, source, map_variable='bound_links', position=None):
source_links = getattr(self, map_variable).setdefault(source, [])
@@ -278,6 +281,24 @@ class Menu(object):
)
return resolved_navigation_object_list
def get_result_position(self, item):
"""
Method to help sort results by position.
"""
if isinstance(item, ResolvedLink):
return self.link_positions.get(item.link, 0)
else:
return self.link_positions.get(item, 0)
def get_result_label(self, item):
"""
Method to help sort results by label.
"""
if isinstance(item, ResolvedLink):
return item.link.text
else:
return item.label
def resolve(self, context, source=None, sort_results=False):
if not self.check_condition(context=context):
return []
@@ -339,7 +360,12 @@ class Menu(object):
pass
if resolved_links:
result.append(resolved_links)
result.append(
{
'object': resolved_navigation_object,
'links': resolved_links
}
)
resolved_links = []
# View links
@@ -350,7 +376,12 @@ class Menu(object):
resolved_links.append(resolved_link)
if resolved_links:
result.append(resolved_links)
result.append(
{
'object': current_view_name,
'links': resolved_links
}
)
resolved_links = []
@@ -368,7 +399,12 @@ class Menu(object):
resolved_links.append(resolved_link)
if resolved_links:
result.append(resolved_links)
result.append(
{
'object': None,
'links': resolved_links
}
)
if result:
unsorted_source = False
@@ -379,16 +415,15 @@ class Menu(object):
break
if sort_results and not unsorted_source:
result[0] = sorted(
result[0], key=lambda item: (
item.link.text if isinstance(item, ResolvedLink) else item.label
for link_group in result:
link_group['links'] = sorted(
link_group['links'], key=self.get_result_label
)
)
else:
# Sort links by position value passed during bind
result[0] = sorted(
result[0], key=lambda item: (self.link_positions.get(item.link) or 0) if isinstance(item, ResolvedLink) else (self.link_positions.get(item) or 0)
)
for link_group in result:
link_group['links'] = sorted(
link_group['links'], key=self.get_result_position
)
return result
@@ -411,12 +446,15 @@ class Menu(object):
class ResolvedLink(object):
def __init__(self, link, current_view_name):
self.context = None
self.current_view_name = current_view_name
self.disabled = False
self.link = link
self.url = '#'
self.context = None
self.request = None
self.url = '#'
def __repr__(self):
return '<ResolvedLink: {}>'.format(self.url)
@property
def active(self):

View File

@@ -12,13 +12,15 @@
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
{% get_menu_links link.name as menu_links %}
{% for linkset in menu_links %}
{% with '' as li_class_active %}
{% with linkset as object_navigation_links %}
{% include 'navigation/generic_navigation.html' %}
{% endwith %}
{% endwith %}
{% navigation_resolve_menu name=link.name as sub_menus_results %}
{% for sub_menu_results in sub_menus_results %}
{% for link_group in sub_menu_results.link_groups %}
{% with '' as li_class_active %}
{% with link_group.links as object_navigation_links %}
{% include 'navigation/generic_navigation.html' %}
{% endwith %}
{% endwith %}
{% endfor %}
{% endfor %}
</ul>
</li>

View File

@@ -20,23 +20,6 @@ def get_menu(name):
return Menu.get(name)
@register.simple_tag(takes_context=True)
def get_menu_links(context, name, source=None, sort_results=None):
return Menu.get(name).resolve(context=context, source=source, sort_results=sort_results)
@register.simple_tag(takes_context=True)
def get_menus_links(context, names, source=None, sort_results=None):
result = []
for name in names.split(','):
for links in Menu.get(name=name).resolve(context=context, sort_results=sort_results):
if links:
result.append(links)
return result
@register.simple_tag(takes_context=True)
def get_sort_field_querystring(context, column):
return column.get_sort_field_querystring(context=context)
@@ -74,6 +57,33 @@ def resolve_link(context, link):
return link.resolve(context=context)
@register.simple_tag(takes_context=True)
def navigation_resolve_menu(context, name, source=None, sort_results=None):
result = []
menu = Menu.get(name)
link_groups = menu.resolve(context=context, source=source, sort_results=sort_results)
if link_groups:
result.append({'link_groups': link_groups, 'menu': menu})
return result
@register.simple_tag(takes_context=True)
def navigation_resolve_menus(context, names, source=None, sort_results=None):
result = []
for name in names.split(','):
menu = Menu.get(name=name)
link_groups = menu.resolve(context=context, sort_results=sort_results)
if link_groups:
result.append({'link_groups': link_groups, 'menu': menu})
return result
@register.simple_tag(takes_context=True)
def source_column_resolve(context, column):
if column: