Add new split move index navigation.
This commit is contained in:
@@ -29,7 +29,7 @@ from .links import (
|
||||
link_template_node_create, link_template_node_delete,
|
||||
link_template_node_edit
|
||||
)
|
||||
from .widgets import get_breadcrumbs, index_instance_item_link, node_level
|
||||
from .widgets import get_instance_link, index_instance_item_link, node_level
|
||||
|
||||
|
||||
class DocumentIndexingApp(MayanAppConfig):
|
||||
@@ -107,7 +107,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
SourceColumn(
|
||||
source=IndexInstance, label=_('Items'),
|
||||
func=lambda context: context['object'].get_items_count(
|
||||
func=lambda context: context['object'].get_item_count(
|
||||
user=context['request'].user
|
||||
)
|
||||
)
|
||||
@@ -144,8 +144,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
SourceColumn(
|
||||
source=DocumentIndexInstanceNode, label=_('Node'),
|
||||
func=lambda context: get_breadcrumbs(
|
||||
index_instance_node=context['object'], single_link=True,
|
||||
func=lambda context: get_instance_link(
|
||||
index_instance_node=context['object'],
|
||||
)
|
||||
)
|
||||
SourceColumn(
|
||||
|
||||
@@ -11,6 +11,11 @@ from documents.models import Document
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DocumentIndexInstanceNodeManager(models.Manager):
|
||||
def get_for(self, document):
|
||||
return self.filter(documents=document)
|
||||
|
||||
|
||||
class IndexManager(models.Manager):
|
||||
def get_by_natural_key(self, name):
|
||||
return self.get(name=name)
|
||||
|
||||
@@ -14,7 +14,9 @@ from documents.models import Document, DocumentType
|
||||
from documents.permissions import permission_document_view
|
||||
from permissions import Permission
|
||||
|
||||
from .managers import IndexManager, IndexInstanceNodeManager
|
||||
from .managers import (
|
||||
DocumentIndexInstanceNodeManager, IndexManager, IndexInstanceNodeManager
|
||||
)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
@@ -88,7 +90,7 @@ class IndexInstance(Index):
|
||||
except IndexInstanceNode.DoesNotExist:
|
||||
return 0
|
||||
|
||||
def get_items_count(self, user):
|
||||
def get_item_count(self, user):
|
||||
try:
|
||||
return self.instance_root.get_item_count(user=user)
|
||||
except IndexInstanceNode.DoesNotExist:
|
||||
@@ -171,7 +173,7 @@ class IndexInstanceNode(MPTTModel):
|
||||
return self.get_children()
|
||||
|
||||
def index(self):
|
||||
return self.index_template_node.index
|
||||
return IndexInstance.objects.get(pk=self.index_template_node.index.pk)
|
||||
|
||||
def get_item_count(self, user):
|
||||
if self.index_template_node.link_documents:
|
||||
@@ -188,16 +190,21 @@ class IndexInstanceNode(MPTTModel):
|
||||
else:
|
||||
return self.get_children().count()
|
||||
|
||||
def get_full_path(self):
|
||||
result = []
|
||||
for node in self.get_ancestors(include_self=True):
|
||||
if node.is_root_node():
|
||||
result.append(unicode(self.index()))
|
||||
else:
|
||||
result.append(unicode(node))
|
||||
|
||||
return ' / '.join(result)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Index node instance')
|
||||
verbose_name_plural = _('Indexes node instances')
|
||||
|
||||
|
||||
class DocumentIndexInstanceNodeManager(models.Manager):
|
||||
def get_for(self, document):
|
||||
return self.filter(documents=document)
|
||||
|
||||
|
||||
class DocumentIndexInstanceNode(IndexInstanceNode):
|
||||
objects = DocumentIndexInstanceNodeManager()
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ def task_do_rebuild_all_indexes(self):
|
||||
app_label='lock_manager', model_name='Lock'
|
||||
)
|
||||
|
||||
if Lock.check_existing(name__startswith='document_indexing_task_update_index_document'):
|
||||
if Lock.objects.check_existing(name__startswith='document_indexing_task_update_index_document'):
|
||||
# A document index update is happening, wait
|
||||
raise self.retry()
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
{% extends 'appearance/base.html' %}
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
{% load navigation_tags %}
|
||||
|
||||
{% block title %}{% include 'appearance/calculate_form_title.html' %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if title %}
|
||||
<h3>{{ title }}</h3>
|
||||
<hr>
|
||||
{% endif %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12 col-md-4">
|
||||
{{ navigation }}
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 col-sm-12 col-md-8">
|
||||
{% include 'appearance/generic_list_subtemplate.html' %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@@ -31,7 +31,7 @@ from .permissions import (
|
||||
permission_document_indexing_setup, permission_document_indexing_view
|
||||
)
|
||||
from .tasks import task_do_rebuild_all_indexes
|
||||
from .widgets import get_breadcrumbs
|
||||
from .widgets import node_tree
|
||||
|
||||
|
||||
# Setup views
|
||||
@@ -236,7 +236,9 @@ class IndexListView(SingleObjectListView):
|
||||
}
|
||||
|
||||
|
||||
class IndexInstanceNodeView(DocumentListView, SingleObjectListView):
|
||||
class IndexInstanceNodeView(DocumentListView):
|
||||
template_name = 'document_indexing/node_details.html'
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
self.index_instance = get_object_or_404(
|
||||
IndexInstanceNode, pk=self.kwargs['pk']
|
||||
@@ -280,11 +282,14 @@ class IndexInstanceNodeView(DocumentListView, SingleObjectListView):
|
||||
context = {
|
||||
'hide_links': True,
|
||||
'object': self.index_instance,
|
||||
'title': mark_safe(
|
||||
_(
|
||||
'Contents for index: %s'
|
||||
) % get_breadcrumbs(self.index_instance)
|
||||
)
|
||||
'navigation': mark_safe(
|
||||
_('Navigation: %s') % node_tree(
|
||||
node=self.index_instance, user=self.request.user
|
||||
)
|
||||
),
|
||||
'title': _(
|
||||
'Contents for index: %s'
|
||||
) % self.index_instance.get_full_path(),
|
||||
}
|
||||
|
||||
if self.index_instance and not self.index_instance.index_template_node.link_documents:
|
||||
|
||||
@@ -2,64 +2,21 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.apps import apps
|
||||
from django.utils.html import mark_safe
|
||||
from django.utils.html import mark_safe, escape
|
||||
from django.utils.translation import ugettext
|
||||
|
||||
|
||||
def get_instance_link(index_instance_node, text=None, simple=False):
|
||||
def get_instance_link(index_instance_node):
|
||||
"""
|
||||
Return an HTML anchor to an index instance
|
||||
Return an HTML anchor to an index node instance
|
||||
"""
|
||||
|
||||
if simple:
|
||||
# Just display the instance's value or overrided text, no
|
||||
# HTML anchor
|
||||
template = '%(value)s'
|
||||
else:
|
||||
template = '<a href="%(url)s">%(value)s</a>'
|
||||
|
||||
return template % {
|
||||
'url': index_instance_node.get_absolute_url(),
|
||||
'value': text if text else (
|
||||
index_instance_node if index_instance_node.parent else index_instance_node.index_template_node.index
|
||||
return mark_safe(
|
||||
'<a href="{url}">{text}</a>'.format(
|
||||
url=index_instance_node.get_absolute_url(),
|
||||
text=escape(index_instance_node.get_full_path())
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
def get_breadcrumbs(index_instance_node, simple=False, single_link=False, include_count=False):
|
||||
"""
|
||||
Return a joined string of HTML anchors to every index instance's
|
||||
parent from the root of the tree to the index instance
|
||||
"""
|
||||
|
||||
result = []
|
||||
if single_link:
|
||||
# Return the entire breadcrumb path as a single HTML anchor
|
||||
simple = True
|
||||
|
||||
for instance in index_instance_node.get_ancestors():
|
||||
result.append(get_instance_link(instance, simple=simple))
|
||||
|
||||
result.append(get_instance_link(index_instance_node, simple=simple))
|
||||
|
||||
output = []
|
||||
|
||||
if include_count:
|
||||
output.append('(%d)' % index_instance_node.documents.count())
|
||||
|
||||
if single_link:
|
||||
# Return the entire breadcrumb path as a single HTML anchor
|
||||
output.insert(
|
||||
0, get_instance_link(
|
||||
index_instance_node=index_instance_node, text=(
|
||||
' / '.join(result)
|
||||
)
|
||||
)
|
||||
)
|
||||
return mark_safe(' '.join(output))
|
||||
else:
|
||||
output.insert(0, ' / '.join(result))
|
||||
return mark_safe(' '.join(output))
|
||||
)
|
||||
|
||||
|
||||
def index_instance_item_link(index_instance_item):
|
||||
@@ -99,3 +56,37 @@ def node_level(node):
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def node_tree(node, user):
|
||||
result = []
|
||||
|
||||
result.append('<div class="list-group">')
|
||||
|
||||
for ancestor in node.get_ancestors(include_self=True):
|
||||
if ancestor.is_root_node():
|
||||
element = node.index()
|
||||
level = 0
|
||||
icon = 'fa fa-list-ul'
|
||||
else:
|
||||
element = ancestor
|
||||
level = getattr(element, element._mptt_meta.level_attr)
|
||||
if element.index_template_node.link_documents:
|
||||
icon = 'fa fa-folder'
|
||||
else:
|
||||
icon = 'fa fa-level-up fa-rotate-90'
|
||||
|
||||
result.append(
|
||||
'<a href="{url}" class="list-group-item {active}"><span class="badge">{count}</span><i class="{icon}"></i>{space} {text}</a>'.format(
|
||||
url=element.get_absolute_url(),
|
||||
active='active' if element == node or node.get_ancestors(include_self=True).count() == 1 else '',
|
||||
count=element.get_item_count(user=user),
|
||||
icon=icon,
|
||||
space=' ' * level,
|
||||
text=escape(element)
|
||||
)
|
||||
)
|
||||
|
||||
result.append('</div>')
|
||||
|
||||
return mark_safe(''.join(result))
|
||||
|
||||
Reference in New Issue
Block a user