Backport new menu, new sidebar and CSS changes
Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
@@ -96,6 +96,9 @@
|
||||
manager.
|
||||
* Remove the MIMETYPE_FILE_READ_SIZE setting.
|
||||
* Use copyfileobj in the document parsers.
|
||||
* Backport list facet menu code.
|
||||
* Backport sidebar code.
|
||||
* CSS updates to maximize usable width.
|
||||
|
||||
3.1.11 (2019-04-XX)
|
||||
===================
|
||||
|
||||
@@ -128,6 +128,9 @@ Other changes
|
||||
manager.
|
||||
* Remove the MIMETYPE_FILE_READ_SIZE setting.
|
||||
* Use copyfileobj in the document parsers.
|
||||
* Backport list facet menu code.
|
||||
* Backport sidebar code.
|
||||
* CSS updates to maximize usable width.
|
||||
|
||||
Removals
|
||||
--------
|
||||
|
||||
@@ -334,3 +334,70 @@ a i {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Main content
|
||||
*/
|
||||
|
||||
.main {
|
||||
}
|
||||
|
||||
/* Remove scroll bar caused by bootstraps -15px on .row margins */
|
||||
.no-gutters {
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
|
||||
> .col,
|
||||
> [class*="col-"] {
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.main {
|
||||
padding-right: 0px;
|
||||
padding-left: 0px;
|
||||
/*margin-left: 210px;*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Side bar */
|
||||
#menu-actions {
|
||||
position: fixed;
|
||||
right: 5px;
|
||||
top: 65px;
|
||||
z-index: 1020;
|
||||
}
|
||||
|
||||
#viewport {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.has-sidebar {
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
#sidebar {
|
||||
bottom: 0;
|
||||
display: block;
|
||||
overflow-x: visible;
|
||||
overflow-y: auto;
|
||||
padding-top: 10px;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 100px;
|
||||
width: 150px;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.has-sidebar {
|
||||
padding-right: 130px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{% if appearance_type == 'plain' %}
|
||||
{% block content_plain %}{% endblock %}
|
||||
{% else %}
|
||||
<div class="container-fluid">
|
||||
<div class="">
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
{% check_sqlite as check_sqlite %}
|
||||
@@ -37,6 +37,86 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% navigation_resolve_menus names='facet,list facet' sort_results=True as facet_menus_link_results %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-12 {% if facet_menus_link_results %}has-sidebar{% endif %}" id="viewport">
|
||||
{% include 'appearance/calculate_form_title.html' %}
|
||||
|
||||
{# action menu #}
|
||||
{% 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' %}
|
||||
<span class="caret"></span>
|
||||
<span class="sr-only">{% trans 'Toggle Dropdown' %}</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
{% 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 %}
|
||||
|
||||
{% 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>
|
||||
{% endif %}
|
||||
|
||||
{% block content %}{% endblock %}
|
||||
{% block footer %}{% endblock %}
|
||||
</div>
|
||||
|
||||
{% if facet_menus_link_results %}
|
||||
<div id="sidebar">
|
||||
<div class="pull-right list-group">
|
||||
{% 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>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% comment %}
|
||||
|
||||
{% get_menus_links names='object,sidebar,secondary' sort_results=True as links %}
|
||||
{% get_menu_links name='facet' sort_results=True as form_navigation_links %}
|
||||
|
||||
@@ -97,6 +177,8 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endcomment %}
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
@@ -11,10 +11,12 @@
|
||||
<div class="well center-block">
|
||||
<div class="row">
|
||||
{% with 'navigation/large_button_link.html' as link_template %}
|
||||
{% for object_navigation_links in resolved_links %}
|
||||
{% 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" colspan=99>
|
||||
<p class="text-center">
|
||||
{% include 'appearance/no_results.html' %}
|
||||
</p>
|
||||
{% endfor %}
|
||||
|
||||
@@ -87,14 +87,40 @@
|
||||
{% endfor %}
|
||||
|
||||
{% if not hide_links %}
|
||||
<p class="text-center">
|
||||
{% get_menu_links name='object' source=object as resolved_links %}
|
||||
{% for object_navigation_links in resolved_links %}
|
||||
{% with 'true' as as_dropdown %}
|
||||
|
||||
{% navigation_resolve_menus names='list facet,object' source=object as facet_menus_link_results %}
|
||||
|
||||
{% 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' %}
|
||||
<span class="caret"></span>
|
||||
<span class="sr-only">{% trans 'Toggle Dropdown' %}</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
{% for facet_menu_link_result in facet_menus_link_results %}
|
||||
{% for link_group in facet_menu_link_result.link_groups %}
|
||||
|
||||
{% 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 %}
|
||||
</p>
|
||||
|
||||
{% if not forloop.last and facet_menu_link_result %}
|
||||
<li class="divider"></li>
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
@@ -96,13 +96,29 @@
|
||||
{% endfor %}
|
||||
{% if not hide_links %}
|
||||
<td class="last">
|
||||
{% get_menu_links 'object' source=object as resolved_links %}
|
||||
{% for object_navigation_links in resolved_links %}
|
||||
{% 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 %}
|
||||
{% 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 %}
|
||||
|
||||
@@ -16,6 +16,25 @@
|
||||
</div>
|
||||
<div id="navbar" class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
{% navigation_resolve_menu name='main' 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 %}
|
||||
|
||||
{% get_menu_links name='main' as menu_links %}
|
||||
{% for link_set in menu_links %}
|
||||
{% for link in link_set %}
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
<div id="menu-main">
|
||||
{% include 'appearance/main_menu.html' %}
|
||||
</div>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="main">
|
||||
<div class="row no-gutters">
|
||||
<div class="col-xs-12">
|
||||
<div id="ajax-content"></div>
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,8 @@ from mayan.apps.acls.classes import ModelPermission
|
||||
from mayan.apps.acls.permissions import permission_acl_edit, permission_acl_view
|
||||
from mayan.apps.common.apps import MayanAppConfig
|
||||
from mayan.apps.common.menus import (
|
||||
menu_facet, menu_main, menu_multi_item, menu_object, menu_sidebar
|
||||
menu_facet, menu_list_facet, menu_main, menu_multi_item, menu_object,
|
||||
menu_sidebar
|
||||
)
|
||||
from mayan.apps.documents.search import document_page_search, document_search
|
||||
from mayan.apps.navigation import SourceColumn
|
||||
@@ -99,6 +100,10 @@ class CabinetsApp(MayanAppConfig):
|
||||
link_cabinet_list, link_cabinet_create
|
||||
)
|
||||
)
|
||||
menu_list_facet.bind_links(
|
||||
links=(link_cabinet_view, link_custom_acl_list),
|
||||
sources=(Cabinet,)
|
||||
)
|
||||
|
||||
menu_main.bind_links(links=(menu_cabinets,), position=98)
|
||||
|
||||
@@ -115,9 +120,7 @@ class CabinetsApp(MayanAppConfig):
|
||||
)
|
||||
menu_object.bind_links(
|
||||
links=(
|
||||
link_cabinet_view, link_cabinet_edit,
|
||||
link_custom_acl_list, link_cabinet_child_add,
|
||||
link_cabinet_delete
|
||||
link_cabinet_delete, link_cabinet_edit, link_cabinet_child_add
|
||||
), sources=(Cabinet,)
|
||||
)
|
||||
menu_sidebar.bind_links(
|
||||
|
||||
@@ -15,6 +15,7 @@ menu_about = Menu(
|
||||
icon_class=icon_menu_about, label=_('System'), name='about'
|
||||
)
|
||||
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(label=_('Actions'), name='object')
|
||||
|
||||
@@ -21,6 +21,14 @@ def check_sqlite():
|
||||
return MESSAGE_SQLITE_WARNING
|
||||
|
||||
|
||||
@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()
|
||||
|
||||
@@ -11,7 +11,8 @@ from mayan.apps.acls.links import link_acl_list
|
||||
from mayan.apps.acls.permissions import permission_acl_edit, permission_acl_view
|
||||
from mayan.apps.common.apps import MayanAppConfig
|
||||
from mayan.apps.common.menus import (
|
||||
menu_facet, menu_main, menu_object, menu_secondary, menu_setup, menu_tools
|
||||
menu_facet, menu_list_facet, menu_main, menu_object, menu_secondary,
|
||||
menu_setup, menu_tools
|
||||
)
|
||||
from mayan.apps.common.widgets import TwoStateWidget
|
||||
from mayan.apps.documents.signals import post_document_created, post_initial_document_type
|
||||
@@ -183,11 +184,15 @@ class DocumentIndexingApp(MayanAppConfig):
|
||||
menu_facet.bind_links(
|
||||
links=(link_document_index_list,), sources=(Document,)
|
||||
)
|
||||
menu_list_facet.bind_links(
|
||||
links=(
|
||||
link_acl_list, link_index_setup_document_types,
|
||||
link_index_setup_view,
|
||||
), sources=(Index,)
|
||||
)
|
||||
menu_object.bind_links(
|
||||
links=(
|
||||
link_index_setup_edit, link_index_setup_view,
|
||||
link_index_setup_document_types, link_acl_list,
|
||||
link_index_setup_delete
|
||||
link_index_setup_delete, link_index_setup_edit,
|
||||
), sources=(Index,)
|
||||
)
|
||||
menu_object.bind_links(
|
||||
|
||||
@@ -12,7 +12,8 @@ from mayan.apps.acls.classes import ModelPermission
|
||||
from mayan.apps.common.apps import MayanAppConfig
|
||||
from mayan.apps.common.classes import ModelField
|
||||
from mayan.apps.common.menus import (
|
||||
menu_facet, menu_multi_item, menu_object, menu_secondary, menu_tools
|
||||
menu_facet, menu_list_facet, menu_multi_item, menu_object, menu_secondary,
|
||||
menu_tools
|
||||
)
|
||||
from mayan.apps.documents.search import document_search, document_page_search
|
||||
from mayan.apps.documents.signals import post_version_upload
|
||||
@@ -145,16 +146,16 @@ class DocumentParsingApp(MayanAppConfig):
|
||||
menu_facet.bind_links(
|
||||
links=(link_document_page_content,), sources=(DocumentPage,)
|
||||
)
|
||||
menu_list_facet.bind_links(
|
||||
links=(link_document_type_parsing_settings,),
|
||||
sources=(DocumentType,)
|
||||
)
|
||||
menu_multi_item.bind_links(
|
||||
links=(link_document_submit_multiple,), sources=(Document,)
|
||||
)
|
||||
menu_object.bind_links(
|
||||
links=(link_document_submit,), sources=(Document,)
|
||||
)
|
||||
menu_object.bind_links(
|
||||
links=(link_document_type_parsing_settings,), sources=(DocumentType,),
|
||||
position=99
|
||||
)
|
||||
menu_secondary.bind_links(
|
||||
links=(
|
||||
link_document_content, link_document_parsing_errors_list,
|
||||
|
||||
@@ -12,8 +12,8 @@ from mayan.apps.common.apps import MayanAppConfig
|
||||
from mayan.apps.common.classes import ModelAttribute
|
||||
from mayan.apps.common.links import link_object_error_list
|
||||
from mayan.apps.common.menus import (
|
||||
menu_facet, menu_main, menu_object, menu_secondary, menu_setup,
|
||||
menu_sidebar, menu_tools
|
||||
menu_facet, menu_list_facet, menu_main, menu_object, menu_secondary,
|
||||
menu_setup, menu_sidebar, menu_tools
|
||||
)
|
||||
from mayan.apps.common.permissions_runtime import permission_error_log_view
|
||||
from mayan.apps.common.widgets import TwoStateWidget
|
||||
@@ -262,13 +262,17 @@ class DocumentStatesApp(MayanAppConfig):
|
||||
menu_facet.bind_links(
|
||||
links=(link_document_workflow_instance_list,), sources=(Document,)
|
||||
)
|
||||
menu_list_facet.bind_links(
|
||||
links=(
|
||||
link_setup_workflow_document_types,
|
||||
link_setup_workflow_states, link_setup_workflow_transitions,
|
||||
link_workflow_preview, link_acl_list
|
||||
), sources=(Workflow,)
|
||||
)
|
||||
menu_main.bind_links(links=(link_workflow_list,), position=10)
|
||||
menu_object.bind_links(
|
||||
links=(
|
||||
link_setup_workflow_states, link_setup_workflow_transitions,
|
||||
link_setup_workflow_document_types, link_setup_workflow_edit,
|
||||
link_acl_list, link_workflow_preview,
|
||||
link_setup_workflow_delete
|
||||
link_setup_workflow_delete, link_setup_workflow_edit
|
||||
), sources=(Workflow,)
|
||||
)
|
||||
menu_object.bind_links(
|
||||
@@ -291,12 +295,14 @@ class DocumentStatesApp(MayanAppConfig):
|
||||
link_workflow_instance_transition
|
||||
), sources=(WorkflowInstance,)
|
||||
)
|
||||
menu_object.bind_links(
|
||||
|
||||
menu_list_facet.bind_links(
|
||||
links=(
|
||||
link_workflow_document_list, link_workflow_state_list,
|
||||
link_workflow_document_list,
|
||||
link_workflow_state_list,
|
||||
), sources=(WorkflowRuntimeProxy,)
|
||||
)
|
||||
menu_object.bind_links(
|
||||
menu_list_facet.bind_links(
|
||||
links=(
|
||||
link_workflow_state_document_list,
|
||||
), sources=(WorkflowStateRuntimeProxy,)
|
||||
|
||||
@@ -13,8 +13,8 @@ from mayan.apps.acls.permissions import permission_acl_edit, permission_acl_view
|
||||
from mayan.apps.common.apps import MayanAppConfig
|
||||
from mayan.apps.common.classes import MissingItem, ModelField, Template
|
||||
from mayan.apps.common.menus import (
|
||||
menu_facet, menu_main, menu_object, menu_secondary, menu_setup,
|
||||
menu_sidebar, menu_multi_item, menu_tools
|
||||
menu_facet, menu_list_facet, menu_main, menu_object, menu_secondary,
|
||||
menu_setup, menu_sidebar, menu_multi_item, menu_tools
|
||||
)
|
||||
from mayan.apps.common.signals import post_initial_setup
|
||||
from mayan.apps.common.widgets import TwoStateWidget
|
||||
@@ -459,12 +459,17 @@ class DocumentsApp(MayanAppConfig):
|
||||
)
|
||||
|
||||
# Document type links
|
||||
menu_list_facet.bind_links(
|
||||
links=(
|
||||
link_document_type_filename_list,
|
||||
link_acl_list, link_object_event_types_user_subcriptions_list,
|
||||
link_events_for_object,
|
||||
), sources=(DocumentType,)
|
||||
)
|
||||
|
||||
menu_object.bind_links(
|
||||
links=(
|
||||
link_document_type_edit, link_document_type_filename_list,
|
||||
link_acl_list, link_object_event_types_user_subcriptions_list,
|
||||
link_document_type_delete,
|
||||
link_events_for_object,
|
||||
link_document_type_delete, link_document_type_edit
|
||||
), sources=(DocumentType,)
|
||||
)
|
||||
menu_object.bind_links(
|
||||
@@ -572,10 +577,10 @@ class DocumentsApp(MayanAppConfig):
|
||||
link_document_page_navigation_first,
|
||||
link_document_page_navigation_previous,
|
||||
link_document_page_navigation_next,
|
||||
link_document_page_navigation_last, link_transformation_list
|
||||
link_document_page_navigation_last
|
||||
), sources=(DocumentPage,)
|
||||
)
|
||||
menu_object.bind_links(
|
||||
menu_list_facet.bind_links(
|
||||
links=(link_transformation_list,), sources=(DocumentPage,)
|
||||
)
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@ from mayan.apps.acls.links import link_acl_list
|
||||
from mayan.apps.acls.permissions import permission_acl_edit, permission_acl_view
|
||||
from mayan.apps.common.apps import MayanAppConfig
|
||||
from mayan.apps.common.menus import (
|
||||
menu_facet, menu_object, menu_secondary, menu_setup, menu_sidebar
|
||||
menu_facet, menu_list_facet, menu_object, menu_secondary, menu_setup,
|
||||
menu_sidebar
|
||||
)
|
||||
from mayan.apps.common.widgets import TwoStateWidget
|
||||
from mayan.apps.navigation import SourceColumn
|
||||
@@ -83,6 +84,12 @@ class LinkingApp(MayanAppConfig):
|
||||
links=(link_smart_link_instances_for_document,),
|
||||
sources=(Document,)
|
||||
)
|
||||
menu_list_facet.bind_links(
|
||||
links=(
|
||||
link_acl_list, link_smart_link_document_types,
|
||||
link_smart_link_condition_list,
|
||||
), sources=(SmartLink,)
|
||||
)
|
||||
menu_object.bind_links(
|
||||
links=(
|
||||
link_smart_link_condition_edit,
|
||||
@@ -91,9 +98,7 @@ class LinkingApp(MayanAppConfig):
|
||||
)
|
||||
menu_object.bind_links(
|
||||
links=(
|
||||
link_smart_link_edit, link_smart_link_document_types,
|
||||
link_smart_link_condition_list, link_acl_list,
|
||||
link_smart_link_delete
|
||||
link_smart_link_delete, link_smart_link_edit
|
||||
), sources=(SmartLink,)
|
||||
)
|
||||
menu_object.bind_links(
|
||||
|
||||
@@ -10,7 +10,8 @@ from mayan.apps.acls.links import link_acl_list
|
||||
from mayan.apps.acls.permissions import permission_acl_edit, permission_acl_view
|
||||
from mayan.apps.common.apps import MayanAppConfig
|
||||
from mayan.apps.common.menus import (
|
||||
menu_object, menu_multi_item, menu_secondary, menu_setup, menu_tools
|
||||
menu_list_facet, menu_multi_item, menu_object, menu_secondary, menu_setup,
|
||||
menu_tools
|
||||
)
|
||||
from mayan.apps.common.widgets import TwoStateWidget
|
||||
from mayan.apps.navigation import SourceColumn
|
||||
@@ -102,6 +103,12 @@ class MailerApp(MayanAppConfig):
|
||||
}
|
||||
)
|
||||
|
||||
menu_list_facet.bind_links(
|
||||
links=(
|
||||
link_acl_list, link_user_mailer_log_list
|
||||
), sources=(UserMailer,)
|
||||
)
|
||||
|
||||
menu_multi_item.bind_links(
|
||||
links=(
|
||||
link_send_multiple_document, link_send_multiple_document_link
|
||||
@@ -116,8 +123,8 @@ class MailerApp(MayanAppConfig):
|
||||
|
||||
menu_object.bind_links(
|
||||
links=(
|
||||
link_user_mailer_edit, link_user_mailer_log_list,
|
||||
link_user_mailer_test, link_acl_list, link_user_mailer_delete,
|
||||
link_user_mailer_delete, link_user_mailer_edit,
|
||||
link_user_mailer_test
|
||||
), sources=(UserMailer,)
|
||||
)
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ from mayan.apps.acls.permissions import permission_acl_edit, permission_acl_view
|
||||
from mayan.apps.common.apps import MayanAppConfig
|
||||
from mayan.apps.common.classes import ModelAttribute, ModelField
|
||||
from mayan.apps.common.menus import (
|
||||
menu_facet, menu_multi_item, menu_object, menu_secondary, menu_setup,
|
||||
menu_sidebar
|
||||
menu_facet, menu_list_facet, menu_multi_item, menu_object, menu_secondary,
|
||||
menu_setup, menu_sidebar
|
||||
)
|
||||
from mayan.apps.common.widgets import TwoStateWidget
|
||||
from mayan.apps.documents.search import document_page_search, document_search
|
||||
@@ -204,23 +204,27 @@ class MetadataApp(MayanAppConfig):
|
||||
)
|
||||
|
||||
menu_facet.bind_links(links=(link_metadata_view,), sources=(Document,))
|
||||
menu_list_facet.bind_links(
|
||||
links=(link_setup_document_type_metadata_types,), sources=(
|
||||
DocumentType,
|
||||
)
|
||||
)
|
||||
menu_multi_item.bind_links(
|
||||
links=(
|
||||
link_metadata_multiple_add, link_metadata_multiple_edit,
|
||||
link_metadata_multiple_remove
|
||||
), sources=(Document,)
|
||||
)
|
||||
menu_object.bind_links(
|
||||
menu_list_facet.bind_links(
|
||||
links=(
|
||||
link_setup_document_type_metadata_types,
|
||||
), sources=(DocumentType,)
|
||||
link_acl_list, link_setup_metadata_type_document_types,
|
||||
link_object_event_types_user_subcriptions_list,
|
||||
link_events_for_object,
|
||||
), sources=(MetadataType,)
|
||||
)
|
||||
menu_object.bind_links(
|
||||
links=(
|
||||
link_setup_metadata_type_edit,
|
||||
link_setup_metadata_type_document_types, link_acl_list,
|
||||
link_object_event_types_user_subcriptions_list,
|
||||
link_events_for_object, link_setup_metadata_type_delete,
|
||||
link_setup_metadata_type_delete, link_setup_metadata_type_edit
|
||||
), sources=(MetadataType,)
|
||||
)
|
||||
menu_secondary.bind_links(
|
||||
|
||||
@@ -8,7 +8,9 @@ from mayan.apps.acls.classes import ModelPermission
|
||||
from mayan.apps.acls.links import link_acl_list
|
||||
from mayan.apps.acls.permissions import permission_acl_edit, permission_acl_view
|
||||
from mayan.apps.common.apps import MayanAppConfig
|
||||
from mayan.apps.common.menus import menu_object, menu_secondary, menu_setup
|
||||
from mayan.apps.common.menus import (
|
||||
menu_list_facet, menu_object, menu_secondary, menu_setup
|
||||
)
|
||||
from mayan.apps.navigation import SourceColumn
|
||||
|
||||
from .links import (
|
||||
@@ -54,9 +56,14 @@ class MOTDApp(MayanAppConfig):
|
||||
func=lambda context: context['object'].end_datetime or _('None')
|
||||
)
|
||||
|
||||
menu_list_facet.bind_links(
|
||||
links=(
|
||||
link_acl_list,
|
||||
), sources=(Message,)
|
||||
)
|
||||
menu_object.bind_links(
|
||||
links=(
|
||||
link_message_edit, link_acl_list, link_message_delete
|
||||
link_message_delete, link_message_edit
|
||||
), sources=(Message,)
|
||||
)
|
||||
menu_secondary.bind_links(
|
||||
|
||||
@@ -6,33 +6,37 @@ import logging
|
||||
from furl import furl
|
||||
|
||||
from django.apps import apps
|
||||
from django.conf import settings
|
||||
from django.contrib.admin.utils import label_for_field
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.shortcuts import resolve_url
|
||||
from django.template import VariableDoesNotExist, Variable
|
||||
from django.template.defaulttags import URLNode
|
||||
from django.urls import Resolver404, resolve
|
||||
from django.urls import resolve, reverse
|
||||
from django.utils.encoding import force_str, force_text
|
||||
|
||||
from mayan.apps.common.settings import setting_home_view
|
||||
from mayan.apps.common.utils import return_attrib
|
||||
from mayan.apps.permissions import Permission
|
||||
|
||||
from .utils import get_current_view_name
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ResolvedLink(object):
|
||||
def __init__(self, link, current_view):
|
||||
self.current_view = current_view
|
||||
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):
|
||||
return self.link.view == self.current_view
|
||||
return self.link.view == self.current_view_name
|
||||
|
||||
@property
|
||||
def badge_text(self):
|
||||
@@ -97,12 +101,15 @@ 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, [])
|
||||
|
||||
for link in links:
|
||||
source_links.append(link)
|
||||
self.link_positions[link] = position
|
||||
self.link_positions[link] = position or 0
|
||||
|
||||
def add_unsorted_source(self, source):
|
||||
self.non_sorted_sources.append(source)
|
||||
@@ -159,6 +166,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) or 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 []
|
||||
@@ -178,15 +203,8 @@ class Menu(object):
|
||||
logger.warning('No request variable, aborting menu resolution')
|
||||
return ()
|
||||
|
||||
current_path = request.META['PATH_INFO']
|
||||
|
||||
# Get sources: view name, view objects
|
||||
try:
|
||||
current_view = resolve(current_path).view_name
|
||||
except Resolver404:
|
||||
# Can't figure out which view corresponds to this URL.
|
||||
# Most likely it is an invalid URL.
|
||||
logger.warning('Can\'t figure out which view corresponds to this URL: %s; aborting menu resolution.', current_path)
|
||||
current_view_name = get_current_view_name(request=request)
|
||||
if not current_view_name:
|
||||
return ()
|
||||
|
||||
resolved_navigation_object_list = self.get_resolved_navigation_object_list(
|
||||
@@ -227,18 +245,28 @@ class Menu(object):
|
||||
pass
|
||||
|
||||
if resolved_links:
|
||||
result.append(resolved_links)
|
||||
result.append(
|
||||
{
|
||||
'object': resolved_navigation_object,
|
||||
'links': resolved_links
|
||||
}
|
||||
)
|
||||
|
||||
resolved_links = []
|
||||
# View links
|
||||
for link in self.bound_links.get(current_view, []):
|
||||
for link in self.bound_links.get(current_view_name, []):
|
||||
resolved_link = link.resolve(context=context)
|
||||
if resolved_link:
|
||||
if resolved_link.link not in self.unbound_links.get(current_view, ()):
|
||||
if resolved_link.link not in self.unbound_links.get(current_view_name, ()):
|
||||
resolved_links.append(resolved_link)
|
||||
|
||||
if resolved_links:
|
||||
result.append(resolved_links)
|
||||
result.append(
|
||||
{
|
||||
'object': current_view_name,
|
||||
'links': resolved_links
|
||||
}
|
||||
)
|
||||
|
||||
resolved_links = []
|
||||
|
||||
@@ -256,7 +284,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
|
||||
@@ -267,15 +300,14 @@ 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
|
||||
@@ -308,7 +340,7 @@ class Link(object):
|
||||
def remove(cls, name):
|
||||
del cls._registry[name]
|
||||
|
||||
def __init__(self, badge_text=None, text=None, view=None, args=None, condition=None,
|
||||
def __init__(self, text=None, view=None, args=None, badge_text=None, condition=None,
|
||||
conditional_disable=None, description=None, html_data=None,
|
||||
html_extra_classes=None, icon=None, icon_class=None,
|
||||
keep_query=False, kwargs=None, name=None, permissions=None,
|
||||
@@ -351,7 +383,7 @@ class Link(object):
|
||||
request = Variable('request').resolve(context)
|
||||
|
||||
current_path = request.META['PATH_INFO']
|
||||
current_view = resolve(current_path).view_name
|
||||
current_view_name = resolve(current_path).view_name
|
||||
|
||||
# ACL is tested agains the resolved_object or just {{ object }} if not
|
||||
if not resolved_object:
|
||||
@@ -386,7 +418,9 @@ class Link(object):
|
||||
if not self.condition(context):
|
||||
return None
|
||||
|
||||
resolved_link = ResolvedLink(current_view=current_view, link=self)
|
||||
resolved_link = ResolvedLink(
|
||||
current_view_name=current_view_name, link=self
|
||||
)
|
||||
|
||||
if self.view:
|
||||
view_name = Variable('"{}"'.format(self.view))
|
||||
@@ -419,7 +453,7 @@ class Link(object):
|
||||
try:
|
||||
resolved_link.url = node.render(context)
|
||||
except Exception as exception:
|
||||
logger.debug(
|
||||
logger.error(
|
||||
'Error resolving link "%s" URL; %s', self.text, exception
|
||||
)
|
||||
elif self.url:
|
||||
@@ -437,7 +471,7 @@ class Link(object):
|
||||
parsed_url = furl(
|
||||
force_str(
|
||||
request.get_full_path() or request.META.get(
|
||||
'HTTP_REFERER', resolve_url(settings.LOGIN_REDIRECT_URL)
|
||||
'HTTP_REFERER', reverse(setting_home_view.value)
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -467,7 +501,7 @@ class Separator(Link):
|
||||
self.view = None
|
||||
|
||||
def resolve(self, *args, **kwargs):
|
||||
result = ResolvedLink(current_view=None, link=self)
|
||||
result = ResolvedLink(current_view_name=None, link=self)
|
||||
result.separator = True
|
||||
return result
|
||||
|
||||
@@ -543,7 +577,7 @@ class Text(Link):
|
||||
self.view = None
|
||||
|
||||
def resolve(self, *args, **kwargs):
|
||||
result = ResolvedLink(current_view=None, link=self)
|
||||
result = ResolvedLink(current_view_name=None, link=self)
|
||||
result.context = kwargs.get('context')
|
||||
result.text_span = True
|
||||
return result
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{% load i18n %}
|
||||
|
||||
{% spaceless %}
|
||||
{% if as_dropdown %}
|
||||
<div class="dropdown text-center">
|
||||
<button class="btn btn-default dropdown-toggle btn-danger btn-sm" type="button" id="dropdownMenu" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
@@ -23,3 +24,4 @@
|
||||
{% include 'navigation/generic_subnavigation.html' %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endspaceless %}
|
||||
|
||||
@@ -12,14 +12,16 @@
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
{% get_menu_links link.name as menu_links %}
|
||||
{% for linkset in menu_links %}
|
||||
{% 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 linkset as object_navigation_links %}
|
||||
{% with link_group.links as object_navigation_links %}
|
||||
{% include 'navigation/generic_navigation.html' %}
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
{% else %}
|
||||
|
||||
@@ -39,7 +39,8 @@ def get_menus_links(context, names, source=None, sort_results=None):
|
||||
def get_multi_item_links_form(context, object_list):
|
||||
actions = []
|
||||
for link_set in Menu.get('multi item').resolve(context=context, source=object_list[0], sort_results=True):
|
||||
for link in link_set:
|
||||
for link in link_set['links']:
|
||||
if hasattr(link, 'url'):
|
||||
actions.append((link.url, link.text))
|
||||
|
||||
form = MultiItemForm(actions=actions)
|
||||
@@ -70,6 +71,35 @@ def get_source_columns(source):
|
||||
return SourceColumn.get_for_source(source)
|
||||
|
||||
|
||||
@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 resolve_link(context, link):
|
||||
# This can be used to resolve links or menus too
|
||||
|
||||
@@ -29,7 +29,8 @@ class LinkClassTestCase(GenericViewTestCase):
|
||||
self.add_test_view(test_object=self.test_object)
|
||||
|
||||
self.namespace = PermissionNamespace(
|
||||
TEST_PERMISSION_NAMESPACE_NAME, TEST_PERMISSION_NAMESPACE_TEXT
|
||||
label=TEST_PERMISSION_NAMESPACE_TEXT,
|
||||
name=TEST_PERMISSION_NAMESPACE_NAME
|
||||
)
|
||||
|
||||
self.test_permission = self.namespace.add_permission(
|
||||
@@ -45,32 +46,30 @@ class LinkClassTestCase(GenericViewTestCase):
|
||||
Permission.invalidate_cache()
|
||||
|
||||
def test_link_resolve(self):
|
||||
response = self.get(TEST_VIEW_NAME)
|
||||
response = self.get(viewname=TEST_VIEW_NAME)
|
||||
|
||||
context = Context({'request': response.wsgi_request})
|
||||
|
||||
resolved_link = self.link.resolve(context=context)
|
||||
|
||||
self.assertEqual(resolved_link.url, reverse(TEST_VIEW_NAME))
|
||||
self.assertEqual(
|
||||
resolved_link.url, reverse(viewname=TEST_VIEW_NAME)
|
||||
)
|
||||
|
||||
def test_link_permission_resolve_no_permission(self):
|
||||
self.login_user()
|
||||
|
||||
link = Link(
|
||||
permissions=(self.test_permission,), text=TEST_LINK_TEXT,
|
||||
view=TEST_VIEW_NAME
|
||||
)
|
||||
|
||||
response = self.get(TEST_VIEW_NAME)
|
||||
response = self.get(viewname=TEST_VIEW_NAME)
|
||||
response.context.update({'request': response.wsgi_request})
|
||||
|
||||
context = Context(response.context)
|
||||
|
||||
resolved_link = link.resolve(context=context)
|
||||
|
||||
self.assertEqual(resolved_link, None)
|
||||
|
||||
def test_link_permission_resolve_with_permission(self):
|
||||
self.login_user()
|
||||
|
||||
link = Link(
|
||||
permissions=(self.test_permission,), text=TEST_LINK_TEXT,
|
||||
view=TEST_VIEW_NAME
|
||||
@@ -78,17 +77,16 @@ class LinkClassTestCase(GenericViewTestCase):
|
||||
|
||||
self.grant_access(obj=self.test_object, permission=self.test_permission)
|
||||
|
||||
response = self.get(TEST_VIEW_NAME)
|
||||
response = self.get(viewname=TEST_VIEW_NAME)
|
||||
response.context.update({'request': response.wsgi_request})
|
||||
|
||||
context = Context(response.context)
|
||||
|
||||
resolved_link = link.resolve(context=context)
|
||||
|
||||
self.assertEqual(resolved_link.url, reverse(TEST_VIEW_NAME))
|
||||
self.assertEqual(resolved_link.url, reverse(viewname=TEST_VIEW_NAME))
|
||||
|
||||
def test_link_permission_resolve_with_acl(self):
|
||||
# ACL is tested agains the resolved_object or just {{ object }} if not
|
||||
|
||||
link = Link(
|
||||
permissions=(self.test_permission,), text=TEST_LINK_TEXT,
|
||||
view=TEST_VIEW_NAME
|
||||
@@ -96,14 +94,14 @@ class LinkClassTestCase(GenericViewTestCase):
|
||||
|
||||
self.grant_access(obj=self.test_object, permission=self.test_permission)
|
||||
|
||||
response = self.get(TEST_VIEW_NAME)
|
||||
response = self.get(viewname=TEST_VIEW_NAME)
|
||||
response.context.update({'request': response.wsgi_request})
|
||||
|
||||
context = Context(response.context)
|
||||
|
||||
resolved_link = link.resolve(context=context)
|
||||
|
||||
self.assertNotEqual(resolved_link, None)
|
||||
self.assertEqual(resolved_link.url, reverse(TEST_VIEW_NAME))
|
||||
self.assertEqual(resolved_link.url, reverse(viewname=TEST_VIEW_NAME))
|
||||
|
||||
def test_link_with_unicode_querystring_request(self):
|
||||
url = furl(reverse(TEST_VIEW_NAME))
|
||||
@@ -130,7 +128,6 @@ class LinkClassTestCase(GenericViewTestCase):
|
||||
context = Context({'request': response.wsgi_request})
|
||||
|
||||
resolved_link = self.link.resolve(context=context)
|
||||
|
||||
self.assertEqual(
|
||||
resolved_link.url,
|
||||
'{}?{}'.format(TEST_URL, TEST_QUERYSTRING_TWO_KEYS)
|
||||
@@ -184,10 +181,10 @@ class MenuClassTestCase(GenericViewTestCase):
|
||||
def test_null_source_link_unbinding(self):
|
||||
self.menu.bind_links(links=(self.link,))
|
||||
|
||||
response = self.get(TEST_VIEW_NAME)
|
||||
response = self.get(viewname=TEST_VIEW_NAME)
|
||||
context = Context({'request': response.wsgi_request})
|
||||
self.assertEqual(
|
||||
self.menu.resolve(context=context)[0][0].link, self.link
|
||||
self.menu.resolve(context=context)[0]['links'][0].link, self.link
|
||||
)
|
||||
|
||||
self.menu.unbind_links(links=(self.link,))
|
||||
@@ -197,10 +194,12 @@ class MenuClassTestCase(GenericViewTestCase):
|
||||
def test_null_source_submenu_unbinding(self):
|
||||
self.menu.bind_links(links=(self.sub_menu,))
|
||||
|
||||
response = self.get(TEST_VIEW_NAME)
|
||||
response = self.get(viewname=TEST_VIEW_NAME)
|
||||
context = Context({'request': response.wsgi_request})
|
||||
|
||||
self.assertEqual(self.menu.resolve(context=context), [[self.sub_menu]])
|
||||
self.assertEqual(
|
||||
self.menu.resolve(context=context)[0]['links'], [self.sub_menu]
|
||||
)
|
||||
|
||||
self.menu.unbind_links(links=(self.sub_menu,))
|
||||
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import logging
|
||||
|
||||
from django.apps import apps
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.urls import Resolver404, resolve
|
||||
|
||||
from mayan.apps.permissions import Permission
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_cascade_condition(app_label, model_name, object_permission, view_permission=None):
|
||||
"""
|
||||
@@ -37,3 +42,20 @@ def get_cascade_condition(app_label, model_name, object_permission, view_permiss
|
||||
return queryset.count() > 0
|
||||
|
||||
return condition
|
||||
|
||||
|
||||
def get_current_view_name(request):
|
||||
current_path = request.META['PATH_INFO']
|
||||
|
||||
# Get sources: view name, view objects
|
||||
try:
|
||||
current_view_name = resolve(current_path).view_name
|
||||
except Resolver404:
|
||||
# Can't figure out which view corresponds to this URL.
|
||||
# Most likely it is an invalid URL.
|
||||
logger.warning(
|
||||
'Can\'t figure out which view corresponds to this '
|
||||
'URL: %s; aborting menu resolution.', current_path
|
||||
)
|
||||
else:
|
||||
return current_view_name
|
||||
|
||||
@@ -12,7 +12,8 @@ from mayan.apps.acls.classes import ModelPermission
|
||||
from mayan.apps.common.apps import MayanAppConfig
|
||||
from mayan.apps.common.classes import ModelField
|
||||
from mayan.apps.common.menus import (
|
||||
menu_facet, menu_multi_item, menu_object, menu_secondary, menu_tools
|
||||
menu_facet, menu_list_facet, menu_multi_item, menu_object, menu_secondary,
|
||||
menu_tools
|
||||
)
|
||||
from mayan.apps.documents.search import document_search, document_page_search
|
||||
from mayan.apps.documents.signals import post_version_upload
|
||||
@@ -138,21 +139,18 @@ class OCRApp(MayanAppConfig):
|
||||
menu_facet.bind_links(
|
||||
links=(link_document_ocr_content,), sources=(Document,)
|
||||
)
|
||||
menu_facet.bind_links(
|
||||
menu_list_facet.bind_links(
|
||||
links=(link_document_page_ocr_content,), sources=(DocumentPage,)
|
||||
)
|
||||
menu_list_facet.bind_links(
|
||||
links=(link_document_type_ocr_settings,), sources=(DocumentType,)
|
||||
)
|
||||
menu_multi_item.bind_links(
|
||||
links=(link_document_submit_multiple,), sources=(Document,)
|
||||
)
|
||||
menu_object.bind_links(
|
||||
links=(link_document_submit,), sources=(Document,)
|
||||
)
|
||||
menu_object.bind_links(
|
||||
links=(link_document_page_ocr_content,), sources=(DocumentPage,)
|
||||
)
|
||||
menu_object.bind_links(
|
||||
links=(link_document_type_ocr_settings,), sources=(DocumentType,)
|
||||
)
|
||||
menu_secondary.bind_links(
|
||||
links=(
|
||||
link_document_ocr_content, link_document_ocr_errors_list,
|
||||
|
||||
@@ -9,7 +9,7 @@ from mayan.apps.acls.permissions import permission_acl_edit, permission_acl_view
|
||||
|
||||
from mayan.apps.common.apps import MayanAppConfig
|
||||
from mayan.apps.common.menus import (
|
||||
menu_multi_item, menu_object, menu_secondary, menu_setup
|
||||
menu_list_facet, menu_multi_item, menu_object, menu_secondary, menu_setup
|
||||
)
|
||||
from mayan.apps.common.signals import perform_upgrade
|
||||
|
||||
@@ -47,13 +47,17 @@ class PermissionsApp(MayanAppConfig):
|
||||
)
|
||||
)
|
||||
|
||||
menu_object.bind_links(
|
||||
links=(link_group_roles,), position=98, sources=(Group,)
|
||||
menu_list_facet.bind_links(
|
||||
links=(
|
||||
link_acl_list, link_role_groups, link_role_permissions,
|
||||
), sources=(Role,)
|
||||
)
|
||||
menu_list_facet.bind_links(
|
||||
links=(link_group_roles,), sources=(Group,)
|
||||
)
|
||||
menu_object.bind_links(
|
||||
links=(
|
||||
link_role_edit, link_role_groups, link_role_permissions,
|
||||
link_acl_list, link_role_delete
|
||||
link_role_delete, link_role_edit
|
||||
), sources=(Role,)
|
||||
)
|
||||
menu_multi_item.bind_links(
|
||||
|
||||
@@ -7,7 +7,7 @@ from kombu import Exchange, Queue
|
||||
from mayan.apps.common.apps import MayanAppConfig
|
||||
from mayan.apps.common.classes import MissingItem
|
||||
from mayan.apps.common.menus import (
|
||||
menu_object, menu_secondary, menu_sidebar, menu_setup
|
||||
menu_list_facet, menu_object, menu_secondary, menu_sidebar, menu_setup
|
||||
)
|
||||
from mayan.apps.common.signals import post_initial_setup, post_upgrade
|
||||
from mayan.apps.converter.links import link_transformation_list
|
||||
@@ -125,10 +125,18 @@ class SourcesApp(MayanAppConfig):
|
||||
)
|
||||
menu_documents.bind_links(links=(link_document_create_multiple,))
|
||||
|
||||
menu_list_facet.bind_links(
|
||||
links=(
|
||||
link_setup_source_logs, link_transformation_list,
|
||||
), sources=(
|
||||
POP3Email, IMAPEmail, SaneScanner, StagingFolderSource,
|
||||
WatchFolderSource, WebFormSource
|
||||
)
|
||||
)
|
||||
|
||||
menu_object.bind_links(
|
||||
links=(
|
||||
link_setup_source_edit, link_setup_source_delete,
|
||||
link_transformation_list, link_setup_source_logs
|
||||
link_setup_source_delete, link_setup_source_edit
|
||||
), sources=(
|
||||
POP3Email, IMAPEmail, SaneScanner, StagingFolderSource,
|
||||
WatchFolderSource, WebFormSource
|
||||
|
||||
@@ -10,7 +10,8 @@ from mayan.apps.acls.permissions import permission_acl_edit, permission_acl_view
|
||||
from mayan.apps.common.apps import MayanAppConfig
|
||||
from mayan.apps.common.classes import ModelField
|
||||
from mayan.apps.common.menus import (
|
||||
menu_facet, menu_object, menu_main, menu_multi_item, menu_sidebar
|
||||
menu_facet, menu_list_facet, menu_main, menu_multi_item, menu_object,
|
||||
menu_sidebar
|
||||
)
|
||||
from mayan.apps.documents.search import document_page_search, document_search
|
||||
from mayan.apps.events import ModelEventType
|
||||
@@ -42,7 +43,7 @@ from .search import tag_search # NOQA
|
||||
|
||||
class TagsApp(MayanAppConfig):
|
||||
app_namespace = 'tags'
|
||||
app_urls = 'tags'
|
||||
app_url = 'tags'
|
||||
has_rest_api = True
|
||||
has_tests = True
|
||||
name = 'mayan.apps.tags'
|
||||
@@ -143,6 +144,14 @@ class TagsApp(MayanAppConfig):
|
||||
links=(link_tag_document_list,), sources=(Document,)
|
||||
)
|
||||
|
||||
menu_list_facet.bind_links(
|
||||
links=(
|
||||
link_acl_list, link_events_for_object,
|
||||
link_object_event_types_user_subcriptions_list,
|
||||
link_tag_tagged_item_list,
|
||||
), sources=(Tag,)
|
||||
)
|
||||
|
||||
menu_tags.bind_links(
|
||||
links=(
|
||||
link_tag_list, link_tag_create
|
||||
@@ -163,10 +172,7 @@ class TagsApp(MayanAppConfig):
|
||||
)
|
||||
menu_object.bind_links(
|
||||
links=(
|
||||
link_tag_tagged_item_list, link_tag_edit, link_acl_list,
|
||||
link_events_for_object,
|
||||
link_object_event_types_user_subcriptions_list,
|
||||
link_tag_delete
|
||||
link_tag_edit, link_tag_delete
|
||||
),
|
||||
sources=(Tag,)
|
||||
)
|
||||
|
||||
@@ -10,7 +10,8 @@ from mayan.apps.acls.links import link_acl_list
|
||||
from mayan.apps.acls.permissions import permission_acl_edit, permission_acl_view
|
||||
from mayan.apps.common.apps import MayanAppConfig
|
||||
from mayan.apps.common.menus import (
|
||||
menu_multi_item, menu_object, menu_secondary, menu_setup, menu_user
|
||||
menu_list_facet, menu_multi_item, menu_object, menu_secondary, menu_setup,
|
||||
menu_user
|
||||
)
|
||||
from mayan.apps.common.widgets import TwoStateWidget
|
||||
from mayan.apps.metadata import MetadataLookup
|
||||
@@ -114,22 +115,31 @@ class UserManagementApp(MayanAppConfig):
|
||||
).render()
|
||||
)
|
||||
|
||||
menu_list_facet.bind_links(
|
||||
links=(
|
||||
link_acl_list, link_group_members
|
||||
), sources=(Group,)
|
||||
)
|
||||
menu_list_facet.bind_links(
|
||||
links=(
|
||||
link_acl_list, link_user_groups, link_user_set_options
|
||||
), sources=(User,)
|
||||
)
|
||||
menu_multi_item.bind_links(
|
||||
links=(link_user_multiple_set_password, link_user_multiple_delete),
|
||||
sources=('user_management:user_list',)
|
||||
)
|
||||
menu_object.bind_links(
|
||||
links=(link_group_edit, link_group_members,),
|
||||
links=(link_group_edit,),
|
||||
sources=(Group,)
|
||||
)
|
||||
menu_object.bind_links(
|
||||
links=(link_acl_list, link_group_delete,), position=99,
|
||||
links=(link_group_delete,), position=99,
|
||||
sources=(Group,)
|
||||
)
|
||||
menu_object.bind_links(
|
||||
links=(
|
||||
link_user_edit, link_user_set_password, link_user_groups,
|
||||
link_user_set_options, link_acl_list, link_user_delete
|
||||
link_user_delete, link_user_edit, link_user_set_password
|
||||
), sources=(User,)
|
||||
)
|
||||
menu_secondary.bind_links(
|
||||
|
||||
Reference in New Issue
Block a user